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/plugins/plugin_installer.h" 65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/bind.h" 85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/bind_helpers.h" 9bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch#include "base/process/process.h" 107dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch#include "base/strings/stringprintf.h" 11ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch#include "chrome/browser/download/download_stats.h" 125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/platform_util.h" 135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/plugins/plugin_installer_observer.h" 145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/public/browser/browser_context.h" 155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/public/browser/download_item.h" 160529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch#include "content/public/browser/download_manager.h" 175d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "content/public/browser/download_url_parameters.h" 185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/public/browser/web_contents.h" 195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using content::DownloadItem; 215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)PluginInstaller::PluginInstaller() 23424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) : state_(INSTALLER_STATE_IDLE), 24424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) strong_observer_count_(0) { 255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)PluginInstaller::~PluginInstaller() { 285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void PluginInstaller::OnDownloadUpdated(DownloadItem* download) { 315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DownloadItem::DownloadState state = download->GetState(); 325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) switch (state) { 335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case DownloadItem::IN_PROGRESS: 345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case DownloadItem::COMPLETE: { 365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK_EQ(INSTALLER_STATE_DOWNLOADING, state_); 375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) state_ = INSTALLER_STATE_IDLE; 385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) FOR_EACH_OBSERVER(PluginInstallerObserver, observers_, 395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DownloadFinished()); 405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case DownloadItem::CANCELLED: { 435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DownloadCancelled(); 445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case DownloadItem::INTERRUPTED: { 475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) content::DownloadInterruptReason reason = download->GetLastReason(); 485d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) DownloadError(content::DownloadInterruptReasonToString(reason)); 495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case DownloadItem::MAX_DOWNLOAD_STATE: { 525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NOTREACHED(); 535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) download->RemoveObserver(this); 575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void PluginInstaller::OnDownloadDestroyed(DownloadItem* download) { 605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK_EQ(INSTALLER_STATE_DOWNLOADING, state_); 615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) state_ = INSTALLER_STATE_IDLE; 625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) download->RemoveObserver(this); 635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void PluginInstaller::AddObserver(PluginInstallerObserver* observer) { 66424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) strong_observer_count_++; 675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) observers_.AddObserver(observer); 685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void PluginInstaller::RemoveObserver(PluginInstallerObserver* observer) { 71424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) strong_observer_count_--; 725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) observers_.RemoveObserver(observer); 73424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) if (strong_observer_count_ == 0) { 745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) FOR_EACH_OBSERVER(WeakPluginInstallerObserver, weak_observers_, 755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) OnlyWeakObserversLeft()); 765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void PluginInstaller::AddWeakObserver(WeakPluginInstallerObserver* observer) { 805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) weak_observers_.AddObserver(observer); 815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void PluginInstaller::RemoveWeakObserver( 845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) WeakPluginInstallerObserver* observer) { 855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) weak_observers_.RemoveObserver(observer); 865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void PluginInstaller::StartInstalling(const GURL& plugin_url, 895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) content::WebContents* web_contents) { 900529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch content::DownloadManager* download_manager = 910529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch content::BrowserContext::GetDownloadManager( 920529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch web_contents->GetBrowserContext()); 930529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch StartInstallingWithDownloadManager( 940529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch plugin_url, web_contents, download_manager); 950529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch} 960529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch 970529e5d033099cbfc42635f6f6183833b09dff6eBen Murdochvoid PluginInstaller::StartInstallingWithDownloadManager( 980529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch const GURL& plugin_url, 990529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch content::WebContents* web_contents, 1000529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch content::DownloadManager* download_manager) { 1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK_EQ(INSTALLER_STATE_IDLE, state_); 1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) state_ = INSTALLER_STATE_DOWNLOADING; 1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) FOR_EACH_OBSERVER(PluginInstallerObserver, observers_, DownloadStarted()); 1040529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch scoped_ptr<content::DownloadUrlParameters> download_parameters( 1050529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch content::DownloadUrlParameters::FromWebContents(web_contents, 1060529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch plugin_url)); 1070529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch download_parameters->set_callback( 1080529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch base::Bind(&PluginInstaller::DownloadStarted, base::Unretained(this))); 109ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch RecordDownloadSource(DOWNLOAD_INITIATED_BY_PLUGIN_INSTALLER); 1100529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch download_manager->DownloadUrl(download_parameters.Pass()); 1115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1135d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)void PluginInstaller::DownloadStarted( 1145d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) content::DownloadItem* item, 1155d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) content::DownloadInterruptReason interrupt_reason) { 1160529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch if (interrupt_reason != content::DOWNLOAD_INTERRUPT_REASON_NONE) { 1175d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) std::string msg = base::StringPrintf( 1185d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) "Error %d: %s", 1195d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) interrupt_reason, 1205d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) content::DownloadInterruptReasonToString(interrupt_reason).c_str()); 1215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DownloadError(msg); 1225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 1235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) item->SetOpenWhenComplete(true); 1255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) item->AddObserver(this); 1265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void PluginInstaller::OpenDownloadURL(const GURL& plugin_url, 1295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) content::WebContents* web_contents) { 1305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK_EQ(INSTALLER_STATE_IDLE, state_); 1315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) web_contents->OpenURL(content::OpenURLParams( 1325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) plugin_url, 1335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) content::Referrer(web_contents->GetURL(), 134f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) blink::WebReferrerPolicyDefault), 1351320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci NEW_FOREGROUND_TAB, ui::PAGE_TRANSITION_TYPED, false)); 1365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) FOR_EACH_OBSERVER(PluginInstallerObserver, observers_, DownloadFinished()); 1375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void PluginInstaller::DownloadError(const std::string& msg) { 1405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK_EQ(INSTALLER_STATE_DOWNLOADING, state_); 1415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) state_ = INSTALLER_STATE_IDLE; 1425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) FOR_EACH_OBSERVER(PluginInstallerObserver, observers_, DownloadError(msg)); 1435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void PluginInstaller::DownloadCancelled() { 1465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK_EQ(INSTALLER_STATE_DOWNLOADING, state_); 1475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) state_ = INSTALLER_STATE_IDLE; 1485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) FOR_EACH_OBSERVER(PluginInstallerObserver, observers_, DownloadCancelled()); 1495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 150