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 "base/pickle.h" 6 #include "testing/gtest/include/gtest/gtest.h" 7 #include "third_party/WebKit/public/platform/WebCursorInfo.h" 8 #include "webkit/common/cursors/webcursor.h" 9 10 using blink::WebCursorInfo; 11 12 TEST(WebCursorTest, OKCursorSerialization) { 13 WebCursor custom_cursor; 14 // This is a valid custom cursor. 15 Pickle ok_custom_pickle; 16 // Type and hotspots. 17 ok_custom_pickle.WriteInt(WebCursorInfo::TypeCustom); 18 ok_custom_pickle.WriteInt(0); 19 ok_custom_pickle.WriteInt(0); 20 // X & Y 21 ok_custom_pickle.WriteInt(1); 22 ok_custom_pickle.WriteInt(1); 23 // Scale 24 ok_custom_pickle.WriteFloat(1.0); 25 // Data len including enough data for a 1x1 image. 26 ok_custom_pickle.WriteInt(4); 27 ok_custom_pickle.WriteUInt32(0); 28 // Custom Windows message. 29 ok_custom_pickle.WriteUInt32(0); 30 PickleIterator iter(ok_custom_pickle); 31 EXPECT_TRUE(custom_cursor.Deserialize(&iter)); 32 33 #if defined(TOOLKIT_GTK) 34 // On GTK+ using platforms, we should get a real native GdkCursor object back 35 // (and the memory used should automatically be freed by the WebCursor object 36 // for valgrind tests). 37 EXPECT_TRUE(custom_cursor.GetCustomCursor()); 38 #endif 39 } 40 41 TEST(WebCursorTest, BrokenCursorSerialization) { 42 WebCursor custom_cursor; 43 // This custom cursor has not been send with enough data. 44 Pickle short_custom_pickle; 45 // Type and hotspots. 46 short_custom_pickle.WriteInt(WebCursorInfo::TypeCustom); 47 short_custom_pickle.WriteInt(0); 48 short_custom_pickle.WriteInt(0); 49 // X & Y 50 short_custom_pickle.WriteInt(1); 51 short_custom_pickle.WriteInt(1); 52 // Scale 53 short_custom_pickle.WriteFloat(1.0); 54 // Data len not including enough data for a 1x1 image. 55 short_custom_pickle.WriteInt(3); 56 short_custom_pickle.WriteUInt32(0); 57 PickleIterator iter(short_custom_pickle); 58 EXPECT_FALSE(custom_cursor.Deserialize(&iter)); 59 60 // This custom cursor has enough data but is too big. 61 Pickle large_custom_pickle; 62 // Type and hotspots. 63 large_custom_pickle.WriteInt(WebCursorInfo::TypeCustom); 64 large_custom_pickle.WriteInt(0); 65 large_custom_pickle.WriteInt(0); 66 // X & Y 67 static const int kTooBigSize = 4096 + 1; 68 large_custom_pickle.WriteInt(kTooBigSize); 69 large_custom_pickle.WriteInt(1); 70 // Scale 71 large_custom_pickle.WriteFloat(1.0); 72 // Data len including enough data for a 4097x1 image. 73 large_custom_pickle.WriteInt(kTooBigSize * 4); 74 for (int i = 0; i < kTooBigSize; ++i) 75 large_custom_pickle.WriteUInt32(0); 76 iter = PickleIterator(large_custom_pickle); 77 EXPECT_FALSE(custom_cursor.Deserialize(&iter)); 78 79 // This custom cursor uses negative lengths. 80 Pickle neg_custom_pickle; 81 // Type and hotspots. 82 neg_custom_pickle.WriteInt(WebCursorInfo::TypeCustom); 83 neg_custom_pickle.WriteInt(0); 84 neg_custom_pickle.WriteInt(0); 85 // X & Y 86 neg_custom_pickle.WriteInt(-1); 87 neg_custom_pickle.WriteInt(-1); 88 // Scale 89 neg_custom_pickle.WriteFloat(1.0); 90 // Data len including enough data for a 1x1 image. 91 neg_custom_pickle.WriteInt(4); 92 neg_custom_pickle.WriteUInt32(0); 93 // Custom Windows message. 94 neg_custom_pickle.WriteUInt32(0); 95 iter = PickleIterator(neg_custom_pickle); 96 EXPECT_FALSE(custom_cursor.Deserialize(&iter)); 97 98 // This custom cursor uses zero scale. 99 Pickle scale_zero_custom_pickle; 100 // Type and hotspots. 101 scale_zero_custom_pickle.WriteInt(WebCursorInfo::TypeCustom); 102 scale_zero_custom_pickle.WriteInt(0); 103 scale_zero_custom_pickle.WriteInt(0); 104 // X & Y 105 scale_zero_custom_pickle.WriteInt(1); 106 scale_zero_custom_pickle.WriteInt(1); 107 // Scale 108 scale_zero_custom_pickle.WriteFloat(0); 109 // Data len including enough data for a 1x1 image. 110 scale_zero_custom_pickle.WriteInt(4); 111 scale_zero_custom_pickle.WriteUInt32(0); 112 // Custom Windows message. 113 scale_zero_custom_pickle.WriteUInt32(0); 114 iter = PickleIterator(scale_zero_custom_pickle); 115 EXPECT_FALSE(custom_cursor.Deserialize(&iter)); 116 117 // This custom cursor uses tiny scale. 118 Pickle scale_tiny_custom_pickle; 119 // Type and hotspots. 120 scale_tiny_custom_pickle.WriteInt(WebCursorInfo::TypeCustom); 121 scale_tiny_custom_pickle.WriteInt(0); 122 scale_tiny_custom_pickle.WriteInt(0); 123 // X & Y 124 scale_tiny_custom_pickle.WriteInt(1); 125 scale_tiny_custom_pickle.WriteInt(1); 126 // Scale 127 scale_tiny_custom_pickle.WriteFloat(0.001f); 128 // Data len including enough data for a 1x1 image. 129 scale_tiny_custom_pickle.WriteInt(4); 130 scale_tiny_custom_pickle.WriteUInt32(0); 131 // Custom Windows message. 132 scale_tiny_custom_pickle.WriteUInt32(0); 133 iter = PickleIterator(scale_tiny_custom_pickle); 134 EXPECT_FALSE(custom_cursor.Deserialize(&iter)); 135 } 136 137 #if defined(OS_WIN) && !defined(USE_AURA) 138 TEST(WebCursorTest, WindowsCursorConversion) { 139 WebCursor custom_cursor; 140 Pickle win32_custom_pickle; 141 WebCursor win32_custom_cursor; 142 win32_custom_cursor.InitFromExternalCursor( 143 reinterpret_cast<HCURSOR>(1000)); 144 EXPECT_TRUE(win32_custom_cursor.Serialize(&win32_custom_pickle)); 145 PickleIterator iter(win32_custom_pickle); 146 EXPECT_TRUE(custom_cursor.Deserialize(&iter)); 147 EXPECT_EQ(reinterpret_cast<HCURSOR>(1000), custom_cursor.GetCursor(NULL)); 148 } 149 #endif // OS_WIN 150 151 TEST(WebCursorTest, ClampHotspot) { 152 WebCursor custom_cursor; 153 // This is a valid custom cursor. 154 Pickle ok_custom_pickle; 155 // Type and hotspots. 156 ok_custom_pickle.WriteInt(WebCursorInfo::TypeCustom); 157 // Hotspot is invalid --- outside the bounds of the image. 158 ok_custom_pickle.WriteInt(5); 159 ok_custom_pickle.WriteInt(5); 160 // X & Y 161 ok_custom_pickle.WriteInt(2); 162 ok_custom_pickle.WriteInt(2); 163 // Scale 164 ok_custom_pickle.WriteFloat(1.0); 165 // Data len including enough data for a 2x2 image. 166 ok_custom_pickle.WriteInt(4 * 4); 167 for (size_t i = 0; i < 4; i++) 168 ok_custom_pickle.WriteUInt32(0); 169 // Custom Windows message. 170 ok_custom_pickle.WriteUInt32(0); 171 PickleIterator iter(ok_custom_pickle); 172 ASSERT_TRUE(custom_cursor.Deserialize(&iter)); 173 174 // Convert to WebCursorInfo, make sure the hotspot got clamped. 175 WebCursor::CursorInfo info; 176 custom_cursor.GetCursorInfo(&info); 177 EXPECT_EQ(gfx::Point(1, 1), info.hotspot); 178 179 // Set hotspot to an invalid point again, pipe back through WebCursor, 180 // and make sure the hotspot got clamped again. 181 info.hotspot = gfx::Point(-1, -1); 182 custom_cursor.InitFromCursorInfo(info); 183 custom_cursor.GetCursorInfo(&info); 184 EXPECT_EQ(gfx::Point(0, 0), info.hotspot); 185 } 186 187 TEST(WebCursorTest, EmptyImage) { 188 WebCursor custom_cursor; 189 Pickle broken_cursor_pickle; 190 broken_cursor_pickle.WriteInt(WebCursorInfo::TypeCustom); 191 // Hotspot is at origin 192 broken_cursor_pickle.WriteInt(0); 193 broken_cursor_pickle.WriteInt(0); 194 // X & Y are empty 195 broken_cursor_pickle.WriteInt(0); 196 broken_cursor_pickle.WriteInt(0); 197 // Scale 198 broken_cursor_pickle.WriteFloat(1.0); 199 // No data for the image since the size is 0. 200 broken_cursor_pickle.WriteInt(0); 201 // Custom Windows message. 202 broken_cursor_pickle.WriteInt(0); 203 204 // Make sure we can read this on all platforms; it is technicaally a valid 205 // cursor. 206 PickleIterator iter(broken_cursor_pickle); 207 ASSERT_TRUE(custom_cursor.Deserialize(&iter)); 208 209 #if defined(TOOLKIT_GTK) 210 // On GTK+ using platforms, we make sure that we get NULL back from this 211 // method; the relevant GDK methods take NULL as a request to use the default 212 // cursor. 213 EXPECT_EQ(NULL, custom_cursor.GetCustomCursor()); 214 #endif 215 } 216 217 TEST(WebCursorTest, Scale2) { 218 WebCursor custom_cursor; 219 // This is a valid custom cursor. 220 Pickle ok_custom_pickle; 221 // Type and hotspots. 222 ok_custom_pickle.WriteInt(WebCursorInfo::TypeCustom); 223 ok_custom_pickle.WriteInt(0); 224 ok_custom_pickle.WriteInt(0); 225 // X & Y 226 ok_custom_pickle.WriteInt(1); 227 ok_custom_pickle.WriteInt(1); 228 // Scale - 2 image pixels per UI pixel. 229 ok_custom_pickle.WriteFloat(2.0); 230 // Data len including enough data for a 1x1 image. 231 ok_custom_pickle.WriteInt(4); 232 ok_custom_pickle.WriteUInt32(0); 233 // Custom Windows message. 234 ok_custom_pickle.WriteUInt32(0); 235 PickleIterator iter(ok_custom_pickle); 236 EXPECT_TRUE(custom_cursor.Deserialize(&iter)); 237 238 #if defined(TOOLKIT_GTK) 239 // On GTK+ using platforms, we should get a real native GdkCursor object back 240 // (and the memory used should automatically be freed by the WebCursor object 241 // for valgrind tests). 242 EXPECT_TRUE(custom_cursor.GetCustomCursor()); 243 #endif 244 } 245