summaryrefslogtreecommitdiffstats
path: root/base/win/metro.cc
blob: c806f62de0632940ceedd8cde1514c82bf7d334f (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
// Copyright (c) 2012 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 "base/win/metro.h"

#include "base/message_loop.h"
#include "base/string_util.h"
#include "base/win/scoped_comptr.h"
#include "base/win/windows_version.h"

namespace base {
namespace win {

const char kActivateApplication[] = "ActivateApplication";

HMODULE GetMetroModule() {
  const HMODULE kUninitialized = reinterpret_cast<HMODULE>(1);
  static HMODULE metro_module = kUninitialized;

  if (metro_module == kUninitialized) {
    // Initialize the cache, note that the initialization is idempotent
    // under the assumption that metro_driver is never unloaded, so the
    // race to this assignment is safe.
    metro_module = GetModuleHandleA("metro_driver.dll");
    if (metro_module != NULL) {
      // This must be a metro process if the metro_driver is loaded.
      DCHECK(IsMetroProcess());
    }
  }

  DCHECK(metro_module != kUninitialized);
  return metro_module;
}

bool IsMetroProcess() {
  enum ImmersiveState {
    kImmersiveUnknown,
    kImmersiveTrue,
    kImmersiveFalse
  };
  typedef BOOL (WINAPI* IsImmersiveProcessFunc)(HANDLE process);

  // The immersive state of a process can never change.
  // Look it up once and cache it here.
  static ImmersiveState state = kImmersiveUnknown;

  if (state == kImmersiveUnknown) {
    // The lookup hasn't been done yet. Note that the code below here is
    // idempotent, so it doesn't matter if it races to assignment on multiple
    // threads.
    HMODULE user32 = ::GetModuleHandleA("user32.dll");
    DCHECK(user32 != NULL);

    IsImmersiveProcessFunc is_immersive_process =
        reinterpret_cast<IsImmersiveProcessFunc>(
            ::GetProcAddress(user32, "IsImmersiveProcess"));

    if (is_immersive_process != NULL) {
      if (is_immersive_process(::GetCurrentProcess())) {
        state = kImmersiveTrue;
      } else {
        state = kImmersiveFalse;
      }
    } else {
      // No "IsImmersiveProcess" export on user32.dll, so this is pre-Windows8
      // and therefore not immersive.
      state = kImmersiveFalse;
    }
  }
  DCHECK_NE(kImmersiveUnknown, state);

  return state == kImmersiveTrue;
}

bool IsTsfAwareRequired() {
  // Although this function is equal to IsMetroProcess at this moment,
  // Chrome for Win7 and Vista may support TSF in the future.
  return IsMetroProcess();
}

wchar_t* LocalAllocAndCopyString(const string16& src) {
  size_t dest_size = (src.length() + 1) * sizeof(wchar_t);
  wchar_t* dest = reinterpret_cast<wchar_t*>(LocalAlloc(LPTR, dest_size));
  base::wcslcpy(dest, src.c_str(), dest_size);
  return dest;
}

bool IsTouchEnabled() {
  int value = GetSystemMetrics(SM_DIGITIZER);
  return value & (NID_READY | NID_INTEGRATED_TOUCH) ==
             (NID_READY | NID_INTEGRATED_TOUCH);
}

bool IsParentalControlActivityLoggingOn() {
  // Query this info on Windows Vista and above.
  if (base::win::GetVersion() < base::win::VERSION_VISTA)
    return false;

  static bool parental_control_logging_required = false;
  static bool parental_control_status_determined = false;

  if (parental_control_status_determined)
    return parental_control_logging_required;

  parental_control_status_determined = true;

  ScopedComPtr<IWindowsParentalControlsCore> parent_controls;
  HRESULT hr = parent_controls.CreateInstance(
      __uuidof(WindowsParentalControls));
  if (FAILED(hr))
    return false;

  ScopedComPtr<IWPCSettings> settings;
  hr = parent_controls->GetUserSettings(NULL, settings.Receive());
  if (FAILED(hr))
    return false;

  unsigned long restrictions = 0;
  settings->GetRestrictions(&restrictions);

  parental_control_logging_required =
      (restrictions & WPCFLAG_LOGGING_REQUIRED) == WPCFLAG_LOGGING_REQUIRED;
  return parental_control_logging_required;
}

}  // namespace win
}  // namespace base