Chromium Code Reviews| 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/extensions/bundle_installer.h" | 5 #include "chrome/browser/extensions/bundle_installer.h" |
| 6 | 6 |
| 7 #include <algorithm> | 7 #include <algorithm> |
| 8 #include <string> | 8 #include <string> |
| 9 #include <vector> | 9 #include <vector> |
| 10 | 10 |
| 11 #include "base/command_line.h" | 11 #include "base/command_line.h" |
| 12 #include "base/i18n/rtl.h" | 12 #include "base/i18n/rtl.h" |
| 13 #include "base/strings/utf_string_conversions.h" | 13 #include "base/strings/utf_string_conversions.h" |
| 14 #include "base/values.h" | 14 #include "base/values.h" |
| 15 #include "chrome/browser/extensions/crx_installer.h" | 15 #include "chrome/browser/extensions/crx_installer.h" |
| 16 #include "chrome/browser/extensions/permissions_updater.h" | 16 #include "chrome/browser/extensions/permissions_updater.h" |
| 17 #include "chrome/browser/profiles/profile.h" | 17 #include "chrome/browser/profiles/profile.h" |
| 18 #include "chrome/browser/ui/browser.h" | 18 #include "chrome/browser/ui/browser.h" |
| 19 #include "chrome/browser/ui/browser_finder.h" | 19 #include "chrome/browser/ui/browser_finder.h" |
| 20 #include "chrome/browser/ui/browser_list.h" | 20 #include "chrome/browser/ui/browser_list.h" |
| 21 #include "chrome/browser/ui/tabs/tab_strip_model.h" | 21 #include "chrome/browser/ui/tabs/tab_strip_model.h" |
| 22 #include "chrome/common/chrome_switches.h" | 22 #include "chrome/common/chrome_switches.h" |
| 23 #include "chrome/grit/generated_resources.h" | 23 #include "chrome/grit/generated_resources.h" |
| 24 #include "content/public/browser/web_contents.h" | 24 #include "content/public/browser/web_contents.h" |
| 25 #include "extensions/common/extension.h" | 25 #include "extensions/common/extension.h" |
| 26 #include "extensions/common/permissions/permission_set.h" | 26 #include "extensions/common/permissions/permission_set.h" |
| 27 #include "extensions/common/permissions/permissions_data.h" | 27 #include "extensions/common/permissions/permissions_data.h" |
| 28 #include "ui/base/l10n/l10n_util.h" | 28 #include "ui/base/l10n/l10n_util.h" |
| 29 #include "ui/gfx/image/image_skia.h" | |
| 29 | 30 |
| 30 namespace extensions { | 31 namespace extensions { |
| 31 | 32 |
| 32 namespace { | 33 namespace { |
| 33 | 34 |
| 34 enum AutoApproveForTest { | 35 enum AutoApproveForTest { |
| 35 DO_NOT_SKIP = 0, | 36 DO_NOT_SKIP = 0, |
| 36 PROCEED, | 37 PROCEED, |
| 37 ABORT | 38 ABORT |
| 38 }; | 39 }; |
| 39 | 40 |
| 40 AutoApproveForTest g_auto_approve_for_test = DO_NOT_SKIP; | 41 AutoApproveForTest g_auto_approve_for_test = DO_NOT_SKIP; |
| 41 | 42 |
| 42 // Creates a dummy extension and sets the manifest's name to the item's | |
| 43 // localized name. | |
| 44 scoped_refptr<Extension> CreateDummyExtension( | 43 scoped_refptr<Extension> CreateDummyExtension( |
| 45 const BundleInstaller::Item& item, | 44 const BundleInstaller::Item& item, |
| 46 base::DictionaryValue* manifest, | 45 const base::DictionaryValue& manifest, |
| 47 content::BrowserContext* browser_context) { | 46 content::BrowserContext* browser_context) { |
| 48 // We require localized names so we can have nice error messages when we can't | 47 // We require localized names so we can have nice error messages when we can't |
| 49 // parse an extension manifest. | 48 // parse an extension manifest. |
| 50 CHECK(!item.localized_name.empty()); | 49 CHECK(!item.localized_name.empty()); |
| 51 | 50 |
| 52 std::string error; | 51 std::string error; |
| 53 scoped_refptr<Extension> extension = Extension::Create(base::FilePath(), | 52 scoped_refptr<Extension> extension = Extension::Create(base::FilePath(), |
| 54 Manifest::INTERNAL, | 53 Manifest::INTERNAL, |
| 55 *manifest, | 54 manifest, |
| 56 Extension::NO_FLAGS, | 55 Extension::NO_FLAGS, |
| 57 item.id, | 56 item.id, |
| 58 &error); | 57 &error); |
| 59 // Initialize permissions so that withheld permissions are displayed properly | 58 // Initialize permissions so that withheld permissions are displayed properly |
| 60 // in the install prompt. | 59 // in the install prompt. |
| 61 PermissionsUpdater(browser_context, PermissionsUpdater::INIT_FLAG_TRANSIENT) | 60 PermissionsUpdater(browser_context, PermissionsUpdater::INIT_FLAG_TRANSIENT) |
| 62 .InitializePermissions(extension.get()); | 61 .InitializePermissions(extension.get()); |
| 63 return extension; | 62 return extension; |
| 64 } | 63 } |
| 65 | 64 |
| 66 bool IsAppPredicate(scoped_refptr<const Extension> extension) { | |
| 67 return extension->is_app(); | |
| 68 } | |
| 69 | |
| 70 struct MatchIdFunctor { | |
| 71 explicit MatchIdFunctor(const std::string& id) : id(id) {} | |
| 72 bool operator()(scoped_refptr<const Extension> extension) { | |
| 73 return extension->id() == id; | |
| 74 } | |
| 75 std::string id; | |
| 76 }; | |
| 77 | |
| 78 // Holds the message IDs for BundleInstaller::GetHeadingTextFor. | 65 // Holds the message IDs for BundleInstaller::GetHeadingTextFor. |
| 79 const int kHeadingIds[3][4] = { | 66 const int kHeadingIds[3][4] = { |
| 80 { | 67 { |
| 81 0, | 68 0, |
| 82 IDS_EXTENSION_BUNDLE_INSTALL_PROMPT_HEADING_EXTENSIONS, | 69 IDS_EXTENSION_BUNDLE_INSTALL_PROMPT_HEADING_EXTENSIONS, |
| 83 IDS_EXTENSION_BUNDLE_INSTALL_PROMPT_HEADING_APPS, | 70 IDS_EXTENSION_BUNDLE_INSTALL_PROMPT_HEADING_APPS, |
| 84 IDS_EXTENSION_BUNDLE_INSTALL_PROMPT_HEADING_EXTENSION_APPS | 71 IDS_EXTENSION_BUNDLE_INSTALL_PROMPT_HEADING_EXTENSION_APPS |
| 85 }, | 72 }, |
| 86 { | 73 { |
| 87 0, | 74 0, |
| 88 IDS_EXTENSION_BUNDLE_INSTALLED_HEADING_EXTENSIONS, | 75 IDS_EXTENSION_BUNDLE_INSTALLED_HEADING_EXTENSIONS, |
| 89 IDS_EXTENSION_BUNDLE_INSTALLED_HEADING_APPS, | 76 IDS_EXTENSION_BUNDLE_INSTALLED_HEADING_APPS, |
| 90 IDS_EXTENSION_BUNDLE_INSTALLED_HEADING_EXTENSION_APPS | 77 IDS_EXTENSION_BUNDLE_INSTALLED_HEADING_EXTENSION_APPS |
| 91 } | 78 } |
| 92 }; | 79 }; |
| 93 | 80 |
| 94 } // namespace | 81 } // namespace |
| 95 | 82 |
| 96 // static | 83 // static |
| 97 void BundleInstaller::SetAutoApproveForTesting(bool auto_approve) { | 84 void BundleInstaller::SetAutoApproveForTesting(bool auto_approve) { |
| 98 CHECK(base::CommandLine::ForCurrentProcess()->HasSwitch(switches::kTestType)); | 85 CHECK(base::CommandLine::ForCurrentProcess()->HasSwitch(switches::kTestType)); |
| 99 g_auto_approve_for_test = auto_approve ? PROCEED : ABORT; | 86 g_auto_approve_for_test = auto_approve ? PROCEED : ABORT; |
| 100 } | 87 } |
| 101 | 88 |
| 102 BundleInstaller::Item::Item() : state(STATE_PENDING) {} | 89 BundleInstaller::Item::Item() : state(STATE_PENDING) {} |
| 103 | 90 |
| 104 base::string16 BundleInstaller::Item::GetNameForDisplay() { | 91 BundleInstaller::Item::~Item() {} |
| 92 | |
| 93 base::string16 BundleInstaller::Item::GetNameForDisplay() const { | |
| 105 base::string16 name = base::UTF8ToUTF16(localized_name); | 94 base::string16 name = base::UTF8ToUTF16(localized_name); |
| 106 base::i18n::AdjustStringForLocaleDirection(&name); | 95 base::i18n::AdjustStringForLocaleDirection(&name); |
| 107 return l10n_util::GetStringFUTF16(IDS_EXTENSION_PERMISSION_LINE, name); | 96 return l10n_util::GetStringFUTF16(IDS_EXTENSION_PERMISSION_LINE, name); |
| 108 } | 97 } |
| 109 | 98 |
| 110 BundleInstaller::BundleInstaller(Browser* browser, | 99 BundleInstaller::BundleInstaller(Browser* browser, |
| 100 const std::string& name, | |
| 101 const SkBitmap& icon, | |
| 102 const std::string& authuser, | |
| 111 const BundleInstaller::ItemList& items) | 103 const BundleInstaller::ItemList& items) |
| 112 : approved_(false), | 104 : approved_(false), |
| 113 browser_(browser), | 105 browser_(browser), |
| 106 name_(name), | |
| 107 icon_(icon), | |
| 108 authuser_(authuser), | |
| 114 host_desktop_type_(browser->host_desktop_type()), | 109 host_desktop_type_(browser->host_desktop_type()), |
| 115 profile_(browser->profile()), | 110 profile_(browser->profile()) { |
| 116 delegate_(NULL) { | |
| 117 BrowserList::AddObserver(this); | 111 BrowserList::AddObserver(this); |
| 118 for (size_t i = 0; i < items.size(); ++i) { | 112 for (size_t i = 0; i < items.size(); ++i) { |
| 119 items_[items[i].id] = items[i]; | 113 items_[items[i].id] = items[i]; |
| 120 items_[items[i].id].state = Item::STATE_PENDING; | 114 items_[items[i].id].state = Item::STATE_PENDING; |
| 121 } | 115 } |
| 122 } | 116 } |
| 123 | 117 |
| 118 BundleInstaller::~BundleInstaller() { | |
| 119 BrowserList::RemoveObserver(this); | |
| 120 } | |
| 121 | |
| 124 BundleInstaller::ItemList BundleInstaller::GetItemsWithState( | 122 BundleInstaller::ItemList BundleInstaller::GetItemsWithState( |
| 125 Item::State state) const { | 123 Item::State state) const { |
| 126 ItemList list; | 124 ItemList list; |
| 127 | 125 |
| 128 for (ItemMap::const_iterator i = items_.begin(); i != items_.end(); ++i) { | 126 for (const std::pair<std::string, Item>& entry : items_) { |
| 129 if (i->second.state == state) | 127 if (entry.second.state == state) |
| 130 list.push_back(i->second); | 128 list.push_back(entry.second); |
| 131 } | 129 } |
| 132 | 130 |
| 133 return list; | 131 return list; |
| 134 } | 132 } |
| 135 | 133 |
| 136 void BundleInstaller::PromptForApproval(Delegate* delegate) { | 134 bool BundleInstaller::HasItemWithState(Item::State state) const { |
| 137 delegate_ = delegate; | 135 return CountItemsWithState(state) > 0; |
| 136 } | |
| 138 | 137 |
| 139 AddRef(); // Balanced in ReportApproved() and ReportCanceled(). | 138 size_t BundleInstaller::CountItemsWithState(Item::State state) const { |
| 139 return std::count_if(items_.begin(), items_.end(), | |
| 140 [&state] (const std::pair<std::string, Item>& entry) { | |
|
asargent_no_longer_on_chrome
2015/03/26 18:12:50
Is there any advantage to capturing state by refer
Marc Treib
2015/03/27 11:52:12
You're right, there's really no point to capturing
| |
| 141 return entry.second.state == state; | |
| 142 }); | |
| 143 } | |
| 144 | |
| 145 void BundleInstaller::PromptForApproval(const ApprovalCallback& callback) { | |
| 146 approval_callback_ = callback; | |
| 140 | 147 |
| 141 ParseManifests(); | 148 ParseManifests(); |
| 142 } | 149 } |
| 143 | 150 |
| 144 void BundleInstaller::CompleteInstall(content::WebContents* web_contents, | 151 void BundleInstaller::CompleteInstall(content::WebContents* web_contents, |
| 145 Delegate* delegate) { | 152 const base::Closure& callback) { |
| 153 DCHECK(web_contents); | |
| 146 CHECK(approved_); | 154 CHECK(approved_); |
| 147 | 155 |
| 148 delegate_ = delegate; | 156 install_callback_ = callback; |
| 149 | 157 |
| 150 AddRef(); // Balanced in ReportComplete(); | 158 if (!HasItemWithState(Item::STATE_PENDING)) { |
| 151 | 159 install_callback_.Run(); |
| 152 if (GetItemsWithState(Item::STATE_PENDING).empty()) { | |
| 153 ReportComplete(); | |
| 154 return; | 160 return; |
| 155 } | 161 } |
| 156 | 162 |
| 157 // Start each WebstoreInstaller. | 163 // Start each WebstoreInstaller. |
| 158 for (ItemMap::iterator i = items_.begin(); i != items_.end(); ++i) { | 164 for (const std::pair<std::string, Item>& entry : items_) { |
| 159 if (i->second.state != Item::STATE_PENDING) | 165 if (entry.second.state != Item::STATE_PENDING) |
| 160 continue; | 166 continue; |
| 161 | 167 |
| 162 // Since we've already confirmed the permissions, create an approval that | 168 // Since we've already confirmed the permissions, create an approval that |
| 163 // lets CrxInstaller bypass the prompt. | 169 // lets CrxInstaller bypass the prompt. |
| 164 scoped_ptr<WebstoreInstaller::Approval> approval( | 170 scoped_ptr<WebstoreInstaller::Approval> approval( |
| 165 WebstoreInstaller::Approval::CreateWithNoInstallPrompt( | 171 WebstoreInstaller::Approval::CreateWithNoInstallPrompt( |
| 166 profile_, | 172 profile_, |
| 167 i->first, | 173 entry.first, |
| 168 scoped_ptr<base::DictionaryValue>( | 174 make_scoped_ptr(parsed_manifests_[entry.first]->DeepCopy()), |
| 169 parsed_manifests_[i->first]->DeepCopy()), true)); | 175 true)); |
| 170 approval->use_app_installed_bubble = false; | 176 approval->use_app_installed_bubble = false; |
| 171 approval->skip_post_install_ui = true; | 177 approval->skip_post_install_ui = true; |
| 178 approval->authuser = authuser_; | |
| 179 approval->installing_icon = | |
| 180 gfx::ImageSkia::CreateFrom1xBitmap(entry.second.icon); | |
| 172 | 181 |
| 173 scoped_refptr<WebstoreInstaller> installer = new WebstoreInstaller( | 182 scoped_refptr<WebstoreInstaller> installer = new WebstoreInstaller( |
| 174 profile_, | 183 profile_, |
| 175 this, | 184 this, |
| 176 web_contents, | 185 web_contents, |
| 177 i->first, | 186 entry.first, |
| 178 approval.Pass(), | 187 approval.Pass(), |
| 179 WebstoreInstaller::INSTALL_SOURCE_OTHER); | 188 WebstoreInstaller::INSTALL_SOURCE_OTHER); |
| 180 installer->Start(); | 189 installer->Start(); |
| 181 } | 190 } |
| 182 } | 191 } |
| 183 | 192 |
| 184 base::string16 BundleInstaller::GetHeadingTextFor(Item::State state) const { | 193 base::string16 BundleInstaller::GetHeadingTextFor(Item::State state) const { |
| 185 // For STATE_FAILED, we can't tell if the items were apps or extensions | 194 // For STATE_FAILED, we can't tell if the items were apps or extensions |
| 186 // so we always show the same message. | 195 // so we always show the same message. |
| 187 if (state == Item::STATE_FAILED) { | 196 if (state == Item::STATE_FAILED) { |
| 188 if (GetItemsWithState(state).size()) | 197 if (HasItemWithState(state)) |
| 189 return l10n_util::GetStringUTF16(IDS_EXTENSION_BUNDLE_ERROR_HEADING); | 198 return l10n_util::GetStringUTF16(IDS_EXTENSION_BUNDLE_ERROR_HEADING); |
| 190 return base::string16(); | 199 return base::string16(); |
| 191 } | 200 } |
| 192 | 201 |
| 193 size_t total = GetItemsWithState(state).size(); | 202 size_t total = CountItemsWithState(state); |
| 194 size_t apps = std::count_if( | 203 size_t apps = std::count_if( |
| 195 dummy_extensions_.begin(), dummy_extensions_.end(), &IsAppPredicate); | 204 dummy_extensions_.begin(), dummy_extensions_.end(), |
| 205 [] (const scoped_refptr<const Extension>& ext) { return ext->is_app(); }); | |
| 196 | 206 |
| 197 bool has_apps = apps > 0; | 207 bool has_apps = apps > 0; |
| 198 bool has_extensions = apps < total; | 208 bool has_extensions = apps < total; |
| 199 size_t index = (has_extensions << 0) + (has_apps << 1); | 209 size_t index = (has_extensions << 0) + (has_apps << 1); |
| 200 | 210 |
| 201 CHECK_LT(static_cast<size_t>(state), arraysize(kHeadingIds)); | 211 CHECK_LT(static_cast<size_t>(state), arraysize(kHeadingIds)); |
| 202 CHECK_LT(index, arraysize(kHeadingIds[state])); | 212 CHECK_LT(index, arraysize(kHeadingIds[state])); |
| 203 | 213 |
| 204 int msg_id = kHeadingIds[state][index]; | 214 int msg_id = kHeadingIds[state][index]; |
| 205 if (!msg_id) | 215 if (!msg_id) |
| 206 return base::string16(); | 216 return base::string16(); |
| 207 | 217 |
| 218 // Only the "pending" message (in the confirmation prompt) contains the | |
| 219 // bundle name. | |
| 220 if (state == Item::STATE_PENDING) | |
| 221 return l10n_util::GetStringFUTF16(msg_id, base::UTF8ToUTF16(name_)); | |
| 222 | |
| 208 return l10n_util::GetStringUTF16(msg_id); | 223 return l10n_util::GetStringUTF16(msg_id); |
| 209 } | 224 } |
| 210 | 225 |
| 211 BundleInstaller::~BundleInstaller() { | |
| 212 BrowserList::RemoveObserver(this); | |
| 213 } | |
| 214 | |
| 215 void BundleInstaller::ParseManifests() { | 226 void BundleInstaller::ParseManifests() { |
| 216 if (items_.empty()) { | 227 if (items_.empty()) { |
| 217 ReportCanceled(false); | 228 approval_callback_.Run(APPROVAL_ERROR); |
| 218 return; | 229 return; |
| 219 } | 230 } |
| 220 | 231 |
| 221 for (ItemMap::iterator i = items_.begin(); i != items_.end(); ++i) { | 232 net::URLRequestContextGetter* context_getter = |
| 233 browser_ ? browser_->profile()->GetRequestContext() : nullptr; | |
| 234 | |
| 235 for (const std::pair<std::string, Item>& entry : items_) { | |
| 222 scoped_refptr<WebstoreInstallHelper> helper = new WebstoreInstallHelper( | 236 scoped_refptr<WebstoreInstallHelper> helper = new WebstoreInstallHelper( |
| 223 this, i->first, i->second.manifest, GURL(), nullptr); | 237 this, entry.first, entry.second.manifest, entry.second.icon_url, |
| 238 context_getter); | |
| 224 helper->Start(); | 239 helper->Start(); |
| 225 } | 240 } |
| 226 } | 241 } |
| 227 | 242 |
| 228 void BundleInstaller::ReportApproved() { | |
| 229 if (delegate_) | |
| 230 delegate_->OnBundleInstallApproved(); | |
| 231 | |
| 232 Release(); // Balanced in PromptForApproval(). | |
| 233 } | |
| 234 | |
| 235 void BundleInstaller::ReportCanceled(bool user_initiated) { | |
| 236 if (delegate_) | |
| 237 delegate_->OnBundleInstallCanceled(user_initiated); | |
| 238 | |
| 239 Release(); // Balanced in PromptForApproval(). | |
| 240 } | |
| 241 | |
| 242 void BundleInstaller::ReportComplete() { | |
| 243 if (delegate_) | |
| 244 delegate_->OnBundleInstallCompleted(); | |
| 245 | |
| 246 Release(); // Balanced in CompleteInstall(). | |
| 247 } | |
| 248 | |
| 249 void BundleInstaller::ShowPromptIfDoneParsing() { | 243 void BundleInstaller::ShowPromptIfDoneParsing() { |
| 250 // We don't prompt until all the manifests have been parsed. | 244 // We don't prompt until all the manifests have been parsed. |
| 251 ItemList pending_items = GetItemsWithState(Item::STATE_PENDING); | 245 if (CountItemsWithState(Item::STATE_PENDING) != dummy_extensions_.size()) |
| 252 if (pending_items.size() != dummy_extensions_.size()) | |
| 253 return; | 246 return; |
| 254 | 247 |
| 255 ShowPrompt(); | 248 ShowPrompt(); |
| 256 } | 249 } |
| 257 | 250 |
| 258 void BundleInstaller::ShowPrompt() { | 251 void BundleInstaller::ShowPrompt() { |
| 259 // Abort if we couldn't create any Extensions out of the manifests. | 252 // Abort if we couldn't create any Extensions out of the manifests. |
| 260 if (dummy_extensions_.empty()) { | 253 if (dummy_extensions_.empty()) { |
| 261 ReportCanceled(false); | 254 approval_callback_.Run(APPROVAL_ERROR); |
| 262 return; | 255 return; |
| 263 } | 256 } |
| 264 | 257 |
| 265 scoped_refptr<PermissionSet> permissions; | 258 scoped_refptr<PermissionSet> permissions; |
| 266 for (size_t i = 0; i < dummy_extensions_.size(); ++i) { | 259 for (size_t i = 0; i < dummy_extensions_.size(); ++i) { |
| 267 permissions = PermissionSet::CreateUnion( | 260 permissions = PermissionSet::CreateUnion( |
| 268 permissions.get(), | 261 permissions.get(), |
| 269 dummy_extensions_[i]->permissions_data()->active_permissions().get()); | 262 dummy_extensions_[i]->permissions_data()->active_permissions().get()); |
| 270 } | 263 } |
| 271 | 264 |
| (...skipping 11 matching lines...) Expand all Loading... | |
| 283 content::WebContents* web_contents = NULL; | 276 content::WebContents* web_contents = NULL; |
| 284 if (browser) | 277 if (browser) |
| 285 web_contents = browser->tab_strip_model()->GetActiveWebContents(); | 278 web_contents = browser->tab_strip_model()->GetActiveWebContents(); |
| 286 install_ui_.reset(new ExtensionInstallPrompt(web_contents)); | 279 install_ui_.reset(new ExtensionInstallPrompt(web_contents)); |
| 287 install_ui_->ConfirmBundleInstall(this, permissions.get()); | 280 install_ui_->ConfirmBundleInstall(this, permissions.get()); |
| 288 } | 281 } |
| 289 } | 282 } |
| 290 | 283 |
| 291 void BundleInstaller::ShowInstalledBubbleIfDone() { | 284 void BundleInstaller::ShowInstalledBubbleIfDone() { |
| 292 // We're ready to show the installed bubble when no items are pending. | 285 // We're ready to show the installed bubble when no items are pending. |
| 293 if (!GetItemsWithState(Item::STATE_PENDING).empty()) | 286 if (HasItemWithState(Item::STATE_PENDING)) |
| 294 return; | 287 return; |
| 295 | 288 |
| 296 if (browser_) | 289 if (browser_) |
| 297 ShowInstalledBubble(this, browser_); | 290 ShowInstalledBubble(this, browser_); |
| 298 | 291 |
| 299 ReportComplete(); | 292 install_callback_.Run(); |
| 300 } | 293 } |
| 301 | 294 |
| 302 void BundleInstaller::OnWebstoreParseSuccess( | 295 void BundleInstaller::OnWebstoreParseSuccess( |
| 303 const std::string& id, | 296 const std::string& id, |
| 304 const SkBitmap& icon, | 297 const SkBitmap& icon, |
| 305 base::DictionaryValue* manifest) { | 298 base::DictionaryValue* manifest) { |
| 299 items_[id].icon = icon; | |
| 306 dummy_extensions_.push_back( | 300 dummy_extensions_.push_back( |
| 307 CreateDummyExtension(items_[id], manifest, profile_)); | 301 CreateDummyExtension(items_[id], *manifest, profile_)); |
| 308 parsed_manifests_[id] = linked_ptr<base::DictionaryValue>(manifest); | 302 parsed_manifests_[id] = linked_ptr<base::DictionaryValue>(manifest); |
| 309 | 303 |
| 310 ShowPromptIfDoneParsing(); | 304 ShowPromptIfDoneParsing(); |
| 311 } | 305 } |
| 312 | 306 |
| 313 void BundleInstaller::OnWebstoreParseFailure( | 307 void BundleInstaller::OnWebstoreParseFailure( |
| 314 const std::string& id, | 308 const std::string& id, |
| 315 WebstoreInstallHelper::Delegate::InstallHelperResultCode result_code, | 309 WebstoreInstallHelper::Delegate::InstallHelperResultCode result_code, |
| 316 const std::string& error_message) { | 310 const std::string& error_message) { |
| 317 items_[id].state = Item::STATE_FAILED; | 311 items_[id].state = Item::STATE_FAILED; |
| 318 | 312 |
| 319 ShowPromptIfDoneParsing(); | 313 ShowPromptIfDoneParsing(); |
| 320 } | 314 } |
| 321 | 315 |
| 322 void BundleInstaller::InstallUIProceed() { | 316 void BundleInstaller::InstallUIProceed() { |
| 323 approved_ = true; | 317 approved_ = true; |
| 324 ReportApproved(); | 318 approval_callback_.Run(APPROVED); |
| 325 } | 319 } |
| 326 | 320 |
| 327 void BundleInstaller::InstallUIAbort(bool user_initiated) { | 321 void BundleInstaller::InstallUIAbort(bool user_initiated) { |
| 328 for (ItemMap::iterator i = items_.begin(); i != items_.end(); ++i) | 322 for (std::pair<const std::string, Item>& entry : items_) |
| 329 i->second.state = Item::STATE_FAILED; | 323 entry.second.state = Item::STATE_FAILED; |
| 330 | 324 |
| 331 ReportCanceled(user_initiated); | 325 approval_callback_.Run(user_initiated ? USER_CANCELED : APPROVAL_ERROR); |
| 332 } | 326 } |
| 333 | 327 |
| 334 void BundleInstaller::OnExtensionInstallSuccess(const std::string& id) { | 328 void BundleInstaller::OnExtensionInstallSuccess(const std::string& id) { |
| 335 items_[id].state = Item::STATE_INSTALLED; | 329 items_[id].state = Item::STATE_INSTALLED; |
| 336 | 330 |
| 337 ShowInstalledBubbleIfDone(); | 331 ShowInstalledBubbleIfDone(); |
| 338 } | 332 } |
| 339 | 333 |
| 340 void BundleInstaller::OnExtensionInstallFailure( | 334 void BundleInstaller::OnExtensionInstallFailure( |
| 341 const std::string& id, | 335 const std::string& id, |
| 342 const std::string& error, | 336 const std::string& error, |
| 343 WebstoreInstaller::FailureReason reason) { | 337 WebstoreInstaller::FailureReason reason) { |
| 344 items_[id].state = Item::STATE_FAILED; | 338 items_[id].state = Item::STATE_FAILED; |
| 345 | 339 |
| 346 ExtensionList::iterator i = std::find_if( | 340 ExtensionList::iterator i = std::find_if( |
| 347 dummy_extensions_.begin(), dummy_extensions_.end(), MatchIdFunctor(id)); | 341 dummy_extensions_.begin(), dummy_extensions_.end(), |
| 342 [&id] (const scoped_refptr<const Extension>& ext) { | |
| 343 return ext->id() == id; | |
| 344 }); | |
| 348 CHECK(dummy_extensions_.end() != i); | 345 CHECK(dummy_extensions_.end() != i); |
| 349 dummy_extensions_.erase(i); | 346 dummy_extensions_.erase(i); |
| 350 | 347 |
| 351 ShowInstalledBubbleIfDone(); | 348 ShowInstalledBubbleIfDone(); |
| 352 } | 349 } |
| 353 | 350 |
| 354 void BundleInstaller::OnBrowserAdded(Browser* browser) {} | |
| 355 | |
| 356 void BundleInstaller::OnBrowserRemoved(Browser* browser) { | 351 void BundleInstaller::OnBrowserRemoved(Browser* browser) { |
| 357 if (browser_ == browser) | 352 if (browser_ == browser) |
| 358 browser_ = NULL; | 353 browser_ = nullptr; |
| 359 } | 354 } |
| 360 | 355 |
| 361 void BundleInstaller::OnBrowserSetLastActive(Browser* browser) {} | |
| 362 | |
| 363 } // namespace extensions | 356 } // namespace extensions |
| OLD | NEW |