iOS factory for AccountFetcherService
[chromium-blink-merge.git] / content / child / web_database_observer_impl.cc
blob68534a2065ba5d395dda3ec32efa5e907c6320eb
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;
22 const int kWebSQLSuccess = -1;
24 int DetermineHistogramResult(int websql_error, int sqlite_error) {
25 // If we have a sqlite error, log it after trimming the extended bits.
26 // There are 26 possible values, but we leave room for some new ones.
27 if (sqlite_error)
28 return std::min(sqlite_error & 0xff, 30);
30 // Otherwise, websql_error may be an SQLExceptionCode, SQLErrorCode
31 // or a DOMExceptionCode, or -1 for success.
32 if (websql_error == kWebSQLSuccess)
33 return 0; // no error
35 // SQLExceptionCode starts at 1000
36 if (websql_error >= 1000)
37 websql_error -= 1000;
39 return std::min(websql_error + 30, kResultHistogramSize - 1);
42 #define UMA_HISTOGRAM_WEBSQL_RESULT(name, callsite, websql_error, sqlite_error) \
43 do { \
44 DCHECK(callsite < kCallsiteHistogramSize); \
45 int result = DetermineHistogramResult(websql_error, sqlite_error); \
46 UMA_HISTOGRAM_ENUMERATION("websql.Async." name, \
47 result, kResultHistogramSize); \
48 if (result) { \
49 UMA_HISTOGRAM_ENUMERATION("websql.Async." name ".ErrorSite", \
50 callsite, kCallsiteHistogramSize); \
51 } \
52 } while (0)
53 } // namespace
55 WebDatabaseObserverImpl::WebDatabaseObserverImpl(IPC::SyncMessageFilter* sender)
56 : sender_(sender),
57 open_connections_(new storage::DatabaseConnectionsWrapper) {
58 DCHECK(sender);
61 WebDatabaseObserverImpl::~WebDatabaseObserverImpl() {
64 void WebDatabaseObserverImpl::databaseOpened(
65 const WebString& origin_identifier,
66 const WebString& database_name,
67 const WebString& database_display_name,
68 unsigned long estimated_size) {
69 open_connections_->AddOpenConnection(origin_identifier.utf8(),
70 database_name);
71 sender_->Send(new DatabaseHostMsg_Opened(
72 origin_identifier.utf8(), database_name,
73 database_display_name, estimated_size));
76 void WebDatabaseObserverImpl::databaseModified(
77 const WebString& origin_identifier,
78 const WebString& database_name) {
79 sender_->Send(new DatabaseHostMsg_Modified(
80 origin_identifier.utf8(), database_name));
83 void WebDatabaseObserverImpl::databaseClosed(
84 const WebString& origin_identifier,
85 const WebString& database_name) {
86 sender_->Send(new DatabaseHostMsg_Closed(
87 origin_identifier.utf8(), database_name));
88 open_connections_->RemoveOpenConnection(origin_identifier.utf8(),
89 database_name);
92 void WebDatabaseObserverImpl::reportOpenDatabaseResult(
93 const WebString& origin_identifier,
94 const WebString& database_name,
95 int callsite,
96 int websql_error,
97 int sqlite_error,
98 double call_time) {
99 UMA_HISTOGRAM_WEBSQL_RESULT("OpenResult", callsite,
100 websql_error, sqlite_error);
101 HandleSqliteError(origin_identifier, database_name, sqlite_error);
103 if (websql_error == kWebSQLSuccess && sqlite_error == SQLITE_OK) {
104 UMA_HISTOGRAM_TIMES("websql.Async.OpenTime.Success",
105 base::TimeDelta::FromSecondsD(call_time));
106 } else {
107 UMA_HISTOGRAM_TIMES("websql.Async.OpenTime.Error",
108 base::TimeDelta::FromSecondsD(call_time));
112 void WebDatabaseObserverImpl::reportChangeVersionResult(
113 const WebString& origin_identifier,
114 const WebString& database_name,
115 int callsite, int websql_error, int sqlite_error) {
116 UMA_HISTOGRAM_WEBSQL_RESULT("ChangeVersionResult", callsite,
117 websql_error, sqlite_error);
118 HandleSqliteError(origin_identifier, database_name, sqlite_error);
121 void WebDatabaseObserverImpl::reportStartTransactionResult(
122 const WebString& origin_identifier,
123 const WebString& database_name,
124 int callsite, int websql_error, int sqlite_error) {
125 UMA_HISTOGRAM_WEBSQL_RESULT("BeginResult", callsite,
126 websql_error, sqlite_error);
127 HandleSqliteError(origin_identifier, database_name, sqlite_error);
130 void WebDatabaseObserverImpl::reportCommitTransactionResult(
131 const WebString& origin_identifier,
132 const WebString& database_name,
133 int callsite, int websql_error, int sqlite_error) {
134 UMA_HISTOGRAM_WEBSQL_RESULT("CommitResult", callsite,
135 websql_error, sqlite_error);
136 HandleSqliteError(origin_identifier, database_name, sqlite_error);
139 void WebDatabaseObserverImpl::reportExecuteStatementResult(
140 const WebString& origin_identifier,
141 const WebString& database_name,
142 int callsite, int websql_error, int sqlite_error) {
143 UMA_HISTOGRAM_WEBSQL_RESULT("StatementResult", callsite,
144 websql_error, sqlite_error);
145 HandleSqliteError(origin_identifier, database_name, sqlite_error);
148 void WebDatabaseObserverImpl::reportVacuumDatabaseResult(
149 const WebString& origin_identifier,
150 const WebString& database_name,
151 int sqlite_error) {
152 int result = DetermineHistogramResult(-1, sqlite_error);
153 UMA_HISTOGRAM_ENUMERATION("websql.Async.VacuumResult",
154 result, kResultHistogramSize);
156 HandleSqliteError(origin_identifier, database_name, sqlite_error);
159 void WebDatabaseObserverImpl::WaitForAllDatabasesToClose() {
160 open_connections_->WaitForAllDatabasesToClose();
163 void WebDatabaseObserverImpl::HandleSqliteError(
164 const WebString& origin_identifier,
165 const WebString& database_name,
166 int error) {
167 // We filter out errors which the backend doesn't act on to avoid
168 // a unnecessary ipc traffic, this method can get called at a fairly
169 // high frequency (per-sqlstatement).
170 if (error == SQLITE_CORRUPT || error == SQLITE_NOTADB) {
171 sender_->Send(new DatabaseHostMsg_HandleSqliteError(
172 origin_identifier.utf8(),
173 database_name,
174 error));
178 } // namespace content