15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Copyright (c) 2012 The Chromium Authors. All rights reserved.
25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file.
45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/extensions/extension_uninstall_dialog.h"
65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
72a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/bind.h"
85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/logging.h"
9ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch#include "base/message_loop/message_loop.h"
10a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#include "base/strings/utf_string_conversions.h"
115c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu#include "chrome/browser/extensions/extension_util.h"
121e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)#include "chrome/browser/profiles/profile.h"
1303b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)#include "chrome/grit/generated_resources.h"
14cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)#include "extensions/browser/extension_registry.h"
156d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)#include "extensions/browser/image_loader.h"
16c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch#include "extensions/common/constants.h"
17f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#include "extensions/common/extension.h"
18c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch#include "extensions/common/extension_icon_set.h"
192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "extensions/common/extension_resource.h"
20c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch#include "extensions/common/manifest_handlers/icons_handler.h"
21a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#include "ui/base/l10n/l10n_util.h"
225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/gfx/image/image.h"
2368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)#include "ui/gfx/image/image_skia.h"
245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)namespace extensions {
265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)namespace {
285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Returns bitmap for the default icon with size equal to the default icon's
305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// pixel size under maximal supported scale factor.
315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)SkBitmap GetDefaultIconBitmapForMaxScaleFactor(bool is_app) {
3246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  const gfx::ImageSkia& image =
3346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)      is_app ? util::GetDefaultAppIcon() : util::GetDefaultExtensionIcon();
3468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  return image.GetRepresentation(
3568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)      gfx::ImageSkia::GetMaxSupportedScale()).sk_bitmap();
365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}  // namespace
395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)ExtensionUninstallDialog::ExtensionUninstallDialog(
412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    Profile* profile,
425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ExtensionUninstallDialog::Delegate* delegate)
432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    : profile_(profile),
445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      delegate_(delegate),
455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      extension_(NULL),
46a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      triggering_extension_(NULL),
4790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      ui_loop_(base::MessageLoop::current()) {
485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)ExtensionUninstallDialog::~ExtensionUninstallDialog() {
515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
53a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)void ExtensionUninstallDialog::ConfirmProgrammaticUninstall(
5446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    const Extension* extension,
5546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    const Extension* triggering_extension) {
56a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  triggering_extension_ = triggering_extension;
57a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  ConfirmUninstall(extension);
58a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)}
59a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
6046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)void ExtensionUninstallDialog::ConfirmUninstall(const Extension* extension) {
6190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  DCHECK(ui_loop_ == base::MessageLoop::current());
625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  extension_ = extension;
6346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  // Bookmark apps may not have 128x128 icons so accept 64x64 icons.
645d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  const int icon_size = extension_->from_bookmark()
6546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)                            ? extension_misc::EXTENSION_ICON_SMALL * 2
6646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)                            : extension_misc::EXTENSION_ICON_LARGE;
6746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  ExtensionResource image = IconsInfo::GetIconResource(
6846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)      extension_, icon_size, ExtensionIconSet::MATCH_BIGGER);
692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Load the image asynchronously. The response will be sent to OnImageLoaded.
7146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  ImageLoader* loader = ImageLoader::Get(profile_);
7246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)
735f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  SetIcon(gfx::Image());
7446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  std::vector<ImageLoader::ImageRepresentation> images_list;
7546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  images_list.push_back(ImageLoader::ImageRepresentation(
7646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)      image,
7746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)      ImageLoader::ImageRepresentation::NEVER_RESIZE,
7846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)      gfx::Size(),
7946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)      ui::SCALE_FACTOR_100P));
8046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  loader->LoadImagesAsync(extension_,
8146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)                          images_list,
8246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)                          base::Bind(&ExtensionUninstallDialog::OnImageLoaded,
8346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)                                     AsWeakPtr(),
8446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)                                     extension_->id()));
855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void ExtensionUninstallDialog::SetIcon(const gfx::Image& image) {
885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (image.IsEmpty()) {
895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Let's set default icon bitmap whose size is equal to the default icon's
905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // pixel size under maximal supported scale factor. If the bitmap is larger
915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // than the one we need, it will be scaled down by the ui code.
925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // TODO(tbarzic): We should use IconImage here and load the required bitmap
935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    //     lazily.
942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    icon_ = gfx::ImageSkia::CreateFrom1xBitmap(
955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        GetDefaultIconBitmapForMaxScaleFactor(extension_->is_app()));
965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  } else {
975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    icon_ = *image.ToImageSkia();
985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
101cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)void ExtensionUninstallDialog::OnImageLoaded(const std::string& extension_id,
102cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)                                             const gfx::Image& image) {
10346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  const Extension* target_extension =
10446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)      ExtensionRegistry::Get(profile_)
10546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)          ->GetExtensionById(extension_id, ExtensionRegistry::EVERYTHING);
106cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  if (!target_extension) {
107cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    delegate_->ExtensionUninstallCanceled();
108cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    return;
109cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  }
110cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
1115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SetIcon(image);
1125f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  Show();
1132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
114a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
115a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)std::string ExtensionUninstallDialog::GetHeadingText() {
116a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  if (triggering_extension_) {
117a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    return l10n_util::GetStringFUTF8(
118a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)        IDS_EXTENSION_PROGRAMMATIC_UNINSTALL_PROMPT_HEADING,
119a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)        base::UTF8ToUTF16(triggering_extension_->name()),
120a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)        base::UTF8ToUTF16(extension_->name()));
121a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  }
122a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  return l10n_util::GetStringFUTF8(IDS_EXTENSION_UNINSTALL_PROMPT_HEADING,
123a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)                                   base::UTF8ToUTF16(extension_->name()));
124a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)}
12546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)
12646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)}  // namespace extensions
127