// 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_BROWSER_HISTOGRAM_SYNCHRONIZER_H_
#define CONTENT_BROWSER_HISTOGRAM_SYNCHRONIZER_H_

#include <string>
#include <vector>

#include "base/basictypes.h"
#include "base/callback.h"
#include "base/memory/singleton.h"
#include "base/synchronization/lock.h"
#include "base/time/time.h"
#include "content/browser/histogram_subscriber.h"

namespace base {
class MessageLoop;
}

namespace content {

// This class maintains state that is used to upload histogram data from the
// various child processes, into the browser process. Such transactions are
// usually instigated by the browser. In general, a child process will respond
// by gathering snapshots of all internal histograms, calculating what has
// changed since its last upload, and transmitting a pickled collection of
// deltas.
//
// There are actually two modes of update request.  One is synchronous (and
// blocks the UI thread, waiting to populate an about:histograms tab) and the
// other is asynchronous, and used by the metrics services in preparation for a
// log upload.
//
// To assure that all the processes have responded, a counter is maintained to
// indicate the number of pending (not yet responsive) processes. To avoid
// confusion about a response (i.e., is the process responding to a current
// request for an update, or to an old request for an update) we tag each group
// of requests with a sequence number. When an update arrives we can ignore it
// (relative to the counter) if it does not relate to a current outstanding
// sequence number.
//
// There is one final mode of use, where a renderer spontaneously decides to
// transmit a collection of histogram data.  This is designed for use when the
// renderer is terminating.  Unfortunately, renders may be terminated without
// warning, and the best we can do is periodically acquire data from a tab, such
// as when a page load has completed.  In this mode, the renderer uses a
// reserved sequence number, different from any sequence number that might be
// specified by a browser request.  Since this sequence number can't match an
// outstanding sequence number, the pickled data is accepted into the browser,
// but there is no impact on the counters.

class HistogramSynchronizer : public HistogramSubscriber {
 public:
  enum ProcessHistogramRequester {
    UNKNOWN,
    ASYNC_HISTOGRAMS,
  };

  // Return pointer to the singleton instance for the current process, or NULL
  // if none.
  static HistogramSynchronizer* GetInstance();

  // Contact all processes, and get them to upload to the browser any/all
  // changes to histograms. This method is called from about:histograms.
  static void FetchHistograms();

  // Contact all child processes, and get them to upload to the browser any/all
  // changes to histograms.  When all changes have been acquired, or when the
  // wait time expires (whichever is sooner), post the callback to the
  // specified message loop. Note the callback is posted exactly once.
  static void FetchHistogramsAsynchronously(base::MessageLoop* callback_thread,
                                            const base::Closure& callback,
                                            base::TimeDelta wait_time);

 private:
  friend struct DefaultSingletonTraits<HistogramSynchronizer>;

  class RequestContext;

  HistogramSynchronizer();
  virtual ~HistogramSynchronizer();

  // Establish a new sequence number, and use it to notify all processes
  // (renderers, plugins, GPU, etc) of the need to supply, to the browser,
  // any/all changes to their histograms. |wait_time| specifies the amount of
  // time to wait before cancelling the requests for non-responsive processes.
  void RegisterAndNotifyAllProcesses(ProcessHistogramRequester requester,
                                     base::TimeDelta wait_time);

  // -------------------------------------------------------
  // HistogramSubscriber methods for browser child processes
  // -------------------------------------------------------

  // Update the number of pending processes for the given |sequence_number|.
  // This is called on UI thread.
  virtual void OnPendingProcesses(int sequence_number,
                                  int pending_processes,
                                  bool end) OVERRIDE;

  // Send histogram_data back to caller and also record that we are waiting
  // for one less histogram data from child process for the given sequence
  // number. This method is accessible on UI thread.
  virtual void OnHistogramDataCollected(
      int sequence_number,
      const std::vector<std::string>& pickled_histograms) OVERRIDE;

  // Set the callback_thread_ and callback_ members. If these members already
  // had values, then as a side effect, post the old callback_ to the old
  // callaback_thread_.  This side effect should not generally happen, but is in
  // place to assure correctness (that any tasks that were set, are eventually
  // called, and never merely discarded).
  void SetCallbackTaskAndThread(base::MessageLoop* callback_thread,
                                const base::Closure& callback);

  void ForceHistogramSynchronizationDoneCallback(int sequence_number);

  // Internal helper function, to post task, and record callback stats.
  void InternalPostTask(base::MessageLoop* thread,
                        const base::Closure& callback);

  // Gets a new sequence number to be sent to processes from browser process.
  int GetNextAvailableSequenceNumber(ProcessHistogramRequester requester);

  // This lock_ protects access to all members.
  base::Lock lock_;

  // When a request is made to asynchronously update the histograms, we store
  // the task and thread we use to post a completion notification in
  // callback_ and callback_thread_.
  base::Closure callback_;
  base::MessageLoop* callback_thread_;

  // We don't track the actual processes that are contacted for an update, only
  // the count of the number of processes, and we can sometimes time-out and
  // give up on a "slow to respond" process.  We use a sequence_number to be
  // sure a response from a process is associated with the current round of
  // requests (and not merely a VERY belated prior response).
  // All sequence numbers used are non-negative.
  // last_used_sequence_number_ is the most recently used number (used to avoid
  // reuse for a long time).
  int last_used_sequence_number_;

  // The sequence number used by the most recent asynchronous update request to
  // contact all processes.
  int async_sequence_number_;

  DISALLOW_COPY_AND_ASSIGN(HistogramSynchronizer);
};

}  // namespace content

#endif  // CONTENT_BROWSER_HISTOGRAM_SYNCHRONIZER_H_
