login_metrics_recorder.cc 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233
  1. // Copyright 2017 The Chromium Authors. All rights reserved.
  2. // Use of this source code is governed by a BSD-style license that can be
  3. // found in the LICENSE file.
  4. #include "ash/metrics/login_metrics_recorder.h"
  5. #include "ash/login/ui/lock_screen.h"
  6. #include "ash/session/session_controller_impl.h"
  7. #include "ash/shell.h"
  8. #include "base/memory/ptr_util.h"
  9. #include "base/metrics/histogram_macros.h"
  10. namespace ash {
  11. namespace {
  12. void LogUserClickOnLock(
  13. LoginMetricsRecorder::LockScreenUserClickTarget target) {
  14. UMA_HISTOGRAM_ENUMERATION(
  15. "Ash.Login.Lock.UserClicks", target,
  16. LoginMetricsRecorder::LockScreenUserClickTarget::kTargetCount);
  17. }
  18. void LogUserClickOnLogin(
  19. LoginMetricsRecorder::LoginScreenUserClickTarget target) {
  20. UMA_HISTOGRAM_ENUMERATION(
  21. "Ash.Login.Login.UserClicks", target,
  22. LoginMetricsRecorder::LoginScreenUserClickTarget::kTargetCount);
  23. }
  24. void LogUserClickInOobe(LoginMetricsRecorder::OobeUserClickTarget target) {
  25. UMA_HISTOGRAM_ENUMERATION(
  26. "Ash.Login.OOBE.UserClicks", target,
  27. LoginMetricsRecorder::OobeUserClickTarget::kTargetCount);
  28. }
  29. // Defines mapping of ShelfButtonClickTarget |original| to different UMA target
  30. // in different session state.
  31. struct ShelfButtonClickMapping {
  32. LoginMetricsRecorder::ShelfButtonClickTarget original;
  33. LoginMetricsRecorder::LockScreenUserClickTarget lock;
  34. LoginMetricsRecorder::LoginScreenUserClickTarget login;
  35. LoginMetricsRecorder::OobeUserClickTarget oobe;
  36. };
  37. // |kTargetCount| is used to mark the click target as unexpected.
  38. const ShelfButtonClickMapping kShelfTargets[] = {
  39. // |kShutDownButton|
  40. {LoginMetricsRecorder::ShelfButtonClickTarget::kShutDownButton,
  41. LoginMetricsRecorder::LockScreenUserClickTarget::kShutDownButton,
  42. LoginMetricsRecorder::LoginScreenUserClickTarget::kShutDownButton,
  43. LoginMetricsRecorder::OobeUserClickTarget::kShutDownButton},
  44. // |kRestartButton|
  45. {LoginMetricsRecorder::ShelfButtonClickTarget::kRestartButton,
  46. LoginMetricsRecorder::LockScreenUserClickTarget::kRestartButton,
  47. LoginMetricsRecorder::LoginScreenUserClickTarget::kRestartButton,
  48. LoginMetricsRecorder::OobeUserClickTarget::kTargetCount},
  49. // |kSignOutButton|
  50. {LoginMetricsRecorder::ShelfButtonClickTarget::kSignOutButton,
  51. LoginMetricsRecorder::LockScreenUserClickTarget::kSignOutButton,
  52. LoginMetricsRecorder::LoginScreenUserClickTarget::kTargetCount,
  53. LoginMetricsRecorder::OobeUserClickTarget::kTargetCount},
  54. // |kBrowseAsGuestButton|
  55. {LoginMetricsRecorder::ShelfButtonClickTarget::kBrowseAsGuestButton,
  56. LoginMetricsRecorder::LockScreenUserClickTarget::kTargetCount,
  57. LoginMetricsRecorder::LoginScreenUserClickTarget::kBrowseAsGuestButton,
  58. LoginMetricsRecorder::OobeUserClickTarget::kBrowseAsGuestButton},
  59. // |kAddUserButton|
  60. {LoginMetricsRecorder::ShelfButtonClickTarget::kAddUserButton,
  61. LoginMetricsRecorder::LockScreenUserClickTarget::kTargetCount,
  62. LoginMetricsRecorder::LoginScreenUserClickTarget::kAddUserButton,
  63. LoginMetricsRecorder::OobeUserClickTarget::kTargetCount},
  64. // |kCloseNoteButton|
  65. {LoginMetricsRecorder::ShelfButtonClickTarget::kCloseNoteButton,
  66. LoginMetricsRecorder::LockScreenUserClickTarget::kCloseNoteButton,
  67. LoginMetricsRecorder::LoginScreenUserClickTarget::kTargetCount,
  68. LoginMetricsRecorder::OobeUserClickTarget::kTargetCount},
  69. // |kParentAccessButton|
  70. {LoginMetricsRecorder::ShelfButtonClickTarget::kParentAccessButton,
  71. LoginMetricsRecorder::LockScreenUserClickTarget::kParentAccessButton,
  72. LoginMetricsRecorder::LoginScreenUserClickTarget::kTargetCount,
  73. LoginMetricsRecorder::OobeUserClickTarget::kTargetCount},
  74. // |kEnterpriseEnrollmentButton|
  75. {LoginMetricsRecorder::ShelfButtonClickTarget::kEnterpriseEnrollmentButton,
  76. LoginMetricsRecorder::LockScreenUserClickTarget::kTargetCount,
  77. LoginMetricsRecorder::LoginScreenUserClickTarget::kTargetCount,
  78. LoginMetricsRecorder::OobeUserClickTarget::kEnterpriseEnrollmentButton},
  79. // |kOsInstallButton|
  80. {LoginMetricsRecorder::ShelfButtonClickTarget::kOsInstallButton,
  81. LoginMetricsRecorder::LockScreenUserClickTarget::kTargetCount,
  82. LoginMetricsRecorder::LoginScreenUserClickTarget::kOsInstallButton,
  83. LoginMetricsRecorder::OobeUserClickTarget::kOsInstallButton},
  84. // |kSignIn|
  85. {LoginMetricsRecorder::ShelfButtonClickTarget::kSignIn,
  86. LoginMetricsRecorder::LockScreenUserClickTarget::kTargetCount,
  87. LoginMetricsRecorder::LoginScreenUserClickTarget::kTargetCount,
  88. LoginMetricsRecorder::OobeUserClickTarget::kSignIn},
  89. };
  90. // Defines mapping of TrayClickTarget |original| to different UMA target in
  91. // different session state.
  92. struct TrayClickMapping {
  93. LoginMetricsRecorder::TrayClickTarget original;
  94. LoginMetricsRecorder::LockScreenUserClickTarget lock;
  95. LoginMetricsRecorder::LoginScreenUserClickTarget login;
  96. LoginMetricsRecorder::OobeUserClickTarget oobe;
  97. };
  98. // |kTargetCount| is used to mark the click target as unexpected.
  99. const TrayClickMapping kTrayTargets[] = {
  100. // |kSystemTray|
  101. {LoginMetricsRecorder::TrayClickTarget::kSystemTray,
  102. LoginMetricsRecorder::LockScreenUserClickTarget::kSystemTray,
  103. LoginMetricsRecorder::LoginScreenUserClickTarget::kSystemTray,
  104. LoginMetricsRecorder::OobeUserClickTarget::kSystemTray},
  105. // |kVirtualKeyboardTray|
  106. {LoginMetricsRecorder::TrayClickTarget::kVirtualKeyboardTray,
  107. LoginMetricsRecorder::LockScreenUserClickTarget::kVirtualKeyboardTray,
  108. LoginMetricsRecorder::LoginScreenUserClickTarget::kVirtualKeyboardTray,
  109. LoginMetricsRecorder::OobeUserClickTarget::kVirtualKeyboardTray},
  110. // |kImeTray|
  111. {LoginMetricsRecorder::TrayClickTarget::kImeTray,
  112. LoginMetricsRecorder::LockScreenUserClickTarget::kImeTray,
  113. LoginMetricsRecorder::LoginScreenUserClickTarget::kImeTray,
  114. LoginMetricsRecorder::OobeUserClickTarget::kImeTray},
  115. // |kNotificationTray|
  116. {LoginMetricsRecorder::TrayClickTarget::kNotificationTray,
  117. LoginMetricsRecorder::LockScreenUserClickTarget::kNotificationTray,
  118. LoginMetricsRecorder::LoginScreenUserClickTarget::kTargetCount,
  119. LoginMetricsRecorder::OobeUserClickTarget::kTargetCount},
  120. // |kTrayActionNoteButton|
  121. {LoginMetricsRecorder::TrayClickTarget::kTrayActionNoteButton,
  122. LoginMetricsRecorder::LockScreenUserClickTarget::kTrayActionNoteButton,
  123. LoginMetricsRecorder::LoginScreenUserClickTarget::kTargetCount,
  124. LoginMetricsRecorder::OobeUserClickTarget::kTargetCount},
  125. };
  126. bool ShouldRecordMetrics() {
  127. session_manager::SessionState session_state =
  128. Shell::Get()->session_controller()->GetSessionState();
  129. return session_state == session_manager::SessionState::LOGIN_PRIMARY ||
  130. session_state == session_manager::SessionState::LOCKED ||
  131. session_state == session_manager::SessionState::OOBE;
  132. }
  133. } // namespace
  134. LoginMetricsRecorder::LoginMetricsRecorder() = default;
  135. LoginMetricsRecorder::~LoginMetricsRecorder() = default;
  136. void LoginMetricsRecorder::RecordNumLoginAttempts(bool success,
  137. int* num_attempt) {
  138. if (success) {
  139. UMA_HISTOGRAM_COUNTS_100("Ash.Login.Lock.NbPasswordAttempts.UntilSuccess",
  140. *num_attempt);
  141. } else if (*num_attempt > 0) {
  142. UMA_HISTOGRAM_COUNTS_100("Ash.Login.Lock.NbPasswordAttempts.UntilFailure",
  143. *num_attempt);
  144. }
  145. *num_attempt = 0;
  146. }
  147. void LoginMetricsRecorder::RecordUserTrayClick(TrayClickTarget target) {
  148. if (!ShouldRecordMetrics())
  149. return;
  150. auto state = Shell::Get()->session_controller()->GetSessionState();
  151. for (const auto& el : kTrayTargets) {
  152. if (el.original != target)
  153. continue;
  154. switch (state) {
  155. case session_manager::SessionState::LOCKED:
  156. DCHECK(el.lock != LockScreenUserClickTarget::kTargetCount)
  157. << "Not expected tray click target: " << static_cast<int>(target)
  158. << " for session state: " << static_cast<int>(state);
  159. LogUserClickOnLock(el.lock);
  160. return;
  161. case session_manager::SessionState::LOGIN_PRIMARY:
  162. DCHECK(el.login != LoginScreenUserClickTarget::kTargetCount)
  163. << "Not expected tray click target: " << static_cast<int>(target)
  164. << " for session state: " << static_cast<int>(state);
  165. LogUserClickOnLogin(el.login);
  166. return;
  167. case session_manager::SessionState::OOBE:
  168. DCHECK(el.oobe != OobeUserClickTarget::kTargetCount)
  169. << "Not expected tray click target: " << static_cast<int>(target)
  170. << " for session state: " << static_cast<int>(state);
  171. LogUserClickInOobe(el.oobe);
  172. return;
  173. default:
  174. NOTREACHED() << "Unexpected session state: " << static_cast<int>(state);
  175. return;
  176. }
  177. }
  178. NOTREACHED() << "Tray click target wasn't found in the |kTrayTargets|.";
  179. }
  180. void LoginMetricsRecorder::RecordUserShelfButtonClick(
  181. ShelfButtonClickTarget target) {
  182. if (!ShouldRecordMetrics())
  183. return;
  184. auto state = Shell::Get()->session_controller()->GetSessionState();
  185. for (const auto& el : kShelfTargets) {
  186. if (el.original != target)
  187. continue;
  188. switch (state) {
  189. case session_manager::SessionState::LOCKED:
  190. DCHECK(el.lock != LockScreenUserClickTarget::kTargetCount)
  191. << "Not expected shelf click target: " << static_cast<int>(target)
  192. << " for session state: " << static_cast<int>(state);
  193. LogUserClickOnLock(el.lock);
  194. return;
  195. case session_manager::SessionState::LOGIN_PRIMARY:
  196. DCHECK(el.login != LoginScreenUserClickTarget::kTargetCount)
  197. << "Not expected shelf click target: " << static_cast<int>(target)
  198. << " for session state: " << static_cast<int>(state);
  199. LogUserClickOnLogin(el.login);
  200. return;
  201. case session_manager::SessionState::OOBE:
  202. DCHECK(el.oobe != OobeUserClickTarget::kTargetCount)
  203. << "Not expected shelf click target: " << static_cast<int>(target)
  204. << " for session state: " << static_cast<int>(state);
  205. LogUserClickInOobe(el.oobe);
  206. return;
  207. default:
  208. NOTREACHED() << "Unexpected session state: " << static_cast<int>(state);
  209. return;
  210. }
  211. }
  212. NOTREACHED() << "Shelf click target wasn't found in the |kShelfTargets|.";
  213. }
  214. } // namespace ash