// Copyright (c) 2012 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#ifndef CONTENT_COMMON_PLUGIN_LIST_H_
#define CONTENT_COMMON_PLUGIN_LIST_H_

#include <set>
#include <string>
#include <utility>
#include <vector>

#include "base/callback.h"
#include "base/files/file_path.h"
#include "base/lazy_instance.h"
#include "base/macros.h"
#include "base/synchronization/lock.h"
#include "build/build_config.h"
#include "content/common/content_export.h"
#include "content/public/common/webplugininfo.h"

#if !defined(ENABLE_PLUGINS)
#error "Plugins should be enabled"
#endif

class GURL;

namespace content {

// The PluginList is responsible for loading our NPAPI based plugins. It does
// so in whatever manner is appropriate for the platform. On Windows, it loads
// plugins from a known directory by looking for DLLs which start with "NP",
// and checking to see if they are valid NPAPI libraries. On the Mac, it walks
// the machine-wide and user plugin directories and loads anything that has
// the correct types. On Linux, it walks the plugin directories as well
// (e.g. /usr/lib/browser-plugins/).
// This object is thread safe.
class CONTENT_EXPORT PluginList {
 public:
  // Gets the one instance of the PluginList.
  static PluginList* Singleton();

  // Returns true if the plugin supports |mime_type|. |mime_type| should be all
  // lower case.
  static bool SupportsType(const WebPluginInfo& plugin,
                           const std::string& mime_type,
                           bool allow_wildcard);

  // Cause the plugin list to refresh next time they are accessed, regardless
  // of whether they are already loaded.
  void RefreshPlugins();

  // Register an internal plugin with the specified plugin information.
  // An internal plugin must be registered before it can
  // be loaded using PluginList::LoadPlugin().
  // If |add_at_beginning| is true the plugin will be added earlier in
  // the list so that it can override the MIME types of older registrations.
  void RegisterInternalPlugin(const WebPluginInfo& info,
                              bool add_at_beginning);

  // Removes a specified internal plugin from the list. The search will match
  // on the path from the version info previously registered.
  void UnregisterInternalPlugin(const base::FilePath& path);

  // Gets a list of all the registered internal plugins.
  void GetInternalPlugins(std::vector<WebPluginInfo>* plugins);

  // Creates a WebPluginInfo structure given a plugin's path.  On success
  // returns true, with the information being put into "info".
  // Returns false if the library couldn't be found, or if it's not a plugin.
  bool ReadPluginInfo(const base::FilePath& filename,
                      WebPluginInfo* info);

  // Get all the plugins synchronously, loading them if necessary.
  void GetPlugins(std::vector<WebPluginInfo>* plugins);

  // Copies the list of plugins into |plugins| without loading them.
  // Returns true if the list of plugins is up to date.
  bool GetPluginsNoRefresh(std::vector<WebPluginInfo>* plugins);

  // Returns a list in |info| containing plugins that are found for
  // the given url and mime type (including disabled plugins, for
  // which |info->enabled| is false).  The mime type which corresponds
  // to the URL is optionally returned back in |actual_mime_types| (if
  // it is non-NULL), one for each of the plugin info objects found.
  // The |allow_wildcard| parameter controls whether this function
  // returns plugins which support wildcard mime types (* as the mime
  // type).  The |info| parameter is required to be non-NULL.  The
  // list is in order of "most desirable" to "least desirable".
  // If |use_stale| is NULL, this will load the plugin list if necessary.
  // If it is not NULL, the plugin list will not be loaded, and |*use_stale|
  // will be true iff the plugin list was stale.
  void GetPluginInfoArray(const GURL& url,
                          const std::string& mime_type,
                          bool allow_wildcard,
                          bool* use_stale,
                          std::vector<WebPluginInfo>* info,
                          std::vector<std::string>* actual_mime_types);

  // Load a specific plugin with full path. Return true iff loading the plugin
  // was successful.
  bool LoadPluginIntoPluginList(const base::FilePath& filename,
                                std::vector<WebPluginInfo>* plugins,
                                WebPluginInfo* plugin_info);

  // The following functions are used to support probing for WebPluginInfo
  // using a different instance of this class.

  // Computes a list of all plugins to potentially load from all sources.
  void GetPluginPathsToLoad(std::vector<base::FilePath>* plugin_paths);

  // Signals that plugin loading will start. This method should be called before
  // loading plugins with a different instance of this class. Returns false if
  // the plugin list is up to date.
  // When loading has finished, SetPlugins() should be called with the list of
  // plugins.
  bool PrepareForPluginLoading();

  // Clears the internal list of Plugins and copies them from the vector.
  void SetPlugins(const std::vector<WebPluginInfo>& plugins);

  void set_will_load_plugins_callback(const base::Closure& callback);

  virtual ~PluginList();

 private:
  enum LoadingState {
    LOADING_STATE_NEEDS_REFRESH,
    LOADING_STATE_REFRESHING,
    LOADING_STATE_UP_TO_DATE,
  };

  friend class PluginListTest;
  friend struct base::DefaultLazyInstanceTraits<PluginList>;

  PluginList();

  // Load all plugins from the default plugins directory.
  void LoadPlugins();

  // Returns true if the given plugin supports a given file extension.
  // |extension| should be all lower case. If |mime_type| is not NULL, it will
  // be set to the MIME type if found. The MIME type which corresponds to the
  // extension is optionally returned back.
  bool SupportsExtension(const WebPluginInfo& plugin,
                         const std::string& extension,
                         std::string* actual_mime_type);

  // Removes |plugin_path| from the list of extra plugin paths. Should only be
  // called while holding |lock_|.
  void RemoveExtraPluginPathLocked(const base::FilePath& plugin_path);

  //
  // Internals
  //

  // States whether we will load the plugin list the next time we try to access
  // it, whether we are currently in the process of loading it, or whether we
  // consider it up to date.
  LoadingState loading_state_;

  // Extra plugin paths that we want to search when loading.
  std::vector<base::FilePath> extra_plugin_paths_;

  // Holds information about internal plugins.
  std::vector<WebPluginInfo> internal_plugins_;

  // A list holding all plugins.
  std::vector<WebPluginInfo> plugins_list_;

  // Callback that is invoked whenever the PluginList will reload the plugins.
  base::Closure will_load_plugins_callback_;

  // Need synchronization for the above members since this object can be
  // accessed on multiple threads.
  base::Lock lock_;

  DISALLOW_COPY_AND_ASSIGN(PluginList);
};

}  // namespace content

#endif  // CONTENT_COMMON_PLUGIN_LIST_H_
