Blink roll 25b6bd3a7a131ffe68d809546ad1a20707915cdc:3a503f41ae42e5b79cfcd2ff10e65afde...
[chromium-blink-merge.git] / content / browser / cocoa / system_hotkey_map_unittest.mm
blob6b2652fb42601c85fd637e1f003a2706aa109269
1 // Copyright 2014 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.
5 #include <gtest/gtest.h>
7 #import <Carbon/Carbon.h>
8 #import <Cocoa/Cocoa.h>
10 #include "base/files/file_path.h"
11 #include "base/mac/scoped_nsobject.h"
12 #include "base/path_service.h"
13 #import "content/browser/cocoa/system_hotkey_map.h"
14 #include "content/public/common/content_paths.h"
16 namespace content {
18 class SystemHotkeyMapTest : public ::testing::Test {
19  protected:
20   SystemHotkeyMapTest() {}
22   NSData* DataFromTestFile(const char* file) {
23     base::FilePath test_data_dir;
24     bool result = PathService::Get(DIR_TEST_DATA, &test_data_dir);
25     if (!result)
26       return nil;
28     base::FilePath test_path = test_data_dir.AppendASCII(file);
29     std::string test_path_string = test_path.AsUTF8Unsafe();
30     NSString* file_path =
31         [NSString stringWithUTF8String:test_path_string.c_str()];
32     return [NSData dataWithContentsOfFile:file_path];
33   }
35   void AddEntryToDictionary(BOOL enabled,
36                             unsigned short key_code,
37                             NSUInteger modifiers) {
38     NSMutableArray* parameters = [NSMutableArray array];
39     // The first parameter is unused.
40     [parameters addObject:[NSNumber numberWithInt:65535]];
41     [parameters addObject:[NSNumber numberWithUnsignedShort:key_code]];
42     [parameters addObject:[NSNumber numberWithUnsignedInteger:modifiers]];
44     NSMutableDictionary* value_dictionary = [NSMutableDictionary dictionary];
45     [value_dictionary setObject:parameters forKey:@"parameters"];
46     [value_dictionary setObject:@"standard" forKey:@"type"];
48     NSMutableDictionary* outer_dictionary = [NSMutableDictionary dictionary];
49     [outer_dictionary setObject:value_dictionary forKey:@"value"];
51     NSNumber* enabled_number = [NSNumber numberWithBool:enabled];
52     [outer_dictionary setObject:enabled_number forKey:@"enabled"];
54     NSString* key = [NSString stringWithFormat:@"%d", count_];
55     [system_hotkey_inner_dictionary_ setObject:outer_dictionary forKey:key];
56     ++count_;
57   }
59   virtual void SetUp() override {
60     system_hotkey_dictionary_.reset([[NSMutableDictionary alloc] init]);
61     system_hotkey_inner_dictionary_.reset([[NSMutableDictionary alloc] init]);
62     [system_hotkey_dictionary_ setObject:system_hotkey_inner_dictionary_
63                                   forKey:@"AppleSymbolicHotKeys"];
64     count_ = 100;
65   }
67   virtual void TearDown() override {
68     system_hotkey_dictionary_.reset();
69     system_hotkey_inner_dictionary_.reset();
70   }
72   // A constructed dictionary that matches the format of the one that would be
73   // parsed from the system hotkeys plist.
74   base::scoped_nsobject<NSMutableDictionary> system_hotkey_dictionary_;
76  private:
77   // A reference to the mutable dictionary to which new entries are added.
78   base::scoped_nsobject<NSMutableDictionary> system_hotkey_inner_dictionary_;
79   // Each entry in the system_hotkey_inner_dictionary_ needs to have a unique
80   // key. This count is used to generate those unique keys.
81   int count_;
84 TEST_F(SystemHotkeyMapTest, Parse) {
85   // This plist was pulled from a real machine. It is extensively populated,
86   // and has no missing or incomplete entries.
87   NSData* data = DataFromTestFile("mac/mac_system_hotkeys.plist");
88   ASSERT_TRUE(data);
90   NSDictionary* dictionary = SystemHotkeyMap::DictionaryFromData(data);
91   ASSERT_TRUE(dictionary);
93   SystemHotkeyMap map;
94   bool result = map.ParseDictionary(dictionary);
95   EXPECT_TRUE(result);
97   // Command + ` is a common key binding. It should exist.
98   unsigned short key_code = kVK_ANSI_Grave;
99   NSUInteger modifiers = NSCommandKeyMask;
100   EXPECT_TRUE(map.IsHotkeyReserved(key_code, modifiers));
102   // Command + Shift + ` is a common key binding. It should exist.
103   modifiers = NSCommandKeyMask | NSShiftKeyMask;
104   EXPECT_TRUE(map.IsHotkeyReserved(key_code, modifiers));
106   // Command + Shift + Ctr + ` is not a common key binding.
107   modifiers = NSCommandKeyMask | NSShiftKeyMask | NSControlKeyMask;
108   EXPECT_FALSE(map.IsHotkeyReserved(key_code, modifiers));
110   // Command + L is not a common key binding.
111   key_code = kVK_ANSI_L;
112   modifiers = NSCommandKeyMask;
113   EXPECT_FALSE(map.IsHotkeyReserved(key_code, modifiers));
116 TEST_F(SystemHotkeyMapTest, ParseNil) {
117   NSDictionary* dictionary = nil;
119   SystemHotkeyMap map;
120   bool result = map.ParseDictionary(dictionary);
121   EXPECT_FALSE(result);
124 TEST_F(SystemHotkeyMapTest, ParseMouse) {
125   // This plist was pulled from a real machine. It has missing entries,
126   // incomplete entries, and mouse hotkeys.
127   NSData* data = DataFromTestFile("mac/mac_system_hotkeys_sparse.plist");
128   ASSERT_TRUE(data);
130   NSDictionary* dictionary = SystemHotkeyMap::DictionaryFromData(data);
131   ASSERT_TRUE(dictionary);
133   SystemHotkeyMap map;
134   bool result = map.ParseDictionary(dictionary);
135   EXPECT_TRUE(result);
137   // Command + ` is a common key binding. It is missing.
138   // TODO(erikchen): OSX uses the default value when the keybinding is missing,
139   // so the hotkey should still be reserved.
140   // http://crbug.com/383558
141   unsigned short key_code = kVK_ANSI_Grave;
142   NSUInteger modifiers = NSCommandKeyMask;
143   EXPECT_FALSE(map.IsHotkeyReserved(key_code, modifiers));
145   // There is a mouse keybinding for 0x08. It should not apply to keyboard
146   // hotkeys.
147   key_code = kVK_ANSI_C;
148   modifiers = 0;
149   EXPECT_FALSE(map.IsHotkeyReserved(key_code, modifiers));
151   // Command + Alt + = is an accessibility shortcut. Its entry in the plist is
152   // incomplete.
153   // TODO(erikchen): OSX uses the default bindings, so this hotkey should still
154   // be reserved.
155   // http://crbug.com/383558
156   key_code = kVK_ANSI_Equal;
157   modifiers = NSCommandKeyMask | NSAlternateKeyMask;
158   EXPECT_FALSE(map.IsHotkeyReserved(key_code, modifiers));
161 TEST_F(SystemHotkeyMapTest, ParseCustomEntries) {
162   unsigned short key_code = kVK_ANSI_C;
164   AddEntryToDictionary(YES, key_code, 0);
165   AddEntryToDictionary(YES, key_code, NSAlphaShiftKeyMask);
166   AddEntryToDictionary(YES, key_code, NSShiftKeyMask);
167   AddEntryToDictionary(YES, key_code, NSControlKeyMask);
168   AddEntryToDictionary(YES, key_code, NSFunctionKeyMask);
169   AddEntryToDictionary(YES, key_code, NSFunctionKeyMask | NSControlKeyMask);
170   AddEntryToDictionary(NO, key_code, NSAlternateKeyMask);
172   SystemHotkeyMap map;
174   bool result = map.ParseDictionary(system_hotkey_dictionary_.get());
175   EXPECT_TRUE(result);
177   // Entries without control, command, or alternate key mask should not be
178   // reserved.
179   EXPECT_FALSE(map.IsHotkeyReserved(key_code, 0));
180   EXPECT_FALSE(map.IsHotkeyReserved(key_code, NSAlphaShiftKeyMask));
181   EXPECT_FALSE(map.IsHotkeyReserved(key_code, NSShiftKeyMask));
182   EXPECT_FALSE(map.IsHotkeyReserved(key_code, NSFunctionKeyMask));
184   // Unlisted entries should not be reserved.
185   EXPECT_FALSE(map.IsHotkeyReserved(key_code, NSCommandKeyMask));
187   // Disabled entries should not be reserved.
188   EXPECT_FALSE(map.IsHotkeyReserved(key_code, NSAlternateKeyMask));
190   // Other entries should be reserved.
191   EXPECT_TRUE(map.IsHotkeyReserved(key_code, NSControlKeyMask));
192   EXPECT_TRUE(
193       map.IsHotkeyReserved(key_code, NSFunctionKeyMask | NSControlKeyMask));
196 }  // namespace content