1 // Copyright 2014 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4 
5 #ifndef COMPONENTS_NACL_RENDERER_NEXE_LOAD_MANAGER_H_
6 #define COMPONENTS_NACL_RENDERER_NEXE_LOAD_MANAGER_H_
7 
8 #include <stdint.h>
9 
10 #include <map>
11 #include <memory>
12 #include <string>
13 
14 #include "base/files/file.h"
15 #include "base/macros.h"
16 #include "base/memory/read_only_shared_memory_region.h"
17 #include "base/memory/weak_ptr.h"
18 #include "base/time/time.h"
19 #include "components/nacl/renderer/ppb_nacl_private.h"
20 #include "url/gurl.h"
21 
22 namespace content {
23 class PepperPluginInstance;
24 }
25 
26 namespace nacl {
27 
28 class ManifestServiceChannel;
29 class TrustedPluginChannel;
30 
31 // NexeLoadManager provides methods for reporting the progress of loading a
32 // nexe.
33 class NexeLoadManager {
34  public:
35   explicit NexeLoadManager(PP_Instance instance);
36   ~NexeLoadManager();
37 
38   void NexeFileDidOpen(int32_t pp_error,
39                        const base::File& file,
40                        int32_t http_status,
41                        int64_t nexe_bytes_read,
42                        const std::string& url,
43                        base::TimeDelta time_since_open);
44   void ReportLoadSuccess(const std::string& url,
45                          uint64_t loaded_bytes,
46                          uint64_t total_bytes);
47   void ReportLoadError(PP_NaClError error,
48                        const std::string& error_message);
49 
50   // console_message is a part of the error that is logged to
51   // the JavaScript console but is not reported to JavaScript via
52   // the lastError property.  This is used to report internal errors which
53   // may easily change in new versions of the browser and we don't want apps
54   // to come to depend on the details of these errors.
55   void ReportLoadError(PP_NaClError error,
56                        const std::string& error_message,
57                        const std::string& console_message);
58   void ReportLoadAbort();
59   void NexeDidCrash();
60 
61   // TODO(dmichael): Everything below this comment should eventually be made
62   // private, when ppb_nacl_private_impl.cc is no longer using them directly.
63   // The intent is for this class to only expose functions for reporting a
64   // load state transition (e.g., ReportLoadError, ReportProgress,
65   // ReportLoadAbort, etc.)
66   void set_trusted_plugin_channel(
67       std::unique_ptr<TrustedPluginChannel> channel);
68   void set_manifest_service_channel(
69       std::unique_ptr<ManifestServiceChannel> channel);
70 
71   PP_NaClReadyState nacl_ready_state();
72   void set_nacl_ready_state(PP_NaClReadyState ready_state);
73 
74   void SetReadOnlyProperty(PP_Var key, PP_Var value);
75   void SetLastError(const std::string& error);
76   void LogToConsole(const std::string& message);
77 
is_installed()78   bool is_installed() const { return is_installed_; }
79 
exit_status()80   int32_t exit_status() const { return exit_status_; }
81   void set_exit_status(int32_t exit_status);
82 
83   void InitializePlugin(uint32_t argc, const char* argn[], const char* argv[]);
84 
85   void ReportStartupOverhead() const;
86 
nexe_size()87   int64_t nexe_size() const { return nexe_size_; }
88 
89   bool RequestNaClManifest(const std::string& url);
90   void ProcessNaClManifest(const std::string& program_url);
91 
92   void CloseTrustedPluginChannel();
93 
94   // URL resolution support.
95   // plugin_base_url is the URL used for resolving relative URLs used in
96   // src="...".
plugin_base_url()97   const GURL& plugin_base_url() const { return plugin_base_url_; }
98 
99   // manifest_base_url is the URL used for resolving relative URLs mentioned
100   // in manifest files.  If the manifest is a data URI, this is an empty string
manifest_base_url()101   const GURL& manifest_base_url() const { return manifest_base_url_; }
102 
103   // Returns the manifest URL passed as an argument for this plugin instance.
104   std::string GetManifestURLArgument() const;
105 
106   // Returns true if the MIME type for this plugin matches the type for PNaCl,
107   // false otherwise.
108   bool IsPNaCl() const;
109 
110   // Returns the time that the work for PNaCl translation began.
pnacl_start_time()111   base::Time pnacl_start_time() const { return pnacl_start_time_; }
set_pnacl_start_time(base::Time time)112   void set_pnacl_start_time(base::Time time) {
113     pnacl_start_time_ = time;
114   }
115 
program_url()116   const std::string& program_url() const { return program_url_; }
117 
set_crash_info_shmem_region(base::ReadOnlySharedMemoryRegion shmem_region)118   void set_crash_info_shmem_region(
119       base::ReadOnlySharedMemoryRegion shmem_region) {
120     crash_info_shmem_region_ = std::move(shmem_region);
121   }
122 
nonsfi()123   bool nonsfi() const { return nonsfi_; }
set_nonsfi(bool nonsfi)124   void set_nonsfi(bool nonsfi) { nonsfi_ = nonsfi; }
125 
126  private:
127   DISALLOW_COPY_AND_ASSIGN(NexeLoadManager);
128 
129   void ReportDeadNexe();
130 
131   // Copies a crash log to the console, one line at a time.
132   void CopyCrashLogToJsConsole(const std::string& crash_log);
133 
134   PP_Instance pp_instance_;
135   PP_NaClReadyState nacl_ready_state_;
136   bool nexe_error_reported_;
137 
138   std::string program_url_;
139 
140   // A flag indicating if the NaCl executable is being loaded from an installed
141   // application.  This flag is used to bucket UMA statistics more precisely to
142   // help determine whether nexe loading problems are caused by networking
143   // issues.  (Installed applications will be loaded from disk.)
144   // Unfortunately, the definition of what it means to be part of an installed
145   // application is a little murky - for example an installed application can
146   // register a mime handler that loads NaCl executables into an arbitrary web
147   // page.  As such, the flag actually means "our best guess, based on the URLs
148   // for NaCl resources that we have seen so far".
149   bool is_installed_;
150 
151   // Time of a successful nexe load.
152   base::Time ready_time_;
153 
154   // Time of plugin initialization.
155   base::Time init_time_;
156 
157   // Time of the start of loading a NaCl module.
158   base::Time load_start_;
159 
160   // The exit status of the plugin process.
161   // This will have a value in the range (0x00-0xff) if the exit status is set,
162   // or -1 if set_exit_status() has never been called.
163   int32_t exit_status_;
164 
165   // Size of the downloaded nexe, in bytes.
166   int64_t nexe_size_;
167 
168   // Non-owning.
169   content::PepperPluginInstance* plugin_instance_;
170 
171   // The URL for the document corresponding to this plugin instance.
172   GURL plugin_base_url_;
173 
174   GURL manifest_base_url_;
175 
176   // Arguments passed to this plugin instance from the DOM.
177   std::map<std::string, std::string> args_;
178 
179   // We store mime_type_ outside of args_ explicitly because we change it to be
180   // lowercase.
181   std::string mime_type_;
182 
183   base::Time pnacl_start_time_;
184 
185   // A flag that indicates if the plugin is using Non-SFI mode.
186   bool nonsfi_;
187 
188   base::ReadOnlySharedMemoryRegion crash_info_shmem_region_;
189 
190   std::unique_ptr<TrustedPluginChannel> trusted_plugin_channel_;
191   std::unique_ptr<ManifestServiceChannel> manifest_service_channel_;
192   base::WeakPtrFactory<NexeLoadManager> weak_factory_{this};
193 };
194 
195 }  // namespace nacl
196 
197 #endif  // COMPONENTS_NACL_RENDERER_NEXE_LOAD_MANAGER_H_
198