| 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 #include "chrome/browser/web_applications/web_app.h" | 5 #include "chrome/browser/web_applications/web_app.h" |
| 6 | 6 |
| 7 #include <shlobj.h> | 7 #include <shlobj.h> |
| 8 | 8 |
| 9 #include "base/command_line.h" | 9 #include "base/command_line.h" |
| 10 #include "base/file_util.h" | 10 #include "base/file_util.h" |
| 11 #include "base/logging.h" | 11 #include "base/logging.h" |
| 12 #include "base/md5.h" | |
| 13 #include "base/path_service.h" | 12 #include "base/path_service.h" |
| 14 #include "base/stringprintf.h" | 13 #include "base/stringprintf.h" |
| 15 #include "base/strings/string_piece.h" | 14 #include "base/strings/string_piece.h" |
| 16 #include "base/utf_string_conversions.h" | 15 #include "base/utf_string_conversions.h" |
| 17 #include "base/win/shortcut.h" | 16 #include "base/win/shortcut.h" |
| 18 #include "base/win/windows_version.h" | 17 #include "base/win/windows_version.h" |
| 19 #include "chrome/common/chrome_switches.h" | 18 #include "chrome/common/chrome_switches.h" |
| 20 #include "chrome/installer/launcher_support/chrome_launcher_support.h" | 19 #include "chrome/installer/launcher_support/chrome_launcher_support.h" |
| 21 #include "chrome/installer/util/util_constants.h" | 20 #include "chrome/installer/util/util_constants.h" |
| 22 #include "content/public/browser/browser_thread.h" | 21 #include "content/public/browser/browser_thread.h" |
| 23 #include "grit/chromium_strings.h" | 22 #include "grit/chromium_strings.h" |
| 24 #include "ui/base/l10n/l10n_util.h" | 23 #include "ui/base/l10n/l10n_util.h" |
| 25 #include "ui/gfx/icon_util.h" | 24 #include "ui/gfx/icon_util.h" |
| 26 #include "ui/gfx/image/image.h" | 25 #include "ui/gfx/image/image.h" |
| 27 #include "ui/gfx/image/image_family.h" | 26 #include "ui/gfx/image/image_family.h" |
| 28 | 27 |
| 29 namespace { | 28 namespace { |
| 30 | 29 |
| 31 const base::FilePath::CharType kIconChecksumFileExt[] = | |
| 32 FILE_PATH_LITERAL(".ico.md5"); | |
| 33 | |
| 34 // Width and height of icons exported to .ico files. | |
| 35 | |
| 36 // Calculates checksum of an icon family using MD5. | |
| 37 // The checksum is derived from all of the icons in the family. | |
| 38 void GetImageCheckSum(const gfx::ImageFamily& image, base::MD5Digest* digest) { | |
| 39 DCHECK(digest); | |
| 40 base::MD5Context md5_context; | |
| 41 base::MD5Init(&md5_context); | |
| 42 | |
| 43 for (gfx::ImageFamily::const_iterator it = image.begin(); it != image.end(); | |
| 44 ++it) { | |
| 45 SkBitmap bitmap = it->AsBitmap(); | |
| 46 | |
| 47 SkAutoLockPixels image_lock(bitmap); | |
| 48 base::StringPiece image_data( | |
| 49 reinterpret_cast<const char*>(bitmap.getPixels()), bitmap.getSize()); | |
| 50 base::MD5Update(&md5_context, image_data); | |
| 51 } | |
| 52 | |
| 53 base::MD5Final(digest, &md5_context); | |
| 54 } | |
| 55 | |
| 56 // Saves |image| as an |icon_file| with the checksum. | |
| 57 bool SaveIconWithCheckSum(const base::FilePath& icon_file, | |
| 58 const gfx::ImageFamily& image) { | |
| 59 if (!IconUtil::CreateIconFileFromImageFamily(image, icon_file)) | |
| 60 return false; | |
| 61 | |
| 62 base::MD5Digest digest; | |
| 63 GetImageCheckSum(image, &digest); | |
| 64 | |
| 65 base::FilePath cheksum_file(icon_file.ReplaceExtension(kIconChecksumFileExt)); | |
| 66 return file_util::WriteFile(cheksum_file, | |
| 67 reinterpret_cast<const char*>(&digest), | |
| 68 sizeof(digest)) == sizeof(digest); | |
| 69 } | |
| 70 | |
| 71 // Returns true if |icon_file| is missing or different from |image|. | |
| 72 bool ShouldUpdateIcon(const base::FilePath& icon_file, | |
| 73 const gfx::ImageFamily& image) { | |
| 74 base::FilePath checksum_file( | |
| 75 icon_file.ReplaceExtension(kIconChecksumFileExt)); | |
| 76 | |
| 77 // Returns true if icon_file or checksum file is missing. | |
| 78 if (!file_util::PathExists(icon_file) || | |
| 79 !file_util::PathExists(checksum_file)) | |
| 80 return true; | |
| 81 | |
| 82 base::MD5Digest persisted_image_checksum; | |
| 83 if (sizeof(persisted_image_checksum) != file_util::ReadFile(checksum_file, | |
| 84 reinterpret_cast<char*>(&persisted_image_checksum), | |
| 85 sizeof(persisted_image_checksum))) | |
| 86 return true; | |
| 87 | |
| 88 base::MD5Digest downloaded_image_checksum; | |
| 89 GetImageCheckSum(image, &downloaded_image_checksum); | |
| 90 | |
| 91 // Update icon if checksums are not equal. | |
| 92 return memcmp(&persisted_image_checksum, &downloaded_image_checksum, | |
| 93 sizeof(base::MD5Digest)) != 0; | |
| 94 } | |
| 95 | |
| 96 bool ShortcutIsForProfile(const base::FilePath& shortcut_file_name, | 30 bool ShortcutIsForProfile(const base::FilePath& shortcut_file_name, |
| 97 const base::FilePath& profile_path) { | 31 const base::FilePath& profile_path) { |
| 98 string16 cmd_line_string; | 32 string16 cmd_line_string; |
| 99 if (base::win::ResolveShortcut(shortcut_file_name, NULL, &cmd_line_string)) { | 33 if (base::win::ResolveShortcut(shortcut_file_name, NULL, &cmd_line_string)) { |
| 100 cmd_line_string = L"program " + cmd_line_string; | 34 cmd_line_string = L"program " + cmd_line_string; |
| 101 CommandLine shortcut_cmd_line = CommandLine::FromString(cmd_line_string); | 35 CommandLine shortcut_cmd_line = CommandLine::FromString(cmd_line_string); |
| 102 return shortcut_cmd_line.HasSwitch(switches::kProfileDirectory) && | 36 return shortcut_cmd_line.HasSwitch(switches::kProfileDirectory) && |
| 103 shortcut_cmd_line.GetSwitchValuePath(switches::kProfileDirectory) == | 37 shortcut_cmd_line.GetSwitchValuePath(switches::kProfileDirectory) == |
| 104 profile_path.BaseName(); | 38 profile_path.BaseName(); |
| 105 } | 39 } |
| (...skipping 29 matching lines...) Expand all Loading... |
| 135 | 69 |
| 136 namespace web_app { | 70 namespace web_app { |
| 137 | 71 |
| 138 namespace internals { | 72 namespace internals { |
| 139 | 73 |
| 140 // Saves |image| to |icon_file| if the file is outdated and refresh shell's | 74 // Saves |image| to |icon_file| if the file is outdated and refresh shell's |
| 141 // icon cache to ensure correct icon is displayed. Returns true if icon_file | 75 // icon cache to ensure correct icon is displayed. Returns true if icon_file |
| 142 // is up to date or successfully updated. | 76 // is up to date or successfully updated. |
| 143 bool CheckAndSaveIcon(const base::FilePath& icon_file, | 77 bool CheckAndSaveIcon(const base::FilePath& icon_file, |
| 144 const gfx::ImageFamily& image) { | 78 const gfx::ImageFamily& image) { |
| 145 if (ShouldUpdateIcon(icon_file, image)) { | 79 if (IconUtil::ShouldUpdateIcon(icon_file, image)) { |
| 146 if (SaveIconWithCheckSum(icon_file, image)) { | 80 if (IconUtil::SaveIconWithCheckSum(icon_file, image)) { |
| 147 // Refresh shell's icon cache. This call is quite disruptive as user would | 81 // Refresh shell's icon cache. This call is quite disruptive as user would |
| 148 // see explorer rebuilding the icon cache. It would be great that we find | 82 // see explorer rebuilding the icon cache. It would be great that we find |
| 149 // a better way to achieve this. | 83 // a better way to achieve this. |
| 150 SHChangeNotify(SHCNE_ASSOCCHANGED, SHCNF_IDLIST | SHCNF_FLUSHNOWAIT, | 84 SHChangeNotify(SHCNE_ASSOCCHANGED, SHCNF_IDLIST | SHCNF_FLUSHNOWAIT, |
| 151 NULL, NULL); | 85 NULL, NULL); |
| 152 } else { | 86 } else { |
| 153 return false; | 87 return false; |
| 154 } | 88 } |
| 155 } | 89 } |
| 156 | 90 |
| (...skipping 220 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 377 path = path.Append(locations[i].subdir); | 311 path = path.Append(locations[i].subdir); |
| 378 shortcut_paths.push_back(path); | 312 shortcut_paths.push_back(path); |
| 379 } | 313 } |
| 380 } | 314 } |
| 381 return shortcut_paths; | 315 return shortcut_paths; |
| 382 } | 316 } |
| 383 | 317 |
| 384 } // namespace internals | 318 } // namespace internals |
| 385 | 319 |
| 386 } // namespace web_app | 320 } // namespace web_app |
| OLD | NEW |