168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)// Copyright 2013 The Chromium Authors. All rights reserved.
268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)// found in the LICENSE file.
468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)
568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)#ifndef CHROME_BROWSER_EXTENSIONS_ACTIVITY_LOG_UMA_POLICY_H_
668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)#define CHROME_BROWSER_EXTENSIONS_ACTIVITY_LOG_UMA_POLICY_H_
768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)
868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)#include <map>
968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)#include <string>
1068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)
1168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)#include "chrome/browser/extensions/activity_log/activity_log_policy.h"
1268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)#include "chrome/browser/ui/browser_list_observer.h"
1368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)#include "chrome/browser/ui/tabs/tab_strip_model_observer.h"
1468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)#include "url/gurl.h"
1568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)
1668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)namespace extensions {
1768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)
1868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)// The UmaPolicy keeps track of how many extensions have read from or modified
1968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)// a given pageload. UmaPolicy records to a histogram when a given tab is
2068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)// closed. Caveats:
2168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)//   * If multiple tabs are open for the same URL at the same time, UmaPolicy
2268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)//     treats them as if they are the same.
2368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)//   * UmaPolicy does not record statistics for incognito tabs. (For privacy.)
2468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)//   * If the number of tabs open exceeds 50, UmaPolicy stops recording stats
2568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)//     for tabs 51+. (For memory.)
2668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)//   * UmaPolicy only handles top frames; stats are not recorded for iframes.
2768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)class UmaPolicy : public ActivityLogPolicy,
2868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)                  public TabStripModelObserver,
2968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)                  public chrome::BrowserListObserver {
3068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) public:
3168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  // The possible status bits for a pageload. If you alter this, make sure to
3268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  // also update GetHistogramName.
3368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  enum PageStatus {
3468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)    NONE = 0,
3568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)    CONTENT_SCRIPT = 1,
3668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)    READ_DOM,
3768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)    MODIFIED_DOM,
3868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)    DOM_METHOD,
3968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)    DOCUMENT_WRITE,
4068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)    INNER_HTML,
4168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)    CREATED_SCRIPT,
4268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)    CREATED_IFRAME,
4368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)    CREATED_DIV,
4468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)    CREATED_LINK,
4568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)    CREATED_INPUT,
4668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)    CREATED_EMBED,
4768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)    CREATED_OBJECT,
480529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    AD_INJECTED,
490529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    AD_REMOVED,
500529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    AD_REPLACED,
51cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    AD_LIKELY_INJECTED,
52cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    AD_LIKELY_REPLACED,
5368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)    MAX_STATUS  // Insert new page statuses right before this one.
5468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  };
5568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)
5668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  explicit UmaPolicy(Profile* profile);
5768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)
580529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  // ActivityLogPolicy implementation.
5968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  virtual void ProcessAction(scoped_refptr<Action> action) OVERRIDE;
6068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  virtual void Close() OVERRIDE;
6168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)
6268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  // Gets the histogram name associated with each PageStatus.
6368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  static const char* GetHistogramName(PageStatus status);
6468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)
6568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) protected:
6668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  // Run when Close() is called.
6768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  virtual ~UmaPolicy();
6868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)
6968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) private:
7068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  // Used as a special key in the ExtensionMap.
7168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  static const char kNumberOfTabs[];
7268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)
7368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  // The max number of tabs we track at a time.
7468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  static const size_t kMaxTabsTracked;
7568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)
7668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  typedef std::map<std::string, int> ExtensionMap;
7768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  typedef std::map<std::string, ExtensionMap> SiteMap;
7868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)
7968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  // BrowserListObserver
8068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  virtual void OnBrowserAdded(Browser* browser) OVERRIDE;
8168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  virtual void OnBrowserRemoved(Browser* browser) OVERRIDE;
8268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)
8368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  // TabStripModelObserver
8468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  // Fired when a page loads, either as a new tab or replacing the contents of
8568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  // an older tab.
8668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  virtual void TabChangedAt(content::WebContents* contents,
8768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)                            int index,
8868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)                            TabChangeType change_type) OVERRIDE;
8968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  // Fired when a tab closes.
9068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  virtual void TabClosingAt(TabStripModel* tab_strip_model,
9168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)                            content::WebContents* contents,
9268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)                            int index) OVERRIDE;
9368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)
9468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  // Assign a status bitmask based on the action's properties.
9568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  int MatchActionToStatus(scoped_refptr<Action> action);
9668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)
9768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  // When a page is opened, add it to the SiteMap url_status_.
9868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  void SetupOpenedPage(const std::string& url);
9968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)
10068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  // When a page is closing, remove it from the SiteMap url_status_.
101cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  void CleanupClosedPage(const std::string& cleaned_url,
102cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)                         content::WebContents* web_contents);
10368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)
10468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  // When a page is closing, save statistics about the page to histograms.
105cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  void HistogramOnClose(const std::string& cleaned_url,
106cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)                        content::WebContents* web_contents);
10768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)
10868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  // Standardizes the way URLs are treated.
10968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  static std::string CleanURL(const GURL& gurl);
11068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)
11168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  // Used by UmaPolicyTest.ProcessActionTest.
11268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  SiteMap url_status() { return url_status_; }
11368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)
11468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  Profile* profile_;
11568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)
11668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  // URL -> extension id -> page status.
11768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  SiteMap url_status_;
11868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)
11968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  // tab index -> URL.
12068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  std::map<int32, std::string> tab_list_;
12168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)
12268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  FRIEND_TEST_ALL_PREFIXES(UmaPolicyTest, CleanURLTest);
12368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  FRIEND_TEST_ALL_PREFIXES(UmaPolicyTest, MatchActionToStatusTest);
12468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  FRIEND_TEST_ALL_PREFIXES(UmaPolicyTest, ProcessActionTest);
12568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  FRIEND_TEST_ALL_PREFIXES(UmaPolicyTest, SiteUrlTest);
12668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)};
12768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)
12868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)}  // namespace extensions
12968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)
13068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)#endif  // CHROME_BROWSER_EXTENSIONS_ACTIVITY_LOG_UMA_POLICY_H_
131