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