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/updater/safe_manifest_parser.h"
65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/bind.h"
85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/command_line.h"
95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/location.h"
105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/logging.h"
115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/common/chrome_utility_messages.h"
125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/public/browser/browser_thread.h"
135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/public/browser/utility_process_host.h"
145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/public/common/content_switches.h"
155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ipc/ipc_message_macros.h"
165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using content::BrowserThread;
185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace extensions {
205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)SafeManifestParser::SafeManifestParser(const std::string& xml,
225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                       ManifestFetchData* fetch_data,
235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                       const UpdateCallback& update_callback)
245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    : xml_(xml),
255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      fetch_data_(fetch_data),
265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      update_callback_(update_callback) {
275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void SafeManifestParser::Start() {
315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!BrowserThread::PostTask(
335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          BrowserThread::IO, FROM_HERE,
345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          base::Bind(&SafeManifestParser::ParseInSandbox, this))) {
355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    NOTREACHED();
365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)SafeManifestParser::~SafeManifestParser() {
405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // If we're using UtilityProcessHost, we may not be destroyed on
415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // the UI or IO thread.
425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void SafeManifestParser::ParseInSandbox() {
455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
477dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  content::UtilityProcessHost* host = content::UtilityProcessHost::Create(
487dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch      this,
497dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch      BrowserThread::GetMessageLoopProxyForThread(BrowserThread::UI).get());
507dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  host->EnableZygote();
517dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  host->Send(new ChromeUtilityMsg_ParseUpdateManifest(xml_));
525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool SafeManifestParser::OnMessageReceived(const IPC::Message& message) {
555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bool handled = true;
565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  IPC_BEGIN_MESSAGE_MAP(SafeManifestParser, message)
575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    IPC_MESSAGE_HANDLER(ChromeUtilityHostMsg_ParseUpdateManifest_Succeeded,
585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                        OnParseUpdateManifestSucceeded)
595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    IPC_MESSAGE_HANDLER(ChromeUtilityHostMsg_ParseUpdateManifest_Failed,
605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                        OnParseUpdateManifestFailed)
615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    IPC_MESSAGE_UNHANDLED(handled = false)
625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  IPC_END_MESSAGE_MAP()
635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return handled;
645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void SafeManifestParser::OnParseUpdateManifestSucceeded(
675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const UpdateManifest::Results& results) {
685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  VLOG(2) << "parsing manifest succeeded (" << fetch_data_->full_url() << ")";
695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  update_callback_.Run(*fetch_data_, &results);
715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void SafeManifestParser::OnParseUpdateManifestFailed(
745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const std::string& error_message) {
755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  VLOG(2) << "parsing manifest failed (" << fetch_data_->full_url() << ")";
765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  LOG(WARNING) << "Error parsing update manifest:\n" << error_message;
785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  update_callback_.Run(*fetch_data_, NULL);
795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}  // namespace extensions
82