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)
51320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "extensions/browser/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 "content/public/browser/browser_thread.h"
125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/public/browser/utility_process_host.h"
135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/public/common/content_switches.h"
141320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "extensions/common/extension_utility_messages.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)
241320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    : xml_(xml), fetch_data_(fetch_data), update_callback_(update_callback) {
25effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  DCHECK_CURRENTLY_ON(BrowserThread::UI);
265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void SafeManifestParser::Start() {
29effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  DCHECK_CURRENTLY_ON(BrowserThread::UI);
305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!BrowserThread::PostTask(
311320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci          BrowserThread::IO,
321320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci          FROM_HERE,
335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          base::Bind(&SafeManifestParser::ParseInSandbox, this))) {
345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    NOTREACHED();
355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)SafeManifestParser::~SafeManifestParser() {
395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // If we're using UtilityProcessHost, we may not be destroyed on
405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // the UI or IO thread.
415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void SafeManifestParser::ParseInSandbox() {
44effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  DCHECK_CURRENTLY_ON(BrowserThread::IO);
455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
467dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  content::UtilityProcessHost* host = content::UtilityProcessHost::Create(
477dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch      this,
487dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch      BrowserThread::GetMessageLoopProxyForThread(BrowserThread::UI).get());
491320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  host->Send(new ExtensionUtilityMsg_ParseUpdateManifest(xml_));
505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool SafeManifestParser::OnMessageReceived(const IPC::Message& message) {
535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bool handled = true;
545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  IPC_BEGIN_MESSAGE_MAP(SafeManifestParser, message)
551320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    IPC_MESSAGE_HANDLER(ExtensionUtilityHostMsg_ParseUpdateManifest_Succeeded,
565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                        OnParseUpdateManifestSucceeded)
571320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    IPC_MESSAGE_HANDLER(ExtensionUtilityHostMsg_ParseUpdateManifest_Failed,
585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                        OnParseUpdateManifestFailed)
595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    IPC_MESSAGE_UNHANDLED(handled = false)
605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  IPC_END_MESSAGE_MAP()
615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return handled;
625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void SafeManifestParser::OnParseUpdateManifestSucceeded(
655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const UpdateManifest::Results& results) {
665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  VLOG(2) << "parsing manifest succeeded (" << fetch_data_->full_url() << ")";
67effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  DCHECK_CURRENTLY_ON(BrowserThread::UI);
685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  update_callback_.Run(*fetch_data_, &results);
695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void SafeManifestParser::OnParseUpdateManifestFailed(
725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const std::string& error_message) {
735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  VLOG(2) << "parsing manifest failed (" << fetch_data_->full_url() << ")";
74effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  DCHECK_CURRENTLY_ON(BrowserThread::UI);
755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  LOG(WARNING) << "Error parsing update manifest:\n" << error_message;
765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  update_callback_.Run(*fetch_data_, NULL);
775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}  // namespace extensions
80