1f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)// Copyright 2013 The Chromium Authors. All rights reserved.
268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)// found in the LICENSE file.
468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)
5f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#include "ui/events/keycodes/dom4/keycode_converter.h"
668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)
768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)#include <map>
868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)
968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)#include "base/basictypes.h"
1068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)#include "testing/gtest/include/gtest/gtest.h"
1168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)
1268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)using ui::KeycodeConverter;
1368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)
1468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)namespace {
1568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)
1668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)#if defined(OS_WIN)
1768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)const size_t kExpectedMappedKeyCount = 138;
1868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)#elif defined(OS_LINUX)
1968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)const size_t kExpectedMappedKeyCount = 145;
2068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)#elif defined(OS_MACOSX)
2168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)const size_t kExpectedMappedKeyCount = 118;
2268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)#else
2368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)const size_t kExpectedMappedKeyCount = 0;
2468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)#endif
2568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)
2668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)const uint32_t kUsbNonExistentKeycode = 0xffffff;
2768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)const uint32_t kUsbUsBackslash =        0x070031;
2868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)const uint32_t kUsbNonUsHash =          0x070032;
2968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)
3068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)TEST(UsbKeycodeMap, Basic) {
3168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  // Verify that the first element in the table is the "invalid" code.
3268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  const ui::KeycodeMapEntry* keycode_map =
331320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      ui::KeycodeConverter::GetKeycodeMapForTest();
341320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  EXPECT_EQ(ui::KeycodeConverter::InvalidUsbKeycode(),
351320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci            keycode_map[0].usb_keycode);
361320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  EXPECT_EQ(ui::KeycodeConverter::InvalidNativeKeycode(),
3768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)            keycode_map[0].native_keycode);
381320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  EXPECT_STREQ(ui::KeycodeConverter::InvalidKeyboardEventCode(),
391320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci               "Unidentified");
401320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  EXPECT_EQ(ui::KeycodeConverter::InvalidNativeKeycode(),
411320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci            ui::KeycodeConverter::CodeToNativeKeycode("Unidentified"));
4268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)
4368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  // Verify that there are no duplicate entries in the mapping.
4468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  std::map<uint32_t, uint16_t> usb_to_native;
4568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  std::map<uint16_t, uint32_t> native_to_usb;
461320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  size_t numEntries = ui::KeycodeConverter::NumKeycodeMapEntriesForTest();
4768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  for (size_t i = 0; i < numEntries; ++i) {
4868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)    const ui::KeycodeMapEntry* entry = &keycode_map[i];
4968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)    // Don't test keys with no native keycode mapping on this platform.
501320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    if (entry->native_keycode == ui::KeycodeConverter::InvalidNativeKeycode())
5168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)      continue;
5268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)
5368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)    // Verify UsbKeycodeToNativeKeycode works for this key.
541320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    EXPECT_EQ(
551320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci        entry->native_keycode,
561320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci        ui::KeycodeConverter::UsbKeycodeToNativeKeycode(entry->usb_keycode));
5768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)
5868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)    // Verify CodeToNativeKeycode and NativeKeycodeToCode work correctly.
5968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)    if (entry->code) {
6068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)      EXPECT_EQ(entry->native_keycode,
611320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                ui::KeycodeConverter::CodeToNativeKeycode(entry->code));
621320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      EXPECT_STREQ(
631320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci          entry->code,
641320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci          ui::KeycodeConverter::NativeKeycodeToCode(entry->native_keycode));
6568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)    }
6668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)    else {
671320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      EXPECT_EQ(ui::KeycodeConverter::InvalidNativeKeycode(),
681320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                ui::KeycodeConverter::CodeToNativeKeycode(entry->code));
6968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)    }
7068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)
7168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)    // Verify that the USB or native codes aren't duplicated.
7268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)    EXPECT_EQ(0U, usb_to_native.count(entry->usb_keycode))
7368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)        << " duplicate of USB code 0x" << std::hex << std::setfill('0')
7468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)        << std::setw(6) << entry->usb_keycode
7568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)        << " to native 0x"
7668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)        << std::setw(4) << entry->native_keycode
7768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)        << " (previous was 0x"
7868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)        << std::setw(4) << usb_to_native[entry->usb_keycode]
7968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)        << ")";
8068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)    usb_to_native[entry->usb_keycode] = entry->native_keycode;
8168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)    EXPECT_EQ(0U, native_to_usb.count(entry->native_keycode))
8268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)        << " duplicate of native code 0x" << std::hex << std::setfill('0')
8368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)        << std::setw(4) << entry->native_keycode
8468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)        << " to USB 0x"
8568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)        << std::setw(6) << entry->usb_keycode
8668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)        << " (previous was 0x"
8768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)        << std::setw(6) << native_to_usb[entry->native_keycode]
8868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)        << ")";
8968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)    native_to_usb[entry->native_keycode] = entry->usb_keycode;
9068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  }
9168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  ASSERT_EQ(usb_to_native.size(), native_to_usb.size());
9268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)
9368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  // Verify that the number of mapped keys is what we expect, i.e. we haven't
9468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  // lost any, and if we've added some then the expectation has been updated.
9568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  EXPECT_EQ(kExpectedMappedKeyCount, usb_to_native.size());
9668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)}
9768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)
9868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)TEST(UsbKeycodeMap, NonExistent) {
9968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  // Verify that UsbKeycodeToNativeKeycode works for a non-existent USB keycode.
1001320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  EXPECT_EQ(
1011320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      ui::KeycodeConverter::InvalidNativeKeycode(),
1021320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      ui::KeycodeConverter::UsbKeycodeToNativeKeycode(kUsbNonExistentKeycode));
10368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)}
10468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)
10568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)TEST(UsbKeycodeMap, UsBackslashIsNonUsHash) {
10668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  // Verify that UsbKeycodeToNativeKeycode treats the non-US "hash" key
10768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  // as equivalent to the US "backslash" key.
1081320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  EXPECT_EQ(ui::KeycodeConverter::UsbKeycodeToNativeKeycode(kUsbUsBackslash),
1091320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci            ui::KeycodeConverter::UsbKeycodeToNativeKeycode(kUsbNonUsHash));
11068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)}
11168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)
11268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)}  // namespace
113