| OLD | NEW |
| 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 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 #include "chrome/browser/ui/views/network_profile_bubble.h" | 5 #include "chrome/browser/ui/views/network_profile_bubble.h" |
| 6 | 6 |
| 7 #include <wtsapi32.h> | 7 #include <wtsapi32.h> |
| 8 // Make sure we link the wtsapi lib file in. | 8 // Make sure we link the wtsapi lib file in. |
| 9 #pragma comment(lib, "wtsapi32.lib") | 9 #pragma comment(lib, "wtsapi32.lib") |
| 10 | 10 |
| (...skipping 24 matching lines...) Expand all Loading... |
| 35 namespace { | 35 namespace { |
| 36 | 36 |
| 37 // The duration of the silent period before we start nagging the user again. | 37 // The duration of the silent period before we start nagging the user again. |
| 38 const int kSilenceDurationDays = 100; | 38 const int kSilenceDurationDays = 100; |
| 39 | 39 |
| 40 // Bubble layout constants. | 40 // Bubble layout constants. |
| 41 const int kAnchorVerticalInset = 5; | 41 const int kAnchorVerticalInset = 5; |
| 42 const int kInset = 2; | 42 const int kInset = 2; |
| 43 const int kNotificationBubbleWidth = 250; | 43 const int kNotificationBubbleWidth = 250; |
| 44 | 44 |
| 45 // The name of the UMA histogram collecting our stats. |
| 46 const char kMetricNetworkedProfileCheck[] = "NetworkedProfile.Check"; |
| 47 |
| 48 enum MetricNetworkedProfileCheck { |
| 49 // Check was suppressed by command line flag. |
| 50 METRIC_CHECK_SUPPRESSED, |
| 51 // WTSQuerySessionInformation call failed. |
| 52 METRIC_CHECK_FAILED, |
| 53 // File access in profile dir failed. |
| 54 METRIC_CHECK_IO_FAILED, |
| 55 |
| 56 // Profile on a network share detected. |
| 57 METRIC_PROFILE_ON_NETWORK, |
| 58 // Profile not on a network share detected. |
| 59 METRIC_PROFILE_NOT_ON_NETWORK, |
| 60 |
| 61 // Check was suppressed because of remote session. |
| 62 METRIC_REMOTE_SESSION, |
| 63 |
| 64 // User has clicked learn more on the notification bubble. |
| 65 METRIC_LEARN_MORE_CLICKED, |
| 66 // User has clicked OK on the notification bubble. |
| 67 METRIC_ACKNOWLEDGED, |
| 68 |
| 69 METRIC_NETWORKED_PROFILE_CHECK_SIZE // Must be the last. |
| 70 }; |
| 71 |
| 72 // Helper function wrapping the UMA_HISTOGRAM_ENUMERATION macro. |
| 73 void RecordUmaEvent(MetricNetworkedProfileCheck event) { |
| 74 UMA_HISTOGRAM_ENUMERATION(kMetricNetworkedProfileCheck, |
| 75 event, |
| 76 METRIC_NETWORKED_PROFILE_CHECK_SIZE); |
| 77 } |
| 78 |
| 45 // Implementation of BrowserList::Observer used to wait for a browser window. | 79 // Implementation of BrowserList::Observer used to wait for a browser window. |
| 46 class BrowserListObserver : public BrowserList::Observer { | 80 class BrowserListObserver : public BrowserList::Observer { |
| 47 private: | 81 private: |
| 48 virtual ~BrowserListObserver(); | 82 virtual ~BrowserListObserver(); |
| 49 | 83 |
| 50 // Overridden from BrowserList::Observer: | 84 // Overridden from BrowserList::Observer: |
| 51 virtual void OnBrowserAdded(const Browser* browser) OVERRIDE; | 85 virtual void OnBrowserAdded(const Browser* browser) OVERRIDE; |
| 52 virtual void OnBrowserRemoved(const Browser* browser) OVERRIDE; | 86 virtual void OnBrowserRemoved(const Browser* browser) OVERRIDE; |
| 53 virtual void OnBrowserSetLastActive(const Browser* browser) OVERRIDE; | 87 virtual void OnBrowserSetLastActive(const Browser* browser) OVERRIDE; |
| 54 }; | 88 }; |
| (...skipping 29 matching lines...) Expand all Loading... |
| 84 // share as we don't officially support this setup yet. | 118 // share as we don't officially support this setup yet. |
| 85 // However we don't want to bother users on Cytrix setups as those have no | 119 // However we don't want to bother users on Cytrix setups as those have no |
| 86 // real choice and their admins must be well aware of the risks associated. | 120 // real choice and their admins must be well aware of the risks associated. |
| 87 // Also the command line flag --no-network-profile-warning can stop this | 121 // Also the command line flag --no-network-profile-warning can stop this |
| 88 // warning from popping up. In this case we can skip the check to make the | 122 // warning from popping up. In this case we can skip the check to make the |
| 89 // start faster. | 123 // start faster. |
| 90 // Collect a lot of stats along the way to see which cases do occur in the | 124 // Collect a lot of stats along the way to see which cases do occur in the |
| 91 // wild often enough. | 125 // wild often enough. |
| 92 if (CommandLine::ForCurrentProcess()->HasSwitch( | 126 if (CommandLine::ForCurrentProcess()->HasSwitch( |
| 93 switches::kNoNetworkProfileWarning)) { | 127 switches::kNoNetworkProfileWarning)) { |
| 94 UMA_HISTOGRAM_COUNTS("NetworkedProfile.CheckSuppressed", 1); | 128 RecordUmaEvent(METRIC_CHECK_SUPPRESSED); |
| 95 return; | 129 return; |
| 96 } | 130 } |
| 97 | 131 |
| 98 LPWSTR buffer = NULL; | 132 LPWSTR buffer = NULL; |
| 99 DWORD buffer_length = 0; | 133 DWORD buffer_length = 0; |
| 100 // Checking for RDP is cheaper than checking for a network drive so do this | 134 // Checking for RDP is cheaper than checking for a network drive so do this |
| 101 // one first. | 135 // one first. |
| 102 if (!WTSQuerySessionInformation(WTS_CURRENT_SERVER, WTS_CURRENT_SESSION, | 136 if (!WTSQuerySessionInformation(WTS_CURRENT_SERVER, WTS_CURRENT_SESSION, |
| 103 WTSClientProtocolType, | 137 WTSClientProtocolType, |
| 104 &buffer, &buffer_length)) { | 138 &buffer, &buffer_length)) { |
| 105 UMA_HISTOGRAM_COUNTS("NetworkedProfile.CheckFailed", 1); | 139 RecordUmaEvent(METRIC_CHECK_FAILED); |
| 106 return; | 140 return; |
| 107 } | 141 } |
| 108 | 142 |
| 109 unsigned short* type = reinterpret_cast<unsigned short*>(buffer); | 143 unsigned short* type = reinterpret_cast<unsigned short*>(buffer); |
| 110 // Zero means local session and we should warn the users if they have | 144 // Zero means local session and we should warn the users if they have |
| 111 // their profile on a network share. | 145 // their profile on a network share. |
| 112 if (*type == 0) { | 146 if (*type == 0) { |
| 113 bool profile_on_network = false; | 147 bool profile_on_network = false; |
| 114 if (!profile_path.empty()) { | 148 if (!profile_path.empty()) { |
| 115 FilePath temp_file; | 149 FilePath temp_file; |
| 116 // Try to create some non-empty temp file in the profile dir and use | 150 // Try to create some non-empty temp file in the profile dir and use |
| 117 // it to check if there is a reparse-point free path to it. | 151 // it to check if there is a reparse-point free path to it. |
| 118 if (file_util::CreateTemporaryFileInDir(profile_path, &temp_file) && | 152 if (file_util::CreateTemporaryFileInDir(profile_path, &temp_file) && |
| 119 file_util::WriteFile(temp_file, ".", 1)) { | 153 file_util::WriteFile(temp_file, ".", 1)) { |
| 120 FilePath normalized_temp_file; | 154 FilePath normalized_temp_file; |
| 121 if (!file_util::NormalizeFilePath(temp_file, &normalized_temp_file)) | 155 if (!file_util::NormalizeFilePath(temp_file, &normalized_temp_file)) |
| 122 profile_on_network = true; | 156 profile_on_network = true; |
| 123 } else { | 157 } else { |
| 124 UMA_HISTOGRAM_COUNTS("NetworkedProfile.CheckIOFailed", 1); | 158 RecordUmaEvent(METRIC_CHECK_IO_FAILED); |
| 125 } | 159 } |
| 126 file_util::Delete(temp_file, false); | 160 file_util::Delete(temp_file, false); |
| 127 } | 161 } |
| 128 if (profile_on_network) { | 162 if (profile_on_network) { |
| 129 UMA_HISTOGRAM_COUNTS("NetworkedProfile.ProfileOnNetwork", 1); | 163 RecordUmaEvent(METRIC_PROFILE_ON_NETWORK); |
| 130 content::BrowserThread::PostTask( | 164 content::BrowserThread::PostTask( |
| 131 content::BrowserThread::UI, FROM_HERE, | 165 content::BrowserThread::UI, FROM_HERE, |
| 132 base::Bind(&NetworkProfileBubble::NotifyNetworkProfileDetected)); | 166 base::Bind(&NetworkProfileBubble::NotifyNetworkProfileDetected)); |
| 133 } else { | 167 } else { |
| 134 UMA_HISTOGRAM_COUNTS("NetworkedProfile.ProfileNotOnNetwork", 1); | 168 RecordUmaEvent(METRIC_PROFILE_NOT_ON_NETWORK); |
| 135 } | 169 } |
| 136 } else { | 170 } else { |
| 137 UMA_HISTOGRAM_COUNTS("NetworkedProfile.RemoteSession", 1); | 171 RecordUmaEvent(METRIC_REMOTE_SESSION); |
| 138 } | 172 } |
| 139 | 173 |
| 140 WTSFreeMemory(buffer); | 174 WTSFreeMemory(buffer); |
| 141 } | 175 } |
| 142 | 176 |
| 143 // static | 177 // static |
| 144 bool NetworkProfileBubble::ShouldCheckNetworkProfile(PrefService* prefs) { | 178 bool NetworkProfileBubble::ShouldCheckNetworkProfile(PrefService* prefs) { |
| 145 if (prefs->GetInteger(prefs::kNetworkProfileWarningsLeft)) | 179 if (prefs->GetInteger(prefs::kNetworkProfileWarningsLeft)) |
| 146 return !notification_shown_; | 180 return !notification_shown_; |
| 147 int64 last_check = prefs->GetInt64(prefs::kNetworkProfileLastWarningTime); | 181 int64 last_check = prefs->GetInt64(prefs::kNetworkProfileLastWarningTime); |
| (...skipping 78 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 226 } | 260 } |
| 227 | 261 |
| 228 gfx::Rect NetworkProfileBubble::GetAnchorRect() { | 262 gfx::Rect NetworkProfileBubble::GetAnchorRect() { |
| 229 // Compensate for padding in anchor. | 263 // Compensate for padding in anchor. |
| 230 gfx::Rect rect(BubbleDelegateView::GetAnchorRect()); | 264 gfx::Rect rect(BubbleDelegateView::GetAnchorRect()); |
| 231 rect.Inset(0, anchor_view() ? kAnchorVerticalInset : 0); | 265 rect.Inset(0, anchor_view() ? kAnchorVerticalInset : 0); |
| 232 return rect; | 266 return rect; |
| 233 } | 267 } |
| 234 | 268 |
| 235 void NetworkProfileBubble::LinkClicked(views::Link* source, int event_flags) { | 269 void NetworkProfileBubble::LinkClicked(views::Link* source, int event_flags) { |
| 236 UMA_HISTOGRAM_COUNTS("NetworkedProfile.LearnMoreClicked", 1); | 270 RecordUmaEvent(METRIC_LEARN_MORE_CLICKED); |
| 237 Browser* browser = BrowserList::GetLastActive(); | 271 Browser* browser = BrowserList::GetLastActive(); |
| 238 if (browser) { | 272 if (browser) { |
| 239 WindowOpenDisposition disposition = | 273 WindowOpenDisposition disposition = |
| 240 event_utils::DispositionFromEventFlags(event_flags); | 274 event_utils::DispositionFromEventFlags(event_flags); |
| 241 content::OpenURLParams params( | 275 content::OpenURLParams params( |
| 242 GURL("https://sites.google.com/a/chromium.org/dev/administrators/" | 276 GURL("https://sites.google.com/a/chromium.org/dev/administrators/" |
| 243 "common-problems-and-solutions#network_profile"), | 277 "common-problems-and-solutions#network_profile"), |
| 244 content::Referrer(), | 278 content::Referrer(), |
| 245 disposition == CURRENT_TAB ? NEW_FOREGROUND_TAB : disposition, | 279 disposition == CURRENT_TAB ? NEW_FOREGROUND_TAB : disposition, |
| 246 content::PAGE_TRANSITION_LINK, false); | 280 content::PAGE_TRANSITION_LINK, false); |
| 247 browser->OpenURL(params); | 281 browser->OpenURL(params); |
| 248 // If the user interacted with the bubble we don't reduce the number of | 282 // If the user interacted with the bubble we don't reduce the number of |
| 249 // warnings left. | 283 // warnings left. |
| 250 PrefService* prefs = browser->profile()->GetPrefs(); | 284 PrefService* prefs = browser->profile()->GetPrefs(); |
| 251 int left_warnings = prefs->GetInteger(prefs::kNetworkProfileWarningsLeft); | 285 int left_warnings = prefs->GetInteger(prefs::kNetworkProfileWarningsLeft); |
| 252 prefs->SetInteger(prefs::kNetworkProfileWarningsLeft, ++left_warnings); | 286 prefs->SetInteger(prefs::kNetworkProfileWarningsLeft, ++left_warnings); |
| 253 } | 287 } |
| 254 GetWidget()->Close(); | 288 GetWidget()->Close(); |
| 255 } | 289 } |
| 256 | 290 |
| 257 void NetworkProfileBubble::ButtonPressed(views::Button* sender, | 291 void NetworkProfileBubble::ButtonPressed(views::Button* sender, |
| 258 const views::Event& event) { | 292 const views::Event& event) { |
| 259 UMA_HISTOGRAM_COUNTS("NetworkedProfile.Acknowledged", 1); | 293 RecordUmaEvent(METRIC_ACKNOWLEDGED); |
| 260 | 294 |
| 261 GetWidget()->Close(); | 295 GetWidget()->Close(); |
| 262 } | 296 } |
| 263 | 297 |
| 264 // static | 298 // static |
| 265 void NetworkProfileBubble::NotifyNetworkProfileDetected() { | 299 void NetworkProfileBubble::NotifyNetworkProfileDetected() { |
| 266 if (BrowserList::GetLastActive() != NULL) | 300 if (BrowserList::GetLastActive() != NULL) |
| 267 ShowNotification(BrowserList::GetLastActive()); | 301 ShowNotification(BrowserList::GetLastActive()); |
| 268 else | 302 else |
| 269 BrowserList::AddObserver(new BrowserListObserver()); | 303 BrowserList::AddObserver(new BrowserListObserver()); |
| 270 } | 304 } |
| OLD | NEW |