123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309 |
- // Copyright 2020 The Chromium Authors. All rights reserved.
- // Use of this source code is governed by a BSD-style license that can be
- // found in the LICENSE file.
- #include "ash/child_accounts/parent_access_controller_impl.h"
- #include <string>
- #include "ash/login/login_screen_controller.h"
- #include "ash/session/session_controller_impl.h"
- #include "ash/shell.h"
- #include "ash/strings/grit/ash_strings.h"
- #include "base/bind.h"
- #include "base/check.h"
- #include "base/metrics/histogram_functions.h"
- #include "base/metrics/histogram_macros.h"
- #include "base/strings/string_util.h"
- #include "components/session_manager/session_manager_types.h"
- #include "ui/base/l10n/l10n_util.h"
- namespace ash {
- namespace {
- // Number of digits displayed in parent access code input.
- constexpr int kParentAccessCodePinLength = 6;
- // Base name of the histogram to log parent access code validation result.
- constexpr char kUMAParentAccessCodeValidationResultBase[] =
- "Supervision.ParentAccessCode.ValidationResult";
- // Suffix of the histogram to log aggregated parent access code validation
- // results.
- constexpr char kUMAValidationResultSuffixAll[] = "All";
- // Suffix of the histogram to log parent access code validation results for
- // reauth flow.
- constexpr char kUMAValidationResultSuffixReauth[] = "Reauth";
- // Suffix of the histogram to log parent access code validation results for add
- // user flow.
- constexpr char kUMAValidationResultSuffixAddUser[] = "AddUser";
- // Suffix of the histogram to log parent access code validation results for time
- // limits override.
- constexpr char kUMAValidationResultSuffixTimeLimits[] = "TimeLimits";
- // Suffix of the histogram to log parent access code validation results for
- // timezone change.
- constexpr char kUMAValidationResultSuffixTimezone[] = "TimezoneChange";
- // Suffix of the histogram to log parent access code validation results for
- // clock change.
- constexpr char kUMAValidationResultSuffixClock[] = "ClockChange";
- std::u16string GetTitle(SupervisedAction action) {
- int title_id;
- switch (action) {
- case SupervisedAction::kUnlockTimeLimits:
- title_id = IDS_ASH_LOGIN_PARENT_ACCESS_TITLE;
- break;
- case SupervisedAction::kUpdateClock:
- title_id = IDS_ASH_LOGIN_PARENT_ACCESS_TITLE_CHANGE_TIME;
- break;
- case SupervisedAction::kUpdateTimezone:
- title_id = IDS_ASH_LOGIN_PARENT_ACCESS_TITLE_CHANGE_TIMEZONE;
- break;
- case SupervisedAction::kAddUser:
- case SupervisedAction::kReauth:
- title_id = IDS_ASH_LOGIN_PARENT_ACCESS_GENERIC_TITLE;
- break;
- }
- return l10n_util::GetStringUTF16(title_id);
- }
- std::u16string GetDescription(SupervisedAction action) {
- int description_id;
- switch (action) {
- case SupervisedAction::kUnlockTimeLimits:
- description_id = IDS_ASH_LOGIN_PARENT_ACCESS_DESCRIPTION;
- break;
- case SupervisedAction::kUpdateClock:
- case SupervisedAction::kUpdateTimezone:
- description_id = IDS_ASH_LOGIN_PARENT_ACCESS_GENERIC_DESCRIPTION;
- break;
- case SupervisedAction::kAddUser:
- description_id = IDS_ASH_LOGIN_PARENT_ACCESS_DESCRIPTION_ADD_USER;
- break;
- case SupervisedAction::kReauth:
- description_id = IDS_ASH_LOGIN_PARENT_ACCESS_DESCRIPTION_REAUTH;
- break;
- }
- return l10n_util::GetStringUTF16(description_id);
- }
- std::u16string GetAccessibleTitle() {
- return l10n_util::GetStringUTF16(IDS_ASH_LOGIN_PARENT_ACCESS_DIALOG_NAME);
- }
- void RecordParentCodeValidationResultToHistogram(
- ParentCodeValidationResult result,
- const std::string& histogram_name) {
- DCHECK(!histogram_name.empty());
- switch (result) {
- case ParentCodeValidationResult::kValid:
- base::UmaHistogramEnumeration(
- histogram_name,
- ParentAccessControllerImpl::UMAValidationResult::kValid);
- return;
- case ParentCodeValidationResult::kInvalid:
- base::UmaHistogramEnumeration(
- histogram_name,
- ParentAccessControllerImpl::UMAValidationResult::kInvalid);
- return;
- case ParentCodeValidationResult::kNoConfig:
- base::UmaHistogramEnumeration(
- histogram_name,
- ParentAccessControllerImpl::UMAValidationResult::kNoConfig);
- return;
- case ParentCodeValidationResult::kInternalError:
- base::UmaHistogramEnumeration(
- histogram_name,
- ParentAccessControllerImpl::UMAValidationResult::kInternalError);
- return;
- }
- }
- void RecordParentCodeValidationResult(ParentCodeValidationResult result,
- SupervisedAction action) {
- // Record to the action specific histogram.
- const std::string action_result_histogram =
- ParentAccessControllerImpl::GetUMAParentCodeValidationResultHistorgam(
- action);
- RecordParentCodeValidationResultToHistogram(result, action_result_histogram);
- // Record the action to the aggregated histogram.
- const std::string all_results_histogram =
- ParentAccessControllerImpl::GetUMAParentCodeValidationResultHistorgam(
- absl::nullopt);
- RecordParentCodeValidationResultToHistogram(result, all_results_histogram);
- }
- } // namespace
- // static
- constexpr char ParentAccessControllerImpl::kUMAParentAccessCodeAction[];
- // static
- constexpr char ParentAccessControllerImpl::kUMAParentAccessCodeUsage[];
- // static
- std::string
- ParentAccessControllerImpl::GetUMAParentCodeValidationResultHistorgam(
- absl::optional<SupervisedAction> action) {
- const std::string separator = ".";
- if (!action) {
- return base::JoinString({kUMAParentAccessCodeValidationResultBase,
- kUMAValidationResultSuffixAll},
- separator);
- }
- switch (action.value()) {
- case SupervisedAction::kUnlockTimeLimits:
- return base::JoinString({kUMAParentAccessCodeValidationResultBase,
- kUMAValidationResultSuffixTimeLimits},
- separator);
- case SupervisedAction::kAddUser:
- return base::JoinString({kUMAParentAccessCodeValidationResultBase,
- kUMAValidationResultSuffixAddUser},
- separator);
- case SupervisedAction::kReauth:
- return base::JoinString({kUMAParentAccessCodeValidationResultBase,
- kUMAValidationResultSuffixReauth},
- separator);
- case SupervisedAction::kUpdateTimezone:
- return base::JoinString({kUMAParentAccessCodeValidationResultBase,
- kUMAValidationResultSuffixTimezone},
- separator);
- case SupervisedAction::kUpdateClock:
- return base::JoinString({kUMAParentAccessCodeValidationResultBase,
- kUMAValidationResultSuffixClock},
- separator);
- }
- }
- ParentAccessControllerImpl::ParentAccessControllerImpl() = default;
- ParentAccessControllerImpl::~ParentAccessControllerImpl() = default;
- void RecordParentAccessAction(ParentAccessControllerImpl::UMAAction action) {
- UMA_HISTOGRAM_ENUMERATION(
- ParentAccessControllerImpl::kUMAParentAccessCodeAction, action);
- }
- void RecordParentAccessUsage(const AccountId& child_account_id,
- SupervisedAction action) {
- switch (action) {
- case SupervisedAction::kUnlockTimeLimits: {
- UMA_HISTOGRAM_ENUMERATION(
- ParentAccessControllerImpl::kUMAParentAccessCodeUsage,
- ParentAccessControllerImpl::UMAUsage::kTimeLimits);
- return;
- }
- case SupervisedAction::kUpdateClock: {
- bool is_login = Shell::Get()->session_controller()->GetSessionState() ==
- session_manager::SessionState::LOGIN_PRIMARY;
- UMA_HISTOGRAM_ENUMERATION(
- ParentAccessControllerImpl::kUMAParentAccessCodeUsage,
- is_login
- ? ParentAccessControllerImpl::UMAUsage::kTimeChangeLoginScreen
- : ParentAccessControllerImpl::UMAUsage::kTimeChangeInSession);
- return;
- }
- case SupervisedAction::kUpdateTimezone: {
- UMA_HISTOGRAM_ENUMERATION(
- ParentAccessControllerImpl::kUMAParentAccessCodeUsage,
- ParentAccessControllerImpl::UMAUsage::kTimezoneChange);
- return;
- }
- case SupervisedAction::kAddUser:
- UMA_HISTOGRAM_ENUMERATION(
- ParentAccessControllerImpl::kUMAParentAccessCodeUsage,
- ParentAccessControllerImpl::UMAUsage::kAddUserLoginScreen);
- return;
- case SupervisedAction::kReauth:
- UMA_HISTOGRAM_ENUMERATION(
- ParentAccessControllerImpl::kUMAParentAccessCodeUsage,
- ParentAccessControllerImpl::UMAUsage::kReauhLoginScreen);
- return;
- }
- NOTREACHED() << "Unknown SupervisedAction";
- }
- PinRequestView::SubmissionResult ParentAccessControllerImpl::OnPinSubmitted(
- const std::string& pin) {
- ParentCodeValidationResult pin_validation_result =
- Shell::Get()->login_screen_controller()->ValidateParentAccessCode(
- account_id_, validation_time_, pin);
- RecordParentCodeValidationResult(pin_validation_result, action_);
- if (pin_validation_result == ParentCodeValidationResult::kValid) {
- VLOG(1) << "Parent access code successfully validated";
- RecordParentAccessAction(
- ParentAccessControllerImpl::UMAAction::kValidationSuccess);
- return PinRequestView::SubmissionResult::kPinAccepted;
- }
- VLOG(1) << "Invalid parent access code entered";
- RecordParentAccessAction(
- ParentAccessControllerImpl::UMAAction::kValidationError);
- PinRequestWidget::Get()->UpdateState(
- PinRequestViewState::kError,
- l10n_util::GetStringUTF16(IDS_ASH_LOGIN_PARENT_ACCESS_TITLE_ERROR),
- GetDescription(action_));
- return PinRequestView::SubmissionResult::kPinError;
- }
- void ParentAccessControllerImpl::OnBack() {
- RecordParentAccessAction(
- ParentAccessControllerImpl::UMAAction::kCanceledByUser);
- }
- void ParentAccessControllerImpl::OnHelp() {
- RecordParentAccessAction(ParentAccessControllerImpl::UMAAction::kGetHelp);
- // TODO(https://crbug.com/999387): Remove this when handling touch
- // cancellation is fixed for system modal windows.
- base::ThreadTaskRunnerHandle::Get()->PostTask(
- FROM_HERE, base::BindOnce([]() {
- Shell::Get()->login_screen_controller()->ShowParentAccessHelpApp();
- }));
- }
- bool ParentAccessControllerImpl::ShowWidget(
- const AccountId& child_account_id,
- PinRequest::OnPinRequestDone on_exit_callback,
- SupervisedAction action,
- bool extra_dimmer,
- base::Time validation_time) {
- if (PinRequestWidget::Get())
- return false;
- // When there is no logged in user we should accept parent access code for any
- // of child account added to the device.
- const auto session_state =
- Shell::Get()->session_controller()->GetSessionState();
- const bool user_in_session =
- session_state == session_manager::SessionState::LOGGED_IN_NOT_ACTIVE ||
- session_state == session_manager::SessionState::ACTIVE ||
- session_state == session_manager::SessionState::LOCKED;
- DCHECK(user_in_session || child_account_id.empty());
- account_id_ = child_account_id;
- action_ = action;
- validation_time_ = validation_time;
- PinRequest request;
- request.on_pin_request_done = std::move(on_exit_callback);
- request.help_button_enabled = true;
- request.extra_dimmer = extra_dimmer;
- request.pin_length = kParentAccessCodePinLength;
- request.obscure_pin = false;
- request.title = GetTitle(action);
- request.description = GetDescription(action);
- request.accessible_title = GetAccessibleTitle();
- PinRequestWidget::Show(std::move(request), this);
- RecordParentAccessUsage(account_id_, action);
- return true;
- }
- } // namespace ash
|