Upstream version 5.34.104.0
[platform/framework/web/crosswalk.git] / src / chrome / browser / extensions / extension_uninstall_dialog.cc
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 "chrome/browser/extensions/extension_uninstall_dialog.h"
6
7 #include "base/bind.h"
8 #include "base/logging.h"
9 #include "base/message_loop/message_loop.h"
10 #include "chrome/browser/chrome_notification_types.h"
11 #include "chrome/browser/extensions/image_loader.h"
12 #include "chrome/browser/profiles/profile.h"
13 #include "chrome/browser/ui/browser.h"
14 #include "chrome/common/extensions/extension_constants.h"
15 #include "chrome/common/extensions/extension_icon_set.h"
16 #include "chrome/common/extensions/manifest_handlers/icons_handler.h"
17 #include "content/public/browser/notification_service.h"
18 #include "content/public/browser/notification_source.h"
19 #include "extensions/common/extension.h"
20 #include "extensions/common/extension_resource.h"
21 #include "grit/generated_resources.h"
22 #include "grit/theme_resources.h"
23 #include "ui/base/resource/resource_bundle.h"
24 #include "ui/gfx/image/image.h"
25 #include "ui/gfx/image/image_skia.h"
26
27 namespace {
28
29 // Returns pixel size under maximal scale factor for the icon whose device
30 // independent size is |size_in_dip|
31 int GetSizeForMaxScaleFactor(int size_in_dip) {
32   float max_scale_factor_scale = gfx::ImageSkia::GetMaxSupportedScale();
33
34   return static_cast<int>(size_in_dip * max_scale_factor_scale);
35 }
36
37 // Returns bitmap for the default icon with size equal to the default icon's
38 // pixel size under maximal supported scale factor.
39 SkBitmap GetDefaultIconBitmapForMaxScaleFactor(bool is_app) {
40   const gfx::ImageSkia& image = is_app ?
41       extensions::IconsInfo::GetDefaultAppIcon() :
42       extensions::IconsInfo::GetDefaultExtensionIcon();
43   return image.GetRepresentation(
44       gfx::ImageSkia::GetMaxSupportedScale()).sk_bitmap();
45 }
46
47 }  // namespace
48
49 // Size of extension icon in top left of dialog.
50 static const int kIconSize = 69;
51
52 ExtensionUninstallDialog::ExtensionUninstallDialog(
53     Profile* profile,
54     Browser* browser,
55     ExtensionUninstallDialog::Delegate* delegate)
56     : profile_(profile),
57       browser_(browser),
58       delegate_(delegate),
59       extension_(NULL),
60       state_(kImageIsLoading),
61       ui_loop_(base::MessageLoop::current()) {
62   if (browser) {
63     registrar_.Add(this,
64                    chrome::NOTIFICATION_BROWSER_CLOSED,
65                    content::Source<Browser>(browser));
66   }
67 }
68
69 ExtensionUninstallDialog::~ExtensionUninstallDialog() {
70 }
71
72 void ExtensionUninstallDialog::ConfirmUninstall(
73     const extensions::Extension* extension) {
74   DCHECK(ui_loop_ == base::MessageLoop::current());
75   extension_ = extension;
76   // Bookmark apps may not have 128x128 icons so accept 48x48 icons.
77   const int icon_size = extension_->from_bookmark()
78       ? extension_misc::EXTENSION_ICON_MEDIUM
79       : extension_misc::EXTENSION_ICON_LARGE;
80   extensions::ExtensionResource image = extensions::IconsInfo::GetIconResource(
81       extension_,
82       icon_size,
83       ExtensionIconSet::MATCH_BIGGER);
84   // Load the icon whose pixel size is large enough to be displayed under
85   // maximal supported scale factor. UI code will scale the icon down if needed.
86   int pixel_size = GetSizeForMaxScaleFactor(kIconSize);
87
88   // Load the image asynchronously. The response will be sent to OnImageLoaded.
89   state_ = kImageIsLoading;
90   extensions::ImageLoader* loader =
91       extensions::ImageLoader::Get(profile_);
92   loader->LoadImageAsync(extension_, image,
93                          gfx::Size(pixel_size, pixel_size),
94                          base::Bind(&ExtensionUninstallDialog::OnImageLoaded,
95                                     AsWeakPtr()));
96 }
97
98 void ExtensionUninstallDialog::SetIcon(const gfx::Image& image) {
99   if (image.IsEmpty()) {
100     // Let's set default icon bitmap whose size is equal to the default icon's
101     // pixel size under maximal supported scale factor. If the bitmap is larger
102     // than the one we need, it will be scaled down by the ui code.
103     // TODO(tbarzic): We should use IconImage here and load the required bitmap
104     //     lazily.
105     icon_ = gfx::ImageSkia::CreateFrom1xBitmap(
106         GetDefaultIconBitmapForMaxScaleFactor(extension_->is_app()));
107   } else {
108     icon_ = *image.ToImageSkia();
109   }
110 }
111
112 void ExtensionUninstallDialog::OnImageLoaded(const gfx::Image& image) {
113   SetIcon(image);
114
115   // Show the dialog unless the browser has been closed while we were waiting
116   // for the image.
117   DCHECK(state_ == kImageIsLoading || state_ == kBrowserIsClosing);
118   if (state_ == kImageIsLoading) {
119     state_ = kDialogIsShowing;
120     Show();
121   }
122 }
123
124 void ExtensionUninstallDialog::Observe(
125     int type,
126     const content::NotificationSource& source,
127     const content::NotificationDetails& details) {
128   DCHECK(type == chrome::NOTIFICATION_BROWSER_CLOSED);
129
130   browser_ = NULL;
131   // If the browser is closed while waiting for the image, we need to send a
132   // "cancel" event here, because there will not be another opportunity to
133   // notify the delegate of the cancellation as we won't open the dialog.
134   if (state_ == kImageIsLoading) {
135     state_ = kBrowserIsClosing;
136     delegate_->ExtensionUninstallCanceled();
137   }
138 }