1 // Copyright (c) 2012 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 CONTENT_BROWSER_PLUGIN_LOADER_POSIX_H_ 6 #define CONTENT_BROWSER_PLUGIN_LOADER_POSIX_H_ 7 8 #include <vector> 9 10 #include "base/basictypes.h" 11 #include "base/compiler_specific.h" 12 #include "base/memory/ref_counted.h" 13 #include "base/time/time.h" 14 #include "content/browser/plugin_service_impl.h" 15 #include "content/public/browser/utility_process_host_client.h" 16 #include "content/public/common/webplugininfo.h" 17 #include "ipc/ipc_sender.h" 18 19 namespace base { 20 class MessageLoopProxy; 21 } 22 23 namespace content { 24 class UtilityProcessHost; 25 26 // This class is responsible for managing the out-of-process plugin loading on 27 // POSIX systems. It primarily lives on the IO thread, but has a brief stay on 28 // the FILE thread to iterate over plugin directories when it is first 29 // constructed. 30 // 31 // The following is the algorithm used to load plugins: 32 // 1. This asks the PluginList for the list of all potential plugins to attempt 33 // to load. This is referred to as the canonical list. 34 // 2. The child process this hosts is forked and the canonical list is sent to 35 // it. 36 // 3. The child process iterates over the canonical list, attempting to load 37 // each plugin in the order specified by the list. It sends an IPC message 38 // to the browser after each load, indicating success or failure. The two 39 // processes synchronize the position in the vector that will be used to 40 // attempt to load the next plugin. 41 // 4. If the child dies during this process, the host forks another child and 42 // resumes loading at the position past the plugin that it just attempted to 43 // load, bypassing the problematic plugin. 44 // 5. This algorithm continues until the canonical list has been walked to the 45 // end, after which the list of loaded plugins is set on the PluginList and 46 // the completion callback is run. 47 class CONTENT_EXPORT PluginLoaderPosix NON_EXPORTED_BASE(UtilityProcessHostClient)48 : public NON_EXPORTED_BASE(UtilityProcessHostClient), 49 public IPC::Sender { 50 public: 51 PluginLoaderPosix(); 52 53 // Must be called from the IO thread. The |callback| will be called on the IO 54 // thread too. 55 void GetPlugins(const PluginService::GetPluginsCallback& callback); 56 57 // UtilityProcessHostClient: 58 virtual void OnProcessCrashed(int exit_code) OVERRIDE; 59 virtual bool OnMessageReceived(const IPC::Message& message) OVERRIDE; 60 61 // IPC::Sender: 62 virtual bool Send(IPC::Message* msg) OVERRIDE; 63 64 private: 65 virtual ~PluginLoaderPosix(); 66 67 // Called on the FILE thread to get the list of plugin paths to probe. 68 void GetPluginsToLoad(); 69 70 // Must be called on the IO thread. 71 virtual void LoadPluginsInternal(); 72 73 // Called after plugin loading has finished, if we don't know whether the 74 // plugin list has been invalidated in the mean time. 75 void GetPluginsWrapper( 76 const PluginService::GetPluginsCallback& callback, 77 const std::vector<WebPluginInfo>& plugins_unused); 78 79 // Message handlers. 80 void OnPluginLoaded(uint32 index, const WebPluginInfo& plugin); 81 void OnPluginLoadFailed(uint32 index, const base::FilePath& plugin_path); 82 83 // Checks if the plugin path is an internal plugin, and, if it is, adds it to 84 // |loaded_plugins_|. 85 bool MaybeAddInternalPlugin(const base::FilePath& plugin_path); 86 87 // Runs all the registered callbacks on each's target loop if the condition 88 // for ending the load process is done (i.e. the |next_load_index_| is outside 89 // the range of the |canonical_list_|). 90 bool MaybeRunPendingCallbacks(); 91 92 // The process host for which this is a client. 93 base::WeakPtr<UtilityProcessHost> process_host_; 94 95 // A list of paths to plugins which will be loaded by the utility process, in 96 // the order specified by this vector. 97 std::vector<base::FilePath> canonical_list_; 98 99 // The index in |canonical_list_| of the plugin that the child process will 100 // attempt to load next. 101 size_t next_load_index_; 102 103 // Internal plugins that have been registered at the time of loading. 104 std::vector<WebPluginInfo> internal_plugins_; 105 106 // A vector of plugins that have been loaded successfully. 107 std::vector<WebPluginInfo> loaded_plugins_; 108 109 // The callback and message loop on which the callback will be run when the 110 // plugin loading process has been completed. 111 std::vector<PluginService::GetPluginsCallback> callbacks_; 112 113 // The time at which plugin loading started. 114 base::TimeTicks load_start_time_; 115 116 friend class MockPluginLoaderPosix; 117 DISALLOW_COPY_AND_ASSIGN(PluginLoaderPosix); 118 }; 119 120 } // namespace content 121 122 #endif // CONTENT_BROWSER_PLUGIN_LOADER_POSIX_H_ 123