1ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen// Copyright (c) 2011 The Chromium Authors. All rights reserved.
2c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// Use of this source code is governed by a BSD-style license that can be
3c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// found in the LICENSE file.
4c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
5c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#ifndef CHROME_BROWSER_UTILITY_PROCESS_HOST_H_
6c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#define CHROME_BROWSER_UTILITY_PROCESS_HOST_H_
73345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick#pragma once
8c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
9c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include <string>
10c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include <vector>
11c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
12c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "base/basictypes.h"
13ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#include "base/memory/ref_counted.h"
14c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "base/task.h"
15c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "chrome/common/extensions/update_manifest.h"
16dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen#include "content/browser/browser_child_process_host.h"
17dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen#include "content/browser/browser_thread.h"
18c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
19c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochclass DictionaryValue;
203345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrickclass IndexedDBKey;
21ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsenclass ListValue;
223345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrickclass SerializedScriptValue;
23c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochclass SkBitmap;
24c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
25c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// This class acts as the browser-side host to a utility child process.  A
26c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// utility process is a short-lived sandboxed process that is created to run
27c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// a specific task.  This class lives solely on the IO thread.
283345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick// If you need a single method call in the sandbox, use StartFooBar(p).
293345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick// If you need multiple batches of work to be done in the sandboxed process,
303345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick// use StartBatchMode(), then multiple calls to StartFooBar(p),
313345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick// then finish with EndBatchMode().
32c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochclass UtilityProcessHost : public BrowserChildProcessHost {
33c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch public:
34c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // An interface to be implemented by consumers of the utility process to
35c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // get results back.  All functions are called on the thread passed along
36c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // to UtilityProcessHost.
37c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  class Client : public base::RefCountedThreadSafe<Client> {
38c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch   public:
39c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    Client() {}
40c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
41c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    // Called when the process has crashed.
4221d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen    virtual void OnProcessCrashed(int exit_code) {}
43c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
44c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    // Called when the extension has unpacked successfully.  |manifest| is the
45c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    // parsed manifest.json file.  |catalogs| contains list of all parsed
46c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    // message catalogs.  |images| contains a list of decoded images and the
47c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    // associated paths where those images live on disk.
48c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    virtual void OnUnpackExtensionSucceeded(const DictionaryValue& manifest) {}
49c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
50c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    // Called when an error occurred while unpacking the extension.
51c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    // |error_message| contains a description of the problem.
52c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    virtual void OnUnpackExtensionFailed(const std::string& error_message) {}
53c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
54c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    // Called when the web resource has been successfully parsed.  |json_data|
55c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    // contains the parsed list of web resource items downloaded from the
56c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    // web resource server.
57c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    virtual void OnUnpackWebResourceSucceeded(
58c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch        const DictionaryValue& json_data) {}
59c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
60c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    // Called when an error occurred while parsing the resource data.
61c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    // |error_message| contains a description of the problem.
62c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    virtual void OnUnpackWebResourceFailed(const std::string& error_message) {}
63c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
64c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    // Called when an update manifest xml file was successfully parsed.
65c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    virtual void OnParseUpdateManifestSucceeded(
66c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch        const UpdateManifest::Results& results) {}
67c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
68c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    // Called when an update manifest xml file failed parsing. |error_message|
69c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    // contains details suitable for logging.
70c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    virtual void OnParseUpdateManifestFailed(
71c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch        const std::string& error_message) {}
72c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
73c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    // Called when image data was successfully decoded. |decoded_image|
74c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    // stores the result.
75c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    virtual void OnDecodeImageSucceeded(
76c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch        const SkBitmap& decoded_image) {}
77c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
78c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    // Called when image data decoding failed.
79c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    virtual void OnDecodeImageFailed() {}
80c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
813345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick    // Called when we have successfully obtained the IndexedDBKey after
823345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick    // a call to StartIDBKeysFromValuesAndKeyPath.
833345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick    // |id| is the corresponding identifier.
843345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick    // |keys| the corresponding IndexedDBKey.
853345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick    virtual void OnIDBKeysFromValuesAndKeyPathSucceeded(
863345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick        int id, const std::vector<IndexedDBKey>& keys) {}
873345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick
883345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick    // Called when IDBKeyPath has failed.
893345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick    // |id| is the corresponding identifier passed on
903345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick    // StartIDBKeysFromValuesAndKeyPath.
913345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick    virtual void OnIDBKeysFromValuesAndKeyPathFailed(int id) {}
923345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick
93dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen    // Called when an IDBKey was injected into a
94dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen    // SerializedScriptValue. If injection failed, SerializedScriptValue is
95dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen    // empty.
96dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen    virtual void OnInjectIDBKeyFinished(
97dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen        const SerializedScriptValue& new_value) {}
98dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen
99ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    // Called when we're finished parsing a JSON string. Note that if parsing
100ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    // was successful, the result Value is contained in the first element of
101ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    // |wrapper| (we do this to get around a trickiness with passing a Value
102ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    // by const reference via our IPC system).
103ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    virtual void OnJSONParseSucceeded(const ListValue& wrapper) {}
104ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    virtual void OnJSONParseFailed(const std::string& error_message) {}
105ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
106c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch   protected:
107c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    friend class base::RefCountedThreadSafe<Client>;
108c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
109c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    virtual ~Client() {}
110c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
111c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch   private:
112c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    friend class UtilityProcessHost;
113c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
11421d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen    bool OnMessageReceived(const IPC::Message& message);
115c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
116c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    DISALLOW_COPY_AND_ASSIGN(Client);
117c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  };
118c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
119ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  UtilityProcessHost(Client* client, BrowserThread::ID client_thread_id);
120c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  virtual ~UtilityProcessHost();
121c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
122c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Start a process to unpack the extension at the given path.  The process
123c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // will be given access to the directory subtree that the extension file is
124c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // in, so the caller is expected to have moved that file into a quarantined
125c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // location first.
126c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  bool StartExtensionUnpacker(const FilePath& extension);
127c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
128c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Start a process to unpack and parse a web resource from the given JSON
129c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // data.  Any links that need to be downloaded from the parsed data
130c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // (thumbnails, etc.) will be unpacked in resource_dir.
131c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // TODO(mrc): Right now, the unpacker just parses the JSON data, and
132c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // doesn't do any unpacking.  This should change once we finalize the
133c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // web resource server format(s).
134c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  bool StartWebResourceUnpacker(const std::string& data);
135c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
136c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Start parsing an extensions auto-update manifest xml file.
137c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  bool StartUpdateManifestParse(const std::string& xml);
138c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
139ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  // Start image decoding. The image can be any format WebCore understands.
140ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  // Results are reported to either OnDecodeImageSuceeded() or
141ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  // OnDecodeImageFailed().
142c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  bool StartImageDecoding(const std::vector<unsigned char>& encoded_data);
143ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  bool StartImageDecodingBase64(const std::string& base64_encoded_data);
144c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
1453345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  // Starts extracting |key_path| from |serialized_values|, and replies with the
1463345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  // corresponding IndexedDBKeys via OnIDBKeysFromValuesAndKeyPathSucceeded.
1473345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  bool StartIDBKeysFromValuesAndKeyPath(
1483345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick      int id, const std::vector<SerializedScriptValue>& serialized_values,
1493345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick      const string16& key_path);
1503345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick
151dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  // Starts injecting |key| into |value| via |key_path|, and replies with the
152dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  // updated value via OnInjectIDBKeyFinished.
153dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  bool StartInjectIDBKey(const IndexedDBKey& key,
154dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen                         const SerializedScriptValue& value,
155dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen                         const string16& key_path);
156dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen
157ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  // Starts parsing a JSON string into a Value object. The result is reported
158ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  // to the client via OnJSONParseSucceeded or OnJSONParseFailed.
159ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  bool StartJSONParsing(const std::string& json);
160ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
1613345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  // Starts utility process in batch mode. Caller must call EndBatchMode()
1623345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  // to finish the utility process.
1633345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  bool StartBatchMode();
1643345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick
1653345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  // Ends the utility process. Must be called after StartBatchMode().
1663345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  void EndBatchMode();
1673345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick
168c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch protected:
169c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Allow these methods to be overridden for tests.
170c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  virtual FilePath GetUtilityProcessCmd();
171c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
172c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch private:
1733345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  // Starts a process if necessary.  Returns true if it succeeded or a process
1743345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  // has already been started via StartBatchMode().
175c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  bool StartProcess(const FilePath& exposed_dir);
176c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
177c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // IPC messages:
17821d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  virtual bool OnMessageReceived(const IPC::Message& message);
179c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
180c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // BrowserChildProcessHost:
18121d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  virtual void OnProcessCrashed(int exit_code);
18221d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  virtual bool CanShutdown();
183c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
184c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // A pointer to our client interface, who will be informed of progress.
185c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  scoped_refptr<Client> client_;
186731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  BrowserThread::ID client_thread_id_;
1873345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  // True when running in batch mode, i.e., StartBatchMode() has been called
1883345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  // and the utility process will run until EndBatchMode().
1893345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  bool is_batch_mode_;
190c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
191c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  DISALLOW_COPY_AND_ASSIGN(UtilityProcessHost);
192c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch};
193c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
194c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#endif  // CHROME_BROWSER_UTILITY_PROCESS_HOST_H_
195