text: // Copyright 2014 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_SERVICE_WORKER_SERVICE_WORKER_HANDLE_H_
  #define CONTENT_BROWSER_SERVICE_WORKER_SERVICE_WORKER_HANDLE_H_
  
  #include "base/basictypes.h"
  #include "base/memory/ref_counted.h"
  #include "base/memory/scoped_ptr.h"
  #include "base/memory/weak_ptr.h"
  #include "content/browser/service_worker/service_worker_version.h"
  #include "content/common/content_export.h"
  #include "content/common/service_worker/service_worker_types.h"
  
  namespace IPC {
  class Sender;
  }
  
  namespace content {
  
  class ServiceWorkerContextCore;
  class ServiceWorkerRegistration;
  
  // Roughly corresponds to one ServiceWorker object in the renderer process
  // (WebServiceWorkerImpl).
  // Has references to the corresponding ServiceWorkerVersion and
  // ServiceWorkerRegistration (therefore they're guaranteed to be alive while
  // this handle is around).
  class CONTENT_EXPORT ServiceWorkerHandle
      : NON_EXPORTED_BASE(public ServiceWorkerVersion::Listener) {
   public:
    // Creates a handle for a live version. The version's corresponding
    // registration must be also alive.
    // This may return NULL if |context|.get() or |version| is NULL.
    // |sender| and |thread_id| will be used to send messages to the
    // corresponding WebServiceWorkerImpl (which should live on |thread_id|
    // in the child process).
    static scoped_ptr<ServiceWorkerHandle> Create(
        base::WeakPtr<ServiceWorkerContextCore> context,
        IPC::Sender* sender,
        int thread_id,
        int provider_id,
        ServiceWorkerVersion* version);
  
    ServiceWorkerHandle(base::WeakPtr<ServiceWorkerContextCore> context,
                        IPC::Sender* sender,
                        int thread_id,
                        int provider_id,
                        ServiceWorkerRegistration* registration,
                        ServiceWorkerVersion* version);
    ~ServiceWorkerHandle() override;
  
    // ServiceWorkerVersion::Listener overrides.
    void OnWorkerStarted(ServiceWorkerVersion* version) override;
    void OnWorkerStopped(ServiceWorkerVersion* version) override;
    void OnErrorReported(ServiceWorkerVersion* version,
                         const base::string16& error_message,
                         int line_number,
                         int column_number,
                         const GURL& source_url) override;
    void OnReportConsoleMessage(ServiceWorkerVersion* version,
                                int source_identifier,
                                int message_level,
                                const base::string16& message,
                                int line_number,
                                const GURL& source_url) override;
    void OnVersionStateChanged(ServiceWorkerVersion* version) override;
  
    ServiceWorkerObjectInfo GetObjectInfo();
  
    int thread_id() const { return thread_id_; }
    int provider_id() const { return provider_id_; }
    int handle_id() const { return handle_id_; }
    ServiceWorkerRegistration* registration() { return registration_.get(); }
    ServiceWorkerVersion* version() { return version_.get(); }
  
    bool HasNoRefCount() const { return ref_count_ <= 0; }
    void IncrementRefCount();
    void DecrementRefCount();
  
   private:
    base::WeakPtr<ServiceWorkerContextCore> context_;
    IPC::Sender* sender_;  // Not owned, it should always outlive this.
    const int thread_id_;
    const int provider_id_;
    const int handle_id_;
    int ref_count_;  // Created with 1.
    scoped_refptr<ServiceWorkerRegistration> registration_;
    scoped_refptr<ServiceWorkerVersion> version_;
  
    DISALLOW_COPY_AND_ASSIGN(ServiceWorkerHandle);
  };
  
  }  // namespace content
  
  #endif  // CONTENT_BROWSER_SERVICE_WORKER_SERVICE_WORKER_HANDLE_H_
  