Re-subimission of https://codereview.chromium.org/1041213003/
[chromium-blink-merge.git] / content / child / web_database_observer_impl.cc
blob3a88133a31c927b0587a6cdc9baaf81a1cbaec99
1 // Copyright 2013 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 #include "content/child/web_database_observer_impl.h"
7 #include "base/metrics/histogram.h"
8 #include "base/strings/string16.h"
9 #include "content/common/database_messages.h"
10 #include "third_party/WebKit/public/platform/WebCString.h"
11 #include "third_party/WebKit/public/platform/WebString.h"
12 #include "third_party/sqlite/sqlite3.h"
14 using blink::WebString;
16 namespace content {
18 namespace {
20 const int kResultHistogramSize = 50;
21 const int kCallsiteHistogramSize = 10;
23 int DetermineHistogramResult(int websql_error, int sqlite_error) {
24 // If we have a sqlite error, log it after trimming the extended bits.
25 // There are 26 possible values, but we leave room for some new ones.
26 if (sqlite_error)
27 return std::min(sqlite_error & 0xff, 30);
29 // Otherwise, websql_error may be an SQLExceptionCode, SQLErrorCode
30 // or a DOMExceptionCode, or -1 for success.
31 if (websql_error == -1)
32 return 0; // no error
34 // SQLExceptionCode starts at 1000
35 if (websql_error >= 1000)
36 websql_error -= 1000;
38 return std::min(websql_error + 30, kResultHistogramSize - 1);
41 #define UMA_HISTOGRAM_WEBSQL_RESULT(name, callsite, websql_error, sqlite_error) \
42 do { \
43 DCHECK(callsite < kCallsiteHistogramSize); \
44 int result = DetermineHistogramResult(websql_error, sqlite_error); \
45 UMA_HISTOGRAM_ENUMERATION("websql.Async." name, \
46 result, kResultHistogramSize); \
47 if (result) { \
48 UMA_HISTOGRAM_ENUMERATION("websql.Async." name ".ErrorSite", \
49 callsite, kCallsiteHistogramSize); \
50 } \
51 } while (0)
52 } // namespace
54 WebDatabaseObserverImpl::WebDatabaseObserverImpl(IPC::SyncMessageFilter* sender)
55 : sender_(sender),
56 open_connections_(new storage::DatabaseConnectionsWrapper) {
57 DCHECK(sender);
60 WebDatabaseObserverImpl::~WebDatabaseObserverImpl() {
63 void WebDatabaseObserverImpl::databaseOpened(
64 const WebString& origin_identifier,
65 const WebString& database_name,
66 const WebString& database_display_name,
67 unsigned long estimated_size) {
68 open_connections_->AddOpenConnection(origin_identifier.utf8(),
69 database_name);
70 sender_->Send(new DatabaseHostMsg_Opened(
71 origin_identifier.utf8(), database_name,
72 database_display_name, estimated_size));
75 void WebDatabaseObserverImpl::databaseModified(
76 const WebString& origin_identifier,
77 const WebString& database_name) {
78 sender_->Send(new DatabaseHostMsg_Modified(
79 origin_identifier.utf8(), database_name));
82 void WebDatabaseObserverImpl::databaseClosed(
83 const WebString& origin_identifier,
84 const WebString& database_name) {
85 sender_->Send(new DatabaseHostMsg_Closed(
86 origin_identifier.utf8(), database_name));
87 open_connections_->RemoveOpenConnection(origin_identifier.utf8(),
88 database_name);
91 void WebDatabaseObserverImpl::reportOpenDatabaseResult(
92 const WebString& origin_identifier,
93 const WebString& database_name,
94 int callsite, int websql_error, int sqlite_error) {
95 UMA_HISTOGRAM_WEBSQL_RESULT("OpenResult", callsite,
96 websql_error, sqlite_error);
97 HandleSqliteError(origin_identifier, database_name, sqlite_error);
100 void WebDatabaseObserverImpl::reportChangeVersionResult(
101 const WebString& origin_identifier,
102 const WebString& database_name,
103 int callsite, int websql_error, int sqlite_error) {
104 UMA_HISTOGRAM_WEBSQL_RESULT("ChangeVersionResult", callsite,
105 websql_error, sqlite_error);
106 HandleSqliteError(origin_identifier, database_name, sqlite_error);
109 void WebDatabaseObserverImpl::reportStartTransactionResult(
110 const WebString& origin_identifier,
111 const WebString& database_name,
112 int callsite, int websql_error, int sqlite_error) {
113 UMA_HISTOGRAM_WEBSQL_RESULT("BeginResult", callsite,
114 websql_error, sqlite_error);
115 HandleSqliteError(origin_identifier, database_name, sqlite_error);
118 void WebDatabaseObserverImpl::reportCommitTransactionResult(
119 const WebString& origin_identifier,
120 const WebString& database_name,
121 int callsite, int websql_error, int sqlite_error) {
122 UMA_HISTOGRAM_WEBSQL_RESULT("CommitResult", callsite,
123 websql_error, sqlite_error);
124 HandleSqliteError(origin_identifier, database_name, sqlite_error);
127 void WebDatabaseObserverImpl::reportExecuteStatementResult(
128 const WebString& origin_identifier,
129 const WebString& database_name,
130 int callsite, int websql_error, int sqlite_error) {
131 UMA_HISTOGRAM_WEBSQL_RESULT("StatementResult", callsite,
132 websql_error, sqlite_error);
133 HandleSqliteError(origin_identifier, database_name, sqlite_error);
136 void WebDatabaseObserverImpl::reportVacuumDatabaseResult(
137 const WebString& origin_identifier,
138 const WebString& database_name,
139 int sqlite_error) {
140 int result = DetermineHistogramResult(-1, sqlite_error);
141 UMA_HISTOGRAM_ENUMERATION("websql.Async.VacuumResult",
142 result, kResultHistogramSize);
144 HandleSqliteError(origin_identifier, database_name, sqlite_error);
147 void WebDatabaseObserverImpl::WaitForAllDatabasesToClose() {
148 open_connections_->WaitForAllDatabasesToClose();
151 void WebDatabaseObserverImpl::HandleSqliteError(
152 const WebString& origin_identifier,
153 const WebString& database_name,
154 int error) {
155 // We filter out errors which the backend doesn't act on to avoid
156 // a unnecessary ipc traffic, this method can get called at a fairly
157 // high frequency (per-sqlstatement).
158 if (error == SQLITE_CORRUPT || error == SQLITE_NOTADB) {
159 sender_->Send(new DatabaseHostMsg_HandleSqliteError(
160 origin_identifier.utf8(),
161 database_name,
162 error));
166 } // namespace content