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
3// found in the LICENSE file.
4
5#include "remoting/host/usage_stats_consent.h"
6
7#include <windows.h>
8#include <string>
9
10#include "base/logging.h"
11#include "base/strings/stringprintf.h"
12#include "base/win/registry.h"
13#include "remoting/host/win/omaha.h"
14
15namespace {
16
17// The following strings are used to construct the registry key names where
18// we record whether the user has consented to crash dump collection.
19// the user's consent to collect crash dumps is recorded.
20const wchar_t kOmahaClientStateKeyFormat[] =
21    L"Software\\Google\\Update\\%ls\\%ls";
22const wchar_t kOmahaClientState[] = L"ClientState";
23const wchar_t kOmahaClientStateMedium[] = L"ClientStateMedium";
24const wchar_t kOmahaUsagestatsValue[] = L"usagestats";
25
26LONG ReadUsageStatsValue(const wchar_t* state_key, DWORD* usagestats_out) {
27  // presubmit: allow wstring
28  std::wstring client_state = base::StringPrintf(kOmahaClientStateKeyFormat,
29                                                 state_key,
30                                                 remoting::kHostOmahaAppid);
31  base::win::RegKey key;
32  LONG result = key.Open(HKEY_LOCAL_MACHINE, client_state.c_str(), KEY_READ);
33  if (result != ERROR_SUCCESS) {
34    return result;
35  }
36
37  return key.ReadValueDW(kOmahaUsagestatsValue, usagestats_out);
38}
39
40}  // namespace
41
42namespace remoting {
43
44bool GetUsageStatsConsent(bool* allowed, bool* set_by_policy) {
45  // TODO(alexeypa): report whether the consent is set by policy once
46  // supported.
47  *set_by_policy = false;
48
49  // The user's consent to collect crash dumps is recored as the "usagestats"
50  // value in the ClientState or ClientStateMedium key. Probe
51  // the ClientStateMedium key first.
52  DWORD value = 0;
53  if (ReadUsageStatsValue(kOmahaClientStateMedium, &value) == ERROR_SUCCESS) {
54    *allowed = value != 0;
55    return true;
56  }
57  if (ReadUsageStatsValue(kOmahaClientState, &value) == ERROR_SUCCESS) {
58    *allowed = value != 0;
59    return true;
60  }
61
62  // We do not log the error code here because the logging hasn't been
63  // initialized yet.
64  return false;
65}
66
67bool IsUsageStatsAllowed() {
68  bool allowed;
69  bool set_by_policy;
70  return GetUsageStatsConsent(&allowed, &set_by_policy) && allowed;
71}
72
73bool SetUsageStatsConsent(bool allowed) {
74  DWORD value = allowed;
75  // presubmit: allow wstring
76  std::wstring client_state = base::StringPrintf(kOmahaClientStateKeyFormat,
77                                                 kOmahaClientStateMedium,
78                                                 kHostOmahaAppid);
79  base::win::RegKey key;
80  LONG result = key.Create(HKEY_LOCAL_MACHINE, client_state.c_str(),
81                           KEY_SET_VALUE);
82  if (result == ERROR_SUCCESS) {
83    result = key.WriteValue(kOmahaUsagestatsValue, value);
84    if (result == ERROR_SUCCESS) {
85      return true;
86    }
87  }
88
89  PLOG(ERROR) << "Failed to record the user's consent to crash dump reporting";
90  return false;
91}
92
93}  // namespace remoting
94