diff options
author | jam@chromium.org <jam@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2011-03-17 00:26:18 +0000 |
---|---|---|
committer | jam@chromium.org <jam@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2011-03-17 00:26:18 +0000 |
commit | 797c355020734dc32ffa57f54d032afa20f018c8 (patch) | |
tree | 8a3a745aea8a8b7bf81c049f387eaa6321bf9bbc /content | |
parent | f6179ec31d0d530bd2ed66808bb24b601d60d453 (diff) | |
download | chromium_src-797c355020734dc32ffa57f54d032afa20f018c8.zip chromium_src-797c355020734dc32ffa57f54d032afa20f018c8.tar.gz chromium_src-797c355020734dc32ffa57f54d032afa20f018c8.tar.bz2 |
Move a bunch of files from chrome\common to content\common.
TBR=avi
Review URL: http://codereview.chromium.org/6677096
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@78473 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'content')
33 files changed, 1185 insertions, 22 deletions
diff --git a/content/browser/geolocation/core_location_data_provider_mac.h b/content/browser/geolocation/core_location_data_provider_mac.h index cbe0e8a..d23341f 100644 --- a/content/browser/geolocation/core_location_data_provider_mac.h +++ b/content/browser/geolocation/core_location_data_provider_mac.h @@ -12,8 +12,8 @@ #include "base/ref_counted.h" #include "base/scoped_nsobject.h" -#include "chrome/common/geoposition.h" #include "content/browser/browser_thread.h" +#include "content/common/geoposition.h" #import <Foundation/Foundation.h> diff --git a/content/browser/geolocation/core_location_provider_mac.h b/content/browser/geolocation/core_location_provider_mac.h index d9b1263..d26428d 100644 --- a/content/browser/geolocation/core_location_provider_mac.h +++ b/content/browser/geolocation/core_location_provider_mac.h @@ -10,8 +10,8 @@ #define CONTENT_BROWSER_GEOLOCATION_CORE_LOCATION_PROVIDER_MAC_H_ #pragma once -#include "chrome/common/geoposition.h" #include "content/browser/geolocation/location_provider.h" +#include "content/common/geoposition.h" class CoreLocationDataProviderMac; diff --git a/content/browser/geolocation/geolocation_dispatcher_host.cc b/content/browser/geolocation/geolocation_dispatcher_host.cc index 3d4cd5b..33193d3 100644 --- a/content/browser/geolocation/geolocation_dispatcher_host.cc +++ b/content/browser/geolocation/geolocation_dispatcher_host.cc @@ -8,13 +8,13 @@ #include <set> #include <utility> -#include "chrome/common/geoposition.h" #include "chrome/common/render_messages.h" #include "content/browser/geolocation/geolocation_permission_context.h" #include "content/browser/geolocation/geolocation_provider.h" #include "content/browser/renderer_host/render_message_filter.h" #include "content/browser/renderer_host/render_process_host.h" #include "content/browser/renderer_host/render_view_host.h" +#include "content/common/geoposition.h" namespace { class GeolocationDispatcherHostImpl : public GeolocationDispatcherHost, diff --git a/content/browser/geolocation/geolocation_provider.h b/content/browser/geolocation/geolocation_provider.h index 45e63e6..aaf398e 100644 --- a/content/browser/geolocation/geolocation_provider.h +++ b/content/browser/geolocation/geolocation_provider.h @@ -9,8 +9,8 @@ #include <map> #include "base/threading/thread.h" -#include "chrome/common/geoposition.h" #include "content/browser/geolocation/geolocation_observer.h" +#include "content/common/geoposition.h" #include "googleurl/src/gurl.h" class GeolocationArbitrator; diff --git a/content/browser/geolocation/gps_location_provider_linux.h b/content/browser/geolocation/gps_location_provider_linux.h index 43b980d..f923dd1 100644 --- a/content/browser/geolocation/gps_location_provider_linux.h +++ b/content/browser/geolocation/gps_location_provider_linux.h @@ -13,8 +13,8 @@ #include "base/scoped_ptr.h" #include "base/task.h" -#include "chrome/common/geoposition.h" #include "content/browser/geolocation/location_provider.h" +#include "content/common/geoposition.h" class LibGps; diff --git a/content/browser/geolocation/libgps_2_38_wrapper_linux.cc b/content/browser/geolocation/libgps_2_38_wrapper_linux.cc index bb49889..7cfdb52 100644 --- a/content/browser/geolocation/libgps_2_38_wrapper_linux.cc +++ b/content/browser/geolocation/libgps_2_38_wrapper_linux.cc @@ -11,7 +11,7 @@ #include <sys/time.h> #include "base/logging.h" -#include "chrome/common/geoposition.h" +#include "content/common/geoposition.h" #include "third_party/gpsd/release-2.38/gps.h" class LibGpsV238 : public LibGps { diff --git a/content/browser/geolocation/libgps_2_94_wrapper_linux.cc b/content/browser/geolocation/libgps_2_94_wrapper_linux.cc index f2f1198..c9fb1bd 100644 --- a/content/browser/geolocation/libgps_2_94_wrapper_linux.cc +++ b/content/browser/geolocation/libgps_2_94_wrapper_linux.cc @@ -7,7 +7,7 @@ #include "content/browser/geolocation/libgps_wrapper_linux.h" #include "base/logging.h" -#include "chrome/common/geoposition.h" +#include "content/common/geoposition.h" #include "third_party/gpsd/release-2.94/gps.h" class LibGpsV294 : public LibGps { diff --git a/content/browser/geolocation/libgps_wrapper_linux.cc b/content/browser/geolocation/libgps_wrapper_linux.cc index bf14005..d09ea01 100644 --- a/content/browser/geolocation/libgps_wrapper_linux.cc +++ b/content/browser/geolocation/libgps_wrapper_linux.cc @@ -7,9 +7,9 @@ #include <dlfcn.h> #include <errno.h> -#include "chrome/common/geoposition.h" #include "base/logging.h" #include "base/string_util.h" +#include "content/common/geoposition.h" namespace { // Pass to TryToOpen() to indicate which functions should be wired up. diff --git a/content/browser/geolocation/location_arbitrator.h b/content/browser/geolocation/location_arbitrator.h index e3bb12b..75481ca 100644 --- a/content/browser/geolocation/location_arbitrator.h +++ b/content/browser/geolocation/location_arbitrator.h @@ -9,11 +9,11 @@ #include "base/string16.h" #include "base/scoped_vector.h" #include "base/time.h" -#include "chrome/common/geoposition.h" #include "chrome/common/net/url_request_context_getter.h" #include "content/browser/geolocation/access_token_store.h" #include "content/browser/geolocation/location_provider.h" #include "content/browser/geolocation/geolocation_observer.h" +#include "content/common/geoposition.h" #include "googleurl/src/gurl.h" class AccessTokenStore; diff --git a/content/browser/geolocation/location_arbitrator_unittest.cc b/content/browser/geolocation/location_arbitrator_unittest.cc index bd73a10..69c85c4a 100644 --- a/content/browser/geolocation/location_arbitrator_unittest.cc +++ b/content/browser/geolocation/location_arbitrator_unittest.cc @@ -3,13 +3,13 @@ // found in the LICENSE file. #include "base/scoped_ptr.h" -#include "chrome/common/geoposition.h" #include "content/browser/geolocation/arbitrator_dependency_factory.h" #include "content/browser/geolocation/fake_access_token_store.h" #include "content/browser/geolocation/geolocation_observer.h" #include "content/browser/geolocation/location_arbitrator.h" #include "content/browser/geolocation/location_provider.h" #include "content/browser/geolocation/mock_location_provider.h" +#include "content/common/geoposition.h" #include "testing/gtest/include/gtest/gtest.h" namespace { diff --git a/content/browser/geolocation/mock_location_provider.h b/content/browser/geolocation/mock_location_provider.h index c983f58..c11367b 100644 --- a/content/browser/geolocation/mock_location_provider.h +++ b/content/browser/geolocation/mock_location_provider.h @@ -10,8 +10,8 @@ #include "base/ref_counted.h" #include "base/scoped_ptr.h" #include "base/threading/thread.h" -#include "chrome/common/geoposition.h" #include "content/browser/geolocation/location_provider.h" +#include "content/common/geoposition.h" #include "googleurl/src/gurl.h" // Mock implementation of a location provider for testing. diff --git a/content/browser/geolocation/network_location_provider.h b/content/browser/geolocation/network_location_provider.h index c105ac6..4a9abd6 100644 --- a/content/browser/geolocation/network_location_provider.h +++ b/content/browser/geolocation/network_location_provider.h @@ -14,10 +14,10 @@ #include "base/scoped_ptr.h" #include "base/string16.h" #include "base/threading/thread.h" -#include "chrome/common/geoposition.h" #include "content/browser/geolocation/device_data_provider.h" #include "content/browser/geolocation/location_provider.h" #include "content/browser/geolocation/network_location_request.h" +#include "content/common/geoposition.h" class URLFetcherProtectEntry; diff --git a/content/browser/geolocation/network_location_request.cc b/content/browser/geolocation/network_location_request.cc index 6c96c2e..ec02d18 100644 --- a/content/browser/geolocation/network_location_request.cc +++ b/content/browser/geolocation/network_location_request.cc @@ -9,8 +9,8 @@ #include "base/string_number_conversions.h" #include "base/utf_string_conversions.h" #include "base/values.h" -#include "chrome/common/geoposition.h" #include "chrome/common/net/url_request_context_getter.h" +#include "content/common/geoposition.h" #include "net/base/load_flags.h" #include "net/url_request/url_request_status.h" diff --git a/content/browser/geolocation/win7_location_api_win.cc b/content/browser/geolocation/win7_location_api_win.cc index c14c16b..a8fab77 100644 --- a/content/browser/geolocation/win7_location_api_win.cc +++ b/content/browser/geolocation/win7_location_api_win.cc @@ -11,7 +11,7 @@ #include "base/path_service.h" #include "base/scoped_ptr.h" #include "chrome/common/chrome_switches.h" -#include "chrome/common/geoposition.h" +#include "content/common/geoposition.h" namespace { const double kKnotsToMetresPerSecondConversionFactor = 0.5144; diff --git a/content/browser/geolocation/win7_location_provider_win.h b/content/browser/geolocation/win7_location_provider_win.h index 33f2818..ce44828 100644 --- a/content/browser/geolocation/win7_location_provider_win.h +++ b/content/browser/geolocation/win7_location_provider_win.h @@ -9,7 +9,7 @@ #include "base/task.h" #include "content/browser/geolocation/location_provider.h" #include "content/browser/geolocation/win7_location_api_win.h" -#include "chrome/common/geoposition.h" +#include "content/common/geoposition.h" // Location provider for Windows 7 that uses the Location and Sensors platform // to obtain position fixes. diff --git a/content/browser/renderer_host/backing_store_manager.cc b/content/browser/renderer_host/backing_store_manager.cc index a725243..7247da0 100644 --- a/content/browser/renderer_host/backing_store_manager.cc +++ b/content/browser/renderer_host/backing_store_manager.cc @@ -8,9 +8,9 @@ #include "base/sys_info.h" #include "chrome/common/chrome_constants.h" #include "chrome/common/chrome_switches.h" -#include "chrome/common/mru_cache.h" #include "content/browser/renderer_host/backing_store.h" #include "content/browser/renderer_host/render_widget_host.h" +#include "content/common/mru_cache.h" #include "content/common/notification_service.h" namespace { diff --git a/content/browser/renderer_host/render_sandbox_host_linux.cc b/content/browser/renderer_host/render_sandbox_host_linux.cc index 4499d77..3fca5127 100644 --- a/content/browser/renderer_host/render_sandbox_host_linux.cc +++ b/content/browser/renderer_host/render_sandbox_host_linux.cc @@ -26,9 +26,9 @@ #include "base/singleton.h" #include "base/string_number_conversions.h" #include "base/string_util.h" -#include "chrome/common/font_config_ipc_linux.h" #include "chrome/common/sandbox_methods_linux.h" -#include "chrome/common/unix_domain_socket_posix.h" +#include "content/common/font_config_ipc_linux.h" +#include "content/common/unix_domain_socket_posix.h" #include "skia/ext/SkFontHost_fontconfig_direct.h" #include "third_party/npapi/bindings/npapi_extensions.h" #include "third_party/WebKit/Source/WebKit/chromium/public/gtk/WebFontInfo.h" diff --git a/content/browser/zygote_host_linux.cc b/content/browser/zygote_host_linux.cc index 9152f9f..1eee6f3 100644 --- a/content/browser/zygote_host_linux.cc +++ b/content/browser/zygote_host_linux.cc @@ -25,8 +25,8 @@ #include "chrome/common/chrome_switches.h" #include "chrome/common/process_watcher.h" #include "chrome/common/result_codes.h" -#include "chrome/common/unix_domain_socket_posix.h" #include "content/browser/renderer_host/render_sandbox_host_linux.h" +#include "content/common/unix_domain_socket_posix.h" #include "sandbox/linux/suid/suid_unsafe_environment_variables.h" static void SaveSUIDUnsafeEnvironmentVariables() { diff --git a/content/browser/zygote_main_linux.cc b/content/browser/zygote_main_linux.cc index b56a8a0..b8fde82 100644 --- a/content/browser/zygote_main_linux.cc +++ b/content/browser/zygote_main_linux.cc @@ -38,14 +38,14 @@ #include "build/build_config.h" #include "chrome/common/chrome_descriptors.h" #include "chrome/common/chrome_switches.h" -#include "chrome/common/font_config_ipc_linux.h" #include "chrome/common/pepper_plugin_registry.h" #include "chrome/common/process_watcher.h" #include "chrome/common/result_codes.h" #include "chrome/common/sandbox_methods_linux.h" #include "chrome/common/set_process_title.h" -#include "chrome/common/unix_domain_socket_posix.h" +#include "content/common/font_config_ipc_linux.h" #include "content/common/main_function_params.h" +#include "content/common/unix_domain_socket_posix.h" #include "media/base/media.h" #include "seccompsandbox/sandbox.h" #include "skia/ext/SkFontHost_fontconfig_control.h" diff --git a/content/common/font_config_ipc_linux.cc b/content/common/font_config_ipc_linux.cc new file mode 100644 index 0000000..c7c6073 --- /dev/null +++ b/content/common/font_config_ipc_linux.cc @@ -0,0 +1,110 @@ +// Copyright (c) 2010 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. + +#include "content/common/font_config_ipc_linux.h" + +#include <errno.h> +#include <unistd.h> +#include <fcntl.h> +#include <sys/socket.h> +#include <sys/uio.h> + +#include "base/pickle.h" +#include "content/common/unix_domain_socket_posix.h" + +FontConfigIPC::FontConfigIPC(int fd) + : fd_(fd) { +} + +FontConfigIPC::~FontConfigIPC() { + close(fd_); +} + +bool FontConfigIPC::Match(std::string* result_family, + unsigned* result_filefaceid, + bool filefaceid_valid, unsigned filefaceid, + const std::string& family, + const void* characters, size_t characters_bytes, + bool* is_bold, bool* is_italic) { + if (family.length() > kMaxFontFamilyLength) + return false; + + Pickle request; + request.WriteInt(METHOD_MATCH); + request.WriteBool(filefaceid_valid); + if (filefaceid_valid) + request.WriteUInt32(filefaceid); + + request.WriteBool(is_bold && *is_bold); + request.WriteBool(is_bold && *is_italic); + + request.WriteUInt32(characters_bytes); + if (characters_bytes) + request.WriteBytes(characters, characters_bytes); + + request.WriteString(family); + + uint8_t reply_buf[512]; + const ssize_t r = UnixDomainSocket::SendRecvMsg(fd_, reply_buf, + sizeof(reply_buf), NULL, + request); + if (r == -1) + return false; + + Pickle reply(reinterpret_cast<char*>(reply_buf), r); + void* iter = NULL; + bool result; + if (!reply.ReadBool(&iter, &result)) + return false; + if (!result) + return false; + + uint32_t reply_filefaceid; + std::string reply_family; + bool resulting_bold, resulting_italic; + if (!reply.ReadUInt32(&iter, &reply_filefaceid) || + !reply.ReadString(&iter, &reply_family) || + !reply.ReadBool(&iter, &resulting_bold) || + !reply.ReadBool(&iter, &resulting_italic)) { + return false; + } + + *result_filefaceid = reply_filefaceid; + if (result_family) + *result_family = reply_family; + + if (is_bold) + *is_bold = resulting_bold; + if (is_italic) + *is_italic = resulting_italic; + + return true; +} + +int FontConfigIPC::Open(unsigned filefaceid) { + Pickle request; + request.WriteInt(METHOD_OPEN); + request.WriteUInt32(filefaceid); + + int result_fd = -1; + uint8_t reply_buf[256]; + const ssize_t r = UnixDomainSocket::SendRecvMsg(fd_, reply_buf, + sizeof(reply_buf), + &result_fd, request); + + if (r == -1) + return -1; + + Pickle reply(reinterpret_cast<char*>(reply_buf), r); + bool result; + void* iter = NULL; + if (!reply.ReadBool(&iter, &result) || + !result) { + if (result_fd) + close(result_fd); + return -1; + } + + return result_fd; +} diff --git a/content/common/font_config_ipc_linux.h b/content/common/font_config_ipc_linux.h new file mode 100644 index 0000000..4873c14 --- /dev/null +++ b/content/common/font_config_ipc_linux.h @@ -0,0 +1,40 @@ +// Copyright (c) 2010 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_COMMON_FONT_CONFIG_IPC_LINUX_H_ +#define CONTENT_COMMON_FONT_CONFIG_IPC_LINUX_H_ +#pragma once + +#include "skia/ext/SkFontHost_fontconfig_impl.h" + +#include <string> + +// FontConfig implementation for Skia that proxies out of process to get out +// of the sandbox. See http://code.google.com/p/chromium/wiki/LinuxSandboxIPC +class FontConfigIPC : public FontConfigInterface { + public: + explicit FontConfigIPC(int fd); + ~FontConfigIPC(); + + // FontConfigInterface implementation. + virtual bool Match(std::string* result_family, + unsigned* result_filefaceid, + bool filefaceid_valid, + unsigned filefaceid, + const std::string& family, + const void* characters, + size_t characters_bytes, + bool* is_bold, bool* is_italic); + virtual int Open(unsigned filefaceid); + + enum Method { + METHOD_MATCH = 0, + METHOD_OPEN = 1, + }; + + private: + const int fd_; +}; + +#endif // CONTENT_COMMON_FONT_CONFIG_IPC_LINUX_H_ diff --git a/content/common/geoposition.cc b/content/common/geoposition.cc new file mode 100644 index 0000000..4beac74 --- /dev/null +++ b/content/common/geoposition.cc @@ -0,0 +1,66 @@ +// Copyright (c) 2010 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. + +#include "content/common/geoposition.h" + +namespace { +// Sentinel values to mark invalid data. (WebKit carries companion is_valid +// bools for this purpose; we may eventually follow that approach, but +// sentinels worked OK in the Gears code this is based on.) +const double kBadLatitudeLongitude = 200; +// Lowest point on land is at approximately -400 meters. +const int kBadAltitude = -10000; +const int kBadAccuracy = -1; // Accuracy must be non-negative. +const int64 kBadTimestamp = kint64min; +const int kBadHeading = -1; // Heading must be non-negative. +const int kBadSpeed = -1; +} + +Geoposition::Geoposition() + : latitude(kBadLatitudeLongitude), + longitude(kBadLatitudeLongitude), + altitude(kBadAltitude), + accuracy(kBadAccuracy), + altitude_accuracy(kBadAccuracy), + heading(kBadHeading), + speed(kBadSpeed), + error_code(ERROR_CODE_NONE) { +} + +bool Geoposition::is_valid_latlong() const { + return latitude >= -90.0 && latitude <= 90.0 && + longitude >= -180.0 && longitude <= 180.0; +} + +bool Geoposition::is_valid_altitude() const { + return altitude > kBadAltitude; +} + +bool Geoposition::is_valid_accuracy() const { + return accuracy >= 0.0; +} + +bool Geoposition::is_valid_altitude_accuracy() const { + return altitude_accuracy >= 0.0; +} + +bool Geoposition::is_valid_heading() const { + return heading >= 0 && heading <= 360; +} + +bool Geoposition::is_valid_speed() const { + return speed >= 0; +} + +bool Geoposition::is_valid_timestamp() const { + return !timestamp.is_null(); +} + +bool Geoposition::IsValidFix() const { + return is_valid_latlong() && is_valid_accuracy() && is_valid_timestamp(); +} + +bool Geoposition::IsInitialized() const { + return error_code != ERROR_CODE_NONE || IsValidFix(); +} diff --git a/content/common/geoposition.h b/content/common/geoposition.h new file mode 100644 index 0000000..9f8f14e --- /dev/null +++ b/content/common/geoposition.h @@ -0,0 +1,65 @@ +// Copyright (c) 2010 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. + +// This file declares the Position structure, which is used to represent a +// position fix. Originally derived from +// http://gears.googlecode.com/svn/trunk/gears/geolocation/geolocation.h + +#ifndef CONTENT_COMMON_GEOPOSITION_H_ +#define CONTENT_COMMON_GEOPOSITION_H_ +#pragma once + +#include <string> +#include "base/time.h" + +// The internal representation of a geo position. Some properties use different +// types when passed to JavaScript. +struct Geoposition { + public: + // Error codes for returning to JavaScript. These values are defined by the + // W3C spec. Note that Gears does not use all of these codes, but we need + // values for all of them to allow us to provide the constants on the error + // object. + enum ErrorCode { + ERROR_CODE_NONE = 0, // Chrome addition + ERROR_CODE_PERMISSION_DENIED = 1, + ERROR_CODE_POSITION_UNAVAILABLE = 2, + ERROR_CODE_TIMEOUT = 3, + }; + + Geoposition(); + + bool is_valid_latlong() const; + bool is_valid_altitude() const; + bool is_valid_accuracy() const; + bool is_valid_altitude_accuracy() const; + bool is_valid_heading() const; + bool is_valid_speed() const; + bool is_valid_timestamp() const; + + // A valid fix has a valid latitude, longitude, accuracy and timestamp. + bool IsValidFix() const; + + // A position is considered initialized if it has either a valid fix or + // an error code other than NONE. + bool IsInitialized() const; + + // These properties correspond to the JavaScript Position object. + double latitude; // In degrees + double longitude; // In degrees + double altitude; // In metres + double accuracy; // In metres + double altitude_accuracy; // In metres + double heading; // In degrees clockwise relative to the true north + double speed; // In meters per second + // Timestamp for this position fix object taken from the host computer's + // system clock (i.e. from Time::Now(), not the source device's clock). + base::Time timestamp; + + // These properties are returned to JavaScript as a PositionError object. + ErrorCode error_code; + std::string error_message; // Human-readable error message +}; + +#endif // CONTENT_COMMON_GEOPOSITION_H_ diff --git a/content/common/mru_cache.h b/content/common/mru_cache.h new file mode 100644 index 0000000..4c55576 --- /dev/null +++ b/content/common/mru_cache.h @@ -0,0 +1,253 @@ +// Copyright (c) 2009 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. + +// This file contains a template for a Most Recently Used cache that allows +// constant-time access to items using a key, but easy identification of the +// least-recently-used items for removal. Each key can only be associated with +// one payload item at a time. +// +// The key object will be stored twice, so it should support efficient copying. +// +// NOTE: While all operations are O(1), this code is written for +// legibility rather than optimality. If future profiling identifies this as +// a bottleneck, there is room for smaller values of 1 in the O(1). :] + +#ifndef CONTENT_COMMON_MRU_CACHE_H_ +#define CONTENT_COMMON_MRU_CACHE_H_ +#pragma once + +#include <list> +#include <map> +#include <utility> + +#include "base/basictypes.h" +#include "base/logging.h" + +// MRUCacheBase ---------------------------------------------------------------- + +// Base class for the MRU cache specializations defined below. +// The deletor will get called on all payloads that are being removed or +// replaced. +template <class KeyType, class PayloadType, class DeletorType> +class MRUCacheBase { + public: + // The payload of the list. This maintains a copy of the key so we can + // efficiently delete things given an element of the list. + typedef std::pair<KeyType, PayloadType> value_type; + + private: + typedef std::list<value_type> PayloadList; + typedef std::map<KeyType, typename PayloadList::iterator> KeyIndex; + + public: + typedef typename PayloadList::size_type size_type; + + typedef typename PayloadList::iterator iterator; + typedef typename PayloadList::const_iterator const_iterator; + typedef typename PayloadList::reverse_iterator reverse_iterator; + typedef typename PayloadList::const_reverse_iterator const_reverse_iterator; + + enum { NO_AUTO_EVICT = 0 }; + + // The max_size is the size at which the cache will prune its members to when + // a new item is inserted. If the caller wants to manager this itself (for + // example, maybe it has special work to do when something is evicted), it + // can pass NO_AUTO_EVICT to not restrict the cache size. + explicit MRUCacheBase(size_type max_size) : max_size_(max_size) { + } + + virtual ~MRUCacheBase() { + iterator i = begin(); + while (i != end()) + i = Erase(i); + } + + // Inserts a payload item with the given key. If an existing item has + // the same key, it is removed prior to insertion. An iterator indicating the + // inserted item will be returned (this will always be the front of the list). + // + // The payload will be copied. In the case of an OwningMRUCache, this function + // will take ownership of the pointer. + iterator Put(const KeyType& key, const PayloadType& payload) { + // Remove any existing payload with that key. + typename KeyIndex::iterator index_iter = index_.find(key); + if (index_iter != index_.end()) { + // Erase the reference to it. This will call the deletor on the removed + // element. The index reference will be replaced in the code below. + Erase(index_iter->second); + } else if (max_size_ != NO_AUTO_EVICT) { + // New item is being inserted which might make it larger than the maximum + // size: kick the oldest thing out if necessary. + ShrinkToSize(max_size_ - 1); + } + + ordering_.push_front(value_type(key, payload)); + index_[key] = ordering_.begin(); + return ordering_.begin(); + } + + // Retrieves the contents of the given key, or end() if not found. This method + // has the side effect of moving the requested item to the front of the + // recency list. + // + // TODO(brettw) We may want a const version of this function in the future. + iterator Get(const KeyType& key) { + typename KeyIndex::iterator index_iter = index_.find(key); + if (index_iter == index_.end()) + return end(); + typename PayloadList::iterator iter = index_iter->second; + + // Move the touched item to the front of the recency ordering. + ordering_.splice(ordering_.begin(), ordering_, iter); + return ordering_.begin(); + } + + // Retrieves the payload associated with a given key and returns it via + // result without affecting the ordering (unlike Get). + // + // TODO(brettw) We may want a const version of this function in the future. + iterator Peek(const KeyType& key) { + typename KeyIndex::const_iterator index_iter = index_.find(key); + if (index_iter == index_.end()) + return end(); + return index_iter->second; + } + + // Erases the item referenced by the given iterator. An iterator to the item + // following it will be returned. The iterator must be valid. + iterator Erase(iterator pos) { + deletor_(pos->second); + index_.erase(pos->first); + return ordering_.erase(pos); + } + + // MRUCache entries are often processed in reverse order, so we add this + // convenience function (not typically defined by STL containers). + reverse_iterator Erase(reverse_iterator pos) { + // We have to actually give it the incremented iterator to delete, since + // the forward iterator that base() returns is actually one past the item + // being iterated over. + return reverse_iterator(Erase((++pos).base())); + } + + // Shrinks the cache so it only holds |new_size| items. If |new_size| is + // bigger or equal to the current number of items, this will do nothing. + void ShrinkToSize(size_type new_size) { + for (size_type i = size(); i > new_size; i--) + Erase(rbegin()); + } + + // Deletes everything from the cache. + void Clear() { + for (typename PayloadList::iterator i(ordering_.begin()); + i != ordering_.end(); ++i) + deletor_(i->second); + index_.clear(); + ordering_.clear(); + } + + // Returns the number of elements in the cache. + size_type size() const { + // We don't use ordering_.size() for the return value because + // (as a linked list) it can be O(n). + DCHECK(index_.size() == ordering_.size()); + return index_.size(); + } + + // Allows iteration over the list. Forward iteration starts with the most + // recent item and works backwards. + // + // Note that since these iterators are actually iterators over a list, you + // can keep them as you insert or delete things (as long as you don't delete + // the one you are pointing to) and they will still be valid. + iterator begin() { return ordering_.begin(); } + const_iterator begin() const { ordering_.begin(); } + iterator end() { return ordering_.end(); } + const_iterator end() const { return ordering_.end(); } + + reverse_iterator rbegin() { return ordering_.rbegin(); } + const_reverse_iterator rbegin() const { ordering_.rbegin(); } + reverse_iterator rend() { return ordering_.rend(); } + const_reverse_iterator rend() const { return ordering_.rend(); } + + bool empty() const { return ordering_.empty(); } + + private: + PayloadList ordering_; + KeyIndex index_; + + size_type max_size_; + + DeletorType deletor_; + + DISALLOW_COPY_AND_ASSIGN(MRUCacheBase); +}; + +// MRUCache -------------------------------------------------------------------- + +// A functor that does nothing. Used by the MRUCache. +template<class PayloadType> +class MRUCacheNullDeletor { + public: + void operator()(PayloadType& payload) { + } +}; + +// A container that does not do anything to free its data. Use this when storing +// value types (as opposed to pointers) in the list. +template <class KeyType, class PayloadType> +class MRUCache : public MRUCacheBase<KeyType, + PayloadType, + MRUCacheNullDeletor<PayloadType> > { + private: + typedef MRUCacheBase<KeyType, PayloadType, + MRUCacheNullDeletor<PayloadType> > ParentType; + + public: + // See MRUCacheBase, noting the possibility of using NO_AUTO_EVICT. + explicit MRUCache(typename ParentType::size_type max_size) + : ParentType(max_size) { + } + virtual ~MRUCache() { + } + + private: + DISALLOW_COPY_AND_ASSIGN(MRUCache); +}; + +// OwningMRUCache -------------------------------------------------------------- + +template<class PayloadType> +class MRUCachePointerDeletor { + public: + void operator()(PayloadType& payload) { + delete payload; + } +}; + +// A cache that owns the payload type, which must be a non-const pointer type. +// The pointers will be deleted when they are removed, replaced, or when the +// cache is destroyed. +template <class KeyType, class PayloadType> +class OwningMRUCache + : public MRUCacheBase<KeyType, + PayloadType, + MRUCachePointerDeletor<PayloadType> > { + private: + typedef MRUCacheBase<KeyType, PayloadType, + MRUCachePointerDeletor<PayloadType> > ParentType; + + public: + // See MRUCacheBase, noting the possibility of using NO_AUTO_EVICT. + explicit OwningMRUCache(typename ParentType::size_type max_size) + : ParentType(max_size) { + } + virtual ~OwningMRUCache() { + } + + private: + DISALLOW_COPY_AND_ASSIGN(OwningMRUCache); +}; + +#endif // CONTENT_COMMON_MRU_CACHE_H_ diff --git a/content/common/mru_cache_unittest.cc b/content/common/mru_cache_unittest.cc new file mode 100644 index 0000000..bd18ffe --- /dev/null +++ b/content/common/mru_cache_unittest.cc @@ -0,0 +1,253 @@ +// Copyright (c) 2009 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. + +#include "base/basictypes.h" +#include "content/common/mru_cache.h" +#include "testing/gtest/include/gtest/gtest.h" + +namespace { + +int cached_item_live_count = 0; + +struct CachedItem { + CachedItem() : value(0) { + cached_item_live_count++; + } + + explicit CachedItem(int new_value) : value(new_value) { + cached_item_live_count++; + } + + explicit CachedItem(const CachedItem& other) : value(other.value) { + cached_item_live_count++; + } + + ~CachedItem() { + cached_item_live_count--; + } + + int value; +}; + +} // namespace + +TEST(MRUCacheTest, Basic) { + typedef MRUCache<int, CachedItem> Cache; + Cache cache(Cache::NO_AUTO_EVICT); + + // Check failure conditions + { + CachedItem test_item; + EXPECT_TRUE(cache.Get(0) == cache.end()); + EXPECT_TRUE(cache.Peek(0) == cache.end()); + } + + static const int kItem1Key = 5; + CachedItem item1(10); + Cache::iterator inserted_item = cache.Put(kItem1Key, item1); + EXPECT_EQ(1U, cache.size()); + + // Check that item1 was properly inserted. + { + Cache::iterator found = cache.Get(kItem1Key); + EXPECT_TRUE(inserted_item == cache.begin()); + EXPECT_TRUE(found != cache.end()); + + found = cache.Peek(kItem1Key); + EXPECT_TRUE(found != cache.end()); + + EXPECT_EQ(kItem1Key, found->first); + EXPECT_EQ(item1.value, found->second.value); + } + + static const int kItem2Key = 7; + CachedItem item2(12); + cache.Put(kItem2Key, item2); + EXPECT_EQ(2U, cache.size()); + + // Check that item1 is the oldest since item2 was added afterwards. + { + Cache::reverse_iterator oldest = cache.rbegin(); + ASSERT_TRUE(oldest != cache.rend()); + EXPECT_EQ(kItem1Key, oldest->first); + EXPECT_EQ(item1.value, oldest->second.value); + } + + // Check that item1 is still accessible by key. + { + Cache::iterator test_item = cache.Get(kItem1Key); + ASSERT_TRUE(test_item != cache.end()); + EXPECT_EQ(kItem1Key, test_item->first); + EXPECT_EQ(item1.value, test_item->second.value); + } + + // Check that retrieving item1 pushed item2 to oldest. + { + Cache::reverse_iterator oldest = cache.rbegin(); + ASSERT_TRUE(oldest != cache.rend()); + EXPECT_EQ(kItem2Key, oldest->first); + EXPECT_EQ(item2.value, oldest->second.value); + } + + // Remove the oldest item and check that item1 is now the only member. + { + Cache::reverse_iterator next = cache.Erase(cache.rbegin()); + + EXPECT_EQ(1U, cache.size()); + + EXPECT_TRUE(next == cache.rbegin()); + EXPECT_EQ(kItem1Key, next->first); + EXPECT_EQ(item1.value, next->second.value); + + cache.Erase(cache.begin()); + EXPECT_EQ(0U, cache.size()); + } + + // Check that Clear() works properly. + cache.Put(kItem1Key, item1); + cache.Put(kItem2Key, item2); + EXPECT_EQ(2U, cache.size()); + cache.Clear(); + EXPECT_EQ(0U, cache.size()); +} + +TEST(MRUCacheTest, GetVsPeek) { + typedef MRUCache<int, CachedItem> Cache; + Cache cache(Cache::NO_AUTO_EVICT); + + static const int kItem1Key = 1; + CachedItem item1(10); + cache.Put(kItem1Key, item1); + + static const int kItem2Key = 2; + CachedItem item2(20); + cache.Put(kItem2Key, item2); + + // This should do nothing since the size is bigger than the number of items. + cache.ShrinkToSize(100); + + // Check that item1 starts out as oldest + { + Cache::reverse_iterator iter = cache.rbegin(); + ASSERT_TRUE(iter != cache.rend()); + EXPECT_EQ(kItem1Key, iter->first); + EXPECT_EQ(item1.value, iter->second.value); + } + + // Check that Peek doesn't change ordering + { + Cache::iterator peekiter = cache.Peek(kItem1Key); + ASSERT_TRUE(peekiter != cache.end()); + + Cache::reverse_iterator iter = cache.rbegin(); + ASSERT_TRUE(iter != cache.rend()); + EXPECT_EQ(kItem1Key, iter->first); + EXPECT_EQ(item1.value, iter->second.value); + } +} + +TEST(MRUCacheTest, KeyReplacement) { + typedef MRUCache<int, CachedItem> Cache; + Cache cache(Cache::NO_AUTO_EVICT); + + static const int kItem1Key = 1; + CachedItem item1(10); + cache.Put(kItem1Key, item1); + + static const int kItem2Key = 2; + CachedItem item2(20); + cache.Put(kItem2Key, item2); + + static const int kItem3Key = 3; + CachedItem item3(30); + cache.Put(kItem3Key, item3); + + static const int kItem4Key = 4; + CachedItem item4(40); + cache.Put(kItem4Key, item4); + + CachedItem item5(50); + cache.Put(kItem3Key, item5); + + EXPECT_EQ(4U, cache.size()); + for (int i = 0; i < 3; ++i) { + Cache::reverse_iterator iter = cache.rbegin(); + ASSERT_TRUE(iter != cache.rend()); + } + + // Make it so only the most important element is there. + cache.ShrinkToSize(1); + + Cache::iterator iter = cache.begin(); + EXPECT_EQ(kItem3Key, iter->first); + EXPECT_EQ(item5.value, iter->second.value); +} + +// Make sure that the owning version release its pointers properly. +TEST(MRUCacheTest, Owning) { + typedef OwningMRUCache<int, CachedItem*> Cache; + Cache cache(Cache::NO_AUTO_EVICT); + + int initial_count = cached_item_live_count; + + // First insert and item and then overwrite it. + static const int kItem1Key = 1; + cache.Put(kItem1Key, new CachedItem(20)); + cache.Put(kItem1Key, new CachedItem(22)); + + // There should still be one item, and one extra live item. + Cache::iterator iter = cache.Get(kItem1Key); + EXPECT_EQ(1U, cache.size()); + EXPECT_TRUE(iter != cache.end()); + EXPECT_EQ(initial_count + 1, cached_item_live_count); + + // Now remove it. + cache.Erase(cache.begin()); + EXPECT_EQ(initial_count, cached_item_live_count); + + // Now try another cache that goes out of scope to make sure its pointers + // go away. + { + Cache cache2(Cache::NO_AUTO_EVICT); + cache2.Put(1, new CachedItem(20)); + cache2.Put(2, new CachedItem(20)); + } + + // There should be no objects leaked. + EXPECT_EQ(initial_count, cached_item_live_count); + + // Check that Clear() also frees things correctly. + { + Cache cache2(Cache::NO_AUTO_EVICT); + cache2.Put(1, new CachedItem(20)); + cache2.Put(2, new CachedItem(20)); + EXPECT_EQ(initial_count + 2, cached_item_live_count); + cache2.Clear(); + EXPECT_EQ(initial_count, cached_item_live_count); + } +} + +TEST(MRUCacheTest, AutoEvict) { + typedef OwningMRUCache<int, CachedItem*> Cache; + static const Cache::size_type kMaxSize = 3; + + int initial_count = cached_item_live_count; + + { + Cache cache(kMaxSize); + + static const int kItem1Key = 1, kItem2Key = 2, kItem3Key = 3, kItem4Key = 4; + cache.Put(kItem1Key, new CachedItem(20)); + cache.Put(kItem2Key, new CachedItem(21)); + cache.Put(kItem3Key, new CachedItem(22)); + cache.Put(kItem4Key, new CachedItem(23)); + + // The cache should only have kMaxSize items in it even though we inserted + // more. + EXPECT_EQ(kMaxSize, cache.size()); + } + + // There should be no objects leaked. + EXPECT_EQ(initial_count, cached_item_live_count); +} diff --git a/content/common/unix_domain_socket_posix.cc b/content/common/unix_domain_socket_posix.cc new file mode 100644 index 0000000..17e8b25 --- /dev/null +++ b/content/common/unix_domain_socket_posix.cc @@ -0,0 +1,146 @@ +// Copyright (c) 2010 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. + +#include "content/common/unix_domain_socket_posix.h" + +#include <errno.h> +#include <unistd.h> +#include <sys/uio.h> +#include <sys/socket.h> + +#include "base/eintr_wrapper.h" +#include "base/logging.h" +#include "base/pickle.h" + +// static +bool UnixDomainSocket::SendMsg(int fd, + const void* buf, + size_t length, + const std::vector<int>& fds) { + struct msghdr msg; + memset(&msg, 0, sizeof(msg)); + struct iovec iov = {const_cast<void*>(buf), length}; + msg.msg_iov = &iov; + msg.msg_iovlen = 1; + + char* control_buffer = NULL; + if (fds.size()) { + const unsigned control_len = CMSG_SPACE(sizeof(int) * fds.size()); + control_buffer = new char[control_len]; + + struct cmsghdr *cmsg; + msg.msg_control = control_buffer; + msg.msg_controllen = control_len; + cmsg = CMSG_FIRSTHDR(&msg); + cmsg->cmsg_level = SOL_SOCKET; + cmsg->cmsg_type = SCM_RIGHTS; + cmsg->cmsg_len = CMSG_LEN(sizeof(int) * fds.size()); + memcpy(CMSG_DATA(cmsg), &fds[0], sizeof(int) * fds.size()); + msg.msg_controllen = cmsg->cmsg_len; + } + + const ssize_t r = HANDLE_EINTR(sendmsg(fd, &msg, 0)); + const bool ret = static_cast<ssize_t>(length) == r; + delete[] control_buffer; + return ret; +} + +// static +ssize_t UnixDomainSocket::RecvMsg(int fd, + void* buf, + size_t length, + std::vector<int>* fds) { + static const unsigned kMaxDescriptors = 16; + + fds->clear(); + + struct msghdr msg; + memset(&msg, 0, sizeof(msg)); + struct iovec iov = {buf, length}; + msg.msg_iov = &iov; + msg.msg_iovlen = 1; + + char control_buffer[CMSG_SPACE(sizeof(int) * kMaxDescriptors)]; + msg.msg_control = control_buffer; + msg.msg_controllen = sizeof(control_buffer); + + const ssize_t r = HANDLE_EINTR(recvmsg(fd, &msg, 0)); + if (r == -1) + return -1; + + int* wire_fds = NULL; + unsigned wire_fds_len = 0; + + if (msg.msg_controllen > 0) { + struct cmsghdr* cmsg; + for (cmsg = CMSG_FIRSTHDR(&msg); cmsg; cmsg = CMSG_NXTHDR(&msg, cmsg)) { + if (cmsg->cmsg_level == SOL_SOCKET && + cmsg->cmsg_type == SCM_RIGHTS) { + const unsigned payload_len = cmsg->cmsg_len - CMSG_LEN(0); + DCHECK(payload_len % sizeof(int) == 0); + wire_fds = reinterpret_cast<int*>(CMSG_DATA(cmsg)); + wire_fds_len = payload_len / sizeof(int); + break; + } + } + } + + if (msg.msg_flags & MSG_TRUNC || msg.msg_flags & MSG_CTRUNC) { + for (unsigned i = 0; i < wire_fds_len; ++i) + close(wire_fds[i]); + errno = EMSGSIZE; + return -1; + } + + fds->resize(wire_fds_len); + memcpy(&(*fds)[0], wire_fds, sizeof(int) * wire_fds_len); + + return r; +} + +// static +ssize_t UnixDomainSocket::SendRecvMsg(int fd, + uint8_t* reply, + unsigned max_reply_len, + int* result_fd, + const Pickle& request) { + int fds[2]; + + // This socketpair is only used for the IPC and is cleaned up before + // returning. + if (socketpair(AF_UNIX, SOCK_DGRAM, 0, fds) == -1) + return false; + + std::vector<int> fd_vector; + fd_vector.push_back(fds[1]); + if (!SendMsg(fd, request.data(), request.size(), fd_vector)) { + close(fds[0]); + close(fds[1]); + return -1; + } + close(fds[1]); + + fd_vector.clear(); + const ssize_t reply_len = RecvMsg(fds[0], reply, max_reply_len, &fd_vector); + close(fds[0]); + if (reply_len == -1) + return -1; + + if ((!fd_vector.empty() && result_fd == NULL) || fd_vector.size() > 1) { + for (std::vector<int>::const_iterator + i = fd_vector.begin(); i != fd_vector.end(); ++i) { + close(*i); + } + + NOTREACHED(); + + return -1; + } + + if (result_fd) + *result_fd = fd_vector.empty() ? -1 : fd_vector[0]; + + return reply_len; +} + diff --git a/content/common/unix_domain_socket_posix.h b/content/common/unix_domain_socket_posix.h new file mode 100644 index 0000000..182cc45 --- /dev/null +++ b/content/common/unix_domain_socket_posix.h @@ -0,0 +1,54 @@ +// Copyright (c) 2010 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_COMMON_UNIX_DOMAIN_SOCKET_POSIX_H_ +#define CONTENT_COMMON_UNIX_DOMAIN_SOCKET_POSIX_H_ +#pragma once + +#include <stdint.h> +#include <sys/types.h> +#include <vector> + +class Pickle; + +class UnixDomainSocket { + public: + // Use sendmsg to write the given msg and include a vector of file + // descriptors. Returns true if successful. + static bool SendMsg(int fd, + const void* msg, + size_t length, + const std::vector<int>& fds); + + // Use recvmsg to read a message and an array of file descriptors. Returns + // -1 on failure. Note: will read, at most, 16 descriptors. + static ssize_t RecvMsg(int fd, + void* msg, + size_t length, + std::vector<int>* fds); + + // Perform a sendmsg/recvmsg pair. + // 1. This process creates a UNIX DGRAM socketpair. + // 2. This proces writes a request to |fd| with an SCM_RIGHTS control + // message containing on end of the fresh socket pair. + // 3. This process blocks reading from the other end of the fresh + // socketpair. + // 4. The target process receives the request, processes it and writes the + // reply to the end of the socketpair contained in the request. + // 5. This process wakes up and continues. + // + // fd: descriptor to send the request on + // reply: buffer for the reply + // reply_len: size of |reply| + // result_fd: (may be NULL) the file descriptor returned in the reply + // (if any) + // request: the bytes to send in the request + static ssize_t SendRecvMsg(int fd, + uint8_t* reply, + unsigned reply_len, + int* result_fd, + const Pickle& request); +}; + +#endif // CONTENT_COMMON_UNIX_DOMAIN_SOCKET_POSIX_H_ diff --git a/content/content_common.gypi b/content/content_common.gypi index 488c2227c..f35ba7e 100644 --- a/content/content_common.gypi +++ b/content/content_common.gypi @@ -71,12 +71,16 @@ 'common/file_system/webfilewriter_impl.h', 'common/file_system_messages.h', 'common/file_utilities_messages.h', + 'common/font_config_ipc_linux.cc', + 'common/font_config_ipc_linux.h', 'common/font_descriptor_mac.h', 'common/font_descriptor_mac.mm', 'common/font_loader_mac.h', 'common/font_loader_mac.mm', 'common/gpu_feature_flags.cc', 'common/gpu_feature_flags.h', + 'common/geoposition.cc', + 'common/geoposition.h', 'common/gpu_info.cc', 'common/gpu_info.h', 'common/gpu_messages.h', @@ -92,6 +96,7 @@ 'common/message_router.cc', 'common/message_router.h', 'common/mime_registry_messages.h', + 'common/mru_cache.h', 'common/notification_details.cc', 'common/notification_details.h', 'common/notification_observer.h', @@ -134,6 +139,8 @@ 'common/socket_stream_messages.h', 'common/speech_input_messages.h', 'common/speech_input_result.h', + 'common/unix_domain_socket_posix.cc', + 'common/unix_domain_socket_posix.h', 'common/web_database_observer_impl.cc', 'common/web_database_observer_impl.h', 'common/webblobregistry_impl.cc', diff --git a/content/content_renderer.gypi b/content/content_renderer.gypi index cfed384..ee7bbf1 100644 --- a/content/content_renderer.gypi +++ b/content/content_renderer.gypi @@ -18,6 +18,8 @@ '..', ], 'sources': [ + 'renderer/active_notification_tracker.cc', + 'renderer/active_notification_tracker.h', 'renderer/audio_device.cc', 'renderer/audio_device.h', 'renderer/audio_message_filter.cc', diff --git a/content/renderer/active_notification_tracker.cc b/content/renderer/active_notification_tracker.cc new file mode 100644 index 0000000..8a560ea --- /dev/null +++ b/content/renderer/active_notification_tracker.cc @@ -0,0 +1,84 @@ +// Copyright (c) 2009 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. + +#include "content/renderer/active_notification_tracker.h" + +#include "base/message_loop.h" +#include "base/scoped_ptr.h" +#include "third_party/WebKit/Source/WebKit/chromium/public/WebNotification.h" +#include "third_party/WebKit/Source/WebKit/chromium/public/WebNotificationPermissionCallback.h" + +using WebKit::WebNotification; +using WebKit::WebNotificationPermissionCallback; + +ActiveNotificationTracker::ActiveNotificationTracker() {} + +ActiveNotificationTracker::~ActiveNotificationTracker() {} + +bool ActiveNotificationTracker::GetId( + const WebNotification& notification, int& id) { + ReverseTable::iterator iter = reverse_notification_table_.find(notification); + if (iter == reverse_notification_table_.end()) + return false; + id = iter->second; + return true; +} + +bool ActiveNotificationTracker::GetNotification( + int id, WebNotification* notification) { + WebNotification* lookup = notification_table_.Lookup(id); + if (!lookup) + return false; + + *notification = *lookup; + return true; +} + +int ActiveNotificationTracker::RegisterNotification( + const WebKit::WebNotification& proxy) { + WebNotification* notification = new WebNotification(proxy); + int id = notification_table_.Add(notification); + reverse_notification_table_[proxy] = id; + return id; +} + +void ActiveNotificationTracker::UnregisterNotification(int id) { + // We want to free the notification after removing it from the table. + scoped_ptr<WebNotification> notification(notification_table_.Lookup(id)); + notification_table_.Remove(id); + DCHECK(notification.get()); + if (notification.get()) + reverse_notification_table_.erase(*notification); +} + +void ActiveNotificationTracker::Clear() { + while (!reverse_notification_table_.empty()) { + ReverseTable::iterator iter = reverse_notification_table_.begin(); + UnregisterNotification((*iter).second); + } +} + +void ActiveNotificationTracker::DetachAll() { + ReverseTable::iterator iter; + for (iter = reverse_notification_table_.begin(); + iter != reverse_notification_table_.end(); + ++iter) { + WebNotification notification(iter->first); + notification.detachPresenter(); + } +} + +WebNotificationPermissionCallback* ActiveNotificationTracker::GetCallback( + int id) { + return callback_table_.Lookup(id); +} + +int ActiveNotificationTracker::RegisterPermissionRequest( + WebNotificationPermissionCallback* callback) { + return callback_table_.Add(callback); +} + +void ActiveNotificationTracker::OnPermissionRequestComplete(int id) { + callback_table_.Remove(id); +} diff --git a/content/renderer/active_notification_tracker.h b/content/renderer/active_notification_tracker.h new file mode 100644 index 0000000..7cfb5ae --- /dev/null +++ b/content/renderer/active_notification_tracker.h @@ -0,0 +1,58 @@ +// Copyright (c) 2009 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_RENDERER_ACTIVE_NOTIFICATION_TRACKER_H_ +#define CONTENT_RENDERER_ACTIVE_NOTIFICATION_TRACKER_H_ +#pragma once + +#include <map> + +#include "base/basictypes.h" +#include "base/id_map.h" +#include "base/hash_tables.h" +#include "third_party/WebKit/Source/WebKit/chromium/public/WebNotification.h" + +namespace WebKit { +class WebNotificationPermissionCallback; +} + +// This class manages the set of active Notification objects in either +// a render or worker process. This class should be accessed only on +// the main thread. +class ActiveNotificationTracker { + public: + ActiveNotificationTracker(); + ~ActiveNotificationTracker(); + + // Methods for tracking active notification objects. + int RegisterNotification(const WebKit::WebNotification& notification); + void UnregisterNotification(int id); + bool GetId(const WebKit::WebNotification& notification, int& id); + bool GetNotification(int id, WebKit::WebNotification* notification); + + // Methods for tracking active permission requests. + int RegisterPermissionRequest( + WebKit::WebNotificationPermissionCallback* callback); + void OnPermissionRequestComplete(int id); + WebKit::WebNotificationPermissionCallback* GetCallback(int id); + + // Clears out all active notifications. Useful on page navigation. + void Clear(); + + // Detaches all active notifications from their presenter. Necessary + // when the Presenter is destroyed. + void DetachAll(); + + private: + typedef std::map<WebKit::WebNotification, int> ReverseTable; + + // Tracking maps for active notifications and permission requests. + IDMap<WebKit::WebNotification> notification_table_; + ReverseTable reverse_notification_table_; + IDMap<WebKit::WebNotificationPermissionCallback> callback_table_; + + DISALLOW_COPY_AND_ASSIGN(ActiveNotificationTracker); +}; + +#endif // CONTENT_RENDERER_ACTIVE_NOTIFICATION_TRACKER_H_ diff --git a/content/renderer/active_notification_tracker_unittest.cc b/content/renderer/active_notification_tracker_unittest.cc new file mode 100644 index 0000000..18a7850 --- /dev/null +++ b/content/renderer/active_notification_tracker_unittest.cc @@ -0,0 +1,25 @@ +// Copyright (c) 2010 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. + +#include "content/renderer/active_notification_tracker.h" +#include "testing/gtest/include/gtest/gtest.h" + +TEST(ActiveNotificationTrackerTest, TestLookupAndClear) { + ActiveNotificationTracker tracker; + + WebKit::WebNotification notification1; + int id1 = tracker.RegisterNotification(notification1); + + WebKit::WebNotification notification2; + int id2 = tracker.RegisterNotification(notification2); + + WebKit::WebNotification result; + tracker.GetNotification(id1, &result); + EXPECT_TRUE(result == notification1); + + tracker.GetNotification(id2, &result); + EXPECT_TRUE(result == notification2); + + tracker.Clear(); +} diff --git a/content/renderer/notification_provider.h b/content/renderer/notification_provider.h index 32abdee..4d641a8 100644 --- a/content/renderer/notification_provider.h +++ b/content/renderer/notification_provider.h @@ -6,8 +6,8 @@ #define CONTENT_RENDERER_NOTIFICATION_PROVIDER_H_ #pragma once -#include "chrome/common/desktop_notifications/active_notification_tracker.h" #include "chrome/renderer/render_view_observer.h" +#include "content/renderer/active_notification_tracker.h" #include "third_party/WebKit/Source/WebKit/chromium/public/WebNotification.h" #include "third_party/WebKit/Source/WebKit/chromium/public/WebNotificationPresenter.h" |