1
    2
    3
    4
    5
    6
    7
    8
    9
   10
   11
   12
   13
   14
   15
   16
   17
   18
   19
   20
   21
   22
   23
   24
   25
   26
   27
   28
   29
   30
   31
   32
   33
   34
   35
   36
   37
   38
   39
   40
   41
   42
   43
   44
   45
   46
   47
   48
   49
   50
   51
   52
   53
   54
   55
   56
   57
   58
   59
   60
   61
   62
   63
   64
   65
   66
   67
   68
   69
   70
   71
   72
   73
   74
   75
   76
   77
   78
   79
   80
   81
   82
   83
   84
   85
   86
   87
   88
   89
   90
   91
   92
   93
   94
   95
   96
   97
   98
   99
  100
  101
  102
  103
  104
  105
  106
  107
  108
  109
  110
  111
  112
  113
  114
  115
  116
  117
  118
  119
  120
  121
  122
  123
  124
  125
  126
  127
  128
  129
  130
  131
  132
  133

content / browser / devtools / devtools_background_services_context_impl.h [blame]

// Copyright 2019 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#ifndef CONTENT_BROWSER_DEVTOOLS_DEVTOOLS_BACKGROUND_SERVICES_CONTEXT_IMPL_H_
#define CONTENT_BROWSER_DEVTOOLS_DEVTOOLS_BACKGROUND_SERVICES_CONTEXT_IMPL_H_

#include <array>
#include <map>
#include <memory>
#include <string>
#include <utility>
#include <vector>

#include "base/functional/callback_forward.h"
#include "base/memory/raw_ref.h"
#include "base/memory/ref_counted.h"
#include "base/memory/scoped_refptr.h"
#include "base/memory/weak_ptr.h"
#include "base/observer_list.h"
#include "base/observer_list_types.h"
#include "base/time/time.h"
#include "content/browser/devtools/devtools_background_services.pb.h"
#include "content/browser/service_worker/service_worker_context_wrapper.h"
#include "content/common/content_export.h"
#include "content/public/browser/devtools_background_services_context.h"

namespace content {

class BrowserContext;
class ServiceWorkerContextWrapper;

// This class is responsible for persisting the debugging events for the
// relevant Web Platform Features. The contexts of the feature will have a
// reference to this, and perform the logging operation.
// This class is also responsible for reading back the data to the DevTools
// client, as the protocol handler will have access to an instance of the
// context.
//
// Lives on the UI thread.
class CONTENT_EXPORT DevToolsBackgroundServicesContextImpl
    : public DevToolsBackgroundServicesContext {
 public:
  using GetLoggedBackgroundServiceEventsCallback = base::OnceCallback<void(
      std::vector<devtools::proto::BackgroundServiceEvent>)>;

  class EventObserver : public base::CheckedObserver {
   public:
    // Notifies observers of the logged event.
    virtual void OnEventReceived(
        const devtools::proto::BackgroundServiceEvent& event) = 0;
    virtual void OnRecordingStateChanged(
        bool should_record,
        devtools::proto::BackgroundService service) = 0;
  };

  DevToolsBackgroundServicesContextImpl(
      BrowserContext* browser_context,
      scoped_refptr<ServiceWorkerContextWrapper> service_worker_context);
  ~DevToolsBackgroundServicesContextImpl() override;

  DevToolsBackgroundServicesContextImpl(
      const DevToolsBackgroundServicesContextImpl&) = delete;
  DevToolsBackgroundServicesContextImpl& operator=(
      const DevToolsBackgroundServicesContextImpl&) = delete;

  void AddObserver(EventObserver* observer);
  void RemoveObserver(const EventObserver* observer);

  // DevToolsBackgroundServicesContext overrides:
  bool IsRecording(DevToolsBackgroundService service) override;
  void LogBackgroundServiceEvent(
      uint64_t service_worker_registration_id,
      blink::StorageKey storage_key,
      DevToolsBackgroundService service,
      const std::string& event_name,
      const std::string& instance_id,
      const std::map<std::string, std::string>& event_metadata) override;

  // Helper function for public override. Can be used directly.
  bool IsRecording(devtools::proto::BackgroundService service);

  // Enables recording mode for |service|. This is capped at 3 days in case
  // developers forget to switch it off.
  void StartRecording(devtools::proto::BackgroundService service);

  // Disables recording mode for |service|.
  void StopRecording(devtools::proto::BackgroundService service);

  // Queries all logged events for |service| and returns them in sorted order
  // (by timestamp). |callback| is called with an empty vector if there was an
  // error.
  void GetLoggedBackgroundServiceEvents(
      devtools::proto::BackgroundService service,
      GetLoggedBackgroundServiceEventsCallback callback);

  // Clears all logged events related to |service|.
  void ClearLoggedBackgroundServiceEvents(
      devtools::proto::BackgroundService service);

 private:
  friend class DevToolsBackgroundServicesContextTest;

  // Whether |service| has an expiration time and it was exceeded.
  bool IsRecordingExpired(devtools::proto::BackgroundService service);

  void DidGetUserData(
      GetLoggedBackgroundServiceEventsCallback callback,
      const std::vector<std::pair<int64_t, std::string>>& user_data,
      blink::ServiceWorkerStatusCode status);

  void NotifyEventObservers(
      const devtools::proto::BackgroundServiceEvent& event);

  void OnRecordingTimeExpired(devtools::proto::BackgroundService service);

  const raw_ref<BrowserContext> browser_context_;
  scoped_refptr<ServiceWorkerContextWrapper> service_worker_context_;

  // Maps from the background service to the time up until the events can be
  // recorded. The BackgroundService enum is used as the index.
  std::array<base::Time, devtools::proto::BackgroundService::COUNT>
      expiration_times_;

  base::ObserverList<EventObserver> observers_;

  base::WeakPtrFactory<DevToolsBackgroundServicesContextImpl> weak_ptr_factory_{
      this};
};

}  // namespace content

#endif  // CONTENT_BROWSER_DEVTOOLS_DEVTOOLS_BACKGROUND_SERVICES_CONTEXT_IMPL_H_