12a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Copyright (c) 2012 The Chromium Authors. All rights reserved.
22a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
32a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// found in the LICENSE file.
42a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
52a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#ifndef CHROME_BROWSER_EXTENSIONS_API_IDLE_IDLE_MANAGER_H_
62a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#define CHROME_BROWSER_EXTENSIONS_API_IDLE_IDLE_MANAGER_H_
72a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
82a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include <map>
92a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include <string>
102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/callback_forward.h"
122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/gtest_prod_util.h"
132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/memory/weak_ptr.h"
14cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)#include "base/scoped_observer.h"
152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/threading/thread_checker.h"
16eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#include "base/timer/timer.h"
172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "chrome/browser/idle.h"
18a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#include "components/keyed_service/core/keyed_service.h"
19f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#include "extensions/browser/event_router.h"
20cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)#include "extensions/browser/extension_registry_observer.h"
212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)namespace base {
232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)class StringValue;
242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}  // namespace base
252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)class Profile;
272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)namespace extensions {
29cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)class ExtensionRegistry;
302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)typedef base::Callback<void(IdleState)> QueryStateCallback;
322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)struct IdleMonitor {
342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  explicit IdleMonitor(IdleState initial_state);
352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  IdleState last_state;
372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  int listeners;
382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  int threshold;
392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)};
402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
41cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)class IdleManager : public ExtensionRegistryObserver,
422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                    public EventRouter::Observer,
43a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)                    public KeyedService {
442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) public:
452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  class IdleTimeProvider {
462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)   public:
472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    IdleTimeProvider() {}
482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    virtual ~IdleTimeProvider() {}
492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    virtual void CalculateIdleState(int idle_threshold,
502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                    IdleCallback notify) = 0;
512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    virtual void CalculateIdleTime(IdleTimeCallback notify) = 0;
522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    virtual bool CheckIdleStateIsLocked() = 0;
532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)   private:
552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    DISALLOW_COPY_AND_ASSIGN(IdleTimeProvider);
562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  };
572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  class EventDelegate {
592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)   public:
602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    EventDelegate() {}
612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    virtual ~EventDelegate() {}
622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    virtual void OnStateChanged(const std::string& extension_id,
632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                IdleState new_state) = 0;
642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    virtual void RegisterObserver(EventRouter::Observer* observer) = 0;
652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    virtual void UnregisterObserver(EventRouter::Observer* observer) = 0;
662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)   private:
682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    DISALLOW_COPY_AND_ASSIGN(EventDelegate);
692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  };
702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  explicit IdleManager(Profile* profile);
722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  virtual ~IdleManager();
732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  void Init();
752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
76a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  // KeyedService implementation.
772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  virtual void Shutdown() OVERRIDE;
782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
79cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  // ExtensionRegistryObserver implementation.
80cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  virtual void OnExtensionUnloaded(
81cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      content::BrowserContext* browser_context,
82cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      const Extension* extension,
83cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      UnloadedExtensionInfo::Reason reason) OVERRIDE;
842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // EventRouter::Observer implementation.
862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  virtual void OnListenerAdded(const EventListenerInfo& details) OVERRIDE;
872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  virtual void OnListenerRemoved(const EventListenerInfo& details) OVERRIDE;
882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  void QueryState(int threshold, QueryStateCallback notify);
902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  void SetThreshold(const std::string& extension_id, int threshold);
912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  static base::StringValue* CreateIdleValue(IdleState idle_state);
922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Override default event class. Callee assumes ownership. Used for testing.
942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  void SetEventDelegateForTest(scoped_ptr<EventDelegate> event_delegate);
952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Override default idle time calculations. Callee assumes ownership. Used
972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // for testing.
982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  void SetIdleTimeProviderForTest(scoped_ptr<IdleTimeProvider> idle_provider);
992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) private:
1012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  FRIEND_TEST_ALL_PREFIXES(IdleTest, ActiveToIdle);
1022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  FRIEND_TEST_ALL_PREFIXES(IdleTest, ActiveToLocked);
1032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  FRIEND_TEST_ALL_PREFIXES(IdleTest, IdleToActive);
1042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  FRIEND_TEST_ALL_PREFIXES(IdleTest, IdleToLocked);
1052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  FRIEND_TEST_ALL_PREFIXES(IdleTest, LockedToActive);
1062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  FRIEND_TEST_ALL_PREFIXES(IdleTest, LockedToIdle);
1072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  FRIEND_TEST_ALL_PREFIXES(IdleTest, MultipleExtensions);
1085c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  FRIEND_TEST_ALL_PREFIXES(IdleTest, ReAddListener);
1092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  FRIEND_TEST_ALL_PREFIXES(IdleTest, SetDetectionInterval);
1102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  FRIEND_TEST_ALL_PREFIXES(IdleTest, SetDetectionIntervalBeforeListener);
1112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  FRIEND_TEST_ALL_PREFIXES(IdleTest, SetDetectionIntervalMaximum);
1122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  FRIEND_TEST_ALL_PREFIXES(IdleTest, SetDetectionIntervalMinimum);
1132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  FRIEND_TEST_ALL_PREFIXES(IdleTest, UnloadCleanup);
1142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  typedef std::map<const std::string, IdleMonitor> MonitorMap;
1162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  IdleMonitor* GetMonitor(const std::string& extension_id);
1182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  void StartPolling();
1192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  void StopPolling();
1202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  void UpdateIdleState();
1212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  void UpdateIdleStateCallback(int idle_time);
1222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  Profile* profile_;
1242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  IdleState last_state_;
1262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  MonitorMap monitors_;
1272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  base::RepeatingTimer<IdleManager> poll_timer_;
1292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_ptr<IdleTimeProvider> idle_time_provider_;
1312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_ptr<EventDelegate> event_delegate_;
1322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  base::ThreadChecker thread_checker_;
1342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
135cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  // Listen to extension unloaded notification.
136cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  ScopedObserver<ExtensionRegistry, ExtensionRegistryObserver>
137cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      extension_registry_observer_;
138cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
1391320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  base::WeakPtrFactory<IdleManager> weak_factory_;
1401320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
1412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DISALLOW_COPY_AND_ASSIGN(IdleManager);
1422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)};
1432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}  // namespace extensions
1452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#endif  // CHROME_BROWSER_EXTENSIONS_API_IDLE_IDLE_MANAGER_H_
147