Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(133)

Side by Side Diff: base/mime_util_xdg.cc

Issue 8413052: Cleanup: Change a static initializer to a LazyInstance, and add some typedefs. (Closed) Base URL: svn://chrome-svn/chrome/trunk/src/
Patch Set: Created 9 years, 1 month ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « no previous file | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2011 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 #include "base/mime_util.h" 5 #include "base/mime_util.h"
6 6
7 #include <gtk/gtk.h> 7 #include <gtk/gtk.h>
8 #include <sys/time.h> 8 #include <sys/time.h>
9 #include <time.h> 9 #include <time.h>
10 10
11 #include <cstdlib> 11 #include <cstdlib>
12 #include <list> 12 #include <list>
13 #include <map> 13 #include <map>
14 #include <vector> 14 #include <vector>
15 15
16 #include "base/file_util.h" 16 #include "base/file_util.h"
17 #include "base/lazy_instance.h"
17 #include "base/logging.h" 18 #include "base/logging.h"
18 #include "base/memory/scoped_ptr.h" 19 #include "base/memory/scoped_ptr.h"
19 #include "base/memory/singleton.h" 20 #include "base/memory/singleton.h"
20 #include "base/message_loop.h" 21 #include "base/message_loop.h"
21 #include "base/string_split.h" 22 #include "base/string_split.h"
22 #include "base/string_util.h" 23 #include "base/string_util.h"
23 #include "base/synchronization/lock.h" 24 #include "base/synchronization/lock.h"
24 #include "base/third_party/xdg_mime/xdgmime.h" 25 #include "base/third_party/xdg_mime/xdgmime.h"
25 #include "base/threading/thread_restrictions.h" 26 #include "base/threading/thread_restrictions.h"
26 27
27 namespace { 28 namespace {
28 29
29 // None of the XDG stuff is thread-safe, so serialize all accesss under 30 // None of the XDG stuff is thread-safe, so serialize all access under
30 // this lock. 31 // this lock.
31 base::Lock g_mime_util_xdg_lock; 32 static base::LazyInstance<base::Lock>
willchan no longer on Chromium 2011/10/28 21:42:25 I wonder if you should use LeakyLazyInstance. Not
Lei Zhang 2011/10/28 21:54:02 Would you say that's true of all locks? There's 7
33 g_mime_util_xdg_lock(base::LINKER_INITIALIZED);
32 34
33 class IconTheme; 35 class IconTheme;
34 36
35 class MimeUtilConstants { 37 class MimeUtilConstants {
36 public: 38 public:
39 typedef std::map<std::string, IconTheme*> IconThemeMap;
40 typedef std::map<FilePath, int> IconDirMtimeMap;
41 typedef std::vector<std::string> IconFormats;
42
43 // In seconds, specified by icon theme specs.
44 static const int kUpdateInterval = 5;
45
46 static const size_t kDefaultThemeNum = 4;
47
37 static MimeUtilConstants* GetInstance() { 48 static MimeUtilConstants* GetInstance() {
38 return Singleton<MimeUtilConstants>::get(); 49 return Singleton<MimeUtilConstants>::get();
39 } 50 }
40 51
41 // In seconds, specified by icon theme specs.
42 const int kUpdateInterval;
43
44 // Store icon directories and their mtimes. 52 // Store icon directories and their mtimes.
45 std::map<FilePath, int>* icon_dirs_; 53 IconDirMtimeMap* icon_dirs_;
46 54
47 // Store icon formats. 55 // Store icon formats.
48 std::vector<std::string> icon_formats_; 56 IconFormats icon_formats_;
49 57
50 // Store loaded icon_theme. 58 // Store loaded icon_theme.
51 std::map<std::string, IconTheme*>* icon_themes_; 59 IconThemeMap* icon_themes_;
52
53 static const size_t kDefaultThemeNum = 4;
54 60
55 // The default theme. 61 // The default theme.
56 IconTheme* default_themes_[kDefaultThemeNum]; 62 IconTheme* default_themes_[kDefaultThemeNum];
57 63
58 time_t last_check_time_; 64 time_t last_check_time_;
59 65
60 // This is set by DetectGtkTheme(). We cache it so that we can access the 66 // This is set by DetectGtkTheme(). We cache it so that we can access the
61 // theme name from threads that aren't allowed to call 67 // theme name from threads that aren't allowed to call
62 // gtk_settings_get_default(). 68 // gtk_settings_get_default().
63 std::string gtk_theme_name_; 69 std::string gtk_theme_name_;
64 70
65 private: 71 private:
66 MimeUtilConstants() 72 MimeUtilConstants()
67 : kUpdateInterval(5), 73 : icon_dirs_(NULL),
68 icon_dirs_(NULL),
69 icon_themes_(NULL), 74 icon_themes_(NULL),
70 last_check_time_(0) { 75 last_check_time_(0) {
71 icon_formats_.push_back(".png"); 76 icon_formats_.push_back(".png");
72 icon_formats_.push_back(".svg"); 77 icon_formats_.push_back(".svg");
73 icon_formats_.push_back(".xpm"); 78 icon_formats_.push_back(".xpm");
74 79
75 for (size_t i = 0; i < kDefaultThemeNum; ++i) 80 for (size_t i = 0; i < kDefaultThemeNum; ++i)
76 default_themes_[i] = NULL; 81 default_themes_[i] = NULL;
77 } 82 }
78 ~MimeUtilConstants(); 83 ~MimeUtilConstants();
(...skipping 78 matching lines...) Expand 10 before | Expand all | Expand 10 after
157 SubDirInfo* info_array_; // List of sub-directories. 162 SubDirInfo* info_array_; // List of sub-directories.
158 std::string inherits_; // Name of the theme this one inherits from. 163 std::string inherits_; // Name of the theme this one inherits from.
159 }; 164 };
160 165
161 IconTheme::IconTheme(const std::string& name) 166 IconTheme::IconTheme(const std::string& name)
162 : index_theme_loaded_(false), 167 : index_theme_loaded_(false),
163 info_array_(NULL) { 168 info_array_(NULL) {
164 base::ThreadRestrictions::AssertIOAllowed(); 169 base::ThreadRestrictions::AssertIOAllowed();
165 // Iterate on all icon directories to find directories of the specified 170 // Iterate on all icon directories to find directories of the specified
166 // theme and load the first encountered index.theme. 171 // theme and load the first encountered index.theme.
167 std::map<FilePath, int>::iterator iter; 172 MimeUtilConstants::IconDirMtimeMap::iterator iter;
168 FilePath theme_path; 173 FilePath theme_path;
169 std::map<FilePath, int>* icon_dirs = 174 MimeUtilConstants::IconDirMtimeMap* icon_dirs =
170 MimeUtilConstants::GetInstance()->icon_dirs_; 175 MimeUtilConstants::GetInstance()->icon_dirs_;
171 for (iter = icon_dirs->begin(); iter != icon_dirs->end(); ++iter) { 176 for (iter = icon_dirs->begin(); iter != icon_dirs->end(); ++iter) {
172 theme_path = iter->first.Append(name); 177 theme_path = iter->first.Append(name);
173 if (!file_util::DirectoryExists(theme_path)) 178 if (!file_util::DirectoryExists(theme_path))
174 continue; 179 continue;
175 FilePath theme_index = theme_path.Append("index.theme"); 180 FilePath theme_index = theme_path.Append("index.theme");
176 if (!index_theme_loaded_ && file_util::PathExists(theme_index)) { 181 if (!index_theme_loaded_ && file_util::PathExists(theme_index)) {
177 if (!LoadIndexTheme(theme_index)) 182 if (!LoadIndexTheme(theme_index))
178 return; 183 return;
179 index_theme_loaded_ = true; 184 index_theme_loaded_ = true;
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after
220 IconTheme* theme = LoadTheme(inherits_); 225 IconTheme* theme = LoadTheme(inherits_);
221 // Inheriting from itself means the theme is buggy but we shouldn't crash. 226 // Inheriting from itself means the theme is buggy but we shouldn't crash.
222 if (theme && theme != this) 227 if (theme && theme != this)
223 return theme->GetIconPath(icon_name, size, inherits); 228 return theme->GetIconPath(icon_name, size, inherits);
224 else 229 else
225 return FilePath(); 230 return FilePath();
226 } 231 }
227 232
228 IconTheme* IconTheme::LoadTheme(const std::string& theme_name) { 233 IconTheme* IconTheme::LoadTheme(const std::string& theme_name) {
229 scoped_ptr<IconTheme> theme; 234 scoped_ptr<IconTheme> theme;
230 std::map<std::string, IconTheme*>* icon_themes = 235 MimeUtilConstants::IconThemeMap* icon_themes =
231 MimeUtilConstants::GetInstance()->icon_themes_; 236 MimeUtilConstants::GetInstance()->icon_themes_;
232 if (icon_themes->find(theme_name) != icon_themes->end()) { 237 if (icon_themes->find(theme_name) != icon_themes->end()) {
233 theme.reset((*icon_themes)[theme_name]); 238 theme.reset((*icon_themes)[theme_name]);
234 } else { 239 } else {
235 theme.reset(new IconTheme(theme_name)); 240 theme.reset(new IconTheme(theme_name));
236 if (!theme->IsValid()) 241 if (!theme->IsValid())
237 theme.reset(); 242 theme.reset();
238 (*icon_themes)[theme_name] = theme.get(); 243 (*icon_themes)[theme_name] = theme.get();
239 } 244 }
240 return theme.release(); 245 return theme.release();
241 } 246 }
242 247
243 FilePath IconTheme::GetIconPathUnderSubdir(const std::string& icon_name, 248 FilePath IconTheme::GetIconPathUnderSubdir(const std::string& icon_name,
244 const std::string& subdir) { 249 const std::string& subdir) {
245 FilePath icon_path; 250 FilePath icon_path;
246 std::list<FilePath>::iterator dir_iter; 251 std::list<FilePath>::iterator dir_iter;
247 std::vector<std::string>* icon_formats = 252 MimeUtilConstants::IconFormats* icon_formats =
248 &MimeUtilConstants::GetInstance()->icon_formats_; 253 &MimeUtilConstants::GetInstance()->icon_formats_;
249 for (dir_iter = dirs_.begin(); dir_iter != dirs_.end(); ++dir_iter) { 254 for (dir_iter = dirs_.begin(); dir_iter != dirs_.end(); ++dir_iter) {
250 for (size_t i = 0; i < icon_formats->size(); ++i) { 255 for (size_t i = 0; i < icon_formats->size(); ++i) {
251 icon_path = dir_iter->Append(subdir); 256 icon_path = dir_iter->Append(subdir);
252 icon_path = icon_path.Append(icon_name + (*icon_formats)[i]); 257 icon_path = icon_path.Append(icon_name + (*icon_formats)[i]);
253 if (file_util::PathExists(icon_path)) 258 if (file_util::PathExists(icon_path))
254 return icon_path; 259 return icon_path;
255 } 260 }
256 } 261 }
257 return FilePath(); 262 return FilePath();
(...skipping 181 matching lines...) Expand 10 before | Expand all | Expand 10 after
439 444
440 // Per xdg theme spec, we should check the icon directories every so often for 445 // Per xdg theme spec, we should check the icon directories every so often for
441 // newly added icons. This isn't quite right. 446 // newly added icons. This isn't quite right.
442 void EnsureUpdated() { 447 void EnsureUpdated() {
443 struct timeval t; 448 struct timeval t;
444 gettimeofday(&t, NULL); 449 gettimeofday(&t, NULL);
445 time_t now = t.tv_sec; 450 time_t now = t.tv_sec;
446 MimeUtilConstants* constants = MimeUtilConstants::GetInstance(); 451 MimeUtilConstants* constants = MimeUtilConstants::GetInstance();
447 452
448 if (constants->last_check_time_ == 0) { 453 if (constants->last_check_time_ == 0) {
449 constants->icon_dirs_ = new std::map<FilePath, int>; 454 constants->icon_dirs_ = new MimeUtilConstants::IconDirMtimeMap;
450 constants->icon_themes_ = new std::map<std::string, IconTheme*>; 455 constants->icon_themes_ = new MimeUtilConstants::IconThemeMap;
451 InitIconDir(); 456 InitIconDir();
452 constants->last_check_time_ = now; 457 constants->last_check_time_ = now;
453 } else { 458 } else {
454 // TODO(thestig): something changed. start over. Upstream fix to Google 459 // TODO(thestig): something changed. start over. Upstream fix to Google
455 // Gadgets for Linux. 460 // Gadgets for Linux.
456 if (now > constants->last_check_time_ + constants->kUpdateInterval) { 461 if (now > constants->last_check_time_ + constants->kUpdateInterval) {
457 } 462 }
458 } 463 }
459 } 464 }
460 465
461 // Find a fallback icon if we cannot find it in the default theme. 466 // Find a fallback icon if we cannot find it in the default theme.
462 FilePath LookupFallbackIcon(const std::string& icon_name) { 467 FilePath LookupFallbackIcon(const std::string& icon_name) {
463 FilePath icon; 468 FilePath icon;
464 MimeUtilConstants* constants = MimeUtilConstants::GetInstance(); 469 MimeUtilConstants* constants = MimeUtilConstants::GetInstance();
465 std::map<FilePath, int>::iterator iter; 470 MimeUtilConstants::IconDirMtimeMap::iterator iter;
466 std::map<FilePath, int>* icon_dirs = constants->icon_dirs_; 471 MimeUtilConstants::IconDirMtimeMap* icon_dirs = constants->icon_dirs_;
467 std::vector<std::string>* icon_formats = &constants->icon_formats_; 472 MimeUtilConstants::IconFormats* icon_formats = &constants->icon_formats_;
468 for (iter = icon_dirs->begin(); iter != icon_dirs->end(); ++iter) { 473 for (iter = icon_dirs->begin(); iter != icon_dirs->end(); ++iter) {
469 for (size_t i = 0; i < icon_formats->size(); ++i) { 474 for (size_t i = 0; i < icon_formats->size(); ++i) {
470 icon = iter->first.Append(icon_name + (*icon_formats)[i]); 475 icon = iter->first.Append(icon_name + (*icon_formats)[i]);
471 if (file_util::PathExists(icon)) 476 if (file_util::PathExists(icon))
472 return icon; 477 return icon;
473 } 478 }
474 } 479 }
475 return FilePath(); 480 return FilePath();
476 } 481 }
477 482
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after
520 if (default_themes[j] == default_themes[i]) 525 if (default_themes[j] == default_themes[i])
521 default_themes[j] = NULL; 526 default_themes[j] = NULL;
522 } 527 }
523 } 528 }
524 } 529 }
525 530
526 // Try to find an icon with the name |icon_name| that's |size| pixels. 531 // Try to find an icon with the name |icon_name| that's |size| pixels.
527 FilePath LookupIconInDefaultTheme(const std::string& icon_name, int size) { 532 FilePath LookupIconInDefaultTheme(const std::string& icon_name, int size) {
528 EnsureUpdated(); 533 EnsureUpdated();
529 MimeUtilConstants* constants = MimeUtilConstants::GetInstance(); 534 MimeUtilConstants* constants = MimeUtilConstants::GetInstance();
530 std::map<std::string, IconTheme*>* icon_themes = constants->icon_themes_; 535 MimeUtilConstants::IconThemeMap* icon_themes = constants->icon_themes_;
531 if (icon_themes->empty()) 536 if (icon_themes->empty())
532 InitDefaultThemes(); 537 InitDefaultThemes();
533 538
534 FilePath icon_path; 539 FilePath icon_path;
535 IconTheme** default_themes = constants->default_themes_; 540 IconTheme** default_themes = constants->default_themes_;
536 for (size_t i = 0; i < MimeUtilConstants::kDefaultThemeNum; i++) { 541 for (size_t i = 0; i < MimeUtilConstants::kDefaultThemeNum; i++) {
537 if (default_themes[i]) { 542 if (default_themes[i]) {
538 icon_path = default_themes[i]->GetIconPath(icon_name, size, true); 543 icon_path = default_themes[i]->GetIconPath(icon_name, size, true);
539 if (!icon_path.empty()) 544 if (!icon_path.empty())
540 return icon_path; 545 return icon_path;
541 } 546 }
542 } 547 }
543 return LookupFallbackIcon(icon_name); 548 return LookupFallbackIcon(icon_name);
544 } 549 }
545 550
546 MimeUtilConstants::~MimeUtilConstants() { 551 MimeUtilConstants::~MimeUtilConstants() {
547 delete icon_dirs_; 552 delete icon_dirs_;
548 delete icon_themes_; 553 delete icon_themes_;
549 for (size_t i = 0; i < kDefaultThemeNum; i++) 554 for (size_t i = 0; i < kDefaultThemeNum; i++)
550 delete default_themes_[i]; 555 delete default_themes_[i];
551 } 556 }
552 557
553 } // namespace 558 } // namespace
554 559
555 namespace mime_util { 560 namespace mime_util {
556 561
557 std::string GetFileMimeType(const FilePath& filepath) { 562 std::string GetFileMimeType(const FilePath& filepath) {
558 base::ThreadRestrictions::AssertIOAllowed(); 563 base::ThreadRestrictions::AssertIOAllowed();
559 base::AutoLock scoped_lock(g_mime_util_xdg_lock); 564 base::AutoLock scoped_lock(g_mime_util_xdg_lock.Get());
560 return xdg_mime_get_mime_type_from_file_name(filepath.value().c_str()); 565 return xdg_mime_get_mime_type_from_file_name(filepath.value().c_str());
561 } 566 }
562 567
563 std::string GetDataMimeType(const std::string& data) { 568 std::string GetDataMimeType(const std::string& data) {
564 base::ThreadRestrictions::AssertIOAllowed(); 569 base::ThreadRestrictions::AssertIOAllowed();
565 base::AutoLock scoped_lock(g_mime_util_xdg_lock); 570 base::AutoLock scoped_lock(g_mime_util_xdg_lock.Get());
566 return xdg_mime_get_mime_type_for_data(data.data(), data.length(), NULL); 571 return xdg_mime_get_mime_type_for_data(data.data(), data.length(), NULL);
567 } 572 }
568 573
569 void DetectGtkTheme() { 574 void DetectGtkTheme() {
570 // If the theme name is already loaded, do nothing. Chrome doesn't respond 575 // If the theme name is already loaded, do nothing. Chrome doesn't respond
571 // to changes in the system theme, so we never need to set this more than 576 // to changes in the system theme, so we never need to set this more than
572 // once. 577 // once.
573 if (!MimeUtilConstants::GetInstance()->gtk_theme_name_.empty()) 578 if (!MimeUtilConstants::GetInstance()->gtk_theme_name_.empty())
574 return; 579 return;
575 580
576 // We should only be called on the UI thread. 581 // We should only be called on the UI thread.
577 DCHECK_EQ(MessageLoop::TYPE_UI, MessageLoop::current()->type()); 582 DCHECK_EQ(MessageLoop::TYPE_UI, MessageLoop::current()->type());
578 583
579 gchar* gtk_theme_name; 584 gchar* gtk_theme_name;
580 g_object_get(gtk_settings_get_default(), 585 g_object_get(gtk_settings_get_default(),
581 "gtk-icon-theme-name", 586 "gtk-icon-theme-name",
582 &gtk_theme_name, NULL); 587 &gtk_theme_name, NULL);
583 MimeUtilConstants::GetInstance()->gtk_theme_name_.assign(gtk_theme_name); 588 MimeUtilConstants::GetInstance()->gtk_theme_name_.assign(gtk_theme_name);
584 g_free(gtk_theme_name); 589 g_free(gtk_theme_name);
585 } 590 }
586 591
587 FilePath GetMimeIcon(const std::string& mime_type, size_t size) { 592 FilePath GetMimeIcon(const std::string& mime_type, size_t size) {
588 base::ThreadRestrictions::AssertIOAllowed(); 593 base::ThreadRestrictions::AssertIOAllowed();
589 std::vector<std::string> icon_names; 594 std::vector<std::string> icon_names;
590 std::string icon_name; 595 std::string icon_name;
591 FilePath icon_file; 596 FilePath icon_file;
592 597
593 { 598 {
594 base::AutoLock scoped_lock(g_mime_util_xdg_lock); 599 base::AutoLock scoped_lock(g_mime_util_xdg_lock.Get());
595 const char *icon = xdg_mime_get_icon(mime_type.c_str()); 600 const char *icon = xdg_mime_get_icon(mime_type.c_str());
596 icon_name = std::string(icon ? icon : ""); 601 icon_name = std::string(icon ? icon : "");
597 } 602 }
598 603
599 if (icon_name.length()) 604 if (icon_name.length())
600 icon_names.push_back(icon_name); 605 icon_names.push_back(icon_name);
601 606
602 // For text/plain, try text-plain. 607 // For text/plain, try text-plain.
603 icon_name = mime_type; 608 icon_name = mime_type;
604 for (size_t i = icon_name.find('/', 0); i != std::string::npos; 609 for (size_t i = icon_name.find('/', 0); i != std::string::npos;
(...skipping 23 matching lines...) Expand all
628 } else { 633 } else {
629 icon_file = LookupIconInDefaultTheme(icon_names[i], size); 634 icon_file = LookupIconInDefaultTheme(icon_names[i], size);
630 if (!icon_file.empty()) 635 if (!icon_file.empty())
631 return icon_file; 636 return icon_file;
632 } 637 }
633 } 638 }
634 return FilePath(); 639 return FilePath();
635 } 640 }
636 641
637 } // namespace mime_util 642 } // namespace mime_util
OLDNEW
« no previous file with comments | « no previous file | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698