summaryrefslogtreecommitdiffstats
path: root/components/nacl/renderer/nexe_load_manager.h
blob: 4b0f3a11199619b3de2b7f056004727259f90292 (plain)
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
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
// 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 COMPONENTS_NACL_RENDERER_NEXE_LOAD_MANAGER_H_
#define COMPONENTS_NACL_RENDERER_NEXE_LOAD_MANAGER_H_

#include <string>

#include "base/macros.h"
#include "base/memory/scoped_ptr.h"
#include "base/memory/weak_ptr.h"
#include "ppapi/c/private/ppb_nacl_private.h"
#include "url/gurl.h"

namespace content {
class PepperPluginInstance;
}

namespace nacl {

class ManifestServiceChannel;
class TrustedPluginChannel;

// NexeLoadManager provides methods for reporting the progress of loading a
// nexe.
class NexeLoadManager {
 public:
  explicit NexeLoadManager(PP_Instance instance);
  ~NexeLoadManager();

  void NexeFileDidOpen(int32_t pp_error,
                       int32_t fd,
                       int32_t http_status,
                       int64_t nexe_bytes_read,
                       const std::string& url,
                       int64_t time_since_open);
  void ReportLoadSuccess(bool is_pnacl,
                         const std::string& url,
                         uint64_t loaded_bytes,
                         uint64_t total_bytes);
  void ReportLoadError(PP_NaClError error,
                       const std::string& error_message);
  void ReportLoadError(PP_NaClError error,
                       const std::string& error_message,
                       const std::string& console_message);
  void ReportLoadAbort();
  void NexeDidCrash(const char* crash_log);

  // TODO(dmichael): Everything below this comment should eventually be made
  // private, when ppb_nacl_private_impl.cc is no longer using them directly.
  // The intent is for this class to only expose functions for reporting a
  // load state transition (e.g., ReportLoadError, ReportProgress,
  // ReportLoadAbort, etc.)
  struct ProgressEvent {
    explicit ProgressEvent(PP_NaClEventType event_type_param)
        : event_type(event_type_param),
          length_is_computable(false),
          loaded_bytes(0),
          total_bytes(0) {
    }
    ProgressEvent(PP_Instance instance, PP_NaClEventType event_type,
                  const std::string& resource_url, bool length_is_computable,
                  uint64_t loaded_bytes, uint64_t total_bytes)
        : instance(instance),
          event_type(event_type),
          resource_url(resource_url),
          length_is_computable(length_is_computable),
          loaded_bytes(loaded_bytes),
          total_bytes(total_bytes) {
    }
    PP_Instance instance;
    PP_NaClEventType event_type;
    std::string resource_url;
    bool length_is_computable;
    uint64_t loaded_bytes;
    uint64_t total_bytes;
  };
  void DispatchEvent(const ProgressEvent &event);
  void set_trusted_plugin_channel(scoped_ptr<TrustedPluginChannel> channel);
  void set_manifest_service_channel(
      scoped_ptr<ManifestServiceChannel> channel);

  PP_NaClReadyState nacl_ready_state();
  void set_nacl_ready_state(PP_NaClReadyState ready_state);

  void SetReadOnlyProperty(PP_Var key, PP_Var value);
  void SetLastError(const std::string& error);
  void LogToConsole(const std::string& message);

  bool is_installed() const { return is_installed_; }
  void set_is_installed(bool installed) { is_installed_ = installed; }

  int32_t exit_status() const { return exit_status_; }
  void set_exit_status(int32_t exit_status);

  void InitializePlugin();

  void ReportStartupOverhead() const;

  int64_t nexe_size() const { return nexe_size_; }

  bool RequestNaClManifest(const std::string& url, bool* is_data_uri);

  // URL resolution support.
  // plugin_base_url is the URL used for resolving relative URLs used in
  // src="...".
  const GURL& plugin_base_url() const { return plugin_base_url_; }

  // manifest_base_url is the URL used for resolving relative URLs mentioned
  // in manifest files.  If the manifest is a data URI, this is an empty string
  const GURL& manifest_base_url() const { return manifest_base_url_; }

 private:
  DISALLOW_COPY_AND_ASSIGN(NexeLoadManager);

  void ReportDeadNexe();

  // Copies a crash log to the console, one line at a time.
  void CopyCrashLogToJsConsole(const std::string& crash_log);

  PP_Instance pp_instance_;
  PP_NaClReadyState nacl_ready_state_;
  bool nexe_error_reported_;

  // A flag indicating if the NaCl executable is being loaded from an installed
  // application.  This flag is used to bucket UMA statistics more precisely to
  // help determine whether nexe loading problems are caused by networking
  // issues.  (Installed applications will be loaded from disk.)
  // Unfortunately, the definition of what it means to be part of an installed
  // application is a little murky - for example an installed application can
  // register a mime handler that loads NaCl executables into an arbitrary web
  // page.  As such, the flag actually means "our best guess, based on the URLs
  // for NaCl resources that we have seen so far".
  bool is_installed_;

  // Time of a successful nexe load.
  base::Time ready_time_;

  // Time of plugin initialization.
  base::Time init_time_;

  // Time of the start of loading a NaCl module.
  base::Time load_start_;

  // The exit status of the plugin process.
  // This will have a value in the range (0x00-0xff) if the exit status is set,
  // or -1 if set_exit_status() has never been called.
  int32_t exit_status_;

  // Size of the downloaded nexe, in bytes.
  int64_t nexe_size_;

  // Non-owning.
  content::PepperPluginInstance* plugin_instance_;

  // The URL for the document corresponding to this plugin instance.
  GURL plugin_base_url_;

  GURL manifest_base_url_;

  scoped_ptr<TrustedPluginChannel> trusted_plugin_channel_;
  scoped_ptr<ManifestServiceChannel> manifest_service_channel_;
  base::WeakPtrFactory<NexeLoadManager> weak_factory_;
};

}  // namespace nacl

#endif  // COMPONENTS_NACL_RENDERER_NEXE_LOAD_MANAGER_H_