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