| OLD | NEW |
| 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 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 | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 // This program generates a user profile and history by randomly generating | 5 // This program generates a user profile and history by randomly generating |
| 6 // data and feeding it to the history service. | 6 // data and feeding it to the history service. |
| 7 | 7 |
| 8 #include "chrome/tools/profiles/thumbnail-inl.h" | 8 #include "chrome/tools/profiles/thumbnail-inl.h" |
| 9 | 9 |
| 10 #include "base/at_exit.h" | 10 #include "base/at_exit.h" |
| 11 #include "base/command_line.h" | 11 #include "base/command_line.h" |
| 12 #include "base/file_path.h" | 12 #include "base/file_path.h" |
| 13 #include "base/file_util.h" | 13 #include "base/file_util.h" |
| 14 #include "base/i18n/icu_util.h" | 14 #include "base/i18n/icu_util.h" |
| 15 #include "base/logging.h" |
| 15 #include "base/message_loop.h" | 16 #include "base/message_loop.h" |
| 16 #include "base/path_service.h" | 17 #include "base/path_service.h" |
| 17 #include "base/process_util.h" | 18 #include "base/process_util.h" |
| 18 #include "base/string_number_conversions.h" | 19 #include "base/string_number_conversions.h" |
| 19 #include "base/time.h" | 20 #include "base/time.h" |
| 20 #include "base/utf_string_conversions.h" | 21 #include "base/utf_string_conversions.h" |
| 21 #include "chrome/browser/history/history.h" | 22 #include "chrome/browser/history/history.h" |
| 22 #include "chrome/browser/history/history_service_factory.h" | 23 #include "chrome/browser/history/history_service_factory.h" |
| 23 #include "chrome/browser/history/top_sites.h" | 24 #include "chrome/browser/history/top_sites.h" |
| 24 #include "chrome/common/chrome_paths.h" | 25 #include "chrome/common/chrome_paths.h" |
| 25 #include "chrome/common/thumbnail_score.h" | 26 #include "chrome/common/thumbnail_score.h" |
| 27 #include "chrome/test/base/testing_browser_process.h" |
| 26 #include "chrome/test/base/testing_profile.h" | 28 #include "chrome/test/base/testing_profile.h" |
| 27 #include "content/browser/browser_thread_impl.h" | 29 #include "content/browser/browser_thread_impl.h" |
| 28 #include "content/public/browser/browser_thread.h" | 30 #include "content/public/browser/browser_thread.h" |
| 29 #include "content/public/browser/notification_service.h" | 31 #include "content/public/browser/notification_service.h" |
| 30 #include "third_party/skia/include/core/SkBitmap.h" | 32 #include "third_party/skia/include/core/SkBitmap.h" |
| 31 #include "ui/base/resource/resource_bundle.h" | 33 #include "ui/base/resource/resource_bundle.h" |
| 32 #include "ui/base/ui_base_paths.h" | 34 #include "ui/base/ui_base_paths.h" |
| 33 #include "ui/gfx/codec/jpeg_codec.h" | 35 #include "ui/gfx/codec/jpeg_codec.h" |
| 34 | 36 |
| 37 #if defined(TOOLKIT_GTK) |
| 38 #include <gtk/gtk.h> |
| 39 #endif |
| 40 |
| 35 using base::Time; | 41 using base::Time; |
| 36 using content::BrowserThread; | 42 using content::BrowserThread; |
| 37 | 43 |
| 38 // Addition types data can be generated for. By default only urls/visits are | 44 // Addition types data can be generated for. By default only urls/visits are |
| 39 // added. | 45 // added. |
| 40 enum Types { | 46 enum Types { |
| 41 TOP_SITES = 1 << 0, | 47 TOP_SITES = 1 << 0, |
| 42 FULL_TEXT = 1 << 1 | 48 FULL_TEXT = 1 << 1 |
| 43 }; | 49 }; |
| 44 | 50 |
| 51 // RAII for initializing and shutting down the TestBrowserProcess |
| 52 class InitBrowserProcess { |
| 53 public: |
| 54 InitBrowserProcess() { |
| 55 DCHECK(!g_browser_process); |
| 56 g_browser_process = new TestingBrowserProcess; |
| 57 } |
| 58 |
| 59 ~InitBrowserProcess() { |
| 60 DCHECK(g_browser_process); |
| 61 delete g_browser_process; |
| 62 g_browser_process = NULL; |
| 63 } |
| 64 }; |
| 65 |
| 45 // Probabilities of different word lengths, as measured from Darin's profile. | 66 // Probabilities of different word lengths, as measured from Darin's profile. |
| 46 // kWordLengthProbabilities[n-1] = P(word of length n) | 67 // kWordLengthProbabilities[n-1] = P(word of length n) |
| 47 const float kWordLengthProbabilities[] = { 0.069f, 0.132f, 0.199f, | 68 const float kWordLengthProbabilities[] = { 0.069f, 0.132f, 0.199f, |
| 48 0.137f, 0.088f, 0.115f, 0.081f, 0.055f, 0.034f, 0.021f, 0.019f, 0.018f, | 69 0.137f, 0.088f, 0.115f, 0.081f, 0.055f, 0.034f, 0.021f, 0.019f, 0.018f, |
| 49 0.007f, 0.007f, 0.005f, 0.004f, 0.003f, 0.003f, 0.003f }; | 70 0.007f, 0.007f, 0.005f, 0.004f, 0.003f, 0.003f, 0.003f }; |
| 50 | 71 |
| 51 // Return a float uniformly in [0,1]. | 72 // Return a float uniformly in [0,1]. |
| 52 // Useful for making probabilistic decisions. | 73 // Useful for making probabilistic decisions. |
| 53 float RandomFloat() { | 74 float RandomFloat() { |
| 54 return rand() / static_cast<float>(RAND_MAX); | 75 return rand() / static_cast<float>(RAND_MAX); |
| 55 } | 76 } |
| 56 | 77 |
| 57 // Return an integer uniformly in [min,max). | 78 // Return an integer uniformly in [min,max). |
| 58 int RandomInt(int min, int max) { | 79 int RandomInt(int min, int max) { |
| 59 return min + (rand() % (max-min)); | 80 return min + (rand() % (max-min)); |
| 60 } | 81 } |
| 61 | 82 |
| 62 // Return a string of |count| lowercase random characters. | 83 // Return a string of |count| lowercase random characters. |
| 63 std::wstring RandomChars(int count) { | 84 string16 RandomChars(int count) { |
| 64 std::wstring str; | 85 string16 str; |
| 65 for (int i = 0; i < count; ++i) | 86 for (int i = 0; i < count; ++i) |
| 66 str += L'a' + rand() % 26; | 87 str += L'a' + rand() % 26; |
| 67 return str; | 88 return str; |
| 68 } | 89 } |
| 69 | 90 |
| 70 std::wstring RandomWord() { | 91 string16 RandomWord() { |
| 71 // TODO(evanm): should we instead use the markov chain based | 92 // TODO(evanm): should we instead use the markov chain based |
| 72 // version of this that I already wrote? | 93 // version of this that I already wrote? |
| 73 | 94 |
| 74 // Sample a word length from kWordLengthProbabilities. | 95 // Sample a word length from kWordLengthProbabilities. |
| 75 float sample = RandomFloat(); | 96 float sample = RandomFloat(); |
| 76 int i; | 97 size_t i; |
| 77 for (i = 0; i < arraysize(kWordLengthProbabilities); ++i) { | 98 for (i = 0; i < arraysize(kWordLengthProbabilities); ++i) { |
| 78 sample -= kWordLengthProbabilities[i]; | 99 sample -= kWordLengthProbabilities[i]; |
| 79 if (sample < 0) break; | 100 if (sample < 0) break; |
| 80 } | 101 } |
| 81 const int word_length = i + 1; | 102 const int word_length = i + 1; |
| 82 return RandomChars(word_length); | 103 return RandomChars(word_length); |
| 83 } | 104 } |
| 84 | 105 |
| 85 // Return a string of |count| random words. | 106 // Return a string of |count| random words. |
| 86 std::wstring RandomWords(int count) { | 107 string16 RandomWords(int count) { |
| 87 std::wstring str; | 108 string16 str; |
| 88 for (int i = 0; i < count; ++i) { | 109 for (int i = 0; i < count; ++i) { |
| 89 if (!str.empty()) | 110 if (!str.empty()) |
| 90 str += L' '; | 111 str += L' '; |
| 91 str += RandomWord(); | 112 str += RandomWord(); |
| 92 } | 113 } |
| 93 return str; | 114 return str; |
| 94 } | 115 } |
| 95 | 116 |
| 96 // Return a random URL-looking string. | 117 // Return a random URL-looking string. |
| 97 GURL ConstructRandomURL() { | 118 GURL ConstructRandomURL() { |
| 98 return GURL(std::wstring(L"http://") + RandomChars(3) + L".com/" + | 119 return GURL(ASCIIToUTF16("http://") + RandomChars(3) + ASCIIToUTF16(".com/") + |
| 99 RandomChars(RandomInt(5, 20))); | 120 RandomChars(RandomInt(5, 20))); |
| 100 } | 121 } |
| 101 | 122 |
| 102 // Return a random page title-looking string. | 123 // Return a random page title-looking string. |
| 103 std::wstring ConstructRandomTitle() { | 124 string16 ConstructRandomTitle() { |
| 104 return RandomWords(RandomInt(3, 15)); | 125 return RandomWords(RandomInt(3, 15)); |
| 105 } | 126 } |
| 106 | 127 |
| 107 // Return a random string that could function as page contents. | 128 // Return a random string that could function as page contents. |
| 108 std::wstring ConstructRandomPage() { | 129 string16 ConstructRandomPage() { |
| 109 return RandomWords(RandomInt(10, 4000)); | 130 return RandomWords(RandomInt(10, 4000)); |
| 110 } | 131 } |
| 111 | 132 |
| 112 // Insert a batch of |batch_size| URLs, starting at pageid |page_id|. | 133 // Insert a batch of |batch_size| URLs, starting at pageid |page_id|. |
| 113 void InsertURLBatch(Profile* profile, | 134 void InsertURLBatch(Profile* profile, |
| 114 int page_id, | 135 int page_id, |
| 115 int batch_size, | 136 int batch_size, |
| 116 int types) { | 137 int types) { |
| 117 HistoryService* history_service = | 138 HistoryService* history_service = |
| 118 HistoryServiceFactory::GetForProfile(profile, Profile::EXPLICIT_ACCESS); | 139 HistoryServiceFactory::GetForProfile(profile, Profile::EXPLICIT_ACCESS); |
| (...skipping 69 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 188 top_sites->SetPageThumbnail(url, image, score); | 209 top_sites->SetPageThumbnail(url, image, score); |
| 189 } | 210 } |
| 190 | 211 |
| 191 previous_url = url; | 212 previous_url = url; |
| 192 | 213 |
| 193 if (revisit_urls.empty() || RandomFloat() < kRevisitableURLProbability) | 214 if (revisit_urls.empty() || RandomFloat() < kRevisitableURLProbability) |
| 194 revisit_urls.push_back(url); | 215 revisit_urls.push_back(url); |
| 195 } | 216 } |
| 196 } | 217 } |
| 197 | 218 |
| 198 int main(int argc, const char* argv[]) { | 219 int main(int argc, char* argv[]) { |
| 199 CommandLine::Init(argc, argv); | 220 CommandLine::Init(argc, argv); |
| 200 base::EnableTerminationOnHeapCorruption(); | 221 base::EnableTerminationOnHeapCorruption(); |
| 201 base::AtExitManager exit_manager; | 222 base::AtExitManager exit_manager; |
| 202 CommandLine* cl = CommandLine::ForCurrentProcess(); | 223 CommandLine* cl = CommandLine::ForCurrentProcess(); |
| 203 | 224 |
| 204 int types = 0; | 225 int types = 0; |
| 205 if (cl->HasSwitch("top-sites")) | 226 if (cl->HasSwitch("top-sites")) |
| 206 types |= TOP_SITES; | 227 types |= TOP_SITES; |
| 207 if (cl->HasSwitch("full-text")) | 228 if (cl->HasSwitch("full-text")) |
| 208 types |= FULL_TEXT; | 229 types |= FULL_TEXT; |
| 209 | 230 |
| 210 // We require two arguments: urlcount and profiledir. | 231 // We require two arguments: urlcount and profiledir. |
| 211 const CommandLine::StringVector& args = cl->GetArgs(); | 232 const CommandLine::StringVector& args = cl->GetArgs(); |
| 212 if (args.size() < 2) { | 233 if (args.size() < 2) { |
| 213 printf("usage: %s [--top-sites] [--full-text] <urlcount> " | 234 printf("usage: %s [--top-sites] [--full-text] <urlcount> " |
| 214 "<profiledir>\n", argv[0]); | 235 "<profiledir>\n", argv[0]); |
| 215 printf("\n --top-sites Generate thumbnails\n"); | 236 printf("\n --top-sites Generate thumbnails\n"); |
| 216 printf("\n --full-text Generate full text index\n"); | 237 printf("\n --full-text Generate full text index\n"); |
| 217 return -1; | 238 return -1; |
| 218 } | 239 } |
| 219 | 240 |
| 220 int url_count = 0; | 241 int url_count = 0; |
| 221 base::StringToInt(WideToUTF8(args[0]), &url_count); | 242 base::StringToInt(args[0], &url_count); |
| 222 FilePath dst_dir(args[1]); | 243 FilePath dst_dir(args[1]); |
| 223 if (!dst_dir.IsAbsolute()) { | 244 if (!dst_dir.IsAbsolute()) { |
| 224 FilePath current_dir; | 245 FilePath current_dir; |
| 225 file_util::GetCurrentDirectory(¤t_dir); | 246 file_util::GetCurrentDirectory(¤t_dir); |
| 226 dst_dir = current_dir.Append(dst_dir); | 247 dst_dir = current_dir.Append(dst_dir); |
| 227 } | 248 } |
| 228 if (!file_util::CreateDirectory(dst_dir)) { | 249 if (!file_util::CreateDirectory(dst_dir)) { |
| 229 printf("Unable to create directory %ls: %d\n", | 250 PLOG(ERROR) << "Unable to create directory " << dst_dir.value().c_str(); |
| 230 dst_dir.value().c_str(), | |
| 231 ::GetLastError()); | |
| 232 } | 251 } |
| 233 | 252 |
| 234 icu_util::Initialize(); | 253 icu_util::Initialize(); |
| 254 // Copied from base/test/test_suite.cc. |
| 255 #if defined(TOOLKIT_GTK) |
| 256 gtk_init_check(&argc, &argv); |
| 257 #endif |
| 235 | 258 |
| 259 InitBrowserProcess initialize_browser_process; |
| 236 chrome::RegisterPathProvider(); | 260 chrome::RegisterPathProvider(); |
| 237 ui::RegisterPathProvider(); | 261 ui::RegisterPathProvider(); |
| 238 ResourceBundle::InitSharedInstanceWithLocale("en-US", NULL); | |
| 239 scoped_ptr<content::NotificationService> notification_service( | |
| 240 content::NotificationService::Create()); | |
| 241 MessageLoopForUI message_loop; | 262 MessageLoopForUI message_loop; |
| 242 content::BrowserThreadImpl ui_thread(BrowserThread::UI, &message_loop); | 263 content::BrowserThreadImpl ui_thread(BrowserThread::UI, &message_loop); |
| 243 content::BrowserThreadImpl db_thread(BrowserThread::DB, &message_loop); | 264 content::BrowserThreadImpl db_thread(BrowserThread::DB, &message_loop); |
| 265 ResourceBundle::InitSharedInstanceWithLocale("en-US", NULL); |
| 244 TestingProfile profile; | 266 TestingProfile profile; |
| 245 profile.CreateHistoryService(false, false); | 267 profile.CreateHistoryService(false, false); |
| 246 if (types & TOP_SITES) { | 268 if (types & TOP_SITES) { |
| 247 profile.CreateTopSites(); | 269 profile.CreateTopSites(); |
| 248 profile.BlockUntilTopSitesLoaded(); | 270 profile.BlockUntilTopSitesLoaded(); |
| 249 } | 271 } |
| 250 | 272 |
| 251 srand(static_cast<unsigned int>(Time::Now().ToInternalValue())); | 273 srand(static_cast<unsigned int>(Time::Now().ToInternalValue())); |
| 252 | 274 |
| 253 // The maximum number of URLs to insert into history in one batch. | 275 // The maximum number of URLs to insert into history in one batch. |
| (...skipping 13 matching lines...) Expand all Loading... |
| 267 profile.DestroyHistoryService(); | 289 profile.DestroyHistoryService(); |
| 268 | 290 |
| 269 message_loop.RunUntilIdle(); | 291 message_loop.RunUntilIdle(); |
| 270 | 292 |
| 271 file_util::FileEnumerator file_iterator(profile.GetPath(), false, | 293 file_util::FileEnumerator file_iterator(profile.GetPath(), false, |
| 272 file_util::FileEnumerator::FILES); | 294 file_util::FileEnumerator::FILES); |
| 273 FilePath path = file_iterator.Next(); | 295 FilePath path = file_iterator.Next(); |
| 274 while (!path.empty()) { | 296 while (!path.empty()) { |
| 275 FilePath dst_file = dst_dir.Append(path.BaseName()); | 297 FilePath dst_file = dst_dir.Append(path.BaseName()); |
| 276 file_util::Delete(dst_file, false); | 298 file_util::Delete(dst_file, false); |
| 277 printf("Copying file %ls to %ls\n", path.value().c_str(), | 299 printf("Copying file %" PRFilePath " to " |
| 300 "%" PRFilePath "\n", path.value().c_str(), |
| 278 dst_file.value().c_str()); | 301 dst_file.value().c_str()); |
| 279 if (!file_util::CopyFile(path, dst_file)) { | 302 if (!file_util::CopyFile(path, dst_file)) { |
| 280 printf("Copying file failed: %d\n", ::GetLastError()); | 303 PLOG(ERROR) << "Copying file failed"; |
| 281 return -1; | 304 return -1; |
| 282 } | 305 } |
| 283 path = file_iterator.Next(); | 306 path = file_iterator.Next(); |
| 284 } | 307 } |
| 285 | 308 |
| 286 return 0; | 309 return 0; |
| 287 } | 310 } |
| OLD | NEW |