1 // Copyright 2020 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 5 #include "chrome/browser/supervised_user/supervised_user_extensions_metrics_recorder.h" 6 7 #include "base/check.h" 8 #include "base/metrics/histogram_functions.h" 9 #include "base/metrics/user_metrics.h" 10 #include "base/time/default_tick_clock.h" 11 12 // static 13 const char SupervisedUserExtensionsMetricsRecorder::kExtensionsHistogramName[] = 14 "SupervisedUsers.Extensions2"; 15 const char 16 SupervisedUserExtensionsMetricsRecorder::kApprovalGrantedActionName[] = 17 "SupervisedUsers_Extensions_ApprovalGranted"; 18 const char SupervisedUserExtensionsMetricsRecorder:: 19 kPermissionsIncreaseGrantedActionName[] = 20 "SupervisedUsers_Extensions_PermissionsIncreaseGranted"; 21 const char 22 SupervisedUserExtensionsMetricsRecorder::kApprovalRemovedActionName[] = 23 "SupervisedUsers_Extensions_ApprovalRemoved"; 24 // Extension Install Dialog. 25 const char SupervisedUserExtensionsMetricsRecorder:: 26 kExtensionInstallDialogHistogramName[] = 27 "SupervisedUsers.ExtensionInstallDialog"; 28 const char SupervisedUserExtensionsMetricsRecorder:: 29 kExtensionInstallDialogAskedParentTimeHistogramName[] = 30 "SupervisedUsers.ExtensionInstallDialog.AskedParentUserTime"; 31 const char SupervisedUserExtensionsMetricsRecorder:: 32 kExtensionInstallDialogChildCanceledTimeHistogramName[] = 33 "SupervisedUsers.ExtensionInstallDialog.ChildCanceledUserTime"; 34 const char SupervisedUserExtensionsMetricsRecorder:: 35 kExtensionInstallDialogOpenedActionName[] = 36 "SupervisedUsers_Extensions_ExtensionInstallDialog_Opened"; 37 const char SupervisedUserExtensionsMetricsRecorder:: 38 kExtensionInstallDialogAskedParentActionName[] = 39 "SupervisedUsers_Extensions_ExtensionInstallDialog_AskedParent"; 40 const char SupervisedUserExtensionsMetricsRecorder:: 41 kExtensionInstallDialogChildCanceledActionName[] = 42 "SupervisedUsers_Extensions_ExtensionInstallDialog_ChildCanceled"; 43 // Parent Permission Dialog. 44 const char SupervisedUserExtensionsMetricsRecorder:: 45 kParentPermissionDialogHistogramName[] = 46 "SupervisedUsers.ParentPermissionDialog"; 47 const char SupervisedUserExtensionsMetricsRecorder:: 48 kParentPermissionDialogParentApprovedTimeHistogramName[] = 49 "SupervisedUsers.ParentPermissionDialog.ParentApprovedUserTime"; 50 const char SupervisedUserExtensionsMetricsRecorder:: 51 kParentPermissionDialogParentCanceledTimeHistogramName[] = 52 "SupervisedUsers.ParentPermissionDialog.ParentCanceledUserTime"; 53 const char SupervisedUserExtensionsMetricsRecorder:: 54 kParentPermissionDialogFailedTimeHistogramName[] = 55 "SupervisedUsers.ParentPermissionDialog.FailedUserTime"; 56 const char SupervisedUserExtensionsMetricsRecorder:: 57 kParentPermissionDialogOpenedActionName[] = 58 "SupervisedUsers_Extensions_ParentPermissionDialog_Opened"; 59 const char SupervisedUserExtensionsMetricsRecorder:: 60 kParentPermissionDialogParentApprovedActionName[] = 61 "SupervisedUsers_Extensions_ParentPermissionDialog_ParentApproved"; 62 const char SupervisedUserExtensionsMetricsRecorder:: 63 kParentPermissionDialogParentCanceledActionName[] = 64 "SupervisedUsers_Extensions_ParentPermissionDialog_ParentCanceled"; 65 // Enabling and disabling extensions. 66 const char SupervisedUserExtensionsMetricsRecorder::kEnablementHistogramName[] = 67 "SupervisedUsers.ExtensionEnablement"; 68 const char SupervisedUserExtensionsMetricsRecorder::kEnabledActionName[] = 69 "SupervisedUsers_Extensions_Enabled"; 70 const char SupervisedUserExtensionsMetricsRecorder::kDisabledActionName[] = 71 "SupervisedUsers_Extensions_Disabled"; 72 const char 73 SupervisedUserExtensionsMetricsRecorder::kFailedToEnableActionName[] = 74 "SupervisedUsers_Extensions_FailedToEnable"; 75 76 SupervisedUserExtensionsMetricsRecorder:: SupervisedUserExtensionsMetricsRecorder()77 SupervisedUserExtensionsMetricsRecorder() 78 : clock_(base::DefaultTickClock::GetInstance()) {} 79 OnDialogOpened()80void SupervisedUserExtensionsMetricsRecorder::OnDialogOpened() { 81 RecordExtensionInstallDialogUmaMetrics(ExtensionInstallDialogState::kOpened); 82 } 83 OnDialogAccepted()84void SupervisedUserExtensionsMetricsRecorder::OnDialogAccepted() { 85 RecordExtensionInstallDialogUmaMetrics( 86 ExtensionInstallDialogState::kAskedParent); 87 } 88 OnDialogCanceled()89void SupervisedUserExtensionsMetricsRecorder::OnDialogCanceled() { 90 RecordExtensionInstallDialogUmaMetrics( 91 ExtensionInstallDialogState::kChildCanceled); 92 } 93 94 // static RecordExtensionsUmaMetrics(UmaExtensionState state)95void SupervisedUserExtensionsMetricsRecorder::RecordExtensionsUmaMetrics( 96 UmaExtensionState state) { 97 base::UmaHistogramEnumeration(kExtensionsHistogramName, state); 98 switch (state) { 99 case UmaExtensionState::kApprovalGranted: 100 // Record UMA metrics for custodian approval for a new extension. 101 base::RecordAction(base::UserMetricsAction(kApprovalGrantedActionName)); 102 break; 103 case UmaExtensionState::kPermissionsIncreaseGranted: 104 // Record UMA metrics for child approval for a newer version of an 105 // existing extension with increased permissions. 106 base::RecordAction( 107 base::UserMetricsAction(kPermissionsIncreaseGrantedActionName)); 108 break; 109 case UmaExtensionState::kApprovalRemoved: 110 // Record UMA metrics for removing an extension. 111 base::RecordAction(base::UserMetricsAction(kApprovalRemovedActionName)); 112 break; 113 } 114 } 115 116 void SupervisedUserExtensionsMetricsRecorder:: RecordExtensionInstallDialogUmaMetrics(ExtensionInstallDialogState state)117 RecordExtensionInstallDialogUmaMetrics(ExtensionInstallDialogState state) { 118 base::UmaHistogramEnumeration(kExtensionInstallDialogHistogramName, state); 119 switch (state) { 120 case ExtensionInstallDialogState::kOpened: 121 base::RecordAction( 122 base::UserMetricsAction(kExtensionInstallDialogOpenedActionName)); 123 start_time_ = clock_->NowTicks(); 124 break; 125 case ExtensionInstallDialogState::kAskedParent: 126 base::RecordAction(base::UserMetricsAction( 127 kExtensionInstallDialogAskedParentActionName)); 128 RecordUserTime(kExtensionInstallDialogAskedParentTimeHistogramName); 129 break; 130 case ExtensionInstallDialogState::kChildCanceled: 131 base::RecordAction(base::UserMetricsAction( 132 kExtensionInstallDialogChildCanceledActionName)); 133 RecordUserTime(kExtensionInstallDialogChildCanceledTimeHistogramName); 134 break; 135 } 136 } 137 138 void SupervisedUserExtensionsMetricsRecorder:: RecordParentPermissionDialogUmaMetrics(ParentPermissionDialogState state)139 RecordParentPermissionDialogUmaMetrics(ParentPermissionDialogState state) { 140 base::UmaHistogramEnumeration(kParentPermissionDialogHistogramName, state); 141 switch (state) { 142 case ParentPermissionDialogState::kOpened: 143 base::RecordAction( 144 base::UserMetricsAction(kParentPermissionDialogOpenedActionName)); 145 start_time_ = clock_->NowTicks(); 146 break; 147 case ParentPermissionDialogState::kParentApproved: 148 base::RecordAction(base::UserMetricsAction( 149 kParentPermissionDialogParentApprovedActionName)); 150 RecordUserTime(kParentPermissionDialogParentApprovedTimeHistogramName); 151 break; 152 case ParentPermissionDialogState::kParentCanceled: 153 base::RecordAction(base::UserMetricsAction( 154 kParentPermissionDialogParentCanceledActionName)); 155 RecordUserTime(kParentPermissionDialogParentCanceledTimeHistogramName); 156 break; 157 case ParentPermissionDialogState::kFailed: 158 RecordUserTime(kParentPermissionDialogFailedTimeHistogramName); 159 break; 160 case ParentPermissionDialogState::kNoParentError: 161 // Nothing to do here. 162 break; 163 } 164 } 165 166 // static RecordEnablementUmaMetrics(EnablementState state)167void SupervisedUserExtensionsMetricsRecorder::RecordEnablementUmaMetrics( 168 EnablementState state) { 169 base::UmaHistogramEnumeration(kEnablementHistogramName, state); 170 switch (state) { 171 case EnablementState::kEnabled: 172 base::RecordAction(base::UserMetricsAction(kEnabledActionName)); 173 break; 174 case EnablementState::kDisabled: 175 base::RecordAction(base::UserMetricsAction(kDisabledActionName)); 176 break; 177 case EnablementState::kFailedToEnable: 178 base::RecordAction(base::UserMetricsAction(kFailedToEnableActionName)); 179 break; 180 } 181 } 182 SetClockForTesting(const base::TickClock * tick_clock)183void SupervisedUserExtensionsMetricsRecorder::SetClockForTesting( 184 const base::TickClock* tick_clock) { 185 clock_ = tick_clock; 186 } 187 RecordUserTime(const std::string & metric_name) const188void SupervisedUserExtensionsMetricsRecorder::RecordUserTime( 189 const std::string& metric_name) const { 190 DCHECK(!start_time_.is_null()) << "start_time_ has not been initialized."; 191 base::TimeDelta duration = clock_->NowTicks() - start_time_; 192 base::UmaHistogramLongTimes(metric_name, duration); 193 } 194