text: // Copyright (c) 2013 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 CHROME_BROWSER_EXTENSIONS_ACTIVITY_LOG_ACTIVITY_ACTIONS_H_
  #define CHROME_BROWSER_EXTENSIONS_ACTIVITY_LOG_ACTIVITY_ACTIONS_H_
  
  #include <stdint.h>
  
  #include <string>
  #include <vector>
  
  #include "base/memory/ref_counted_memory.h"
  #include "base/time/time.h"
  #include "chrome/browser/profiles/profile.h"
  #include "chrome/common/extensions/api/activity_log_private.h"
  #include "url/gurl.h"
  
  namespace base {
  class ListValue;
  class DictionaryValue;
  }
  
  namespace extensions {
  
  // This is the interface for extension actions that are to be recorded in
  // the activity log.
  class Action : public base::RefCountedThreadSafe<Action> {
   public:
    // Types of log entries that can be stored.  The numeric values are stored in
    // the database, so keep them stable.  Append values only.
    enum ActionType {
      ACTION_API_CALL = 0,
      ACTION_API_EVENT = 1,
      UNUSED_ACTION_API_BLOCKED = 2,  // Not in use, but reserved for future.
      ACTION_CONTENT_SCRIPT = 3,
      ACTION_DOM_ACCESS = 4,
      ACTION_DOM_EVENT = 5,
      ACTION_WEB_REQUEST = 6,
      ACTION_ANY = 1001,              // Used for lookups of unspecified type.
    };
  
    // A useful shorthand for methods that take or return collections of Action
    // objects.
    typedef std::vector<scoped_refptr<Action> > ActionVector;
  
    // Creates a new activity log Action object.  The extension_id and type
    // fields are immutable.  All other fields can be filled in with the
    // accessors/mutators below.
    Action(const std::string& extension_id,
           const base::Time& time,
           const ActionType action_type,
           const std::string& api_name,
           int64_t action_id = -1);
  
    Action(const Action&) = delete;
    Action& operator=(const Action&) = delete;
  
    // Creates and returns a mutable copy of an Action.
    scoped_refptr<Action> Clone() const;
  
    // The extension which caused this record to be generated.
    const std::string& extension_id() const { return extension_id_; }
  
    // The time the record was generated (or some approximation).
    const base::Time& time() const { return time_; }
    void set_time(const base::Time& time) { time_ = time; }
  
    // The ActionType distinguishes different classes of actions that can be
    // logged, and determines which other fields are expected to be filled in.
    ActionType action_type() const { return action_type_; }
  
    // The specific API call used or accessed, for example "chrome.tabs.get".
    const std::string& api_name() const { return api_name_; }
    void set_api_name(const std::string& api_name) { api_name_ = api_name; }
  
    // Any applicable arguments.  This might be null to indicate no data
    // available (a distinct condition from an empty argument list).
    // mutable_args() returns a pointer to the list stored in the Action which
    // can be modified in place; if the list was null an empty list is created
    // first.
    const base::ListValue* args() const { return args_.get(); }
    void set_args(std::unique_ptr<base::ListValue> args);
    base::ListValue* mutable_args();
  
    // The URL of the page which was modified or accessed.
    const GURL& page_url() const { return page_url_; }
    void set_page_url(const GURL& page_url);
  
    // The title of the above page if available.
    const std::string& page_title() const { return page_title_; }
    void set_page_title(const std::string& title) { page_title_ = title; }
  
    // A URL which appears in the arguments of the API call, if present.
    const GURL& arg_url() const { return arg_url_; }
    void set_arg_url(const GURL& arg_url);
  
    // Get or set a flag indicating whether the page or argument values above
    // refer to incognito pages.
    bool page_incognito() const { return page_incognito_; }
    void set_page_incognito(bool incognito) { page_incognito_ = incognito; }
    bool arg_incognito() const { return arg_incognito_; }
    void set_arg_incognito(bool incognito) { arg_incognito_ = incognito; }
  
    // A dictionary where any additional data can be stored.
    const base::DictionaryValue* other() const { return other_.get(); }
    void set_other(std::unique_ptr<base::DictionaryValue> other);
    base::DictionaryValue* mutable_other();
  
    // An ID that identifies an action stored in the Activity Log database. If the
    // action is not retrieved from the database, e.g., live stream, then the ID
    // is set to -1.
    int64_t action_id() const { return action_id_; }
  
    // Helper methods for serializing and deserializing URLs into strings.  If
    // the URL is marked as incognito, then the string is prefixed with
    // kIncognitoUrl ("<incognito>").
    std::string SerializePageUrl() const;
    void ParsePageUrl(const std::string& url);
    std::string SerializeArgUrl() const;
    void ParseArgUrl(const std::string& url);
  
    // Number of merged records for this action.
    int count() const { return count_; }
    void set_count(int count) { count_ = count; }
  
    // Flatten the activity's type-specific fields into an ExtensionActivity.
    api::activity_log_private::ExtensionActivity ConvertToExtensionActivity();
  
    // Print an action as a regular string for debugging purposes.
    virtual std::string PrintForDebug() const;
  
   protected:
    virtual ~Action();
  
   private:
    friend class base::RefCountedThreadSafe<Action>;
  
    std::string extension_id_;
    base::Time time_;
    ActionType action_type_;
    std::string api_name_;
    std::unique_ptr<base::ListValue> args_;
    GURL page_url_;
    std::string page_title_;
    bool page_incognito_;
    GURL arg_url_;
    bool arg_incognito_;
    std::unique_ptr<base::DictionaryValue> other_;
    int count_;
    int64_t action_id_;
  };
  
  // A comparator for Action class objects; this performs a lexicographic
  // comparison of the fields of the Action object (in an unspecfied order).
  // This can be used to use Action objects as keys in STL containers.
  struct ActionComparator {
    // Evaluates the comparison lhs < rhs.
    bool operator()(const scoped_refptr<Action>& lhs,
                    const scoped_refptr<Action>& rhs) const;
  };
  
  // Like ActionComparator, but ignores the time field and the action ID field in
  // comparisons.
  struct ActionComparatorExcludingTimeAndActionId {
    // Evaluates the comparison lhs < rhs.
    bool operator()(const scoped_refptr<Action>& lhs,
                    const scoped_refptr<Action>& rhs) const;
  };
  
  }  // namespace extensions
  
  #endif  // CHROME_BROWSER_EXTENSIONS_ACTIVITY_LOG_ACTIVITY_ACTIONS_H_
  