Merge from Chromium at DEPS revision r198571
This commit was generated by merge_to_master.py.
Change-Id: I951118a03836157090561764dd2627f0add8118f
diff --git a/base/OWNERS b/base/OWNERS
index 80ed2f4..7e0e67f 100644
--- a/base/OWNERS
+++ b/base/OWNERS
@@ -4,6 +4,8 @@
willchan@chromium.org
jar@chromium.org
+per-file *.isolate=csharp@chromium.org
+per-file *.isolate=maruel@chromium.org
per-file bind.h=ajwong@chromium.org
per-file bind_helpers.cc=ajwong@chromium.org
per-file bind_helpers.h=ajwong@chromium.org
diff --git a/base/allocator/allocator_extension_thunks.target.darwin-arm.mk b/base/allocator/allocator_extension_thunks.target.darwin-arm.mk
new file mode 100644
index 0000000..f0d8a83
--- /dev/null
+++ b/base/allocator/allocator_extension_thunks.target.darwin-arm.mk
@@ -0,0 +1,147 @@
+# This file is generated by gyp; do not edit.
+
+include $(CLEAR_VARS)
+
+LOCAL_MODULE_CLASS := STATIC_LIBRARIES
+LOCAL_MODULE := base_allocator_allocator_extension_thunks_gyp
+LOCAL_MODULE_SUFFIX := .a
+LOCAL_MODULE_TAGS := optional
+gyp_intermediate_dir := $(call local-intermediates-dir)
+gyp_shared_intermediate_dir := $(call intermediates-dir-for,GYP,shared)
+
+# Make sure our deps are built first.
+GYP_TARGET_DEPENDENCIES :=
+
+GYP_GENERATED_OUTPUTS :=
+
+# Make sure our deps and generated files are built first.
+LOCAL_ADDITIONAL_DEPENDENCIES := $(GYP_TARGET_DEPENDENCIES) $(GYP_GENERATED_OUTPUTS)
+
+LOCAL_CPP_EXTENSION := .cc
+LOCAL_GENERATED_SOURCES :=
+
+GYP_COPIED_SOURCE_ORIGIN_DIRS :=
+
+LOCAL_SRC_FILES := \
+ base/allocator/allocator_extension_thunks.cc
+
+
+# Flags passed to both C and C++ files.
+MY_CFLAGS := \
+ -fstack-protector \
+ --param=ssp-buffer-size=4 \
+ -fno-exceptions \
+ -fno-strict-aliasing \
+ -Wno-unused-parameter \
+ -Wno-missing-field-initializers \
+ -fvisibility=hidden \
+ -pipe \
+ -fPIC \
+ -Wno-format \
+ -fno-tree-sra \
+ -fuse-ld=gold \
+ -Wno-psabi \
+ -ffunction-sections \
+ -funwind-tables \
+ -g \
+ -fstack-protector \
+ -fno-short-enums \
+ -finline-limit=64 \
+ -Wa,--noexecstack \
+ -U_FORTIFY_SOURCE \
+ -Wno-extra \
+ -Wno-ignored-qualifiers \
+ -Wno-type-limits \
+ -Wno-address \
+ -Wno-format-security \
+ -Wno-return-type \
+ -Wno-sequence-point \
+ -Os \
+ -g \
+ -fomit-frame-pointer \
+ -fdata-sections \
+ -ffunction-sections
+
+MY_CFLAGS_C :=
+
+MY_DEFS := \
+ '-D_FILE_OFFSET_BITS=64' \
+ '-DUSE_LINUX_BREAKPAD' \
+ '-DNO_TCMALLOC' \
+ '-DDISABLE_NACL' \
+ '-DCHROMIUM_BUILD' \
+ '-DUSE_LIBJPEG_TURBO=1' \
+ '-DUSE_PROPRIETARY_CODECS' \
+ '-DENABLE_GPU=1' \
+ '-DUSE_OPENSSL=1' \
+ '-DENABLE_EGLIMAGE=1' \
+ '-DENABLE_LANGUAGE_DETECTION=1' \
+ '-DANDROID' \
+ '-D__GNU_SOURCE=1' \
+ '-DUSE_STLPORT=1' \
+ '-D_STLP_USE_PTR_SPECIALIZATIONS=1' \
+ '-DCHROME_BUILD_ID=""' \
+ '-DDYNAMIC_ANNOTATIONS_ENABLED=1' \
+ '-DWTF_USE_DYNAMIC_ANNOTATIONS=1' \
+ '-D_DEBUG'
+
+LOCAL_CFLAGS := $(MY_CFLAGS_C) $(MY_CFLAGS) $(MY_DEFS)
+
+# Include paths placed before CFLAGS/CPPFLAGS
+LOCAL_C_INCLUDES := \
+ $(LOCAL_PATH) \
+ $(GYP_ABS_ANDROID_TOP_DIR)/frameworks/wilhelm/include \
+ $(GYP_ABS_ANDROID_TOP_DIR)/bionic \
+ $(GYP_ABS_ANDROID_TOP_DIR)/external/stlport/stlport
+
+LOCAL_C_INCLUDES := $(GYP_COPIED_SOURCE_ORIGIN_DIRS) $(LOCAL_C_INCLUDES)
+
+# Flags passed to only C++ (and not C) files.
+LOCAL_CPPFLAGS := \
+ -fno-rtti \
+ -fno-threadsafe-statics \
+ -fvisibility-inlines-hidden \
+ -Wno-deprecated \
+ -Wno-abi \
+ -Wno-error=c++0x-compat \
+ -Wno-non-virtual-dtor \
+ -Wno-sign-promo \
+ -Wno-non-virtual-dtor
+
+### Rules for final target.
+
+LOCAL_LDFLAGS := \
+ -Wl,-z,now \
+ -Wl,-z,relro \
+ -Wl,-z,noexecstack \
+ -fPIC \
+ -Wl,-z,relro \
+ -Wl,-z,now \
+ -fuse-ld=gold \
+ -nostdlib \
+ -Wl,--no-undefined \
+ -Wl,--exclude-libs=ALL \
+ -Wl,--icf=safe \
+ -Wl,--gc-sections \
+ -Wl,-O1 \
+ -Wl,--as-needed
+
+
+LOCAL_STATIC_LIBRARIES :=
+
+# Enable grouping to fix circular references
+LOCAL_GROUP_STATIC_LIBRARIES := true
+
+LOCAL_SHARED_LIBRARIES := \
+ libstlport \
+ libdl
+
+# Add target alias to "gyp_all_modules" target.
+.PHONY: gyp_all_modules
+gyp_all_modules: base_allocator_allocator_extension_thunks_gyp
+
+# Alias gyp target name.
+.PHONY: allocator_extension_thunks
+allocator_extension_thunks: base_allocator_allocator_extension_thunks_gyp
+
+include $(BUILD_STATIC_LIBRARY)
diff --git a/base/allocator/allocator_extension_thunks.target.darwin-x86.mk b/base/allocator/allocator_extension_thunks.target.darwin-x86.mk
new file mode 100644
index 0000000..98aa2fb
--- /dev/null
+++ b/base/allocator/allocator_extension_thunks.target.darwin-x86.mk
@@ -0,0 +1,146 @@
+# This file is generated by gyp; do not edit.
+
+include $(CLEAR_VARS)
+
+LOCAL_MODULE_CLASS := STATIC_LIBRARIES
+LOCAL_MODULE := base_allocator_allocator_extension_thunks_gyp
+LOCAL_MODULE_SUFFIX := .a
+LOCAL_MODULE_TAGS := optional
+gyp_intermediate_dir := $(call local-intermediates-dir)
+gyp_shared_intermediate_dir := $(call intermediates-dir-for,GYP,shared)
+
+# Make sure our deps are built first.
+GYP_TARGET_DEPENDENCIES :=
+
+GYP_GENERATED_OUTPUTS :=
+
+# Make sure our deps and generated files are built first.
+LOCAL_ADDITIONAL_DEPENDENCIES := $(GYP_TARGET_DEPENDENCIES) $(GYP_GENERATED_OUTPUTS)
+
+LOCAL_CPP_EXTENSION := .cc
+LOCAL_GENERATED_SOURCES :=
+
+GYP_COPIED_SOURCE_ORIGIN_DIRS :=
+
+LOCAL_SRC_FILES := \
+ base/allocator/allocator_extension_thunks.cc
+
+
+# Flags passed to both C and C++ files.
+MY_CFLAGS := \
+ --param=ssp-buffer-size=4 \
+ -fno-exceptions \
+ -fno-strict-aliasing \
+ -Wno-unused-parameter \
+ -Wno-missing-field-initializers \
+ -fvisibility=hidden \
+ -pipe \
+ -fPIC \
+ -Wno-format \
+ -m32 \
+ -mmmx \
+ -march=pentium4 \
+ -msse2 \
+ -mfpmath=sse \
+ -fuse-ld=gold \
+ -ffunction-sections \
+ -funwind-tables \
+ -g \
+ -fno-short-enums \
+ -finline-limit=64 \
+ -Wa,--noexecstack \
+ -U_FORTIFY_SOURCE \
+ -Wno-extra \
+ -Wno-ignored-qualifiers \
+ -Wno-type-limits \
+ -Wno-address \
+ -Wno-format-security \
+ -Wno-return-type \
+ -Wno-sequence-point \
+ -fno-stack-protector \
+ -Os \
+ -g \
+ -fomit-frame-pointer \
+ -fdata-sections \
+ -ffunction-sections
+
+MY_CFLAGS_C :=
+
+MY_DEFS := \
+ '-D_FILE_OFFSET_BITS=64' \
+ '-DUSE_LINUX_BREAKPAD' \
+ '-DNO_TCMALLOC' \
+ '-DDISABLE_NACL' \
+ '-DCHROMIUM_BUILD' \
+ '-DUSE_LIBJPEG_TURBO=1' \
+ '-DUSE_PROPRIETARY_CODECS' \
+ '-DENABLE_GPU=1' \
+ '-DUSE_OPENSSL=1' \
+ '-DENABLE_EGLIMAGE=1' \
+ '-DENABLE_LANGUAGE_DETECTION=1' \
+ '-DANDROID' \
+ '-D__GNU_SOURCE=1' \
+ '-DUSE_STLPORT=1' \
+ '-D_STLP_USE_PTR_SPECIALIZATIONS=1' \
+ '-DCHROME_BUILD_ID=""' \
+ '-DDYNAMIC_ANNOTATIONS_ENABLED=1' \
+ '-DWTF_USE_DYNAMIC_ANNOTATIONS=1' \
+ '-D_DEBUG'
+
+LOCAL_CFLAGS := $(MY_CFLAGS_C) $(MY_CFLAGS) $(MY_DEFS)
+
+# Include paths placed before CFLAGS/CPPFLAGS
+LOCAL_C_INCLUDES := \
+ $(LOCAL_PATH) \
+ $(GYP_ABS_ANDROID_TOP_DIR)/frameworks/wilhelm/include \
+ $(GYP_ABS_ANDROID_TOP_DIR)/bionic \
+ $(GYP_ABS_ANDROID_TOP_DIR)/external/stlport/stlport
+
+LOCAL_C_INCLUDES := $(GYP_COPIED_SOURCE_ORIGIN_DIRS) $(LOCAL_C_INCLUDES)
+
+# Flags passed to only C++ (and not C) files.
+LOCAL_CPPFLAGS := \
+ -fno-rtti \
+ -fno-threadsafe-statics \
+ -fvisibility-inlines-hidden \
+ -Wno-deprecated \
+ -Wno-error=c++0x-compat \
+ -Wno-non-virtual-dtor \
+ -Wno-sign-promo \
+ -Wno-non-virtual-dtor
+
+### Rules for final target.
+
+LOCAL_LDFLAGS := \
+ -Wl,-z,now \
+ -Wl,-z,relro \
+ -Wl,-z,noexecstack \
+ -fPIC \
+ -m32 \
+ -fuse-ld=gold \
+ -nostdlib \
+ -Wl,--no-undefined \
+ -Wl,--exclude-libs=ALL \
+ -Wl,--gc-sections \
+ -Wl,-O1 \
+ -Wl,--as-needed
+
+
+LOCAL_STATIC_LIBRARIES :=
+
+# Enable grouping to fix circular references
+LOCAL_GROUP_STATIC_LIBRARIES := true
+
+LOCAL_SHARED_LIBRARIES := \
+ libstlport \
+ libdl
+
+# Add target alias to "gyp_all_modules" target.
+.PHONY: gyp_all_modules
+gyp_all_modules: base_allocator_allocator_extension_thunks_gyp
+
+# Alias gyp target name.
+.PHONY: allocator_extension_thunks
+allocator_extension_thunks: base_allocator_allocator_extension_thunks_gyp
+
+include $(BUILD_STATIC_LIBRARY)
diff --git a/base/allocator/allocator_extension_thunks.target.linux-arm.mk b/base/allocator/allocator_extension_thunks.target.linux-arm.mk
index 4ec26a1..f0d8a83 100644
--- a/base/allocator/allocator_extension_thunks.target.linux-arm.mk
+++ b/base/allocator/allocator_extension_thunks.target.linux-arm.mk
@@ -65,7 +65,6 @@
MY_CFLAGS_C :=
MY_DEFS := \
- '-DUSE_SKIA' \
'-D_FILE_OFFSET_BITS=64' \
'-DUSE_LINUX_BREAKPAD' \
'-DNO_TCMALLOC' \
@@ -73,7 +72,6 @@
'-DCHROMIUM_BUILD' \
'-DUSE_LIBJPEG_TURBO=1' \
'-DUSE_PROPRIETARY_CODECS' \
- '-DENABLE_PEPPER_THREADING' \
'-DENABLE_GPU=1' \
'-DUSE_OPENSSL=1' \
'-DENABLE_EGLIMAGE=1' \
@@ -124,9 +122,9 @@
-Wl,--no-undefined \
-Wl,--exclude-libs=ALL \
-Wl,--icf=safe \
+ -Wl,--gc-sections \
-Wl,-O1 \
- -Wl,--as-needed \
- -Wl,--gc-sections
+ -Wl,--as-needed
LOCAL_STATIC_LIBRARIES :=
diff --git a/base/allocator/allocator_extension_thunks.target.linux-x86.mk b/base/allocator/allocator_extension_thunks.target.linux-x86.mk
index af62cd0..98aa2fb 100644
--- a/base/allocator/allocator_extension_thunks.target.linux-x86.mk
+++ b/base/allocator/allocator_extension_thunks.target.linux-x86.mk
@@ -42,6 +42,7 @@
-march=pentium4 \
-msse2 \
-mfpmath=sse \
+ -fuse-ld=gold \
-ffunction-sections \
-funwind-tables \
-g \
@@ -66,7 +67,6 @@
MY_CFLAGS_C :=
MY_DEFS := \
- '-DUSE_SKIA' \
'-D_FILE_OFFSET_BITS=64' \
'-DUSE_LINUX_BREAKPAD' \
'-DNO_TCMALLOC' \
@@ -74,7 +74,6 @@
'-DCHROMIUM_BUILD' \
'-DUSE_LIBJPEG_TURBO=1' \
'-DUSE_PROPRIETARY_CODECS' \
- '-DENABLE_PEPPER_THREADING' \
'-DENABLE_GPU=1' \
'-DUSE_OPENSSL=1' \
'-DENABLE_EGLIMAGE=1' \
@@ -118,12 +117,13 @@
-Wl,-z,noexecstack \
-fPIC \
-m32 \
+ -fuse-ld=gold \
-nostdlib \
-Wl,--no-undefined \
-Wl,--exclude-libs=ALL \
+ -Wl,--gc-sections \
-Wl,-O1 \
- -Wl,--as-needed \
- -Wl,--gc-sections
+ -Wl,--as-needed
LOCAL_STATIC_LIBRARIES :=
diff --git a/base/android/activity_state_list.h b/base/android/activity_state_list.h
new file mode 100644
index 0000000..d2a84dc
--- /dev/null
+++ b/base/android/activity_state_list.h
@@ -0,0 +1,16 @@
+// Copyright (c) 2013 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 intentionally does not have header guards, it's included
+// inside a macro to generate enum.
+
+#ifndef DEFINE_ACTIVITY_STATE
+#error "DEFINE_ACTIVITY_STATE should be defined before including this file"
+#endif
+DEFINE_ACTIVITY_STATE(CREATED, 1)
+DEFINE_ACTIVITY_STATE(STARTED, 2)
+DEFINE_ACTIVITY_STATE(RESUMED, 3)
+DEFINE_ACTIVITY_STATE(PAUSED, 4)
+DEFINE_ACTIVITY_STATE(STOPPED, 5)
+DEFINE_ACTIVITY_STATE(DESTROYED, 6)
diff --git a/base/android/activity_status.cc b/base/android/activity_status.cc
new file mode 100644
index 0000000..4d0be32
--- /dev/null
+++ b/base/android/activity_status.cc
@@ -0,0 +1,66 @@
+// Copyright 2013 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/android/activity_status.h"
+
+#include <jni.h>
+
+#include "base/memory/singleton.h"
+#include "jni/ActivityStatus_jni.h"
+
+namespace base {
+namespace android {
+
+ActivityStatus::Listener::Listener(
+ const ActivityStatus::StateChangeCallback& callback)
+ : callback_(callback) {
+ ActivityStatus::GetInstance()->RegisterListener(this);
+}
+
+ActivityStatus::Listener::~Listener() {
+ ActivityStatus::GetInstance()->UnregisterListener(this);
+}
+
+void ActivityStatus::Listener::Notify(ActivityState state) {
+ callback_.Run(state);
+}
+
+// static
+ActivityStatus* ActivityStatus::GetInstance() {
+ return Singleton<ActivityStatus,
+ LeakySingletonTraits<ActivityStatus> >::get();
+}
+
+static void OnActivityStateChange(JNIEnv* env, jclass clazz, int new_state) {
+ ActivityStatus* activity_status = ActivityStatus::GetInstance();
+ ActivityState activity_state = static_cast<ActivityState>(new_state);
+ activity_status->OnActivityStateChange(activity_state);
+}
+
+bool ActivityStatus::RegisterBindings(JNIEnv* env) {
+ return RegisterNativesImpl(env);
+}
+
+ActivityStatus::ActivityStatus()
+ : observers_(new ObserverListThreadSafe<Listener>()) {
+ Java_ActivityStatus_registerThreadSafeNativeStateListener(
+ base::android::AttachCurrentThread());
+}
+
+ActivityStatus::~ActivityStatus() {}
+
+void ActivityStatus::RegisterListener(Listener* listener) {
+ observers_->AddObserver(listener);
+}
+
+void ActivityStatus::UnregisterListener(Listener* listener) {
+ observers_->RemoveObserver(listener);
+}
+
+void ActivityStatus::OnActivityStateChange(ActivityState new_state) {
+ observers_->Notify(&ActivityStatus::Listener::Notify, new_state);
+}
+
+} // namespace android
+} // namespace base
diff --git a/base/android/activity_status.h b/base/android/activity_status.h
new file mode 100644
index 0000000..7975a78
--- /dev/null
+++ b/base/android/activity_status.h
@@ -0,0 +1,98 @@
+// Copyright 2013 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 BASE_ANDROID_ACTIVITY_STATUS_H_
+#define BASE_ANDROID_ACTIVITY_STATUS_H_
+
+#include <jni.h>
+
+#include "base/android/jni_android.h"
+#include "base/base_export.h"
+#include "base/basictypes.h"
+#include "base/memory/ref_counted.h"
+#include "base/memory/singleton.h"
+#include "base/observer_list_threadsafe.h"
+
+namespace base {
+namespace android {
+
+// Define activity state values like ACTIVITY_STATE_CREATED in a
+// way that ensures they're always the same than their Java counterpart.
+enum ActivityState {
+#define DEFINE_ACTIVITY_STATE(x, y) ACTIVITY_STATE_##x = y,
+#include "base/android/activity_state_list.h"
+#undef DEFINE_ACTIVITY_STATE
+};
+
+// A native helper class to listen to state changes of the current
+// Android Activity. This mirrors org.chromium.base.ActivityStatus.
+// any thread.
+//
+// To start listening, create a new instance, passing a callback to a
+// function that takes an ActivityState parameter. To stop listening,
+// simply delete the listener object. The implementation guarantees
+// that the callback will always be called on the thread that created
+// the listener.
+//
+// Example:
+//
+// void OnActivityStateChange(ActivityState state) {
+// ...
+// }
+//
+// // Start listening.
+// ActivityStatus::Listener* my_listener =
+// new ActivityStatus::Listener(base::Bind(&OnActivityStateChange));
+//
+// ...
+//
+// // Stop listening.
+// delete my_listener
+//
+class BASE_EXPORT ActivityStatus {
+ public:
+ typedef base::Callback<void(ActivityState)> StateChangeCallback;
+
+ class Listener {
+ public:
+ explicit Listener(const StateChangeCallback& callback);
+ ~Listener();
+
+ private:
+ friend class ActivityStatus;
+
+ void Notify(ActivityState state);
+
+ StateChangeCallback callback_;
+
+ DISALLOW_COPY_AND_ASSIGN(Listener);
+ };
+
+ // NOTE: The Java ActivityStatus is a singleton too.
+ static ActivityStatus* GetInstance();
+
+ // Internal use: must be public to be called from base_jni_registrar.cc
+ static bool RegisterBindings(JNIEnv* env);
+
+ // Internal use only: must be public to be called from JNI and unit tests.
+ void OnActivityStateChange(ActivityState new_state);
+
+ private:
+ friend struct DefaultSingletonTraits<ActivityStatus>;
+
+ ActivityStatus();
+ ~ActivityStatus();
+
+ void RegisterListener(Listener* listener);
+ void UnregisterListener(Listener* listener);
+
+ scoped_refptr<ObserverListThreadSafe<Listener> > observers_;
+
+ DISALLOW_COPY_AND_ASSIGN(ActivityStatus);
+};
+
+} // namespace android
+} // namespace base
+
+#endif // BASE_ANDROID_ACTIVITY_STATUS_H_
diff --git a/base/android/activity_status_unittest.cc b/base/android/activity_status_unittest.cc
new file mode 100644
index 0000000..aa6a69f
--- /dev/null
+++ b/base/android/activity_status_unittest.cc
@@ -0,0 +1,129 @@
+// Copyright 2013 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/android/activity_status.h"
+#include "base/bind.h"
+#include "base/callback_forward.h"
+#include "base/logging.h"
+#include "base/memory/scoped_ptr.h"
+#include "base/message_loop/message_loop_proxy.h"
+#include "base/run_loop.h"
+#include "base/synchronization/waitable_event.h"
+#include "base/threading/thread.h"
+#include "testing/gtest/include/gtest/gtest.h"
+
+namespace base {
+namespace android {
+
+namespace {
+
+using base::android::ScopedJavaLocalRef;
+
+// An invalid ActivityState value.
+const ActivityState kInvalidActivityState = static_cast<ActivityState>(100);
+
+// Used to generate a callback that stores the new state at a given location.
+void StoreStateTo(ActivityState* target, ActivityState state) {
+ *target = state;
+}
+
+void RunTasksUntilIdle() {
+ RunLoop run_loop;
+ run_loop.RunUntilIdle();
+}
+
+// Shared state for the multi-threaded test.
+// This uses a thread to register for events and listen to them, while state
+// changes are forced on the main thread.
+class MultiThreadedTest {
+ public:
+ MultiThreadedTest()
+ : activity_status_(ActivityStatus::GetInstance()),
+ state_(kInvalidActivityState),
+ event_(false, false),
+ thread_("ActivityStatusTest thread"),
+ main_(),
+ listener_(NULL) {
+ }
+
+ void Run() {
+ // Start the thread and tell it to register for events.
+ thread_.Start();
+ thread_.message_loop()
+ ->PostTask(FROM_HERE,
+ base::Bind(&MultiThreadedTest::RegisterThreadForEvents,
+ base::Unretained(this)));
+
+ // Wait for its completion.
+ event_.Wait();
+
+ // Change state, then wait for the thread to modify state.
+ activity_status_->OnActivityStateChange(ACTIVITY_STATE_CREATED);
+ event_.Wait();
+ EXPECT_EQ(ACTIVITY_STATE_CREATED, state_);
+
+ // Again
+ activity_status_->OnActivityStateChange(ACTIVITY_STATE_DESTROYED);
+ event_.Wait();
+ EXPECT_EQ(ACTIVITY_STATE_DESTROYED, state_);
+ }
+
+ private:
+ void ExpectOnThread() {
+ EXPECT_EQ(thread_.message_loop(), base::MessageLoop::current());
+ }
+
+ void RegisterThreadForEvents() {
+ ExpectOnThread();
+ listener_.reset(new ActivityStatus::Listener(base::Bind(
+ &MultiThreadedTest::StoreStateAndSignal, base::Unretained(this))));
+ EXPECT_TRUE(listener_.get());
+ event_.Signal();
+ }
+
+ void StoreStateAndSignal(ActivityState state) {
+ ExpectOnThread();
+ state_ = state;
+ event_.Signal();
+ }
+
+ ActivityStatus* const activity_status_;
+ ActivityState state_;
+ base::WaitableEvent event_;
+ base::Thread thread_;
+ base::MessageLoop main_;
+ scoped_ptr<ActivityStatus::Listener> listener_;
+};
+
+} // namespace
+
+TEST(ActivityStatusTest, SingleThread) {
+ MessageLoop message_loop;
+
+ ActivityState result = kInvalidActivityState;
+
+ // Create a new listener that stores the new state into |result| on every
+ // state change.
+ ActivityStatus::Listener listener(
+ base::Bind(&StoreStateTo, base::Unretained(&result)));
+
+ EXPECT_EQ(kInvalidActivityState, result);
+
+ ActivityStatus* const activity_status = ActivityStatus::GetInstance();
+ activity_status->OnActivityStateChange(ACTIVITY_STATE_CREATED);
+ RunTasksUntilIdle();
+ EXPECT_EQ(ACTIVITY_STATE_CREATED, result);
+
+ activity_status->OnActivityStateChange(ACTIVITY_STATE_DESTROYED);
+ RunTasksUntilIdle();
+ EXPECT_EQ(ACTIVITY_STATE_DESTROYED, result);
+}
+
+TEST(ActivityStatusTest, TwoThreads) {
+ MultiThreadedTest test;
+ test.Run();
+}
+
+} // namespace android
+} // namespace base
diff --git a/base/android/base_jni_registrar.cc b/base/android/base_jni_registrar.cc
index 6aabd0d..606ab38 100644
--- a/base/android/base_jni_registrar.cc
+++ b/base/android/base_jni_registrar.cc
@@ -4,36 +4,38 @@
#include "base/android/base_jni_registrar.h"
-#include "base/basictypes.h"
+#include "base/android/activity_status.h"
#include "base/android/build_info.h"
#include "base/android/cpu_features.h"
#include "base/android/important_file_writer_android.h"
#include "base/android/jni_android.h"
#include "base/android/jni_registrar.h"
-#include "base/android/locale_utils.h"
#include "base/android/path_service_android.h"
#include "base/android/path_utils.h"
#include "base/android/thread_utils.h"
+#include "base/basictypes.h"
+#include "base/debug/trace_event.h"
#include "base/message_pump_android.h"
-#include "base/system_monitor/system_monitor_android.h"
+#include "base/power_monitor/power_monitor_android.h"
namespace base {
namespace android {
static RegistrationMethod kBaseRegisteredMethods[] = {
+ { "ActivityStatus", base::android::ActivityStatus::RegisterBindings },
{ "BuildInfo", base::android::BuildInfo::RegisterBindings },
{ "CpuFeatures", base::android::RegisterCpuFeatures },
{ "ImportantFileWriterAndroid",
base::android::RegisterImportantFileWriterAndroid },
- { "LocaleUtils", base::android::RegisterLocaleUtils },
{ "PathService", base::android::RegisterPathService },
{ "PathUtils", base::android::RegisterPathUtils },
{ "SystemMessageHandler", base::MessagePumpForUI::RegisterBindings },
- { "SystemMonitor", base::RegisterSystemMonitor },
+ { "PowerMonitor", base::RegisterPowerMonitor },
{ "ThreadUtils", base::RegisterThreadUtils },
};
bool RegisterJni(JNIEnv* env) {
+ TRACE_EVENT0("startup", "base_android::RegisterJni");
return RegisterNativeMethods(env, kBaseRegisteredMethods,
arraysize(kBaseRegisteredMethods));
}
diff --git a/base/android/java/src/org/chromium/base/ActivityState.template b/base/android/java/src/org/chromium/base/ActivityState.template
new file mode 100644
index 0000000..adf990a
--- /dev/null
+++ b/base/android/java/src/org/chromium/base/ActivityState.template
@@ -0,0 +1,14 @@
+// Copyright (c) 2013 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.
+
+package org.chromium.base;
+
+// A simple auto-generated interface used to list the various
+// states of an activity as used by both org.chromium.base.ActivityStatus
+// and base/android/activity_status.h
+interface ActivityState {
+#define DEFINE_ACTIVITY_STATE(x,y) public final int x = y;
+#include "base/android/activity_state_list.h"
+#undef DEFINE_ACTIVITY_STATE
+}
diff --git a/base/android/java/src/org/chromium/base/ActivityStatus.java b/base/android/java/src/org/chromium/base/ActivityStatus.java
index 7d0ee94..4747234 100644
--- a/base/android/java/src/org/chromium/base/ActivityStatus.java
+++ b/base/android/java/src/org/chromium/base/ActivityStatus.java
@@ -5,20 +5,25 @@
package org.chromium.base;
import android.app.Activity;
+import android.os.Handler;
import android.os.Looper;
/**
- * Provides information about the parent activity's status.
+ * Provides information about the current activity's status, and a way
+ * to register / unregister listeners for state changes.
*/
+@JNINamespace("base::android")
public class ActivityStatus {
// Constants matching activity states reported to StateListener.onStateChange
- public static final int CREATED = 1;
- public static final int STARTED = 2;
- public static final int RESUMED = 3;
- public static final int PAUSED = 4;
- public static final int STOPPED = 5;
- public static final int DESTROYED = 6;
+ // As an implementation detail, these are now defined in the auto-generated
+ // ActivityState interface, to be shared with C++.
+ public static final int CREATED = ActivityState.CREATED;
+ public static final int STARTED = ActivityState.STARTED;
+ public static final int RESUMED = ActivityState.RESUMED;
+ public static final int PAUSED = ActivityState.PAUSED;
+ public static final int STOPPED = ActivityState.STOPPED;
+ public static final int DESTROYED = ActivityState.DESTROYED;
// Current main activity, or null if none.
private static Activity sActivity;
@@ -102,4 +107,30 @@
public static void unregisterStateListener(StateListener listener) {
sStateListeners.removeObserver(listener);
}
+
+ /**
+ * Registers the single thread-safe native activity status listener.
+ * This handles the case where the caller is not on the main thread.
+ * Note that this is used by a leaky singleton object from the native
+ * side, hence lifecycle management is greatly simplified.
+ */
+ @CalledByNative
+ private static void registerThreadSafeNativeStateListener() {
+ ThreadUtils.runOnUiThread(new Runnable () {
+ @Override
+ public void run() {
+ // Register a new listener that calls nativeOnActivityStateChange.
+ sStateListeners.addObserver(new StateListener() {
+ @Override
+ public void onActivityStateChange(int newState) {
+ nativeOnActivityStateChange(newState);
+ }
+ });
+ }
+ });
+ }
+
+ // Called to notify the native side of state changes.
+ // IMPORTANT: This is always called on the main thread!
+ private static native void nativeOnActivityStateChange(int newState);
}
diff --git a/base/android/java/src/org/chromium/base/LocaleUtils.java b/base/android/java/src/org/chromium/base/LocaleUtils.java
deleted file mode 100644
index e57b45a..0000000
--- a/base/android/java/src/org/chromium/base/LocaleUtils.java
+++ /dev/null
@@ -1,48 +0,0 @@
-// Copyright (c) 2012 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.
-
-package org.chromium.base;
-
-import java.util.Locale;
-
-/**
- * This class provides the locale related methods for the native library.
- */
-public class LocaleUtils {
-
- private LocaleUtils() { /* cannot be instantiated */ }
-
- /**
- * @return the default locale, translating Android deprecated
- * language codes into the modern ones used by Chromium.
- */
- @CalledByNative
- public static String getDefaultLocale() {
- Locale locale = Locale.getDefault();
- String language = locale.getLanguage();
- String country = locale.getCountry();
-
- // Android uses deprecated lanuages codes for Hebrew, Indonesian and
- // Yiddish but Chromium uses the updated codes, so apply a mapping.
- // See http://developer.android.com/reference/java/util/Locale.html
- if ("iw".equals(language)) {
- language = "he";
- } else if ("in".equals(language)) {
- language = "id";
- } else if ("ji".equals(language)) {
- language = "yi";
- }
- return country.isEmpty() ? language : language + "-" + country;
- }
-
- @CalledByNative
- private static Locale getJavaLocale(String language, String country, String variant) {
- return new Locale(language, country, variant);
- }
-
- @CalledByNative
- private static String getDisplayNameForLocale(Locale locale, Locale displayLocale) {
- return locale.getDisplayName(displayLocale);
- }
-}
diff --git a/base/android/java/src/org/chromium/base/PathUtils.java b/base/android/java/src/org/chromium/base/PathUtils.java
index 1d9af7e..aee5c05 100644
--- a/base/android/java/src/org/chromium/base/PathUtils.java
+++ b/base/android/java/src/org/chromium/base/PathUtils.java
@@ -60,7 +60,7 @@
*/
@SuppressWarnings("unused")
@CalledByNative
- private static String getCacheDirectory(Context appContext) {
+ public static String getCacheDirectory(Context appContext) {
if (ContextTypes.getInstance().getType(appContext) == ContextTypes.CONTEXT_TYPE_NORMAL) {
return appContext.getCacheDir().getPath();
}
diff --git a/base/android/java/src/org/chromium/base/SystemMonitor.java b/base/android/java/src/org/chromium/base/PowerMonitor.java
similarity index 89%
rename from base/android/java/src/org/chromium/base/SystemMonitor.java
rename to base/android/java/src/org/chromium/base/PowerMonitor.java
index 138ae28..b7a691e 100644
--- a/base/android/java/src/org/chromium/base/SystemMonitor.java
+++ b/base/android/java/src/org/chromium/base/PowerMonitor.java
@@ -13,12 +13,15 @@
/**
- * Integrates native SystemMonitor with the java side.
+ * Integrates native PowerMonitor with the java side.
*/
@JNINamespace("base::android")
-public class SystemMonitor implements ActivityStatus.StateListener {
+public class PowerMonitor implements ActivityStatus.StateListener {
private static final long SUSPEND_DELAY_MS = 1 * 60 * 1000; // 1 minute.
- private static SystemMonitor sInstance;
+ private static class LazyHolder {
+ private static final PowerMonitor INSTANCE = new PowerMonitor();
+ }
+ private static PowerMonitor sInstance;
private boolean mIsBatteryPower;
private final Handler mHandler = new Handler(Looper.getMainLooper());
@@ -38,12 +41,12 @@
// Applications will create this once the JNI side has been fully wired up both sides. For
// tests, we just need native -> java, that is, we don't need to notify java -> native on
// creation.
- sInstance = new SystemMonitor();
+ sInstance = LazyHolder.INSTANCE;
}
public static void create(Context context) {
if (sInstance == null) {
- sInstance = new SystemMonitor();
+ sInstance = LazyHolder.INSTANCE;
ActivityStatus.registerStateListener(sInstance);
IntentFilter ifilter = new IntentFilter(Intent.ACTION_BATTERY_CHANGED);
Intent batteryStatusIntent = context.registerReceiver(null, ifilter);
@@ -51,7 +54,7 @@
}
}
- private SystemMonitor() {
+ private PowerMonitor() {
}
public static void onBatteryChargingChanged(Intent intent) {
diff --git a/base/android/java/src/org/chromium/base/PowerStatusReceiver.java b/base/android/java/src/org/chromium/base/PowerStatusReceiver.java
index 89594b8..f36c146 100644
--- a/base/android/java/src/org/chromium/base/PowerStatusReceiver.java
+++ b/base/android/java/src/org/chromium/base/PowerStatusReceiver.java
@@ -11,13 +11,13 @@
/**
* A BroadcastReceiver that listens to changes in power status and notifies
- * SystemMonitor.
+ * PowerMonitor.
* It's instantiated by the framework via the application intent-filter
* declared in its manifest.
*/
public class PowerStatusReceiver extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
- SystemMonitor.onBatteryChargingChanged(intent);
+ PowerMonitor.onBatteryChargingChanged(intent);
}
}
diff --git a/base/android/jni_android.cc b/base/android/jni_android.cc
index fdc2170..fc89b54 100644
--- a/base/android/jni_android.cc
+++ b/base/android/jni_android.cc
@@ -135,13 +135,9 @@
}
ScopedJavaLocalRef<jclass> GetClass(JNIEnv* env, const char* class_name) {
- return ScopedJavaLocalRef<jclass>(env, GetUnscopedClass(env, class_name));
-}
-
-jclass GetUnscopedClass(JNIEnv* env, const char* class_name) {
jclass clazz = env->FindClass(class_name);
CHECK(!ClearException(env) && clazz) << "Failed to find class " << class_name;
- return clazz;
+ return ScopedJavaLocalRef<jclass>(env, clazz);
}
bool HasClass(JNIEnv* env, const char* class_name) {
diff --git a/base/android/jni_android.h b/base/android/jni_android.h
index 16b85af..e8f68ac 100644
--- a/base/android/jni_android.h
+++ b/base/android/jni_android.h
@@ -53,11 +53,6 @@
BASE_EXPORT ScopedJavaLocalRef<jclass> GetClass(JNIEnv* env,
const char* class_name);
-// Similar to the above, but the caller is responsible to manage the jclass
-// lifetime.
-BASE_EXPORT jclass GetUnscopedClass(JNIEnv* env,
- const char* class_name) WARN_UNUSED_RESULT;
-
// Returns true iff the class |class_name| could be found.
BASE_EXPORT bool HasClass(JNIEnv* env, const char* class_name);
diff --git a/base/android/jni_generator/golden_sample_for_tests_jni.h b/base/android/jni_generator/golden_sample_for_tests_jni.h
index bba64ba..2c5f6c0 100644
--- a/base/android/jni_generator/golden_sample_for_tests_jni.h
+++ b/base/android/jni_generator/golden_sample_for_tests_jni.h
@@ -301,11 +301,11 @@
static bool RegisterNativesImpl(JNIEnv* env) {
g_InnerStructA_clazz = reinterpret_cast<jclass>(env->NewGlobalRef(
- base::android::GetUnscopedClass(env, kInnerStructAClassPath)));
+ base::android::GetClass(env, kInnerStructAClassPath).obj()));
g_SampleForTests_clazz = reinterpret_cast<jclass>(env->NewGlobalRef(
- base::android::GetUnscopedClass(env, kSampleForTestsClassPath)));
+ base::android::GetClass(env, kSampleForTestsClassPath).obj()));
g_InnerStructB_clazz = reinterpret_cast<jclass>(env->NewGlobalRef(
- base::android::GetUnscopedClass(env, kInnerStructBClassPath)));
+ base::android::GetClass(env, kInnerStructBClassPath).obj()));
static const JNINativeMethod kMethodsSampleForTests[] = {
{ "nativeInit",
"("
diff --git a/base/android/jni_generator/jni_generator.py b/base/android/jni_generator/jni_generator.py
index 6da9849..f71f553 100755
--- a/base/android/jni_generator/jni_generator.py
+++ b/base/android/jni_generator/jni_generator.py
@@ -264,14 +264,14 @@
'\(\"(?P<native_class_name>.*?)\"\))?\s*'
'(@NativeCall(\(\"(?P<java_class_name>.*?)\"\)))?\s*'
'(?P<qualifiers>\w+\s\w+|\w+|\s+)\s*?native '
- '(?P<return>\S*?) '
+ '(?P<return_type>\S*?) '
'(?P<name>\w+?)\((?P<params>.*?)\);')
for match in re.finditer(re_native, contents):
native = NativeMethod(
static='static' in match.group('qualifiers'),
java_class_name=match.group('java_class_name'),
native_class_name=match.group('native_class_name'),
- return_type=match.group('return'),
+ return_type=match.group('return_type'),
name=match.group('name').replace('native', ''),
params=JniParams.Parse(match.group('params')))
natives += [native]
@@ -381,7 +381,7 @@
RE_CALLED_BY_NATIVE = re.compile(
'@CalledByNative(?P<Unchecked>(Unchecked)*?)(?:\("(?P<annotation>.*)"\))?'
'\s+(?P<prefix>[\w ]*?)'
- '\s*(?P<return_type>[\w\.]+(\[\])*?)'
+ '\s*(?P<return_type>\S+?)'
'\s+(?P<name>\w+)'
'\s*\((?P<params>[^\)]*)\)')
@@ -878,7 +878,7 @@
"""Returns the imlementation of FindClass for all known classes."""
template = Template("""\
g_${JAVA_CLASS}_clazz = reinterpret_cast<jclass>(env->NewGlobalRef(
- base::android::GetUnscopedClass(env, k${JAVA_CLASS}ClassPath)));""")
+ base::android::GetClass(env, k${JAVA_CLASS}ClassPath).obj()));""")
ret = []
for clazz in self.GetUniqueClasses(self.called_by_natives):
values = {'JAVA_CLASS': clazz}
diff --git a/base/android/jni_generator/jni_generator_tests.py b/base/android/jni_generator/jni_generator_tests.py
index b804474..f6dd3c9 100755
--- a/base/android/jni_generator/jni_generator_tests.py
+++ b/base/android/jni_generator/jni_generator_tests.py
@@ -325,7 +325,7 @@
static bool RegisterNativesImpl(JNIEnv* env) {
g_TestJni_clazz = reinterpret_cast<jclass>(env->NewGlobalRef(
- base::android::GetUnscopedClass(env, kTestJniClassPath)));
+ base::android::GetClass(env, kTestJniClassPath).obj()));
static const JNINativeMethod kMethodsTestJni[] = {
{ "nativeInit",
"("
@@ -483,7 +483,7 @@
static bool RegisterNativesImpl(JNIEnv* env) {
g_TestJni_clazz = reinterpret_cast<jclass>(env->NewGlobalRef(
- base::android::GetUnscopedClass(env, kTestJniClassPath)));
+ base::android::GetClass(env, kTestJniClassPath).obj()));
static const JNINativeMethod kMethodsMyInnerClass[] = {
{ "nativeInit",
"("
@@ -574,7 +574,7 @@
static bool RegisterNativesImpl(JNIEnv* env) {
g_TestJni_clazz = reinterpret_cast<jclass>(env->NewGlobalRef(
- base::android::GetUnscopedClass(env, kTestJniClassPath)));
+ base::android::GetClass(env, kTestJniClassPath).obj()));
static const JNINativeMethod kMethodsMyOtherInnerClass[] = {
{ "nativeInit",
"("
@@ -679,7 +679,7 @@
static bool RegisterNativesImpl(JNIEnv* env) {
g_TestJni_clazz = reinterpret_cast<jclass>(env->NewGlobalRef(
- base::android::GetUnscopedClass(env, kTestJniClassPath)));
+ base::android::GetClass(env, kTestJniClassPath).obj()));
static const JNINativeMethod kMethodsMyOtherInnerClass[] = {
{ "nativeInit",
"("
@@ -723,6 +723,7 @@
import android.graphics.Bitmap;
import android.view.View;
import java.io.InputStream;
+ import java.util.List;
class InnerClass {}
@@ -799,6 +800,9 @@
@CalledByNative
public Bitmap.CompressFormat getCompressFormat();
+
+ @CalledByNative
+ public List<Bitmap.CompressFormat> getCompressFormatList();
"""
jni_generator.JniParams.SetFullyQualifiedClass('org/chromium/Foo')
jni_generator.JniParams.ExtractImportsAndInnerClasses(test_data)
@@ -1006,6 +1010,17 @@
env_call=('Void', ''),
unchecked=False,
),
+ CalledByNative(
+ return_type='List<Bitmap.CompressFormat>',
+ system_class=False,
+ static=False,
+ name='getCompressFormatList',
+ method_id_var_name='getCompressFormatList',
+ java_class_name='',
+ params=[],
+ env_call=('Void', ''),
+ unchecked=False,
+ ),
]
self.assertListEquals(golden_called_by_natives, called_by_natives)
h = jni_generator.InlHeaderFileGenerator('', 'org/chromium/TestJni',
@@ -1054,7 +1069,7 @@
/* Must call RegisterNativesImpl() */
DCHECK(g_TestJni_clazz);
jmethodID method_id =
- base::android::MethodID::LazyGet<
+ base::android::MethodID::LazyGet<
base::android::MethodID::TYPE_INSTANCE>(
env, g_TestJni_clazz,
"showConfirmInfoBar",
@@ -1085,7 +1100,7 @@
/* Must call RegisterNativesImpl() */
DCHECK(g_TestJni_clazz);
jmethodID method_id =
- base::android::MethodID::LazyGet<
+ base::android::MethodID::LazyGet<
base::android::MethodID::TYPE_INSTANCE>(
env, g_TestJni_clazz,
"showAutoLoginInfoBar",
@@ -1111,7 +1126,7 @@
/* Must call RegisterNativesImpl() */
DCHECK(g_InfoBar_clazz);
jmethodID method_id =
- base::android::MethodID::LazyGet<
+ base::android::MethodID::LazyGet<
base::android::MethodID::TYPE_INSTANCE>(
env, g_InfoBar_clazz,
"dismiss",
@@ -1135,7 +1150,7 @@
/* Must call RegisterNativesImpl() */
DCHECK(g_TestJni_clazz);
jmethodID method_id =
- base::android::MethodID::LazyGet<
+ base::android::MethodID::LazyGet<
base::android::MethodID::TYPE_STATIC>(
env, g_TestJni_clazz,
"shouldShowAutoLogin",
@@ -1162,7 +1177,7 @@
/* Must call RegisterNativesImpl() */
DCHECK(g_TestJni_clazz);
jmethodID method_id =
- base::android::MethodID::LazyGet<
+ base::android::MethodID::LazyGet<
base::android::MethodID::TYPE_STATIC>(
env, g_TestJni_clazz,
"openUrl",
@@ -1190,7 +1205,7 @@
/* Must call RegisterNativesImpl() */
DCHECK(g_TestJni_clazz);
jmethodID method_id =
- base::android::MethodID::LazyGet<
+ base::android::MethodID::LazyGet<
base::android::MethodID::TYPE_INSTANCE>(
env, g_TestJni_clazz,
"activateHardwareAcceleration",
@@ -1216,7 +1231,7 @@
/* Must call RegisterNativesImpl() */
DCHECK(g_TestJni_clazz);
jmethodID method_id =
- base::android::MethodID::LazyGet<
+ base::android::MethodID::LazyGet<
base::android::MethodID::TYPE_INSTANCE>(
env, g_TestJni_clazz,
"uncheckedCall",
@@ -1418,7 +1433,7 @@
static base::subtle::AtomicWord g_TestJni_returnArrayOfByteArray = 0;
static ScopedJavaLocalRef<jobjectArray>
-Java_TestJni_returnArrayOfByteArray(JNIEnv* env, jobject obj) {
+ Java_TestJni_returnArrayOfByteArray(JNIEnv* env, jobject obj) {
/* Must call RegisterNativesImpl() */
DCHECK(g_TestJni_clazz);
jmethodID method_id =
@@ -1462,14 +1477,37 @@
return ScopedJavaLocalRef<jobject>(env, ret);
}
+static base::subtle::AtomicWord g_TestJni_getCompressFormatList = 0;
+static ScopedJavaLocalRef<jobject> Java_TestJni_getCompressFormatList(JNIEnv*
+ env, jobject obj) {
+ /* Must call RegisterNativesImpl() */
+ DCHECK(g_TestJni_clazz);
+ jmethodID method_id =
+ base::android::MethodID::LazyGet<
+ base::android::MethodID::TYPE_INSTANCE>(
+ env, g_TestJni_clazz,
+ "getCompressFormatList",
+
+"("
+")"
+"Ljava/util/List;",
+ &g_TestJni_getCompressFormatList);
+
+ jobject ret =
+ env->CallObjectMethod(obj,
+ method_id);
+ base::android::CheckException(env);
+ return ScopedJavaLocalRef<jobject>(env, ret);
+}
+
// Step 3: RegisterNatives.
static bool RegisterNativesImpl(JNIEnv* env) {
g_TestJni_clazz = reinterpret_cast<jclass>(env->NewGlobalRef(
- base::android::GetUnscopedClass(env, kTestJniClassPath)));
+ base::android::GetClass(env, kTestJniClassPath).obj()));
g_InfoBar_clazz = reinterpret_cast<jclass>(env->NewGlobalRef(
- base::android::GetUnscopedClass(env, kInfoBarClassPath)));
+ base::android::GetClass(env, kInfoBarClassPath).obj()));
return true;
}
@@ -1832,7 +1870,7 @@
static bool RegisterNativesImpl(JNIEnv* env) {
g_InputStream_clazz = reinterpret_cast<jclass>(env->NewGlobalRef(
- base::android::GetUnscopedClass(env, kInputStreamClassPath)));
+ base::android::GetClass(env, kInputStreamClassPath).obj()));
return true;
}
} // namespace JNI_InputStream
diff --git a/base/android/jni_registrar.cc b/base/android/jni_registrar.cc
index fb39946..0f32089 100644
--- a/base/android/jni_registrar.cc
+++ b/base/android/jni_registrar.cc
@@ -4,6 +4,7 @@
#include "base/android/jni_registrar.h"
+#include "base/debug/trace_event.h"
#include "base/logging.h"
#include "base/android/jni_android.h"
@@ -13,6 +14,7 @@
bool RegisterNativeMethods(JNIEnv* env,
const RegistrationMethod* method,
size_t count) {
+ TRACE_EVENT0("startup", "base_android::RegisterNativeMethods")
const RegistrationMethod* end = method + count;
while (method != end) {
if (!method->func(env)) {
diff --git a/base/android/jni_string.h b/base/android/jni_string.h
index 222b78d..89af5b0 100644
--- a/base/android/jni_string.h
+++ b/base/android/jni_string.h
@@ -10,7 +10,7 @@
#include "base/android/scoped_java_ref.h"
#include "base/base_export.h"
-#include "base/string_piece.h"
+#include "base/strings/string_piece.h"
namespace base {
namespace android {
diff --git a/base/android/locale_utils.cc b/base/android/locale_utils.cc
deleted file mode 100644
index f9c030d..0000000
--- a/base/android/locale_utils.cc
+++ /dev/null
@@ -1,83 +0,0 @@
-// Copyright (c) 2012 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/android/locale_utils.h"
-
-#include "base/android/jni_android.h"
-#include "base/android/jni_string.h"
-#include "base/android/scoped_java_ref.h"
-#include "base/logging.h"
-#include "base/string_util.h"
-#include "jni/LocaleUtils_jni.h"
-#include "third_party/icu/public/common/unicode/uloc.h"
-
-namespace base {
-namespace android {
-
-std::string GetDefaultLocale() {
- JNIEnv* env = AttachCurrentThread();
- ScopedJavaLocalRef<jstring> locale = Java_LocaleUtils_getDefaultLocale(env);
- return ConvertJavaStringToUTF8(locale);
-}
-
-namespace {
-
-// Common prototype of ICU uloc_getXXX() functions.
-typedef int32_t (*UlocGetComponentFunc)(const char*, char*, int32_t,
- UErrorCode*);
-
-std::string GetLocaleComponent(const std::string& locale,
- UlocGetComponentFunc uloc_func,
- int32_t max_capacity) {
- std::string result;
- UErrorCode error = U_ZERO_ERROR;
- int32_t actual_length = uloc_func(locale.c_str(),
- WriteInto(&result, max_capacity),
- max_capacity,
- &error);
- DCHECK(U_SUCCESS(error));
- DCHECK(actual_length < max_capacity);
- result.resize(actual_length);
- return result;
-}
-
-ScopedJavaLocalRef<jobject> NewJavaLocale(
- JNIEnv* env,
- const std::string& locale) {
- // TODO(wangxianzhu): Use new Locale API once Android supports scripts.
- std::string language = GetLocaleComponent(
- locale, uloc_getLanguage, ULOC_LANG_CAPACITY);
- std::string country = GetLocaleComponent(
- locale, uloc_getCountry, ULOC_COUNTRY_CAPACITY);
- std::string variant = GetLocaleComponent(
- locale, uloc_getVariant, ULOC_FULLNAME_CAPACITY);
- return Java_LocaleUtils_getJavaLocale(env,
- ConvertUTF8ToJavaString(env, language).obj(),
- ConvertUTF8ToJavaString(env, country).obj(),
- ConvertUTF8ToJavaString(env, variant).obj());
-}
-
-} // namespace
-
-string16 GetDisplayNameForLocale(const std::string& locale,
- const std::string& display_locale) {
- JNIEnv* env = AttachCurrentThread();
- ScopedJavaLocalRef<jobject> java_locale =
- NewJavaLocale(env, locale);
- ScopedJavaLocalRef<jobject> java_display_locale =
- NewJavaLocale(env, display_locale);
-
- ScopedJavaLocalRef<jstring> java_result(
- Java_LocaleUtils_getDisplayNameForLocale(env,
- java_locale.obj(),
- java_display_locale.obj()));
- return ConvertJavaStringToUTF16(java_result);
-}
-
-bool RegisterLocaleUtils(JNIEnv* env) {
- return RegisterNativesImpl(env);
-}
-
-} // namespace android
-} // namespace base
diff --git a/base/android/locale_utils.h b/base/android/locale_utils.h
deleted file mode 100644
index cef39f4..0000000
--- a/base/android/locale_utils.h
+++ /dev/null
@@ -1,29 +0,0 @@
-// Copyright (c) 2012 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 BASE_ANDROID_LOCALE_UTILS_H_
-#define BASE_ANDROID_LOCALE_UTILS_H_
-
-#include <jni.h>
-
-#include <string>
-
-#include "base/base_export.h"
-#include "base/string16.h"
-
-namespace base {
-namespace android {
-
-// Return the current default locale of the device.
-BASE_EXPORT std::string GetDefaultLocale();
-
-BASE_EXPORT string16 GetDisplayNameForLocale(const std::string& locale,
- const std::string& display_locale);
-
-bool RegisterLocaleUtils(JNIEnv* env);
-
-} // namespace android
-} // namespace base
-
-#endif // BASE_ANDROID_LOCALE_UTILS_H_
diff --git a/base/base.gyp b/base/base.gyp
index f18f975..8b3ebac 100644
--- a/base/base.gyp
+++ b/base/base.gyp
@@ -134,12 +134,16 @@
['include', '^atomicops_internals_x86_gcc\\.cc$'],
],
}],
+ ['target_arch == "mipsel"', {
+ 'sources/': [
+ ['include', '^atomicops_internals_mips_gcc\\.cc$'],
+ ],
+ }],
],
'dependencies': [
'base_jni_headers',
'symbolize',
'../third_party/ashmem/ashmem.gyp:ashmem',
- '../third_party/icu/icu.gyp:icuuc',
],
'include_dirs': [
'<(SHARED_INTERMEDIATE_DIR)/base',
@@ -322,6 +326,8 @@
'i18n/number_formatting.h',
'i18n/rtl.cc',
'i18n/rtl.h',
+ 'i18n/string_compare.cc',
+ 'i18n/string_compare.h',
'i18n/string_search.cc',
'i18n/string_search.h',
'i18n/time_formatting.cc',
@@ -435,6 +441,7 @@
'type': '<(gtest_target_type)',
'sources': [
# Tests.
+ 'android/activity_status_unittest.cc',
'android/jni_android_unittest.cc',
'android/jni_array_unittest.cc',
'android/jni_string_unittest.cc',
@@ -463,6 +470,7 @@
'debug/trace_event_unittest.cc',
'debug/trace_event_unittest.h',
'debug/trace_event_win_unittest.cc',
+ 'deferred_sequenced_task_runner_unittest.cc',
'environment_unittest.cc',
'file_util_unittest.cc',
'file_version_info_unittest.cc',
@@ -509,11 +517,12 @@
'memory/scoped_ptr_unittest.cc',
'memory/scoped_ptr_unittest.nc',
'memory/scoped_vector_unittest.cc',
+ 'memory/shared_memory_unittest.cc',
'memory/singleton_unittest.cc',
'memory/weak_ptr_unittest.cc',
'memory/weak_ptr_unittest.nc',
- 'message_loop_proxy_impl_unittest.cc',
- 'message_loop_proxy_unittest.cc',
+ 'message_loop/message_loop_proxy_impl_unittest.cc',
+ 'message_loop/message_loop_proxy_unittest.cc',
'message_loop_unittest.cc',
'message_pump_glib_unittest.cc',
'message_pump_io_ios_unittest.cc',
@@ -534,6 +543,7 @@
'platform_file_unittest.cc',
'posix/file_descriptor_shuffle_unittest.cc',
'posix/unix_domain_socket_linux_unittest.cc',
+ 'power_monitor/power_monitor_unittest.cc',
'pr_time_unittest.cc',
'prefs/default_pref_store_unittest.cc',
'prefs/json_pref_store_unittest.cc',
@@ -553,25 +563,26 @@
'rand_util_unittest.cc',
'safe_numerics_unittest.cc',
'safe_numerics_unittest.nc',
+ 'scoped_clear_errno_unittest.cc',
'scoped_native_library_unittest.cc',
'scoped_observer.h',
'security_unittest.cc',
'sequence_checker_unittest.cc',
'sequence_checker_impl_unittest.cc',
'sha1_unittest.cc',
- 'shared_memory_unittest.cc',
'stl_util_unittest.cc',
'string16_unittest.cc',
- 'string_piece_unittest.cc',
'string_util_unittest.cc',
'stringprintf_unittest.cc',
'strings/string_number_conversions_unittest.cc',
+ 'strings/string_piece_unittest.cc',
'strings/string_split_unittest.cc',
'strings/string_tokenizer_unittest.cc',
'strings/stringize_macros_unittest.cc',
'strings/sys_string_conversions_mac_unittest.mm',
'strings/sys_string_conversions_unittest.cc',
'strings/utf_offset_string_conversions_unittest.cc',
+ 'strings/utf_string_conversions_unittest.cc',
'synchronization/cancellation_flag_unittest.cc',
'synchronization/condition_variable_unittest.cc',
'synchronization/lock_unittest.cc',
@@ -603,7 +614,6 @@
'tools_sanity_unittest.cc',
'tracked_objects_unittest.cc',
'tuple_unittest.cc',
- 'utf_string_conversions_unittest.cc',
'values_unittest.cc',
'version_unittest.cc',
'vlog_unittest.cc',
@@ -673,8 +683,6 @@
['exclude', '^metrics/stats_table_unittest\\.cc$'],
# iOS does not use message_pump_libevent.
['exclude', '^message_pump_libevent_unittest\\.cc$'],
- ['exclude', '^prefs/json_pref_store_unittest.\\cc$'],
-
],
'conditions': [
['coverage != 0', {
@@ -682,7 +690,7 @@
# These sources can't be built with coverage due to a toolchain
# bug: http://openradar.appspot.com/radar?id=1499403
'json/json_reader_unittest.cc',
- 'string_piece_unittest.cc',
+ 'strings/string_piece_unittest.cc',
# These tests crash when run with coverage turned on due to an
# issue with llvm_gcda_increment_indirect_counter:
@@ -701,8 +709,7 @@
'action_name': 'copy_test_data',
'variables': {
'test_data_files': [
- 'data/json/bom_feff.json',
- 'data/file_util_unittest',
+ 'test/data',
],
'test_data_prefix': 'base',
},
@@ -740,6 +747,11 @@
'message_pump_glib_unittest.cc',
]
}],
+ ['use_ozone == 1', {
+ 'sources!': [
+ 'message_pump_glib_unittest.cc',
+ ]
+ }],
# This is needed to trigger the dll copy step on windows.
# TODO(mark): This should not be necessary.
['OS == "win"', {
@@ -852,6 +864,7 @@
'test/simple_test_tick_clock.h',
'test/task_runner_test_template.cc',
'test/task_runner_test_template.h',
+ 'test/test_file_util.cc',
'test/test_file_util.h',
'test/test_file_util_linux.cc',
'test/test_file_util_mac.cc',
@@ -1113,14 +1126,14 @@
'target_name': 'base_jni_headers',
'type': 'none',
'sources': [
+ 'android/java/src/org/chromium/base/ActivityStatus.java',
'android/java/src/org/chromium/base/BuildInfo.java',
'android/java/src/org/chromium/base/CpuFeatures.java',
'android/java/src/org/chromium/base/ImportantFileWriterAndroid.java',
- 'android/java/src/org/chromium/base/LocaleUtils.java',
'android/java/src/org/chromium/base/PathService.java',
'android/java/src/org/chromium/base/PathUtils.java',
+ 'android/java/src/org/chromium/base/PowerMonitor.java',
'android/java/src/org/chromium/base/SystemMessageHandler.java',
- 'android/java/src/org/chromium/base/SystemMonitor.java',
'android/java/src/org/chromium/base/ThreadUtils.java',
],
'variables': {
@@ -1134,6 +1147,9 @@
'variables': {
'java_in_dir': '../base/android/java',
},
+ 'dependencies': [
+ 'base_java_activity_state',
+ ],
'includes': [ '../build/java.gypi' ],
'conditions': [
['android_webview_build==0', {
@@ -1144,6 +1160,22 @@
],
},
{
+ 'target_name': 'base_java_activity_state',
+ 'type': 'none',
+ # This target is used to auto-generate ActivityState.java
+ # from a template file. The source file contains a list of
+ # Java constant declarations matching the ones in
+ # android/activity_state_list.h.
+ 'sources': [
+ 'android/java/src/org/chromium/base/ActivityState.template',
+ ],
+ 'variables': {
+ 'package_name': 'org/chromium/base',
+ 'template_deps': ['android/activity_state_list.h'],
+ },
+ 'includes': [ '../build/android/java_cpp_template.gypi' ],
+ },
+ {
'target_name': 'base_java_test_support',
'type': 'none',
'dependencies': [
diff --git a/base/base.gypi b/base/base.gypi
index ce7f7e8..7194f24 100644
--- a/base/base.gypi
+++ b/base/base.gypi
@@ -33,6 +33,8 @@
'allocator/allocator_extension.h',
'allocator/type_profiler_control.cc',
'allocator/type_profiler_control.h',
+ 'android/activity_status.cc',
+ 'android/activity_status.h',
'android/base_jni_registrar.cc',
'android/base_jni_registrar.h',
'android/build_info.cc',
@@ -52,8 +54,6 @@
'android/jni_registrar.h',
'android/jni_string.cc',
'android/jni_string.h',
- 'android/locale_utils.cc',
- 'android/locale_utils.h',
'android/path_service_android.cc',
'android/path_service_android.h',
'android/path_utils.cc',
@@ -138,8 +138,9 @@
'debug/trace_event_android.cc',
'debug/trace_event_impl.cc',
'debug/trace_event_impl.h',
- 'debug/trace_event_internal.h',
'debug/trace_event_win.cc',
+ 'deferred_sequenced_task_runner.cc',
+ 'deferred_sequenced_task_runner.h',
'environment.cc',
'environment.h',
'file_descriptor_posix.h',
@@ -225,6 +226,8 @@
'mac/cocoa_protocols.h',
'mac/foundation_util.h',
'mac/foundation_util.mm',
+ 'mac/launch_services_util.cc',
+ 'mac/launch_services_util.h',
'mac/launchd.cc',
'mac/launchd.h',
'mac/libdispatch_task_runner.cc',
@@ -251,8 +254,6 @@
'mac/scoped_nsexception_enabler.mm',
'mac/scoped_sending_event.h',
'mac/scoped_sending_event.mm',
- 'mach_ipc_mac.h',
- 'mach_ipc_mac.mm',
'memory/aligned_memory.cc',
'memory/aligned_memory.h',
'memory/discardable_memory.cc',
@@ -272,22 +273,29 @@
'memory/scoped_policy.h',
'memory/scoped_ptr.h',
'memory/scoped_vector.h',
+ 'memory/shared_memory.h',
+ 'memory/shared_memory_android.cc',
+ 'memory/shared_memory_nacl.cc',
+ 'memory/shared_memory_posix.cc',
+ 'memory/shared_memory_win.cc',
'memory/singleton.cc',
'memory/singleton.h',
'memory/weak_ptr.cc',
'memory/weak_ptr.h',
+ 'message_loop/message_loop_proxy.cc',
+ 'message_loop/message_loop_proxy.h',
+ 'message_loop/message_loop_proxy_impl.cc',
+ 'message_loop/message_loop_proxy_impl.h',
'message_loop.cc',
'message_loop.h',
- 'message_loop_proxy.cc',
- 'message_loop_proxy.h',
- 'message_loop_proxy_impl.cc',
- 'message_loop_proxy_impl.h',
'message_pump.cc',
'message_pump.h',
'message_pump_android.cc',
'message_pump_android.h',
'message_pump_default.cc',
'message_pump_default.h',
+ 'message_pump_ozone.cc',
+ 'message_pump_ozone.h',
'message_pump_win.cc',
'message_pump_win.h',
'metrics/sample_map.cc',
@@ -340,6 +348,15 @@
'posix/global_descriptors.h',
'posix/unix_domain_socket_linux.cc',
'posix/unix_domain_socket_linux.h',
+ 'power_monitor/power_monitor.cc',
+ 'power_monitor/power_monitor.h',
+ 'power_monitor/power_monitor_android.cc',
+ 'power_monitor/power_monitor_android.h',
+ 'power_monitor/power_monitor_ios.mm',
+ 'power_monitor/power_monitor_mac.mm',
+ 'power_monitor/power_monitor_posix.cc',
+ 'power_monitor/power_monitor_win.cc',
+ 'power_monitor/power_observer.h',
'process.h',
'process_info.h',
'process_info_mac.cc',
@@ -383,15 +400,8 @@
'sha1.h',
'sha1_portable.cc',
'sha1_win.cc',
- 'shared_memory.h',
- 'shared_memory_android.cc',
- 'shared_memory_nacl.cc',
- 'shared_memory_posix.cc',
- 'shared_memory_win.cc',
'single_thread_task_runner.h',
'stl_util.h',
- 'string_piece.cc',
- 'string_piece.h',
'string_util.cc',
'string_util.h',
'string_util_posix.h',
@@ -404,6 +414,8 @@
'strings/string_split.h',
'strings/string_number_conversions.cc',
'strings/string_number_conversions.h',
+ 'strings/string_piece.cc',
+ 'strings/string_piece.h',
'strings/string_tokenizer.h',
'strings/stringize_macros.h',
'strings/sys_string_conversions.h',
@@ -414,6 +426,8 @@
'strings/utf_offset_string_conversions.h',
'strings/utf_string_conversion_utils.cc',
'strings/utf_string_conversion_utils.h',
+ 'strings/utf_string_conversions.cc',
+ 'strings/utf_string_conversions.h',
'supports_user_data.cc',
'supports_user_data.h',
'synchronization/cancellation_flag.cc',
@@ -435,12 +449,6 @@
'synchronization/waitable_event_win.cc',
'system_monitor/system_monitor.cc',
'system_monitor/system_monitor.h',
- 'system_monitor/system_monitor_android.cc',
- 'system_monitor/system_monitor_android.h',
- 'system_monitor/system_monitor_ios.mm',
- 'system_monitor/system_monitor_mac.mm',
- 'system_monitor/system_monitor_posix.cc',
- 'system_monitor/system_monitor_win.cc',
'sys_byteorder.h',
'sys_info.cc',
'sys_info.h',
@@ -517,8 +525,6 @@
'tracking_info.cc',
'tracking_info.h',
'tuple.h',
- 'utf_string_conversions.cc',
- 'utf_string_conversions.h',
'values.cc',
'values.h',
'value_conversions.cc',
@@ -618,13 +624,13 @@
'allocator/type_profiler_control.cc',
'allocator/type_profiler_control.h',
'base_paths.cc',
- 'command_line.cc',
'cpu.cc',
'debug/stack_trace_posix.cc',
'file_util.cc',
'file_util_posix.cc',
'file_util_proxy.cc',
'files/file_path_watcher_kqueue.cc',
+ 'memory/shared_memory_posix.cc',
'native_library_posix.cc',
'path_service.cc',
'platform_file_posix.cc',
@@ -635,7 +641,6 @@
'rand_util_posix.cc',
'scoped_native_library.cc',
'files/scoped_temp_dir.cc',
- 'shared_memory_posix.cc',
'sys_info_posix.cc',
'threading/sequenced_worker_pool.cc',
'third_party/dynamic_annotations/dynamic_annotations.c',
@@ -648,7 +653,7 @@
'base_paths_posix.cc',
'files/file_path_watcher_kqueue.cc',
'files/file_path_watcher_stub.cc',
- 'system_monitor/system_monitor_posix.cc',
+ 'power_monitor/power_monitor_posix.cc',
],
'sources/': [
['include', '^files/file_path_watcher_linux\\.cc$'],
@@ -727,6 +732,12 @@
'string16.cc',
],
},],
+ ['<(use_ozone) == 1', {
+ 'sources!': [
+ 'message_pump_glib.cc',
+ 'message_pump_aurax11.cc',
+ ]
+ }],
['OS == "linux" and >(nacl_untrusted_build)==0', {
'sources!': [
'files/file_path_watcher_kqueue.cc',
diff --git a/base/base.target.darwin-arm.mk b/base/base.target.darwin-arm.mk
new file mode 100644
index 0000000..b112d4c
--- /dev/null
+++ b/base/base.target.darwin-arm.mk
@@ -0,0 +1,326 @@
+# This file is generated by gyp; do not edit.
+
+include $(CLEAR_VARS)
+
+LOCAL_MODULE_CLASS := STATIC_LIBRARIES
+LOCAL_MODULE := base_base_gyp
+LOCAL_MODULE_SUFFIX := .a
+LOCAL_MODULE_TAGS := optional
+gyp_intermediate_dir := $(call local-intermediates-dir)
+gyp_shared_intermediate_dir := $(call intermediates-dir-for,GYP,shared)
+
+# Make sure our deps are built first.
+GYP_TARGET_DEPENDENCIES := \
+ $(call intermediates-dir-for,GYP,testing_gtest_prod_gyp)/gtest_prod.stamp \
+ $(call intermediates-dir-for,GYP,base_base_jni_headers_gyp)/base_jni_headers.stamp \
+ $(call intermediates-dir-for,GYP,third_party_ashmem_ashmem_gyp)/ashmem.stamp
+
+GYP_GENERATED_OUTPUTS :=
+
+# Make sure our deps and generated files are built first.
+LOCAL_ADDITIONAL_DEPENDENCIES := $(GYP_TARGET_DEPENDENCIES) $(GYP_GENERATED_OUTPUTS)
+
+LOCAL_CPP_EXTENSION := .cc
+LOCAL_GENERATED_SOURCES :=
+
+GYP_COPIED_SOURCE_ORIGIN_DIRS :=
+
+LOCAL_SRC_FILES := \
+ base/event_recorder_stubs.cc \
+ base/linux_util.cc \
+ base/md5.cc \
+ base/message_pump_android.cc \
+ base/message_pump_libevent.cc \
+ base/metrics/field_trial.cc \
+ base/posix/file_descriptor_shuffle.cc \
+ base/sync_socket_posix.cc \
+ base/third_party/dmg_fp/g_fmt.cc \
+ base/third_party/dmg_fp/dtoa_wrapper.cc \
+ base/third_party/icu/icu_utf.cc \
+ base/third_party/nspr/prtime.cc \
+ base/allocator/allocator_extension.cc \
+ base/allocator/type_profiler_control.cc \
+ base/android/activity_status.cc \
+ base/android/base_jni_registrar.cc \
+ base/android/build_info.cc \
+ base/android/cpu_features.cc \
+ base/android/important_file_writer_android.cc \
+ base/android/scoped_java_ref.cc \
+ base/android/jni_android.cc \
+ base/android/jni_array.cc \
+ base/android/jni_helper.cc \
+ base/android/jni_registrar.cc \
+ base/android/jni_string.cc \
+ base/android/path_service_android.cc \
+ base/android/path_utils.cc \
+ base/at_exit.cc \
+ base/base_paths.cc \
+ base/base_paths_android.cc \
+ base/base64.cc \
+ base/bind_helpers.cc \
+ base/build_time.cc \
+ base/callback_internal.cc \
+ base/command_line.cc \
+ base/cpu.cc \
+ base/debug/alias.cc \
+ base/debug/crash_logging.cc \
+ base/debug/debugger.cc \
+ base/debug/debugger_posix.cc \
+ base/debug/profiler.cc \
+ base/debug/stack_trace.cc \
+ base/debug/stack_trace_android.cc \
+ base/debug/trace_event_android.cc \
+ base/debug/trace_event_impl.cc \
+ base/deferred_sequenced_task_runner.cc \
+ base/environment.cc \
+ base/file_util.cc \
+ base/file_util_android.cc \
+ base/file_util_posix.cc \
+ base/files/file_path.cc \
+ base/files/file_path_watcher.cc \
+ base/files/file_path_watcher_linux.cc \
+ base/files/file_util_proxy.cc \
+ base/files/important_file_writer.cc \
+ base/files/memory_mapped_file.cc \
+ base/files/memory_mapped_file_posix.cc \
+ base/files/scoped_temp_dir.cc \
+ base/guid.cc \
+ base/guid_posix.cc \
+ base/hash.cc \
+ base/hi_res_timer_manager_posix.cc \
+ base/json/json_file_value_serializer.cc \
+ base/json/json_parser.cc \
+ base/json/json_reader.cc \
+ base/json/json_string_value_serializer.cc \
+ base/json/json_writer.cc \
+ base/json/string_escape.cc \
+ base/lazy_instance.cc \
+ base/location.cc \
+ base/logging.cc \
+ base/memory/aligned_memory.cc \
+ base/memory/discardable_memory.cc \
+ base/memory/discardable_memory_android.cc \
+ base/memory/ref_counted.cc \
+ base/memory/ref_counted_memory.cc \
+ base/memory/shared_memory_android.cc \
+ base/memory/shared_memory_posix.cc \
+ base/memory/singleton.cc \
+ base/memory/weak_ptr.cc \
+ base/message_loop/message_loop_proxy.cc \
+ base/message_loop/message_loop_proxy_impl.cc \
+ base/message_loop.cc \
+ base/message_pump.cc \
+ base/message_pump_default.cc \
+ base/metrics/sample_map.cc \
+ base/metrics/sample_vector.cc \
+ base/metrics/bucket_ranges.cc \
+ base/metrics/histogram.cc \
+ base/metrics/histogram_base.cc \
+ base/metrics/histogram_samples.cc \
+ base/metrics/histogram_snapshot_manager.cc \
+ base/metrics/sparse_histogram.cc \
+ base/metrics/statistics_recorder.cc \
+ base/metrics/stats_counters.cc \
+ base/metrics/stats_table.cc \
+ base/native_library_posix.cc \
+ base/os_compat_android.cc \
+ base/path_service.cc \
+ base/pending_task.cc \
+ base/pickle.cc \
+ base/platform_file.cc \
+ base/platform_file_posix.cc \
+ base/posix/global_descriptors.cc \
+ base/posix/unix_domain_socket_linux.cc \
+ base/power_monitor/power_monitor.cc \
+ base/power_monitor/power_monitor_android.cc \
+ base/process_posix.cc \
+ base/process_util.cc \
+ base/process_util_linux.cc \
+ base/process_util_posix.cc \
+ base/profiler/scoped_profile.cc \
+ base/profiler/alternate_timer.cc \
+ base/profiler/tracked_time.cc \
+ base/rand_util.cc \
+ base/rand_util_posix.cc \
+ base/run_loop.cc \
+ base/safe_strerror_posix.cc \
+ base/scoped_native_library.cc \
+ base/sequence_checker_impl.cc \
+ base/sequenced_task_runner.cc \
+ base/sha1_portable.cc \
+ base/string_util.cc \
+ base/string16.cc \
+ base/stringprintf.cc \
+ base/strings/string_split.cc \
+ base/strings/string_number_conversions.cc \
+ base/strings/string_piece.cc \
+ base/strings/sys_string_conversions_posix.cc \
+ base/strings/utf_offset_string_conversions.cc \
+ base/strings/utf_string_conversion_utils.cc \
+ base/strings/utf_string_conversions.cc \
+ base/supports_user_data.cc \
+ base/synchronization/cancellation_flag.cc \
+ base/synchronization/condition_variable_posix.cc \
+ base/synchronization/lock.cc \
+ base/synchronization/lock_impl_posix.cc \
+ base/synchronization/waitable_event_posix.cc \
+ base/synchronization/waitable_event_watcher_posix.cc \
+ base/system_monitor/system_monitor.cc \
+ base/sys_info.cc \
+ base/sys_info_android.cc \
+ base/sys_info_linux.cc \
+ base/sys_info_posix.cc \
+ base/task_runner.cc \
+ base/thread_task_runner_handle.cc \
+ base/threading/non_thread_safe_impl.cc \
+ base/threading/platform_thread_posix.cc \
+ base/threading/post_task_and_reply_impl.cc \
+ base/threading/sequenced_worker_pool.cc \
+ base/threading/simple_thread.cc \
+ base/threading/thread.cc \
+ base/threading/thread_checker_impl.cc \
+ base/threading/thread_collision_warner.cc \
+ base/threading/thread_id_name_manager.cc \
+ base/threading/thread_local_posix.cc \
+ base/threading/thread_local_storage_posix.cc \
+ base/threading/thread_restrictions.cc \
+ base/threading/watchdog.cc \
+ base/threading/worker_pool.cc \
+ base/threading/worker_pool_posix.cc \
+ base/time/clock.cc \
+ base/time/default_clock.cc \
+ base/time/default_tick_clock.cc \
+ base/time/tick_clock.cc \
+ base/time.cc \
+ base/time_posix.cc \
+ base/timer.cc \
+ base/tracked_objects.cc \
+ base/tracking_info.cc \
+ base/values.cc \
+ base/value_conversions.cc \
+ base/version.cc \
+ base/vlog.cc
+
+
+# Flags passed to both C and C++ files.
+MY_CFLAGS := \
+ -fstack-protector \
+ --param=ssp-buffer-size=4 \
+ -Werror \
+ -fno-exceptions \
+ -fno-strict-aliasing \
+ -Wall \
+ -Wno-unused-parameter \
+ -Wno-missing-field-initializers \
+ -fvisibility=hidden \
+ -pipe \
+ -fPIC \
+ -fno-tree-sra \
+ -fuse-ld=gold \
+ -Wno-psabi \
+ -ffunction-sections \
+ -funwind-tables \
+ -g \
+ -fstack-protector \
+ -fno-short-enums \
+ -finline-limit=64 \
+ -Wa,--noexecstack \
+ -U_FORTIFY_SOURCE \
+ -Wno-extra \
+ -Wno-ignored-qualifiers \
+ -Wno-type-limits \
+ -Os \
+ -g \
+ -fomit-frame-pointer \
+ -fdata-sections \
+ -ffunction-sections
+
+MY_CFLAGS_C :=
+
+MY_DEFS := \
+ '-D_FILE_OFFSET_BITS=64' \
+ '-DUSE_LINUX_BREAKPAD' \
+ '-DNO_TCMALLOC' \
+ '-DDISABLE_NACL' \
+ '-DCHROMIUM_BUILD' \
+ '-DUSE_LIBJPEG_TURBO=1' \
+ '-DUSE_PROPRIETARY_CODECS' \
+ '-DENABLE_GPU=1' \
+ '-DUSE_OPENSSL=1' \
+ '-DENABLE_EGLIMAGE=1' \
+ '-DENABLE_LANGUAGE_DETECTION=1' \
+ '-DUSE_SYMBOLIZE' \
+ '-D__STDC_CONSTANT_MACROS' \
+ '-D__STDC_FORMAT_MACROS' \
+ '-DBASE_IMPLEMENTATION' \
+ '-DANDROID' \
+ '-D__GNU_SOURCE=1' \
+ '-DUSE_STLPORT=1' \
+ '-D_STLP_USE_PTR_SPECIALIZATIONS=1' \
+ '-DCHROME_BUILD_ID=""' \
+ '-DDYNAMIC_ANNOTATIONS_ENABLED=1' \
+ '-DWTF_USE_DYNAMIC_ANNOTATIONS=1' \
+ '-D_DEBUG'
+
+LOCAL_CFLAGS := $(MY_CFLAGS_C) $(MY_CFLAGS) $(MY_DEFS)
+
+# Include paths placed before CFLAGS/CPPFLAGS
+LOCAL_C_INCLUDES := \
+ $(gyp_shared_intermediate_dir)/base \
+ $(gyp_shared_intermediate_dir)/shim_headers/ashmem/target \
+ $(LOCAL_PATH) \
+ $(GYP_ABS_ANDROID_TOP_DIR)/frameworks/wilhelm/include \
+ $(GYP_ABS_ANDROID_TOP_DIR)/bionic \
+ $(GYP_ABS_ANDROID_TOP_DIR)/external/stlport/stlport
+
+LOCAL_C_INCLUDES := $(GYP_COPIED_SOURCE_ORIGIN_DIRS) $(LOCAL_C_INCLUDES)
+
+# Flags passed to only C++ (and not C) files.
+LOCAL_CPPFLAGS := \
+ -fno-rtti \
+ -fno-threadsafe-statics \
+ -fvisibility-inlines-hidden \
+ -Wsign-compare \
+ -Wno-abi \
+ -Wno-error=c++0x-compat \
+ -Wno-non-virtual-dtor \
+ -Wno-sign-promo
+
+### Rules for final target.
+
+LOCAL_LDFLAGS := \
+ -Wl,-z,now \
+ -Wl,-z,relro \
+ -Wl,-z,noexecstack \
+ -fPIC \
+ -Wl,-z,relro \
+ -Wl,-z,now \
+ -fuse-ld=gold \
+ -nostdlib \
+ -Wl,--no-undefined \
+ -Wl,--exclude-libs=ALL \
+ -Wl,--icf=safe \
+ -Wl,--gc-sections \
+ -Wl,-O1 \
+ -Wl,--as-needed
+
+
+LOCAL_STATIC_LIBRARIES := \
+ cpufeatures
+
+# Enable grouping to fix circular references
+LOCAL_GROUP_STATIC_LIBRARIES := true
+
+LOCAL_SHARED_LIBRARIES := \
+ libstlport \
+ libdl
+
+# Add target alias to "gyp_all_modules" target.
+.PHONY: gyp_all_modules
+gyp_all_modules: base_base_gyp
+
+# Alias gyp target name.
+.PHONY: base
+base: base_base_gyp
+
+include $(BUILD_STATIC_LIBRARY)
diff --git a/base/base.target.darwin-x86.mk b/base/base.target.darwin-x86.mk
new file mode 100644
index 0000000..8ea1770
--- /dev/null
+++ b/base/base.target.darwin-x86.mk
@@ -0,0 +1,326 @@
+# This file is generated by gyp; do not edit.
+
+include $(CLEAR_VARS)
+
+LOCAL_MODULE_CLASS := STATIC_LIBRARIES
+LOCAL_MODULE := base_base_gyp
+LOCAL_MODULE_SUFFIX := .a
+LOCAL_MODULE_TAGS := optional
+gyp_intermediate_dir := $(call local-intermediates-dir)
+gyp_shared_intermediate_dir := $(call intermediates-dir-for,GYP,shared)
+
+# Make sure our deps are built first.
+GYP_TARGET_DEPENDENCIES := \
+ $(call intermediates-dir-for,GYP,testing_gtest_prod_gyp)/gtest_prod.stamp \
+ $(call intermediates-dir-for,GYP,base_base_jni_headers_gyp)/base_jni_headers.stamp \
+ $(call intermediates-dir-for,GYP,third_party_ashmem_ashmem_gyp)/ashmem.stamp
+
+GYP_GENERATED_OUTPUTS :=
+
+# Make sure our deps and generated files are built first.
+LOCAL_ADDITIONAL_DEPENDENCIES := $(GYP_TARGET_DEPENDENCIES) $(GYP_GENERATED_OUTPUTS)
+
+LOCAL_CPP_EXTENSION := .cc
+LOCAL_GENERATED_SOURCES :=
+
+GYP_COPIED_SOURCE_ORIGIN_DIRS :=
+
+LOCAL_SRC_FILES := \
+ base/event_recorder_stubs.cc \
+ base/linux_util.cc \
+ base/md5.cc \
+ base/message_pump_android.cc \
+ base/message_pump_libevent.cc \
+ base/metrics/field_trial.cc \
+ base/posix/file_descriptor_shuffle.cc \
+ base/sync_socket_posix.cc \
+ base/third_party/dmg_fp/g_fmt.cc \
+ base/third_party/dmg_fp/dtoa_wrapper.cc \
+ base/third_party/icu/icu_utf.cc \
+ base/third_party/nspr/prtime.cc \
+ base/allocator/allocator_extension.cc \
+ base/allocator/type_profiler_control.cc \
+ base/android/activity_status.cc \
+ base/android/base_jni_registrar.cc \
+ base/android/build_info.cc \
+ base/android/cpu_features.cc \
+ base/android/important_file_writer_android.cc \
+ base/android/scoped_java_ref.cc \
+ base/android/jni_android.cc \
+ base/android/jni_array.cc \
+ base/android/jni_helper.cc \
+ base/android/jni_registrar.cc \
+ base/android/jni_string.cc \
+ base/android/path_service_android.cc \
+ base/android/path_utils.cc \
+ base/at_exit.cc \
+ base/atomicops_internals_x86_gcc.cc \
+ base/base_paths.cc \
+ base/base_paths_android.cc \
+ base/base64.cc \
+ base/bind_helpers.cc \
+ base/build_time.cc \
+ base/callback_internal.cc \
+ base/command_line.cc \
+ base/cpu.cc \
+ base/debug/alias.cc \
+ base/debug/crash_logging.cc \
+ base/debug/debugger.cc \
+ base/debug/debugger_posix.cc \
+ base/debug/profiler.cc \
+ base/debug/stack_trace.cc \
+ base/debug/stack_trace_android.cc \
+ base/debug/trace_event_android.cc \
+ base/debug/trace_event_impl.cc \
+ base/deferred_sequenced_task_runner.cc \
+ base/environment.cc \
+ base/file_util.cc \
+ base/file_util_android.cc \
+ base/file_util_posix.cc \
+ base/files/file_path.cc \
+ base/files/file_path_watcher.cc \
+ base/files/file_path_watcher_linux.cc \
+ base/files/file_util_proxy.cc \
+ base/files/important_file_writer.cc \
+ base/files/memory_mapped_file.cc \
+ base/files/memory_mapped_file_posix.cc \
+ base/files/scoped_temp_dir.cc \
+ base/guid.cc \
+ base/guid_posix.cc \
+ base/hash.cc \
+ base/hi_res_timer_manager_posix.cc \
+ base/json/json_file_value_serializer.cc \
+ base/json/json_parser.cc \
+ base/json/json_reader.cc \
+ base/json/json_string_value_serializer.cc \
+ base/json/json_writer.cc \
+ base/json/string_escape.cc \
+ base/lazy_instance.cc \
+ base/location.cc \
+ base/logging.cc \
+ base/memory/aligned_memory.cc \
+ base/memory/discardable_memory.cc \
+ base/memory/discardable_memory_android.cc \
+ base/memory/ref_counted.cc \
+ base/memory/ref_counted_memory.cc \
+ base/memory/shared_memory_android.cc \
+ base/memory/shared_memory_posix.cc \
+ base/memory/singleton.cc \
+ base/memory/weak_ptr.cc \
+ base/message_loop/message_loop_proxy.cc \
+ base/message_loop/message_loop_proxy_impl.cc \
+ base/message_loop.cc \
+ base/message_pump.cc \
+ base/message_pump_default.cc \
+ base/metrics/sample_map.cc \
+ base/metrics/sample_vector.cc \
+ base/metrics/bucket_ranges.cc \
+ base/metrics/histogram.cc \
+ base/metrics/histogram_base.cc \
+ base/metrics/histogram_samples.cc \
+ base/metrics/histogram_snapshot_manager.cc \
+ base/metrics/sparse_histogram.cc \
+ base/metrics/statistics_recorder.cc \
+ base/metrics/stats_counters.cc \
+ base/metrics/stats_table.cc \
+ base/native_library_posix.cc \
+ base/os_compat_android.cc \
+ base/path_service.cc \
+ base/pending_task.cc \
+ base/pickle.cc \
+ base/platform_file.cc \
+ base/platform_file_posix.cc \
+ base/posix/global_descriptors.cc \
+ base/posix/unix_domain_socket_linux.cc \
+ base/power_monitor/power_monitor.cc \
+ base/power_monitor/power_monitor_android.cc \
+ base/process_posix.cc \
+ base/process_util.cc \
+ base/process_util_linux.cc \
+ base/process_util_posix.cc \
+ base/profiler/scoped_profile.cc \
+ base/profiler/alternate_timer.cc \
+ base/profiler/tracked_time.cc \
+ base/rand_util.cc \
+ base/rand_util_posix.cc \
+ base/run_loop.cc \
+ base/safe_strerror_posix.cc \
+ base/scoped_native_library.cc \
+ base/sequence_checker_impl.cc \
+ base/sequenced_task_runner.cc \
+ base/sha1_portable.cc \
+ base/string_util.cc \
+ base/string16.cc \
+ base/stringprintf.cc \
+ base/strings/string_split.cc \
+ base/strings/string_number_conversions.cc \
+ base/strings/string_piece.cc \
+ base/strings/sys_string_conversions_posix.cc \
+ base/strings/utf_offset_string_conversions.cc \
+ base/strings/utf_string_conversion_utils.cc \
+ base/strings/utf_string_conversions.cc \
+ base/supports_user_data.cc \
+ base/synchronization/cancellation_flag.cc \
+ base/synchronization/condition_variable_posix.cc \
+ base/synchronization/lock.cc \
+ base/synchronization/lock_impl_posix.cc \
+ base/synchronization/waitable_event_posix.cc \
+ base/synchronization/waitable_event_watcher_posix.cc \
+ base/system_monitor/system_monitor.cc \
+ base/sys_info.cc \
+ base/sys_info_android.cc \
+ base/sys_info_linux.cc \
+ base/sys_info_posix.cc \
+ base/task_runner.cc \
+ base/thread_task_runner_handle.cc \
+ base/threading/non_thread_safe_impl.cc \
+ base/threading/platform_thread_posix.cc \
+ base/threading/post_task_and_reply_impl.cc \
+ base/threading/sequenced_worker_pool.cc \
+ base/threading/simple_thread.cc \
+ base/threading/thread.cc \
+ base/threading/thread_checker_impl.cc \
+ base/threading/thread_collision_warner.cc \
+ base/threading/thread_id_name_manager.cc \
+ base/threading/thread_local_posix.cc \
+ base/threading/thread_local_storage_posix.cc \
+ base/threading/thread_restrictions.cc \
+ base/threading/watchdog.cc \
+ base/threading/worker_pool.cc \
+ base/threading/worker_pool_posix.cc \
+ base/time/clock.cc \
+ base/time/default_clock.cc \
+ base/time/default_tick_clock.cc \
+ base/time/tick_clock.cc \
+ base/time.cc \
+ base/time_posix.cc \
+ base/timer.cc \
+ base/tracked_objects.cc \
+ base/tracking_info.cc \
+ base/values.cc \
+ base/value_conversions.cc \
+ base/version.cc \
+ base/vlog.cc
+
+
+# Flags passed to both C and C++ files.
+MY_CFLAGS := \
+ --param=ssp-buffer-size=4 \
+ -Werror \
+ -fno-exceptions \
+ -fno-strict-aliasing \
+ -Wall \
+ -Wno-unused-parameter \
+ -Wno-missing-field-initializers \
+ -fvisibility=hidden \
+ -pipe \
+ -fPIC \
+ -m32 \
+ -mmmx \
+ -march=pentium4 \
+ -msse2 \
+ -mfpmath=sse \
+ -fuse-ld=gold \
+ -ffunction-sections \
+ -funwind-tables \
+ -g \
+ -fno-short-enums \
+ -finline-limit=64 \
+ -Wa,--noexecstack \
+ -U_FORTIFY_SOURCE \
+ -Wno-extra \
+ -Wno-ignored-qualifiers \
+ -Wno-type-limits \
+ -fno-stack-protector \
+ -Os \
+ -g \
+ -fomit-frame-pointer \
+ -fdata-sections \
+ -ffunction-sections
+
+MY_CFLAGS_C :=
+
+MY_DEFS := \
+ '-D_FILE_OFFSET_BITS=64' \
+ '-DUSE_LINUX_BREAKPAD' \
+ '-DNO_TCMALLOC' \
+ '-DDISABLE_NACL' \
+ '-DCHROMIUM_BUILD' \
+ '-DUSE_LIBJPEG_TURBO=1' \
+ '-DUSE_PROPRIETARY_CODECS' \
+ '-DENABLE_GPU=1' \
+ '-DUSE_OPENSSL=1' \
+ '-DENABLE_EGLIMAGE=1' \
+ '-DENABLE_LANGUAGE_DETECTION=1' \
+ '-DUSE_SYMBOLIZE' \
+ '-D__STDC_CONSTANT_MACROS' \
+ '-D__STDC_FORMAT_MACROS' \
+ '-DBASE_IMPLEMENTATION' \
+ '-DANDROID' \
+ '-D__GNU_SOURCE=1' \
+ '-DUSE_STLPORT=1' \
+ '-D_STLP_USE_PTR_SPECIALIZATIONS=1' \
+ '-DCHROME_BUILD_ID=""' \
+ '-DDYNAMIC_ANNOTATIONS_ENABLED=1' \
+ '-DWTF_USE_DYNAMIC_ANNOTATIONS=1' \
+ '-D_DEBUG'
+
+LOCAL_CFLAGS := $(MY_CFLAGS_C) $(MY_CFLAGS) $(MY_DEFS)
+
+# Include paths placed before CFLAGS/CPPFLAGS
+LOCAL_C_INCLUDES := \
+ $(gyp_shared_intermediate_dir)/base \
+ $(gyp_shared_intermediate_dir)/shim_headers/ashmem/target \
+ $(LOCAL_PATH) \
+ $(GYP_ABS_ANDROID_TOP_DIR)/frameworks/wilhelm/include \
+ $(GYP_ABS_ANDROID_TOP_DIR)/bionic \
+ $(GYP_ABS_ANDROID_TOP_DIR)/external/stlport/stlport
+
+LOCAL_C_INCLUDES := $(GYP_COPIED_SOURCE_ORIGIN_DIRS) $(LOCAL_C_INCLUDES)
+
+# Flags passed to only C++ (and not C) files.
+LOCAL_CPPFLAGS := \
+ -fno-rtti \
+ -fno-threadsafe-statics \
+ -fvisibility-inlines-hidden \
+ -Wsign-compare \
+ -Wno-error=c++0x-compat \
+ -Wno-non-virtual-dtor \
+ -Wno-sign-promo
+
+### Rules for final target.
+
+LOCAL_LDFLAGS := \
+ -Wl,-z,now \
+ -Wl,-z,relro \
+ -Wl,-z,noexecstack \
+ -fPIC \
+ -m32 \
+ -fuse-ld=gold \
+ -nostdlib \
+ -Wl,--no-undefined \
+ -Wl,--exclude-libs=ALL \
+ -Wl,--gc-sections \
+ -Wl,-O1 \
+ -Wl,--as-needed
+
+
+LOCAL_STATIC_LIBRARIES := \
+ cpufeatures
+
+# Enable grouping to fix circular references
+LOCAL_GROUP_STATIC_LIBRARIES := true
+
+LOCAL_SHARED_LIBRARIES := \
+ libstlport \
+ libdl
+
+# Add target alias to "gyp_all_modules" target.
+.PHONY: gyp_all_modules
+gyp_all_modules: base_base_gyp
+
+# Alias gyp target name.
+.PHONY: base
+base: base_base_gyp
+
+include $(BUILD_STATIC_LIBRARY)
diff --git a/base/base.target.linux-arm.mk b/base/base.target.linux-arm.mk
index d5f779a..b112d4c 100644
--- a/base/base.target.linux-arm.mk
+++ b/base/base.target.linux-arm.mk
@@ -13,7 +13,7 @@
GYP_TARGET_DEPENDENCIES := \
$(call intermediates-dir-for,GYP,testing_gtest_prod_gyp)/gtest_prod.stamp \
$(call intermediates-dir-for,GYP,base_base_jni_headers_gyp)/base_jni_headers.stamp \
- $(call intermediates-dir-for,GYP,third_party_icu_icuuc_gyp)/icuuc.stamp
+ $(call intermediates-dir-for,GYP,third_party_ashmem_ashmem_gyp)/ashmem.stamp
GYP_GENERATED_OUTPUTS :=
@@ -40,6 +40,7 @@
base/third_party/nspr/prtime.cc \
base/allocator/allocator_extension.cc \
base/allocator/type_profiler_control.cc \
+ base/android/activity_status.cc \
base/android/base_jni_registrar.cc \
base/android/build_info.cc \
base/android/cpu_features.cc \
@@ -50,7 +51,6 @@
base/android/jni_helper.cc \
base/android/jni_registrar.cc \
base/android/jni_string.cc \
- base/android/locale_utils.cc \
base/android/path_service_android.cc \
base/android/path_utils.cc \
base/at_exit.cc \
@@ -71,6 +71,7 @@
base/debug/stack_trace_android.cc \
base/debug/trace_event_android.cc \
base/debug/trace_event_impl.cc \
+ base/deferred_sequenced_task_runner.cc \
base/environment.cc \
base/file_util.cc \
base/file_util_android.cc \
@@ -101,11 +102,13 @@
base/memory/discardable_memory_android.cc \
base/memory/ref_counted.cc \
base/memory/ref_counted_memory.cc \
+ base/memory/shared_memory_android.cc \
+ base/memory/shared_memory_posix.cc \
base/memory/singleton.cc \
base/memory/weak_ptr.cc \
+ base/message_loop/message_loop_proxy.cc \
+ base/message_loop/message_loop_proxy_impl.cc \
base/message_loop.cc \
- base/message_loop_proxy.cc \
- base/message_loop_proxy_impl.cc \
base/message_pump.cc \
base/message_pump_default.cc \
base/metrics/sample_map.cc \
@@ -128,6 +131,8 @@
base/platform_file_posix.cc \
base/posix/global_descriptors.cc \
base/posix/unix_domain_socket_linux.cc \
+ base/power_monitor/power_monitor.cc \
+ base/power_monitor/power_monitor_android.cc \
base/process_posix.cc \
base/process_util.cc \
base/process_util_linux.cc \
@@ -143,17 +148,16 @@
base/sequence_checker_impl.cc \
base/sequenced_task_runner.cc \
base/sha1_portable.cc \
- base/shared_memory_android.cc \
- base/shared_memory_posix.cc \
- base/string_piece.cc \
base/string_util.cc \
base/string16.cc \
base/stringprintf.cc \
base/strings/string_split.cc \
base/strings/string_number_conversions.cc \
+ base/strings/string_piece.cc \
base/strings/sys_string_conversions_posix.cc \
base/strings/utf_offset_string_conversions.cc \
base/strings/utf_string_conversion_utils.cc \
+ base/strings/utf_string_conversions.cc \
base/supports_user_data.cc \
base/synchronization/cancellation_flag.cc \
base/synchronization/condition_variable_posix.cc \
@@ -162,7 +166,6 @@
base/synchronization/waitable_event_posix.cc \
base/synchronization/waitable_event_watcher_posix.cc \
base/system_monitor/system_monitor.cc \
- base/system_monitor/system_monitor_android.cc \
base/sys_info.cc \
base/sys_info_android.cc \
base/sys_info_linux.cc \
@@ -193,7 +196,6 @@
base/timer.cc \
base/tracked_objects.cc \
base/tracking_info.cc \
- base/utf_string_conversions.cc \
base/values.cc \
base/value_conversions.cc \
base/version.cc \
@@ -236,7 +238,6 @@
MY_CFLAGS_C :=
MY_DEFS := \
- '-DUSE_SKIA' \
'-D_FILE_OFFSET_BITS=64' \
'-DUSE_LINUX_BREAKPAD' \
'-DNO_TCMALLOC' \
@@ -244,13 +245,11 @@
'-DCHROMIUM_BUILD' \
'-DUSE_LIBJPEG_TURBO=1' \
'-DUSE_PROPRIETARY_CODECS' \
- '-DENABLE_PEPPER_THREADING' \
'-DENABLE_GPU=1' \
'-DUSE_OPENSSL=1' \
'-DENABLE_EGLIMAGE=1' \
'-DENABLE_LANGUAGE_DETECTION=1' \
'-DUSE_SYMBOLIZE' \
- '-DU_USING_ICU_NAMESPACE=0' \
'-D__STDC_CONSTANT_MACROS' \
'-D__STDC_FORMAT_MACROS' \
'-DBASE_IMPLEMENTATION' \
@@ -267,10 +266,8 @@
# Include paths placed before CFLAGS/CPPFLAGS
LOCAL_C_INCLUDES := \
- $(gyp_shared_intermediate_dir)/shim_headers/icuuc/target \
$(gyp_shared_intermediate_dir)/base \
- $(GYP_ABS_ANDROID_TOP_DIR)/external/icu4c/common \
- $(GYP_ABS_ANDROID_TOP_DIR)/external/icu4c/i18n \
+ $(gyp_shared_intermediate_dir)/shim_headers/ashmem/target \
$(LOCAL_PATH) \
$(GYP_ABS_ANDROID_TOP_DIR)/frameworks/wilhelm/include \
$(GYP_ABS_ANDROID_TOP_DIR)/bionic \
@@ -303,9 +300,9 @@
-Wl,--no-undefined \
-Wl,--exclude-libs=ALL \
-Wl,--icf=safe \
+ -Wl,--gc-sections \
-Wl,-O1 \
- -Wl,--as-needed \
- -Wl,--gc-sections
+ -Wl,--as-needed
LOCAL_STATIC_LIBRARIES := \
diff --git a/base/base.target.linux-x86.mk b/base/base.target.linux-x86.mk
index 59b2553..8ea1770 100644
--- a/base/base.target.linux-x86.mk
+++ b/base/base.target.linux-x86.mk
@@ -13,7 +13,7 @@
GYP_TARGET_DEPENDENCIES := \
$(call intermediates-dir-for,GYP,testing_gtest_prod_gyp)/gtest_prod.stamp \
$(call intermediates-dir-for,GYP,base_base_jni_headers_gyp)/base_jni_headers.stamp \
- $(call intermediates-dir-for,GYP,third_party_icu_icuuc_gyp)/icuuc.stamp
+ $(call intermediates-dir-for,GYP,third_party_ashmem_ashmem_gyp)/ashmem.stamp
GYP_GENERATED_OUTPUTS :=
@@ -40,6 +40,7 @@
base/third_party/nspr/prtime.cc \
base/allocator/allocator_extension.cc \
base/allocator/type_profiler_control.cc \
+ base/android/activity_status.cc \
base/android/base_jni_registrar.cc \
base/android/build_info.cc \
base/android/cpu_features.cc \
@@ -50,7 +51,6 @@
base/android/jni_helper.cc \
base/android/jni_registrar.cc \
base/android/jni_string.cc \
- base/android/locale_utils.cc \
base/android/path_service_android.cc \
base/android/path_utils.cc \
base/at_exit.cc \
@@ -72,6 +72,7 @@
base/debug/stack_trace_android.cc \
base/debug/trace_event_android.cc \
base/debug/trace_event_impl.cc \
+ base/deferred_sequenced_task_runner.cc \
base/environment.cc \
base/file_util.cc \
base/file_util_android.cc \
@@ -102,11 +103,13 @@
base/memory/discardable_memory_android.cc \
base/memory/ref_counted.cc \
base/memory/ref_counted_memory.cc \
+ base/memory/shared_memory_android.cc \
+ base/memory/shared_memory_posix.cc \
base/memory/singleton.cc \
base/memory/weak_ptr.cc \
+ base/message_loop/message_loop_proxy.cc \
+ base/message_loop/message_loop_proxy_impl.cc \
base/message_loop.cc \
- base/message_loop_proxy.cc \
- base/message_loop_proxy_impl.cc \
base/message_pump.cc \
base/message_pump_default.cc \
base/metrics/sample_map.cc \
@@ -129,6 +132,8 @@
base/platform_file_posix.cc \
base/posix/global_descriptors.cc \
base/posix/unix_domain_socket_linux.cc \
+ base/power_monitor/power_monitor.cc \
+ base/power_monitor/power_monitor_android.cc \
base/process_posix.cc \
base/process_util.cc \
base/process_util_linux.cc \
@@ -144,17 +149,16 @@
base/sequence_checker_impl.cc \
base/sequenced_task_runner.cc \
base/sha1_portable.cc \
- base/shared_memory_android.cc \
- base/shared_memory_posix.cc \
- base/string_piece.cc \
base/string_util.cc \
base/string16.cc \
base/stringprintf.cc \
base/strings/string_split.cc \
base/strings/string_number_conversions.cc \
+ base/strings/string_piece.cc \
base/strings/sys_string_conversions_posix.cc \
base/strings/utf_offset_string_conversions.cc \
base/strings/utf_string_conversion_utils.cc \
+ base/strings/utf_string_conversions.cc \
base/supports_user_data.cc \
base/synchronization/cancellation_flag.cc \
base/synchronization/condition_variable_posix.cc \
@@ -163,7 +167,6 @@
base/synchronization/waitable_event_posix.cc \
base/synchronization/waitable_event_watcher_posix.cc \
base/system_monitor/system_monitor.cc \
- base/system_monitor/system_monitor_android.cc \
base/sys_info.cc \
base/sys_info_android.cc \
base/sys_info_linux.cc \
@@ -194,7 +197,6 @@
base/timer.cc \
base/tracked_objects.cc \
base/tracking_info.cc \
- base/utf_string_conversions.cc \
base/values.cc \
base/value_conversions.cc \
base/version.cc \
@@ -218,6 +220,7 @@
-march=pentium4 \
-msse2 \
-mfpmath=sse \
+ -fuse-ld=gold \
-ffunction-sections \
-funwind-tables \
-g \
@@ -238,7 +241,6 @@
MY_CFLAGS_C :=
MY_DEFS := \
- '-DUSE_SKIA' \
'-D_FILE_OFFSET_BITS=64' \
'-DUSE_LINUX_BREAKPAD' \
'-DNO_TCMALLOC' \
@@ -246,13 +248,11 @@
'-DCHROMIUM_BUILD' \
'-DUSE_LIBJPEG_TURBO=1' \
'-DUSE_PROPRIETARY_CODECS' \
- '-DENABLE_PEPPER_THREADING' \
'-DENABLE_GPU=1' \
'-DUSE_OPENSSL=1' \
'-DENABLE_EGLIMAGE=1' \
'-DENABLE_LANGUAGE_DETECTION=1' \
'-DUSE_SYMBOLIZE' \
- '-DU_USING_ICU_NAMESPACE=0' \
'-D__STDC_CONSTANT_MACROS' \
'-D__STDC_FORMAT_MACROS' \
'-DBASE_IMPLEMENTATION' \
@@ -269,10 +269,8 @@
# Include paths placed before CFLAGS/CPPFLAGS
LOCAL_C_INCLUDES := \
- $(gyp_shared_intermediate_dir)/shim_headers/icuuc/target \
$(gyp_shared_intermediate_dir)/base \
- $(GYP_ABS_ANDROID_TOP_DIR)/external/icu4c/common \
- $(GYP_ABS_ANDROID_TOP_DIR)/external/icu4c/i18n \
+ $(gyp_shared_intermediate_dir)/shim_headers/ashmem/target \
$(LOCAL_PATH) \
$(GYP_ABS_ANDROID_TOP_DIR)/frameworks/wilhelm/include \
$(GYP_ABS_ANDROID_TOP_DIR)/bionic \
@@ -298,12 +296,13 @@
-Wl,-z,noexecstack \
-fPIC \
-m32 \
+ -fuse-ld=gold \
-nostdlib \
-Wl,--no-undefined \
-Wl,--exclude-libs=ALL \
+ -Wl,--gc-sections \
-Wl,-O1 \
- -Wl,--as-needed \
- -Wl,--gc-sections
+ -Wl,--as-needed
LOCAL_STATIC_LIBRARIES := \
diff --git a/base/base64.h b/base/base64.h
index 983d5e2..cc78edc 100644
--- a/base/base64.h
+++ b/base/base64.h
@@ -8,7 +8,7 @@
#include <string>
#include "base/base_export.h"
-#include "base/string_piece.h"
+#include "base/strings/string_piece.h"
namespace base {
diff --git a/base/base_i18n.target.darwin-arm.mk b/base/base_i18n.target.darwin-arm.mk
new file mode 100644
index 0000000..a779ecf
--- /dev/null
+++ b/base/base_i18n.target.darwin-arm.mk
@@ -0,0 +1,166 @@
+# This file is generated by gyp; do not edit.
+
+include $(CLEAR_VARS)
+
+LOCAL_MODULE_CLASS := STATIC_LIBRARIES
+LOCAL_MODULE := base_base_i18n_gyp
+LOCAL_MODULE_SUFFIX := .a
+LOCAL_MODULE_TAGS := optional
+gyp_intermediate_dir := $(call local-intermediates-dir)
+gyp_shared_intermediate_dir := $(call intermediates-dir-for,GYP,shared)
+
+# Make sure our deps are built first.
+GYP_TARGET_DEPENDENCIES := \
+ $(call intermediates-dir-for,GYP,third_party_icu_icui18n_gyp)/icui18n.stamp \
+ $(call intermediates-dir-for,GYP,third_party_icu_icuuc_gyp)/icuuc.stamp
+
+GYP_GENERATED_OUTPUTS :=
+
+# Make sure our deps and generated files are built first.
+LOCAL_ADDITIONAL_DEPENDENCIES := $(GYP_TARGET_DEPENDENCIES) $(GYP_GENERATED_OUTPUTS)
+
+LOCAL_CPP_EXTENSION := .cc
+LOCAL_GENERATED_SOURCES :=
+
+GYP_COPIED_SOURCE_ORIGIN_DIRS :=
+
+LOCAL_SRC_FILES := \
+ base/i18n/bidi_line_iterator.cc \
+ base/i18n/break_iterator.cc \
+ base/i18n/char_iterator.cc \
+ base/i18n/case_conversion.cc \
+ base/i18n/file_util_icu.cc \
+ base/i18n/icu_encoding_detection.cc \
+ base/i18n/icu_string_conversions.cc \
+ base/i18n/icu_util.cc \
+ base/i18n/number_formatting.cc \
+ base/i18n/rtl.cc \
+ base/i18n/string_compare.cc \
+ base/i18n/string_search.cc \
+ base/i18n/time_formatting.cc
+
+
+# Flags passed to both C and C++ files.
+MY_CFLAGS := \
+ -fstack-protector \
+ --param=ssp-buffer-size=4 \
+ -Werror \
+ -fno-exceptions \
+ -fno-strict-aliasing \
+ -Wall \
+ -Wno-unused-parameter \
+ -Wno-missing-field-initializers \
+ -fvisibility=hidden \
+ -pipe \
+ -fPIC \
+ -fno-tree-sra \
+ -fuse-ld=gold \
+ -Wno-psabi \
+ -ffunction-sections \
+ -funwind-tables \
+ -g \
+ -fstack-protector \
+ -fno-short-enums \
+ -finline-limit=64 \
+ -Wa,--noexecstack \
+ -U_FORTIFY_SOURCE \
+ -Wno-extra \
+ -Wno-ignored-qualifiers \
+ -Wno-type-limits \
+ -Os \
+ -g \
+ -fomit-frame-pointer \
+ -fdata-sections \
+ -ffunction-sections
+
+MY_CFLAGS_C :=
+
+MY_DEFS := \
+ '-D_FILE_OFFSET_BITS=64' \
+ '-DUSE_LINUX_BREAKPAD' \
+ '-DNO_TCMALLOC' \
+ '-DDISABLE_NACL' \
+ '-DCHROMIUM_BUILD' \
+ '-DUSE_LIBJPEG_TURBO=1' \
+ '-DUSE_PROPRIETARY_CODECS' \
+ '-DENABLE_GPU=1' \
+ '-DUSE_OPENSSL=1' \
+ '-DENABLE_EGLIMAGE=1' \
+ '-DENABLE_LANGUAGE_DETECTION=1' \
+ '-DBASE_I18N_IMPLEMENTATION' \
+ '-DU_USING_ICU_NAMESPACE=0' \
+ '-D__STDC_CONSTANT_MACROS' \
+ '-D__STDC_FORMAT_MACROS' \
+ '-DANDROID' \
+ '-D__GNU_SOURCE=1' \
+ '-DUSE_STLPORT=1' \
+ '-D_STLP_USE_PTR_SPECIALIZATIONS=1' \
+ '-DCHROME_BUILD_ID=""' \
+ '-DDYNAMIC_ANNOTATIONS_ENABLED=1' \
+ '-DWTF_USE_DYNAMIC_ANNOTATIONS=1' \
+ '-D_DEBUG'
+
+LOCAL_CFLAGS := $(MY_CFLAGS_C) $(MY_CFLAGS) $(MY_DEFS)
+
+# Include paths placed before CFLAGS/CPPFLAGS
+LOCAL_C_INCLUDES := \
+ $(gyp_shared_intermediate_dir)/shim_headers/ashmem/target \
+ $(gyp_shared_intermediate_dir)/shim_headers/icui18n/target \
+ $(gyp_shared_intermediate_dir)/shim_headers/icuuc/target \
+ $(LOCAL_PATH) \
+ $(GYP_ABS_ANDROID_TOP_DIR)/external/icu4c/common \
+ $(GYP_ABS_ANDROID_TOP_DIR)/external/icu4c/i18n \
+ $(GYP_ABS_ANDROID_TOP_DIR)/frameworks/wilhelm/include \
+ $(GYP_ABS_ANDROID_TOP_DIR)/bionic \
+ $(GYP_ABS_ANDROID_TOP_DIR)/external/stlport/stlport
+
+LOCAL_C_INCLUDES := $(GYP_COPIED_SOURCE_ORIGIN_DIRS) $(LOCAL_C_INCLUDES)
+
+# Flags passed to only C++ (and not C) files.
+LOCAL_CPPFLAGS := \
+ -fno-rtti \
+ -fno-threadsafe-statics \
+ -fvisibility-inlines-hidden \
+ -Wsign-compare \
+ -Wno-abi \
+ -Wno-error=c++0x-compat \
+ -Wno-non-virtual-dtor \
+ -Wno-sign-promo
+
+### Rules for final target.
+
+LOCAL_LDFLAGS := \
+ -Wl,-z,now \
+ -Wl,-z,relro \
+ -Wl,-z,noexecstack \
+ -fPIC \
+ -Wl,-z,relro \
+ -Wl,-z,now \
+ -fuse-ld=gold \
+ -nostdlib \
+ -Wl,--no-undefined \
+ -Wl,--exclude-libs=ALL \
+ -Wl,--icf=safe \
+ -Wl,--gc-sections \
+ -Wl,-O1 \
+ -Wl,--as-needed
+
+
+LOCAL_STATIC_LIBRARIES :=
+
+# Enable grouping to fix circular references
+LOCAL_GROUP_STATIC_LIBRARIES := true
+
+LOCAL_SHARED_LIBRARIES := \
+ libstlport \
+ libdl
+
+# Add target alias to "gyp_all_modules" target.
+.PHONY: gyp_all_modules
+gyp_all_modules: base_base_i18n_gyp
+
+# Alias gyp target name.
+.PHONY: base_i18n
+base_i18n: base_base_i18n_gyp
+
+include $(BUILD_STATIC_LIBRARY)
diff --git a/base/base_i18n.target.darwin-x86.mk b/base/base_i18n.target.darwin-x86.mk
new file mode 100644
index 0000000..0d4ddcc
--- /dev/null
+++ b/base/base_i18n.target.darwin-x86.mk
@@ -0,0 +1,165 @@
+# This file is generated by gyp; do not edit.
+
+include $(CLEAR_VARS)
+
+LOCAL_MODULE_CLASS := STATIC_LIBRARIES
+LOCAL_MODULE := base_base_i18n_gyp
+LOCAL_MODULE_SUFFIX := .a
+LOCAL_MODULE_TAGS := optional
+gyp_intermediate_dir := $(call local-intermediates-dir)
+gyp_shared_intermediate_dir := $(call intermediates-dir-for,GYP,shared)
+
+# Make sure our deps are built first.
+GYP_TARGET_DEPENDENCIES := \
+ $(call intermediates-dir-for,GYP,third_party_icu_icui18n_gyp)/icui18n.stamp \
+ $(call intermediates-dir-for,GYP,third_party_icu_icuuc_gyp)/icuuc.stamp
+
+GYP_GENERATED_OUTPUTS :=
+
+# Make sure our deps and generated files are built first.
+LOCAL_ADDITIONAL_DEPENDENCIES := $(GYP_TARGET_DEPENDENCIES) $(GYP_GENERATED_OUTPUTS)
+
+LOCAL_CPP_EXTENSION := .cc
+LOCAL_GENERATED_SOURCES :=
+
+GYP_COPIED_SOURCE_ORIGIN_DIRS :=
+
+LOCAL_SRC_FILES := \
+ base/i18n/bidi_line_iterator.cc \
+ base/i18n/break_iterator.cc \
+ base/i18n/char_iterator.cc \
+ base/i18n/case_conversion.cc \
+ base/i18n/file_util_icu.cc \
+ base/i18n/icu_encoding_detection.cc \
+ base/i18n/icu_string_conversions.cc \
+ base/i18n/icu_util.cc \
+ base/i18n/number_formatting.cc \
+ base/i18n/rtl.cc \
+ base/i18n/string_compare.cc \
+ base/i18n/string_search.cc \
+ base/i18n/time_formatting.cc
+
+
+# Flags passed to both C and C++ files.
+MY_CFLAGS := \
+ --param=ssp-buffer-size=4 \
+ -Werror \
+ -fno-exceptions \
+ -fno-strict-aliasing \
+ -Wall \
+ -Wno-unused-parameter \
+ -Wno-missing-field-initializers \
+ -fvisibility=hidden \
+ -pipe \
+ -fPIC \
+ -m32 \
+ -mmmx \
+ -march=pentium4 \
+ -msse2 \
+ -mfpmath=sse \
+ -fuse-ld=gold \
+ -ffunction-sections \
+ -funwind-tables \
+ -g \
+ -fno-short-enums \
+ -finline-limit=64 \
+ -Wa,--noexecstack \
+ -U_FORTIFY_SOURCE \
+ -Wno-extra \
+ -Wno-ignored-qualifiers \
+ -Wno-type-limits \
+ -fno-stack-protector \
+ -Os \
+ -g \
+ -fomit-frame-pointer \
+ -fdata-sections \
+ -ffunction-sections
+
+MY_CFLAGS_C :=
+
+MY_DEFS := \
+ '-D_FILE_OFFSET_BITS=64' \
+ '-DUSE_LINUX_BREAKPAD' \
+ '-DNO_TCMALLOC' \
+ '-DDISABLE_NACL' \
+ '-DCHROMIUM_BUILD' \
+ '-DUSE_LIBJPEG_TURBO=1' \
+ '-DUSE_PROPRIETARY_CODECS' \
+ '-DENABLE_GPU=1' \
+ '-DUSE_OPENSSL=1' \
+ '-DENABLE_EGLIMAGE=1' \
+ '-DENABLE_LANGUAGE_DETECTION=1' \
+ '-DBASE_I18N_IMPLEMENTATION' \
+ '-DU_USING_ICU_NAMESPACE=0' \
+ '-D__STDC_CONSTANT_MACROS' \
+ '-D__STDC_FORMAT_MACROS' \
+ '-DANDROID' \
+ '-D__GNU_SOURCE=1' \
+ '-DUSE_STLPORT=1' \
+ '-D_STLP_USE_PTR_SPECIALIZATIONS=1' \
+ '-DCHROME_BUILD_ID=""' \
+ '-DDYNAMIC_ANNOTATIONS_ENABLED=1' \
+ '-DWTF_USE_DYNAMIC_ANNOTATIONS=1' \
+ '-D_DEBUG'
+
+LOCAL_CFLAGS := $(MY_CFLAGS_C) $(MY_CFLAGS) $(MY_DEFS)
+
+# Include paths placed before CFLAGS/CPPFLAGS
+LOCAL_C_INCLUDES := \
+ $(gyp_shared_intermediate_dir)/shim_headers/ashmem/target \
+ $(gyp_shared_intermediate_dir)/shim_headers/icui18n/target \
+ $(gyp_shared_intermediate_dir)/shim_headers/icuuc/target \
+ $(LOCAL_PATH) \
+ $(GYP_ABS_ANDROID_TOP_DIR)/external/icu4c/common \
+ $(GYP_ABS_ANDROID_TOP_DIR)/external/icu4c/i18n \
+ $(GYP_ABS_ANDROID_TOP_DIR)/frameworks/wilhelm/include \
+ $(GYP_ABS_ANDROID_TOP_DIR)/bionic \
+ $(GYP_ABS_ANDROID_TOP_DIR)/external/stlport/stlport
+
+LOCAL_C_INCLUDES := $(GYP_COPIED_SOURCE_ORIGIN_DIRS) $(LOCAL_C_INCLUDES)
+
+# Flags passed to only C++ (and not C) files.
+LOCAL_CPPFLAGS := \
+ -fno-rtti \
+ -fno-threadsafe-statics \
+ -fvisibility-inlines-hidden \
+ -Wsign-compare \
+ -Wno-error=c++0x-compat \
+ -Wno-non-virtual-dtor \
+ -Wno-sign-promo
+
+### Rules for final target.
+
+LOCAL_LDFLAGS := \
+ -Wl,-z,now \
+ -Wl,-z,relro \
+ -Wl,-z,noexecstack \
+ -fPIC \
+ -m32 \
+ -fuse-ld=gold \
+ -nostdlib \
+ -Wl,--no-undefined \
+ -Wl,--exclude-libs=ALL \
+ -Wl,--gc-sections \
+ -Wl,-O1 \
+ -Wl,--as-needed
+
+
+LOCAL_STATIC_LIBRARIES :=
+
+# Enable grouping to fix circular references
+LOCAL_GROUP_STATIC_LIBRARIES := true
+
+LOCAL_SHARED_LIBRARIES := \
+ libstlport \
+ libdl
+
+# Add target alias to "gyp_all_modules" target.
+.PHONY: gyp_all_modules
+gyp_all_modules: base_base_i18n_gyp
+
+# Alias gyp target name.
+.PHONY: base_i18n
+base_i18n: base_base_i18n_gyp
+
+include $(BUILD_STATIC_LIBRARY)
diff --git a/base/base_i18n.target.linux-arm.mk b/base/base_i18n.target.linux-arm.mk
index 99dce67..a779ecf 100644
--- a/base/base_i18n.target.linux-arm.mk
+++ b/base/base_i18n.target.linux-arm.mk
@@ -35,6 +35,7 @@
base/i18n/icu_util.cc \
base/i18n/number_formatting.cc \
base/i18n/rtl.cc \
+ base/i18n/string_compare.cc \
base/i18n/string_search.cc \
base/i18n/time_formatting.cc
@@ -75,7 +76,6 @@
MY_CFLAGS_C :=
MY_DEFS := \
- '-DUSE_SKIA' \
'-D_FILE_OFFSET_BITS=64' \
'-DUSE_LINUX_BREAKPAD' \
'-DNO_TCMALLOC' \
@@ -83,7 +83,6 @@
'-DCHROMIUM_BUILD' \
'-DUSE_LIBJPEG_TURBO=1' \
'-DUSE_PROPRIETARY_CODECS' \
- '-DENABLE_PEPPER_THREADING' \
'-DENABLE_GPU=1' \
'-DUSE_OPENSSL=1' \
'-DENABLE_EGLIMAGE=1' \
@@ -105,6 +104,7 @@
# Include paths placed before CFLAGS/CPPFLAGS
LOCAL_C_INCLUDES := \
+ $(gyp_shared_intermediate_dir)/shim_headers/ashmem/target \
$(gyp_shared_intermediate_dir)/shim_headers/icui18n/target \
$(gyp_shared_intermediate_dir)/shim_headers/icuuc/target \
$(LOCAL_PATH) \
@@ -141,9 +141,9 @@
-Wl,--no-undefined \
-Wl,--exclude-libs=ALL \
-Wl,--icf=safe \
+ -Wl,--gc-sections \
-Wl,-O1 \
- -Wl,--as-needed \
- -Wl,--gc-sections
+ -Wl,--as-needed
LOCAL_STATIC_LIBRARIES :=
diff --git a/base/base_i18n.target.linux-x86.mk b/base/base_i18n.target.linux-x86.mk
index 012d8f8..0d4ddcc 100644
--- a/base/base_i18n.target.linux-x86.mk
+++ b/base/base_i18n.target.linux-x86.mk
@@ -35,6 +35,7 @@
base/i18n/icu_util.cc \
base/i18n/number_formatting.cc \
base/i18n/rtl.cc \
+ base/i18n/string_compare.cc \
base/i18n/string_search.cc \
base/i18n/time_formatting.cc
@@ -56,6 +57,7 @@
-march=pentium4 \
-msse2 \
-mfpmath=sse \
+ -fuse-ld=gold \
-ffunction-sections \
-funwind-tables \
-g \
@@ -76,7 +78,6 @@
MY_CFLAGS_C :=
MY_DEFS := \
- '-DUSE_SKIA' \
'-D_FILE_OFFSET_BITS=64' \
'-DUSE_LINUX_BREAKPAD' \
'-DNO_TCMALLOC' \
@@ -84,7 +85,6 @@
'-DCHROMIUM_BUILD' \
'-DUSE_LIBJPEG_TURBO=1' \
'-DUSE_PROPRIETARY_CODECS' \
- '-DENABLE_PEPPER_THREADING' \
'-DENABLE_GPU=1' \
'-DUSE_OPENSSL=1' \
'-DENABLE_EGLIMAGE=1' \
@@ -106,6 +106,7 @@
# Include paths placed before CFLAGS/CPPFLAGS
LOCAL_C_INCLUDES := \
+ $(gyp_shared_intermediate_dir)/shim_headers/ashmem/target \
$(gyp_shared_intermediate_dir)/shim_headers/icui18n/target \
$(gyp_shared_intermediate_dir)/shim_headers/icuuc/target \
$(LOCAL_PATH) \
@@ -135,12 +136,13 @@
-Wl,-z,noexecstack \
-fPIC \
-m32 \
+ -fuse-ld=gold \
-nostdlib \
-Wl,--no-undefined \
-Wl,--exclude-libs=ALL \
+ -Wl,--gc-sections \
-Wl,-O1 \
- -Wl,--as-needed \
- -Wl,--gc-sections
+ -Wl,--as-needed
LOCAL_STATIC_LIBRARIES :=
diff --git a/base/base_java_activity_state.target.darwin-arm.mk b/base/base_java_activity_state.target.darwin-arm.mk
new file mode 100644
index 0000000..c85db90
--- /dev/null
+++ b/base/base_java_activity_state.target.darwin-arm.mk
@@ -0,0 +1,141 @@
+# This file is generated by gyp; do not edit.
+
+include $(CLEAR_VARS)
+
+LOCAL_MODULE_CLASS := GYP
+LOCAL_MODULE := base_base_java_activity_state_gyp
+LOCAL_MODULE_STEM := base_java_activity_state
+LOCAL_MODULE_SUFFIX := .stamp
+LOCAL_MODULE_TAGS := optional
+gyp_intermediate_dir := $(call local-intermediates-dir)
+gyp_shared_intermediate_dir := $(call intermediates-dir-for,GYP,shared)
+
+# Make sure our deps are built first.
+GYP_TARGET_DEPENDENCIES :=
+
+
+### Generated for rule "base_base_gyp_base_java_activity_state_target_generate_java_constants":
+# "{'inputs': ['../build/android/gyp/util/build_utils.py', '../build/android/gyp/gcc_preprocess.py', 'android/activity_state_list.h'], 'extension': 'template', 'outputs': ['$(gyp_shared_intermediate_dir)/templates/org/chromium/base/%(INPUT_ROOT)s.java'], 'variables': {'output_path': '$(gyp_shared_intermediate_dir)/templates/org/chromium/base/%(INPUT_ROOT)s.java'}, 'rule_name': 'generate_java_constants', 'rule_sources': ['android/java/src/org/chromium/base/ActivityState.template'], 'action': ['python', '../build/android/gyp/gcc_preprocess.py', '--include-path=..', '--output=$(gyp_shared_intermediate_dir)/templates/org/chromium/base/%(INPUT_ROOT)s.java', '--template=$(RULE_SOURCES)'], 'message': 'Generating Java from cpp template $(RULE_SOURCES)'}":
+$(gyp_shared_intermediate_dir)/templates/org/chromium/base/ActivityState.java: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/templates/org/chromium/base/ActivityState.java: gyp_intermediate_dir := $(GYP_ABS_ANDROID_TOP_DIR)/$(gyp_intermediate_dir)
+$(gyp_shared_intermediate_dir)/templates/org/chromium/base/ActivityState.java: gyp_shared_intermediate_dir := $(GYP_ABS_ANDROID_TOP_DIR)/$(gyp_shared_intermediate_dir)
+$(gyp_shared_intermediate_dir)/templates/org/chromium/base/ActivityState.java: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
+$(gyp_shared_intermediate_dir)/templates/org/chromium/base/ActivityState.java: $(LOCAL_PATH)/base/android/java/src/org/chromium/base/ActivityState.template $(LOCAL_PATH)/build/android/gyp/util/build_utils.py $(LOCAL_PATH)/build/android/gyp/gcc_preprocess.py $(LOCAL_PATH)/base/android/activity_state_list.h $(GYP_TARGET_DEPENDENCIES)
+ mkdir -p $(gyp_shared_intermediate_dir)/templates/org/chromium/base; cd $(gyp_local_path)/base; python ../build/android/gyp/gcc_preprocess.py "--include-path=.." "--output=$(gyp_shared_intermediate_dir)/templates/org/chromium/base/ActivityState.java" "--template=android/java/src/org/chromium/base/ActivityState.template"
+
+.PHONY: base_base_java_activity_state_gyp_rule_trigger
+base_base_java_activity_state_gyp_rule_trigger: $(gyp_shared_intermediate_dir)/templates/org/chromium/base/ActivityState.java
+
+### Finished generating for all rules
+
+GYP_GENERATED_OUTPUTS := \
+ $(gyp_shared_intermediate_dir)/templates/org/chromium/base/ActivityState.java
+
+# Make sure our deps and generated files are built first.
+LOCAL_ADDITIONAL_DEPENDENCIES := $(GYP_TARGET_DEPENDENCIES) $(GYP_GENERATED_OUTPUTS)
+
+LOCAL_GENERATED_SOURCES := \
+ base_base_java_activity_state_gyp_rule_trigger
+
+GYP_COPIED_SOURCE_ORIGIN_DIRS :=
+
+LOCAL_SRC_FILES :=
+
+
+# Flags passed to both C and C++ files.
+MY_CFLAGS := \
+ -fstack-protector \
+ --param=ssp-buffer-size=4 \
+ -Werror \
+ -fno-exceptions \
+ -fno-strict-aliasing \
+ -Wall \
+ -Wno-unused-parameter \
+ -Wno-missing-field-initializers \
+ -fvisibility=hidden \
+ -pipe \
+ -fPIC \
+ -fno-tree-sra \
+ -fuse-ld=gold \
+ -Wno-psabi \
+ -ffunction-sections \
+ -funwind-tables \
+ -g \
+ -fstack-protector \
+ -fno-short-enums \
+ -finline-limit=64 \
+ -Wa,--noexecstack \
+ -U_FORTIFY_SOURCE \
+ -Wno-extra \
+ -Wno-ignored-qualifiers \
+ -Wno-type-limits \
+ -Os \
+ -g \
+ -fomit-frame-pointer \
+ -fdata-sections \
+ -ffunction-sections
+
+MY_CFLAGS_C :=
+
+MY_DEFS := \
+ '-D_FILE_OFFSET_BITS=64' \
+ '-DUSE_LINUX_BREAKPAD' \
+ '-DNO_TCMALLOC' \
+ '-DDISABLE_NACL' \
+ '-DCHROMIUM_BUILD' \
+ '-DUSE_LIBJPEG_TURBO=1' \
+ '-DUSE_PROPRIETARY_CODECS' \
+ '-DENABLE_GPU=1' \
+ '-DUSE_OPENSSL=1' \
+ '-DENABLE_EGLIMAGE=1' \
+ '-DENABLE_LANGUAGE_DETECTION=1' \
+ '-D__STDC_CONSTANT_MACROS' \
+ '-D__STDC_FORMAT_MACROS' \
+ '-DANDROID' \
+ '-D__GNU_SOURCE=1' \
+ '-DUSE_STLPORT=1' \
+ '-D_STLP_USE_PTR_SPECIALIZATIONS=1' \
+ '-DCHROME_BUILD_ID=""' \
+ '-DDYNAMIC_ANNOTATIONS_ENABLED=1' \
+ '-DWTF_USE_DYNAMIC_ANNOTATIONS=1' \
+ '-D_DEBUG'
+
+LOCAL_CFLAGS := $(MY_CFLAGS_C) $(MY_CFLAGS) $(MY_DEFS)
+
+# Include paths placed before CFLAGS/CPPFLAGS
+LOCAL_C_INCLUDES := \
+ $(GYP_ABS_ANDROID_TOP_DIR)/frameworks/wilhelm/include \
+ $(GYP_ABS_ANDROID_TOP_DIR)/bionic \
+ $(GYP_ABS_ANDROID_TOP_DIR)/external/stlport/stlport
+
+LOCAL_C_INCLUDES := $(GYP_COPIED_SOURCE_ORIGIN_DIRS) $(LOCAL_C_INCLUDES)
+
+# Flags passed to only C++ (and not C) files.
+LOCAL_CPPFLAGS := \
+ -fno-rtti \
+ -fno-threadsafe-statics \
+ -fvisibility-inlines-hidden \
+ -Wsign-compare \
+ -Wno-abi \
+ -Wno-error=c++0x-compat \
+ -Wno-non-virtual-dtor \
+ -Wno-sign-promo
+
+### Rules for final target.
+# Add target alias to "gyp_all_modules" target.
+.PHONY: gyp_all_modules
+gyp_all_modules: base_base_java_activity_state_gyp
+
+# Alias gyp target name.
+.PHONY: base_java_activity_state
+base_java_activity_state: base_base_java_activity_state_gyp
+
+LOCAL_MODULE_PATH := $(PRODUCT_OUT)/gyp_stamp
+LOCAL_UNINSTALLABLE_MODULE := true
+
+include $(BUILD_SYSTEM)/base_rules.mk
+
+$(LOCAL_BUILT_MODULE): $(LOCAL_ADDITIONAL_DEPENDENCIES)
+ $(hide) echo "Gyp timestamp: $@"
+ $(hide) mkdir -p $(dir $@)
+ $(hide) touch $@
diff --git a/base/base_java_activity_state.target.darwin-x86.mk b/base/base_java_activity_state.target.darwin-x86.mk
new file mode 100644
index 0000000..34649dd
--- /dev/null
+++ b/base/base_java_activity_state.target.darwin-x86.mk
@@ -0,0 +1,142 @@
+# This file is generated by gyp; do not edit.
+
+include $(CLEAR_VARS)
+
+LOCAL_MODULE_CLASS := GYP
+LOCAL_MODULE := base_base_java_activity_state_gyp
+LOCAL_MODULE_STEM := base_java_activity_state
+LOCAL_MODULE_SUFFIX := .stamp
+LOCAL_MODULE_TAGS := optional
+gyp_intermediate_dir := $(call local-intermediates-dir)
+gyp_shared_intermediate_dir := $(call intermediates-dir-for,GYP,shared)
+
+# Make sure our deps are built first.
+GYP_TARGET_DEPENDENCIES :=
+
+
+### Generated for rule "base_base_gyp_base_java_activity_state_target_generate_java_constants":
+# "{'inputs': ['../build/android/gyp/util/build_utils.py', '../build/android/gyp/gcc_preprocess.py', 'android/activity_state_list.h'], 'extension': 'template', 'outputs': ['$(gyp_shared_intermediate_dir)/templates/org/chromium/base/%(INPUT_ROOT)s.java'], 'variables': {'output_path': '$(gyp_shared_intermediate_dir)/templates/org/chromium/base/%(INPUT_ROOT)s.java'}, 'rule_name': 'generate_java_constants', 'rule_sources': ['android/java/src/org/chromium/base/ActivityState.template'], 'action': ['python', '../build/android/gyp/gcc_preprocess.py', '--include-path=..', '--output=$(gyp_shared_intermediate_dir)/templates/org/chromium/base/%(INPUT_ROOT)s.java', '--template=$(RULE_SOURCES)'], 'message': 'Generating Java from cpp template $(RULE_SOURCES)'}":
+$(gyp_shared_intermediate_dir)/templates/org/chromium/base/ActivityState.java: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/templates/org/chromium/base/ActivityState.java: gyp_intermediate_dir := $(GYP_ABS_ANDROID_TOP_DIR)/$(gyp_intermediate_dir)
+$(gyp_shared_intermediate_dir)/templates/org/chromium/base/ActivityState.java: gyp_shared_intermediate_dir := $(GYP_ABS_ANDROID_TOP_DIR)/$(gyp_shared_intermediate_dir)
+$(gyp_shared_intermediate_dir)/templates/org/chromium/base/ActivityState.java: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
+$(gyp_shared_intermediate_dir)/templates/org/chromium/base/ActivityState.java: $(LOCAL_PATH)/base/android/java/src/org/chromium/base/ActivityState.template $(LOCAL_PATH)/build/android/gyp/util/build_utils.py $(LOCAL_PATH)/build/android/gyp/gcc_preprocess.py $(LOCAL_PATH)/base/android/activity_state_list.h $(GYP_TARGET_DEPENDENCIES)
+ mkdir -p $(gyp_shared_intermediate_dir)/templates/org/chromium/base; cd $(gyp_local_path)/base; python ../build/android/gyp/gcc_preprocess.py "--include-path=.." "--output=$(gyp_shared_intermediate_dir)/templates/org/chromium/base/ActivityState.java" "--template=android/java/src/org/chromium/base/ActivityState.template"
+
+.PHONY: base_base_java_activity_state_gyp_rule_trigger
+base_base_java_activity_state_gyp_rule_trigger: $(gyp_shared_intermediate_dir)/templates/org/chromium/base/ActivityState.java
+
+### Finished generating for all rules
+
+GYP_GENERATED_OUTPUTS := \
+ $(gyp_shared_intermediate_dir)/templates/org/chromium/base/ActivityState.java
+
+# Make sure our deps and generated files are built first.
+LOCAL_ADDITIONAL_DEPENDENCIES := $(GYP_TARGET_DEPENDENCIES) $(GYP_GENERATED_OUTPUTS)
+
+LOCAL_GENERATED_SOURCES := \
+ base_base_java_activity_state_gyp_rule_trigger
+
+GYP_COPIED_SOURCE_ORIGIN_DIRS :=
+
+LOCAL_SRC_FILES :=
+
+
+# Flags passed to both C and C++ files.
+MY_CFLAGS := \
+ --param=ssp-buffer-size=4 \
+ -Werror \
+ -fno-exceptions \
+ -fno-strict-aliasing \
+ -Wall \
+ -Wno-unused-parameter \
+ -Wno-missing-field-initializers \
+ -fvisibility=hidden \
+ -pipe \
+ -fPIC \
+ -m32 \
+ -mmmx \
+ -march=pentium4 \
+ -msse2 \
+ -mfpmath=sse \
+ -fuse-ld=gold \
+ -ffunction-sections \
+ -funwind-tables \
+ -g \
+ -fno-short-enums \
+ -finline-limit=64 \
+ -Wa,--noexecstack \
+ -U_FORTIFY_SOURCE \
+ -Wno-extra \
+ -Wno-ignored-qualifiers \
+ -Wno-type-limits \
+ -fno-stack-protector \
+ -Os \
+ -g \
+ -fomit-frame-pointer \
+ -fdata-sections \
+ -ffunction-sections
+
+MY_CFLAGS_C :=
+
+MY_DEFS := \
+ '-D_FILE_OFFSET_BITS=64' \
+ '-DUSE_LINUX_BREAKPAD' \
+ '-DNO_TCMALLOC' \
+ '-DDISABLE_NACL' \
+ '-DCHROMIUM_BUILD' \
+ '-DUSE_LIBJPEG_TURBO=1' \
+ '-DUSE_PROPRIETARY_CODECS' \
+ '-DENABLE_GPU=1' \
+ '-DUSE_OPENSSL=1' \
+ '-DENABLE_EGLIMAGE=1' \
+ '-DENABLE_LANGUAGE_DETECTION=1' \
+ '-D__STDC_CONSTANT_MACROS' \
+ '-D__STDC_FORMAT_MACROS' \
+ '-DANDROID' \
+ '-D__GNU_SOURCE=1' \
+ '-DUSE_STLPORT=1' \
+ '-D_STLP_USE_PTR_SPECIALIZATIONS=1' \
+ '-DCHROME_BUILD_ID=""' \
+ '-DDYNAMIC_ANNOTATIONS_ENABLED=1' \
+ '-DWTF_USE_DYNAMIC_ANNOTATIONS=1' \
+ '-D_DEBUG'
+
+LOCAL_CFLAGS := $(MY_CFLAGS_C) $(MY_CFLAGS) $(MY_DEFS)
+
+# Include paths placed before CFLAGS/CPPFLAGS
+LOCAL_C_INCLUDES := \
+ $(GYP_ABS_ANDROID_TOP_DIR)/frameworks/wilhelm/include \
+ $(GYP_ABS_ANDROID_TOP_DIR)/bionic \
+ $(GYP_ABS_ANDROID_TOP_DIR)/external/stlport/stlport
+
+LOCAL_C_INCLUDES := $(GYP_COPIED_SOURCE_ORIGIN_DIRS) $(LOCAL_C_INCLUDES)
+
+# Flags passed to only C++ (and not C) files.
+LOCAL_CPPFLAGS := \
+ -fno-rtti \
+ -fno-threadsafe-statics \
+ -fvisibility-inlines-hidden \
+ -Wsign-compare \
+ -Wno-error=c++0x-compat \
+ -Wno-non-virtual-dtor \
+ -Wno-sign-promo
+
+### Rules for final target.
+# Add target alias to "gyp_all_modules" target.
+.PHONY: gyp_all_modules
+gyp_all_modules: base_base_java_activity_state_gyp
+
+# Alias gyp target name.
+.PHONY: base_java_activity_state
+base_java_activity_state: base_base_java_activity_state_gyp
+
+LOCAL_MODULE_PATH := $(PRODUCT_OUT)/gyp_stamp
+LOCAL_UNINSTALLABLE_MODULE := true
+
+include $(BUILD_SYSTEM)/base_rules.mk
+
+$(LOCAL_BUILT_MODULE): $(LOCAL_ADDITIONAL_DEPENDENCIES)
+ $(hide) echo "Gyp timestamp: $@"
+ $(hide) mkdir -p $(dir $@)
+ $(hide) touch $@
diff --git a/base/base_java_activity_state.target.linux-arm.mk b/base/base_java_activity_state.target.linux-arm.mk
new file mode 100644
index 0000000..c85db90
--- /dev/null
+++ b/base/base_java_activity_state.target.linux-arm.mk
@@ -0,0 +1,141 @@
+# This file is generated by gyp; do not edit.
+
+include $(CLEAR_VARS)
+
+LOCAL_MODULE_CLASS := GYP
+LOCAL_MODULE := base_base_java_activity_state_gyp
+LOCAL_MODULE_STEM := base_java_activity_state
+LOCAL_MODULE_SUFFIX := .stamp
+LOCAL_MODULE_TAGS := optional
+gyp_intermediate_dir := $(call local-intermediates-dir)
+gyp_shared_intermediate_dir := $(call intermediates-dir-for,GYP,shared)
+
+# Make sure our deps are built first.
+GYP_TARGET_DEPENDENCIES :=
+
+
+### Generated for rule "base_base_gyp_base_java_activity_state_target_generate_java_constants":
+# "{'inputs': ['../build/android/gyp/util/build_utils.py', '../build/android/gyp/gcc_preprocess.py', 'android/activity_state_list.h'], 'extension': 'template', 'outputs': ['$(gyp_shared_intermediate_dir)/templates/org/chromium/base/%(INPUT_ROOT)s.java'], 'variables': {'output_path': '$(gyp_shared_intermediate_dir)/templates/org/chromium/base/%(INPUT_ROOT)s.java'}, 'rule_name': 'generate_java_constants', 'rule_sources': ['android/java/src/org/chromium/base/ActivityState.template'], 'action': ['python', '../build/android/gyp/gcc_preprocess.py', '--include-path=..', '--output=$(gyp_shared_intermediate_dir)/templates/org/chromium/base/%(INPUT_ROOT)s.java', '--template=$(RULE_SOURCES)'], 'message': 'Generating Java from cpp template $(RULE_SOURCES)'}":
+$(gyp_shared_intermediate_dir)/templates/org/chromium/base/ActivityState.java: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/templates/org/chromium/base/ActivityState.java: gyp_intermediate_dir := $(GYP_ABS_ANDROID_TOP_DIR)/$(gyp_intermediate_dir)
+$(gyp_shared_intermediate_dir)/templates/org/chromium/base/ActivityState.java: gyp_shared_intermediate_dir := $(GYP_ABS_ANDROID_TOP_DIR)/$(gyp_shared_intermediate_dir)
+$(gyp_shared_intermediate_dir)/templates/org/chromium/base/ActivityState.java: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
+$(gyp_shared_intermediate_dir)/templates/org/chromium/base/ActivityState.java: $(LOCAL_PATH)/base/android/java/src/org/chromium/base/ActivityState.template $(LOCAL_PATH)/build/android/gyp/util/build_utils.py $(LOCAL_PATH)/build/android/gyp/gcc_preprocess.py $(LOCAL_PATH)/base/android/activity_state_list.h $(GYP_TARGET_DEPENDENCIES)
+ mkdir -p $(gyp_shared_intermediate_dir)/templates/org/chromium/base; cd $(gyp_local_path)/base; python ../build/android/gyp/gcc_preprocess.py "--include-path=.." "--output=$(gyp_shared_intermediate_dir)/templates/org/chromium/base/ActivityState.java" "--template=android/java/src/org/chromium/base/ActivityState.template"
+
+.PHONY: base_base_java_activity_state_gyp_rule_trigger
+base_base_java_activity_state_gyp_rule_trigger: $(gyp_shared_intermediate_dir)/templates/org/chromium/base/ActivityState.java
+
+### Finished generating for all rules
+
+GYP_GENERATED_OUTPUTS := \
+ $(gyp_shared_intermediate_dir)/templates/org/chromium/base/ActivityState.java
+
+# Make sure our deps and generated files are built first.
+LOCAL_ADDITIONAL_DEPENDENCIES := $(GYP_TARGET_DEPENDENCIES) $(GYP_GENERATED_OUTPUTS)
+
+LOCAL_GENERATED_SOURCES := \
+ base_base_java_activity_state_gyp_rule_trigger
+
+GYP_COPIED_SOURCE_ORIGIN_DIRS :=
+
+LOCAL_SRC_FILES :=
+
+
+# Flags passed to both C and C++ files.
+MY_CFLAGS := \
+ -fstack-protector \
+ --param=ssp-buffer-size=4 \
+ -Werror \
+ -fno-exceptions \
+ -fno-strict-aliasing \
+ -Wall \
+ -Wno-unused-parameter \
+ -Wno-missing-field-initializers \
+ -fvisibility=hidden \
+ -pipe \
+ -fPIC \
+ -fno-tree-sra \
+ -fuse-ld=gold \
+ -Wno-psabi \
+ -ffunction-sections \
+ -funwind-tables \
+ -g \
+ -fstack-protector \
+ -fno-short-enums \
+ -finline-limit=64 \
+ -Wa,--noexecstack \
+ -U_FORTIFY_SOURCE \
+ -Wno-extra \
+ -Wno-ignored-qualifiers \
+ -Wno-type-limits \
+ -Os \
+ -g \
+ -fomit-frame-pointer \
+ -fdata-sections \
+ -ffunction-sections
+
+MY_CFLAGS_C :=
+
+MY_DEFS := \
+ '-D_FILE_OFFSET_BITS=64' \
+ '-DUSE_LINUX_BREAKPAD' \
+ '-DNO_TCMALLOC' \
+ '-DDISABLE_NACL' \
+ '-DCHROMIUM_BUILD' \
+ '-DUSE_LIBJPEG_TURBO=1' \
+ '-DUSE_PROPRIETARY_CODECS' \
+ '-DENABLE_GPU=1' \
+ '-DUSE_OPENSSL=1' \
+ '-DENABLE_EGLIMAGE=1' \
+ '-DENABLE_LANGUAGE_DETECTION=1' \
+ '-D__STDC_CONSTANT_MACROS' \
+ '-D__STDC_FORMAT_MACROS' \
+ '-DANDROID' \
+ '-D__GNU_SOURCE=1' \
+ '-DUSE_STLPORT=1' \
+ '-D_STLP_USE_PTR_SPECIALIZATIONS=1' \
+ '-DCHROME_BUILD_ID=""' \
+ '-DDYNAMIC_ANNOTATIONS_ENABLED=1' \
+ '-DWTF_USE_DYNAMIC_ANNOTATIONS=1' \
+ '-D_DEBUG'
+
+LOCAL_CFLAGS := $(MY_CFLAGS_C) $(MY_CFLAGS) $(MY_DEFS)
+
+# Include paths placed before CFLAGS/CPPFLAGS
+LOCAL_C_INCLUDES := \
+ $(GYP_ABS_ANDROID_TOP_DIR)/frameworks/wilhelm/include \
+ $(GYP_ABS_ANDROID_TOP_DIR)/bionic \
+ $(GYP_ABS_ANDROID_TOP_DIR)/external/stlport/stlport
+
+LOCAL_C_INCLUDES := $(GYP_COPIED_SOURCE_ORIGIN_DIRS) $(LOCAL_C_INCLUDES)
+
+# Flags passed to only C++ (and not C) files.
+LOCAL_CPPFLAGS := \
+ -fno-rtti \
+ -fno-threadsafe-statics \
+ -fvisibility-inlines-hidden \
+ -Wsign-compare \
+ -Wno-abi \
+ -Wno-error=c++0x-compat \
+ -Wno-non-virtual-dtor \
+ -Wno-sign-promo
+
+### Rules for final target.
+# Add target alias to "gyp_all_modules" target.
+.PHONY: gyp_all_modules
+gyp_all_modules: base_base_java_activity_state_gyp
+
+# Alias gyp target name.
+.PHONY: base_java_activity_state
+base_java_activity_state: base_base_java_activity_state_gyp
+
+LOCAL_MODULE_PATH := $(PRODUCT_OUT)/gyp_stamp
+LOCAL_UNINSTALLABLE_MODULE := true
+
+include $(BUILD_SYSTEM)/base_rules.mk
+
+$(LOCAL_BUILT_MODULE): $(LOCAL_ADDITIONAL_DEPENDENCIES)
+ $(hide) echo "Gyp timestamp: $@"
+ $(hide) mkdir -p $(dir $@)
+ $(hide) touch $@
diff --git a/base/base_java_activity_state.target.linux-x86.mk b/base/base_java_activity_state.target.linux-x86.mk
new file mode 100644
index 0000000..34649dd
--- /dev/null
+++ b/base/base_java_activity_state.target.linux-x86.mk
@@ -0,0 +1,142 @@
+# This file is generated by gyp; do not edit.
+
+include $(CLEAR_VARS)
+
+LOCAL_MODULE_CLASS := GYP
+LOCAL_MODULE := base_base_java_activity_state_gyp
+LOCAL_MODULE_STEM := base_java_activity_state
+LOCAL_MODULE_SUFFIX := .stamp
+LOCAL_MODULE_TAGS := optional
+gyp_intermediate_dir := $(call local-intermediates-dir)
+gyp_shared_intermediate_dir := $(call intermediates-dir-for,GYP,shared)
+
+# Make sure our deps are built first.
+GYP_TARGET_DEPENDENCIES :=
+
+
+### Generated for rule "base_base_gyp_base_java_activity_state_target_generate_java_constants":
+# "{'inputs': ['../build/android/gyp/util/build_utils.py', '../build/android/gyp/gcc_preprocess.py', 'android/activity_state_list.h'], 'extension': 'template', 'outputs': ['$(gyp_shared_intermediate_dir)/templates/org/chromium/base/%(INPUT_ROOT)s.java'], 'variables': {'output_path': '$(gyp_shared_intermediate_dir)/templates/org/chromium/base/%(INPUT_ROOT)s.java'}, 'rule_name': 'generate_java_constants', 'rule_sources': ['android/java/src/org/chromium/base/ActivityState.template'], 'action': ['python', '../build/android/gyp/gcc_preprocess.py', '--include-path=..', '--output=$(gyp_shared_intermediate_dir)/templates/org/chromium/base/%(INPUT_ROOT)s.java', '--template=$(RULE_SOURCES)'], 'message': 'Generating Java from cpp template $(RULE_SOURCES)'}":
+$(gyp_shared_intermediate_dir)/templates/org/chromium/base/ActivityState.java: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/templates/org/chromium/base/ActivityState.java: gyp_intermediate_dir := $(GYP_ABS_ANDROID_TOP_DIR)/$(gyp_intermediate_dir)
+$(gyp_shared_intermediate_dir)/templates/org/chromium/base/ActivityState.java: gyp_shared_intermediate_dir := $(GYP_ABS_ANDROID_TOP_DIR)/$(gyp_shared_intermediate_dir)
+$(gyp_shared_intermediate_dir)/templates/org/chromium/base/ActivityState.java: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
+$(gyp_shared_intermediate_dir)/templates/org/chromium/base/ActivityState.java: $(LOCAL_PATH)/base/android/java/src/org/chromium/base/ActivityState.template $(LOCAL_PATH)/build/android/gyp/util/build_utils.py $(LOCAL_PATH)/build/android/gyp/gcc_preprocess.py $(LOCAL_PATH)/base/android/activity_state_list.h $(GYP_TARGET_DEPENDENCIES)
+ mkdir -p $(gyp_shared_intermediate_dir)/templates/org/chromium/base; cd $(gyp_local_path)/base; python ../build/android/gyp/gcc_preprocess.py "--include-path=.." "--output=$(gyp_shared_intermediate_dir)/templates/org/chromium/base/ActivityState.java" "--template=android/java/src/org/chromium/base/ActivityState.template"
+
+.PHONY: base_base_java_activity_state_gyp_rule_trigger
+base_base_java_activity_state_gyp_rule_trigger: $(gyp_shared_intermediate_dir)/templates/org/chromium/base/ActivityState.java
+
+### Finished generating for all rules
+
+GYP_GENERATED_OUTPUTS := \
+ $(gyp_shared_intermediate_dir)/templates/org/chromium/base/ActivityState.java
+
+# Make sure our deps and generated files are built first.
+LOCAL_ADDITIONAL_DEPENDENCIES := $(GYP_TARGET_DEPENDENCIES) $(GYP_GENERATED_OUTPUTS)
+
+LOCAL_GENERATED_SOURCES := \
+ base_base_java_activity_state_gyp_rule_trigger
+
+GYP_COPIED_SOURCE_ORIGIN_DIRS :=
+
+LOCAL_SRC_FILES :=
+
+
+# Flags passed to both C and C++ files.
+MY_CFLAGS := \
+ --param=ssp-buffer-size=4 \
+ -Werror \
+ -fno-exceptions \
+ -fno-strict-aliasing \
+ -Wall \
+ -Wno-unused-parameter \
+ -Wno-missing-field-initializers \
+ -fvisibility=hidden \
+ -pipe \
+ -fPIC \
+ -m32 \
+ -mmmx \
+ -march=pentium4 \
+ -msse2 \
+ -mfpmath=sse \
+ -fuse-ld=gold \
+ -ffunction-sections \
+ -funwind-tables \
+ -g \
+ -fno-short-enums \
+ -finline-limit=64 \
+ -Wa,--noexecstack \
+ -U_FORTIFY_SOURCE \
+ -Wno-extra \
+ -Wno-ignored-qualifiers \
+ -Wno-type-limits \
+ -fno-stack-protector \
+ -Os \
+ -g \
+ -fomit-frame-pointer \
+ -fdata-sections \
+ -ffunction-sections
+
+MY_CFLAGS_C :=
+
+MY_DEFS := \
+ '-D_FILE_OFFSET_BITS=64' \
+ '-DUSE_LINUX_BREAKPAD' \
+ '-DNO_TCMALLOC' \
+ '-DDISABLE_NACL' \
+ '-DCHROMIUM_BUILD' \
+ '-DUSE_LIBJPEG_TURBO=1' \
+ '-DUSE_PROPRIETARY_CODECS' \
+ '-DENABLE_GPU=1' \
+ '-DUSE_OPENSSL=1' \
+ '-DENABLE_EGLIMAGE=1' \
+ '-DENABLE_LANGUAGE_DETECTION=1' \
+ '-D__STDC_CONSTANT_MACROS' \
+ '-D__STDC_FORMAT_MACROS' \
+ '-DANDROID' \
+ '-D__GNU_SOURCE=1' \
+ '-DUSE_STLPORT=1' \
+ '-D_STLP_USE_PTR_SPECIALIZATIONS=1' \
+ '-DCHROME_BUILD_ID=""' \
+ '-DDYNAMIC_ANNOTATIONS_ENABLED=1' \
+ '-DWTF_USE_DYNAMIC_ANNOTATIONS=1' \
+ '-D_DEBUG'
+
+LOCAL_CFLAGS := $(MY_CFLAGS_C) $(MY_CFLAGS) $(MY_DEFS)
+
+# Include paths placed before CFLAGS/CPPFLAGS
+LOCAL_C_INCLUDES := \
+ $(GYP_ABS_ANDROID_TOP_DIR)/frameworks/wilhelm/include \
+ $(GYP_ABS_ANDROID_TOP_DIR)/bionic \
+ $(GYP_ABS_ANDROID_TOP_DIR)/external/stlport/stlport
+
+LOCAL_C_INCLUDES := $(GYP_COPIED_SOURCE_ORIGIN_DIRS) $(LOCAL_C_INCLUDES)
+
+# Flags passed to only C++ (and not C) files.
+LOCAL_CPPFLAGS := \
+ -fno-rtti \
+ -fno-threadsafe-statics \
+ -fvisibility-inlines-hidden \
+ -Wsign-compare \
+ -Wno-error=c++0x-compat \
+ -Wno-non-virtual-dtor \
+ -Wno-sign-promo
+
+### Rules for final target.
+# Add target alias to "gyp_all_modules" target.
+.PHONY: gyp_all_modules
+gyp_all_modules: base_base_java_activity_state_gyp
+
+# Alias gyp target name.
+.PHONY: base_java_activity_state
+base_java_activity_state: base_base_java_activity_state_gyp
+
+LOCAL_MODULE_PATH := $(PRODUCT_OUT)/gyp_stamp
+LOCAL_UNINSTALLABLE_MODULE := true
+
+include $(BUILD_SYSTEM)/base_rules.mk
+
+$(LOCAL_BUILT_MODULE): $(LOCAL_ADDITIONAL_DEPENDENCIES)
+ $(hide) echo "Gyp timestamp: $@"
+ $(hide) mkdir -p $(dir $@)
+ $(hide) touch $@
diff --git a/base/base_jni_headers.target.darwin-arm.mk b/base/base_jni_headers.target.darwin-arm.mk
new file mode 100644
index 0000000..74dde73
--- /dev/null
+++ b/base/base_jni_headers.target.darwin-arm.mk
@@ -0,0 +1,238 @@
+# This file is generated by gyp; do not edit.
+
+include $(CLEAR_VARS)
+
+LOCAL_MODULE_CLASS := GYP
+LOCAL_MODULE := base_base_jni_headers_gyp
+LOCAL_MODULE_STEM := base_jni_headers
+LOCAL_MODULE_SUFFIX := .stamp
+LOCAL_MODULE_TAGS := optional
+gyp_intermediate_dir := $(call local-intermediates-dir)
+gyp_shared_intermediate_dir := $(call intermediates-dir-for,GYP,shared)
+
+# Make sure our deps are built first.
+GYP_TARGET_DEPENDENCIES :=
+
+
+### Generated for rule "base_base_gyp_base_jni_headers_target_generate_jni_headers":
+# "{'inputs': ['../base/android/jni_generator/jni_generator.py'], 'process_outputs_as_sources': '1', 'extension': 'java', 'outputs': ['$(gyp_shared_intermediate_dir)/base/jni/%(INPUT_ROOT)s_jni.h'], 'rule_name': 'generate_jni_headers', 'rule_sources': ['android/java/src/org/chromium/base/ActivityStatus.java', 'android/java/src/org/chromium/base/BuildInfo.java', 'android/java/src/org/chromium/base/CpuFeatures.java', 'android/java/src/org/chromium/base/ImportantFileWriterAndroid.java', 'android/java/src/org/chromium/base/PathService.java', 'android/java/src/org/chromium/base/PathUtils.java', 'android/java/src/org/chromium/base/PowerMonitor.java', 'android/java/src/org/chromium/base/SystemMessageHandler.java', 'android/java/src/org/chromium/base/ThreadUtils.java'], 'action': ['../base/android/jni_generator/jni_generator.py', '--input_file', '$(RULE_SOURCES)', '--output_dir', '$(gyp_shared_intermediate_dir)/base/jni', '--optimize_generation', '0'], 'message': 'Generating JNI bindings from $(RULE_SOURCES)'}":
+$(gyp_shared_intermediate_dir)/base/jni/ActivityStatus_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/base/jni/ActivityStatus_jni.h: gyp_intermediate_dir := $(GYP_ABS_ANDROID_TOP_DIR)/$(gyp_intermediate_dir)
+$(gyp_shared_intermediate_dir)/base/jni/ActivityStatus_jni.h: gyp_shared_intermediate_dir := $(GYP_ABS_ANDROID_TOP_DIR)/$(gyp_shared_intermediate_dir)
+$(gyp_shared_intermediate_dir)/base/jni/ActivityStatus_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
+$(gyp_shared_intermediate_dir)/base/jni/ActivityStatus_jni.h: $(LOCAL_PATH)/base/android/java/src/org/chromium/base/ActivityStatus.java $(LOCAL_PATH)/base/android/jni_generator/jni_generator.py $(GYP_TARGET_DEPENDENCIES)
+ mkdir -p $(gyp_shared_intermediate_dir)/base/jni; cd $(gyp_local_path)/base; ../base/android/jni_generator/jni_generator.py --input_file android/java/src/org/chromium/base/ActivityStatus.java --output_dir "$(gyp_shared_intermediate_dir)/base/jni" --optimize_generation 0
+
+.PHONY: base_base_jni_headers_gyp_rule_trigger
+base_base_jni_headers_gyp_rule_trigger: $(gyp_shared_intermediate_dir)/base/jni/ActivityStatus_jni.h
+
+$(gyp_shared_intermediate_dir)/base/jni/BuildInfo_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/base/jni/BuildInfo_jni.h: gyp_intermediate_dir := $(GYP_ABS_ANDROID_TOP_DIR)/$(gyp_intermediate_dir)
+$(gyp_shared_intermediate_dir)/base/jni/BuildInfo_jni.h: gyp_shared_intermediate_dir := $(GYP_ABS_ANDROID_TOP_DIR)/$(gyp_shared_intermediate_dir)
+$(gyp_shared_intermediate_dir)/base/jni/BuildInfo_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
+$(gyp_shared_intermediate_dir)/base/jni/BuildInfo_jni.h: $(LOCAL_PATH)/base/android/java/src/org/chromium/base/BuildInfo.java $(LOCAL_PATH)/base/android/jni_generator/jni_generator.py $(GYP_TARGET_DEPENDENCIES)
+ mkdir -p $(gyp_shared_intermediate_dir)/base/jni; cd $(gyp_local_path)/base; ../base/android/jni_generator/jni_generator.py --input_file android/java/src/org/chromium/base/BuildInfo.java --output_dir "$(gyp_shared_intermediate_dir)/base/jni" --optimize_generation 0
+
+.PHONY: base_base_jni_headers_gyp_rule_trigger
+base_base_jni_headers_gyp_rule_trigger: $(gyp_shared_intermediate_dir)/base/jni/BuildInfo_jni.h
+
+$(gyp_shared_intermediate_dir)/base/jni/CpuFeatures_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/base/jni/CpuFeatures_jni.h: gyp_intermediate_dir := $(GYP_ABS_ANDROID_TOP_DIR)/$(gyp_intermediate_dir)
+$(gyp_shared_intermediate_dir)/base/jni/CpuFeatures_jni.h: gyp_shared_intermediate_dir := $(GYP_ABS_ANDROID_TOP_DIR)/$(gyp_shared_intermediate_dir)
+$(gyp_shared_intermediate_dir)/base/jni/CpuFeatures_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
+$(gyp_shared_intermediate_dir)/base/jni/CpuFeatures_jni.h: $(LOCAL_PATH)/base/android/java/src/org/chromium/base/CpuFeatures.java $(LOCAL_PATH)/base/android/jni_generator/jni_generator.py $(GYP_TARGET_DEPENDENCIES)
+ mkdir -p $(gyp_shared_intermediate_dir)/base/jni; cd $(gyp_local_path)/base; ../base/android/jni_generator/jni_generator.py --input_file android/java/src/org/chromium/base/CpuFeatures.java --output_dir "$(gyp_shared_intermediate_dir)/base/jni" --optimize_generation 0
+
+.PHONY: base_base_jni_headers_gyp_rule_trigger
+base_base_jni_headers_gyp_rule_trigger: $(gyp_shared_intermediate_dir)/base/jni/CpuFeatures_jni.h
+
+$(gyp_shared_intermediate_dir)/base/jni/ImportantFileWriterAndroid_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/base/jni/ImportantFileWriterAndroid_jni.h: gyp_intermediate_dir := $(GYP_ABS_ANDROID_TOP_DIR)/$(gyp_intermediate_dir)
+$(gyp_shared_intermediate_dir)/base/jni/ImportantFileWriterAndroid_jni.h: gyp_shared_intermediate_dir := $(GYP_ABS_ANDROID_TOP_DIR)/$(gyp_shared_intermediate_dir)
+$(gyp_shared_intermediate_dir)/base/jni/ImportantFileWriterAndroid_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
+$(gyp_shared_intermediate_dir)/base/jni/ImportantFileWriterAndroid_jni.h: $(LOCAL_PATH)/base/android/java/src/org/chromium/base/ImportantFileWriterAndroid.java $(LOCAL_PATH)/base/android/jni_generator/jni_generator.py $(GYP_TARGET_DEPENDENCIES)
+ mkdir -p $(gyp_shared_intermediate_dir)/base/jni; cd $(gyp_local_path)/base; ../base/android/jni_generator/jni_generator.py --input_file android/java/src/org/chromium/base/ImportantFileWriterAndroid.java --output_dir "$(gyp_shared_intermediate_dir)/base/jni" --optimize_generation 0
+
+.PHONY: base_base_jni_headers_gyp_rule_trigger
+base_base_jni_headers_gyp_rule_trigger: $(gyp_shared_intermediate_dir)/base/jni/ImportantFileWriterAndroid_jni.h
+
+$(gyp_shared_intermediate_dir)/base/jni/PathService_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/base/jni/PathService_jni.h: gyp_intermediate_dir := $(GYP_ABS_ANDROID_TOP_DIR)/$(gyp_intermediate_dir)
+$(gyp_shared_intermediate_dir)/base/jni/PathService_jni.h: gyp_shared_intermediate_dir := $(GYP_ABS_ANDROID_TOP_DIR)/$(gyp_shared_intermediate_dir)
+$(gyp_shared_intermediate_dir)/base/jni/PathService_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
+$(gyp_shared_intermediate_dir)/base/jni/PathService_jni.h: $(LOCAL_PATH)/base/android/java/src/org/chromium/base/PathService.java $(LOCAL_PATH)/base/android/jni_generator/jni_generator.py $(GYP_TARGET_DEPENDENCIES)
+ mkdir -p $(gyp_shared_intermediate_dir)/base/jni; cd $(gyp_local_path)/base; ../base/android/jni_generator/jni_generator.py --input_file android/java/src/org/chromium/base/PathService.java --output_dir "$(gyp_shared_intermediate_dir)/base/jni" --optimize_generation 0
+
+.PHONY: base_base_jni_headers_gyp_rule_trigger
+base_base_jni_headers_gyp_rule_trigger: $(gyp_shared_intermediate_dir)/base/jni/PathService_jni.h
+
+$(gyp_shared_intermediate_dir)/base/jni/PathUtils_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/base/jni/PathUtils_jni.h: gyp_intermediate_dir := $(GYP_ABS_ANDROID_TOP_DIR)/$(gyp_intermediate_dir)
+$(gyp_shared_intermediate_dir)/base/jni/PathUtils_jni.h: gyp_shared_intermediate_dir := $(GYP_ABS_ANDROID_TOP_DIR)/$(gyp_shared_intermediate_dir)
+$(gyp_shared_intermediate_dir)/base/jni/PathUtils_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
+$(gyp_shared_intermediate_dir)/base/jni/PathUtils_jni.h: $(LOCAL_PATH)/base/android/java/src/org/chromium/base/PathUtils.java $(LOCAL_PATH)/base/android/jni_generator/jni_generator.py $(GYP_TARGET_DEPENDENCIES)
+ mkdir -p $(gyp_shared_intermediate_dir)/base/jni; cd $(gyp_local_path)/base; ../base/android/jni_generator/jni_generator.py --input_file android/java/src/org/chromium/base/PathUtils.java --output_dir "$(gyp_shared_intermediate_dir)/base/jni" --optimize_generation 0
+
+.PHONY: base_base_jni_headers_gyp_rule_trigger
+base_base_jni_headers_gyp_rule_trigger: $(gyp_shared_intermediate_dir)/base/jni/PathUtils_jni.h
+
+$(gyp_shared_intermediate_dir)/base/jni/PowerMonitor_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/base/jni/PowerMonitor_jni.h: gyp_intermediate_dir := $(GYP_ABS_ANDROID_TOP_DIR)/$(gyp_intermediate_dir)
+$(gyp_shared_intermediate_dir)/base/jni/PowerMonitor_jni.h: gyp_shared_intermediate_dir := $(GYP_ABS_ANDROID_TOP_DIR)/$(gyp_shared_intermediate_dir)
+$(gyp_shared_intermediate_dir)/base/jni/PowerMonitor_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
+$(gyp_shared_intermediate_dir)/base/jni/PowerMonitor_jni.h: $(LOCAL_PATH)/base/android/java/src/org/chromium/base/PowerMonitor.java $(LOCAL_PATH)/base/android/jni_generator/jni_generator.py $(GYP_TARGET_DEPENDENCIES)
+ mkdir -p $(gyp_shared_intermediate_dir)/base/jni; cd $(gyp_local_path)/base; ../base/android/jni_generator/jni_generator.py --input_file android/java/src/org/chromium/base/PowerMonitor.java --output_dir "$(gyp_shared_intermediate_dir)/base/jni" --optimize_generation 0
+
+.PHONY: base_base_jni_headers_gyp_rule_trigger
+base_base_jni_headers_gyp_rule_trigger: $(gyp_shared_intermediate_dir)/base/jni/PowerMonitor_jni.h
+
+$(gyp_shared_intermediate_dir)/base/jni/SystemMessageHandler_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/base/jni/SystemMessageHandler_jni.h: gyp_intermediate_dir := $(GYP_ABS_ANDROID_TOP_DIR)/$(gyp_intermediate_dir)
+$(gyp_shared_intermediate_dir)/base/jni/SystemMessageHandler_jni.h: gyp_shared_intermediate_dir := $(GYP_ABS_ANDROID_TOP_DIR)/$(gyp_shared_intermediate_dir)
+$(gyp_shared_intermediate_dir)/base/jni/SystemMessageHandler_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
+$(gyp_shared_intermediate_dir)/base/jni/SystemMessageHandler_jni.h: $(LOCAL_PATH)/base/android/java/src/org/chromium/base/SystemMessageHandler.java $(LOCAL_PATH)/base/android/jni_generator/jni_generator.py $(GYP_TARGET_DEPENDENCIES)
+ mkdir -p $(gyp_shared_intermediate_dir)/base/jni; cd $(gyp_local_path)/base; ../base/android/jni_generator/jni_generator.py --input_file android/java/src/org/chromium/base/SystemMessageHandler.java --output_dir "$(gyp_shared_intermediate_dir)/base/jni" --optimize_generation 0
+
+.PHONY: base_base_jni_headers_gyp_rule_trigger
+base_base_jni_headers_gyp_rule_trigger: $(gyp_shared_intermediate_dir)/base/jni/SystemMessageHandler_jni.h
+
+$(gyp_shared_intermediate_dir)/base/jni/ThreadUtils_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/base/jni/ThreadUtils_jni.h: gyp_intermediate_dir := $(GYP_ABS_ANDROID_TOP_DIR)/$(gyp_intermediate_dir)
+$(gyp_shared_intermediate_dir)/base/jni/ThreadUtils_jni.h: gyp_shared_intermediate_dir := $(GYP_ABS_ANDROID_TOP_DIR)/$(gyp_shared_intermediate_dir)
+$(gyp_shared_intermediate_dir)/base/jni/ThreadUtils_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
+$(gyp_shared_intermediate_dir)/base/jni/ThreadUtils_jni.h: $(LOCAL_PATH)/base/android/java/src/org/chromium/base/ThreadUtils.java $(LOCAL_PATH)/base/android/jni_generator/jni_generator.py $(GYP_TARGET_DEPENDENCIES)
+ mkdir -p $(gyp_shared_intermediate_dir)/base/jni; cd $(gyp_local_path)/base; ../base/android/jni_generator/jni_generator.py --input_file android/java/src/org/chromium/base/ThreadUtils.java --output_dir "$(gyp_shared_intermediate_dir)/base/jni" --optimize_generation 0
+
+.PHONY: base_base_jni_headers_gyp_rule_trigger
+base_base_jni_headers_gyp_rule_trigger: $(gyp_shared_intermediate_dir)/base/jni/ThreadUtils_jni.h
+
+### Finished generating for all rules
+
+GYP_GENERATED_OUTPUTS := \
+ $(gyp_shared_intermediate_dir)/base/jni/ActivityStatus_jni.h \
+ $(gyp_shared_intermediate_dir)/base/jni/BuildInfo_jni.h \
+ $(gyp_shared_intermediate_dir)/base/jni/CpuFeatures_jni.h \
+ $(gyp_shared_intermediate_dir)/base/jni/ImportantFileWriterAndroid_jni.h \
+ $(gyp_shared_intermediate_dir)/base/jni/PathService_jni.h \
+ $(gyp_shared_intermediate_dir)/base/jni/PathUtils_jni.h \
+ $(gyp_shared_intermediate_dir)/base/jni/PowerMonitor_jni.h \
+ $(gyp_shared_intermediate_dir)/base/jni/SystemMessageHandler_jni.h \
+ $(gyp_shared_intermediate_dir)/base/jni/ThreadUtils_jni.h
+
+# Make sure our deps and generated files are built first.
+LOCAL_ADDITIONAL_DEPENDENCIES := $(GYP_TARGET_DEPENDENCIES) $(GYP_GENERATED_OUTPUTS)
+
+LOCAL_GENERATED_SOURCES := \
+ $(gyp_shared_intermediate_dir)/base/jni/ActivityStatus_jni.h \
+ $(gyp_shared_intermediate_dir)/base/jni/BuildInfo_jni.h \
+ $(gyp_shared_intermediate_dir)/base/jni/CpuFeatures_jni.h \
+ $(gyp_shared_intermediate_dir)/base/jni/ImportantFileWriterAndroid_jni.h \
+ $(gyp_shared_intermediate_dir)/base/jni/PathService_jni.h \
+ $(gyp_shared_intermediate_dir)/base/jni/PathUtils_jni.h \
+ $(gyp_shared_intermediate_dir)/base/jni/PowerMonitor_jni.h \
+ $(gyp_shared_intermediate_dir)/base/jni/SystemMessageHandler_jni.h \
+ $(gyp_shared_intermediate_dir)/base/jni/ThreadUtils_jni.h \
+ base_base_jni_headers_gyp_rule_trigger
+
+GYP_COPIED_SOURCE_ORIGIN_DIRS :=
+
+LOCAL_SRC_FILES :=
+
+
+# Flags passed to both C and C++ files.
+MY_CFLAGS := \
+ -fstack-protector \
+ --param=ssp-buffer-size=4 \
+ -Werror \
+ -fno-exceptions \
+ -fno-strict-aliasing \
+ -Wall \
+ -Wno-unused-parameter \
+ -Wno-missing-field-initializers \
+ -fvisibility=hidden \
+ -pipe \
+ -fPIC \
+ -fno-tree-sra \
+ -fuse-ld=gold \
+ -Wno-psabi \
+ -ffunction-sections \
+ -funwind-tables \
+ -g \
+ -fstack-protector \
+ -fno-short-enums \
+ -finline-limit=64 \
+ -Wa,--noexecstack \
+ -U_FORTIFY_SOURCE \
+ -Wno-extra \
+ -Wno-ignored-qualifiers \
+ -Wno-type-limits \
+ -Os \
+ -g \
+ -fomit-frame-pointer \
+ -fdata-sections \
+ -ffunction-sections
+
+MY_CFLAGS_C :=
+
+MY_DEFS := \
+ '-D_FILE_OFFSET_BITS=64' \
+ '-DUSE_LINUX_BREAKPAD' \
+ '-DNO_TCMALLOC' \
+ '-DDISABLE_NACL' \
+ '-DCHROMIUM_BUILD' \
+ '-DUSE_LIBJPEG_TURBO=1' \
+ '-DUSE_PROPRIETARY_CODECS' \
+ '-DENABLE_GPU=1' \
+ '-DUSE_OPENSSL=1' \
+ '-DENABLE_EGLIMAGE=1' \
+ '-DENABLE_LANGUAGE_DETECTION=1' \
+ '-D__STDC_CONSTANT_MACROS' \
+ '-D__STDC_FORMAT_MACROS' \
+ '-DANDROID' \
+ '-D__GNU_SOURCE=1' \
+ '-DUSE_STLPORT=1' \
+ '-D_STLP_USE_PTR_SPECIALIZATIONS=1' \
+ '-DCHROME_BUILD_ID=""' \
+ '-DDYNAMIC_ANNOTATIONS_ENABLED=1' \
+ '-DWTF_USE_DYNAMIC_ANNOTATIONS=1' \
+ '-D_DEBUG'
+
+LOCAL_CFLAGS := $(MY_CFLAGS_C) $(MY_CFLAGS) $(MY_DEFS)
+
+# Include paths placed before CFLAGS/CPPFLAGS
+LOCAL_C_INCLUDES := \
+ $(GYP_ABS_ANDROID_TOP_DIR)/frameworks/wilhelm/include \
+ $(GYP_ABS_ANDROID_TOP_DIR)/bionic \
+ $(GYP_ABS_ANDROID_TOP_DIR)/external/stlport/stlport
+
+LOCAL_C_INCLUDES := $(GYP_COPIED_SOURCE_ORIGIN_DIRS) $(LOCAL_C_INCLUDES)
+
+# Flags passed to only C++ (and not C) files.
+LOCAL_CPPFLAGS := \
+ -fno-rtti \
+ -fno-threadsafe-statics \
+ -fvisibility-inlines-hidden \
+ -Wsign-compare \
+ -Wno-abi \
+ -Wno-error=c++0x-compat \
+ -Wno-non-virtual-dtor \
+ -Wno-sign-promo
+
+### Rules for final target.
+# Add target alias to "gyp_all_modules" target.
+.PHONY: gyp_all_modules
+gyp_all_modules: base_base_jni_headers_gyp
+
+# Alias gyp target name.
+.PHONY: base_jni_headers
+base_jni_headers: base_base_jni_headers_gyp
+
+LOCAL_MODULE_PATH := $(PRODUCT_OUT)/gyp_stamp
+LOCAL_UNINSTALLABLE_MODULE := true
+
+include $(BUILD_SYSTEM)/base_rules.mk
+
+$(LOCAL_BUILT_MODULE): $(LOCAL_ADDITIONAL_DEPENDENCIES)
+ $(hide) echo "Gyp timestamp: $@"
+ $(hide) mkdir -p $(dir $@)
+ $(hide) touch $@
diff --git a/base/base_jni_headers.target.darwin-x86.mk b/base/base_jni_headers.target.darwin-x86.mk
new file mode 100644
index 0000000..77a542b
--- /dev/null
+++ b/base/base_jni_headers.target.darwin-x86.mk
@@ -0,0 +1,239 @@
+# This file is generated by gyp; do not edit.
+
+include $(CLEAR_VARS)
+
+LOCAL_MODULE_CLASS := GYP
+LOCAL_MODULE := base_base_jni_headers_gyp
+LOCAL_MODULE_STEM := base_jni_headers
+LOCAL_MODULE_SUFFIX := .stamp
+LOCAL_MODULE_TAGS := optional
+gyp_intermediate_dir := $(call local-intermediates-dir)
+gyp_shared_intermediate_dir := $(call intermediates-dir-for,GYP,shared)
+
+# Make sure our deps are built first.
+GYP_TARGET_DEPENDENCIES :=
+
+
+### Generated for rule "base_base_gyp_base_jni_headers_target_generate_jni_headers":
+# "{'inputs': ['../base/android/jni_generator/jni_generator.py'], 'process_outputs_as_sources': '1', 'extension': 'java', 'outputs': ['$(gyp_shared_intermediate_dir)/base/jni/%(INPUT_ROOT)s_jni.h'], 'rule_name': 'generate_jni_headers', 'rule_sources': ['android/java/src/org/chromium/base/ActivityStatus.java', 'android/java/src/org/chromium/base/BuildInfo.java', 'android/java/src/org/chromium/base/CpuFeatures.java', 'android/java/src/org/chromium/base/ImportantFileWriterAndroid.java', 'android/java/src/org/chromium/base/PathService.java', 'android/java/src/org/chromium/base/PathUtils.java', 'android/java/src/org/chromium/base/PowerMonitor.java', 'android/java/src/org/chromium/base/SystemMessageHandler.java', 'android/java/src/org/chromium/base/ThreadUtils.java'], 'action': ['../base/android/jni_generator/jni_generator.py', '--input_file', '$(RULE_SOURCES)', '--output_dir', '$(gyp_shared_intermediate_dir)/base/jni', '--optimize_generation', '0'], 'message': 'Generating JNI bindings from $(RULE_SOURCES)'}":
+$(gyp_shared_intermediate_dir)/base/jni/ActivityStatus_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/base/jni/ActivityStatus_jni.h: gyp_intermediate_dir := $(GYP_ABS_ANDROID_TOP_DIR)/$(gyp_intermediate_dir)
+$(gyp_shared_intermediate_dir)/base/jni/ActivityStatus_jni.h: gyp_shared_intermediate_dir := $(GYP_ABS_ANDROID_TOP_DIR)/$(gyp_shared_intermediate_dir)
+$(gyp_shared_intermediate_dir)/base/jni/ActivityStatus_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
+$(gyp_shared_intermediate_dir)/base/jni/ActivityStatus_jni.h: $(LOCAL_PATH)/base/android/java/src/org/chromium/base/ActivityStatus.java $(LOCAL_PATH)/base/android/jni_generator/jni_generator.py $(GYP_TARGET_DEPENDENCIES)
+ mkdir -p $(gyp_shared_intermediate_dir)/base/jni; cd $(gyp_local_path)/base; ../base/android/jni_generator/jni_generator.py --input_file android/java/src/org/chromium/base/ActivityStatus.java --output_dir "$(gyp_shared_intermediate_dir)/base/jni" --optimize_generation 0
+
+.PHONY: base_base_jni_headers_gyp_rule_trigger
+base_base_jni_headers_gyp_rule_trigger: $(gyp_shared_intermediate_dir)/base/jni/ActivityStatus_jni.h
+
+$(gyp_shared_intermediate_dir)/base/jni/BuildInfo_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/base/jni/BuildInfo_jni.h: gyp_intermediate_dir := $(GYP_ABS_ANDROID_TOP_DIR)/$(gyp_intermediate_dir)
+$(gyp_shared_intermediate_dir)/base/jni/BuildInfo_jni.h: gyp_shared_intermediate_dir := $(GYP_ABS_ANDROID_TOP_DIR)/$(gyp_shared_intermediate_dir)
+$(gyp_shared_intermediate_dir)/base/jni/BuildInfo_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
+$(gyp_shared_intermediate_dir)/base/jni/BuildInfo_jni.h: $(LOCAL_PATH)/base/android/java/src/org/chromium/base/BuildInfo.java $(LOCAL_PATH)/base/android/jni_generator/jni_generator.py $(GYP_TARGET_DEPENDENCIES)
+ mkdir -p $(gyp_shared_intermediate_dir)/base/jni; cd $(gyp_local_path)/base; ../base/android/jni_generator/jni_generator.py --input_file android/java/src/org/chromium/base/BuildInfo.java --output_dir "$(gyp_shared_intermediate_dir)/base/jni" --optimize_generation 0
+
+.PHONY: base_base_jni_headers_gyp_rule_trigger
+base_base_jni_headers_gyp_rule_trigger: $(gyp_shared_intermediate_dir)/base/jni/BuildInfo_jni.h
+
+$(gyp_shared_intermediate_dir)/base/jni/CpuFeatures_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/base/jni/CpuFeatures_jni.h: gyp_intermediate_dir := $(GYP_ABS_ANDROID_TOP_DIR)/$(gyp_intermediate_dir)
+$(gyp_shared_intermediate_dir)/base/jni/CpuFeatures_jni.h: gyp_shared_intermediate_dir := $(GYP_ABS_ANDROID_TOP_DIR)/$(gyp_shared_intermediate_dir)
+$(gyp_shared_intermediate_dir)/base/jni/CpuFeatures_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
+$(gyp_shared_intermediate_dir)/base/jni/CpuFeatures_jni.h: $(LOCAL_PATH)/base/android/java/src/org/chromium/base/CpuFeatures.java $(LOCAL_PATH)/base/android/jni_generator/jni_generator.py $(GYP_TARGET_DEPENDENCIES)
+ mkdir -p $(gyp_shared_intermediate_dir)/base/jni; cd $(gyp_local_path)/base; ../base/android/jni_generator/jni_generator.py --input_file android/java/src/org/chromium/base/CpuFeatures.java --output_dir "$(gyp_shared_intermediate_dir)/base/jni" --optimize_generation 0
+
+.PHONY: base_base_jni_headers_gyp_rule_trigger
+base_base_jni_headers_gyp_rule_trigger: $(gyp_shared_intermediate_dir)/base/jni/CpuFeatures_jni.h
+
+$(gyp_shared_intermediate_dir)/base/jni/ImportantFileWriterAndroid_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/base/jni/ImportantFileWriterAndroid_jni.h: gyp_intermediate_dir := $(GYP_ABS_ANDROID_TOP_DIR)/$(gyp_intermediate_dir)
+$(gyp_shared_intermediate_dir)/base/jni/ImportantFileWriterAndroid_jni.h: gyp_shared_intermediate_dir := $(GYP_ABS_ANDROID_TOP_DIR)/$(gyp_shared_intermediate_dir)
+$(gyp_shared_intermediate_dir)/base/jni/ImportantFileWriterAndroid_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
+$(gyp_shared_intermediate_dir)/base/jni/ImportantFileWriterAndroid_jni.h: $(LOCAL_PATH)/base/android/java/src/org/chromium/base/ImportantFileWriterAndroid.java $(LOCAL_PATH)/base/android/jni_generator/jni_generator.py $(GYP_TARGET_DEPENDENCIES)
+ mkdir -p $(gyp_shared_intermediate_dir)/base/jni; cd $(gyp_local_path)/base; ../base/android/jni_generator/jni_generator.py --input_file android/java/src/org/chromium/base/ImportantFileWriterAndroid.java --output_dir "$(gyp_shared_intermediate_dir)/base/jni" --optimize_generation 0
+
+.PHONY: base_base_jni_headers_gyp_rule_trigger
+base_base_jni_headers_gyp_rule_trigger: $(gyp_shared_intermediate_dir)/base/jni/ImportantFileWriterAndroid_jni.h
+
+$(gyp_shared_intermediate_dir)/base/jni/PathService_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/base/jni/PathService_jni.h: gyp_intermediate_dir := $(GYP_ABS_ANDROID_TOP_DIR)/$(gyp_intermediate_dir)
+$(gyp_shared_intermediate_dir)/base/jni/PathService_jni.h: gyp_shared_intermediate_dir := $(GYP_ABS_ANDROID_TOP_DIR)/$(gyp_shared_intermediate_dir)
+$(gyp_shared_intermediate_dir)/base/jni/PathService_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
+$(gyp_shared_intermediate_dir)/base/jni/PathService_jni.h: $(LOCAL_PATH)/base/android/java/src/org/chromium/base/PathService.java $(LOCAL_PATH)/base/android/jni_generator/jni_generator.py $(GYP_TARGET_DEPENDENCIES)
+ mkdir -p $(gyp_shared_intermediate_dir)/base/jni; cd $(gyp_local_path)/base; ../base/android/jni_generator/jni_generator.py --input_file android/java/src/org/chromium/base/PathService.java --output_dir "$(gyp_shared_intermediate_dir)/base/jni" --optimize_generation 0
+
+.PHONY: base_base_jni_headers_gyp_rule_trigger
+base_base_jni_headers_gyp_rule_trigger: $(gyp_shared_intermediate_dir)/base/jni/PathService_jni.h
+
+$(gyp_shared_intermediate_dir)/base/jni/PathUtils_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/base/jni/PathUtils_jni.h: gyp_intermediate_dir := $(GYP_ABS_ANDROID_TOP_DIR)/$(gyp_intermediate_dir)
+$(gyp_shared_intermediate_dir)/base/jni/PathUtils_jni.h: gyp_shared_intermediate_dir := $(GYP_ABS_ANDROID_TOP_DIR)/$(gyp_shared_intermediate_dir)
+$(gyp_shared_intermediate_dir)/base/jni/PathUtils_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
+$(gyp_shared_intermediate_dir)/base/jni/PathUtils_jni.h: $(LOCAL_PATH)/base/android/java/src/org/chromium/base/PathUtils.java $(LOCAL_PATH)/base/android/jni_generator/jni_generator.py $(GYP_TARGET_DEPENDENCIES)
+ mkdir -p $(gyp_shared_intermediate_dir)/base/jni; cd $(gyp_local_path)/base; ../base/android/jni_generator/jni_generator.py --input_file android/java/src/org/chromium/base/PathUtils.java --output_dir "$(gyp_shared_intermediate_dir)/base/jni" --optimize_generation 0
+
+.PHONY: base_base_jni_headers_gyp_rule_trigger
+base_base_jni_headers_gyp_rule_trigger: $(gyp_shared_intermediate_dir)/base/jni/PathUtils_jni.h
+
+$(gyp_shared_intermediate_dir)/base/jni/PowerMonitor_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/base/jni/PowerMonitor_jni.h: gyp_intermediate_dir := $(GYP_ABS_ANDROID_TOP_DIR)/$(gyp_intermediate_dir)
+$(gyp_shared_intermediate_dir)/base/jni/PowerMonitor_jni.h: gyp_shared_intermediate_dir := $(GYP_ABS_ANDROID_TOP_DIR)/$(gyp_shared_intermediate_dir)
+$(gyp_shared_intermediate_dir)/base/jni/PowerMonitor_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
+$(gyp_shared_intermediate_dir)/base/jni/PowerMonitor_jni.h: $(LOCAL_PATH)/base/android/java/src/org/chromium/base/PowerMonitor.java $(LOCAL_PATH)/base/android/jni_generator/jni_generator.py $(GYP_TARGET_DEPENDENCIES)
+ mkdir -p $(gyp_shared_intermediate_dir)/base/jni; cd $(gyp_local_path)/base; ../base/android/jni_generator/jni_generator.py --input_file android/java/src/org/chromium/base/PowerMonitor.java --output_dir "$(gyp_shared_intermediate_dir)/base/jni" --optimize_generation 0
+
+.PHONY: base_base_jni_headers_gyp_rule_trigger
+base_base_jni_headers_gyp_rule_trigger: $(gyp_shared_intermediate_dir)/base/jni/PowerMonitor_jni.h
+
+$(gyp_shared_intermediate_dir)/base/jni/SystemMessageHandler_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/base/jni/SystemMessageHandler_jni.h: gyp_intermediate_dir := $(GYP_ABS_ANDROID_TOP_DIR)/$(gyp_intermediate_dir)
+$(gyp_shared_intermediate_dir)/base/jni/SystemMessageHandler_jni.h: gyp_shared_intermediate_dir := $(GYP_ABS_ANDROID_TOP_DIR)/$(gyp_shared_intermediate_dir)
+$(gyp_shared_intermediate_dir)/base/jni/SystemMessageHandler_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
+$(gyp_shared_intermediate_dir)/base/jni/SystemMessageHandler_jni.h: $(LOCAL_PATH)/base/android/java/src/org/chromium/base/SystemMessageHandler.java $(LOCAL_PATH)/base/android/jni_generator/jni_generator.py $(GYP_TARGET_DEPENDENCIES)
+ mkdir -p $(gyp_shared_intermediate_dir)/base/jni; cd $(gyp_local_path)/base; ../base/android/jni_generator/jni_generator.py --input_file android/java/src/org/chromium/base/SystemMessageHandler.java --output_dir "$(gyp_shared_intermediate_dir)/base/jni" --optimize_generation 0
+
+.PHONY: base_base_jni_headers_gyp_rule_trigger
+base_base_jni_headers_gyp_rule_trigger: $(gyp_shared_intermediate_dir)/base/jni/SystemMessageHandler_jni.h
+
+$(gyp_shared_intermediate_dir)/base/jni/ThreadUtils_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/base/jni/ThreadUtils_jni.h: gyp_intermediate_dir := $(GYP_ABS_ANDROID_TOP_DIR)/$(gyp_intermediate_dir)
+$(gyp_shared_intermediate_dir)/base/jni/ThreadUtils_jni.h: gyp_shared_intermediate_dir := $(GYP_ABS_ANDROID_TOP_DIR)/$(gyp_shared_intermediate_dir)
+$(gyp_shared_intermediate_dir)/base/jni/ThreadUtils_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
+$(gyp_shared_intermediate_dir)/base/jni/ThreadUtils_jni.h: $(LOCAL_PATH)/base/android/java/src/org/chromium/base/ThreadUtils.java $(LOCAL_PATH)/base/android/jni_generator/jni_generator.py $(GYP_TARGET_DEPENDENCIES)
+ mkdir -p $(gyp_shared_intermediate_dir)/base/jni; cd $(gyp_local_path)/base; ../base/android/jni_generator/jni_generator.py --input_file android/java/src/org/chromium/base/ThreadUtils.java --output_dir "$(gyp_shared_intermediate_dir)/base/jni" --optimize_generation 0
+
+.PHONY: base_base_jni_headers_gyp_rule_trigger
+base_base_jni_headers_gyp_rule_trigger: $(gyp_shared_intermediate_dir)/base/jni/ThreadUtils_jni.h
+
+### Finished generating for all rules
+
+GYP_GENERATED_OUTPUTS := \
+ $(gyp_shared_intermediate_dir)/base/jni/ActivityStatus_jni.h \
+ $(gyp_shared_intermediate_dir)/base/jni/BuildInfo_jni.h \
+ $(gyp_shared_intermediate_dir)/base/jni/CpuFeatures_jni.h \
+ $(gyp_shared_intermediate_dir)/base/jni/ImportantFileWriterAndroid_jni.h \
+ $(gyp_shared_intermediate_dir)/base/jni/PathService_jni.h \
+ $(gyp_shared_intermediate_dir)/base/jni/PathUtils_jni.h \
+ $(gyp_shared_intermediate_dir)/base/jni/PowerMonitor_jni.h \
+ $(gyp_shared_intermediate_dir)/base/jni/SystemMessageHandler_jni.h \
+ $(gyp_shared_intermediate_dir)/base/jni/ThreadUtils_jni.h
+
+# Make sure our deps and generated files are built first.
+LOCAL_ADDITIONAL_DEPENDENCIES := $(GYP_TARGET_DEPENDENCIES) $(GYP_GENERATED_OUTPUTS)
+
+LOCAL_GENERATED_SOURCES := \
+ $(gyp_shared_intermediate_dir)/base/jni/ActivityStatus_jni.h \
+ $(gyp_shared_intermediate_dir)/base/jni/BuildInfo_jni.h \
+ $(gyp_shared_intermediate_dir)/base/jni/CpuFeatures_jni.h \
+ $(gyp_shared_intermediate_dir)/base/jni/ImportantFileWriterAndroid_jni.h \
+ $(gyp_shared_intermediate_dir)/base/jni/PathService_jni.h \
+ $(gyp_shared_intermediate_dir)/base/jni/PathUtils_jni.h \
+ $(gyp_shared_intermediate_dir)/base/jni/PowerMonitor_jni.h \
+ $(gyp_shared_intermediate_dir)/base/jni/SystemMessageHandler_jni.h \
+ $(gyp_shared_intermediate_dir)/base/jni/ThreadUtils_jni.h \
+ base_base_jni_headers_gyp_rule_trigger
+
+GYP_COPIED_SOURCE_ORIGIN_DIRS :=
+
+LOCAL_SRC_FILES :=
+
+
+# Flags passed to both C and C++ files.
+MY_CFLAGS := \
+ --param=ssp-buffer-size=4 \
+ -Werror \
+ -fno-exceptions \
+ -fno-strict-aliasing \
+ -Wall \
+ -Wno-unused-parameter \
+ -Wno-missing-field-initializers \
+ -fvisibility=hidden \
+ -pipe \
+ -fPIC \
+ -m32 \
+ -mmmx \
+ -march=pentium4 \
+ -msse2 \
+ -mfpmath=sse \
+ -fuse-ld=gold \
+ -ffunction-sections \
+ -funwind-tables \
+ -g \
+ -fno-short-enums \
+ -finline-limit=64 \
+ -Wa,--noexecstack \
+ -U_FORTIFY_SOURCE \
+ -Wno-extra \
+ -Wno-ignored-qualifiers \
+ -Wno-type-limits \
+ -fno-stack-protector \
+ -Os \
+ -g \
+ -fomit-frame-pointer \
+ -fdata-sections \
+ -ffunction-sections
+
+MY_CFLAGS_C :=
+
+MY_DEFS := \
+ '-D_FILE_OFFSET_BITS=64' \
+ '-DUSE_LINUX_BREAKPAD' \
+ '-DNO_TCMALLOC' \
+ '-DDISABLE_NACL' \
+ '-DCHROMIUM_BUILD' \
+ '-DUSE_LIBJPEG_TURBO=1' \
+ '-DUSE_PROPRIETARY_CODECS' \
+ '-DENABLE_GPU=1' \
+ '-DUSE_OPENSSL=1' \
+ '-DENABLE_EGLIMAGE=1' \
+ '-DENABLE_LANGUAGE_DETECTION=1' \
+ '-D__STDC_CONSTANT_MACROS' \
+ '-D__STDC_FORMAT_MACROS' \
+ '-DANDROID' \
+ '-D__GNU_SOURCE=1' \
+ '-DUSE_STLPORT=1' \
+ '-D_STLP_USE_PTR_SPECIALIZATIONS=1' \
+ '-DCHROME_BUILD_ID=""' \
+ '-DDYNAMIC_ANNOTATIONS_ENABLED=1' \
+ '-DWTF_USE_DYNAMIC_ANNOTATIONS=1' \
+ '-D_DEBUG'
+
+LOCAL_CFLAGS := $(MY_CFLAGS_C) $(MY_CFLAGS) $(MY_DEFS)
+
+# Include paths placed before CFLAGS/CPPFLAGS
+LOCAL_C_INCLUDES := \
+ $(GYP_ABS_ANDROID_TOP_DIR)/frameworks/wilhelm/include \
+ $(GYP_ABS_ANDROID_TOP_DIR)/bionic \
+ $(GYP_ABS_ANDROID_TOP_DIR)/external/stlport/stlport
+
+LOCAL_C_INCLUDES := $(GYP_COPIED_SOURCE_ORIGIN_DIRS) $(LOCAL_C_INCLUDES)
+
+# Flags passed to only C++ (and not C) files.
+LOCAL_CPPFLAGS := \
+ -fno-rtti \
+ -fno-threadsafe-statics \
+ -fvisibility-inlines-hidden \
+ -Wsign-compare \
+ -Wno-error=c++0x-compat \
+ -Wno-non-virtual-dtor \
+ -Wno-sign-promo
+
+### Rules for final target.
+# Add target alias to "gyp_all_modules" target.
+.PHONY: gyp_all_modules
+gyp_all_modules: base_base_jni_headers_gyp
+
+# Alias gyp target name.
+.PHONY: base_jni_headers
+base_jni_headers: base_base_jni_headers_gyp
+
+LOCAL_MODULE_PATH := $(PRODUCT_OUT)/gyp_stamp
+LOCAL_UNINSTALLABLE_MODULE := true
+
+include $(BUILD_SYSTEM)/base_rules.mk
+
+$(LOCAL_BUILT_MODULE): $(LOCAL_ADDITIONAL_DEPENDENCIES)
+ $(hide) echo "Gyp timestamp: $@"
+ $(hide) mkdir -p $(dir $@)
+ $(hide) touch $@
diff --git a/base/base_jni_headers.target.linux-arm.mk b/base/base_jni_headers.target.linux-arm.mk
index f219459..74dde73 100644
--- a/base/base_jni_headers.target.linux-arm.mk
+++ b/base/base_jni_headers.target.linux-arm.mk
@@ -15,7 +15,17 @@
### Generated for rule "base_base_gyp_base_jni_headers_target_generate_jni_headers":
-# "{'inputs': ['../base/android/jni_generator/jni_generator.py'], 'process_outputs_as_sources': '1', 'extension': 'java', 'outputs': ['$(gyp_shared_intermediate_dir)/base/jni/%(INPUT_ROOT)s_jni.h'], 'rule_name': 'generate_jni_headers', 'rule_sources': ['android/java/src/org/chromium/base/BuildInfo.java', 'android/java/src/org/chromium/base/CpuFeatures.java', 'android/java/src/org/chromium/base/ImportantFileWriterAndroid.java', 'android/java/src/org/chromium/base/LocaleUtils.java', 'android/java/src/org/chromium/base/PathService.java', 'android/java/src/org/chromium/base/PathUtils.java', 'android/java/src/org/chromium/base/SystemMessageHandler.java', 'android/java/src/org/chromium/base/SystemMonitor.java', 'android/java/src/org/chromium/base/ThreadUtils.java'], 'action': ['../base/android/jni_generator/jni_generator.py', '--input_file', '$(RULE_SOURCES)', '--output_dir', '$(gyp_shared_intermediate_dir)/base/jni', '--optimize_generation', '0'], 'message': 'Generating JNI bindings from $(RULE_SOURCES)'}":
+# "{'inputs': ['../base/android/jni_generator/jni_generator.py'], 'process_outputs_as_sources': '1', 'extension': 'java', 'outputs': ['$(gyp_shared_intermediate_dir)/base/jni/%(INPUT_ROOT)s_jni.h'], 'rule_name': 'generate_jni_headers', 'rule_sources': ['android/java/src/org/chromium/base/ActivityStatus.java', 'android/java/src/org/chromium/base/BuildInfo.java', 'android/java/src/org/chromium/base/CpuFeatures.java', 'android/java/src/org/chromium/base/ImportantFileWriterAndroid.java', 'android/java/src/org/chromium/base/PathService.java', 'android/java/src/org/chromium/base/PathUtils.java', 'android/java/src/org/chromium/base/PowerMonitor.java', 'android/java/src/org/chromium/base/SystemMessageHandler.java', 'android/java/src/org/chromium/base/ThreadUtils.java'], 'action': ['../base/android/jni_generator/jni_generator.py', '--input_file', '$(RULE_SOURCES)', '--output_dir', '$(gyp_shared_intermediate_dir)/base/jni', '--optimize_generation', '0'], 'message': 'Generating JNI bindings from $(RULE_SOURCES)'}":
+$(gyp_shared_intermediate_dir)/base/jni/ActivityStatus_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/base/jni/ActivityStatus_jni.h: gyp_intermediate_dir := $(GYP_ABS_ANDROID_TOP_DIR)/$(gyp_intermediate_dir)
+$(gyp_shared_intermediate_dir)/base/jni/ActivityStatus_jni.h: gyp_shared_intermediate_dir := $(GYP_ABS_ANDROID_TOP_DIR)/$(gyp_shared_intermediate_dir)
+$(gyp_shared_intermediate_dir)/base/jni/ActivityStatus_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
+$(gyp_shared_intermediate_dir)/base/jni/ActivityStatus_jni.h: $(LOCAL_PATH)/base/android/java/src/org/chromium/base/ActivityStatus.java $(LOCAL_PATH)/base/android/jni_generator/jni_generator.py $(GYP_TARGET_DEPENDENCIES)
+ mkdir -p $(gyp_shared_intermediate_dir)/base/jni; cd $(gyp_local_path)/base; ../base/android/jni_generator/jni_generator.py --input_file android/java/src/org/chromium/base/ActivityStatus.java --output_dir "$(gyp_shared_intermediate_dir)/base/jni" --optimize_generation 0
+
+.PHONY: base_base_jni_headers_gyp_rule_trigger
+base_base_jni_headers_gyp_rule_trigger: $(gyp_shared_intermediate_dir)/base/jni/ActivityStatus_jni.h
+
$(gyp_shared_intermediate_dir)/base/jni/BuildInfo_jni.h: gyp_local_path := $(LOCAL_PATH)
$(gyp_shared_intermediate_dir)/base/jni/BuildInfo_jni.h: gyp_intermediate_dir := $(GYP_ABS_ANDROID_TOP_DIR)/$(gyp_intermediate_dir)
$(gyp_shared_intermediate_dir)/base/jni/BuildInfo_jni.h: gyp_shared_intermediate_dir := $(GYP_ABS_ANDROID_TOP_DIR)/$(gyp_shared_intermediate_dir)
@@ -46,16 +56,6 @@
.PHONY: base_base_jni_headers_gyp_rule_trigger
base_base_jni_headers_gyp_rule_trigger: $(gyp_shared_intermediate_dir)/base/jni/ImportantFileWriterAndroid_jni.h
-$(gyp_shared_intermediate_dir)/base/jni/LocaleUtils_jni.h: gyp_local_path := $(LOCAL_PATH)
-$(gyp_shared_intermediate_dir)/base/jni/LocaleUtils_jni.h: gyp_intermediate_dir := $(GYP_ABS_ANDROID_TOP_DIR)/$(gyp_intermediate_dir)
-$(gyp_shared_intermediate_dir)/base/jni/LocaleUtils_jni.h: gyp_shared_intermediate_dir := $(GYP_ABS_ANDROID_TOP_DIR)/$(gyp_shared_intermediate_dir)
-$(gyp_shared_intermediate_dir)/base/jni/LocaleUtils_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
-$(gyp_shared_intermediate_dir)/base/jni/LocaleUtils_jni.h: $(LOCAL_PATH)/base/android/java/src/org/chromium/base/LocaleUtils.java $(LOCAL_PATH)/base/android/jni_generator/jni_generator.py $(GYP_TARGET_DEPENDENCIES)
- mkdir -p $(gyp_shared_intermediate_dir)/base/jni; cd $(gyp_local_path)/base; ../base/android/jni_generator/jni_generator.py --input_file android/java/src/org/chromium/base/LocaleUtils.java --output_dir "$(gyp_shared_intermediate_dir)/base/jni" --optimize_generation 0
-
-.PHONY: base_base_jni_headers_gyp_rule_trigger
-base_base_jni_headers_gyp_rule_trigger: $(gyp_shared_intermediate_dir)/base/jni/LocaleUtils_jni.h
-
$(gyp_shared_intermediate_dir)/base/jni/PathService_jni.h: gyp_local_path := $(LOCAL_PATH)
$(gyp_shared_intermediate_dir)/base/jni/PathService_jni.h: gyp_intermediate_dir := $(GYP_ABS_ANDROID_TOP_DIR)/$(gyp_intermediate_dir)
$(gyp_shared_intermediate_dir)/base/jni/PathService_jni.h: gyp_shared_intermediate_dir := $(GYP_ABS_ANDROID_TOP_DIR)/$(gyp_shared_intermediate_dir)
@@ -76,6 +76,16 @@
.PHONY: base_base_jni_headers_gyp_rule_trigger
base_base_jni_headers_gyp_rule_trigger: $(gyp_shared_intermediate_dir)/base/jni/PathUtils_jni.h
+$(gyp_shared_intermediate_dir)/base/jni/PowerMonitor_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/base/jni/PowerMonitor_jni.h: gyp_intermediate_dir := $(GYP_ABS_ANDROID_TOP_DIR)/$(gyp_intermediate_dir)
+$(gyp_shared_intermediate_dir)/base/jni/PowerMonitor_jni.h: gyp_shared_intermediate_dir := $(GYP_ABS_ANDROID_TOP_DIR)/$(gyp_shared_intermediate_dir)
+$(gyp_shared_intermediate_dir)/base/jni/PowerMonitor_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
+$(gyp_shared_intermediate_dir)/base/jni/PowerMonitor_jni.h: $(LOCAL_PATH)/base/android/java/src/org/chromium/base/PowerMonitor.java $(LOCAL_PATH)/base/android/jni_generator/jni_generator.py $(GYP_TARGET_DEPENDENCIES)
+ mkdir -p $(gyp_shared_intermediate_dir)/base/jni; cd $(gyp_local_path)/base; ../base/android/jni_generator/jni_generator.py --input_file android/java/src/org/chromium/base/PowerMonitor.java --output_dir "$(gyp_shared_intermediate_dir)/base/jni" --optimize_generation 0
+
+.PHONY: base_base_jni_headers_gyp_rule_trigger
+base_base_jni_headers_gyp_rule_trigger: $(gyp_shared_intermediate_dir)/base/jni/PowerMonitor_jni.h
+
$(gyp_shared_intermediate_dir)/base/jni/SystemMessageHandler_jni.h: gyp_local_path := $(LOCAL_PATH)
$(gyp_shared_intermediate_dir)/base/jni/SystemMessageHandler_jni.h: gyp_intermediate_dir := $(GYP_ABS_ANDROID_TOP_DIR)/$(gyp_intermediate_dir)
$(gyp_shared_intermediate_dir)/base/jni/SystemMessageHandler_jni.h: gyp_shared_intermediate_dir := $(GYP_ABS_ANDROID_TOP_DIR)/$(gyp_shared_intermediate_dir)
@@ -86,16 +96,6 @@
.PHONY: base_base_jni_headers_gyp_rule_trigger
base_base_jni_headers_gyp_rule_trigger: $(gyp_shared_intermediate_dir)/base/jni/SystemMessageHandler_jni.h
-$(gyp_shared_intermediate_dir)/base/jni/SystemMonitor_jni.h: gyp_local_path := $(LOCAL_PATH)
-$(gyp_shared_intermediate_dir)/base/jni/SystemMonitor_jni.h: gyp_intermediate_dir := $(GYP_ABS_ANDROID_TOP_DIR)/$(gyp_intermediate_dir)
-$(gyp_shared_intermediate_dir)/base/jni/SystemMonitor_jni.h: gyp_shared_intermediate_dir := $(GYP_ABS_ANDROID_TOP_DIR)/$(gyp_shared_intermediate_dir)
-$(gyp_shared_intermediate_dir)/base/jni/SystemMonitor_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
-$(gyp_shared_intermediate_dir)/base/jni/SystemMonitor_jni.h: $(LOCAL_PATH)/base/android/java/src/org/chromium/base/SystemMonitor.java $(LOCAL_PATH)/base/android/jni_generator/jni_generator.py $(GYP_TARGET_DEPENDENCIES)
- mkdir -p $(gyp_shared_intermediate_dir)/base/jni; cd $(gyp_local_path)/base; ../base/android/jni_generator/jni_generator.py --input_file android/java/src/org/chromium/base/SystemMonitor.java --output_dir "$(gyp_shared_intermediate_dir)/base/jni" --optimize_generation 0
-
-.PHONY: base_base_jni_headers_gyp_rule_trigger
-base_base_jni_headers_gyp_rule_trigger: $(gyp_shared_intermediate_dir)/base/jni/SystemMonitor_jni.h
-
$(gyp_shared_intermediate_dir)/base/jni/ThreadUtils_jni.h: gyp_local_path := $(LOCAL_PATH)
$(gyp_shared_intermediate_dir)/base/jni/ThreadUtils_jni.h: gyp_intermediate_dir := $(GYP_ABS_ANDROID_TOP_DIR)/$(gyp_intermediate_dir)
$(gyp_shared_intermediate_dir)/base/jni/ThreadUtils_jni.h: gyp_shared_intermediate_dir := $(GYP_ABS_ANDROID_TOP_DIR)/$(gyp_shared_intermediate_dir)
@@ -109,28 +109,28 @@
### Finished generating for all rules
GYP_GENERATED_OUTPUTS := \
+ $(gyp_shared_intermediate_dir)/base/jni/ActivityStatus_jni.h \
$(gyp_shared_intermediate_dir)/base/jni/BuildInfo_jni.h \
$(gyp_shared_intermediate_dir)/base/jni/CpuFeatures_jni.h \
$(gyp_shared_intermediate_dir)/base/jni/ImportantFileWriterAndroid_jni.h \
- $(gyp_shared_intermediate_dir)/base/jni/LocaleUtils_jni.h \
$(gyp_shared_intermediate_dir)/base/jni/PathService_jni.h \
$(gyp_shared_intermediate_dir)/base/jni/PathUtils_jni.h \
+ $(gyp_shared_intermediate_dir)/base/jni/PowerMonitor_jni.h \
$(gyp_shared_intermediate_dir)/base/jni/SystemMessageHandler_jni.h \
- $(gyp_shared_intermediate_dir)/base/jni/SystemMonitor_jni.h \
$(gyp_shared_intermediate_dir)/base/jni/ThreadUtils_jni.h
# Make sure our deps and generated files are built first.
LOCAL_ADDITIONAL_DEPENDENCIES := $(GYP_TARGET_DEPENDENCIES) $(GYP_GENERATED_OUTPUTS)
LOCAL_GENERATED_SOURCES := \
+ $(gyp_shared_intermediate_dir)/base/jni/ActivityStatus_jni.h \
$(gyp_shared_intermediate_dir)/base/jni/BuildInfo_jni.h \
$(gyp_shared_intermediate_dir)/base/jni/CpuFeatures_jni.h \
$(gyp_shared_intermediate_dir)/base/jni/ImportantFileWriterAndroid_jni.h \
- $(gyp_shared_intermediate_dir)/base/jni/LocaleUtils_jni.h \
$(gyp_shared_intermediate_dir)/base/jni/PathService_jni.h \
$(gyp_shared_intermediate_dir)/base/jni/PathUtils_jni.h \
+ $(gyp_shared_intermediate_dir)/base/jni/PowerMonitor_jni.h \
$(gyp_shared_intermediate_dir)/base/jni/SystemMessageHandler_jni.h \
- $(gyp_shared_intermediate_dir)/base/jni/SystemMonitor_jni.h \
$(gyp_shared_intermediate_dir)/base/jni/ThreadUtils_jni.h \
base_base_jni_headers_gyp_rule_trigger
@@ -175,7 +175,6 @@
MY_CFLAGS_C :=
MY_DEFS := \
- '-DUSE_SKIA' \
'-D_FILE_OFFSET_BITS=64' \
'-DUSE_LINUX_BREAKPAD' \
'-DNO_TCMALLOC' \
@@ -183,7 +182,6 @@
'-DCHROMIUM_BUILD' \
'-DUSE_LIBJPEG_TURBO=1' \
'-DUSE_PROPRIETARY_CODECS' \
- '-DENABLE_PEPPER_THREADING' \
'-DENABLE_GPU=1' \
'-DUSE_OPENSSL=1' \
'-DENABLE_EGLIMAGE=1' \
diff --git a/base/base_jni_headers.target.linux-x86.mk b/base/base_jni_headers.target.linux-x86.mk
index b64fd13..77a542b 100644
--- a/base/base_jni_headers.target.linux-x86.mk
+++ b/base/base_jni_headers.target.linux-x86.mk
@@ -15,7 +15,17 @@
### Generated for rule "base_base_gyp_base_jni_headers_target_generate_jni_headers":
-# "{'inputs': ['../base/android/jni_generator/jni_generator.py'], 'process_outputs_as_sources': '1', 'extension': 'java', 'outputs': ['$(gyp_shared_intermediate_dir)/base/jni/%(INPUT_ROOT)s_jni.h'], 'rule_name': 'generate_jni_headers', 'rule_sources': ['android/java/src/org/chromium/base/BuildInfo.java', 'android/java/src/org/chromium/base/CpuFeatures.java', 'android/java/src/org/chromium/base/ImportantFileWriterAndroid.java', 'android/java/src/org/chromium/base/LocaleUtils.java', 'android/java/src/org/chromium/base/PathService.java', 'android/java/src/org/chromium/base/PathUtils.java', 'android/java/src/org/chromium/base/SystemMessageHandler.java', 'android/java/src/org/chromium/base/SystemMonitor.java', 'android/java/src/org/chromium/base/ThreadUtils.java'], 'action': ['../base/android/jni_generator/jni_generator.py', '--input_file', '$(RULE_SOURCES)', '--output_dir', '$(gyp_shared_intermediate_dir)/base/jni', '--optimize_generation', '0'], 'message': 'Generating JNI bindings from $(RULE_SOURCES)'}":
+# "{'inputs': ['../base/android/jni_generator/jni_generator.py'], 'process_outputs_as_sources': '1', 'extension': 'java', 'outputs': ['$(gyp_shared_intermediate_dir)/base/jni/%(INPUT_ROOT)s_jni.h'], 'rule_name': 'generate_jni_headers', 'rule_sources': ['android/java/src/org/chromium/base/ActivityStatus.java', 'android/java/src/org/chromium/base/BuildInfo.java', 'android/java/src/org/chromium/base/CpuFeatures.java', 'android/java/src/org/chromium/base/ImportantFileWriterAndroid.java', 'android/java/src/org/chromium/base/PathService.java', 'android/java/src/org/chromium/base/PathUtils.java', 'android/java/src/org/chromium/base/PowerMonitor.java', 'android/java/src/org/chromium/base/SystemMessageHandler.java', 'android/java/src/org/chromium/base/ThreadUtils.java'], 'action': ['../base/android/jni_generator/jni_generator.py', '--input_file', '$(RULE_SOURCES)', '--output_dir', '$(gyp_shared_intermediate_dir)/base/jni', '--optimize_generation', '0'], 'message': 'Generating JNI bindings from $(RULE_SOURCES)'}":
+$(gyp_shared_intermediate_dir)/base/jni/ActivityStatus_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/base/jni/ActivityStatus_jni.h: gyp_intermediate_dir := $(GYP_ABS_ANDROID_TOP_DIR)/$(gyp_intermediate_dir)
+$(gyp_shared_intermediate_dir)/base/jni/ActivityStatus_jni.h: gyp_shared_intermediate_dir := $(GYP_ABS_ANDROID_TOP_DIR)/$(gyp_shared_intermediate_dir)
+$(gyp_shared_intermediate_dir)/base/jni/ActivityStatus_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
+$(gyp_shared_intermediate_dir)/base/jni/ActivityStatus_jni.h: $(LOCAL_PATH)/base/android/java/src/org/chromium/base/ActivityStatus.java $(LOCAL_PATH)/base/android/jni_generator/jni_generator.py $(GYP_TARGET_DEPENDENCIES)
+ mkdir -p $(gyp_shared_intermediate_dir)/base/jni; cd $(gyp_local_path)/base; ../base/android/jni_generator/jni_generator.py --input_file android/java/src/org/chromium/base/ActivityStatus.java --output_dir "$(gyp_shared_intermediate_dir)/base/jni" --optimize_generation 0
+
+.PHONY: base_base_jni_headers_gyp_rule_trigger
+base_base_jni_headers_gyp_rule_trigger: $(gyp_shared_intermediate_dir)/base/jni/ActivityStatus_jni.h
+
$(gyp_shared_intermediate_dir)/base/jni/BuildInfo_jni.h: gyp_local_path := $(LOCAL_PATH)
$(gyp_shared_intermediate_dir)/base/jni/BuildInfo_jni.h: gyp_intermediate_dir := $(GYP_ABS_ANDROID_TOP_DIR)/$(gyp_intermediate_dir)
$(gyp_shared_intermediate_dir)/base/jni/BuildInfo_jni.h: gyp_shared_intermediate_dir := $(GYP_ABS_ANDROID_TOP_DIR)/$(gyp_shared_intermediate_dir)
@@ -46,16 +56,6 @@
.PHONY: base_base_jni_headers_gyp_rule_trigger
base_base_jni_headers_gyp_rule_trigger: $(gyp_shared_intermediate_dir)/base/jni/ImportantFileWriterAndroid_jni.h
-$(gyp_shared_intermediate_dir)/base/jni/LocaleUtils_jni.h: gyp_local_path := $(LOCAL_PATH)
-$(gyp_shared_intermediate_dir)/base/jni/LocaleUtils_jni.h: gyp_intermediate_dir := $(GYP_ABS_ANDROID_TOP_DIR)/$(gyp_intermediate_dir)
-$(gyp_shared_intermediate_dir)/base/jni/LocaleUtils_jni.h: gyp_shared_intermediate_dir := $(GYP_ABS_ANDROID_TOP_DIR)/$(gyp_shared_intermediate_dir)
-$(gyp_shared_intermediate_dir)/base/jni/LocaleUtils_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
-$(gyp_shared_intermediate_dir)/base/jni/LocaleUtils_jni.h: $(LOCAL_PATH)/base/android/java/src/org/chromium/base/LocaleUtils.java $(LOCAL_PATH)/base/android/jni_generator/jni_generator.py $(GYP_TARGET_DEPENDENCIES)
- mkdir -p $(gyp_shared_intermediate_dir)/base/jni; cd $(gyp_local_path)/base; ../base/android/jni_generator/jni_generator.py --input_file android/java/src/org/chromium/base/LocaleUtils.java --output_dir "$(gyp_shared_intermediate_dir)/base/jni" --optimize_generation 0
-
-.PHONY: base_base_jni_headers_gyp_rule_trigger
-base_base_jni_headers_gyp_rule_trigger: $(gyp_shared_intermediate_dir)/base/jni/LocaleUtils_jni.h
-
$(gyp_shared_intermediate_dir)/base/jni/PathService_jni.h: gyp_local_path := $(LOCAL_PATH)
$(gyp_shared_intermediate_dir)/base/jni/PathService_jni.h: gyp_intermediate_dir := $(GYP_ABS_ANDROID_TOP_DIR)/$(gyp_intermediate_dir)
$(gyp_shared_intermediate_dir)/base/jni/PathService_jni.h: gyp_shared_intermediate_dir := $(GYP_ABS_ANDROID_TOP_DIR)/$(gyp_shared_intermediate_dir)
@@ -76,6 +76,16 @@
.PHONY: base_base_jni_headers_gyp_rule_trigger
base_base_jni_headers_gyp_rule_trigger: $(gyp_shared_intermediate_dir)/base/jni/PathUtils_jni.h
+$(gyp_shared_intermediate_dir)/base/jni/PowerMonitor_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/base/jni/PowerMonitor_jni.h: gyp_intermediate_dir := $(GYP_ABS_ANDROID_TOP_DIR)/$(gyp_intermediate_dir)
+$(gyp_shared_intermediate_dir)/base/jni/PowerMonitor_jni.h: gyp_shared_intermediate_dir := $(GYP_ABS_ANDROID_TOP_DIR)/$(gyp_shared_intermediate_dir)
+$(gyp_shared_intermediate_dir)/base/jni/PowerMonitor_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
+$(gyp_shared_intermediate_dir)/base/jni/PowerMonitor_jni.h: $(LOCAL_PATH)/base/android/java/src/org/chromium/base/PowerMonitor.java $(LOCAL_PATH)/base/android/jni_generator/jni_generator.py $(GYP_TARGET_DEPENDENCIES)
+ mkdir -p $(gyp_shared_intermediate_dir)/base/jni; cd $(gyp_local_path)/base; ../base/android/jni_generator/jni_generator.py --input_file android/java/src/org/chromium/base/PowerMonitor.java --output_dir "$(gyp_shared_intermediate_dir)/base/jni" --optimize_generation 0
+
+.PHONY: base_base_jni_headers_gyp_rule_trigger
+base_base_jni_headers_gyp_rule_trigger: $(gyp_shared_intermediate_dir)/base/jni/PowerMonitor_jni.h
+
$(gyp_shared_intermediate_dir)/base/jni/SystemMessageHandler_jni.h: gyp_local_path := $(LOCAL_PATH)
$(gyp_shared_intermediate_dir)/base/jni/SystemMessageHandler_jni.h: gyp_intermediate_dir := $(GYP_ABS_ANDROID_TOP_DIR)/$(gyp_intermediate_dir)
$(gyp_shared_intermediate_dir)/base/jni/SystemMessageHandler_jni.h: gyp_shared_intermediate_dir := $(GYP_ABS_ANDROID_TOP_DIR)/$(gyp_shared_intermediate_dir)
@@ -86,16 +96,6 @@
.PHONY: base_base_jni_headers_gyp_rule_trigger
base_base_jni_headers_gyp_rule_trigger: $(gyp_shared_intermediate_dir)/base/jni/SystemMessageHandler_jni.h
-$(gyp_shared_intermediate_dir)/base/jni/SystemMonitor_jni.h: gyp_local_path := $(LOCAL_PATH)
-$(gyp_shared_intermediate_dir)/base/jni/SystemMonitor_jni.h: gyp_intermediate_dir := $(GYP_ABS_ANDROID_TOP_DIR)/$(gyp_intermediate_dir)
-$(gyp_shared_intermediate_dir)/base/jni/SystemMonitor_jni.h: gyp_shared_intermediate_dir := $(GYP_ABS_ANDROID_TOP_DIR)/$(gyp_shared_intermediate_dir)
-$(gyp_shared_intermediate_dir)/base/jni/SystemMonitor_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
-$(gyp_shared_intermediate_dir)/base/jni/SystemMonitor_jni.h: $(LOCAL_PATH)/base/android/java/src/org/chromium/base/SystemMonitor.java $(LOCAL_PATH)/base/android/jni_generator/jni_generator.py $(GYP_TARGET_DEPENDENCIES)
- mkdir -p $(gyp_shared_intermediate_dir)/base/jni; cd $(gyp_local_path)/base; ../base/android/jni_generator/jni_generator.py --input_file android/java/src/org/chromium/base/SystemMonitor.java --output_dir "$(gyp_shared_intermediate_dir)/base/jni" --optimize_generation 0
-
-.PHONY: base_base_jni_headers_gyp_rule_trigger
-base_base_jni_headers_gyp_rule_trigger: $(gyp_shared_intermediate_dir)/base/jni/SystemMonitor_jni.h
-
$(gyp_shared_intermediate_dir)/base/jni/ThreadUtils_jni.h: gyp_local_path := $(LOCAL_PATH)
$(gyp_shared_intermediate_dir)/base/jni/ThreadUtils_jni.h: gyp_intermediate_dir := $(GYP_ABS_ANDROID_TOP_DIR)/$(gyp_intermediate_dir)
$(gyp_shared_intermediate_dir)/base/jni/ThreadUtils_jni.h: gyp_shared_intermediate_dir := $(GYP_ABS_ANDROID_TOP_DIR)/$(gyp_shared_intermediate_dir)
@@ -109,28 +109,28 @@
### Finished generating for all rules
GYP_GENERATED_OUTPUTS := \
+ $(gyp_shared_intermediate_dir)/base/jni/ActivityStatus_jni.h \
$(gyp_shared_intermediate_dir)/base/jni/BuildInfo_jni.h \
$(gyp_shared_intermediate_dir)/base/jni/CpuFeatures_jni.h \
$(gyp_shared_intermediate_dir)/base/jni/ImportantFileWriterAndroid_jni.h \
- $(gyp_shared_intermediate_dir)/base/jni/LocaleUtils_jni.h \
$(gyp_shared_intermediate_dir)/base/jni/PathService_jni.h \
$(gyp_shared_intermediate_dir)/base/jni/PathUtils_jni.h \
+ $(gyp_shared_intermediate_dir)/base/jni/PowerMonitor_jni.h \
$(gyp_shared_intermediate_dir)/base/jni/SystemMessageHandler_jni.h \
- $(gyp_shared_intermediate_dir)/base/jni/SystemMonitor_jni.h \
$(gyp_shared_intermediate_dir)/base/jni/ThreadUtils_jni.h
# Make sure our deps and generated files are built first.
LOCAL_ADDITIONAL_DEPENDENCIES := $(GYP_TARGET_DEPENDENCIES) $(GYP_GENERATED_OUTPUTS)
LOCAL_GENERATED_SOURCES := \
+ $(gyp_shared_intermediate_dir)/base/jni/ActivityStatus_jni.h \
$(gyp_shared_intermediate_dir)/base/jni/BuildInfo_jni.h \
$(gyp_shared_intermediate_dir)/base/jni/CpuFeatures_jni.h \
$(gyp_shared_intermediate_dir)/base/jni/ImportantFileWriterAndroid_jni.h \
- $(gyp_shared_intermediate_dir)/base/jni/LocaleUtils_jni.h \
$(gyp_shared_intermediate_dir)/base/jni/PathService_jni.h \
$(gyp_shared_intermediate_dir)/base/jni/PathUtils_jni.h \
+ $(gyp_shared_intermediate_dir)/base/jni/PowerMonitor_jni.h \
$(gyp_shared_intermediate_dir)/base/jni/SystemMessageHandler_jni.h \
- $(gyp_shared_intermediate_dir)/base/jni/SystemMonitor_jni.h \
$(gyp_shared_intermediate_dir)/base/jni/ThreadUtils_jni.h \
base_base_jni_headers_gyp_rule_trigger
@@ -156,6 +156,7 @@
-march=pentium4 \
-msse2 \
-mfpmath=sse \
+ -fuse-ld=gold \
-ffunction-sections \
-funwind-tables \
-g \
@@ -176,7 +177,6 @@
MY_CFLAGS_C :=
MY_DEFS := \
- '-DUSE_SKIA' \
'-D_FILE_OFFSET_BITS=64' \
'-DUSE_LINUX_BREAKPAD' \
'-DNO_TCMALLOC' \
@@ -184,7 +184,6 @@
'-DCHROMIUM_BUILD' \
'-DUSE_LIBJPEG_TURBO=1' \
'-DUSE_PROPRIETARY_CODECS' \
- '-DENABLE_PEPPER_THREADING' \
'-DENABLE_GPU=1' \
'-DUSE_OPENSSL=1' \
'-DENABLE_EGLIMAGE=1' \
diff --git a/base/base_paths.cc b/base/base_paths.cc
index 05a55af..b90efba 100644
--- a/base/base_paths.cc
+++ b/base/base_paths.cc
@@ -15,18 +15,27 @@
FilePath cur;
switch (key) {
- case base::DIR_EXE:
- PathService::Get(base::FILE_EXE, &cur);
+ case DIR_EXE:
+ PathService::Get(FILE_EXE, &cur);
cur = cur.DirName();
break;
- case base::DIR_MODULE:
- PathService::Get(base::FILE_MODULE, &cur);
+ case DIR_MODULE:
+ PathService::Get(FILE_MODULE, &cur);
cur = cur.DirName();
break;
- case base::DIR_TEMP:
+ case DIR_TEMP:
if (!file_util::GetTempDir(&cur))
return false;
break;
+ case DIR_TEST_DATA:
+ if (!PathService::Get(DIR_SOURCE_ROOT, &cur))
+ return false;
+ cur = cur.Append(FILE_PATH_LITERAL("base"));
+ cur = cur.Append(FILE_PATH_LITERAL("test"));
+ cur = cur.Append(FILE_PATH_LITERAL("data"));
+ if (!file_util::PathExists(cur)) // We don't want to create this.
+ return false;
+ break;
default:
return false;
}
diff --git a/base/base_paths.h b/base/base_paths.h
index 3251a84..f9601a2 100644
--- a/base/base_paths.h
+++ b/base/base_paths.h
@@ -27,19 +27,22 @@
enum BasePathKey {
PATH_START = 0,
- DIR_CURRENT, // current directory
- DIR_EXE, // directory containing FILE_EXE
- DIR_MODULE, // directory containing FILE_MODULE
- DIR_TEMP, // temporary directory
- FILE_EXE, // Path and filename of the current executable.
- FILE_MODULE, // Path and filename of the module containing the code for the
- // PathService (which could differ from FILE_EXE if the
- // PathService were compiled into a shared object, for example).
- DIR_SOURCE_ROOT, // Returns the root of the source tree. This key is useful
- // for tests that need to locate various resources. It
- // should not be used outside of test code.
+ DIR_CURRENT, // Current directory.
+ DIR_EXE, // Directory containing FILE_EXE.
+ DIR_MODULE, // Directory containing FILE_MODULE.
+ DIR_TEMP, // Temporary directory.
+ FILE_EXE, // Path and filename of the current executable.
+ FILE_MODULE, // Path and filename of the module containing the code for
+ // the PathService (which could differ from FILE_EXE if the
+ // PathService were compiled into a shared object, for
+ // example).
+ DIR_SOURCE_ROOT, // Returns the root of the source tree. This key is useful
+ // for tests that need to locate various resources. It
+ // should not be used outside of test code.
DIR_USER_DESKTOP, // The current user's Desktop.
+ DIR_TEST_DATA, // Used only for testing.
+
PATH_END
};
diff --git a/base/base_static.target.darwin-arm.mk b/base/base_static.target.darwin-arm.mk
new file mode 100644
index 0000000..f5d7240
--- /dev/null
+++ b/base/base_static.target.darwin-arm.mk
@@ -0,0 +1,145 @@
+# This file is generated by gyp; do not edit.
+
+include $(CLEAR_VARS)
+
+LOCAL_MODULE_CLASS := STATIC_LIBRARIES
+LOCAL_MODULE := base_base_static_gyp
+LOCAL_MODULE_SUFFIX := .a
+LOCAL_MODULE_TAGS := optional
+gyp_intermediate_dir := $(call local-intermediates-dir)
+gyp_shared_intermediate_dir := $(call intermediates-dir-for,GYP,shared)
+
+# Make sure our deps are built first.
+GYP_TARGET_DEPENDENCIES :=
+
+GYP_GENERATED_OUTPUTS :=
+
+# Make sure our deps and generated files are built first.
+LOCAL_ADDITIONAL_DEPENDENCIES := $(GYP_TARGET_DEPENDENCIES) $(GYP_GENERATED_OUTPUTS)
+
+LOCAL_CPP_EXTENSION := .cc
+LOCAL_GENERATED_SOURCES :=
+
+GYP_COPIED_SOURCE_ORIGIN_DIRS :=
+
+LOCAL_SRC_FILES := \
+ base/base_switches.cc
+
+
+# Flags passed to both C and C++ files.
+MY_CFLAGS := \
+ -fstack-protector \
+ --param=ssp-buffer-size=4 \
+ -Werror \
+ -fno-exceptions \
+ -fno-strict-aliasing \
+ -Wall \
+ -Wno-unused-parameter \
+ -Wno-missing-field-initializers \
+ -fvisibility=hidden \
+ -pipe \
+ -fPIC \
+ -fno-tree-sra \
+ -fuse-ld=gold \
+ -Wno-psabi \
+ -ffunction-sections \
+ -funwind-tables \
+ -g \
+ -fstack-protector \
+ -fno-short-enums \
+ -finline-limit=64 \
+ -Wa,--noexecstack \
+ -U_FORTIFY_SOURCE \
+ -Wno-extra \
+ -Wno-ignored-qualifiers \
+ -Wno-type-limits \
+ -Os \
+ -g \
+ -fomit-frame-pointer \
+ -fdata-sections \
+ -ffunction-sections
+
+MY_CFLAGS_C :=
+
+MY_DEFS := \
+ '-D_FILE_OFFSET_BITS=64' \
+ '-DUSE_LINUX_BREAKPAD' \
+ '-DNO_TCMALLOC' \
+ '-DDISABLE_NACL' \
+ '-DCHROMIUM_BUILD' \
+ '-DUSE_LIBJPEG_TURBO=1' \
+ '-DUSE_PROPRIETARY_CODECS' \
+ '-DENABLE_GPU=1' \
+ '-DUSE_OPENSSL=1' \
+ '-DENABLE_EGLIMAGE=1' \
+ '-DENABLE_LANGUAGE_DETECTION=1' \
+ '-D__STDC_CONSTANT_MACROS' \
+ '-D__STDC_FORMAT_MACROS' \
+ '-DANDROID' \
+ '-D__GNU_SOURCE=1' \
+ '-DUSE_STLPORT=1' \
+ '-D_STLP_USE_PTR_SPECIALIZATIONS=1' \
+ '-DCHROME_BUILD_ID=""' \
+ '-DDYNAMIC_ANNOTATIONS_ENABLED=1' \
+ '-DWTF_USE_DYNAMIC_ANNOTATIONS=1' \
+ '-D_DEBUG'
+
+LOCAL_CFLAGS := $(MY_CFLAGS_C) $(MY_CFLAGS) $(MY_DEFS)
+
+# Include paths placed before CFLAGS/CPPFLAGS
+LOCAL_C_INCLUDES := \
+ $(LOCAL_PATH) \
+ $(GYP_ABS_ANDROID_TOP_DIR)/frameworks/wilhelm/include \
+ $(GYP_ABS_ANDROID_TOP_DIR)/bionic \
+ $(GYP_ABS_ANDROID_TOP_DIR)/external/stlport/stlport
+
+LOCAL_C_INCLUDES := $(GYP_COPIED_SOURCE_ORIGIN_DIRS) $(LOCAL_C_INCLUDES)
+
+# Flags passed to only C++ (and not C) files.
+LOCAL_CPPFLAGS := \
+ -fno-rtti \
+ -fno-threadsafe-statics \
+ -fvisibility-inlines-hidden \
+ -Wsign-compare \
+ -Wno-abi \
+ -Wno-error=c++0x-compat \
+ -Wno-non-virtual-dtor \
+ -Wno-sign-promo
+
+### Rules for final target.
+
+LOCAL_LDFLAGS := \
+ -Wl,-z,now \
+ -Wl,-z,relro \
+ -Wl,-z,noexecstack \
+ -fPIC \
+ -Wl,-z,relro \
+ -Wl,-z,now \
+ -fuse-ld=gold \
+ -nostdlib \
+ -Wl,--no-undefined \
+ -Wl,--exclude-libs=ALL \
+ -Wl,--icf=safe \
+ -Wl,--gc-sections \
+ -Wl,-O1 \
+ -Wl,--as-needed
+
+
+LOCAL_STATIC_LIBRARIES :=
+
+# Enable grouping to fix circular references
+LOCAL_GROUP_STATIC_LIBRARIES := true
+
+LOCAL_SHARED_LIBRARIES := \
+ libstlport \
+ libdl
+
+# Add target alias to "gyp_all_modules" target.
+.PHONY: gyp_all_modules
+gyp_all_modules: base_base_static_gyp
+
+# Alias gyp target name.
+.PHONY: base_static
+base_static: base_base_static_gyp
+
+include $(BUILD_STATIC_LIBRARY)
diff --git a/base/base_static.target.darwin-x86.mk b/base/base_static.target.darwin-x86.mk
new file mode 100644
index 0000000..be6a762
--- /dev/null
+++ b/base/base_static.target.darwin-x86.mk
@@ -0,0 +1,144 @@
+# This file is generated by gyp; do not edit.
+
+include $(CLEAR_VARS)
+
+LOCAL_MODULE_CLASS := STATIC_LIBRARIES
+LOCAL_MODULE := base_base_static_gyp
+LOCAL_MODULE_SUFFIX := .a
+LOCAL_MODULE_TAGS := optional
+gyp_intermediate_dir := $(call local-intermediates-dir)
+gyp_shared_intermediate_dir := $(call intermediates-dir-for,GYP,shared)
+
+# Make sure our deps are built first.
+GYP_TARGET_DEPENDENCIES :=
+
+GYP_GENERATED_OUTPUTS :=
+
+# Make sure our deps and generated files are built first.
+LOCAL_ADDITIONAL_DEPENDENCIES := $(GYP_TARGET_DEPENDENCIES) $(GYP_GENERATED_OUTPUTS)
+
+LOCAL_CPP_EXTENSION := .cc
+LOCAL_GENERATED_SOURCES :=
+
+GYP_COPIED_SOURCE_ORIGIN_DIRS :=
+
+LOCAL_SRC_FILES := \
+ base/base_switches.cc
+
+
+# Flags passed to both C and C++ files.
+MY_CFLAGS := \
+ --param=ssp-buffer-size=4 \
+ -Werror \
+ -fno-exceptions \
+ -fno-strict-aliasing \
+ -Wall \
+ -Wno-unused-parameter \
+ -Wno-missing-field-initializers \
+ -fvisibility=hidden \
+ -pipe \
+ -fPIC \
+ -m32 \
+ -mmmx \
+ -march=pentium4 \
+ -msse2 \
+ -mfpmath=sse \
+ -fuse-ld=gold \
+ -ffunction-sections \
+ -funwind-tables \
+ -g \
+ -fno-short-enums \
+ -finline-limit=64 \
+ -Wa,--noexecstack \
+ -U_FORTIFY_SOURCE \
+ -Wno-extra \
+ -Wno-ignored-qualifiers \
+ -Wno-type-limits \
+ -fno-stack-protector \
+ -Os \
+ -g \
+ -fomit-frame-pointer \
+ -fdata-sections \
+ -ffunction-sections
+
+MY_CFLAGS_C :=
+
+MY_DEFS := \
+ '-D_FILE_OFFSET_BITS=64' \
+ '-DUSE_LINUX_BREAKPAD' \
+ '-DNO_TCMALLOC' \
+ '-DDISABLE_NACL' \
+ '-DCHROMIUM_BUILD' \
+ '-DUSE_LIBJPEG_TURBO=1' \
+ '-DUSE_PROPRIETARY_CODECS' \
+ '-DENABLE_GPU=1' \
+ '-DUSE_OPENSSL=1' \
+ '-DENABLE_EGLIMAGE=1' \
+ '-DENABLE_LANGUAGE_DETECTION=1' \
+ '-D__STDC_CONSTANT_MACROS' \
+ '-D__STDC_FORMAT_MACROS' \
+ '-DANDROID' \
+ '-D__GNU_SOURCE=1' \
+ '-DUSE_STLPORT=1' \
+ '-D_STLP_USE_PTR_SPECIALIZATIONS=1' \
+ '-DCHROME_BUILD_ID=""' \
+ '-DDYNAMIC_ANNOTATIONS_ENABLED=1' \
+ '-DWTF_USE_DYNAMIC_ANNOTATIONS=1' \
+ '-D_DEBUG'
+
+LOCAL_CFLAGS := $(MY_CFLAGS_C) $(MY_CFLAGS) $(MY_DEFS)
+
+# Include paths placed before CFLAGS/CPPFLAGS
+LOCAL_C_INCLUDES := \
+ $(LOCAL_PATH) \
+ $(GYP_ABS_ANDROID_TOP_DIR)/frameworks/wilhelm/include \
+ $(GYP_ABS_ANDROID_TOP_DIR)/bionic \
+ $(GYP_ABS_ANDROID_TOP_DIR)/external/stlport/stlport
+
+LOCAL_C_INCLUDES := $(GYP_COPIED_SOURCE_ORIGIN_DIRS) $(LOCAL_C_INCLUDES)
+
+# Flags passed to only C++ (and not C) files.
+LOCAL_CPPFLAGS := \
+ -fno-rtti \
+ -fno-threadsafe-statics \
+ -fvisibility-inlines-hidden \
+ -Wsign-compare \
+ -Wno-error=c++0x-compat \
+ -Wno-non-virtual-dtor \
+ -Wno-sign-promo
+
+### Rules for final target.
+
+LOCAL_LDFLAGS := \
+ -Wl,-z,now \
+ -Wl,-z,relro \
+ -Wl,-z,noexecstack \
+ -fPIC \
+ -m32 \
+ -fuse-ld=gold \
+ -nostdlib \
+ -Wl,--no-undefined \
+ -Wl,--exclude-libs=ALL \
+ -Wl,--gc-sections \
+ -Wl,-O1 \
+ -Wl,--as-needed
+
+
+LOCAL_STATIC_LIBRARIES :=
+
+# Enable grouping to fix circular references
+LOCAL_GROUP_STATIC_LIBRARIES := true
+
+LOCAL_SHARED_LIBRARIES := \
+ libstlport \
+ libdl
+
+# Add target alias to "gyp_all_modules" target.
+.PHONY: gyp_all_modules
+gyp_all_modules: base_base_static_gyp
+
+# Alias gyp target name.
+.PHONY: base_static
+base_static: base_base_static_gyp
+
+include $(BUILD_STATIC_LIBRARY)
diff --git a/base/base_static.target.linux-arm.mk b/base/base_static.target.linux-arm.mk
index 69b8036..f5d7240 100644
--- a/base/base_static.target.linux-arm.mk
+++ b/base/base_static.target.linux-arm.mk
@@ -62,7 +62,6 @@
MY_CFLAGS_C :=
MY_DEFS := \
- '-DUSE_SKIA' \
'-D_FILE_OFFSET_BITS=64' \
'-DUSE_LINUX_BREAKPAD' \
'-DNO_TCMALLOC' \
@@ -70,7 +69,6 @@
'-DCHROMIUM_BUILD' \
'-DUSE_LIBJPEG_TURBO=1' \
'-DUSE_PROPRIETARY_CODECS' \
- '-DENABLE_PEPPER_THREADING' \
'-DENABLE_GPU=1' \
'-DUSE_OPENSSL=1' \
'-DENABLE_EGLIMAGE=1' \
@@ -122,9 +120,9 @@
-Wl,--no-undefined \
-Wl,--exclude-libs=ALL \
-Wl,--icf=safe \
+ -Wl,--gc-sections \
-Wl,-O1 \
- -Wl,--as-needed \
- -Wl,--gc-sections
+ -Wl,--as-needed
LOCAL_STATIC_LIBRARIES :=
diff --git a/base/base_static.target.linux-x86.mk b/base/base_static.target.linux-x86.mk
index 02e0dfa..be6a762 100644
--- a/base/base_static.target.linux-x86.mk
+++ b/base/base_static.target.linux-x86.mk
@@ -43,6 +43,7 @@
-march=pentium4 \
-msse2 \
-mfpmath=sse \
+ -fuse-ld=gold \
-ffunction-sections \
-funwind-tables \
-g \
@@ -63,7 +64,6 @@
MY_CFLAGS_C :=
MY_DEFS := \
- '-DUSE_SKIA' \
'-D_FILE_OFFSET_BITS=64' \
'-DUSE_LINUX_BREAKPAD' \
'-DNO_TCMALLOC' \
@@ -71,7 +71,6 @@
'-DCHROMIUM_BUILD' \
'-DUSE_LIBJPEG_TURBO=1' \
'-DUSE_PROPRIETARY_CODECS' \
- '-DENABLE_PEPPER_THREADING' \
'-DENABLE_GPU=1' \
'-DUSE_OPENSSL=1' \
'-DENABLE_EGLIMAGE=1' \
@@ -116,12 +115,13 @@
-Wl,-z,noexecstack \
-fPIC \
-m32 \
+ -fuse-ld=gold \
-nostdlib \
-Wl,--no-undefined \
-Wl,--exclude-libs=ALL \
+ -Wl,--gc-sections \
-Wl,-O1 \
- -Wl,--as-needed \
- -Wl,--gc-sections
+ -Wl,--as-needed
LOCAL_STATIC_LIBRARIES :=
diff --git a/base/base_unittests.isolate b/base/base_unittests.isolate
index 039edd6..929b146 100644
--- a/base/base_unittests.isolate
+++ b/base/base_unittests.isolate
@@ -2,18 +2,6 @@
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.
{
- 'variables': {
- 'isolate_dependency_tracked': [
- '../testing/test_env.py',
- '../tools/swarm_client/run_isolated.py',
- '../tools/swarm_client/run_test_cases.py',
- '<(PRODUCT_DIR)/base_unittests<(EXECUTABLE_SUFFIX)',
- ],
- 'isolate_dependency_untracked': [
- 'data/',
- 'prefs/test/',
- ],
- },
'conditions': [
['OS=="linux"', {
'variables': {
@@ -28,7 +16,22 @@
'<(PRODUCT_DIR)/xdisplaycheck<(EXECUTABLE_SUFFIX)',
],
},
- }, {
+ }],
+ ['OS=="linux" or OS=="mac" or OS=="win"', {
+ 'variables': {
+ 'isolate_dependency_tracked': [
+ '../testing/test_env.py',
+ '../tools/swarm_client/run_isolated.py',
+ '../tools/swarm_client/run_test_cases.py',
+ '<(PRODUCT_DIR)/base_unittests<(EXECUTABLE_SUFFIX)',
+ ],
+ 'isolate_dependency_untracked': [
+ 'data/',
+ 'test/data/',
+ ],
+ },
+ }],
+ ['OS=="mac" or OS=="win"', {
'variables': {
'command': [
'../testing/test_env.py',
diff --git a/base/base_untrusted.gyp b/base/base_untrusted.gyp
index b63885b..a4c26b1 100644
--- a/base/base_untrusted.gyp
+++ b/base/base_untrusted.gyp
@@ -23,6 +23,8 @@
'build_glibc': 1,
'build_newlib': 1,
'sources': [
+ 'base_switches.cc',
+ 'base_switches.h',
'string16.cc',
'sync_socket_nacl.cc',
'time_posix.cc',
diff --git a/base/callback_internal.h b/base/callback_internal.h
index d9aba39..5993824 100644
--- a/base/callback_internal.h
+++ b/base/callback_internal.h
@@ -136,12 +136,6 @@
typedef scoped_ptr<T, D> StorageType;
};
-template <typename T>
-struct CallbackParamTraits<scoped_array<T> > {
- typedef scoped_array<T> ForwardType;
- typedef scoped_array<T> StorageType;
-};
-
template <typename T, typename R>
struct CallbackParamTraits<scoped_ptr_malloc<T, R> > {
typedef scoped_ptr_malloc<T, R> ForwardType;
@@ -176,9 +170,6 @@
template <typename T, typename D>
scoped_ptr<T, D> CallbackForward(scoped_ptr<T, D>& p) { return p.Pass(); }
-template <typename T>
-scoped_array<T> CallbackForward(scoped_array<T>& p) { return p.Pass(); }
-
template <typename T, typename R>
scoped_ptr_malloc<T, R> CallbackForward(scoped_ptr_malloc<T, R>& p) {
return p.Pass();
diff --git a/base/cancelable_callback.h b/base/cancelable_callback.h
index acbffdd..1cfcf2b 100644
--- a/base/cancelable_callback.h
+++ b/base/cancelable_callback.h
@@ -58,11 +58,11 @@
template <>
class CancelableCallback<void(void)> {
public:
- CancelableCallback() : ALLOW_THIS_IN_INITIALIZER_LIST(weak_factory_(this)) {}
+ CancelableCallback() : weak_factory_(this) {}
// |callback| must not be null.
explicit CancelableCallback(const base::Callback<void(void)>& callback)
- : ALLOW_THIS_IN_INITIALIZER_LIST(weak_factory_(this)),
+ : weak_factory_(this),
callback_(callback) {
DCHECK(!callback.is_null());
InitializeForwarder();
@@ -128,11 +128,11 @@
template <typename A1>
class CancelableCallback<void(A1)> {
public:
- CancelableCallback() : ALLOW_THIS_IN_INITIALIZER_LIST(weak_factory_(this)) {}
+ CancelableCallback() : weak_factory_(this) {}
// |callback| must not be null.
explicit CancelableCallback(const base::Callback<void(A1)>& callback)
- : ALLOW_THIS_IN_INITIALIZER_LIST(weak_factory_(this)),
+ : weak_factory_(this),
callback_(callback) {
DCHECK(!callback.is_null());
InitializeForwarder();
diff --git a/base/compiler_specific.h b/base/compiler_specific.h
index 01c1eb1..0be7d89 100644
--- a/base/compiler_specific.h
+++ b/base/compiler_specific.h
@@ -40,19 +40,6 @@
#define MSVC_DISABLE_OPTIMIZE() __pragma(optimize("", off))
#define MSVC_ENABLE_OPTIMIZE() __pragma(optimize("", on))
-// Allows |this| to be passed as an argument in constructor initializer lists.
-// This uses push/pop instead of the seemingly simpler suppress feature to avoid
-// having the warning be disabled for more than just |code|.
-//
-// Example usage:
-// Foo::Foo() : x(NULL), ALLOW_THIS_IN_INITIALIZER_LIST(y(this)), z(3) {}
-//
-// Compiler warning C4355: 'this': used in base member initializer list:
-// http://msdn.microsoft.com/en-us/library/3c594ae3(VS.80).aspx
-#define ALLOW_THIS_IN_INITIALIZER_LIST(code) MSVC_PUSH_DISABLE_WARNING(4355) \
- code \
- MSVC_POP_WARNING()
-
// Allows exporting a class that inherits from a non-exported base class.
// This uses suppress instead of push/pop because the delimiter after the
// declaration (either "," or "{") has to be placed before the pop macro.
@@ -76,7 +63,6 @@
#define MSVC_POP_WARNING()
#define MSVC_DISABLE_OPTIMIZE()
#define MSVC_ENABLE_OPTIMIZE()
-#define ALLOW_THIS_IN_INITIALIZER_LIST(code) code
#define NON_EXPORTED_BASE(code) code
#endif // COMPILER_MSVC
diff --git a/base/cpu.cc b/base/cpu.cc
index d6976ba..4a94af0 100644
--- a/base/cpu.cc
+++ b/base/cpu.cc
@@ -32,6 +32,7 @@
has_ssse3_(false),
has_sse41_(false),
has_sse42_(false),
+ has_non_stop_time_stamp_counter_(false),
cpu_vendor_("unknown") {
Initialize();
}
@@ -123,6 +124,7 @@
// Get the brand string of the cpu.
__cpuid(cpu_info, 0x80000000);
const int parameter_end = 0x80000004;
+ int max_parameter = cpu_info[0];
if (cpu_info[0] >= parameter_end) {
char* cpu_string_ptr = cpu_string;
@@ -135,6 +137,12 @@
}
cpu_brand_.assign(cpu_string, cpu_string_ptr - cpu_string);
}
+
+ const int parameter_containing_non_stop_time_stamp_counter = 0x80000007;
+ if (max_parameter >= parameter_containing_non_stop_time_stamp_counter) {
+ __cpuid(cpu_info, parameter_containing_non_stop_time_stamp_counter);
+ has_non_stop_time_stamp_counter_ = (cpu_info[3] & (1 << 8)) != 0;
+ }
#endif
}
diff --git a/base/cpu.h b/base/cpu.h
index 65fda47..1d45258 100644
--- a/base/cpu.h
+++ b/base/cpu.h
@@ -45,6 +45,9 @@
bool has_sse41() const { return has_sse41_; }
bool has_sse42() const { return has_sse42_; }
bool has_avx() const { return has_avx_; }
+ bool has_non_stop_time_stamp_counter() const {
+ return has_non_stop_time_stamp_counter_;
+ }
IntelMicroArchitecture GetIntelMicroArchitecture() const;
const std::string& cpu_brand() const { return cpu_brand_; }
@@ -66,6 +69,7 @@
bool has_sse41_;
bool has_sse42_;
bool has_avx_;
+ bool has_non_stop_time_stamp_counter_;
std::string cpu_vendor_;
std::string cpu_brand_;
};
diff --git a/base/debug/crash_logging.h b/base/debug/crash_logging.h
index 9b284ee..d6ffa91 100644
--- a/base/debug/crash_logging.h
+++ b/base/debug/crash_logging.h
@@ -10,7 +10,7 @@
#include "base/base_export.h"
#include "base/basictypes.h"
-#include "base/string_piece.h"
+#include "base/strings/string_piece.h"
// These functions add metadata to the upload payload when sending crash reports
// to the crash server.
diff --git a/base/debug/debugger_posix.cc b/base/debug/debugger_posix.cc
index 0fbefde..2072806 100644
--- a/base/debug/debugger_posix.cc
+++ b/base/debug/debugger_posix.cc
@@ -44,8 +44,8 @@
#include "base/memory/scoped_ptr.h"
#include "base/posix/eintr_wrapper.h"
#include "base/safe_strerror_posix.h"
-#include "base/string_piece.h"
#include "base/stringprintf.h"
+#include "base/strings/string_piece.h"
#if defined(USE_SYMBOLIZE)
#include "base/third_party/symbolize/symbolize.h"
@@ -209,29 +209,35 @@
// should ask for advice from some NaCl experts about the optimum thing here.
// http://code.google.com/p/nativeclient/issues/detail?id=645
#define DEBUG_BREAK() abort()
-#elif defined(ARCH_CPU_ARM_FAMILY)
-#if defined(OS_ANDROID)
+#elif defined(OS_ANDROID)
// Though Android has a "helpful" process called debuggerd to catch native
-// signals on the general assumption that they are fatal errors. The bkpt
-// instruction appears to cause SIGBUS which is trapped by debuggerd, and
-// we've had great difficulty continuing in a debugger once we stop from
-// SIG triggered by native code.
-//
-// Use GDB to set |go| to 1 to resume execution.
-#define DEBUG_BREAK() do { \
- if (!BeingDebugged()) { \
- abort(); \
- } else { \
- volatile int go = 0; \
- while (!go) { \
- base::PlatformThread::Sleep(base::TimeDelta::FromMilliseconds(100)); \
- } \
- } \
-} while (0)
+// signals on the general assumption that they are fatal errors. If no debugger
+// is attached, we call abort since Breakpad needs SIGABRT to create a dump.
+// When debugger is attached, for ARM platform the bkpt instruction appears
+// to cause SIGBUS which is trapped by debuggerd, and we've had great
+// difficulty continuing in a debugger once we stop from SIG triggered by native
+// code, use GDB to set |go| to 1 to resume execution; for X86 platform, use
+// "int3" to setup breakpiont and raise SIGTRAP.
+namespace {
+void DebugBreak() {
+ if (!BeingDebugged()) {
+ abort();
+ } else {
+#if defined(ARCH_CPU_X86_FAMILY)
+ asm("int3");
#else
+ volatile int go = 0;
+ while (!go) {
+ base::PlatformThread::Sleep(base::TimeDelta::FromMilliseconds(100));
+ }
+#endif
+ }
+}
+} // namespace
+#define DEBUG_BREAK() DebugBreak()
+#elif defined(ARCH_CPU_ARM_FAMILY)
// ARM && !ANDROID
#define DEBUG_BREAK() asm("bkpt 0")
-#endif
#elif defined(ARCH_CPU_MIPS_FAMILY)
#define DEBUG_BREAK() asm("break 2")
#else
diff --git a/base/debug/stack_trace_android.cc b/base/debug/stack_trace_android.cc
index cc03d60..050a2d8 100644
--- a/base/debug/stack_trace_android.cc
+++ b/base/debug/stack_trace_android.cc
@@ -7,9 +7,68 @@
#include <signal.h>
#include <sys/types.h>
#include <unistd.h>
+#include <unwind.h> // TODO(dmikurube): Remove. See http://crbug.com/236855.
#include "base/logging.h"
+#ifdef __MIPSEL__
+// SIGSTKFLT is not defined for MIPS.
+#define SIGSTKFLT SIGSEGV
+#endif
+
+// TODO(dmikurube): Remove when Bionic's get_backtrace() gets popular.
+// See http://crbug.com/236855.
+namespace {
+
+/* depends how the system includes define this */
+#ifdef HAVE_UNWIND_CONTEXT_STRUCT
+typedef struct _Unwind_Context __unwind_context;
+#else
+typedef _Unwind_Context __unwind_context;
+#endif
+
+struct stack_crawl_state_t {
+ uintptr_t* frames;
+ size_t frame_count;
+ size_t max_depth;
+ bool have_skipped_self;
+
+ stack_crawl_state_t(uintptr_t* frames, size_t max_depth)
+ : frames(frames),
+ frame_count(0),
+ max_depth(max_depth),
+ have_skipped_self(false) {
+ }
+};
+
+static _Unwind_Reason_Code tracer(__unwind_context* context, void* arg) {
+ stack_crawl_state_t* state = static_cast<stack_crawl_state_t*>(arg);
+
+#if defined(__clang__)
+ // Vanilla Clang's unwind.h doesn't have _Unwind_GetIP for ARM.
+ // See http://crbug.com/236855, too.
+ uintptr_t ip = 0;
+ _Unwind_VRS_Get(context, _UVRSC_CORE, 15, _UVRSD_UINT32, &ip);
+ ip &= ~(uintptr_t)0x1; // remove thumb mode bit
+#else
+ uintptr_t ip = _Unwind_GetIP(context);
+#endif
+
+ // The first stack frame is this function itself. Skip it.
+ if (ip != 0 && !state->have_skipped_self) {
+ state->have_skipped_self = true;
+ return _URC_NO_REASON;
+ }
+
+ state->frames[state->frame_count++] = ip;
+ if (state->frame_count >= state->max_depth)
+ return _URC_END_OF_STACK;
+ else
+ return _URC_NO_REASON;
+}
+
+} // namespace
+
namespace base {
namespace debug {
@@ -26,6 +85,12 @@
}
StackTrace::StackTrace() {
+ // TODO(dmikurube): Replace it with Bionic's get_backtrace().
+ // See http://crbug.com/236855.
+ stack_crawl_state_t state(reinterpret_cast<uintptr_t*>(trace_), kMaxTraces);
+ _Unwind_Backtrace(tracer, &state);
+ count_ = state.frame_count;
+ // TODO(dmikurube): Symbolize in Chrome.
}
// Sends fake SIGSTKFLT signals to let the Android linker and debuggerd dump
diff --git a/base/debug/stack_trace_win.cc b/base/debug/stack_trace_win.cc
index da75b0b..f1d3590 100644
--- a/base/debug/stack_trace_win.cc
+++ b/base/debug/stack_trace_win.cc
@@ -12,8 +12,11 @@
#include "base/basictypes.h"
#include "base/logging.h"
#include "base/memory/singleton.h"
+#include "base/path_service.h"
#include "base/process_util.h"
+#include "base/string_util.h"
#include "base/synchronization/lock.h"
+#include "base/win/windows_version.h"
namespace base {
namespace debug {
@@ -129,9 +132,7 @@
SymSetOptions(SYMOPT_DEFERRED_LOADS |
SYMOPT_UNDNAME |
SYMOPT_LOAD_LINES);
- if (SymInitialize(GetCurrentProcess(), NULL, TRUE)) {
- init_error_ = ERROR_SUCCESS;
- } else {
+ if (!SymInitialize(GetCurrentProcess(), NULL, TRUE)) {
init_error_ = GetLastError();
// TODO(awong): Handle error: SymInitialize can fail with
// ERROR_INVALID_PARAMETER.
@@ -139,6 +140,41 @@
// process (prevents future tests from running or kills the browser
// process).
DLOG(ERROR) << "SymInitialize failed: " << init_error_;
+ return;
+ }
+
+ init_error_ = ERROR_SUCCESS;
+
+ // Work around a mysterious hang on Windows XP.
+ if (base::win::GetVersion() < base::win::VERSION_VISTA)
+ return;
+
+ // When transferring the binaries e.g. between bots, path put
+ // into the executable will get off. To still retrieve symbols correctly,
+ // add the directory of the executable to symbol search path.
+ // All following errors are non-fatal.
+ wchar_t symbols_path[1024];
+
+ // Note: The below function takes buffer size as number of characters,
+ // not number of bytes!
+ if (!SymGetSearchPathW(GetCurrentProcess(),
+ symbols_path,
+ arraysize(symbols_path))) {
+ DLOG(WARNING) << "SymGetSearchPath failed: ";
+ return;
+ }
+
+ FilePath module_path;
+ if (!PathService::Get(FILE_EXE, &module_path)) {
+ DLOG(WARNING) << "PathService::Get(FILE_EXE) failed.";
+ return;
+ }
+
+ std::wstring new_path(std::wstring(symbols_path) +
+ L";" + module_path.DirName().value());
+ if (!SymSetSearchPathW(GetCurrentProcess(), new_path.c_str())) {
+ DLOG(WARNING) << "SymSetSearchPath failed.";
+ return;
}
}
diff --git a/base/debug/trace_event.h b/base/debug/trace_event.h
index e651547..366f4ac 100644
--- a/base/debug/trace_event.h
+++ b/base/debug/trace_event.h
@@ -2,38 +2,686 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-// This header defines the set of functions necessary for trace_event_internal.h
-// to remain platform and context neutral. To use tracing in another context,
-// copy this header (and trace_event_internal.h) and implement the
-// TRACE_EVENT_API_* macros below for the new environment.
+// This header file defines the set of trace_event macros without specifying
+// how the events actually get collected and stored. If you need to expose trace
+// events to some other universe, you can copy-and-paste this file as well as
+// trace_event.h, modifying the macros contained there as necessary for the
+// target platform. The end result is that multiple libraries can funnel events
+// through to a shared trace event collector.
+
+// Trace events are for tracking application performance and resource usage.
+// Macros are provided to track:
+// Begin and end of function calls
+// Counters
+//
+// Events are issued against categories. Whereas LOG's
+// categories are statically defined, TRACE categories are created
+// implicitly with a string. For example:
+// TRACE_EVENT_INSTANT0("MY_SUBSYSTEM", "SomeImportantEvent")
+//
+// It is often the case that one trace may belong in multiple categories at the
+// same time. The first argument to the trace can be a comma-separated list of
+// categories, forming a category group, like:
+//
+// TRACE_EVENT_INSTANT0("input,views", "OnMouseOver")
+//
+// We can enable/disable tracing of OnMouseOver by enabling/disabling either
+// category.
+//
+// Events can be INSTANT, or can be pairs of BEGIN and END in the same scope:
+// TRACE_EVENT_BEGIN0("MY_SUBSYSTEM", "SomethingCostly")
+// doSomethingCostly()
+// TRACE_EVENT_END0("MY_SUBSYSTEM", "SomethingCostly")
+// Note: our tools can't always determine the correct BEGIN/END pairs unless
+// these are used in the same scope. Use ASYNC_BEGIN/ASYNC_END macros if you
+// need them to be in separate scopes.
+//
+// A common use case is to trace entire function scopes. This
+// issues a trace BEGIN and END automatically:
+// void doSomethingCostly() {
+// TRACE_EVENT0("MY_SUBSYSTEM", "doSomethingCostly");
+// ...
+// }
+//
+// Additional parameters can be associated with an event:
+// void doSomethingCostly2(int howMuch) {
+// TRACE_EVENT1("MY_SUBSYSTEM", "doSomethingCostly",
+// "howMuch", howMuch);
+// ...
+// }
+//
+// The trace system will automatically add to this information the
+// current process id, thread id, and a timestamp in microseconds.
+//
+// To trace an asynchronous procedure such as an IPC send/receive, use
+// ASYNC_BEGIN and ASYNC_END:
+// [single threaded sender code]
+// static int send_count = 0;
+// ++send_count;
+// TRACE_EVENT_ASYNC_BEGIN0("ipc", "message", send_count);
+// Send(new MyMessage(send_count));
+// [receive code]
+// void OnMyMessage(send_count) {
+// TRACE_EVENT_ASYNC_END0("ipc", "message", send_count);
+// }
+// The third parameter is a unique ID to match ASYNC_BEGIN/ASYNC_END pairs.
+// ASYNC_BEGIN and ASYNC_END can occur on any thread of any traced process.
+// Pointers can be used for the ID parameter, and they will be mangled
+// internally so that the same pointer on two different processes will not
+// match. For example:
+// class MyTracedClass {
+// public:
+// MyTracedClass() {
+// TRACE_EVENT_ASYNC_BEGIN0("category", "MyTracedClass", this);
+// }
+// ~MyTracedClass() {
+// TRACE_EVENT_ASYNC_END0("category", "MyTracedClass", this);
+// }
+// }
+//
+// Trace event also supports counters, which is a way to track a quantity
+// as it varies over time. Counters are created with the following macro:
+// TRACE_COUNTER1("MY_SUBSYSTEM", "myCounter", g_myCounterValue);
+//
+// Counters are process-specific. The macro itself can be issued from any
+// thread, however.
+//
+// Sometimes, you want to track two counters at once. You can do this with two
+// counter macros:
+// TRACE_COUNTER1("MY_SUBSYSTEM", "myCounter0", g_myCounterValue[0]);
+// TRACE_COUNTER1("MY_SUBSYSTEM", "myCounter1", g_myCounterValue[1]);
+// Or you can do it with a combined macro:
+// TRACE_COUNTER2("MY_SUBSYSTEM", "myCounter",
+// "bytesPinned", g_myCounterValue[0],
+// "bytesAllocated", g_myCounterValue[1]);
+// This indicates to the tracing UI that these counters should be displayed
+// in a single graph, as a summed area chart.
+//
+// Since counters are in a global namespace, you may want to disembiguate with a
+// unique ID, by using the TRACE_COUNTER_ID* variations.
+//
+// By default, trace collection is compiled in, but turned off at runtime.
+// Collecting trace data is the responsibility of the embedding
+// application. In Chrome's case, navigating to about:tracing will turn on
+// tracing and display data collected across all active processes.
+//
+//
+// Memory scoping note:
+// Tracing copies the pointers, not the string content, of the strings passed
+// in for category_group, name, and arg_names. Thus, the following code will
+// cause problems:
+// char* str = strdup("importantName");
+// TRACE_EVENT_INSTANT0("SUBSYSTEM", str); // BAD!
+// free(str); // Trace system now has dangling pointer
+//
+// To avoid this issue with the |name| and |arg_name| parameters, use the
+// TRACE_EVENT_COPY_XXX overloads of the macros at additional runtime overhead.
+// Notes: The category must always be in a long-lived char* (i.e. static const).
+// The |arg_values|, when used, are always deep copied with the _COPY
+// macros.
+//
+// When are string argument values copied:
+// const char* arg_values are only referenced by default:
+// TRACE_EVENT1("category", "name",
+// "arg1", "literal string is only referenced");
+// Use TRACE_STR_COPY to force copying of a const char*:
+// TRACE_EVENT1("category", "name",
+// "arg1", TRACE_STR_COPY("string will be copied"));
+// std::string arg_values are always copied:
+// TRACE_EVENT1("category", "name",
+// "arg1", std::string("string will be copied"));
+//
+//
+// Convertable notes:
+// Converting a large data type to a string can be costly. To help with this,
+// the trace framework provides an interface ConvertableToTraceFormat. If you
+// inherit from it and implement the AppendAsTraceFormat method the trace
+// framework will call back to your object to convert a trace output time. This
+// means, if the category for the event is disabled, the conversion will not
+// happen.
+//
+// class MyData : public base::debug::ConvertableToTraceFormat {
+// public:
+// MyData() {}
+// virtual ~MyData() {}
+// virtual void AppendAsTraceFormat(std::string* out) const OVERRIDE {
+// out->append("{\"foo\":1}");
+// }
+// private:
+// DISALLOW_COPY_AND_ASSIGN(MyData);
+// };
+//
+// scoped_ptr<MyData> data(new MyData());
+// TRACE_EVENT1("foo", "bar", "data",
+// data.PassAs<base::debug::ConvertableToTraceFormat>());
+//
+// The trace framework will take ownership if the passed pointer and it will
+// be free'd when the trace buffer is flushed.
+//
+// Note, we only do the conversion when the buffer is flushed, so the provided
+// data object should not be modified after it's passed to the trace framework.
+//
+//
+// Thread Safety:
+// A thread safe singleton and mutex are used for thread safety. Category
+// enabled flags are used to limit the performance impact when the system
+// is not enabled.
+//
+// TRACE_EVENT macros first cache a pointer to a category. The categories are
+// statically allocated and safe at all times, even after exit. Fetching a
+// category is protected by the TraceLog::lock_. Multiple threads initializing
+// the static variable is safe, as they will be serialized by the lock and
+// multiple calls will return the same pointer to the category.
+//
+// Then the category_group_enabled flag is checked. This is a unsigned char, and
+// not intended to be multithread safe. It optimizes access to AddTraceEvent
+// which is threadsafe internally via TraceLog::lock_. The enabled flag may
+// cause some threads to incorrectly call or skip calling AddTraceEvent near
+// the time of the system being enabled or disabled. This is acceptable as
+// we tolerate some data loss while the system is being enabled/disabled and
+// because AddTraceEvent is threadsafe internally and checks the enabled state
+// again under lock.
+//
+// Without the use of these static category pointers and enabled flags all
+// trace points would carry a significant performance cost of aquiring a lock
+// and resolving the category.
#ifndef BASE_DEBUG_TRACE_EVENT_H_
#define BASE_DEBUG_TRACE_EVENT_H_
+#include <string>
+
#include "base/atomicops.h"
#include "base/debug/trace_event_impl.h"
#include "build/build_config.h"
+// By default, const char* argument values are assumed to have long-lived scope
+// and will not be copied. Use this macro to force a const char* to be copied.
+#define TRACE_STR_COPY(str) \
+ trace_event_internal::TraceStringWithCopy(str)
+
+// By default, uint64 ID argument values are not mangled with the Process ID in
+// TRACE_EVENT_ASYNC macros. Use this macro to force Process ID mangling.
+#define TRACE_ID_MANGLE(id) \
+ trace_event_internal::TraceID::ForceMangle(id)
+
+// By default, pointers are mangled with the Process ID in TRACE_EVENT_ASYNC
+// macros. Use this macro to prevent Process ID mangling.
+#define TRACE_ID_DONT_MANGLE(id) \
+ trace_event_internal::TraceID::DontMangle(id)
+
+// Records a pair of begin and end events called "name" for the current
+// scope, with 0, 1 or 2 associated arguments. If the category is not
+// enabled, then this does nothing.
+// - category and name strings must have application lifetime (statics or
+// literals). They may not include " chars.
+#define TRACE_EVENT0(category_group, name) \
+ INTERNAL_TRACE_EVENT_ADD_SCOPED(category_group, name)
+#define TRACE_EVENT1(category_group, name, arg1_name, arg1_val) \
+ INTERNAL_TRACE_EVENT_ADD_SCOPED(category_group, name, arg1_name, arg1_val)
+#define TRACE_EVENT2(category_group, name, arg1_name, arg1_val, arg2_name, \
+ arg2_val) \
+ INTERNAL_TRACE_EVENT_ADD_SCOPED(category_group, name, arg1_name, arg1_val, \
+ arg2_name, arg2_val)
+
+// Same as TRACE_EVENT except that they are not included in official builds.
+#ifdef OFFICIAL_BUILD
+#define UNSHIPPED_TRACE_EVENT0(category_group, name) (void)0
+#define UNSHIPPED_TRACE_EVENT1(category_group, name, arg1_name, arg1_val) \
+ (void)0
+#define UNSHIPPED_TRACE_EVENT2(category_group, name, arg1_name, arg1_val, \
+ arg2_name, arg2_val) (void)0
+#define UNSHIPPED_TRACE_EVENT_INSTANT0(category_group, name, scope) (void)0
+#define UNSHIPPED_TRACE_EVENT_INSTANT1(category_group, name, scope, \
+ arg1_name, arg1_val) (void)0
+#define UNSHIPPED_TRACE_EVENT_INSTANT2(category_group, name, scope, \
+ arg1_name, arg1_val, \
+ arg2_name, arg2_val) (void)0
+#else
+#define UNSHIPPED_TRACE_EVENT0(category_group, name) \
+ TRACE_EVENT0(category_group, name)
+#define UNSHIPPED_TRACE_EVENT1(category_group, name, arg1_name, arg1_val) \
+ TRACE_EVENT1(category_group, name, arg1_name, arg1_val)
+#define UNSHIPPED_TRACE_EVENT2(category_group, name, arg1_name, arg1_val, \
+ arg2_name, arg2_val) \
+ TRACE_EVENT2(category_group, name, arg1_name, arg1_val, arg2_name, arg2_val)
+#define UNSHIPPED_TRACE_EVENT_INSTANT0(category_group, name, scope) \
+ TRACE_EVENT_INSTANT0(category_group, name, scope)
+#define UNSHIPPED_TRACE_EVENT_INSTANT1(category_group, name, scope, \
+ arg1_name, arg1_val) \
+ TRACE_EVENT_INSTANT1(category_group, name, scope, arg1_name, arg1_val)
+#define UNSHIPPED_TRACE_EVENT_INSTANT2(category_group, name, scope, \
+ arg1_name, arg1_val, \
+ arg2_name, arg2_val) \
+ TRACE_EVENT_INSTANT2(category_group, name, scope, arg1_name, arg1_val, \
+ arg2_name, arg2_val)
+#endif
+
+// Records a single event called "name" immediately, with 0, 1 or 2
+// associated arguments. If the category is not enabled, then this
+// does nothing.
+// - category and name strings must have application lifetime (statics or
+// literals). They may not include " chars.
+#define TRACE_EVENT_INSTANT0(category_group, name, scope) \
+ INTERNAL_TRACE_EVENT_ADD(TRACE_EVENT_PHASE_INSTANT, \
+ category_group, name, TRACE_EVENT_FLAG_NONE | scope)
+#define TRACE_EVENT_INSTANT1(category_group, name, scope, arg1_name, arg1_val) \
+ INTERNAL_TRACE_EVENT_ADD(TRACE_EVENT_PHASE_INSTANT, \
+ category_group, name, TRACE_EVENT_FLAG_NONE | scope, \
+ arg1_name, arg1_val)
+#define TRACE_EVENT_INSTANT2(category_group, name, scope, arg1_name, arg1_val, \
+ arg2_name, arg2_val) \
+ INTERNAL_TRACE_EVENT_ADD(TRACE_EVENT_PHASE_INSTANT, \
+ category_group, name, TRACE_EVENT_FLAG_NONE | scope, \
+ arg1_name, arg1_val, arg2_name, arg2_val)
+#define TRACE_EVENT_COPY_INSTANT0(category_group, name, scope) \
+ INTERNAL_TRACE_EVENT_ADD(TRACE_EVENT_PHASE_INSTANT, \
+ category_group, name, TRACE_EVENT_FLAG_COPY | scope)
+#define TRACE_EVENT_COPY_INSTANT1(category_group, name, scope, \
+ arg1_name, arg1_val) \
+ INTERNAL_TRACE_EVENT_ADD(TRACE_EVENT_PHASE_INSTANT, \
+ category_group, name, TRACE_EVENT_FLAG_COPY | scope, arg1_name, \
+ arg1_val)
+#define TRACE_EVENT_COPY_INSTANT2(category_group, name, scope, \
+ arg1_name, arg1_val, \
+ arg2_name, arg2_val) \
+ INTERNAL_TRACE_EVENT_ADD(TRACE_EVENT_PHASE_INSTANT, \
+ category_group, name, TRACE_EVENT_FLAG_COPY | scope, \
+ arg1_name, arg1_val, arg2_name, arg2_val)
+
+// Sets the current sample state to the given category and name (both must be
+// constant strings). These states are intended for a sampling profiler.
+// Implementation note: we store category and name together because we don't
+// want the inconsistency/expense of storing two pointers.
+// |thread_bucket| is [0..2] and is used to statically isolate samples in one
+// thread from others.
+#define TRACE_EVENT_SAMPLE_STATE(thread_bucket, category, name) \
+ TRACE_EVENT_API_ATOMIC_STORE( \
+ TRACE_EVENT_API_THREAD_BUCKET(thread_bucket), \
+ reinterpret_cast<TRACE_EVENT_API_ATOMIC_WORD>(category "\0" name));
+
+// Records a single BEGIN event called "name" immediately, with 0, 1 or 2
+// associated arguments. If the category is not enabled, then this
+// does nothing.
+// - category and name strings must have application lifetime (statics or
+// literals). They may not include " chars.
+#define TRACE_EVENT_BEGIN0(category_group, name) \
+ INTERNAL_TRACE_EVENT_ADD(TRACE_EVENT_PHASE_BEGIN, \
+ category_group, name, TRACE_EVENT_FLAG_NONE)
+#define TRACE_EVENT_BEGIN1(category_group, name, arg1_name, arg1_val) \
+ INTERNAL_TRACE_EVENT_ADD(TRACE_EVENT_PHASE_BEGIN, \
+ category_group, name, TRACE_EVENT_FLAG_NONE, arg1_name, arg1_val)
+#define TRACE_EVENT_BEGIN2(category_group, name, arg1_name, arg1_val, \
+ arg2_name, arg2_val) \
+ INTERNAL_TRACE_EVENT_ADD(TRACE_EVENT_PHASE_BEGIN, \
+ category_group, name, TRACE_EVENT_FLAG_NONE, arg1_name, arg1_val, \
+ arg2_name, arg2_val)
+#define TRACE_EVENT_COPY_BEGIN0(category_group, name) \
+ INTERNAL_TRACE_EVENT_ADD(TRACE_EVENT_PHASE_BEGIN, \
+ category_group, name, TRACE_EVENT_FLAG_COPY)
+#define TRACE_EVENT_COPY_BEGIN1(category_group, name, arg1_name, arg1_val) \
+ INTERNAL_TRACE_EVENT_ADD(TRACE_EVENT_PHASE_BEGIN, \
+ category_group, name, TRACE_EVENT_FLAG_COPY, arg1_name, arg1_val)
+#define TRACE_EVENT_COPY_BEGIN2(category_group, name, arg1_name, arg1_val, \
+ arg2_name, arg2_val) \
+ INTERNAL_TRACE_EVENT_ADD(TRACE_EVENT_PHASE_BEGIN, \
+ category_group, name, TRACE_EVENT_FLAG_COPY, arg1_name, arg1_val, \
+ arg2_name, arg2_val)
+
+// Similar to TRACE_EVENT_BEGINx but with a custom |at| timestamp provided.
+// - |id| is used to match the _BEGIN event with the _END event.
+// Events are considered to match if their category_group, name and id values
+// all match. |id| must either be a pointer or an integer value up to 64 bits.
+// If it's a pointer, the bits will be xored with a hash of the process ID so
+// that the same pointer on two different processes will not collide.
+#define TRACE_EVENT_BEGIN_WITH_ID_TID_AND_TIMESTAMP0(category_group, \
+ name, id, thread_id, timestamp) \
+ INTERNAL_TRACE_EVENT_ADD_WITH_ID_TID_AND_TIMESTAMP( \
+ TRACE_EVENT_PHASE_ASYNC_BEGIN, category_group, name, id, thread_id, \
+ timestamp, TRACE_EVENT_FLAG_NONE)
+#define TRACE_EVENT_COPY_BEGIN_WITH_ID_TID_AND_TIMESTAMP0( \
+ category_group, name, id, thread_id, timestamp) \
+ INTERNAL_TRACE_EVENT_ADD_WITH_ID_TID_AND_TIMESTAMP( \
+ TRACE_EVENT_PHASE_ASYNC_BEGIN, category_group, name, id, thread_id, \
+ timestamp, TRACE_EVENT_FLAG_COPY)
+
+// Records a single END event for "name" immediately. If the category
+// is not enabled, then this does nothing.
+// - category and name strings must have application lifetime (statics or
+// literals). They may not include " chars.
+#define TRACE_EVENT_END0(category_group, name) \
+ INTERNAL_TRACE_EVENT_ADD(TRACE_EVENT_PHASE_END, \
+ category_group, name, TRACE_EVENT_FLAG_NONE)
+#define TRACE_EVENT_END1(category_group, name, arg1_name, arg1_val) \
+ INTERNAL_TRACE_EVENT_ADD(TRACE_EVENT_PHASE_END, \
+ category_group, name, TRACE_EVENT_FLAG_NONE, arg1_name, arg1_val)
+#define TRACE_EVENT_END2(category_group, name, arg1_name, arg1_val, \
+ arg2_name, arg2_val) \
+ INTERNAL_TRACE_EVENT_ADD(TRACE_EVENT_PHASE_END, \
+ category_group, name, TRACE_EVENT_FLAG_NONE, arg1_name, arg1_val, \
+ arg2_name, arg2_val)
+#define TRACE_EVENT_COPY_END0(category_group, name) \
+ INTERNAL_TRACE_EVENT_ADD(TRACE_EVENT_PHASE_END, \
+ category_group, name, TRACE_EVENT_FLAG_COPY)
+#define TRACE_EVENT_COPY_END1(category_group, name, arg1_name, arg1_val) \
+ INTERNAL_TRACE_EVENT_ADD(TRACE_EVENT_PHASE_END, \
+ category_group, name, TRACE_EVENT_FLAG_COPY, arg1_name, arg1_val)
+#define TRACE_EVENT_COPY_END2(category_group, name, arg1_name, arg1_val, \
+ arg2_name, arg2_val) \
+ INTERNAL_TRACE_EVENT_ADD(TRACE_EVENT_PHASE_END, \
+ category_group, name, TRACE_EVENT_FLAG_COPY, arg1_name, arg1_val, \
+ arg2_name, arg2_val)
+
+// Similar to TRACE_EVENT_ENDx but with a custom |at| timestamp provided.
+// - |id| is used to match the _BEGIN event with the _END event.
+// Events are considered to match if their category_group, name and id values
+// all match. |id| must either be a pointer or an integer value up to 64 bits.
+// If it's a pointer, the bits will be xored with a hash of the process ID so
+// that the same pointer on two different processes will not collide.
+#define TRACE_EVENT_END_WITH_ID_TID_AND_TIMESTAMP0(category_group, \
+ name, id, thread_id, timestamp) \
+ INTERNAL_TRACE_EVENT_ADD_WITH_ID_TID_AND_TIMESTAMP( \
+ TRACE_EVENT_PHASE_ASYNC_END, category_group, name, id, thread_id, \
+ timestamp, TRACE_EVENT_FLAG_NONE)
+#define TRACE_EVENT_COPY_END_WITH_ID_TID_AND_TIMESTAMP0( \
+ category_group, name, id, thread_id, timestamp) \
+ INTERNAL_TRACE_EVENT_ADD_WITH_ID_TID_AND_TIMESTAMP( \
+ TRACE_EVENT_PHASE_ASYNC_END, category_group, name, id, thread_id, \
+ timestamp, TRACE_EVENT_FLAG_COPY)
+
+// Records the value of a counter called "name" immediately. Value
+// must be representable as a 32 bit integer.
+// - category and name strings must have application lifetime (statics or
+// literals). They may not include " chars.
+#define TRACE_COUNTER1(category_group, name, value) \
+ INTERNAL_TRACE_EVENT_ADD(TRACE_EVENT_PHASE_COUNTER, \
+ category_group, name, TRACE_EVENT_FLAG_NONE, \
+ "value", static_cast<int>(value))
+#define TRACE_COPY_COUNTER1(category_group, name, value) \
+ INTERNAL_TRACE_EVENT_ADD(TRACE_EVENT_PHASE_COUNTER, \
+ category_group, name, TRACE_EVENT_FLAG_COPY, \
+ "value", static_cast<int>(value))
+
+// Records the values of a multi-parted counter called "name" immediately.
+// The UI will treat value1 and value2 as parts of a whole, displaying their
+// values as a stacked-bar chart.
+// - category and name strings must have application lifetime (statics or
+// literals). They may not include " chars.
+#define TRACE_COUNTER2(category_group, name, value1_name, value1_val, \
+ value2_name, value2_val) \
+ INTERNAL_TRACE_EVENT_ADD(TRACE_EVENT_PHASE_COUNTER, \
+ category_group, name, TRACE_EVENT_FLAG_NONE, \
+ value1_name, static_cast<int>(value1_val), \
+ value2_name, static_cast<int>(value2_val))
+#define TRACE_COPY_COUNTER2(category_group, name, value1_name, value1_val, \
+ value2_name, value2_val) \
+ INTERNAL_TRACE_EVENT_ADD(TRACE_EVENT_PHASE_COUNTER, \
+ category_group, name, TRACE_EVENT_FLAG_COPY, \
+ value1_name, static_cast<int>(value1_val), \
+ value2_name, static_cast<int>(value2_val))
+
+// Records the value of a counter called "name" immediately. Value
+// must be representable as a 32 bit integer.
+// - category and name strings must have application lifetime (statics or
+// literals). They may not include " chars.
+// - |id| is used to disambiguate counters with the same name. It must either
+// be a pointer or an integer value up to 64 bits. If it's a pointer, the bits
+// will be xored with a hash of the process ID so that the same pointer on
+// two different processes will not collide.
+#define TRACE_COUNTER_ID1(category_group, name, id, value) \
+ INTERNAL_TRACE_EVENT_ADD_WITH_ID(TRACE_EVENT_PHASE_COUNTER, \
+ category_group, name, id, TRACE_EVENT_FLAG_NONE, \
+ "value", static_cast<int>(value))
+#define TRACE_COPY_COUNTER_ID1(category_group, name, id, value) \
+ INTERNAL_TRACE_EVENT_ADD_WITH_ID(TRACE_EVENT_PHASE_COUNTER, \
+ category_group, name, id, TRACE_EVENT_FLAG_COPY, \
+ "value", static_cast<int>(value))
+
+// Records the values of a multi-parted counter called "name" immediately.
+// The UI will treat value1 and value2 as parts of a whole, displaying their
+// values as a stacked-bar chart.
+// - category and name strings must have application lifetime (statics or
+// literals). They may not include " chars.
+// - |id| is used to disambiguate counters with the same name. It must either
+// be a pointer or an integer value up to 64 bits. If it's a pointer, the bits
+// will be xored with a hash of the process ID so that the same pointer on
+// two different processes will not collide.
+#define TRACE_COUNTER_ID2(category_group, name, id, value1_name, value1_val, \
+ value2_name, value2_val) \
+ INTERNAL_TRACE_EVENT_ADD_WITH_ID(TRACE_EVENT_PHASE_COUNTER, \
+ category_group, name, id, TRACE_EVENT_FLAG_NONE, \
+ value1_name, static_cast<int>(value1_val), \
+ value2_name, static_cast<int>(value2_val))
+#define TRACE_COPY_COUNTER_ID2(category_group, name, id, value1_name, \
+ value1_val, value2_name, value2_val) \
+ INTERNAL_TRACE_EVENT_ADD_WITH_ID(TRACE_EVENT_PHASE_COUNTER, \
+ category_group, name, id, TRACE_EVENT_FLAG_COPY, \
+ value1_name, static_cast<int>(value1_val), \
+ value2_name, static_cast<int>(value2_val))
+
+
+// Records a single ASYNC_BEGIN event called "name" immediately, with 0, 1 or 2
+// associated arguments. If the category is not enabled, then this
+// does nothing.
+// - category and name strings must have application lifetime (statics or
+// literals). They may not include " chars.
+// - |id| is used to match the ASYNC_BEGIN event with the ASYNC_END event. ASYNC
+// events are considered to match if their category_group, name and id values
+// all match. |id| must either be a pointer or an integer value up to 64 bits.
+// If it's a pointer, the bits will be xored with a hash of the process ID so
+// that the same pointer on two different processes will not collide.
+// An asynchronous operation can consist of multiple phases. The first phase is
+// defined by the ASYNC_BEGIN calls. Additional phases can be defined using the
+// ASYNC_STEP macros. When the operation completes, call ASYNC_END.
+// An ASYNC trace typically occur on a single thread (if not, they will only be
+// drawn on the thread defined in the ASYNC_BEGIN event), but all events in that
+// operation must use the same |name| and |id|. Each event can have its own
+// args.
+#define TRACE_EVENT_ASYNC_BEGIN0(category_group, name, id) \
+ INTERNAL_TRACE_EVENT_ADD_WITH_ID(TRACE_EVENT_PHASE_ASYNC_BEGIN, \
+ category_group, name, id, TRACE_EVENT_FLAG_NONE)
+#define TRACE_EVENT_ASYNC_BEGIN1(category_group, name, id, arg1_name, \
+ arg1_val) \
+ INTERNAL_TRACE_EVENT_ADD_WITH_ID(TRACE_EVENT_PHASE_ASYNC_BEGIN, \
+ category_group, name, id, TRACE_EVENT_FLAG_NONE, arg1_name, arg1_val)
+#define TRACE_EVENT_ASYNC_BEGIN2(category_group, name, id, arg1_name, \
+ arg1_val, arg2_name, arg2_val) \
+ INTERNAL_TRACE_EVENT_ADD_WITH_ID(TRACE_EVENT_PHASE_ASYNC_BEGIN, \
+ category_group, name, id, TRACE_EVENT_FLAG_NONE, \
+ arg1_name, arg1_val, arg2_name, arg2_val)
+#define TRACE_EVENT_COPY_ASYNC_BEGIN0(category_group, name, id) \
+ INTERNAL_TRACE_EVENT_ADD_WITH_ID(TRACE_EVENT_PHASE_ASYNC_BEGIN, \
+ category_group, name, id, TRACE_EVENT_FLAG_COPY)
+#define TRACE_EVENT_COPY_ASYNC_BEGIN1(category_group, name, id, arg1_name, \
+ arg1_val) \
+ INTERNAL_TRACE_EVENT_ADD_WITH_ID(TRACE_EVENT_PHASE_ASYNC_BEGIN, \
+ category_group, name, id, TRACE_EVENT_FLAG_COPY, \
+ arg1_name, arg1_val)
+#define TRACE_EVENT_COPY_ASYNC_BEGIN2(category_group, name, id, arg1_name, \
+ arg1_val, arg2_name, arg2_val) \
+ INTERNAL_TRACE_EVENT_ADD_WITH_ID(TRACE_EVENT_PHASE_ASYNC_BEGIN, \
+ category_group, name, id, TRACE_EVENT_FLAG_COPY, \
+ arg1_name, arg1_val, arg2_name, arg2_val)
+
+// Records a single ASYNC_STEP event for |step| immediately. If the category
+// is not enabled, then this does nothing. The |name| and |id| must match the
+// ASYNC_BEGIN event above. The |step| param identifies this step within the
+// async event. This should be called at the beginning of the next phase of an
+// asynchronous operation.
+#define TRACE_EVENT_ASYNC_STEP0(category_group, name, id, step) \
+ INTERNAL_TRACE_EVENT_ADD_WITH_ID(TRACE_EVENT_PHASE_ASYNC_STEP, \
+ category_group, name, id, TRACE_EVENT_FLAG_NONE, "step", step)
+#define TRACE_EVENT_ASYNC_STEP1(category_group, name, id, step, \
+ arg1_name, arg1_val) \
+ INTERNAL_TRACE_EVENT_ADD_WITH_ID(TRACE_EVENT_PHASE_ASYNC_STEP, \
+ category_group, name, id, TRACE_EVENT_FLAG_NONE, "step", step, \
+ arg1_name, arg1_val)
+#define TRACE_EVENT_COPY_ASYNC_STEP0(category_group, name, id, step) \
+ INTERNAL_TRACE_EVENT_ADD_WITH_ID(TRACE_EVENT_PHASE_ASYNC_STEP, \
+ category_group, name, id, TRACE_EVENT_FLAG_COPY, "step", step)
+#define TRACE_EVENT_COPY_ASYNC_STEP1(category_group, name, id, step, \
+ arg1_name, arg1_val) \
+ INTERNAL_TRACE_EVENT_ADD_WITH_ID(TRACE_EVENT_PHASE_ASYNC_STEP, \
+ category_group, name, id, TRACE_EVENT_FLAG_COPY, "step", step, \
+ arg1_name, arg1_val)
+
+// Records a single ASYNC_END event for "name" immediately. If the category
+// is not enabled, then this does nothing.
+#define TRACE_EVENT_ASYNC_END0(category_group, name, id) \
+ INTERNAL_TRACE_EVENT_ADD_WITH_ID(TRACE_EVENT_PHASE_ASYNC_END, \
+ category_group, name, id, TRACE_EVENT_FLAG_NONE)
+#define TRACE_EVENT_ASYNC_END1(category_group, name, id, arg1_name, arg1_val) \
+ INTERNAL_TRACE_EVENT_ADD_WITH_ID(TRACE_EVENT_PHASE_ASYNC_END, \
+ category_group, name, id, TRACE_EVENT_FLAG_NONE, arg1_name, arg1_val)
+#define TRACE_EVENT_ASYNC_END2(category_group, name, id, arg1_name, arg1_val, \
+ arg2_name, arg2_val) \
+ INTERNAL_TRACE_EVENT_ADD_WITH_ID(TRACE_EVENT_PHASE_ASYNC_END, \
+ category_group, name, id, TRACE_EVENT_FLAG_NONE, \
+ arg1_name, arg1_val, arg2_name, arg2_val)
+#define TRACE_EVENT_COPY_ASYNC_END0(category_group, name, id) \
+ INTERNAL_TRACE_EVENT_ADD_WITH_ID(TRACE_EVENT_PHASE_ASYNC_END, \
+ category_group, name, id, TRACE_EVENT_FLAG_COPY)
+#define TRACE_EVENT_COPY_ASYNC_END1(category_group, name, id, arg1_name, \
+ arg1_val) \
+ INTERNAL_TRACE_EVENT_ADD_WITH_ID(TRACE_EVENT_PHASE_ASYNC_END, \
+ category_group, name, id, TRACE_EVENT_FLAG_COPY, \
+ arg1_name, arg1_val)
+#define TRACE_EVENT_COPY_ASYNC_END2(category_group, name, id, arg1_name, \
+ arg1_val, arg2_name, arg2_val) \
+ INTERNAL_TRACE_EVENT_ADD_WITH_ID(TRACE_EVENT_PHASE_ASYNC_END, \
+ category_group, name, id, TRACE_EVENT_FLAG_COPY, \
+ arg1_name, arg1_val, arg2_name, arg2_val)
+
+
+// Records a single FLOW_BEGIN event called "name" immediately, with 0, 1 or 2
+// associated arguments. If the category is not enabled, then this
+// does nothing.
+// - category and name strings must have application lifetime (statics or
+// literals). They may not include " chars.
+// - |id| is used to match the FLOW_BEGIN event with the FLOW_END event. FLOW
+// events are considered to match if their category_group, name and id values
+// all match. |id| must either be a pointer or an integer value up to 64 bits.
+// If it's a pointer, the bits will be xored with a hash of the process ID so
+// that the same pointer on two different processes will not collide.
+// FLOW events are different from ASYNC events in how they are drawn by the
+// tracing UI. A FLOW defines asynchronous data flow, such as posting a task
+// (FLOW_BEGIN) and later executing that task (FLOW_END). Expect FLOWs to be
+// drawn as lines or arrows from FLOW_BEGIN scopes to FLOW_END scopes. Similar
+// to ASYNC, a FLOW can consist of multiple phases. The first phase is defined
+// by the FLOW_BEGIN calls. Additional phases can be defined using the FLOW_STEP
+// macros. When the operation completes, call FLOW_END. An async operation can
+// span threads and processes, but all events in that operation must use the
+// same |name| and |id|. Each event can have its own args.
+#define TRACE_EVENT_FLOW_BEGIN0(category_group, name, id) \
+ INTERNAL_TRACE_EVENT_ADD_WITH_ID(TRACE_EVENT_PHASE_FLOW_BEGIN, \
+ category_group, name, id, TRACE_EVENT_FLAG_NONE)
+#define TRACE_EVENT_FLOW_BEGIN1(category_group, name, id, arg1_name, arg1_val) \
+ INTERNAL_TRACE_EVENT_ADD_WITH_ID(TRACE_EVENT_PHASE_FLOW_BEGIN, \
+ category_group, name, id, TRACE_EVENT_FLAG_NONE, arg1_name, arg1_val)
+#define TRACE_EVENT_FLOW_BEGIN2(category_group, name, id, arg1_name, arg1_val, \
+ arg2_name, arg2_val) \
+ INTERNAL_TRACE_EVENT_ADD_WITH_ID(TRACE_EVENT_PHASE_FLOW_BEGIN, \
+ category_group, name, id, TRACE_EVENT_FLAG_NONE, \
+ arg1_name, arg1_val, arg2_name, arg2_val)
+#define TRACE_EVENT_COPY_FLOW_BEGIN0(category_group, name, id) \
+ INTERNAL_TRACE_EVENT_ADD_WITH_ID(TRACE_EVENT_PHASE_FLOW_BEGIN, \
+ category_group, name, id, TRACE_EVENT_FLAG_COPY)
+#define TRACE_EVENT_COPY_FLOW_BEGIN1(category_group, name, id, arg1_name, \
+ arg1_val) \
+ INTERNAL_TRACE_EVENT_ADD_WITH_ID(TRACE_EVENT_PHASE_FLOW_BEGIN, \
+ category_group, name, id, TRACE_EVENT_FLAG_COPY, \
+ arg1_name, arg1_val)
+#define TRACE_EVENT_COPY_FLOW_BEGIN2(category_group, name, id, arg1_name, \
+ arg1_val, arg2_name, arg2_val) \
+ INTERNAL_TRACE_EVENT_ADD_WITH_ID(TRACE_EVENT_PHASE_FLOW_BEGIN, \
+ category_group, name, id, TRACE_EVENT_FLAG_COPY, \
+ arg1_name, arg1_val, arg2_name, arg2_val)
+
+// Records a single FLOW_STEP event for |step| immediately. If the category
+// is not enabled, then this does nothing. The |name| and |id| must match the
+// FLOW_BEGIN event above. The |step| param identifies this step within the
+// async event. This should be called at the beginning of the next phase of an
+// asynchronous operation.
+#define TRACE_EVENT_FLOW_STEP0(category_group, name, id, step) \
+ INTERNAL_TRACE_EVENT_ADD_WITH_ID(TRACE_EVENT_PHASE_FLOW_STEP, \
+ category_group, name, id, TRACE_EVENT_FLAG_NONE, "step", step)
+#define TRACE_EVENT_FLOW_STEP1(category_group, name, id, step, \
+ arg1_name, arg1_val) \
+ INTERNAL_TRACE_EVENT_ADD_WITH_ID(TRACE_EVENT_PHASE_FLOW_STEP, \
+ category_group, name, id, TRACE_EVENT_FLAG_NONE, "step", step, \
+ arg1_name, arg1_val)
+#define TRACE_EVENT_COPY_FLOW_STEP0(category_group, name, id, step) \
+ INTERNAL_TRACE_EVENT_ADD_WITH_ID(TRACE_EVENT_PHASE_FLOW_STEP, \
+ category_group, name, id, TRACE_EVENT_FLAG_COPY, "step", step)
+#define TRACE_EVENT_COPY_FLOW_STEP1(category_group, name, id, step, \
+ arg1_name, arg1_val) \
+ INTERNAL_TRACE_EVENT_ADD_WITH_ID(TRACE_EVENT_PHASE_FLOW_STEP, \
+ category_group, name, id, TRACE_EVENT_FLAG_COPY, "step", step, \
+ arg1_name, arg1_val)
+
+// Records a single FLOW_END event for "name" immediately. If the category
+// is not enabled, then this does nothing.
+#define TRACE_EVENT_FLOW_END0(category_group, name, id) \
+ INTERNAL_TRACE_EVENT_ADD_WITH_ID(TRACE_EVENT_PHASE_FLOW_END, \
+ category_group, name, id, TRACE_EVENT_FLAG_NONE)
+#define TRACE_EVENT_FLOW_END1(category_group, name, id, arg1_name, arg1_val) \
+ INTERNAL_TRACE_EVENT_ADD_WITH_ID(TRACE_EVENT_PHASE_FLOW_END, \
+ category_group, name, id, TRACE_EVENT_FLAG_NONE, arg1_name, arg1_val)
+#define TRACE_EVENT_FLOW_END2(category_group, name, id, arg1_name, arg1_val, \
+ arg2_name, arg2_val) \
+ INTERNAL_TRACE_EVENT_ADD_WITH_ID(TRACE_EVENT_PHASE_FLOW_END, \
+ category_group, name, id, TRACE_EVENT_FLAG_NONE, \
+ arg1_name, arg1_val, arg2_name, arg2_val)
+#define TRACE_EVENT_COPY_FLOW_END0(category_group, name, id) \
+ INTERNAL_TRACE_EVENT_ADD_WITH_ID(TRACE_EVENT_PHASE_FLOW_END, \
+ category_group, name, id, TRACE_EVENT_FLAG_COPY)
+#define TRACE_EVENT_COPY_FLOW_END1(category_group, name, id, arg1_name, \
+ arg1_val) \
+ INTERNAL_TRACE_EVENT_ADD_WITH_ID(TRACE_EVENT_PHASE_FLOW_END, \
+ category_group, name, id, TRACE_EVENT_FLAG_COPY, \
+ arg1_name, arg1_val)
+#define TRACE_EVENT_COPY_FLOW_END2(category_group, name, id, arg1_name, \
+ arg1_val, arg2_name, arg2_val) \
+ INTERNAL_TRACE_EVENT_ADD_WITH_ID(TRACE_EVENT_PHASE_FLOW_END, \
+ category_group, name, id, TRACE_EVENT_FLAG_COPY, \
+ arg1_name, arg1_val, arg2_name, arg2_val)
+
+// Macros to track the life time and value of arbitratry client objects.
+// See also TraceTrackableObject.
+#define TRACE_EVENT_OBJECT_CREATED_WITH_ID(category_group, name, id) \
+ INTERNAL_TRACE_EVENT_ADD_WITH_ID(TRACE_EVENT_PHASE_CREATE_OBJECT, \
+ category_group, name, TRACE_ID_DONT_MANGLE(id), TRACE_EVENT_FLAG_NONE)
+
+#define TRACE_EVENT_OBJECT_SNAPSHOT_WITH_ID(category_group, name, id, snapshot) \
+ INTERNAL_TRACE_EVENT_ADD_WITH_ID(TRACE_EVENT_PHASE_SNAPSHOT_OBJECT, \
+ category_group, name, TRACE_ID_DONT_MANGLE(id), TRACE_EVENT_FLAG_NONE,\
+ "snapshot", snapshot)
+
+#define TRACE_EVENT_OBJECT_DELETED_WITH_ID(category_group, name, id) \
+ INTERNAL_TRACE_EVENT_ADD_WITH_ID(TRACE_EVENT_PHASE_DELETE_OBJECT, \
+ category_group, name, TRACE_ID_DONT_MANGLE(id), TRACE_EVENT_FLAG_NONE)
+
+
////////////////////////////////////////////////////////////////////////////////
// Implementation specific tracing API definitions.
// Get a pointer to the enabled state of the given trace category. Only
-// long-lived literal strings should be given as the category name. The returned
-// pointer can be held permanently in a local static for example. If the
-// unsigned char is non-zero, tracing is enabled. If tracing is enabled,
+// long-lived literal strings should be given as the category group. The
+// returned pointer can be held permanently in a local static for example. If
+// the unsigned char is non-zero, tracing is enabled. If tracing is enabled,
// TRACE_EVENT_API_ADD_TRACE_EVENT can be called. It's OK if tracing is disabled
// between the load of the tracing state and the call to
// TRACE_EVENT_API_ADD_TRACE_EVENT, because this flag only provides an early out
// for best performance when tracing is disabled.
// const unsigned char*
-// TRACE_EVENT_API_GET_CATEGORY_ENABLED(const char* category_name)
-#define TRACE_EVENT_API_GET_CATEGORY_ENABLED \
- base::debug::TraceLog::GetCategoryEnabled
+// TRACE_EVENT_API_GET_CATEGORY_GROUP_ENABLED(const char* category_group)
+#define TRACE_EVENT_API_GET_CATEGORY_GROUP_ENABLED \
+ base::debug::TraceLog::GetCategoryGroupEnabled
// Add a trace event to the platform tracing system.
// void TRACE_EVENT_API_ADD_TRACE_EVENT(
// char phase,
-// const unsigned char* category_enabled,
+// const unsigned char* category_group_enabled,
// const char* name,
// unsigned long long id,
// int num_args,
@@ -47,7 +695,7 @@
// Add a trace event to the platform tracing system.
// void TRACE_EVENT_API_ADD_TRACE_EVENT_WITH_TIMESTAMP(
// char phase,
-// const unsigned char* category_enabled,
+// const unsigned char* category_group_enabled,
// const char* name,
// unsigned long long id,
// int thread_id,
@@ -66,7 +714,7 @@
#define TRACE_EVENT_API_ATOMIC_STORE(var, value) \
base::subtle::NoBarrier_Store(&(var), (value))
-// Defines visibility for classes in trace_event_internal.h
+// Defines visibility for classes in trace_event.h
#define TRACE_EVENT_API_CLASS_EXPORT BASE_EXPORT
// The thread buckets for the sampling profiler.
@@ -78,26 +726,606 @@
////////////////////////////////////////////////////////////////////////////////
-#include "base/debug/trace_event_internal.h"
+// Implementation detail: trace event macros create temporary variables
+// to keep instrumentation overhead low. These macros give each temporary
+// variable a unique name based on the line number to prevent name collissions.
+#define INTERNAL_TRACE_EVENT_UID3(a,b) \
+ trace_event_unique_##a##b
+#define INTERNAL_TRACE_EVENT_UID2(a,b) \
+ INTERNAL_TRACE_EVENT_UID3(a,b)
+#define INTERNAL_TRACE_EVENT_UID(name_prefix) \
+ INTERNAL_TRACE_EVENT_UID2(name_prefix, __LINE__)
+
+// Implementation detail: internal macro to create static category.
+// No barriers are needed, because this code is designed to operate safely
+// even when the unsigned char* points to garbage data (which may be the case
+// on processors without cache coherency).
+#define INTERNAL_TRACE_EVENT_GET_CATEGORY_INFO(category_group) \
+ static TRACE_EVENT_API_ATOMIC_WORD INTERNAL_TRACE_EVENT_UID(atomic) = 0; \
+ const unsigned char* INTERNAL_TRACE_EVENT_UID(catstatic) = \
+ reinterpret_cast<const unsigned char*>(TRACE_EVENT_API_ATOMIC_LOAD( \
+ INTERNAL_TRACE_EVENT_UID(atomic))); \
+ if (!INTERNAL_TRACE_EVENT_UID(catstatic)) { \
+ INTERNAL_TRACE_EVENT_UID(catstatic) = \
+ TRACE_EVENT_API_GET_CATEGORY_GROUP_ENABLED(category_group); \
+ TRACE_EVENT_API_ATOMIC_STORE(INTERNAL_TRACE_EVENT_UID(atomic), \
+ reinterpret_cast<TRACE_EVENT_API_ATOMIC_WORD>( \
+ INTERNAL_TRACE_EVENT_UID(catstatic))); \
+ }
+
+// Implementation detail: internal macro to create static category and add
+// event if the category is enabled.
+#define INTERNAL_TRACE_EVENT_ADD(phase, category_group, name, flags, ...) \
+ do { \
+ INTERNAL_TRACE_EVENT_GET_CATEGORY_INFO(category_group); \
+ if (*INTERNAL_TRACE_EVENT_UID(catstatic)) { \
+ trace_event_internal::AddTraceEvent( \
+ phase, INTERNAL_TRACE_EVENT_UID(catstatic), name, \
+ trace_event_internal::kNoEventId, flags, ##__VA_ARGS__); \
+ } \
+ } while (0)
+
+// Implementation detail: internal macro to create static category and add begin
+// event if the category is enabled. Also adds the end event when the scope
+// ends.
+#define INTERNAL_TRACE_EVENT_ADD_SCOPED(category_group, name, ...) \
+ INTERNAL_TRACE_EVENT_GET_CATEGORY_INFO(category_group); \
+ trace_event_internal::TraceEndOnScopeClose \
+ INTERNAL_TRACE_EVENT_UID(profileScope); \
+ if (*INTERNAL_TRACE_EVENT_UID(catstatic)) { \
+ trace_event_internal::AddTraceEvent( \
+ TRACE_EVENT_PHASE_BEGIN, \
+ INTERNAL_TRACE_EVENT_UID(catstatic), \
+ name, trace_event_internal::kNoEventId, \
+ TRACE_EVENT_FLAG_NONE, ##__VA_ARGS__); \
+ INTERNAL_TRACE_EVENT_UID(profileScope).Initialize( \
+ INTERNAL_TRACE_EVENT_UID(catstatic), name); \
+ }
+
+// Implementation detail: internal macro to create static category and add
+// event if the category is enabled.
+#define INTERNAL_TRACE_EVENT_ADD_WITH_ID(phase, category_group, name, id, \
+ flags, ...) \
+ do { \
+ INTERNAL_TRACE_EVENT_GET_CATEGORY_INFO(category_group); \
+ if (*INTERNAL_TRACE_EVENT_UID(catstatic)) { \
+ unsigned char trace_event_flags = flags | TRACE_EVENT_FLAG_HAS_ID; \
+ trace_event_internal::TraceID trace_event_trace_id( \
+ id, &trace_event_flags); \
+ trace_event_internal::AddTraceEvent( \
+ phase, INTERNAL_TRACE_EVENT_UID(catstatic), \
+ name, trace_event_trace_id.data(), trace_event_flags, \
+ ##__VA_ARGS__); \
+ } \
+ } while (0)
+
+// Implementation detail: internal macro to create static category and add
+// event if the category is enabled.
+#define INTERNAL_TRACE_EVENT_ADD_WITH_ID_TID_AND_TIMESTAMP(phase, \
+ category_group, name, id, thread_id, timestamp, flags, ...) \
+ do { \
+ INTERNAL_TRACE_EVENT_GET_CATEGORY_INFO(category_group); \
+ if (*INTERNAL_TRACE_EVENT_UID(catstatic)) { \
+ unsigned char trace_event_flags = flags | TRACE_EVENT_FLAG_HAS_ID; \
+ trace_event_internal::TraceID trace_event_trace_id( \
+ id, &trace_event_flags); \
+ trace_event_internal::AddTraceEventWithThreadIdAndTimestamp( \
+ phase, INTERNAL_TRACE_EVENT_UID(catstatic), \
+ name, trace_event_trace_id.data(), \
+ thread_id, base::TimeTicks::FromInternalValue(timestamp), \
+ trace_event_flags, ##__VA_ARGS__); \
+ } \
+ } while (0)
+
+// Notes regarding the following definitions:
+// New values can be added and propagated to third party libraries, but existing
+// definitions must never be changed, because third party libraries may use old
+// definitions.
+
+// Phase indicates the nature of an event entry. E.g. part of a begin/end pair.
+#define TRACE_EVENT_PHASE_BEGIN ('B')
+#define TRACE_EVENT_PHASE_END ('E')
+#define TRACE_EVENT_PHASE_INSTANT ('i')
+#define TRACE_EVENT_PHASE_ASYNC_BEGIN ('S')
+#define TRACE_EVENT_PHASE_ASYNC_STEP ('T')
+#define TRACE_EVENT_PHASE_ASYNC_END ('F')
+#define TRACE_EVENT_PHASE_FLOW_BEGIN ('s')
+#define TRACE_EVENT_PHASE_FLOW_STEP ('t')
+#define TRACE_EVENT_PHASE_FLOW_END ('f')
+#define TRACE_EVENT_PHASE_METADATA ('M')
+#define TRACE_EVENT_PHASE_COUNTER ('C')
+#define TRACE_EVENT_PHASE_SAMPLE ('P')
+#define TRACE_EVENT_PHASE_CREATE_OBJECT ('N')
+#define TRACE_EVENT_PHASE_SNAPSHOT_OBJECT ('O')
+#define TRACE_EVENT_PHASE_DELETE_OBJECT ('D')
+
+// Flags for changing the behavior of TRACE_EVENT_API_ADD_TRACE_EVENT.
+#define TRACE_EVENT_FLAG_NONE (static_cast<unsigned char>(0))
+#define TRACE_EVENT_FLAG_COPY (static_cast<unsigned char>(1 << 0))
+#define TRACE_EVENT_FLAG_HAS_ID (static_cast<unsigned char>(1 << 1))
+#define TRACE_EVENT_FLAG_MANGLE_ID (static_cast<unsigned char>(1 << 2))
+#define TRACE_EVENT_FLAG_SCOPE_OFFSET (static_cast<unsigned char>(1 << 3))
+
+#define TRACE_EVENT_FLAG_SCOPE_MASK (static_cast<unsigned char>( \
+ TRACE_EVENT_FLAG_SCOPE_OFFSET | (TRACE_EVENT_FLAG_SCOPE_OFFSET << 1)))
+
+// Type values for identifying types in the TraceValue union.
+#define TRACE_VALUE_TYPE_BOOL (static_cast<unsigned char>(1))
+#define TRACE_VALUE_TYPE_UINT (static_cast<unsigned char>(2))
+#define TRACE_VALUE_TYPE_INT (static_cast<unsigned char>(3))
+#define TRACE_VALUE_TYPE_DOUBLE (static_cast<unsigned char>(4))
+#define TRACE_VALUE_TYPE_POINTER (static_cast<unsigned char>(5))
+#define TRACE_VALUE_TYPE_STRING (static_cast<unsigned char>(6))
+#define TRACE_VALUE_TYPE_COPY_STRING (static_cast<unsigned char>(7))
+#define TRACE_VALUE_TYPE_CONVERTABLE (static_cast<unsigned char>(8))
+
+// Enum reflecting the scope of an INSTANT event. Must fit within
+// TRACE_EVENT_FLAG_SCOPE_MASK.
+#define TRACE_EVENT_SCOPE_GLOBAL (static_cast<unsigned char>(0 << 3))
+#define TRACE_EVENT_SCOPE_PROCESS (static_cast<unsigned char>(1 << 3))
+#define TRACE_EVENT_SCOPE_THREAD (static_cast<unsigned char>(2 << 3))
+
+#define TRACE_EVENT_SCOPE_NAME_GLOBAL ('g')
+#define TRACE_EVENT_SCOPE_NAME_PROCESS ('p')
+#define TRACE_EVENT_SCOPE_NAME_THREAD ('t')
+
+namespace trace_event_internal {
+
+// Specify these values when the corresponding argument of AddTraceEvent is not
+// used.
+const int kZeroNumArgs = 0;
+const unsigned long long kNoEventId = 0;
+
+// TraceID encapsulates an ID that can either be an integer or pointer. Pointers
+// are by default mangled with the Process ID so that they are unlikely to
+// collide when the same pointer is used on different processes.
+class TraceID {
+ public:
+ class DontMangle {
+ public:
+ explicit DontMangle(void* id)
+ : data_(static_cast<unsigned long long>(
+ reinterpret_cast<unsigned long>(id))) {}
+ explicit DontMangle(unsigned long long id) : data_(id) {}
+ explicit DontMangle(unsigned long id) : data_(id) {}
+ explicit DontMangle(unsigned int id) : data_(id) {}
+ explicit DontMangle(unsigned short id) : data_(id) {}
+ explicit DontMangle(unsigned char id) : data_(id) {}
+ explicit DontMangle(long long id)
+ : data_(static_cast<unsigned long long>(id)) {}
+ explicit DontMangle(long id)
+ : data_(static_cast<unsigned long long>(id)) {}
+ explicit DontMangle(int id)
+ : data_(static_cast<unsigned long long>(id)) {}
+ explicit DontMangle(short id)
+ : data_(static_cast<unsigned long long>(id)) {}
+ explicit DontMangle(signed char id)
+ : data_(static_cast<unsigned long long>(id)) {}
+ unsigned long long data() const { return data_; }
+ private:
+ unsigned long long data_;
+ };
+
+ class ForceMangle {
+ public:
+ explicit ForceMangle(unsigned long long id) : data_(id) {}
+ explicit ForceMangle(unsigned long id) : data_(id) {}
+ explicit ForceMangle(unsigned int id) : data_(id) {}
+ explicit ForceMangle(unsigned short id) : data_(id) {}
+ explicit ForceMangle(unsigned char id) : data_(id) {}
+ explicit ForceMangle(long long id)
+ : data_(static_cast<unsigned long long>(id)) {}
+ explicit ForceMangle(long id)
+ : data_(static_cast<unsigned long long>(id)) {}
+ explicit ForceMangle(int id)
+ : data_(static_cast<unsigned long long>(id)) {}
+ explicit ForceMangle(short id)
+ : data_(static_cast<unsigned long long>(id)) {}
+ explicit ForceMangle(signed char id)
+ : data_(static_cast<unsigned long long>(id)) {}
+ unsigned long long data() const { return data_; }
+ private:
+ unsigned long long data_;
+ };
+
+ TraceID(const void* id, unsigned char* flags)
+ : data_(static_cast<unsigned long long>(
+ reinterpret_cast<unsigned long>(id))) {
+ *flags |= TRACE_EVENT_FLAG_MANGLE_ID;
+ }
+ TraceID(ForceMangle id, unsigned char* flags) : data_(id.data()) {
+ *flags |= TRACE_EVENT_FLAG_MANGLE_ID;
+ }
+ TraceID(DontMangle id, unsigned char* flags) : data_(id.data()) {
+ }
+ TraceID(unsigned long long id, unsigned char* flags)
+ : data_(id) { (void)flags; }
+ TraceID(unsigned long id, unsigned char* flags)
+ : data_(id) { (void)flags; }
+ TraceID(unsigned int id, unsigned char* flags)
+ : data_(id) { (void)flags; }
+ TraceID(unsigned short id, unsigned char* flags)
+ : data_(id) { (void)flags; }
+ TraceID(unsigned char id, unsigned char* flags)
+ : data_(id) { (void)flags; }
+ TraceID(long long id, unsigned char* flags)
+ : data_(static_cast<unsigned long long>(id)) { (void)flags; }
+ TraceID(long id, unsigned char* flags)
+ : data_(static_cast<unsigned long long>(id)) { (void)flags; }
+ TraceID(int id, unsigned char* flags)
+ : data_(static_cast<unsigned long long>(id)) { (void)flags; }
+ TraceID(short id, unsigned char* flags)
+ : data_(static_cast<unsigned long long>(id)) { (void)flags; }
+ TraceID(signed char id, unsigned char* flags)
+ : data_(static_cast<unsigned long long>(id)) { (void)flags; }
+
+ unsigned long long data() const { return data_; }
+
+ private:
+ unsigned long long data_;
+};
+
+// Simple union to store various types as unsigned long long.
+union TraceValueUnion {
+ bool as_bool;
+ unsigned long long as_uint;
+ long long as_int;
+ double as_double;
+ const void* as_pointer;
+ const char* as_string;
+};
+
+// Simple container for const char* that should be copied instead of retained.
+class TraceStringWithCopy {
+ public:
+ explicit TraceStringWithCopy(const char* str) : str_(str) {}
+ operator const char* () const { return str_; }
+ private:
+ const char* str_;
+};
+
+// Define SetTraceValue for each allowed type. It stores the type and
+// value in the return arguments. This allows this API to avoid declaring any
+// structures so that it is portable to third_party libraries.
+#define INTERNAL_DECLARE_SET_TRACE_VALUE(actual_type, \
+ union_member, \
+ value_type_id) \
+ static inline void SetTraceValue( \
+ actual_type arg, \
+ unsigned char* type, \
+ unsigned long long* value) { \
+ TraceValueUnion type_value; \
+ type_value.union_member = arg; \
+ *type = value_type_id; \
+ *value = type_value.as_uint; \
+ }
+// Simpler form for int types that can be safely casted.
+#define INTERNAL_DECLARE_SET_TRACE_VALUE_INT(actual_type, \
+ value_type_id) \
+ static inline void SetTraceValue( \
+ actual_type arg, \
+ unsigned char* type, \
+ unsigned long long* value) { \
+ *type = value_type_id; \
+ *value = static_cast<unsigned long long>(arg); \
+ }
+
+INTERNAL_DECLARE_SET_TRACE_VALUE_INT(unsigned long long, TRACE_VALUE_TYPE_UINT)
+INTERNAL_DECLARE_SET_TRACE_VALUE_INT(unsigned long, TRACE_VALUE_TYPE_UINT)
+INTERNAL_DECLARE_SET_TRACE_VALUE_INT(unsigned int, TRACE_VALUE_TYPE_UINT)
+INTERNAL_DECLARE_SET_TRACE_VALUE_INT(unsigned short, TRACE_VALUE_TYPE_UINT)
+INTERNAL_DECLARE_SET_TRACE_VALUE_INT(unsigned char, TRACE_VALUE_TYPE_UINT)
+INTERNAL_DECLARE_SET_TRACE_VALUE_INT(long long, TRACE_VALUE_TYPE_INT)
+INTERNAL_DECLARE_SET_TRACE_VALUE_INT(long, TRACE_VALUE_TYPE_INT)
+INTERNAL_DECLARE_SET_TRACE_VALUE_INT(int, TRACE_VALUE_TYPE_INT)
+INTERNAL_DECLARE_SET_TRACE_VALUE_INT(short, TRACE_VALUE_TYPE_INT)
+INTERNAL_DECLARE_SET_TRACE_VALUE_INT(signed char, TRACE_VALUE_TYPE_INT)
+INTERNAL_DECLARE_SET_TRACE_VALUE(bool, as_bool, TRACE_VALUE_TYPE_BOOL)
+INTERNAL_DECLARE_SET_TRACE_VALUE(double, as_double, TRACE_VALUE_TYPE_DOUBLE)
+INTERNAL_DECLARE_SET_TRACE_VALUE(const void*, as_pointer,
+ TRACE_VALUE_TYPE_POINTER)
+INTERNAL_DECLARE_SET_TRACE_VALUE(const char*, as_string,
+ TRACE_VALUE_TYPE_STRING)
+INTERNAL_DECLARE_SET_TRACE_VALUE(const TraceStringWithCopy&, as_string,
+ TRACE_VALUE_TYPE_COPY_STRING)
+
+#undef INTERNAL_DECLARE_SET_TRACE_VALUE
+#undef INTERNAL_DECLARE_SET_TRACE_VALUE_INT
+
+// std::string version of SetTraceValue so that trace arguments can be strings.
+static inline void SetTraceValue(const std::string& arg,
+ unsigned char* type,
+ unsigned long long* value) {
+ TraceValueUnion type_value;
+ type_value.as_string = arg.c_str();
+ *type = TRACE_VALUE_TYPE_COPY_STRING;
+ *value = type_value.as_uint;
+}
+
+// These AddTraceEvent and AddTraceEventWithThreadIdAndTimestamp template
+// functions are defined here instead of in the macro, because the arg_values
+// could be temporary objects, such as std::string. In order to store
+// pointers to the internal c_str and pass through to the tracing API,
+// the arg_values must live throughout these procedures.
+
+static inline void AddTraceEventWithThreadIdAndTimestamp(
+ char phase,
+ const unsigned char* category_group_enabled,
+ const char* name,
+ unsigned long long id,
+ int thread_id,
+ const base::TimeTicks& timestamp,
+ unsigned char flags,
+ const char* arg1_name,
+ scoped_ptr<base::debug::ConvertableToTraceFormat> arg1_val) {
+ const int num_args = 1;
+ unsigned char arg_types[1] = { TRACE_VALUE_TYPE_CONVERTABLE };
+ scoped_ptr<base::debug::ConvertableToTraceFormat> convertable_values[1];
+ convertable_values[0].reset(arg1_val.release());
+
+ TRACE_EVENT_API_ADD_TRACE_EVENT_WITH_THREAD_ID_AND_TIMESTAMP(
+ phase, category_group_enabled, name, id, thread_id, timestamp,
+ num_args, &arg1_name, arg_types, NULL, convertable_values, flags);
+}
+
+static inline void AddTraceEvent(
+ char phase,
+ const unsigned char* category_group_enabled,
+ const char* name,
+ unsigned long long id,
+ unsigned char flags,
+ const char* arg1_name,
+ scoped_ptr<base::debug::ConvertableToTraceFormat> arg1_val) {
+ int thread_id = static_cast<int>(base::PlatformThread::CurrentId());
+ base::TimeTicks now = base::TimeTicks::NowFromSystemTraceTime();
+ AddTraceEventWithThreadIdAndTimestamp(phase, category_group_enabled, name, id,
+ thread_id, now, flags, arg1_name,
+ arg1_val.Pass());
+}
+
+static inline void AddTraceEventWithThreadIdAndTimestamp(
+ char phase,
+ const unsigned char* category_group_enabled,
+ const char* name,
+ unsigned long long id,
+ int thread_id,
+ const base::TimeTicks& timestamp,
+ unsigned char flags,
+ const char* arg1_name,
+ scoped_ptr<base::debug::ConvertableToTraceFormat> arg1_val,
+ const char* arg2_name,
+ scoped_ptr<base::debug::ConvertableToTraceFormat> arg2_val) {
+ const int num_args = 2;
+ const char* arg_names[2] = { arg1_name, arg2_name };
+ unsigned char arg_types[2] =
+ { TRACE_VALUE_TYPE_CONVERTABLE, TRACE_VALUE_TYPE_CONVERTABLE };
+ scoped_ptr<base::debug::ConvertableToTraceFormat> convertable_values[2];
+ convertable_values[0].reset(arg1_val.release());
+ convertable_values[1].reset(arg2_val.release());
+
+ TRACE_EVENT_API_ADD_TRACE_EVENT_WITH_THREAD_ID_AND_TIMESTAMP(
+ phase, category_group_enabled, name, id, thread_id, timestamp,
+ num_args, arg_names, arg_types, NULL, convertable_values, flags);
+}
+
+static inline void AddTraceEvent(
+ char phase,
+ const unsigned char* category_group_enabled,
+ const char* name,
+ unsigned long long id,
+ unsigned char flags,
+ const char* arg1_name,
+ scoped_ptr<base::debug::ConvertableToTraceFormat> arg1_val,
+ const char* arg2_name,
+ scoped_ptr<base::debug::ConvertableToTraceFormat> arg2_val) {
+ int thread_id = static_cast<int>(base::PlatformThread::CurrentId());
+ base::TimeTicks now = base::TimeTicks::NowFromSystemTraceTime();
+ AddTraceEventWithThreadIdAndTimestamp(phase, category_group_enabled, name, id,
+ thread_id, now, flags,
+ arg1_name, arg1_val.Pass(),
+ arg2_name, arg2_val.Pass());
+}
+
+static inline void AddTraceEventWithThreadIdAndTimestamp(
+ char phase,
+ const unsigned char* category_group_enabled,
+ const char* name,
+ unsigned long long id,
+ int thread_id,
+ const base::TimeTicks& timestamp,
+ unsigned char flags) {
+ TRACE_EVENT_API_ADD_TRACE_EVENT_WITH_THREAD_ID_AND_TIMESTAMP(
+ phase, category_group_enabled, name, id, thread_id, timestamp,
+ kZeroNumArgs, NULL, NULL, NULL, NULL, flags);
+}
+
+static inline void AddTraceEvent(char phase,
+ const unsigned char* category_group_enabled,
+ const char* name,
+ unsigned long long id,
+ unsigned char flags) {
+ int thread_id = static_cast<int>(base::PlatformThread::CurrentId());
+ base::TimeTicks now = base::TimeTicks::NowFromSystemTraceTime();
+ AddTraceEventWithThreadIdAndTimestamp(phase, category_group_enabled, name, id,
+ thread_id, now, flags);
+}
+
+template<class ARG1_TYPE>
+static inline void AddTraceEventWithThreadIdAndTimestamp(
+ char phase,
+ const unsigned char* category_group_enabled,
+ const char* name,
+ unsigned long long id,
+ int thread_id,
+ const base::TimeTicks& timestamp,
+ unsigned char flags,
+ const char* arg1_name,
+ const ARG1_TYPE& arg1_val) {
+ const int num_args = 1;
+ unsigned char arg_types[1];
+ unsigned long long arg_values[1];
+ SetTraceValue(arg1_val, &arg_types[0], &arg_values[0]);
+ TRACE_EVENT_API_ADD_TRACE_EVENT_WITH_THREAD_ID_AND_TIMESTAMP(
+ phase, category_group_enabled, name, id, thread_id, timestamp,
+ num_args, &arg1_name, arg_types, arg_values, NULL, flags);
+}
+
+template<class ARG1_TYPE>
+static inline void AddTraceEvent(char phase,
+ const unsigned char* category_group_enabled,
+ const char* name,
+ unsigned long long id,
+ unsigned char flags,
+ const char* arg1_name,
+ const ARG1_TYPE& arg1_val) {
+ int thread_id = static_cast<int>(base::PlatformThread::CurrentId());
+ base::TimeTicks now = base::TimeTicks::NowFromSystemTraceTime();
+ AddTraceEventWithThreadIdAndTimestamp(phase, category_group_enabled, name, id,
+ thread_id, now, flags, arg1_name,
+ arg1_val);
+}
+
+template<class ARG1_TYPE, class ARG2_TYPE>
+static inline void AddTraceEventWithThreadIdAndTimestamp(
+ char phase,
+ const unsigned char* category_group_enabled,
+ const char* name,
+ unsigned long long id,
+ int thread_id,
+ const base::TimeTicks& timestamp,
+ unsigned char flags,
+ const char* arg1_name,
+ const ARG1_TYPE& arg1_val,
+ const char* arg2_name,
+ const ARG2_TYPE& arg2_val) {
+ const int num_args = 2;
+ const char* arg_names[2] = { arg1_name, arg2_name };
+ unsigned char arg_types[2];
+ unsigned long long arg_values[2];
+ SetTraceValue(arg1_val, &arg_types[0], &arg_values[0]);
+ SetTraceValue(arg2_val, &arg_types[1], &arg_values[1]);
+ TRACE_EVENT_API_ADD_TRACE_EVENT_WITH_THREAD_ID_AND_TIMESTAMP(
+ phase, category_group_enabled, name, id, thread_id, timestamp,
+ num_args, arg_names, arg_types, arg_values, NULL, flags);
+}
+
+template<class ARG1_TYPE, class ARG2_TYPE>
+static inline void AddTraceEvent(char phase,
+ const unsigned char* category_group_enabled,
+ const char* name,
+ unsigned long long id,
+ unsigned char flags,
+ const char* arg1_name,
+ const ARG1_TYPE& arg1_val,
+ const char* arg2_name,
+ const ARG2_TYPE& arg2_val) {
+ int thread_id = static_cast<int>(base::PlatformThread::CurrentId());
+ base::TimeTicks now = base::TimeTicks::NowFromSystemTraceTime();
+ AddTraceEventWithThreadIdAndTimestamp(phase, category_group_enabled, name, id,
+ thread_id, now, flags, arg1_name,
+ arg1_val, arg2_name, arg2_val);
+}
+
+// Used by TRACE_EVENTx macro. Do not use directly.
+class TRACE_EVENT_API_CLASS_EXPORT TraceEndOnScopeClose {
+ public:
+ // Note: members of data_ intentionally left uninitialized. See Initialize.
+ TraceEndOnScopeClose() : p_data_(NULL) {}
+ ~TraceEndOnScopeClose() {
+ if (p_data_)
+ AddEventIfEnabled();
+ }
+
+ void Initialize(const unsigned char* category_group_enabled,
+ const char* name) {
+ data_.category_group_enabled = category_group_enabled;
+ data_.name = name;
+ p_data_ = &data_;
+ }
+
+ private:
+ // Add the end event if the category is still enabled.
+ void AddEventIfEnabled() {
+ // Only called when p_data_ is non-null.
+ if (*p_data_->category_group_enabled) {
+ TRACE_EVENT_API_ADD_TRACE_EVENT(
+ TRACE_EVENT_PHASE_END, // phase
+ p_data_->category_group_enabled, // category enabled
+ p_data_->name, // name
+ kNoEventId, // id
+ kZeroNumArgs, // num_args
+ NULL, // arg_names
+ NULL, // arg_types
+ NULL, // arg_values
+ NULL, // convertable_values
+ TRACE_EVENT_FLAG_NONE); // flags
+ }
+ }
+
+ // This Data struct workaround is to avoid initializing all the members
+ // in Data during construction of this object, since this object is always
+ // constructed, even when tracing is disabled. If the members of Data were
+ // members of this class instead, compiler warnings occur about potential
+ // uninitialized accesses.
+ struct Data {
+ const unsigned char* category_group_enabled;
+ const char* name;
+ };
+ Data* p_data_;
+ Data data_;
+};
+
+// Used by TRACE_EVENT_BINARY_EFFICIENTx macro. Do not use directly.
+class TRACE_EVENT_API_CLASS_EXPORT ScopedTrace {
+ public:
+ ScopedTrace(TRACE_EVENT_API_ATOMIC_WORD* event_uid, const char* name);
+ ~ScopedTrace();
+
+ private:
+ const unsigned char* category_group_enabled_;
+ const char* name_;
+};
+
+// A support macro for TRACE_EVENT_BINARY_EFFICIENTx
+#define INTERNAL_TRACE_EVENT_BINARY_EFFICIENT_ADD_SCOPED( \
+ category_group, name, ...) \
+ static TRACE_EVENT_API_ATOMIC_WORD INTERNAL_TRACE_EVENT_UID(atomic) = 0; \
+ trace_event_internal::ScopedTrace \
+ INTERNAL_TRACE_EVENT_UID(profileScope)( \
+ &INTERNAL_TRACE_EVENT_UID(atomic), name); \
+
+// This macro generates less code then TRACE_EVENT0 but is also
+// slower to execute when tracing is off. It should generally only be
+// used with code that is seldom executed or conditionally executed
+// when debugging.
+#define TRACE_EVENT_BINARY_EFFICIENT0(category_group, name) \
+ INTERNAL_TRACE_EVENT_BINARY_EFFICIENT_ADD_SCOPED(category_group, name)
+
+} // namespace trace_event_internal
namespace base {
namespace debug {
template<typename IDType> class TraceScopedTrackableObject {
public:
- TraceScopedTrackableObject(const char* category, const char* name, IDType id)
- : category_(category),
+ TraceScopedTrackableObject(const char* category_group, const char* name,
+ IDType id)
+ : category_group_(category_group),
name_(name),
id_(id) {
- TRACE_EVENT_OBJECT_CREATED_WITH_ID(category_, name_, id_);
+ TRACE_EVENT_OBJECT_CREATED_WITH_ID(category_group_, name_, id_);
+ }
+
+ template <typename ArgType> void snapshot(ArgType snapshot) {
+ TRACE_EVENT_OBJECT_SNAPSHOT_WITH_ID(category_group_, name_, id_, snapshot);
}
~TraceScopedTrackableObject() {
- TRACE_EVENT_OBJECT_DELETED_WITH_ID(category_, name_, id_);
+ TRACE_EVENT_OBJECT_DELETED_WITH_ID(category_group_, name_, id_);
}
private:
- const char* category_;
+ const char* category_group_;
const char* name_;
IDType id_;
diff --git a/base/debug/trace_event_android.cc b/base/debug/trace_event_android.cc
index 70e377b..8cc5f3c 100644
--- a/base/debug/trace_event_android.cc
+++ b/base/debug/trace_event_android.cc
@@ -17,7 +17,7 @@
const char* kATraceMarkerFile = "/sys/kernel/debug/tracing/trace_marker";
void WriteEvent(char phase,
- const char* category,
+ const char* category_group,
const char* name,
unsigned long long id,
int num_args,
@@ -48,7 +48,7 @@
}
out += '|';
- out += category;
+ out += category_group;
write(g_atrace_fd, out.c_str(), out.size());
}
@@ -75,7 +75,7 @@
}
void TraceLog::SendToATrace(char phase,
- const char* category,
+ const char* category_group,
const char* name,
unsigned long long id,
int num_args,
@@ -88,20 +88,20 @@
switch (phase) {
case TRACE_EVENT_PHASE_BEGIN:
- WriteEvent('B', category, name, id,
+ WriteEvent('B', category_group, name, id,
num_args, arg_names, arg_types, arg_values, flags);
break;
case TRACE_EVENT_PHASE_END:
- // Though a single 'E' is enough, here append pid, name and category etc.
- // so that unpaired events can be found easily.
- WriteEvent('E', category, name, id,
+ // Though a single 'E' is enough, here append pid, name and
+ // category_group etc. So that unpaired events can be found easily.
+ WriteEvent('E', category_group, name, id,
num_args, arg_names, arg_types, arg_values, flags);
break;
case TRACE_EVENT_PHASE_INSTANT:
// Simulate an instance event with a pair of begin/end events.
- WriteEvent('B', category, name, id,
+ WriteEvent('B', category_group, name, id,
num_args, arg_names, arg_types, arg_values, flags);
write(g_atrace_fd, "E", 1);
break;
@@ -114,7 +114,7 @@
if (flags & TRACE_EVENT_FLAG_HAS_ID)
StringAppendF(&out, "-%" PRIx64, static_cast<uint64>(id));
StringAppendF(&out, "|%d|%s",
- static_cast<int>(arg_values[i]), category);
+ static_cast<int>(arg_values[i]), category_group);
write(g_atrace_fd, out.c_str(), out.size());
}
break;
@@ -126,11 +126,11 @@
}
// Must be called with lock_ locked.
-void TraceLog::ApplyATraceEnabledFlag(unsigned char* category_enabled) {
+void TraceLog::ApplyATraceEnabledFlag(unsigned char* category_group_enabled) {
if (g_atrace_fd != -1)
- *category_enabled |= ATRACE_ENABLED;
+ *category_group_enabled |= ATRACE_ENABLED;
else
- *category_enabled &= ~ATRACE_ENABLED;
+ *category_group_enabled &= ~ATRACE_ENABLED;
}
} // namespace debug
diff --git a/base/debug/trace_event_impl.cc b/base/debug/trace_event_impl.cc
index d543d87..9a24abe 100644
--- a/base/debug/trace_event_impl.cc
+++ b/base/debug/trace_event_impl.cc
@@ -54,27 +54,29 @@
const size_t kTraceEventBatchSize = 1000;
const size_t kTraceEventInitialBufferSize = 1024;
-#define TRACE_EVENT_MAX_CATEGORIES 100
+#define MAX_CATEGORY_GROUPS 100
namespace {
-// Parallel arrays g_categories and g_category_enabled are separate so that
-// a pointer to a member of g_category_enabled can be easily converted to an
-// index into g_categories. This allows macros to deal only with char enabled
-// pointers from g_category_enabled, and we can convert internally to determine
-// the category name from the char enabled pointer.
-const char* g_categories[TRACE_EVENT_MAX_CATEGORIES] = {
+// Parallel arrays g_category_groups and g_category_group_enabled are separate
+// so that a pointer to a member of g_category_group_enabled can be easily
+// converted to an index into g_category_groups. This allows macros to deal
+// only with char enabled pointers from g_category_group_enabled, and we can
+// convert internally to determine the category name from the char enabled
+// pointer.
+const char* g_category_groups[MAX_CATEGORY_GROUPS] = {
"tracing already shutdown",
- "tracing categories exhausted; must increase TRACE_EVENT_MAX_CATEGORIES",
+ "tracing categories exhausted; must increase MAX_CATEGORY_GROUPS",
"__metadata",
};
// The enabled flag is char instead of bool so that the API can be used from C.
-unsigned char g_category_enabled[TRACE_EVENT_MAX_CATEGORIES] = { 0 };
+unsigned char g_category_group_enabled[MAX_CATEGORY_GROUPS] = { 0 };
const int g_category_already_shutdown = 0;
const int g_category_categories_exhausted = 1;
const int g_category_metadata = 2;
-int g_category_index = 3; // skip initial 3 categories
+const int g_num_builtin_categories = 3;
+int g_category_index = g_num_builtin_categories; // Skip default categories.
// The name of the current thread. This is used to decide if the current
// thread name has changed. We combine all the seen thread names into the
@@ -102,9 +104,9 @@
logged_events_.reserve(kTraceEventInitialBufferSize);
}
- ~TraceBufferRingBuffer() {}
+ virtual ~TraceBufferRingBuffer() {}
- void AddEvent(const TraceEvent& event) OVERRIDE {
+ virtual void AddEvent(const TraceEvent& event) OVERRIDE {
if (unused_event_index_ < Size())
logged_events_[unused_event_index_] = event;
else
@@ -116,11 +118,11 @@
}
}
- bool HasMoreEvents() const OVERRIDE {
+ virtual bool HasMoreEvents() const OVERRIDE {
return oldest_event_index_ != unused_event_index_;
}
- const TraceEvent& NextEvent() OVERRIDE {
+ virtual const TraceEvent& NextEvent() OVERRIDE {
DCHECK(HasMoreEvents());
size_t next = oldest_event_index_;
@@ -128,17 +130,18 @@
return GetEventAt(next);
}
- bool IsFull() const OVERRIDE {
+ virtual bool IsFull() const OVERRIDE {
return false;
}
- size_t CountEnabledByName(const unsigned char* category,
- const std::string& event_name) const OVERRIDE {
+ virtual size_t CountEnabledByName(
+ const unsigned char* category,
+ const std::string& event_name) const OVERRIDE {
size_t notify_count = 0;
size_t index = oldest_event_index_;
while (index != unused_event_index_) {
const TraceEvent& event = GetEventAt(index);
- if (category == event.category_enabled() &&
+ if (category == event.category_group_enabled() &&
strcmp(event_name.c_str(), event.name()) == 0) {
++notify_count;
}
@@ -147,12 +150,12 @@
return notify_count;
}
- const TraceEvent& GetEventAt(size_t index) const OVERRIDE {
+ virtual const TraceEvent& GetEventAt(size_t index) const OVERRIDE {
DCHECK(index < logged_events_.size());
return logged_events_[index];
}
- size_t Size() const OVERRIDE {
+ virtual size_t Size() const OVERRIDE {
return logged_events_.size();
}
@@ -170,10 +173,10 @@
logged_events_.reserve(kTraceEventInitialBufferSize);
}
- ~TraceBufferVector() {
+ virtual ~TraceBufferVector() {
}
- void AddEvent(const TraceEvent& event) OVERRIDE {
+ virtual void AddEvent(const TraceEvent& event) OVERRIDE {
// Note, we have two callers which need to be handled. The first is
// AddTraceEventWithThreadIdAndTimestamp() which checks Size() and does an
// early exit if full. The second is AddThreadNameMetadataEvents().
@@ -182,25 +185,26 @@
logged_events_.push_back(event);
}
- bool HasMoreEvents() const OVERRIDE {
+ virtual bool HasMoreEvents() const OVERRIDE {
return current_iteration_index_ < Size();
}
- const TraceEvent& NextEvent() OVERRIDE {
+ virtual const TraceEvent& NextEvent() OVERRIDE {
DCHECK(HasMoreEvents());
return GetEventAt(current_iteration_index_++);
}
- bool IsFull() const OVERRIDE {
+ virtual bool IsFull() const OVERRIDE {
return Size() >= kTraceEventBufferSize;
}
- size_t CountEnabledByName(const unsigned char* category,
- const std::string& event_name) const OVERRIDE {
+ virtual size_t CountEnabledByName(
+ const unsigned char* category,
+ const std::string& event_name) const OVERRIDE {
size_t notify_count = 0;
for (size_t i = 0; i < Size(); i++) {
const TraceEvent& event = GetEventAt(i);
- if (category == event.category_enabled() &&
+ if (category == event.category_group_enabled() &&
strcmp(event_name.c_str(), event.name()) == 0) {
++notify_count;
}
@@ -208,12 +212,12 @@
return notify_count;
}
- const TraceEvent& GetEventAt(size_t index) const OVERRIDE {
+ virtual const TraceEvent& GetEventAt(size_t index) const OVERRIDE {
DCHECK(index < logged_events_.size());
return logged_events_[index];
}
- size_t Size() const OVERRIDE {
+ virtual size_t Size() const OVERRIDE {
return logged_events_.size();
}
@@ -224,6 +228,34 @@
DISALLOW_COPY_AND_ASSIGN(TraceBufferVector);
};
+class TraceBufferDiscardsEvents : public TraceBuffer {
+ public:
+ virtual ~TraceBufferDiscardsEvents() { }
+
+ virtual void AddEvent(const TraceEvent& event) OVERRIDE {}
+ virtual bool HasMoreEvents() const OVERRIDE { return false; }
+
+ virtual const TraceEvent& NextEvent() OVERRIDE {
+ NOTREACHED();
+ return *static_cast<TraceEvent*>(NULL);
+ }
+
+ virtual bool IsFull() const OVERRIDE { return false; }
+
+ virtual size_t CountEnabledByName(
+ const unsigned char* category,
+ const std::string& event_name) const OVERRIDE {
+ return 0;
+ }
+
+ virtual size_t Size() const OVERRIDE { return 0; }
+
+ virtual const TraceEvent& GetEventAt(size_t index) const OVERRIDE {
+ NOTREACHED();
+ return *static_cast<TraceEvent*>(NULL);
+ }
+};
+
////////////////////////////////////////////////////////////////////////////////
//
// TraceEvent
@@ -251,7 +283,7 @@
TraceEvent::TraceEvent()
: id_(0u),
- category_enabled_(NULL),
+ category_group_enabled_(NULL),
name_(NULL),
thread_id_(0),
phase_(TRACE_EVENT_PHASE_BEGIN),
@@ -261,20 +293,22 @@
memset(arg_values_, 0, sizeof(arg_values_));
}
-TraceEvent::TraceEvent(int thread_id,
- TimeTicks timestamp,
- char phase,
- const unsigned char* category_enabled,
- const char* name,
- unsigned long long id,
- int num_args,
- const char** arg_names,
- const unsigned char* arg_types,
- const unsigned long long* arg_values,
- unsigned char flags)
+TraceEvent::TraceEvent(
+ int thread_id,
+ TimeTicks timestamp,
+ char phase,
+ const unsigned char* category_group_enabled,
+ const char* name,
+ unsigned long long id,
+ int num_args,
+ const char** arg_names,
+ const unsigned char* arg_types,
+ const unsigned long long* arg_values,
+ scoped_ptr<ConvertableToTraceFormat> convertable_values[],
+ unsigned char flags)
: timestamp_(timestamp),
id_(id),
- category_enabled_(category_enabled),
+ category_group_enabled_(category_group_enabled),
name_(name),
thread_id_(thread_id),
phase_(phase),
@@ -284,12 +318,17 @@
int i = 0;
for (; i < num_args; ++i) {
arg_names_[i] = arg_names[i];
- arg_values_[i].as_uint = arg_values[i];
arg_types_[i] = arg_types[i];
+
+ if (arg_types[i] == TRACE_VALUE_TYPE_CONVERTABLE)
+ convertable_values_[i].reset(convertable_values[i].release());
+ else
+ arg_values_[i].as_uint = arg_values[i];
}
for (; i < kTraceMaxNumArgs; ++i) {
arg_names_[i] = NULL;
arg_values_[i].as_uint = 0u;
+ convertable_values_[i].reset();
arg_types_[i] = TRACE_VALUE_TYPE_UINT;
}
@@ -306,6 +345,10 @@
bool arg_is_copy[kTraceMaxNumArgs];
for (i = 0; i < num_args; ++i) {
+ // No copying of convertable types, we retain ownership.
+ if (arg_types_[i] == TRACE_VALUE_TYPE_CONVERTABLE)
+ continue;
+
// We only take a copy of arg_vals if they are of type COPY_STRING.
arg_is_copy[i] = (arg_types_[i] == TRACE_VALUE_TYPE_COPY_STRING);
if (arg_is_copy[i])
@@ -319,10 +362,13 @@
const char* end = ptr + alloc_size;
if (copy) {
CopyTraceEventParameter(&ptr, &name_, end);
- for (i = 0; i < num_args; ++i)
+ for (i = 0; i < num_args; ++i) {
CopyTraceEventParameter(&ptr, &arg_names_[i], end);
+ }
}
for (i = 0; i < num_args; ++i) {
+ if (arg_types_[i] == TRACE_VALUE_TYPE_CONVERTABLE)
+ continue;
if (arg_is_copy[i])
CopyTraceEventParameter(&ptr, &arg_values_[i].as_string, end);
}
@@ -330,6 +376,58 @@
}
}
+TraceEvent::TraceEvent(const TraceEvent& other)
+ : timestamp_(other.timestamp_),
+ id_(other.id_),
+ category_group_enabled_(other.category_group_enabled_),
+ name_(other.name_),
+ thread_id_(other.thread_id_),
+ phase_(other.phase_),
+ flags_(other.flags_) {
+ parameter_copy_storage_ = other.parameter_copy_storage_;
+
+ for (int i = 0; i < kTraceMaxNumArgs; ++i) {
+ arg_values_[i] = other.arg_values_[i];
+ arg_names_[i] = other.arg_names_[i];
+ arg_types_[i] = other.arg_types_[i];
+
+ if (arg_types_[i] == TRACE_VALUE_TYPE_CONVERTABLE) {
+ convertable_values_[i].reset(
+ const_cast<TraceEvent*>(&other)->convertable_values_[i].release());
+ } else {
+ convertable_values_[i].reset();
+ }
+ }
+}
+
+TraceEvent& TraceEvent::operator=(const TraceEvent& other) {
+ if (this == &other)
+ return *this;
+
+ timestamp_ = other.timestamp_;
+ id_ = other.id_;
+ category_group_enabled_ = other.category_group_enabled_;
+ name_ = other.name_;
+ parameter_copy_storage_ = other.parameter_copy_storage_;
+ thread_id_ = other.thread_id_;
+ phase_ = other.phase_;
+ flags_ = other.flags_;
+
+ for (int i = 0; i < kTraceMaxNumArgs; ++i) {
+ arg_values_[i] = other.arg_values_[i];
+ arg_names_[i] = other.arg_names_[i];
+ arg_types_[i] = other.arg_types_[i];
+
+ if (arg_types_[i] == TRACE_VALUE_TYPE_CONVERTABLE) {
+ convertable_values_[i].reset(
+ const_cast<TraceEvent*>(&other)->convertable_values_[i].release());
+ } else {
+ convertable_values_[i].reset();
+ }
+ }
+ return *this;
+}
+
TraceEvent::~TraceEvent() {
}
@@ -354,7 +452,7 @@
case TRACE_VALUE_TYPE_POINTER:
// JSON only supports double and int numbers.
// So as not to lose bits from a 64-bit pointer, output as a hex string.
- StringAppendF(out, "\"%" PRIx64 "\"", static_cast<uint64>(
+ StringAppendF(out, "\"0x%" PRIx64 "\"", static_cast<uint64>(
reinterpret_cast<intptr_t>(
value.as_pointer)));
break;
@@ -381,12 +479,12 @@
void TraceEvent::AppendAsJSON(std::string* out) const {
int64 time_int64 = timestamp_.ToInternalValue();
int process_id = TraceLog::GetInstance()->process_id();
- // Category name checked at category creation time.
+ // Category group checked at category creation time.
DCHECK(!strchr(name_, '"'));
StringAppendF(out,
"{\"cat\":\"%s\",\"pid\":%i,\"tid\":%i,\"ts\":%" PRId64 ","
"\"ph\":\"%c\",\"name\":\"%s\",\"args\":{",
- TraceLog::GetCategoryName(category_enabled_),
+ TraceLog::GetCategoryGroupName(category_group_enabled_),
process_id,
thread_id_,
time_int64,
@@ -400,14 +498,38 @@
*out += "\"";
*out += arg_names_[i];
*out += "\":";
- AppendValueAsJSON(arg_types_[i], arg_values_[i], out);
+
+ if (arg_types_[i] == TRACE_VALUE_TYPE_CONVERTABLE)
+ convertable_values_[i]->AppendAsTraceFormat(out);
+ else
+ AppendValueAsJSON(arg_types_[i], arg_values_[i], out);
}
*out += "}";
// If id_ is set, print it out as a hex string so we don't loose any
// bits (it might be a 64-bit pointer).
if (flags_ & TRACE_EVENT_FLAG_HAS_ID)
- StringAppendF(out, ",\"id\":\"%" PRIx64 "\"", static_cast<uint64>(id_));
+ StringAppendF(out, ",\"id\":\"0x%" PRIx64 "\"", static_cast<uint64>(id_));
+
+ // Instant events also output their scope.
+ if (phase_ == TRACE_EVENT_PHASE_INSTANT) {
+ char scope = '?';
+ switch (flags_ & TRACE_EVENT_FLAG_SCOPE_MASK) {
+ case TRACE_EVENT_SCOPE_GLOBAL:
+ scope = TRACE_EVENT_SCOPE_NAME_GLOBAL;
+ break;
+
+ case TRACE_EVENT_SCOPE_PROCESS:
+ scope = TRACE_EVENT_SCOPE_NAME_PROCESS;
+ break;
+
+ case TRACE_EVENT_SCOPE_THREAD:
+ scope = TRACE_EVENT_SCOPE_NAME_THREAD;
+ break;
+ }
+ StringAppendF(out, ",\"s\":\"%c\"", scope);
+ }
+
*out += "}";
}
@@ -537,18 +659,12 @@
return;
const char* const combined =
reinterpret_cast<const char* const>(category_and_name);
- const char* category;
+ const char* category_group;
const char* name;
- ExtractCategoryAndName(combined, &category, &name);
+ ExtractCategoryAndName(combined, &category_group, &name);
TRACE_EVENT_API_ADD_TRACE_EVENT(TRACE_EVENT_PHASE_SAMPLE,
- TraceLog::GetCategoryEnabled(category),
- name,
- 0,
- 0,
- NULL,
- NULL,
- NULL,
- 0);
+ TraceLog::GetCategoryGroupEnabled(category_group),
+ name, 0, 0, NULL, NULL, NULL, NULL, 0);
}
void TraceSamplingThread::GetSamples() {
@@ -658,16 +774,18 @@
dispatching_to_observer_list_(false),
watch_category_(NULL),
trace_options_(RECORD_UNTIL_FULL),
- sampling_thread_handle_(0) {
+ sampling_thread_handle_(0),
+ category_filter_(CategoryFilter::kDefaultCategoryFilterString) {
// Trace is enabled or disabled on one thread while other threads are
// accessing the enabled flag. We don't care whether edge-case events are
// traced or not, so we allow races on the enabled flag to keep the trace
// macros fast.
// TODO(jbates): ANNOTATE_BENIGN_RACE_SIZED crashes windows TSAN bots:
- // ANNOTATE_BENIGN_RACE_SIZED(g_category_enabled, sizeof(g_category_enabled),
- // "trace_event category enabled");
- for (int i = 0; i < TRACE_EVENT_MAX_CATEGORIES; ++i) {
- ANNOTATE_BENIGN_RACE(&g_category_enabled[i],
+ // ANNOTATE_BENIGN_RACE_SIZED(g_category_group_enabled,
+ // sizeof(g_category_group_enabled),
+ // "trace_event category enabled");
+ for (int i = 0; i < MAX_CATEGORY_GROUPS; ++i) {
+ ANNOTATE_BENIGN_RACE(&g_category_group_enabled[i],
"trace_event category enabled");
}
#if defined(OS_NACL) // NaCl shouldn't expose the process id.
@@ -682,112 +800,100 @@
TraceLog::~TraceLog() {
}
-const unsigned char* TraceLog::GetCategoryEnabled(const char* name) {
+const unsigned char* TraceLog::GetCategoryGroupEnabled(
+ const char* category_group) {
TraceLog* tracelog = GetInstance();
if (!tracelog) {
- DCHECK(!g_category_enabled[g_category_already_shutdown]);
- return &g_category_enabled[g_category_already_shutdown];
+ DCHECK(!g_category_group_enabled[g_category_already_shutdown]);
+ return &g_category_group_enabled[g_category_already_shutdown];
}
- return tracelog->GetCategoryEnabledInternal(name);
+ return tracelog->GetCategoryGroupEnabledInternal(category_group);
}
-const char* TraceLog::GetCategoryName(const unsigned char* category_enabled) {
- // Calculate the index of the category by finding category_enabled in
- // g_category_enabled array.
- uintptr_t category_begin = reinterpret_cast<uintptr_t>(g_category_enabled);
- uintptr_t category_ptr = reinterpret_cast<uintptr_t>(category_enabled);
+const char* TraceLog::GetCategoryGroupName(
+ const unsigned char* category_group_enabled) {
+ // Calculate the index of the category group by finding
+ // category_group_enabled in g_category_group_enabled array.
+ uintptr_t category_begin =
+ reinterpret_cast<uintptr_t>(g_category_group_enabled);
+ uintptr_t category_ptr = reinterpret_cast<uintptr_t>(category_group_enabled);
DCHECK(category_ptr >= category_begin &&
- category_ptr < reinterpret_cast<uintptr_t>(g_category_enabled +
- TRACE_EVENT_MAX_CATEGORIES)) <<
+ category_ptr < reinterpret_cast<uintptr_t>(
+ g_category_group_enabled + MAX_CATEGORY_GROUPS)) <<
"out of bounds category pointer";
uintptr_t category_index =
- (category_ptr - category_begin) / sizeof(g_category_enabled[0]);
- return g_categories[category_index];
+ (category_ptr - category_begin) / sizeof(g_category_group_enabled[0]);
+ return g_category_groups[category_index];
}
-static void EnableMatchingCategory(int category_index,
- const std::vector<std::string>& patterns,
- unsigned char matched_value,
- unsigned char unmatched_value) {
- std::vector<std::string>::const_iterator ci = patterns.begin();
- bool is_match = false;
- for (; ci != patterns.end(); ++ci) {
- is_match = MatchPattern(g_categories[category_index], ci->c_str());
- if (is_match)
- break;
- }
- g_category_enabled[category_index] = is_match ?
- matched_value : unmatched_value;
+void TraceLog::EnableIncludedCategoryGroup(int category_index) {
+ bool is_enabled = category_filter_.IsCategoryGroupEnabled(
+ g_category_groups[category_index]);
+ g_category_group_enabled[category_index] =
+ is_enabled ? TraceLog::CATEGORY_ENABLED : 0;
}
-// Enable/disable each category based on the category filters in |patterns|.
-// If the category name matches one of the patterns, its enabled status is set
-// to |matched_value|. Otherwise its enabled status is set to |unmatched_value|.
-static void EnableMatchingCategories(const std::vector<std::string>& patterns,
- unsigned char matched_value,
- unsigned char unmatched_value) {
+void TraceLog::EnableIncludedCategoryGroups() {
for (int i = 0; i < g_category_index; i++)
- EnableMatchingCategory(i, patterns, matched_value, unmatched_value);
+ EnableIncludedCategoryGroup(i);
}
-const unsigned char* TraceLog::GetCategoryEnabledInternal(const char* name) {
+const unsigned char* TraceLog::GetCategoryGroupEnabledInternal(
+ const char* category_group) {
+ DCHECK(!strchr(category_group, '"')) <<
+ "Category groups may not contain double quote";
AutoLock lock(lock_);
- DCHECK(!strchr(name, '"')) << "Category names may not contain double quote";
- unsigned char* category_enabled = NULL;
- // Search for pre-existing category matching this name
+ unsigned char* category_group_enabled = NULL;
+ // Search for pre-existing category group.
for (int i = 0; i < g_category_index; i++) {
- if (strcmp(g_categories[i], name) == 0) {
- category_enabled = &g_category_enabled[i];
+ if (strcmp(g_category_groups[i], category_group) == 0) {
+ category_group_enabled = &g_category_group_enabled[i];
break;
}
}
- if (!category_enabled) {
- // Create a new category
- DCHECK(g_category_index < TRACE_EVENT_MAX_CATEGORIES) <<
- "must increase TRACE_EVENT_MAX_CATEGORIES";
- if (g_category_index < TRACE_EVENT_MAX_CATEGORIES) {
+ if (!category_group_enabled) {
+ // Create a new category group
+ DCHECK(g_category_index < MAX_CATEGORY_GROUPS) <<
+ "must increase MAX_CATEGORY_GROUPS";
+ if (g_category_index < MAX_CATEGORY_GROUPS) {
int new_index = g_category_index++;
- // Don't hold on to the name pointer, so that we can create categories
- // with strings not known at compile time (this is required by
- // SetWatchEvent).
- const char* new_name = strdup(name);
- ANNOTATE_LEAKING_OBJECT_PTR(new_name);
- g_categories[new_index] = new_name;
- DCHECK(!g_category_enabled[new_index]);
+ // Don't hold on to the category_group pointer, so that we can create
+ // category groups with strings not known at compile time (this is
+ // required by SetWatchEvent).
+ const char* new_group = strdup(category_group);
+ ANNOTATE_LEAKING_OBJECT_PTR(new_group);
+ g_category_groups[new_index] = new_group;
+ DCHECK(!g_category_group_enabled[new_index]);
if (enable_count_) {
- // Note that if both included and excluded_categories are empty, the
- // else clause below excludes nothing, thereby enabling this category.
- if (!included_categories_.empty()) {
- EnableMatchingCategory(new_index, included_categories_,
- CATEGORY_ENABLED, 0);
- } else {
- EnableMatchingCategory(new_index, excluded_categories_,
- 0, CATEGORY_ENABLED);
- }
+ // Note that if both included and excluded patterns in the
+ // CategoryFilter are empty, we exclude nothing,
+ // thereby enabling this category group.
+ EnableIncludedCategoryGroup(new_index);
} else {
- g_category_enabled[new_index] = 0;
+ g_category_group_enabled[new_index] = 0;
}
- category_enabled = &g_category_enabled[new_index];
+ category_group_enabled = &g_category_group_enabled[new_index];
} else {
- category_enabled = &g_category_enabled[g_category_categories_exhausted];
+ category_group_enabled =
+ &g_category_group_enabled[g_category_categories_exhausted];
}
}
#if defined(OS_ANDROID)
- ApplyATraceEnabledFlag(category_enabled);
+ ApplyATraceEnabledFlag(category_group_enabled);
#endif
- return category_enabled;
+ return category_group_enabled;
}
-void TraceLog::GetKnownCategories(std::vector<std::string>* categories) {
+void TraceLog::GetKnownCategoryGroups(
+ std::vector<std::string>* category_groups) {
AutoLock lock(lock_);
- for (int i = 0; i < g_category_index; i++)
- categories->push_back(g_categories[i]);
+ for (int i = g_num_builtin_categories; i < g_category_index; i++)
+ category_groups->push_back(g_category_groups[i]);
}
-void TraceLog::SetEnabled(const std::vector<std::string>& included_categories,
- const std::vector<std::string>& excluded_categories,
+void TraceLog::SetEnabled(const CategoryFilter& category_filter,
Options options) {
AutoLock lock(lock_);
@@ -799,17 +905,14 @@
// Tracing is already enabled, so just merge in enabled categories.
// We only expand the set of enabled categories upon nested SetEnable().
- if (!included_categories_.empty() && !included_categories.empty()) {
- included_categories_.insert(included_categories_.end(),
- included_categories.begin(),
- included_categories.end());
- EnableMatchingCategories(included_categories_, CATEGORY_ENABLED, 0);
+ if (category_filter_.HasIncludedPatterns() &&
+ category_filter.HasIncludedPatterns()) {
+ category_filter_.Merge(category_filter);
} else {
// If either old or new included categories are empty, allow all events.
- included_categories_.clear();
- excluded_categories_.clear();
- EnableMatchingCategories(excluded_categories_, 0, CATEGORY_ENABLED);
+ category_filter_.Clear();
}
+ EnableIncludedCategoryGroups();
return;
}
@@ -829,14 +932,8 @@
OnTraceLogWillEnable());
dispatching_to_observer_list_ = false;
- included_categories_ = included_categories;
- excluded_categories_ = excluded_categories;
- // Note that if both included and excluded_categories are empty, the else
- // clause below excludes nothing, thereby enabling all categories.
- if (!included_categories_.empty())
- EnableMatchingCategories(included_categories_, CATEGORY_ENABLED, 0);
- else
- EnableMatchingCategories(excluded_categories_, 0, CATEGORY_ENABLED);
+ category_filter_ = CategoryFilter(category_filter);
+ EnableIncludedCategoryGroups();
if (options & ENABLE_SAMPLING) {
sampling_thread_.reset(new TraceSamplingThread);
@@ -859,35 +956,10 @@
}
}
-void TraceLog::SetEnabled(const std::string& categories, Options options) {
- std::vector<std::string> included, excluded;
- // Tokenize list of categories, delimited by ','.
- StringTokenizer tokens(categories, ",");
- while (tokens.GetNext()) {
- bool is_included = true;
- std::string category = tokens.token();
- // Excluded categories start with '-'.
- if (category.at(0) == '-') {
- // Remove '-' from category string.
- category = category.substr(1);
- is_included = false;
- }
- if (is_included)
- included.push_back(category);
- else
- excluded.push_back(category);
- }
- SetEnabled(included, excluded, options);
-}
-
-void TraceLog::GetEnabledTraceCategories(
- std::vector<std::string>* included_out,
- std::vector<std::string>* excluded_out) {
+const CategoryFilter& TraceLog::GetCurrentCategoryFilter() {
AutoLock lock(lock_);
- if (enable_count_) {
- *included_out = included_categories_;
- *excluded_out = excluded_categories_;
- }
+ DCHECK(enable_count_ > 0);
+ return category_filter_;
}
void TraceLog::SetDisabled() {
@@ -918,22 +990,14 @@
OnTraceLogWillDisable());
dispatching_to_observer_list_ = false;
- included_categories_.clear();
- excluded_categories_.clear();
+ category_filter_.Clear();
watch_category_ = NULL;
watch_event_name_ = "";
for (int i = 0; i < g_category_index; i++)
- g_category_enabled[i] = 0;
+ g_category_group_enabled[i] = 0;
AddThreadNameMetadataEvents();
}
-void TraceLog::SetEnabled(bool enabled, Options options) {
- if (enabled)
- SetEnabled(std::vector<std::string>(), std::vector<std::string>(), options);
- else
- SetDisabled();
-}
-
void TraceLog::AddEnabledStateObserver(EnabledStateChangedObserver* listener) {
enabled_state_observer_list_.AddObserver(listener);
}
@@ -956,6 +1020,8 @@
TraceBuffer* TraceLog::GetTraceBuffer() {
if (trace_options_ & RECORD_CONTINUOUSLY)
return new TraceBufferRingBuffer();
+ else if (trace_options_ & ECHO_TO_VLOG)
+ return new TraceBufferDiscardsEvents();
return new TraceBufferVector();
}
@@ -991,25 +1057,28 @@
}
}
-void TraceLog::AddTraceEvent(char phase,
- const unsigned char* category_enabled,
- const char* name,
- unsigned long long id,
- int num_args,
- const char** arg_names,
- const unsigned char* arg_types,
- const unsigned long long* arg_values,
- unsigned char flags) {
+void TraceLog::AddTraceEvent(
+ char phase,
+ const unsigned char* category_group_enabled,
+ const char* name,
+ unsigned long long id,
+ int num_args,
+ const char** arg_names,
+ const unsigned char* arg_types,
+ const unsigned long long* arg_values,
+ scoped_ptr<ConvertableToTraceFormat> convertable_values[],
+ unsigned char flags) {
int thread_id = static_cast<int>(base::PlatformThread::CurrentId());
base::TimeTicks now = base::TimeTicks::NowFromSystemTraceTime();
- AddTraceEventWithThreadIdAndTimestamp(phase, category_enabled, name, id,
+ AddTraceEventWithThreadIdAndTimestamp(phase, category_group_enabled, name, id,
thread_id, now, num_args, arg_names,
- arg_types, arg_values, flags);
+ arg_types, arg_values,
+ convertable_values, flags);
}
void TraceLog::AddTraceEventWithThreadIdAndTimestamp(
char phase,
- const unsigned char* category_enabled,
+ const unsigned char* category_group_enabled,
const char* name,
unsigned long long id,
int thread_id,
@@ -1018,14 +1087,21 @@
const char** arg_names,
const unsigned char* arg_types,
const unsigned long long* arg_values,
+ scoped_ptr<ConvertableToTraceFormat> convertable_values[],
unsigned char flags) {
DCHECK(name);
+ TimeDelta duration;
+ if (phase == TRACE_EVENT_PHASE_END && trace_options_ & ECHO_TO_VLOG) {
+ duration = timestamp - thread_event_start_times_[thread_id].top();
+ thread_event_start_times_[thread_id].pop();
+ }
+
if (flags & TRACE_EVENT_FLAG_MANGLE_ID)
id ^= process_id_hash_;
#if defined(OS_ANDROID)
- SendToATrace(phase, GetCategoryName(category_enabled), name, id,
+ SendToATrace(phase, GetCategoryGroupName(category_group_enabled), name, id,
num_args, arg_names, arg_types, arg_values, flags);
#endif
@@ -1034,12 +1110,14 @@
NotificationHelper notifier(this);
- {
+ do {
AutoLock lock(lock_);
- if (*category_enabled != CATEGORY_ENABLED)
+ if (*category_group_enabled != CATEGORY_ENABLED)
return;
+
+ event_callback_copy = event_callback_;
if (logged_events_->IsFull())
- return;
+ break;
const char* new_name = ThreadIdNameManager::GetInstance()->
GetName(thread_id);
@@ -1071,23 +1149,50 @@
}
}
+ if (trace_options_ & ECHO_TO_VLOG) {
+ std::string thread_name = thread_names_[thread_id];
+ if (thread_colors_.find(thread_name) == thread_colors_.end())
+ thread_colors_[thread_name] = (thread_colors_.size() % 6) + 1;
+
+ std::ostringstream log;
+ log << base::StringPrintf("%s: \x1b[0;3%dm",
+ thread_name.c_str(),
+ thread_colors_[thread_name]);
+
+ size_t depth = 0;
+ if (thread_event_start_times_.find(thread_id) !=
+ thread_event_start_times_.end())
+ depth = thread_event_start_times_[thread_id].size();
+
+ for (size_t i = 0; i < depth; ++i)
+ log << "| ";
+
+ log << base::StringPrintf("'%c', %s", phase, name);
+
+ if (phase == TRACE_EVENT_PHASE_END)
+ log << base::StringPrintf(" (%.3f ms)", duration.InMillisecondsF());
+
+ VLOG(0) << log.str() << "\x1b[0;m";
+ }
+
logged_events_->AddEvent(TraceEvent(thread_id,
- now, phase, category_enabled, name, id,
+ now, phase, category_group_enabled, name, id,
num_args, arg_names, arg_types, arg_values,
- flags));
+ convertable_values, flags));
if (logged_events_->IsFull())
notifier.AddNotificationWhileLocked(TRACE_BUFFER_FULL);
- if (watch_category_ == category_enabled && watch_event_name_ == name)
+ if (watch_category_ == category_group_enabled && watch_event_name_ == name)
notifier.AddNotificationWhileLocked(EVENT_WATCH_NOTIFICATION);
+ } while (0); // release lock
- event_callback_copy = event_callback_;
- } // release lock
+ if (phase == TRACE_EVENT_PHASE_BEGIN && trace_options_ & ECHO_TO_VLOG)
+ thread_event_start_times_[thread_id].push(timestamp);
notifier.SendNotificationIfAny();
if (event_callback_copy != NULL) {
- event_callback_copy(phase, category_enabled, name, id,
+ event_callback_copy(phase, category_group_enabled, name, id,
num_args, arg_names, arg_types, arg_values,
flags);
}
@@ -1118,7 +1223,8 @@
void TraceLog::SetWatchEvent(const std::string& category_name,
const std::string& event_name) {
- const unsigned char* category = GetCategoryEnabled(category_name.c_str());
+ const unsigned char* category = GetCategoryGroupEnabled(
+ category_name.c_str());
size_t notify_count = 0;
{
AutoLock lock(lock_);
@@ -1159,9 +1265,9 @@
trace_event_internal::SetTraceValue(it->second, &arg_type, &arg_value);
logged_events_->AddEvent(TraceEvent(it->first,
TimeTicks(), TRACE_EVENT_PHASE_METADATA,
- &g_category_enabled[g_category_metadata],
+ &g_category_group_enabled[g_category_metadata],
"thread_name", trace_event_internal::kNoEventId,
- num_args, &arg_name, &arg_type, &arg_value,
+ num_args, &arg_name, &arg_type, &arg_value, NULL,
TRACE_EVENT_FLAG_NONE));
}
}
@@ -1194,6 +1300,145 @@
time_offset_ = offset;
}
+bool CategoryFilter::IsEmptyOrContainsLeadingOrTrailingWhitespace(
+ const std::string& str) {
+ return str.empty() ||
+ str.at(0) == ' ' ||
+ str.at(str.length() - 1) == ' ';
+}
+
+static bool DoesCategoryGroupContainCategory(const char* category_group,
+ const char* category) {
+ DCHECK(category);
+ CStringTokenizer category_group_tokens(category_group,
+ category_group + strlen(category_group), ",");
+ while (category_group_tokens.GetNext()) {
+ std::string category_group_token = category_group_tokens.token();
+ // Don't allow empty tokens, nor tokens with leading or trailing space.
+ DCHECK(!CategoryFilter::IsEmptyOrContainsLeadingOrTrailingWhitespace(
+ category_group_token))
+ << "Disallowed category string";
+ if (MatchPattern(category_group_token.c_str(), category))
+ return true;
+ }
+ return false;
+}
+
+// Enable everything but debug and test categories by default.
+const char* CategoryFilter::kDefaultCategoryFilterString = "-*Debug,-*Test";
+
+CategoryFilter::CategoryFilter(const std::string& filter_string) {
+ if (!filter_string.empty())
+ Initialize(filter_string);
+ else
+ Initialize(CategoryFilter::kDefaultCategoryFilterString);
+}
+
+CategoryFilter::CategoryFilter(const CategoryFilter& cf)
+ : included_(cf.included_),
+ excluded_(cf.excluded_) {
+}
+
+CategoryFilter::~CategoryFilter() {
+}
+
+CategoryFilter& CategoryFilter::operator=(const CategoryFilter& rhs) {
+ if (this == &rhs)
+ return *this;
+
+ included_ = rhs.included_;
+ excluded_ = rhs.excluded_;
+ return *this;
+}
+
+void CategoryFilter::Initialize(const std::string& filter_string) {
+ // Tokenize list of categories, delimited by ','.
+ StringTokenizer tokens(filter_string, ",");
+ // Add each token to the appropriate list (included_,excluded_).
+ while (tokens.GetNext()) {
+ std::string category = tokens.token();
+ // Ignore empty categories.
+ if (category.empty())
+ continue;
+ // Excluded categories start with '-'.
+ if (category.at(0) == '-') {
+ // Remove '-' from category string.
+ category = category.substr(1);
+ excluded_.push_back(category);
+ } else {
+ included_.push_back(category);
+ }
+ }
+}
+
+void CategoryFilter::WriteString(std::string* out,
+ bool included) const {
+ std::vector<std::string>::const_iterator ci;
+ std::vector<std::string>::const_iterator end;
+ if (included) {
+ ci = included_.begin();
+ end = included_.end();
+ } else {
+ ci = excluded_.begin();
+ end = excluded_.end();
+ }
+
+ // Prepend commas for all excluded categories IF we have included categories.
+ bool prepend_comma_for_first_excluded = !included && !included_.empty();
+ int token_cnt = 0;
+ for (; ci != end; ++ci) {
+ if (token_cnt > 0 || prepend_comma_for_first_excluded)
+ StringAppendF(out, ",");
+ StringAppendF(out, "%s%s", (included ? "" : "-"), ci->c_str());
+ ++token_cnt;
+ }
+}
+
+std::string CategoryFilter::ToString() const {
+ std::string filter_string;
+ WriteString(&filter_string, true);
+ WriteString(&filter_string, false);
+
+ return filter_string;
+}
+
+bool CategoryFilter::IsCategoryGroupEnabled(
+ const char* category_group_name) const {
+ // TraceLog should call this method only as part of enabling/disabling
+ // categories.
+ std::vector<std::string>::const_iterator ci = included_.begin();
+ for (; ci != included_.end(); ++ci) {
+ if (DoesCategoryGroupContainCategory(category_group_name, ci->c_str()))
+ return true;
+ }
+ ci = excluded_.begin();
+ for (; ci != excluded_.end(); ++ci) {
+ if (DoesCategoryGroupContainCategory(category_group_name, ci->c_str()))
+ return false;
+ }
+ // If the category group is not excluded, and there are no included patterns
+ // we consider this pattern enabled.
+ return included_.empty();
+}
+
+void CategoryFilter::Merge(const CategoryFilter& nested_filter) {
+ included_.insert(included_.end(),
+ nested_filter.included_.begin(),
+ nested_filter.included_.end());
+ excluded_.insert(excluded_.end(),
+ nested_filter.excluded_.begin(),
+ nested_filter.excluded_.end());
+}
+
+bool CategoryFilter::HasIncludedPatterns() const {
+ return !included_.empty();
+}
+
+void CategoryFilter::Clear() {
+ included_.clear();
+ excluded_.clear();
+}
+
} // namespace debug
} // namespace base
@@ -1201,43 +1446,45 @@
ScopedTrace::ScopedTrace(
TRACE_EVENT_API_ATOMIC_WORD* event_uid, const char* name) {
- category_enabled_ =
+ category_group_enabled_ =
reinterpret_cast<const unsigned char*>(TRACE_EVENT_API_ATOMIC_LOAD(
*event_uid));
- if (!category_enabled_) {
- category_enabled_ = TRACE_EVENT_API_GET_CATEGORY_ENABLED("gpu");
+ if (!category_group_enabled_) {
+ category_group_enabled_ = TRACE_EVENT_API_GET_CATEGORY_GROUP_ENABLED("gpu");
TRACE_EVENT_API_ATOMIC_STORE(
*event_uid,
- reinterpret_cast<TRACE_EVENT_API_ATOMIC_WORD>(category_enabled_));
+ reinterpret_cast<TRACE_EVENT_API_ATOMIC_WORD>(category_group_enabled_));
}
- if (*category_enabled_) {
+ if (*category_group_enabled_) {
name_ = name;
TRACE_EVENT_API_ADD_TRACE_EVENT(
TRACE_EVENT_PHASE_BEGIN, // phase
- category_enabled_, // category enabled
+ category_group_enabled_, // category enabled
name, // name
0, // id
0, // num_args
NULL, // arg_names
NULL, // arg_types
NULL, // arg_values
+ NULL, // convertable_values
TRACE_EVENT_FLAG_NONE); // flags
} else {
- category_enabled_ = NULL;
+ category_group_enabled_ = NULL;
}
}
ScopedTrace::~ScopedTrace() {
- if (category_enabled_ && *category_enabled_) {
+ if (category_group_enabled_ && *category_group_enabled_) {
TRACE_EVENT_API_ADD_TRACE_EVENT(
TRACE_EVENT_PHASE_END, // phase
- category_enabled_, // category enabled
+ category_group_enabled_, // category enabled
name_, // name
0, // id
0, // num_args
NULL, // arg_names
NULL, // arg_types
NULL, // arg_values
+ NULL, // convertable values
TRACE_EVENT_FLAG_NONE); // flags
}
}
diff --git a/base/debug/trace_event_impl.h b/base/debug/trace_event_impl.h
index 7652419..30178a7 100644
--- a/base/debug/trace_event_impl.h
+++ b/base/debug/trace_event_impl.h
@@ -6,6 +6,7 @@
#ifndef BASE_DEBUG_TRACE_EVENT_IMPL_H_
#define BASE_DEBUG_TRACE_EVENT_IMPL_H_
+#include <stack>
#include <string>
#include <vector>
@@ -46,6 +47,19 @@
namespace debug {
+// For any argument of type TRACE_VALUE_TYPE_CONVERTABLE the provided
+// class must implement this interface.
+class ConvertableToTraceFormat {
+ public:
+ virtual ~ConvertableToTraceFormat() {}
+
+ // Append the class info to the provided |out| string. The appended
+ // data must be a valid JSON object. Strings must be propertly quoted, and
+ // escaped. There is no processing applied to the content after it is
+ // appended.
+ virtual void AppendAsTraceFormat(std::string* out) const = 0;
+};
+
const int kTraceMaxNumArgs = 2;
// Output records are "Events" and can be obtained via the
@@ -67,14 +81,17 @@
TraceEvent(int thread_id,
TimeTicks timestamp,
char phase,
- const unsigned char* category_enabled,
+ const unsigned char* category_group_enabled,
const char* name,
unsigned long long id,
int num_args,
const char** arg_names,
const unsigned char* arg_types,
const unsigned long long* arg_values,
+ scoped_ptr<ConvertableToTraceFormat> convertable_values[],
unsigned char flags);
+ TraceEvent(const TraceEvent& other);
+ TraceEvent& operator=(const TraceEvent& other);
~TraceEvent();
// Serialize event data to JSON
@@ -96,7 +113,10 @@
return parameter_copy_storage_.get();
}
- const unsigned char* category_enabled() const { return category_enabled_; }
+ const unsigned char* category_group_enabled() const {
+ return category_group_enabled_;
+ }
+
const char* name() const { return name_; }
private:
@@ -106,7 +126,8 @@
unsigned long long id_;
TraceValue arg_values_[kTraceMaxNumArgs];
const char* arg_names_[kTraceMaxNumArgs];
- const unsigned char* category_enabled_;
+ scoped_ptr<ConvertableToTraceFormat> convertable_values_[kTraceMaxNumArgs];
+ const unsigned char* category_group_enabled_;
const char* name_;
scoped_refptr<base::RefCountedString> parameter_copy_storage_;
int thread_id_;
@@ -173,6 +194,67 @@
bool append_comma_;
};
+class BASE_EXPORT CategoryFilter {
+ public:
+ // The default category filter, used when none is provided.
+ // Allows all categories through, except if they end in the suffix 'Debug' or
+ // 'Test'.
+ static const char* kDefaultCategoryFilterString;
+
+ // |filter_string| is a comma-delimited list of category wildcards.
+ // A category can have an optional '-' prefix to make it an excluded category.
+ // All the same rules apply above, so for example, having both included and
+ // excluded categories in the same list would not be supported.
+ //
+ // Example: CategoryFilter"test_MyTest*");
+ // Example: CategoryFilter("test_MyTest*,test_OtherStuff");
+ // Example: CategoryFilter("-excluded_category1,-excluded_category2");
+ // Example: CategoryFilter("-*,webkit"); would disable everything but webkit.
+ // Example: CategoryFilter("-webkit"); would enable everything but webkit.
+ explicit CategoryFilter(const std::string& filter_string);
+
+ CategoryFilter(const CategoryFilter& cf);
+
+ ~CategoryFilter();
+
+ CategoryFilter& operator=(const CategoryFilter& rhs);
+
+ // Writes the string representation of the CategoryFilter. This is a comma
+ // separated string, similar in nature to the one used to determine
+ // enabled/disabled category patterns, except here there is an arbitrary
+ // order, included categories go first, then excluded categories. Excluded
+ // categories are distinguished from included categories by the prefix '-'.
+ std::string ToString() const;
+
+ // Determines whether category group would be enabled or
+ // disabled by this category filter.
+ bool IsCategoryGroupEnabled(const char* category_group) const;
+
+ // Merges nested_filter with the current CategoryFilter
+ void Merge(const CategoryFilter& nested_filter);
+
+ // Determines whether or not we have explicitly allowed category patterns.
+ bool HasIncludedPatterns() const;
+
+ // Clears both included/excluded pattern lists. This would be equivalent to
+ // creating a CategoryFilter with an empty string, through the constructor.
+ // i.e: CategoryFilter("").
+ //
+ // When using an empty filter, all categories are considered included as we
+ // are not excluding anything.
+ void Clear();
+
+ static bool IsEmptyOrContainsLeadingOrTrailingWhitespace(
+ const std::string& str);
+
+ private:
+ void Initialize(const std::string& filter_string);
+ void WriteString(std::string* out, bool included) const;
+
+ std::vector<std::string> included_;
+ std::vector<std::string> excluded_;
+};
+
class TraceSamplingThread;
class BASE_EXPORT TraceLog {
@@ -197,7 +279,10 @@
RECORD_CONTINUOUSLY = 1 << 1,
// Enable the sampling profiler.
- ENABLE_SAMPLING = 1 << 2
+ ENABLE_SAMPLING = 1 << 2,
+
+ // Echo to VLOG. Events are discared.
+ ECHO_TO_VLOG = 1 << 3
};
static TraceLog* GetInstance();
@@ -206,43 +291,21 @@
// the string does not provide valid options.
static Options TraceOptionsFromString(const std::string& str);
- // Get set of known categories. This can change as new code paths are reached.
- // The known categories are inserted into |categories|.
- void GetKnownCategories(std::vector<std::string>* categories);
+ // Get set of known category groups. This can change as new code paths are
+ // reached. The known category groups are inserted into |category_groups|.
+ void GetKnownCategoryGroups(std::vector<std::string>* category_groups);
- // Enable tracing for provided list of categories. If tracing is already
- // enabled, this method does nothing -- changing categories during trace is
- // not supported.
- // If both included_categories and excluded_categories are empty,
- // all categories are traced.
- // Else if included_categories is non-empty, only those are traced.
- // Else if excluded_categories is non-empty, everything but those are traced.
- // Wildcards * and ? are supported (see MatchPattern in string_util.h).
- void SetEnabled(const std::vector<std::string>& included_categories,
- const std::vector<std::string>& excluded_categories,
- Options options);
-
- // |categories| is a comma-delimited list of category wildcards.
- // A category can have an optional '-' prefix to make it an excluded category.
- // All the same rules apply above, so for example, having both included and
- // excluded categories in the same list would not be supported.
- //
- // Example: SetEnabled("test_MyTest*");
- // Example: SetEnabled("test_MyTest*,test_OtherStuff");
- // Example: SetEnabled("-excluded_category1,-excluded_category2");
- void SetEnabled(const std::string& categories, Options options);
-
- // Retieves the categories set via a prior call to SetEnabled(). Only
- // meaningful if |IsEnabled()| is true.
- void GetEnabledTraceCategories(std::vector<std::string>* included_out,
- std::vector<std::string>* excluded_out);
+ // Retrieves the current CategoryFilter.
+ const CategoryFilter& GetCurrentCategoryFilter();
Options trace_options() const { return trace_options_; }
+ // Enables tracing. See CategoryFilter comments for details
+ // on how to control what categories will be traced.
+ void SetEnabled(const CategoryFilter& category_filter, Options options);
+
// Disable tracing for all categories.
void SetDisabled();
- // Helper method to enable/disable tracing for all categories.
- void SetEnabled(bool enabled, Options options);
bool IsEnabled() { return !!enable_count_; }
#if defined(OS_ANDROID)
@@ -285,7 +348,7 @@
// after a call to SetEventCallback() that replaces or clears the callback.
// This callback may be invoked on any thread.
typedef void (*EventCallback)(char phase,
- const unsigned char* category_enabled,
+ const unsigned char* category_group_enabled,
const char* name,
unsigned long long id,
int num_args,
@@ -304,24 +367,28 @@
void Flush(const OutputCallback& cb);
// Called by TRACE_EVENT* macros, don't call this directly.
- static const unsigned char* GetCategoryEnabled(const char* name);
- static const char* GetCategoryName(const unsigned char* category_enabled);
+ // The name parameter is a category group for example:
+ // TRACE_EVENT0("renderer,webkit", "WebViewImpl::HandleInputEvent")
+ static const unsigned char* GetCategoryGroupEnabled(const char* name);
+ static const char* GetCategoryGroupName(
+ const unsigned char* category_group_enabled);
// Called by TRACE_EVENT* macros, don't call this directly.
// If |copy| is set, |name|, |arg_name1| and |arg_name2| will be deep copied
// into the event; see "Memory scoping note" and TRACE_EVENT_COPY_XXX above.
void AddTraceEvent(char phase,
- const unsigned char* category_enabled,
- const char* name,
+ const unsigned char* category_group_enabled,
+ const char* category_group,
unsigned long long id,
int num_args,
const char** arg_names,
const unsigned char* arg_types,
const unsigned long long* arg_values,
+ scoped_ptr<ConvertableToTraceFormat> convertable_values[],
unsigned char flags);
void AddTraceEventWithThreadIdAndTimestamp(
char phase,
- const unsigned char* category_enabled,
+ const unsigned char* category_group_enabled,
const char* name,
unsigned long long id,
int thread_id,
@@ -330,13 +397,14 @@
const char** arg_names,
const unsigned char* arg_types,
const unsigned long long* arg_values,
+ scoped_ptr<ConvertableToTraceFormat> convertable_values[],
unsigned char flags);
static void AddTraceEventEtw(char phase,
- const char* name,
+ const char* category_group,
const void* id,
const char* extra);
static void AddTraceEventEtw(char phase,
- const char* name,
+ const char* category_group,
const void* id,
const std::string& extra);
@@ -379,8 +447,14 @@
// by the Singleton class.
friend struct StaticMemorySingletonTraits<TraceLog>;
- // The pointer returned from GetCategoryEnabledInternal() points to a value
- // with zero or more of the following bits. Used in this class only.
+ // Enable/disable each category group based on the current category_filter_.
+ // If the category group contains a category that matches an included category
+ // pattern, that category group will be enabled.
+ void EnableIncludedCategoryGroups();
+ void EnableIncludedCategoryGroup(int category_index);
+
+ // The pointer returned from GetCategoryGroupEnabledInternal() points to a
+ // value with zero or more of the following bits. Used in this class only.
// The TRACE_EVENT macros should only use the value as a bool.
enum CategoryEnabledFlags {
// Normal enabled flag for categories enabled with Enable().
@@ -415,12 +489,12 @@
TraceLog();
~TraceLog();
- const unsigned char* GetCategoryEnabledInternal(const char* name);
+ const unsigned char* GetCategoryGroupEnabledInternal(const char* name);
void AddThreadNameMetadataEvents();
#if defined(OS_ANDROID)
void SendToATrace(char phase,
- const char* category,
+ const char* category_group,
const char* name,
unsigned long long id,
int num_args,
@@ -428,7 +502,7 @@
const unsigned char* arg_types,
const unsigned long long* arg_values,
unsigned char flags);
- static void ApplyATraceEnabledFlag(unsigned char* category_enabled);
+ static void ApplyATraceEnabledFlag(unsigned char* category_group_enabled);
#endif
TraceBuffer* GetTraceBuffer();
@@ -441,12 +515,12 @@
NotificationCallback notification_callback_;
scoped_ptr<TraceBuffer> logged_events_;
EventCallback event_callback_;
- std::vector<std::string> included_categories_;
- std::vector<std::string> excluded_categories_;
bool dispatching_to_observer_list_;
ObserverList<EnabledStateChangedObserver> enabled_state_observer_list_;
base::hash_map<int, std::string> thread_names_;
+ base::hash_map<int, std::stack<TimeTicks> > thread_event_start_times_;
+ base::hash_map<std::string, int> thread_colors_;
// XORed with TraceID to make it unlikely to collide with other processes.
unsigned long long process_id_hash_;
@@ -465,6 +539,8 @@
scoped_ptr<TraceSamplingThread> sampling_thread_;
PlatformThreadHandle sampling_thread_handle_;
+ CategoryFilter category_filter_;
+
DISALLOW_COPY_AND_ASSIGN(TraceLog);
};
diff --git a/base/debug/trace_event_internal.h b/base/debug/trace_event_internal.h
deleted file mode 100644
index 864315e..0000000
--- a/base/debug/trace_event_internal.h
+++ /dev/null
@@ -1,1046 +0,0 @@
-// Copyright (c) 2012 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 header file defines the set of trace_event macros without specifying
-// how the events actually get collected and stored. If you need to expose trace
-// events to some other universe, you can copy-and-paste this file as well as
-// trace_event.h, modifying the macros contained there as necessary for the
-// target platform. The end result is that multiple libraries can funnel events
-// through to a shared trace event collector.
-
-// Trace events are for tracking application performance and resource usage.
-// Macros are provided to track:
-// Begin and end of function calls
-// Counters
-//
-// Events are issued against categories. Whereas LOG's
-// categories are statically defined, TRACE categories are created
-// implicitly with a string. For example:
-// TRACE_EVENT_INSTANT0("MY_SUBSYSTEM", "SomeImportantEvent")
-//
-// Events can be INSTANT, or can be pairs of BEGIN and END in the same scope:
-// TRACE_EVENT_BEGIN0("MY_SUBSYSTEM", "SomethingCostly")
-// doSomethingCostly()
-// TRACE_EVENT_END0("MY_SUBSYSTEM", "SomethingCostly")
-// Note: our tools can't always determine the correct BEGIN/END pairs unless
-// these are used in the same scope. Use ASYNC_BEGIN/ASYNC_END macros if you
-// need them to be in separate scopes.
-//
-// A common use case is to trace entire function scopes. This
-// issues a trace BEGIN and END automatically:
-// void doSomethingCostly() {
-// TRACE_EVENT0("MY_SUBSYSTEM", "doSomethingCostly");
-// ...
-// }
-//
-// Additional parameters can be associated with an event:
-// void doSomethingCostly2(int howMuch) {
-// TRACE_EVENT1("MY_SUBSYSTEM", "doSomethingCostly",
-// "howMuch", howMuch);
-// ...
-// }
-//
-// The trace system will automatically add to this information the
-// current process id, thread id, and a timestamp in microseconds.
-//
-// To trace an asynchronous procedure such as an IPC send/receive, use
-// ASYNC_BEGIN and ASYNC_END:
-// [single threaded sender code]
-// static int send_count = 0;
-// ++send_count;
-// TRACE_EVENT_ASYNC_BEGIN0("ipc", "message", send_count);
-// Send(new MyMessage(send_count));
-// [receive code]
-// void OnMyMessage(send_count) {
-// TRACE_EVENT_ASYNC_END0("ipc", "message", send_count);
-// }
-// The third parameter is a unique ID to match ASYNC_BEGIN/ASYNC_END pairs.
-// ASYNC_BEGIN and ASYNC_END can occur on any thread of any traced process.
-// Pointers can be used for the ID parameter, and they will be mangled
-// internally so that the same pointer on two different processes will not
-// match. For example:
-// class MyTracedClass {
-// public:
-// MyTracedClass() {
-// TRACE_EVENT_ASYNC_BEGIN0("category", "MyTracedClass", this);
-// }
-// ~MyTracedClass() {
-// TRACE_EVENT_ASYNC_END0("category", "MyTracedClass", this);
-// }
-// }
-//
-// Trace event also supports counters, which is a way to track a quantity
-// as it varies over time. Counters are created with the following macro:
-// TRACE_COUNTER1("MY_SUBSYSTEM", "myCounter", g_myCounterValue);
-//
-// Counters are process-specific. The macro itself can be issued from any
-// thread, however.
-//
-// Sometimes, you want to track two counters at once. You can do this with two
-// counter macros:
-// TRACE_COUNTER1("MY_SUBSYSTEM", "myCounter0", g_myCounterValue[0]);
-// TRACE_COUNTER1("MY_SUBSYSTEM", "myCounter1", g_myCounterValue[1]);
-// Or you can do it with a combined macro:
-// TRACE_COUNTER2("MY_SUBSYSTEM", "myCounter",
-// "bytesPinned", g_myCounterValue[0],
-// "bytesAllocated", g_myCounterValue[1]);
-// This indicates to the tracing UI that these counters should be displayed
-// in a single graph, as a summed area chart.
-//
-// Since counters are in a global namespace, you may want to disembiguate with a
-// unique ID, by using the TRACE_COUNTER_ID* variations.
-//
-// By default, trace collection is compiled in, but turned off at runtime.
-// Collecting trace data is the responsibility of the embedding
-// application. In Chrome's case, navigating to about:tracing will turn on
-// tracing and display data collected across all active processes.
-//
-//
-// Memory scoping note:
-// Tracing copies the pointers, not the string content, of the strings passed
-// in for category, name, and arg_names. Thus, the following code will
-// cause problems:
-// char* str = strdup("impprtantName");
-// TRACE_EVENT_INSTANT0("SUBSYSTEM", str); // BAD!
-// free(str); // Trace system now has dangling pointer
-//
-// To avoid this issue with the |name| and |arg_name| parameters, use the
-// TRACE_EVENT_COPY_XXX overloads of the macros at additional runtime overhead.
-// Notes: The category must always be in a long-lived char* (i.e. static const).
-// The |arg_values|, when used, are always deep copied with the _COPY
-// macros.
-//
-// When are string argument values copied:
-// const char* arg_values are only referenced by default:
-// TRACE_EVENT1("category", "name",
-// "arg1", "literal string is only referenced");
-// Use TRACE_STR_COPY to force copying of a const char*:
-// TRACE_EVENT1("category", "name",
-// "arg1", TRACE_STR_COPY("string will be copied"));
-// std::string arg_values are always copied:
-// TRACE_EVENT1("category", "name",
-// "arg1", std::string("string will be copied"));
-//
-//
-// Thread Safety:
-// A thread safe singleton and mutex are used for thread safety. Category
-// enabled flags are used to limit the performance impact when the system
-// is not enabled.
-//
-// TRACE_EVENT macros first cache a pointer to a category. The categories are
-// statically allocated and safe at all times, even after exit. Fetching a
-// category is protected by the TraceLog::lock_. Multiple threads initializing
-// the static variable is safe, as they will be serialized by the lock and
-// multiple calls will return the same pointer to the category.
-//
-// Then the category_enabled flag is checked. This is a unsigned char, and
-// not intended to be multithread safe. It optimizes access to AddTraceEvent
-// which is threadsafe internally via TraceLog::lock_. The enabled flag may
-// cause some threads to incorrectly call or skip calling AddTraceEvent near
-// the time of the system being enabled or disabled. This is acceptable as
-// we tolerate some data loss while the system is being enabled/disabled and
-// because AddTraceEvent is threadsafe internally and checks the enabled state
-// again under lock.
-//
-// Without the use of these static category pointers and enabled flags all
-// trace points would carry a significant performance cost of aquiring a lock
-// and resolving the category.
-
-
-#ifndef BASE_DEBUG_TRACE_EVENT_INTERNAL_H_
-#define BASE_DEBUG_TRACE_EVENT_INTERNAL_H_
-
-#include <string>
-
-// By default, const char* argument values are assumed to have long-lived scope
-// and will not be copied. Use this macro to force a const char* to be copied.
-#define TRACE_STR_COPY(str) \
- trace_event_internal::TraceStringWithCopy(str)
-
-// By default, uint64 ID argument values are not mangled with the Process ID in
-// TRACE_EVENT_ASYNC macros. Use this macro to force Process ID mangling.
-#define TRACE_ID_MANGLE(id) \
- trace_event_internal::TraceID::ForceMangle(id)
-
-// Records a pair of begin and end events called "name" for the current
-// scope, with 0, 1 or 2 associated arguments. If the category is not
-// enabled, then this does nothing.
-// - category and name strings must have application lifetime (statics or
-// literals). They may not include " chars.
-#define TRACE_EVENT0(category, name) \
- INTERNAL_TRACE_EVENT_ADD_SCOPED(category, name)
-#define TRACE_EVENT1(category, name, arg1_name, arg1_val) \
- INTERNAL_TRACE_EVENT_ADD_SCOPED(category, name, arg1_name, arg1_val)
-#define TRACE_EVENT2(category, name, arg1_name, arg1_val, arg2_name, arg2_val) \
- INTERNAL_TRACE_EVENT_ADD_SCOPED(category, name, arg1_name, arg1_val, \
- arg2_name, arg2_val)
-
-// Same as TRACE_EVENT except that they are not included in official builds.
-#ifdef OFFICIAL_BUILD
-#define UNSHIPPED_TRACE_EVENT0(category, name) (void)0
-#define UNSHIPPED_TRACE_EVENT1(category, name, arg1_name, arg1_val) (void)0
-#define UNSHIPPED_TRACE_EVENT2(category, name, arg1_name, arg1_val, \
- arg2_name, arg2_val) (void)0
-#define UNSHIPPED_TRACE_EVENT_INSTANT0(category, name) (void)0
-#define UNSHIPPED_TRACE_EVENT_INSTANT1(category, name, arg1_name, arg1_val) \
- (void)0
-#define UNSHIPPED_TRACE_EVENT_INSTANT2(category, name, arg1_name, arg1_val, \
- arg2_name, arg2_val) (void)0
-#else
-#define UNSHIPPED_TRACE_EVENT0(category, name) \
- TRACE_EVENT0(category, name)
-#define UNSHIPPED_TRACE_EVENT1(category, name, arg1_name, arg1_val) \
- TRACE_EVENT1(category, name, arg1_name, arg1_val)
-#define UNSHIPPED_TRACE_EVENT2(category, name, arg1_name, arg1_val, \
- arg2_name, arg2_val) \
- TRACE_EVENT2(category, name, arg1_name, arg1_val, arg2_name, arg2_val)
-#define UNSHIPPED_TRACE_EVENT_INSTANT0(category, name) \
- TRACE_EVENT_INSTANT0(category, name)
-#define UNSHIPPED_TRACE_EVENT_INSTANT1(category, name, arg1_name, arg1_val) \
- TRACE_EVENT_INSTANT1(category, name, arg1_name, arg1_val)
-#define UNSHIPPED_TRACE_EVENT_INSTANT2(category, name, arg1_name, arg1_val, \
- arg2_name, arg2_val) \
- TRACE_EVENT_INSTANT2(category, name, arg1_name, arg1_val, \
- arg2_name, arg2_val)
-#endif
-
-// Records a single event called "name" immediately, with 0, 1 or 2
-// associated arguments. If the category is not enabled, then this
-// does nothing.
-// - category and name strings must have application lifetime (statics or
-// literals). They may not include " chars.
-#define TRACE_EVENT_INSTANT0(category, name) \
- INTERNAL_TRACE_EVENT_ADD(TRACE_EVENT_PHASE_INSTANT, \
- category, name, TRACE_EVENT_FLAG_NONE)
-#define TRACE_EVENT_INSTANT1(category, name, arg1_name, arg1_val) \
- INTERNAL_TRACE_EVENT_ADD(TRACE_EVENT_PHASE_INSTANT, \
- category, name, TRACE_EVENT_FLAG_NONE, arg1_name, arg1_val)
-#define TRACE_EVENT_INSTANT2(category, name, arg1_name, arg1_val, \
- arg2_name, arg2_val) \
- INTERNAL_TRACE_EVENT_ADD(TRACE_EVENT_PHASE_INSTANT, \
- category, name, TRACE_EVENT_FLAG_NONE, arg1_name, arg1_val, \
- arg2_name, arg2_val)
-#define TRACE_EVENT_COPY_INSTANT0(category, name) \
- INTERNAL_TRACE_EVENT_ADD(TRACE_EVENT_PHASE_INSTANT, \
- category, name, TRACE_EVENT_FLAG_COPY)
-#define TRACE_EVENT_COPY_INSTANT1(category, name, arg1_name, arg1_val) \
- INTERNAL_TRACE_EVENT_ADD(TRACE_EVENT_PHASE_INSTANT, \
- category, name, TRACE_EVENT_FLAG_COPY, arg1_name, arg1_val)
-#define TRACE_EVENT_COPY_INSTANT2(category, name, arg1_name, arg1_val, \
- arg2_name, arg2_val) \
- INTERNAL_TRACE_EVENT_ADD(TRACE_EVENT_PHASE_INSTANT, \
- category, name, TRACE_EVENT_FLAG_COPY, arg1_name, arg1_val, \
- arg2_name, arg2_val)
-
-// Sets the current sample state to the given category and name (both must be
-// constant strings). These states are intended for a sampling profiler.
-// Implementation note: we store category and name together because we don't
-// want the inconsistency/expense of storing two pointers.
-// |thread_bucket| is [0..2] and is used to statically isolate samples in one
-// thread from others.
-#define TRACE_EVENT_SAMPLE_STATE(thread_bucket, category, name) \
- TRACE_EVENT_API_ATOMIC_STORE( \
- TRACE_EVENT_API_THREAD_BUCKET(thread_bucket), \
- reinterpret_cast<TRACE_EVENT_API_ATOMIC_WORD>(category "\0" name));
-
-// Records a single BEGIN event called "name" immediately, with 0, 1 or 2
-// associated arguments. If the category is not enabled, then this
-// does nothing.
-// - category and name strings must have application lifetime (statics or
-// literals). They may not include " chars.
-#define TRACE_EVENT_BEGIN0(category, name) \
- INTERNAL_TRACE_EVENT_ADD(TRACE_EVENT_PHASE_BEGIN, \
- category, name, TRACE_EVENT_FLAG_NONE)
-#define TRACE_EVENT_BEGIN1(category, name, arg1_name, arg1_val) \
- INTERNAL_TRACE_EVENT_ADD(TRACE_EVENT_PHASE_BEGIN, \
- category, name, TRACE_EVENT_FLAG_NONE, arg1_name, arg1_val)
-#define TRACE_EVENT_BEGIN2(category, name, arg1_name, arg1_val, \
- arg2_name, arg2_val) \
- INTERNAL_TRACE_EVENT_ADD(TRACE_EVENT_PHASE_BEGIN, \
- category, name, TRACE_EVENT_FLAG_NONE, arg1_name, arg1_val, \
- arg2_name, arg2_val)
-#define TRACE_EVENT_COPY_BEGIN0(category, name) \
- INTERNAL_TRACE_EVENT_ADD(TRACE_EVENT_PHASE_BEGIN, \
- category, name, TRACE_EVENT_FLAG_COPY)
-#define TRACE_EVENT_COPY_BEGIN1(category, name, arg1_name, arg1_val) \
- INTERNAL_TRACE_EVENT_ADD(TRACE_EVENT_PHASE_BEGIN, \
- category, name, TRACE_EVENT_FLAG_COPY, arg1_name, arg1_val)
-#define TRACE_EVENT_COPY_BEGIN2(category, name, arg1_name, arg1_val, \
- arg2_name, arg2_val) \
- INTERNAL_TRACE_EVENT_ADD(TRACE_EVENT_PHASE_BEGIN, \
- category, name, TRACE_EVENT_FLAG_COPY, arg1_name, arg1_val, \
- arg2_name, arg2_val)
-
-// Similar to TRACE_EVENT_BEGINx but with a custom |at| timestamp provided.
-// - |id| is used to match the _BEGIN event with the _END event.
-// Events are considered to match if their category, name and id values all
-// match. |id| must either be a pointer or an integer value up to 64 bits. If
-// it's a pointer, the bits will be xored with a hash of the process ID so
-// that the same pointer on two different processes will not collide.
-#define TRACE_EVENT_BEGIN_WITH_ID_TID_AND_TIMESTAMP0(category, \
- name, id, thread_id, timestamp) \
- INTERNAL_TRACE_EVENT_ADD_WITH_ID_TID_AND_TIMESTAMP( \
- TRACE_EVENT_PHASE_ASYNC_BEGIN, category, name, id, thread_id, \
- timestamp, TRACE_EVENT_FLAG_NONE)
-#define TRACE_EVENT_COPY_BEGIN_WITH_ID_TID_AND_TIMESTAMP0( \
- category, name, id, thread_id, timestamp) \
- INTERNAL_TRACE_EVENT_ADD_WITH_ID_TID_AND_TIMESTAMP( \
- TRACE_EVENT_PHASE_ASYNC_BEGIN, category, name, id, thread_id, \
- timestamp, TRACE_EVENT_FLAG_COPY)
-
-// Records a single END event for "name" immediately. If the category
-// is not enabled, then this does nothing.
-// - category and name strings must have application lifetime (statics or
-// literals). They may not include " chars.
-#define TRACE_EVENT_END0(category, name) \
- INTERNAL_TRACE_EVENT_ADD(TRACE_EVENT_PHASE_END, \
- category, name, TRACE_EVENT_FLAG_NONE)
-#define TRACE_EVENT_END1(category, name, arg1_name, arg1_val) \
- INTERNAL_TRACE_EVENT_ADD(TRACE_EVENT_PHASE_END, \
- category, name, TRACE_EVENT_FLAG_NONE, arg1_name, arg1_val)
-#define TRACE_EVENT_END2(category, name, arg1_name, arg1_val, \
- arg2_name, arg2_val) \
- INTERNAL_TRACE_EVENT_ADD(TRACE_EVENT_PHASE_END, \
- category, name, TRACE_EVENT_FLAG_NONE, arg1_name, arg1_val, \
- arg2_name, arg2_val)
-#define TRACE_EVENT_COPY_END0(category, name) \
- INTERNAL_TRACE_EVENT_ADD(TRACE_EVENT_PHASE_END, \
- category, name, TRACE_EVENT_FLAG_COPY)
-#define TRACE_EVENT_COPY_END1(category, name, arg1_name, arg1_val) \
- INTERNAL_TRACE_EVENT_ADD(TRACE_EVENT_PHASE_END, \
- category, name, TRACE_EVENT_FLAG_COPY, arg1_name, arg1_val)
-#define TRACE_EVENT_COPY_END2(category, name, arg1_name, arg1_val, \
- arg2_name, arg2_val) \
- INTERNAL_TRACE_EVENT_ADD(TRACE_EVENT_PHASE_END, \
- category, name, TRACE_EVENT_FLAG_COPY, arg1_name, arg1_val, \
- arg2_name, arg2_val)
-
-// Similar to TRACE_EVENT_ENDx but with a custom |at| timestamp provided.
-// - |id| is used to match the _BEGIN event with the _END event.
-// Events are considered to match if their category, name and id values all
-// match. |id| must either be a pointer or an integer value up to 64 bits. If
-// it's a pointer, the bits will be xored with a hash of the process ID so
-// that the same pointer on two different processes will not collide.
-#define TRACE_EVENT_END_WITH_ID_TID_AND_TIMESTAMP0(category, \
- name, id, thread_id, timestamp) \
- INTERNAL_TRACE_EVENT_ADD_WITH_ID_TID_AND_TIMESTAMP( \
- TRACE_EVENT_PHASE_ASYNC_END, category, name, id, thread_id, timestamp, \
- TRACE_EVENT_FLAG_NONE)
-#define TRACE_EVENT_COPY_END_WITH_ID_TID_AND_TIMESTAMP0( \
- category, name, id, thread_id, timestamp) \
- INTERNAL_TRACE_EVENT_ADD_WITH_ID_TID_AND_TIMESTAMP( \
- TRACE_EVENT_PHASE_ASYNC_END, category, name, id, thread_id, timestamp, \
- TRACE_EVENT_FLAG_COPY)
-
-// Records the value of a counter called "name" immediately. Value
-// must be representable as a 32 bit integer.
-// - category and name strings must have application lifetime (statics or
-// literals). They may not include " chars.
-#define TRACE_COUNTER1(category, name, value) \
- INTERNAL_TRACE_EVENT_ADD(TRACE_EVENT_PHASE_COUNTER, \
- category, name, TRACE_EVENT_FLAG_NONE, \
- "value", static_cast<int>(value))
-#define TRACE_COPY_COUNTER1(category, name, value) \
- INTERNAL_TRACE_EVENT_ADD(TRACE_EVENT_PHASE_COUNTER, \
- category, name, TRACE_EVENT_FLAG_COPY, \
- "value", static_cast<int>(value))
-
-// Records the values of a multi-parted counter called "name" immediately.
-// The UI will treat value1 and value2 as parts of a whole, displaying their
-// values as a stacked-bar chart.
-// - category and name strings must have application lifetime (statics or
-// literals). They may not include " chars.
-#define TRACE_COUNTER2(category, name, value1_name, value1_val, \
- value2_name, value2_val) \
- INTERNAL_TRACE_EVENT_ADD(TRACE_EVENT_PHASE_COUNTER, \
- category, name, TRACE_EVENT_FLAG_NONE, \
- value1_name, static_cast<int>(value1_val), \
- value2_name, static_cast<int>(value2_val))
-#define TRACE_COPY_COUNTER2(category, name, value1_name, value1_val, \
- value2_name, value2_val) \
- INTERNAL_TRACE_EVENT_ADD(TRACE_EVENT_PHASE_COUNTER, \
- category, name, TRACE_EVENT_FLAG_COPY, \
- value1_name, static_cast<int>(value1_val), \
- value2_name, static_cast<int>(value2_val))
-
-// Records the value of a counter called "name" immediately. Value
-// must be representable as a 32 bit integer.
-// - category and name strings must have application lifetime (statics or
-// literals). They may not include " chars.
-// - |id| is used to disambiguate counters with the same name. It must either
-// be a pointer or an integer value up to 64 bits. If it's a pointer, the bits
-// will be xored with a hash of the process ID so that the same pointer on
-// two different processes will not collide.
-#define TRACE_COUNTER_ID1(category, name, id, value) \
- INTERNAL_TRACE_EVENT_ADD_WITH_ID(TRACE_EVENT_PHASE_COUNTER, \
- category, name, id, TRACE_EVENT_FLAG_NONE, \
- "value", static_cast<int>(value))
-#define TRACE_COPY_COUNTER_ID1(category, name, id, value) \
- INTERNAL_TRACE_EVENT_ADD_WITH_ID(TRACE_EVENT_PHASE_COUNTER, \
- category, name, id, TRACE_EVENT_FLAG_COPY, \
- "value", static_cast<int>(value))
-
-// Records the values of a multi-parted counter called "name" immediately.
-// The UI will treat value1 and value2 as parts of a whole, displaying their
-// values as a stacked-bar chart.
-// - category and name strings must have application lifetime (statics or
-// literals). They may not include " chars.
-// - |id| is used to disambiguate counters with the same name. It must either
-// be a pointer or an integer value up to 64 bits. If it's a pointer, the bits
-// will be xored with a hash of the process ID so that the same pointer on
-// two different processes will not collide.
-#define TRACE_COUNTER_ID2(category, name, id, value1_name, value1_val, \
- value2_name, value2_val) \
- INTERNAL_TRACE_EVENT_ADD_WITH_ID(TRACE_EVENT_PHASE_COUNTER, \
- category, name, id, TRACE_EVENT_FLAG_NONE, \
- value1_name, static_cast<int>(value1_val), \
- value2_name, static_cast<int>(value2_val))
-#define TRACE_COPY_COUNTER_ID2(category, name, id, value1_name, value1_val, \
- value2_name, value2_val) \
- INTERNAL_TRACE_EVENT_ADD_WITH_ID(TRACE_EVENT_PHASE_COUNTER, \
- category, name, id, TRACE_EVENT_FLAG_COPY, \
- value1_name, static_cast<int>(value1_val), \
- value2_name, static_cast<int>(value2_val))
-
-
-// Records a single ASYNC_BEGIN event called "name" immediately, with 0, 1 or 2
-// associated arguments. If the category is not enabled, then this
-// does nothing.
-// - category and name strings must have application lifetime (statics or
-// literals). They may not include " chars.
-// - |id| is used to match the ASYNC_BEGIN event with the ASYNC_END event. ASYNC
-// events are considered to match if their category, name and id values all
-// match. |id| must either be a pointer or an integer value up to 64 bits. If
-// it's a pointer, the bits will be xored with a hash of the process ID so
-// that the same pointer on two different processes will not collide.
-// An asynchronous operation can consist of multiple phases. The first phase is
-// defined by the ASYNC_BEGIN calls. Additional phases can be defined using the
-// ASYNC_STEP macros. When the operation completes, call ASYNC_END.
-// An ASYNC trace typically occur on a single thread (if not, they will only be
-// drawn on the thread defined in the ASYNC_BEGIN event), but all events in that
-// operation must use the same |name| and |id|. Each event can have its own
-// args.
-#define TRACE_EVENT_ASYNC_BEGIN0(category, name, id) \
- INTERNAL_TRACE_EVENT_ADD_WITH_ID(TRACE_EVENT_PHASE_ASYNC_BEGIN, \
- category, name, id, TRACE_EVENT_FLAG_NONE)
-#define TRACE_EVENT_ASYNC_BEGIN1(category, name, id, arg1_name, arg1_val) \
- INTERNAL_TRACE_EVENT_ADD_WITH_ID(TRACE_EVENT_PHASE_ASYNC_BEGIN, \
- category, name, id, TRACE_EVENT_FLAG_NONE, arg1_name, arg1_val)
-#define TRACE_EVENT_ASYNC_BEGIN2(category, name, id, arg1_name, arg1_val, \
- arg2_name, arg2_val) \
- INTERNAL_TRACE_EVENT_ADD_WITH_ID(TRACE_EVENT_PHASE_ASYNC_BEGIN, \
- category, name, id, TRACE_EVENT_FLAG_NONE, \
- arg1_name, arg1_val, arg2_name, arg2_val)
-#define TRACE_EVENT_COPY_ASYNC_BEGIN0(category, name, id) \
- INTERNAL_TRACE_EVENT_ADD_WITH_ID(TRACE_EVENT_PHASE_ASYNC_BEGIN, \
- category, name, id, TRACE_EVENT_FLAG_COPY)
-#define TRACE_EVENT_COPY_ASYNC_BEGIN1(category, name, id, arg1_name, arg1_val) \
- INTERNAL_TRACE_EVENT_ADD_WITH_ID(TRACE_EVENT_PHASE_ASYNC_BEGIN, \
- category, name, id, TRACE_EVENT_FLAG_COPY, \
- arg1_name, arg1_val)
-#define TRACE_EVENT_COPY_ASYNC_BEGIN2(category, name, id, arg1_name, arg1_val, \
- arg2_name, arg2_val) \
- INTERNAL_TRACE_EVENT_ADD_WITH_ID(TRACE_EVENT_PHASE_ASYNC_BEGIN, \
- category, name, id, TRACE_EVENT_FLAG_COPY, \
- arg1_name, arg1_val, arg2_name, arg2_val)
-
-// Records a single ASYNC_STEP event for |step| immediately. If the category
-// is not enabled, then this does nothing. The |name| and |id| must match the
-// ASYNC_BEGIN event above. The |step| param identifies this step within the
-// async event. This should be called at the beginning of the next phase of an
-// asynchronous operation.
-#define TRACE_EVENT_ASYNC_STEP0(category, name, id, step) \
- INTERNAL_TRACE_EVENT_ADD_WITH_ID(TRACE_EVENT_PHASE_ASYNC_STEP, \
- category, name, id, TRACE_EVENT_FLAG_NONE, "step", step)
-#define TRACE_EVENT_ASYNC_STEP1(category, name, id, step, \
- arg1_name, arg1_val) \
- INTERNAL_TRACE_EVENT_ADD_WITH_ID(TRACE_EVENT_PHASE_ASYNC_STEP, \
- category, name, id, TRACE_EVENT_FLAG_NONE, "step", step, \
- arg1_name, arg1_val)
-#define TRACE_EVENT_COPY_ASYNC_STEP0(category, name, id, step) \
- INTERNAL_TRACE_EVENT_ADD_WITH_ID(TRACE_EVENT_PHASE_ASYNC_STEP, \
- category, name, id, TRACE_EVENT_FLAG_COPY, "step", step)
-#define TRACE_EVENT_COPY_ASYNC_STEP1(category, name, id, step, \
- arg1_name, arg1_val) \
- INTERNAL_TRACE_EVENT_ADD_WITH_ID(TRACE_EVENT_PHASE_ASYNC_STEP, \
- category, name, id, TRACE_EVENT_FLAG_COPY, "step", step, \
- arg1_name, arg1_val)
-
-// Records a single ASYNC_END event for "name" immediately. If the category
-// is not enabled, then this does nothing.
-#define TRACE_EVENT_ASYNC_END0(category, name, id) \
- INTERNAL_TRACE_EVENT_ADD_WITH_ID(TRACE_EVENT_PHASE_ASYNC_END, \
- category, name, id, TRACE_EVENT_FLAG_NONE)
-#define TRACE_EVENT_ASYNC_END1(category, name, id, arg1_name, arg1_val) \
- INTERNAL_TRACE_EVENT_ADD_WITH_ID(TRACE_EVENT_PHASE_ASYNC_END, \
- category, name, id, TRACE_EVENT_FLAG_NONE, arg1_name, arg1_val)
-#define TRACE_EVENT_ASYNC_END2(category, name, id, arg1_name, arg1_val, \
- arg2_name, arg2_val) \
- INTERNAL_TRACE_EVENT_ADD_WITH_ID(TRACE_EVENT_PHASE_ASYNC_END, \
- category, name, id, TRACE_EVENT_FLAG_NONE, \
- arg1_name, arg1_val, arg2_name, arg2_val)
-#define TRACE_EVENT_COPY_ASYNC_END0(category, name, id) \
- INTERNAL_TRACE_EVENT_ADD_WITH_ID(TRACE_EVENT_PHASE_ASYNC_END, \
- category, name, id, TRACE_EVENT_FLAG_COPY)
-#define TRACE_EVENT_COPY_ASYNC_END1(category, name, id, arg1_name, arg1_val) \
- INTERNAL_TRACE_EVENT_ADD_WITH_ID(TRACE_EVENT_PHASE_ASYNC_END, \
- category, name, id, TRACE_EVENT_FLAG_COPY, \
- arg1_name, arg1_val)
-#define TRACE_EVENT_COPY_ASYNC_END2(category, name, id, arg1_name, arg1_val, \
- arg2_name, arg2_val) \
- INTERNAL_TRACE_EVENT_ADD_WITH_ID(TRACE_EVENT_PHASE_ASYNC_END, \
- category, name, id, TRACE_EVENT_FLAG_COPY, \
- arg1_name, arg1_val, arg2_name, arg2_val)
-
-
-// Records a single FLOW_BEGIN event called "name" immediately, with 0, 1 or 2
-// associated arguments. If the category is not enabled, then this
-// does nothing.
-// - category and name strings must have application lifetime (statics or
-// literals). They may not include " chars.
-// - |id| is used to match the FLOW_BEGIN event with the FLOW_END event. FLOW
-// events are considered to match if their category, name and id values all
-// match. |id| must either be a pointer or an integer value up to 64 bits. If
-// it's a pointer, the bits will be xored with a hash of the process ID so
-// that the same pointer on two different processes will not collide.
-// FLOW events are different from ASYNC events in how they are drawn by the
-// tracing UI. A FLOW defines asynchronous data flow, such as posting a task
-// (FLOW_BEGIN) and later executing that task (FLOW_END). Expect FLOWs to be
-// drawn as lines or arrows from FLOW_BEGIN scopes to FLOW_END scopes. Similar
-// to ASYNC, a FLOW can consist of multiple phases. The first phase is defined
-// by the FLOW_BEGIN calls. Additional phases can be defined using the FLOW_STEP
-// macros. When the operation completes, call FLOW_END. An async operation can
-// span threads and processes, but all events in that operation must use the
-// same |name| and |id|. Each event can have its own args.
-#define TRACE_EVENT_FLOW_BEGIN0(category, name, id) \
- INTERNAL_TRACE_EVENT_ADD_WITH_ID(TRACE_EVENT_PHASE_FLOW_BEGIN, \
- category, name, id, TRACE_EVENT_FLAG_NONE)
-#define TRACE_EVENT_FLOW_BEGIN1(category, name, id, arg1_name, arg1_val) \
- INTERNAL_TRACE_EVENT_ADD_WITH_ID(TRACE_EVENT_PHASE_FLOW_BEGIN, \
- category, name, id, TRACE_EVENT_FLAG_NONE, arg1_name, arg1_val)
-#define TRACE_EVENT_FLOW_BEGIN2(category, name, id, arg1_name, arg1_val, \
- arg2_name, arg2_val) \
- INTERNAL_TRACE_EVENT_ADD_WITH_ID(TRACE_EVENT_PHASE_FLOW_BEGIN, \
- category, name, id, TRACE_EVENT_FLAG_NONE, \
- arg1_name, arg1_val, arg2_name, arg2_val)
-#define TRACE_EVENT_COPY_FLOW_BEGIN0(category, name, id) \
- INTERNAL_TRACE_EVENT_ADD_WITH_ID(TRACE_EVENT_PHASE_FLOW_BEGIN, \
- category, name, id, TRACE_EVENT_FLAG_COPY)
-#define TRACE_EVENT_COPY_FLOW_BEGIN1(category, name, id, arg1_name, arg1_val) \
- INTERNAL_TRACE_EVENT_ADD_WITH_ID(TRACE_EVENT_PHASE_FLOW_BEGIN, \
- category, name, id, TRACE_EVENT_FLAG_COPY, \
- arg1_name, arg1_val)
-#define TRACE_EVENT_COPY_FLOW_BEGIN2(category, name, id, arg1_name, arg1_val, \
- arg2_name, arg2_val) \
- INTERNAL_TRACE_EVENT_ADD_WITH_ID(TRACE_EVENT_PHASE_FLOW_BEGIN, \
- category, name, id, TRACE_EVENT_FLAG_COPY, \
- arg1_name, arg1_val, arg2_name, arg2_val)
-
-// Records a single FLOW_STEP event for |step| immediately. If the category
-// is not enabled, then this does nothing. The |name| and |id| must match the
-// FLOW_BEGIN event above. The |step| param identifies this step within the
-// async event. This should be called at the beginning of the next phase of an
-// asynchronous operation.
-#define TRACE_EVENT_FLOW_STEP0(category, name, id, step) \
- INTERNAL_TRACE_EVENT_ADD_WITH_ID(TRACE_EVENT_PHASE_FLOW_STEP, \
- category, name, id, TRACE_EVENT_FLAG_NONE, "step", step)
-#define TRACE_EVENT_FLOW_STEP1(category, name, id, step, \
- arg1_name, arg1_val) \
- INTERNAL_TRACE_EVENT_ADD_WITH_ID(TRACE_EVENT_PHASE_FLOW_STEP, \
- category, name, id, TRACE_EVENT_FLAG_NONE, "step", step, \
- arg1_name, arg1_val)
-#define TRACE_EVENT_COPY_FLOW_STEP0(category, name, id, step) \
- INTERNAL_TRACE_EVENT_ADD_WITH_ID(TRACE_EVENT_PHASE_FLOW_STEP, \
- category, name, id, TRACE_EVENT_FLAG_COPY, "step", step)
-#define TRACE_EVENT_COPY_FLOW_STEP1(category, name, id, step, \
- arg1_name, arg1_val) \
- INTERNAL_TRACE_EVENT_ADD_WITH_ID(TRACE_EVENT_PHASE_FLOW_STEP, \
- category, name, id, TRACE_EVENT_FLAG_COPY, "step", step, \
- arg1_name, arg1_val)
-
-// Records a single FLOW_END event for "name" immediately. If the category
-// is not enabled, then this does nothing.
-#define TRACE_EVENT_FLOW_END0(category, name, id) \
- INTERNAL_TRACE_EVENT_ADD_WITH_ID(TRACE_EVENT_PHASE_FLOW_END, \
- category, name, id, TRACE_EVENT_FLAG_NONE)
-#define TRACE_EVENT_FLOW_END1(category, name, id, arg1_name, arg1_val) \
- INTERNAL_TRACE_EVENT_ADD_WITH_ID(TRACE_EVENT_PHASE_FLOW_END, \
- category, name, id, TRACE_EVENT_FLAG_NONE, arg1_name, arg1_val)
-#define TRACE_EVENT_FLOW_END2(category, name, id, arg1_name, arg1_val, \
- arg2_name, arg2_val) \
- INTERNAL_TRACE_EVENT_ADD_WITH_ID(TRACE_EVENT_PHASE_FLOW_END, \
- category, name, id, TRACE_EVENT_FLAG_NONE, \
- arg1_name, arg1_val, arg2_name, arg2_val)
-#define TRACE_EVENT_COPY_FLOW_END0(category, name, id) \
- INTERNAL_TRACE_EVENT_ADD_WITH_ID(TRACE_EVENT_PHASE_FLOW_END, \
- category, name, id, TRACE_EVENT_FLAG_COPY)
-#define TRACE_EVENT_COPY_FLOW_END1(category, name, id, arg1_name, arg1_val) \
- INTERNAL_TRACE_EVENT_ADD_WITH_ID(TRACE_EVENT_PHASE_FLOW_END, \
- category, name, id, TRACE_EVENT_FLAG_COPY, \
- arg1_name, arg1_val)
-#define TRACE_EVENT_COPY_FLOW_END2(category, name, id, arg1_name, arg1_val, \
- arg2_name, arg2_val) \
- INTERNAL_TRACE_EVENT_ADD_WITH_ID(TRACE_EVENT_PHASE_FLOW_END, \
- category, name, id, TRACE_EVENT_FLAG_COPY, \
- arg1_name, arg1_val, arg2_name, arg2_val)
-
-// Macros to track the life time of arbitratry client objects.
-// See also TraceTrackableObject.
-#define TRACE_EVENT_OBJECT_CREATED_WITH_ID(category, name, id) \
- INTERNAL_TRACE_EVENT_ADD_WITH_ID(TRACE_EVENT_PHASE_CREATE_OBJECT, \
- category, name, id, TRACE_EVENT_FLAG_NONE)
-
-#define TRACE_EVENT_OBJECT_DELETED_WITH_ID(category, name, id) \
- INTERNAL_TRACE_EVENT_ADD_WITH_ID(TRACE_EVENT_PHASE_DELETE_OBJECT, \
- category, name, id, TRACE_EVENT_FLAG_NONE)
-
-// Implementation detail: trace event macros create temporary variables
-// to keep instrumentation overhead low. These macros give each temporary
-// variable a unique name based on the line number to prevent name collissions.
-#define INTERNAL_TRACE_EVENT_UID3(a,b) \
- trace_event_unique_##a##b
-#define INTERNAL_TRACE_EVENT_UID2(a,b) \
- INTERNAL_TRACE_EVENT_UID3(a,b)
-#define INTERNAL_TRACE_EVENT_UID(name_prefix) \
- INTERNAL_TRACE_EVENT_UID2(name_prefix, __LINE__)
-
-// Implementation detail: internal macro to create static category.
-// No barriers are needed, because this code is designed to operate safely
-// even when the unsigned char* points to garbage data (which may be the case
-// on processors without cache coherency).
-#define INTERNAL_TRACE_EVENT_GET_CATEGORY_INFO(category) \
- static TRACE_EVENT_API_ATOMIC_WORD INTERNAL_TRACE_EVENT_UID(atomic) = 0; \
- const unsigned char* INTERNAL_TRACE_EVENT_UID(catstatic) = \
- reinterpret_cast<const unsigned char*>(TRACE_EVENT_API_ATOMIC_LOAD( \
- INTERNAL_TRACE_EVENT_UID(atomic))); \
- if (!INTERNAL_TRACE_EVENT_UID(catstatic)) { \
- INTERNAL_TRACE_EVENT_UID(catstatic) = \
- TRACE_EVENT_API_GET_CATEGORY_ENABLED(category); \
- TRACE_EVENT_API_ATOMIC_STORE(INTERNAL_TRACE_EVENT_UID(atomic), \
- reinterpret_cast<TRACE_EVENT_API_ATOMIC_WORD>( \
- INTERNAL_TRACE_EVENT_UID(catstatic))); \
- }
-
-// Implementation detail: internal macro to create static category and add
-// event if the category is enabled.
-#define INTERNAL_TRACE_EVENT_ADD(phase, category, name, flags, ...) \
- do { \
- INTERNAL_TRACE_EVENT_GET_CATEGORY_INFO(category); \
- if (*INTERNAL_TRACE_EVENT_UID(catstatic)) { \
- trace_event_internal::AddTraceEvent( \
- phase, INTERNAL_TRACE_EVENT_UID(catstatic), name, \
- trace_event_internal::kNoEventId, flags, ##__VA_ARGS__); \
- } \
- } while (0)
-
-// Implementation detail: internal macro to create static category and add begin
-// event if the category is enabled. Also adds the end event when the scope
-// ends.
-#define INTERNAL_TRACE_EVENT_ADD_SCOPED(category, name, ...) \
- INTERNAL_TRACE_EVENT_GET_CATEGORY_INFO(category); \
- trace_event_internal::TraceEndOnScopeClose \
- INTERNAL_TRACE_EVENT_UID(profileScope); \
- if (*INTERNAL_TRACE_EVENT_UID(catstatic)) { \
- trace_event_internal::AddTraceEvent( \
- TRACE_EVENT_PHASE_BEGIN, \
- INTERNAL_TRACE_EVENT_UID(catstatic), \
- name, trace_event_internal::kNoEventId, \
- TRACE_EVENT_FLAG_NONE, ##__VA_ARGS__); \
- INTERNAL_TRACE_EVENT_UID(profileScope).Initialize( \
- INTERNAL_TRACE_EVENT_UID(catstatic), name); \
- }
-
-// Implementation detail: internal macro to create static category and add
-// event if the category is enabled.
-#define INTERNAL_TRACE_EVENT_ADD_WITH_ID(phase, category, name, id, flags, \
- ...) \
- do { \
- INTERNAL_TRACE_EVENT_GET_CATEGORY_INFO(category); \
- if (*INTERNAL_TRACE_EVENT_UID(catstatic)) { \
- unsigned char trace_event_flags = flags | TRACE_EVENT_FLAG_HAS_ID; \
- trace_event_internal::TraceID trace_event_trace_id( \
- id, &trace_event_flags); \
- trace_event_internal::AddTraceEvent( \
- phase, INTERNAL_TRACE_EVENT_UID(catstatic), \
- name, trace_event_trace_id.data(), trace_event_flags, \
- ##__VA_ARGS__); \
- } \
- } while (0)
-
-// Implementation detail: internal macro to create static category and add
-// event if the category is enabled.
-#define INTERNAL_TRACE_EVENT_ADD_WITH_ID_TID_AND_TIMESTAMP(phase, category, \
- name, id, thread_id, timestamp, flags, ...) \
- do { \
- INTERNAL_TRACE_EVENT_GET_CATEGORY_INFO(category); \
- if (*INTERNAL_TRACE_EVENT_UID(catstatic)) { \
- unsigned char trace_event_flags = flags | TRACE_EVENT_FLAG_HAS_ID; \
- trace_event_internal::TraceID trace_event_trace_id( \
- id, &trace_event_flags); \
- trace_event_internal::AddTraceEventWithThreadIdAndTimestamp( \
- phase, INTERNAL_TRACE_EVENT_UID(catstatic), \
- name, trace_event_trace_id.data(), \
- thread_id, base::TimeTicks::FromInternalValue(timestamp), \
- trace_event_flags, ##__VA_ARGS__); \
- } \
- } while (0)
-
-// Notes regarding the following definitions:
-// New values can be added and propagated to third party libraries, but existing
-// definitions must never be changed, because third party libraries may use old
-// definitions.
-
-// Phase indicates the nature of an event entry. E.g. part of a begin/end pair.
-#define TRACE_EVENT_PHASE_BEGIN ('B')
-#define TRACE_EVENT_PHASE_END ('E')
-#define TRACE_EVENT_PHASE_INSTANT ('I')
-#define TRACE_EVENT_PHASE_ASYNC_BEGIN ('S')
-#define TRACE_EVENT_PHASE_ASYNC_STEP ('T')
-#define TRACE_EVENT_PHASE_ASYNC_END ('F')
-#define TRACE_EVENT_PHASE_FLOW_BEGIN ('s')
-#define TRACE_EVENT_PHASE_FLOW_STEP ('t')
-#define TRACE_EVENT_PHASE_FLOW_END ('f')
-#define TRACE_EVENT_PHASE_METADATA ('M')
-#define TRACE_EVENT_PHASE_COUNTER ('C')
-#define TRACE_EVENT_PHASE_SAMPLE ('P')
-#define TRACE_EVENT_PHASE_CREATE_OBJECT ('N')
-#define TRACE_EVENT_PHASE_DELETE_OBJECT ('D')
-
-// Flags for changing the behavior of TRACE_EVENT_API_ADD_TRACE_EVENT.
-#define TRACE_EVENT_FLAG_NONE (static_cast<unsigned char>(0))
-#define TRACE_EVENT_FLAG_COPY (static_cast<unsigned char>(1 << 0))
-#define TRACE_EVENT_FLAG_HAS_ID (static_cast<unsigned char>(1 << 1))
-#define TRACE_EVENT_FLAG_MANGLE_ID (static_cast<unsigned char>(1 << 2))
-
-// Type values for identifying types in the TraceValue union.
-#define TRACE_VALUE_TYPE_BOOL (static_cast<unsigned char>(1))
-#define TRACE_VALUE_TYPE_UINT (static_cast<unsigned char>(2))
-#define TRACE_VALUE_TYPE_INT (static_cast<unsigned char>(3))
-#define TRACE_VALUE_TYPE_DOUBLE (static_cast<unsigned char>(4))
-#define TRACE_VALUE_TYPE_POINTER (static_cast<unsigned char>(5))
-#define TRACE_VALUE_TYPE_STRING (static_cast<unsigned char>(6))
-#define TRACE_VALUE_TYPE_COPY_STRING (static_cast<unsigned char>(7))
-
-namespace trace_event_internal {
-
-// Specify these values when the corresponding argument of AddTraceEvent is not
-// used.
-const int kZeroNumArgs = 0;
-const unsigned long long kNoEventId = 0;
-
-// TraceID encapsulates an ID that can either be an integer or pointer. Pointers
-// are mangled with the Process ID so that they are unlikely to collide when the
-// same pointer is used on different processes.
-class TraceID {
- public:
- class ForceMangle {
- public:
- explicit ForceMangle(unsigned long long id) : data_(id) {}
- explicit ForceMangle(unsigned long id) : data_(id) {}
- explicit ForceMangle(unsigned int id) : data_(id) {}
- explicit ForceMangle(unsigned short id) : data_(id) {}
- explicit ForceMangle(unsigned char id) : data_(id) {}
- explicit ForceMangle(long long id)
- : data_(static_cast<unsigned long long>(id)) {}
- explicit ForceMangle(long id)
- : data_(static_cast<unsigned long long>(id)) {}
- explicit ForceMangle(int id)
- : data_(static_cast<unsigned long long>(id)) {}
- explicit ForceMangle(short id)
- : data_(static_cast<unsigned long long>(id)) {}
- explicit ForceMangle(signed char id)
- : data_(static_cast<unsigned long long>(id)) {}
-
- unsigned long long data() const { return data_; }
-
- private:
- unsigned long long data_;
- };
-
- TraceID(const void* id, unsigned char* flags)
- : data_(static_cast<unsigned long long>(
- reinterpret_cast<unsigned long>(id))) {
- *flags |= TRACE_EVENT_FLAG_MANGLE_ID;
- }
- TraceID(ForceMangle id, unsigned char* flags) : data_(id.data()) {
- *flags |= TRACE_EVENT_FLAG_MANGLE_ID;
- }
- TraceID(unsigned long long id, unsigned char* flags)
- : data_(id) { (void)flags; }
- TraceID(unsigned long id, unsigned char* flags)
- : data_(id) { (void)flags; }
- TraceID(unsigned int id, unsigned char* flags)
- : data_(id) { (void)flags; }
- TraceID(unsigned short id, unsigned char* flags)
- : data_(id) { (void)flags; }
- TraceID(unsigned char id, unsigned char* flags)
- : data_(id) { (void)flags; }
- TraceID(long long id, unsigned char* flags)
- : data_(static_cast<unsigned long long>(id)) { (void)flags; }
- TraceID(long id, unsigned char* flags)
- : data_(static_cast<unsigned long long>(id)) { (void)flags; }
- TraceID(int id, unsigned char* flags)
- : data_(static_cast<unsigned long long>(id)) { (void)flags; }
- TraceID(short id, unsigned char* flags)
- : data_(static_cast<unsigned long long>(id)) { (void)flags; }
- TraceID(signed char id, unsigned char* flags)
- : data_(static_cast<unsigned long long>(id)) { (void)flags; }
-
- unsigned long long data() const { return data_; }
-
- private:
- unsigned long long data_;
-};
-
-// Simple union to store various types as unsigned long long.
-union TraceValueUnion {
- bool as_bool;
- unsigned long long as_uint;
- long long as_int;
- double as_double;
- const void* as_pointer;
- const char* as_string;
-};
-
-// Simple container for const char* that should be copied instead of retained.
-class TraceStringWithCopy {
- public:
- explicit TraceStringWithCopy(const char* str) : str_(str) {}
- operator const char* () const { return str_; }
- private:
- const char* str_;
-};
-
-// Define SetTraceValue for each allowed type. It stores the type and
-// value in the return arguments. This allows this API to avoid declaring any
-// structures so that it is portable to third_party libraries.
-#define INTERNAL_DECLARE_SET_TRACE_VALUE(actual_type, \
- union_member, \
- value_type_id) \
- static inline void SetTraceValue(actual_type arg, \
- unsigned char* type, \
- unsigned long long* value) { \
- TraceValueUnion type_value; \
- type_value.union_member = arg; \
- *type = value_type_id; \
- *value = type_value.as_uint; \
- }
-// Simpler form for int types that can be safely casted.
-#define INTERNAL_DECLARE_SET_TRACE_VALUE_INT(actual_type, \
- value_type_id) \
- static inline void SetTraceValue(actual_type arg, \
- unsigned char* type, \
- unsigned long long* value) { \
- *type = value_type_id; \
- *value = static_cast<unsigned long long>(arg); \
- }
-
-INTERNAL_DECLARE_SET_TRACE_VALUE_INT(unsigned long long, TRACE_VALUE_TYPE_UINT)
-INTERNAL_DECLARE_SET_TRACE_VALUE_INT(unsigned long, TRACE_VALUE_TYPE_UINT)
-INTERNAL_DECLARE_SET_TRACE_VALUE_INT(unsigned int, TRACE_VALUE_TYPE_UINT)
-INTERNAL_DECLARE_SET_TRACE_VALUE_INT(unsigned short, TRACE_VALUE_TYPE_UINT)
-INTERNAL_DECLARE_SET_TRACE_VALUE_INT(unsigned char, TRACE_VALUE_TYPE_UINT)
-INTERNAL_DECLARE_SET_TRACE_VALUE_INT(long long, TRACE_VALUE_TYPE_INT)
-INTERNAL_DECLARE_SET_TRACE_VALUE_INT(long, TRACE_VALUE_TYPE_INT)
-INTERNAL_DECLARE_SET_TRACE_VALUE_INT(int, TRACE_VALUE_TYPE_INT)
-INTERNAL_DECLARE_SET_TRACE_VALUE_INT(short, TRACE_VALUE_TYPE_INT)
-INTERNAL_DECLARE_SET_TRACE_VALUE_INT(signed char, TRACE_VALUE_TYPE_INT)
-INTERNAL_DECLARE_SET_TRACE_VALUE(bool, as_bool, TRACE_VALUE_TYPE_BOOL)
-INTERNAL_DECLARE_SET_TRACE_VALUE(double, as_double, TRACE_VALUE_TYPE_DOUBLE)
-INTERNAL_DECLARE_SET_TRACE_VALUE(const void*, as_pointer,
- TRACE_VALUE_TYPE_POINTER)
-INTERNAL_DECLARE_SET_TRACE_VALUE(const char*, as_string,
- TRACE_VALUE_TYPE_STRING)
-INTERNAL_DECLARE_SET_TRACE_VALUE(const TraceStringWithCopy&, as_string,
- TRACE_VALUE_TYPE_COPY_STRING)
-
-#undef INTERNAL_DECLARE_SET_TRACE_VALUE
-#undef INTERNAL_DECLARE_SET_TRACE_VALUE_INT
-
-// std::string version of SetTraceValue so that trace arguments can be strings.
-static inline void SetTraceValue(const std::string& arg,
- unsigned char* type,
- unsigned long long* value) {
- TraceValueUnion type_value;
- type_value.as_string = arg.c_str();
- *type = TRACE_VALUE_TYPE_COPY_STRING;
- *value = type_value.as_uint;
-}
-
-// These AddTraceEvent and AddTraceEventWithThreadIdAndTimestamp template
-// functions are defined here instead of in the macro, because the arg_values
-// could be temporary objects, such as std::string. In order to store
-// pointers to the internal c_str and pass through to the tracing API,
-// the arg_values must live throughout these procedures.
-
-static inline void AddTraceEventWithThreadIdAndTimestamp(char phase,
- const unsigned char* category_enabled,
- const char* name,
- unsigned long long id,
- int thread_id,
- const base::TimeTicks& timestamp,
- unsigned char flags) {
- TRACE_EVENT_API_ADD_TRACE_EVENT_WITH_THREAD_ID_AND_TIMESTAMP(
- phase, category_enabled, name, id, thread_id, timestamp,
- kZeroNumArgs, NULL, NULL, NULL, flags);
-}
-
-static inline void AddTraceEvent(char phase,
- const unsigned char* category_enabled,
- const char* name,
- unsigned long long id,
- unsigned char flags) {
- int thread_id = static_cast<int>(base::PlatformThread::CurrentId());
- base::TimeTicks now = base::TimeTicks::NowFromSystemTraceTime();
- AddTraceEventWithThreadIdAndTimestamp(phase, category_enabled, name, id,
- thread_id, now, flags);
-}
-
-template<class ARG1_TYPE>
-static inline void AddTraceEventWithThreadIdAndTimestamp(char phase,
- const unsigned char* category_enabled,
- const char* name,
- unsigned long long id,
- int thread_id,
- const base::TimeTicks& timestamp,
- unsigned char flags,
- const char* arg1_name,
- const ARG1_TYPE& arg1_val) {
- const int num_args = 1;
- unsigned char arg_types[1];
- unsigned long long arg_values[1];
- SetTraceValue(arg1_val, &arg_types[0], &arg_values[0]);
- TRACE_EVENT_API_ADD_TRACE_EVENT_WITH_THREAD_ID_AND_TIMESTAMP(
- phase, category_enabled, name, id, thread_id, timestamp,
- num_args, &arg1_name, arg_types, arg_values, flags);
-}
-
-template<class ARG1_TYPE>
-static inline void AddTraceEvent(char phase,
- const unsigned char* category_enabled,
- const char* name,
- unsigned long long id,
- unsigned char flags,
- const char* arg1_name,
- const ARG1_TYPE& arg1_val) {
- int thread_id = static_cast<int>(base::PlatformThread::CurrentId());
- base::TimeTicks now = base::TimeTicks::NowFromSystemTraceTime();
- AddTraceEventWithThreadIdAndTimestamp(phase, category_enabled, name, id,
- thread_id, now, flags, arg1_name,
- arg1_val);
-}
-
-template<class ARG1_TYPE, class ARG2_TYPE>
-static inline void AddTraceEventWithThreadIdAndTimestamp(char phase,
- const unsigned char* category_enabled,
- const char* name,
- unsigned long long id,
- int thread_id,
- const base::TimeTicks& timestamp,
- unsigned char flags,
- const char* arg1_name,
- const ARG1_TYPE& arg1_val,
- const char* arg2_name,
- const ARG2_TYPE& arg2_val) {
- const int num_args = 2;
- const char* arg_names[2] = { arg1_name, arg2_name };
- unsigned char arg_types[2];
- unsigned long long arg_values[2];
- SetTraceValue(arg1_val, &arg_types[0], &arg_values[0]);
- SetTraceValue(arg2_val, &arg_types[1], &arg_values[1]);
- TRACE_EVENT_API_ADD_TRACE_EVENT_WITH_THREAD_ID_AND_TIMESTAMP(
- phase, category_enabled, name, id, thread_id, timestamp,
- num_args, arg_names, arg_types, arg_values, flags);
-}
-
-template<class ARG1_TYPE, class ARG2_TYPE>
-static inline void AddTraceEvent(char phase,
- const unsigned char* category_enabled,
- const char* name,
- unsigned long long id,
- unsigned char flags,
- const char* arg1_name,
- const ARG1_TYPE& arg1_val,
- const char* arg2_name,
- const ARG2_TYPE& arg2_val) {
- int thread_id = static_cast<int>(base::PlatformThread::CurrentId());
- base::TimeTicks now = base::TimeTicks::NowFromSystemTraceTime();
- AddTraceEventWithThreadIdAndTimestamp(phase, category_enabled, name, id,
- thread_id, now, flags, arg1_name,
- arg1_val, arg2_name, arg2_val);
-}
-
-// Used by TRACE_EVENTx macro. Do not use directly.
-class TRACE_EVENT_API_CLASS_EXPORT TraceEndOnScopeClose {
- public:
- // Note: members of data_ intentionally left uninitialized. See Initialize.
- TraceEndOnScopeClose() : p_data_(NULL) {}
- ~TraceEndOnScopeClose() {
- if (p_data_)
- AddEventIfEnabled();
- }
-
- void Initialize(const unsigned char* category_enabled,
- const char* name) {
- data_.category_enabled = category_enabled;
- data_.name = name;
- p_data_ = &data_;
- }
-
- private:
- // Add the end event if the category is still enabled.
- void AddEventIfEnabled() {
- // Only called when p_data_ is non-null.
- if (*p_data_->category_enabled) {
- TRACE_EVENT_API_ADD_TRACE_EVENT(
- TRACE_EVENT_PHASE_END,
- p_data_->category_enabled,
- p_data_->name, kNoEventId,
- kZeroNumArgs, NULL, NULL, NULL,
- TRACE_EVENT_FLAG_NONE);
- }
- }
-
- // This Data struct workaround is to avoid initializing all the members
- // in Data during construction of this object, since this object is always
- // constructed, even when tracing is disabled. If the members of Data were
- // members of this class instead, compiler warnings occur about potential
- // uninitialized accesses.
- struct Data {
- const unsigned char* category_enabled;
- const char* name;
- };
- Data* p_data_;
- Data data_;
-};
-
-// Used by TRACE_EVENT_BINARY_EFFICIENTx macro. Do not use directly.
-class TRACE_EVENT_API_CLASS_EXPORT ScopedTrace {
- public:
- ScopedTrace(TRACE_EVENT_API_ATOMIC_WORD* event_uid, const char* name);
- ~ScopedTrace();
-
- private:
- const unsigned char* category_enabled_;
- const char* name_;
-};
-
-// A support macro for TRACE_EVENT_BINARY_EFFICIENTx
-#define INTERNAL_TRACE_EVENT_BINARY_EFFICIENT_ADD_SCOPED( \
- category, name, ...) \
- static TRACE_EVENT_API_ATOMIC_WORD INTERNAL_TRACE_EVENT_UID(atomic) = 0; \
- trace_event_internal::ScopedTrace \
- INTERNAL_TRACE_EVENT_UID(profileScope)( \
- &INTERNAL_TRACE_EVENT_UID(atomic), name); \
-
-// This macro generates less code then TRACE_EVENT0 but is also
-// slower to execute when tracing is off. It should generally only be
-// used with code that is seldom executed or conditionally executed
-// when debugging.
-#define TRACE_EVENT_BINARY_EFFICIENT0(category, name) \
- INTERNAL_TRACE_EVENT_BINARY_EFFICIENT_ADD_SCOPED(category, name)
-
-} // namespace trace_event_internal
-
-#endif // BASE_DEBUG_TRACE_EVENT_INTERNAL_H_
diff --git a/base/debug/trace_event_unittest.cc b/base/debug/trace_event_unittest.cc
index 5fb9040..805c4dc 100644
--- a/base/debug/trace_event_unittest.cc
+++ b/base/debug/trace_event_unittest.cc
@@ -41,9 +41,11 @@
CompareOp op;
};
-static int kThreadId = 42;
-static int kAsyncId = 5;
-static const char kAsyncIdStr[] = "5";
+const int kThreadId = 42;
+const int kAsyncId = 5;
+const char kAsyncIdStr[] = "0x5";
+const int kAsyncId2 = 6;
+const char kAsyncId2Str[] = "0x6";
class TraceEventTestFixture : public testing::Test {
public:
@@ -55,6 +57,7 @@
void OnTraceNotification(int notification) {
if (notification & TraceLog::EVENT_WATCH_NOTIFICATION)
++event_watch_notification_;
+ notifications_received_ |= notification;
}
DictionaryValue* FindMatchingTraceEntry(const JsonKeyValue* key_values);
DictionaryValue* FindNamePhase(const char* name, const char* phase);
@@ -73,7 +76,8 @@
void BeginTrace() {
event_watch_notification_ = 0;
- TraceLog::GetInstance()->SetEnabled(std::string("*"),
+ notifications_received_ = 0;
+ TraceLog::GetInstance()->SetEnabled(CategoryFilter("*"),
TraceLog::RECORD_UNTIL_FULL);
}
@@ -88,6 +92,7 @@
virtual void SetUp() OVERRIDE {
const char* name = PlatformThread::GetName();
old_thread_name_ = name ? strdup(name) : NULL;
+ notifications_received_ = 0;
}
virtual void TearDown() OVERRIDE {
if (TraceLog::GetInstance())
@@ -102,6 +107,7 @@
base::debug::TraceResultBuffer trace_buffer_;
base::debug::TraceResultBuffer::SimpleOutput json_output_;
int event_watch_notification_;
+ int notifications_received_;
private:
// We want our singleton torn down after each test.
@@ -326,9 +332,12 @@
"name1", "\"value1\"",
"name2", "value\\2");
- TRACE_EVENT_INSTANT0("all", "TRACE_EVENT_INSTANT0 call");
- TRACE_EVENT_INSTANT1("all", "TRACE_EVENT_INSTANT1 call", "name1", "value1");
+ TRACE_EVENT_INSTANT0("all", "TRACE_EVENT_INSTANT0 call",
+ TRACE_EVENT_SCOPE_GLOBAL);
+ TRACE_EVENT_INSTANT1("all", "TRACE_EVENT_INSTANT1 call",
+ TRACE_EVENT_SCOPE_PROCESS, "name1", "value1");
TRACE_EVENT_INSTANT2("all", "TRACE_EVENT_INSTANT2 call",
+ TRACE_EVENT_SCOPE_THREAD,
"name1", "value1",
"name2", "value2");
@@ -388,16 +397,19 @@
TRACE_EVENT_BEGIN_WITH_ID_TID_AND_TIMESTAMP0("all",
"TRACE_EVENT_BEGIN_WITH_ID_TID_AND_TIMESTAMP0 call",
- kAsyncId + 1, kThreadId, 34567);
+ kAsyncId2, kThreadId, 34567);
TRACE_EVENT_END_WITH_ID_TID_AND_TIMESTAMP0("all",
"TRACE_EVENT_END_WITH_ID_TID_AND_TIMESTAMP0 call",
- kAsyncId + 1, kThreadId, 45678);
+ kAsyncId2, kThreadId, 45678);
TRACE_EVENT_OBJECT_CREATED_WITH_ID("all", "tracked object 1", 0x42);
+ TRACE_EVENT_OBJECT_SNAPSHOT_WITH_ID(
+ "all", "tracked object 1", 0x42, "hello");
TRACE_EVENT_OBJECT_DELETED_WITH_ID("all", "tracked object 1", 0x42);
TraceScopedTrackableObject<int> trackable("all", "tracked object 2",
0x2128506);
+ trackable.snapshot("world");
} // Scope close causes TRACE_EVENT0 etc to send their END events.
if (task_complete_event)
@@ -420,7 +432,7 @@
{
std::string str_val;
EXPECT_TRUE(item && item->GetString("args.id", &str_val));
- EXPECT_STREQ("1122", str_val.c_str());
+ EXPECT_STREQ("0x1122", str_val.c_str());
}
EXPECT_SUB_FIND_("extrastring1");
EXPECT_FIND_("TRACE_EVENT_END_ETW call");
@@ -447,10 +459,25 @@
EXPECT_SUB_FIND_("value\\2");
EXPECT_FIND_("TRACE_EVENT_INSTANT0 call");
+ {
+ std::string scope;
+ EXPECT_TRUE((item && item->GetString("s", &scope)));
+ EXPECT_EQ("g", scope);
+ }
EXPECT_FIND_("TRACE_EVENT_INSTANT1 call");
+ {
+ std::string scope;
+ EXPECT_TRUE((item && item->GetString("s", &scope)));
+ EXPECT_EQ("p", scope);
+ }
EXPECT_SUB_FIND_("name1");
EXPECT_SUB_FIND_("value1");
EXPECT_FIND_("TRACE_EVENT_INSTANT2 call");
+ {
+ std::string scope;
+ EXPECT_TRUE((item && item->GetString("s", &scope)));
+ EXPECT_EQ("t", scope);
+ }
EXPECT_SUB_FIND_("name1");
EXPECT_SUB_FIND_("value1");
EXPECT_SUB_FIND_("name2");
@@ -579,7 +606,7 @@
{
std::string id;
EXPECT_TRUE((item && item->GetString("id", &id)));
- EXPECT_EQ("319009", id);
+ EXPECT_EQ("0x319009", id);
std::string ph;
EXPECT_TRUE((item && item->GetString("ph", &ph)));
@@ -594,7 +621,7 @@
{
std::string id;
EXPECT_TRUE((item && item->GetString("id", &id)));
- EXPECT_EQ("319009", id);
+ EXPECT_EQ("0x319009", id);
std::string ph;
EXPECT_TRUE((item && item->GetString("ph", &ph)));
@@ -617,7 +644,7 @@
EXPECT_EQ(kThreadId, val);
std::string id;
EXPECT_TRUE((item && item->GetString("id", &id)));
- EXPECT_EQ(kAsyncId, atoi(id.c_str()));
+ EXPECT_EQ(kAsyncIdStr, id);
}
EXPECT_FIND_("TRACE_EVENT_COPY_END_WITH_ID_TID_AND_TIMESTAMP0 call");
@@ -629,7 +656,7 @@
EXPECT_EQ(kThreadId, val);
std::string id;
EXPECT_TRUE((item && item->GetString("id", &id)));
- EXPECT_EQ(kAsyncId, atoi(id.c_str()));
+ EXPECT_EQ(kAsyncIdStr, id);
}
EXPECT_FIND_("TRACE_EVENT_BEGIN_WITH_ID_TID_AND_TIMESTAMP0 call");
@@ -641,7 +668,7 @@
EXPECT_EQ(kThreadId, val);
std::string id;
EXPECT_TRUE((item && item->GetString("id", &id)));
- EXPECT_EQ(kAsyncId + 1, atoi(id.c_str()));
+ EXPECT_EQ(kAsyncId2Str, id);
}
EXPECT_FIND_("TRACE_EVENT_END_WITH_ID_TID_AND_TIMESTAMP0 call");
@@ -653,41 +680,63 @@
EXPECT_EQ(kThreadId, val);
std::string id;
EXPECT_TRUE((item && item->GetString("id", &id)));
- EXPECT_EQ(kAsyncId + 1, atoi(id.c_str()));
+ EXPECT_EQ(kAsyncId2Str, id);
}
EXPECT_FIND_("tracked object 1");
{
std::string phase;
std::string id;
+ std::string snapshot;
EXPECT_TRUE((item && item->GetString("ph", &phase)));
EXPECT_EQ("N", phase);
EXPECT_TRUE((item && item->GetString("id", &id)));
- EXPECT_EQ("42", id);
- EXPECT_TRUE((item = FindTraceEntry(trace_parsed, "tracked object 1",
- item)));
- EXPECT_TRUE((item && item->GetString("ph", &phase)));
+ EXPECT_EQ("0x42", id);
+
+ item = FindTraceEntry(trace_parsed, "tracked object 1", item);
+ EXPECT_TRUE(item);
+ EXPECT_TRUE(item && item->GetString("ph", &phase));
+ EXPECT_EQ("O", phase);
+ EXPECT_TRUE(item && item->GetString("id", &id));
+ EXPECT_EQ("0x42", id);
+ EXPECT_TRUE(item && item->GetString("args.snapshot", &snapshot));
+ EXPECT_EQ("hello", snapshot);
+
+ item = FindTraceEntry(trace_parsed, "tracked object 1", item);
+ EXPECT_TRUE(item);
+ EXPECT_TRUE(item && item->GetString("ph", &phase));
EXPECT_EQ("D", phase);
- EXPECT_TRUE((item && item->GetString("id", &id)));
- EXPECT_EQ("42", id);
+ EXPECT_TRUE(item && item->GetString("id", &id));
+ EXPECT_EQ("0x42", id);
}
EXPECT_FIND_("tracked object 2");
{
std::string phase;
std::string id;
+ std::string snapshot;
- EXPECT_TRUE((item && item->GetString("ph", &phase)));
+ EXPECT_TRUE(item && item->GetString("ph", &phase));
EXPECT_EQ("N", phase);
- EXPECT_TRUE((item && item->GetString("id", &id)));
- EXPECT_EQ("2128506", id);
- EXPECT_TRUE((item = FindTraceEntry(trace_parsed, "tracked object 2",
- item)));
- EXPECT_TRUE((item && item->GetString("ph", &phase)));
+ EXPECT_TRUE(item && item->GetString("id", &id));
+ EXPECT_EQ("0x2128506", id);
+
+ item = FindTraceEntry(trace_parsed, "tracked object 2", item);
+ EXPECT_TRUE(item);
+ EXPECT_TRUE(item && item->GetString("ph", &phase));
+ EXPECT_EQ("O", phase);
+ EXPECT_TRUE(item && item->GetString("id", &id));
+ EXPECT_EQ("0x2128506", id);
+ EXPECT_TRUE(item && item->GetString("args.snapshot", &snapshot));
+ EXPECT_EQ("world", snapshot);
+
+ item = FindTraceEntry(trace_parsed, "tracked object 2", item);
+ EXPECT_TRUE(item);
+ EXPECT_TRUE(item && item->GetString("ph", &phase));
EXPECT_EQ("D", phase);
- EXPECT_TRUE((item && item->GetString("id", &id)));
- EXPECT_EQ("2128506", id);
+ EXPECT_TRUE(item && item->GetString("id", &id));
+ EXPECT_EQ("0x2128506", id);
}
}
@@ -695,6 +744,7 @@
WaitableEvent* task_complete_event) {
for (int i = 0; i < num_events; i++) {
TRACE_EVENT_INSTANT2("all", "multi thread event",
+ TRACE_EVENT_SCOPE_THREAD,
"thread", thread_id,
"event", i);
}
@@ -737,7 +787,7 @@
void TraceCallsWithCachedCategoryPointersPointers(const char* name_str) {
TRACE_EVENT0("category name1", name_str);
- TRACE_EVENT_INSTANT0("category name2", name_str);
+ TRACE_EVENT_INSTANT0("category name2", name_str, TRACE_EVENT_SCOPE_THREAD);
TRACE_EVENT_BEGIN0("category name3", name_str);
TRACE_EVENT_END0("category name4", name_str);
}
@@ -754,7 +804,8 @@
// Simple Test for emitting data and validating it was received.
TEST_F(TraceEventTestFixture, DataCaptured) {
ManualTestSetUp();
- TraceLog::GetInstance()->SetEnabled(true, TraceLog::RECORD_UNTIL_FULL);
+ TraceLog::GetInstance()->SetEnabled(CategoryFilter("*"),
+ TraceLog::RECORD_UNTIL_FULL);
TraceWithAllMacroVariants(NULL);
@@ -778,18 +829,20 @@
EXPECT_CALL(observer, OnTraceLogWillEnable())
.Times(1);
- TraceLog::GetInstance()->SetEnabled(true, TraceLog::RECORD_UNTIL_FULL);
+ TraceLog::GetInstance()->SetEnabled(CategoryFilter("*"),
+ TraceLog::RECORD_UNTIL_FULL);
testing::Mock::VerifyAndClear(&observer);
// Cleanup.
TraceLog::GetInstance()->RemoveEnabledStateObserver(&observer);
- TraceLog::GetInstance()->SetEnabled(false, TraceLog::RECORD_UNTIL_FULL);
+ TraceLog::GetInstance()->SetDisabled();
}
TEST_F(TraceEventTestFixture, EnabledObserverDoesntFireOnSecondEnable) {
ManualTestSetUp();
- TraceLog::GetInstance()->SetEnabled(true, TraceLog::RECORD_UNTIL_FULL);
+ TraceLog::GetInstance()->SetEnabled(CategoryFilter("*"),
+ TraceLog::RECORD_UNTIL_FULL);
testing::StrictMock<MockEnabledStateChangedObserver> observer;
TraceLog::GetInstance()->AddEnabledStateObserver(&observer);
@@ -798,20 +851,22 @@
.Times(0);
EXPECT_CALL(observer, OnTraceLogWillDisable())
.Times(0);
- TraceLog::GetInstance()->SetEnabled(true, TraceLog::RECORD_UNTIL_FULL);
+ TraceLog::GetInstance()->SetEnabled(CategoryFilter("*"),
+ TraceLog::RECORD_UNTIL_FULL);
testing::Mock::VerifyAndClear(&observer);
// Cleanup.
TraceLog::GetInstance()->RemoveEnabledStateObserver(&observer);
- TraceLog::GetInstance()->SetEnabled(false, TraceLog::RECORD_UNTIL_FULL);
- TraceLog::GetInstance()->SetEnabled(false, TraceLog::RECORD_UNTIL_FULL);
+ TraceLog::GetInstance()->SetDisabled();
+ TraceLog::GetInstance()->SetDisabled();
}
TEST_F(TraceEventTestFixture, EnabledObserverDoesntFireOnNestedDisable) {
ManualTestSetUp();
- TraceLog::GetInstance()->SetEnabled(true, TraceLog::RECORD_UNTIL_FULL);
- TraceLog::GetInstance()->SetEnabled(true, TraceLog::RECORD_UNTIL_FULL);
+ CategoryFilter cf_inc_all("*");
+ TraceLog::GetInstance()->SetEnabled(cf_inc_all, TraceLog::RECORD_UNTIL_FULL);
+ TraceLog::GetInstance()->SetEnabled(cf_inc_all, TraceLog::RECORD_UNTIL_FULL);
testing::StrictMock<MockEnabledStateChangedObserver> observer;
TraceLog::GetInstance()->AddEnabledStateObserver(&observer);
@@ -820,25 +875,26 @@
.Times(0);
EXPECT_CALL(observer, OnTraceLogWillDisable())
.Times(0);
- TraceLog::GetInstance()->SetEnabled(false, TraceLog::RECORD_UNTIL_FULL);
+ TraceLog::GetInstance()->SetDisabled();
testing::Mock::VerifyAndClear(&observer);
// Cleanup.
TraceLog::GetInstance()->RemoveEnabledStateObserver(&observer);
- TraceLog::GetInstance()->SetEnabled(false, TraceLog::RECORD_UNTIL_FULL);
+ TraceLog::GetInstance()->SetDisabled();
}
TEST_F(TraceEventTestFixture, EnabledObserverFiresOnDisable) {
ManualTestSetUp();
- TraceLog::GetInstance()->SetEnabled(true, TraceLog::RECORD_UNTIL_FULL);
+ TraceLog::GetInstance()->SetEnabled(CategoryFilter("*"),
+ TraceLog::RECORD_UNTIL_FULL);
MockEnabledStateChangedObserver observer;
TraceLog::GetInstance()->AddEnabledStateObserver(&observer);
EXPECT_CALL(observer, OnTraceLogWillDisable())
.Times(1);
- TraceLog::GetInstance()->SetEnabled(false, TraceLog::RECORD_UNTIL_FULL);
+ TraceLog::GetInstance()->SetDisabled();
testing::Mock::VerifyAndClear(&observer);
// Cleanup.
@@ -851,18 +907,33 @@
// Test that categories that are used can be retrieved whether trace was
// enabled or disabled when the trace event was encountered.
- TRACE_EVENT_INSTANT0("c1", "name");
- TRACE_EVENT_INSTANT0("c2", "name");
+ TRACE_EVENT_INSTANT0("c1", "name", TRACE_EVENT_SCOPE_THREAD);
+ TRACE_EVENT_INSTANT0("c2", "name", TRACE_EVENT_SCOPE_THREAD);
BeginTrace();
- TRACE_EVENT_INSTANT0("c3", "name");
- TRACE_EVENT_INSTANT0("c4", "name");
+ TRACE_EVENT_INSTANT0("c3", "name", TRACE_EVENT_SCOPE_THREAD);
+ TRACE_EVENT_INSTANT0("c4", "name", TRACE_EVENT_SCOPE_THREAD);
+ // Category groups containing more than one category.
+ TRACE_EVENT_INSTANT0("c5,c6", "name", TRACE_EVENT_SCOPE_THREAD);
+ TRACE_EVENT_INSTANT0("c7,c8", "name", TRACE_EVENT_SCOPE_THREAD);
+
EndTraceAndFlush();
- std::vector<std::string> cats;
- TraceLog::GetInstance()->GetKnownCategories(&cats);
- EXPECT_TRUE(std::find(cats.begin(), cats.end(), "c1") != cats.end());
- EXPECT_TRUE(std::find(cats.begin(), cats.end(), "c2") != cats.end());
- EXPECT_TRUE(std::find(cats.begin(), cats.end(), "c3") != cats.end());
- EXPECT_TRUE(std::find(cats.begin(), cats.end(), "c4") != cats.end());
+ std::vector<std::string> cat_groups;
+ TraceLog::GetInstance()->GetKnownCategoryGroups(&cat_groups);
+ EXPECT_TRUE(std::find(cat_groups.begin(),
+ cat_groups.end(), "c1") != cat_groups.end());
+ EXPECT_TRUE(std::find(cat_groups.begin(),
+ cat_groups.end(), "c2") != cat_groups.end());
+ EXPECT_TRUE(std::find(cat_groups.begin(),
+ cat_groups.end(), "c3") != cat_groups.end());
+ EXPECT_TRUE(std::find(cat_groups.begin(),
+ cat_groups.end(), "c4") != cat_groups.end());
+ EXPECT_TRUE(std::find(cat_groups.begin(),
+ cat_groups.end(), "c5,c6") != cat_groups.end());
+ EXPECT_TRUE(std::find(cat_groups.begin(),
+ cat_groups.end(), "c7,c8") != cat_groups.end());
+ // Make sure metadata isn't returned.
+ EXPECT_TRUE(std::find(cat_groups.begin(),
+ cat_groups.end(), "__metadata") == cat_groups.end());
const std::vector<std::string> empty_categories;
std::vector<std::string> included_categories;
@@ -873,22 +944,20 @@
// Include nonexistent category -> no events
Clear();
included_categories.clear();
- included_categories.push_back("not_found823564786");
- TraceLog::GetInstance()->SetEnabled(included_categories, empty_categories,
+ TraceLog::GetInstance()->SetEnabled(CategoryFilter("not_found823564786"),
TraceLog::RECORD_UNTIL_FULL);
- TRACE_EVENT_INSTANT0("cat1", "name");
- TRACE_EVENT_INSTANT0("cat2", "name");
+ TRACE_EVENT_INSTANT0("cat1", "name", TRACE_EVENT_SCOPE_THREAD);
+ TRACE_EVENT_INSTANT0("cat2", "name", TRACE_EVENT_SCOPE_THREAD);
EndTraceAndFlush();
EXPECT_TRUE(trace_parsed_.empty());
// Include existent category -> only events of that category
Clear();
included_categories.clear();
- included_categories.push_back("inc");
- TraceLog::GetInstance()->SetEnabled(included_categories, empty_categories,
+ TraceLog::GetInstance()->SetEnabled(CategoryFilter("inc"),
TraceLog::RECORD_UNTIL_FULL);
- TRACE_EVENT_INSTANT0("inc", "name");
- TRACE_EVENT_INSTANT0("inc2", "name");
+ TRACE_EVENT_INSTANT0("inc", "name", TRACE_EVENT_SCOPE_THREAD);
+ TRACE_EVENT_INSTANT0("inc2", "name", TRACE_EVENT_SCOPE_THREAD);
EndTraceAndFlush();
EXPECT_TRUE(FindMatchingValue("cat", "inc"));
EXPECT_FALSE(FindNonMatchingValue("cat", "inc"));
@@ -896,61 +965,75 @@
// Include existent wildcard -> all categories matching wildcard
Clear();
included_categories.clear();
- included_categories.push_back("inc_wildcard_*");
- included_categories.push_back("inc_wildchar_?_end");
- TraceLog::GetInstance()->SetEnabled(included_categories, empty_categories,
- TraceLog::RECORD_UNTIL_FULL);
- TRACE_EVENT_INSTANT0("inc_wildcard_abc", "included");
- TRACE_EVENT_INSTANT0("inc_wildcard_", "included");
- TRACE_EVENT_INSTANT0("inc_wildchar_x_end", "included");
- TRACE_EVENT_INSTANT0("inc_wildchar_bla_end", "not_inc");
- TRACE_EVENT_INSTANT0("cat1", "not_inc");
- TRACE_EVENT_INSTANT0("cat2", "not_inc");
+ TraceLog::GetInstance()->SetEnabled(
+ CategoryFilter("inc_wildcard_*,inc_wildchar_?_end"),
+ TraceLog::RECORD_UNTIL_FULL);
+ TRACE_EVENT_INSTANT0("inc_wildcard_abc", "included",
+ TRACE_EVENT_SCOPE_THREAD);
+ TRACE_EVENT_INSTANT0("inc_wildcard_", "included", TRACE_EVENT_SCOPE_THREAD);
+ TRACE_EVENT_INSTANT0("inc_wildchar_x_end", "included",
+ TRACE_EVENT_SCOPE_THREAD);
+ TRACE_EVENT_INSTANT0("inc_wildchar_bla_end", "not_inc",
+ TRACE_EVENT_SCOPE_THREAD);
+ TRACE_EVENT_INSTANT0("cat1", "not_inc", TRACE_EVENT_SCOPE_THREAD);
+ TRACE_EVENT_INSTANT0("cat2", "not_inc", TRACE_EVENT_SCOPE_THREAD);
+ TRACE_EVENT_INSTANT0("inc_wildcard_category,other_category", "included",
+ TRACE_EVENT_SCOPE_THREAD);
+ TRACE_EVENT_INSTANT0(
+ "non_included_category,inc_wildcard_category", "included",
+ TRACE_EVENT_SCOPE_THREAD);
EndTraceAndFlush();
EXPECT_TRUE(FindMatchingValue("cat", "inc_wildcard_abc"));
EXPECT_TRUE(FindMatchingValue("cat", "inc_wildcard_"));
EXPECT_TRUE(FindMatchingValue("cat", "inc_wildchar_x_end"));
EXPECT_FALSE(FindMatchingValue("name", "not_inc"));
+ EXPECT_TRUE(FindMatchingValue("cat", "inc_wildcard_category,other_category"));
+ EXPECT_TRUE(FindMatchingValue("cat",
+ "non_included_category,inc_wildcard_category"));
included_categories.clear();
// Exclude nonexistent category -> all events
Clear();
- excluded_categories.clear();
- excluded_categories.push_back("not_found823564786");
- TraceLog::GetInstance()->SetEnabled(empty_categories, excluded_categories,
+ TraceLog::GetInstance()->SetEnabled(CategoryFilter("-not_found823564786"),
TraceLog::RECORD_UNTIL_FULL);
- TRACE_EVENT_INSTANT0("cat1", "name");
- TRACE_EVENT_INSTANT0("cat2", "name");
+ TRACE_EVENT_INSTANT0("cat1", "name", TRACE_EVENT_SCOPE_THREAD);
+ TRACE_EVENT_INSTANT0("cat2", "name", TRACE_EVENT_SCOPE_THREAD);
+ TRACE_EVENT_INSTANT0("category1,category2", "name", TRACE_EVENT_SCOPE_THREAD);
EndTraceAndFlush();
EXPECT_TRUE(FindMatchingValue("cat", "cat1"));
EXPECT_TRUE(FindMatchingValue("cat", "cat2"));
+ EXPECT_TRUE(FindMatchingValue("cat", "category1,category2"));
// Exclude existent category -> only events of other categories
Clear();
- excluded_categories.clear();
- excluded_categories.push_back("inc");
- TraceLog::GetInstance()->SetEnabled(empty_categories, excluded_categories,
+ TraceLog::GetInstance()->SetEnabled(CategoryFilter("-inc"),
TraceLog::RECORD_UNTIL_FULL);
- TRACE_EVENT_INSTANT0("inc", "name");
- TRACE_EVENT_INSTANT0("inc2", "name");
+ TRACE_EVENT_INSTANT0("inc", "name", TRACE_EVENT_SCOPE_THREAD);
+ TRACE_EVENT_INSTANT0("inc2", "name", TRACE_EVENT_SCOPE_THREAD);
+ TRACE_EVENT_INSTANT0("inc2,inc", "name", TRACE_EVENT_SCOPE_THREAD);
+ TRACE_EVENT_INSTANT0("inc,inc2", "name", TRACE_EVENT_SCOPE_THREAD);
EndTraceAndFlush();
EXPECT_TRUE(FindMatchingValue("cat", "inc2"));
EXPECT_FALSE(FindMatchingValue("cat", "inc"));
+ EXPECT_FALSE(FindMatchingValue("cat", "inc2,inc"));
+ EXPECT_FALSE(FindMatchingValue("cat", "inc,inc2"));
// Exclude existent wildcard -> all categories not matching wildcard
Clear();
- excluded_categories.clear();
- excluded_categories.push_back("inc_wildcard_*");
- excluded_categories.push_back("inc_wildchar_?_end");
- TraceLog::GetInstance()->SetEnabled(empty_categories, excluded_categories,
- TraceLog::RECORD_UNTIL_FULL);
- TRACE_EVENT_INSTANT0("inc_wildcard_abc", "not_inc");
- TRACE_EVENT_INSTANT0("inc_wildcard_", "not_inc");
- TRACE_EVENT_INSTANT0("inc_wildchar_x_end", "not_inc");
- TRACE_EVENT_INSTANT0("inc_wildchar_bla_end", "included");
- TRACE_EVENT_INSTANT0("cat1", "included");
- TRACE_EVENT_INSTANT0("cat2", "included");
+ TraceLog::GetInstance()->SetEnabled(
+ CategoryFilter("-inc_wildcard_*,-inc_wildchar_?_end"),
+ TraceLog::RECORD_UNTIL_FULL);
+ TRACE_EVENT_INSTANT0("inc_wildcard_abc", "not_inc",
+ TRACE_EVENT_SCOPE_THREAD);
+ TRACE_EVENT_INSTANT0("inc_wildcard_", "not_inc",
+ TRACE_EVENT_SCOPE_THREAD);
+ TRACE_EVENT_INSTANT0("inc_wildchar_x_end", "not_inc",
+ TRACE_EVENT_SCOPE_THREAD);
+ TRACE_EVENT_INSTANT0("inc_wildchar_bla_end", "included",
+ TRACE_EVENT_SCOPE_THREAD);
+ TRACE_EVENT_INSTANT0("cat1", "included", TRACE_EVENT_SCOPE_THREAD);
+ TRACE_EVENT_INSTANT0("cat2", "included", TRACE_EVENT_SCOPE_THREAD);
EndTraceAndFlush();
EXPECT_TRUE(FindMatchingValue("cat", "inc_wildchar_bla_end"));
EXPECT_TRUE(FindMatchingValue("cat", "cat1"));
@@ -966,13 +1049,13 @@
// Basic one occurrence.
BeginTrace();
TraceLog::GetInstance()->SetWatchEvent("cat", "event");
- TRACE_EVENT_INSTANT0("cat", "event");
+ TRACE_EVENT_INSTANT0("cat", "event", TRACE_EVENT_SCOPE_THREAD);
EndTraceAndFlush();
EXPECT_EQ(event_watch_notification_, 1);
// Basic one occurrence before Set.
BeginTrace();
- TRACE_EVENT_INSTANT0("cat", "event");
+ TRACE_EVENT_INSTANT0("cat", "event", TRACE_EVENT_SCOPE_THREAD);
TraceLog::GetInstance()->SetWatchEvent("cat", "event");
EndTraceAndFlush();
EXPECT_EQ(event_watch_notification_, 1);
@@ -982,7 +1065,7 @@
TraceLog::GetInstance()->SetWatchEvent("cat", "event");
EndTraceAndFlush();
BeginTrace();
- TRACE_EVENT_INSTANT0("cat", "event");
+ TRACE_EVENT_INSTANT0("cat", "event", TRACE_EVENT_SCOPE_THREAD);
EndTraceAndFlush();
EXPECT_EQ(event_watch_notification_, 0);
@@ -991,21 +1074,21 @@
int num_occurrences = 5;
TraceLog::GetInstance()->SetWatchEvent("cat", "event");
for (int i = 0; i < num_occurrences; ++i)
- TRACE_EVENT_INSTANT0("cat", "event");
+ TRACE_EVENT_INSTANT0("cat", "event", TRACE_EVENT_SCOPE_THREAD);
EndTraceAndFlush();
EXPECT_EQ(event_watch_notification_, num_occurrences);
// Wrong category.
BeginTrace();
TraceLog::GetInstance()->SetWatchEvent("cat", "event");
- TRACE_EVENT_INSTANT0("wrong_cat", "event");
+ TRACE_EVENT_INSTANT0("wrong_cat", "event", TRACE_EVENT_SCOPE_THREAD);
EndTraceAndFlush();
EXPECT_EQ(event_watch_notification_, 0);
// Wrong name.
BeginTrace();
TraceLog::GetInstance()->SetWatchEvent("cat", "event");
- TRACE_EVENT_INSTANT0("cat", "wrong_event");
+ TRACE_EVENT_INSTANT0("cat", "wrong_event", TRACE_EVENT_SCOPE_THREAD);
EndTraceAndFlush();
EXPECT_EQ(event_watch_notification_, 0);
@@ -1013,7 +1096,7 @@
BeginTrace();
TraceLog::GetInstance()->SetWatchEvent("cat", "event");
TraceLog::GetInstance()->CancelWatchEvent();
- TRACE_EVENT_INSTANT0("cat", "event");
+ TRACE_EVENT_INSTANT0("cat", "event", TRACE_EVENT_SCOPE_THREAD);
EndTraceAndFlush();
EXPECT_EQ(event_watch_notification_, 0);
}
@@ -1037,12 +1120,12 @@
EXPECT_TRUE(FindNamePhase("name1", "F"));
std::string id_str;
- StringAppendF(&id_str, "%llx", id);
+ StringAppendF(&id_str, "0x%llx", id);
EXPECT_TRUE(FindNamePhaseKeyValue("name1", "S", "id", id_str.c_str()));
EXPECT_TRUE(FindNamePhaseKeyValue("name1", "T", "id", id_str.c_str()));
EXPECT_TRUE(FindNamePhaseKeyValue("name1", "F", "id", id_str.c_str()));
- EXPECT_TRUE(FindNamePhaseKeyValue("name3", "S", "id", "0"));
+ EXPECT_TRUE(FindNamePhaseKeyValue("name3", "S", "id", "0x0"));
// BEGIN events should not have id
EXPECT_FALSE(FindNamePhaseKeyValue("name2", "B", "id", "0"));
@@ -1268,20 +1351,20 @@
BeginTrace();
PlatformThread::SetName("");
- TRACE_EVENT_INSTANT0("drink", "water");
+ TRACE_EVENT_INSTANT0("drink", "water", TRACE_EVENT_SCOPE_THREAD);
PlatformThread::SetName("cafe");
- TRACE_EVENT_INSTANT0("drink", "coffee");
+ TRACE_EVENT_INSTANT0("drink", "coffee", TRACE_EVENT_SCOPE_THREAD);
PlatformThread::SetName("shop");
// No event here, so won't appear in combined name.
PlatformThread::SetName("pub");
- TRACE_EVENT_INSTANT0("drink", "beer");
- TRACE_EVENT_INSTANT0("drink", "wine");
+ TRACE_EVENT_INSTANT0("drink", "beer", TRACE_EVENT_SCOPE_THREAD);
+ TRACE_EVENT_INSTANT0("drink", "wine", TRACE_EVENT_SCOPE_THREAD);
PlatformThread::SetName(" bar");
- TRACE_EVENT_INSTANT0("drink", "whisky");
+ TRACE_EVENT_INSTANT0("drink", "whisky", TRACE_EVENT_SCOPE_THREAD);
EndTraceAndFlush();
@@ -1320,11 +1403,13 @@
// so that it will be destroyed when this scope closes.
ManualTestSetUp();
- TRACE_EVENT_INSTANT0("all", "not recorded; system not enabled");
+ TRACE_EVENT_INSTANT0("all", "not recorded; system not enabled",
+ TRACE_EVENT_SCOPE_THREAD);
BeginTrace();
- TRACE_EVENT_INSTANT0("all", "is recorded 1; system has been enabled");
+ TRACE_EVENT_INSTANT0("all", "is recorded 1; system has been enabled",
+ TRACE_EVENT_SCOPE_THREAD);
// Trace calls that will cache pointers to categories; they're valid here
TraceCallsWithCachedCategoryPointersPointers(
"is recorded 2; system has been enabled");
@@ -1347,12 +1432,14 @@
TRACE_EVENT_END_ETW("not recorded; system shutdown", 0, NULL);
TRACE_EVENT_INSTANT_ETW("not recorded; system shutdown", 0, NULL);
TRACE_EVENT0("all", "not recorded; system shutdown");
- TRACE_EVENT_INSTANT0("all", "not recorded; system shutdown");
+ TRACE_EVENT_INSTANT0("all", "not recorded; system shutdown",
+ TRACE_EVENT_SCOPE_THREAD);
TRACE_EVENT_BEGIN0("all", "not recorded; system shutdown");
TRACE_EVENT_END0("all", "not recorded; system shutdown");
TRACE_EVENT0("new category 0!", "not recorded; system shutdown");
- TRACE_EVENT_INSTANT0("new category 1!", "not recorded; system shutdown");
+ TRACE_EVENT_INSTANT0("new category 1!", "not recorded; system shutdown",
+ TRACE_EVENT_SCOPE_THREAD);
TRACE_EVENT_BEGIN0("new category 2!", "not recorded; system shutdown");
TRACE_EVENT_END0("new category 3!", "not recorded; system shutdown");
@@ -1371,7 +1458,8 @@
std::string name_string("event name");
BeginTrace();
- TRACE_EVENT_INSTANT0("category", name_string.c_str());
+ TRACE_EVENT_INSTANT0("category", name_string.c_str(),
+ TRACE_EVENT_SCOPE_THREAD);
// Modify the string in place (a wholesale reassignment may leave the old
// string intact on the heap).
@@ -1398,7 +1486,8 @@
std::string val2("val2");
BeginTrace();
- TRACE_EVENT_COPY_INSTANT0("category", name1.c_str());
+ TRACE_EVENT_COPY_INSTANT0("category", name1.c_str(),
+ TRACE_EVENT_SCOPE_THREAD);
TRACE_EVENT_COPY_BEGIN1("category", name2.c_str(),
arg1.c_str(), 5);
TRACE_EVENT_COPY_END2("category", name3.c_str(),
@@ -1462,12 +1551,12 @@
BeginTrace();
int a = 0;
- TRACE_EVENT_INSTANT1("category", "test", "a", a++);
+ TRACE_EVENT_INSTANT1("category", "test", TRACE_EVENT_SCOPE_THREAD, "a", a++);
EXPECT_EQ(1, a);
TraceLog::GetInstance()->SetDisabled();
- TRACE_EVENT_INSTANT1("category", "test", "a", a++);
+ TRACE_EVENT_INSTANT1("category", "test", TRACE_EVENT_SCOPE_THREAD, "a", a++);
EXPECT_EQ(1, a);
EndTraceAndFlush();
@@ -1477,17 +1566,18 @@
ManualTestSetUp();
TraceLog* trace_log = TraceLog::GetInstance();
- trace_log->SetEnabled(std::string(), TraceLog::RECORD_UNTIL_FULL);
+ CategoryFilter cf_inc_all("*");
+ trace_log->SetEnabled(cf_inc_all, TraceLog::RECORD_UNTIL_FULL);
EXPECT_TRUE(trace_log->IsEnabled());
trace_log->SetDisabled();
EXPECT_FALSE(trace_log->IsEnabled());
- trace_log->SetEnabled(true, TraceLog::RECORD_UNTIL_FULL);
+ trace_log->SetEnabled(cf_inc_all, TraceLog::RECORD_UNTIL_FULL);
EXPECT_TRUE(trace_log->IsEnabled());
const std::vector<std::string> empty;
- trace_log->SetEnabled(empty, empty, TraceLog::RECORD_UNTIL_FULL);
+ trace_log->SetEnabled(CategoryFilter(""), TraceLog::RECORD_UNTIL_FULL);
EXPECT_TRUE(trace_log->IsEnabled());
- trace_log->SetEnabled(false, TraceLog::RECORD_UNTIL_FULL);
+ trace_log->SetDisabled();
EXPECT_TRUE(trace_log->IsEnabled());
trace_log->SetDisabled();
EXPECT_FALSE(trace_log->IsEnabled());
@@ -1497,29 +1587,30 @@
ManualTestSetUp();
TraceLog* trace_log = TraceLog::GetInstance();
- trace_log->SetEnabled(std::string("foo,bar"), TraceLog::RECORD_UNTIL_FULL);
- EXPECT_TRUE(*trace_log->GetCategoryEnabled("foo"));
- EXPECT_TRUE(*trace_log->GetCategoryEnabled("bar"));
- EXPECT_FALSE(*trace_log->GetCategoryEnabled("baz"));
- trace_log->SetEnabled(std::string("foo2"), TraceLog::RECORD_UNTIL_FULL);
- EXPECT_TRUE(*trace_log->GetCategoryEnabled("foo2"));
- EXPECT_FALSE(*trace_log->GetCategoryEnabled("baz"));
- trace_log->SetEnabled(std::string(""), TraceLog::RECORD_UNTIL_FULL);
- EXPECT_TRUE(*trace_log->GetCategoryEnabled("foo"));
- EXPECT_TRUE(*trace_log->GetCategoryEnabled("baz"));
+ trace_log->SetEnabled(CategoryFilter("foo,bar"), TraceLog::RECORD_UNTIL_FULL);
+ EXPECT_TRUE(*trace_log->GetCategoryGroupEnabled("foo"));
+ EXPECT_TRUE(*trace_log->GetCategoryGroupEnabled("bar"));
+ EXPECT_FALSE(*trace_log->GetCategoryGroupEnabled("baz"));
+ trace_log->SetEnabled(CategoryFilter("foo2"), TraceLog::RECORD_UNTIL_FULL);
+ EXPECT_TRUE(*trace_log->GetCategoryGroupEnabled("foo2"));
+ EXPECT_FALSE(*trace_log->GetCategoryGroupEnabled("baz"));
+ trace_log->SetEnabled(CategoryFilter(""), TraceLog::RECORD_UNTIL_FULL);
+ EXPECT_TRUE(*trace_log->GetCategoryGroupEnabled("foo"));
+ EXPECT_TRUE(*trace_log->GetCategoryGroupEnabled("baz"));
trace_log->SetDisabled();
trace_log->SetDisabled();
trace_log->SetDisabled();
- EXPECT_FALSE(*trace_log->GetCategoryEnabled("foo"));
- EXPECT_FALSE(*trace_log->GetCategoryEnabled("baz"));
+ EXPECT_FALSE(*trace_log->GetCategoryGroupEnabled("foo"));
+ EXPECT_FALSE(*trace_log->GetCategoryGroupEnabled("baz"));
- trace_log->SetEnabled(std::string("-foo,-bar"), TraceLog::RECORD_UNTIL_FULL);
- EXPECT_FALSE(*trace_log->GetCategoryEnabled("foo"));
- EXPECT_TRUE(*trace_log->GetCategoryEnabled("baz"));
- trace_log->SetEnabled(std::string("moo"), TraceLog::RECORD_UNTIL_FULL);
- EXPECT_TRUE(*trace_log->GetCategoryEnabled("baz"));
- EXPECT_TRUE(*trace_log->GetCategoryEnabled("moo"));
- EXPECT_TRUE(*trace_log->GetCategoryEnabled("foo"));
+ trace_log->SetEnabled(CategoryFilter("-foo,-bar"),
+ TraceLog::RECORD_UNTIL_FULL);
+ EXPECT_FALSE(*trace_log->GetCategoryGroupEnabled("foo"));
+ EXPECT_TRUE(*trace_log->GetCategoryGroupEnabled("baz"));
+ trace_log->SetEnabled(CategoryFilter("moo"), TraceLog::RECORD_UNTIL_FULL);
+ EXPECT_TRUE(*trace_log->GetCategoryGroupEnabled("baz"));
+ EXPECT_TRUE(*trace_log->GetCategoryGroupEnabled("moo"));
+ EXPECT_TRUE(*trace_log->GetCategoryGroupEnabled("foo"));
trace_log->SetDisabled();
trace_log->SetDisabled();
}
@@ -1527,7 +1618,8 @@
TEST_F(TraceEventTestFixture, TraceOptionsParsing) {
ManualTestSetUp();
- EXPECT_EQ(TraceLog::RECORD_UNTIL_FULL, TraceLog::TraceOptionsFromString(""));
+ EXPECT_EQ(TraceLog::RECORD_UNTIL_FULL,
+ TraceLog::TraceOptionsFromString(std::string()));
EXPECT_EQ(TraceLog::RECORD_UNTIL_FULL,
TraceLog::TraceOptionsFromString("record-until-full"));
@@ -1540,7 +1632,7 @@
event_watch_notification_ = 0;
TraceLog::GetInstance()->SetEnabled(
- std::string("*"),
+ CategoryFilter("*"),
TraceLog::Options(TraceLog::RECORD_UNTIL_FULL |
TraceLog::ENABLE_SAMPLING));
@@ -1559,6 +1651,69 @@
EXPECT_TRUE(FindNamePhase("Things", "P"));
}
+class MyData : public base::debug::ConvertableToTraceFormat {
+ public:
+ MyData() {}
+ virtual ~MyData() {}
+
+ virtual void AppendAsTraceFormat(std::string* out) const OVERRIDE {
+ out->append("{\"foo\":1}");
+ }
+
+ private:
+ DISALLOW_COPY_AND_ASSIGN(MyData);
+};
+
+TEST_F(TraceEventTestFixture, ConvertableTypes) {
+ ManualTestSetUp();
+ TraceLog::GetInstance()->SetEnabled(CategoryFilter("*"),
+ TraceLog::RECORD_UNTIL_FULL);
+
+ scoped_ptr<MyData> data(new MyData());
+ scoped_ptr<MyData> data1(new MyData());
+ scoped_ptr<MyData> data2(new MyData());
+ TRACE_EVENT1("foo", "bar", "data",
+ data.PassAs<base::debug::ConvertableToTraceFormat>());
+ TRACE_EVENT2("foo", "baz",
+ "data1", data1.PassAs<base::debug::ConvertableToTraceFormat>(),
+ "data2", data2.PassAs<base::debug::ConvertableToTraceFormat>());
+
+ EndTraceAndFlush();
+
+ DictionaryValue* dict = FindNamePhase("bar", "B");
+ ASSERT_TRUE(dict);
+
+ const DictionaryValue* args_dict = NULL;
+ dict->GetDictionary("args", &args_dict);
+ ASSERT_TRUE(args_dict);
+
+ const Value* value = NULL;
+ const DictionaryValue* convertable_dict = NULL;
+ EXPECT_TRUE(args_dict->Get("data", &value));
+ ASSERT_TRUE(value->GetAsDictionary(&convertable_dict));
+
+ int foo_val;
+ EXPECT_TRUE(convertable_dict->GetInteger("foo", &foo_val));
+ EXPECT_EQ(1, foo_val);
+
+ dict = FindNamePhase("baz", "B");
+ ASSERT_TRUE(dict);
+ args_dict = NULL;
+ dict->GetDictionary("args", &args_dict);
+ ASSERT_TRUE(args_dict);
+
+ value = NULL;
+ convertable_dict = NULL;
+ EXPECT_TRUE(args_dict->Get("data1", &value));
+ ASSERT_TRUE(value->GetAsDictionary(&convertable_dict));
+
+ value = NULL;
+ convertable_dict = NULL;
+ EXPECT_TRUE(args_dict->Get("data2", &value));
+ ASSERT_TRUE(value->GetAsDictionary(&convertable_dict));
+}
+
+
class TraceEventCallbackTest : public TraceEventTestFixture {
public:
virtual void SetUp() OVERRIDE {
@@ -1595,20 +1750,116 @@
TraceEventCallbackTest* TraceEventCallbackTest::s_instance;
TEST_F(TraceEventCallbackTest, TraceEventCallback) {
- TRACE_EVENT_INSTANT0("all", "before enable");
- TraceLog::GetInstance()->SetEnabled(true, TraceLog::RECORD_UNTIL_FULL);
- TRACE_EVENT_INSTANT0("all", "before callback set");
+ TRACE_EVENT_INSTANT0("all", "before enable", TRACE_EVENT_SCOPE_THREAD);
+ TraceLog::GetInstance()->SetEnabled(CategoryFilter("*"),
+ TraceLog::RECORD_UNTIL_FULL);
+ TRACE_EVENT_INSTANT0("all", "before callback set", TRACE_EVENT_SCOPE_THREAD);
TraceLog::GetInstance()->SetEventCallback(Callback);
- TRACE_EVENT_INSTANT0("all", "event1");
- TRACE_EVENT_INSTANT0("all", "event2");
+ TRACE_EVENT_INSTANT0("all", "event1", TRACE_EVENT_SCOPE_GLOBAL);
+ TRACE_EVENT_INSTANT0("all", "event2", TRACE_EVENT_SCOPE_GLOBAL);
TraceLog::GetInstance()->SetEventCallback(NULL);
- TRACE_EVENT_INSTANT0("all", "after callback removed");
- EXPECT_EQ(2u, collected_events_.size());
+ TRACE_EVENT_INSTANT0("all", "after callback removed",
+ TRACE_EVENT_SCOPE_GLOBAL);
+ ASSERT_EQ(2u, collected_events_.size());
EXPECT_EQ("event1", collected_events_[0]);
EXPECT_EQ("event2", collected_events_[1]);
}
+TEST_F(TraceEventCallbackTest, TraceEventCallbackWhileFull) {
+ TraceLog::GetInstance()->SetEnabled(CategoryFilter("*"),
+ TraceLog::RECORD_UNTIL_FULL);
+ do {
+ TRACE_EVENT_INSTANT0("all", "badger badger", TRACE_EVENT_SCOPE_GLOBAL);
+ } while ((notifications_received_ & TraceLog::TRACE_BUFFER_FULL) == 0);
+ TraceLog::GetInstance()->SetEventCallback(Callback);
+ TRACE_EVENT_INSTANT0("all", "a snake", TRACE_EVENT_SCOPE_GLOBAL);
+ TraceLog::GetInstance()->SetEventCallback(NULL);
+ ASSERT_EQ(1u, collected_events_.size());
+ EXPECT_EQ("a snake", collected_events_[0]);
+}
+
// TODO(dsinclair): Continuous Tracing unit test.
+// Test the category filter.
+TEST_F(TraceEventTestFixture, CategoryFilter) {
+ ManualTestSetUp();
+
+ // Using the default filter.
+ CategoryFilter default_cf = CategoryFilter(
+ CategoryFilter::kDefaultCategoryFilterString);
+ std::string category_filter_str = default_cf.ToString();
+ EXPECT_STREQ("-*Debug,-*Test", category_filter_str.c_str());
+ EXPECT_TRUE(default_cf.IsCategoryGroupEnabled("not-excluded-category"));
+ EXPECT_FALSE(default_cf.IsCategoryGroupEnabled("Category1,CategoryDebug"));
+ EXPECT_FALSE(default_cf.IsCategoryGroupEnabled("CategoryDebug,Category1"));
+ EXPECT_FALSE(default_cf.IsCategoryGroupEnabled("CategoryTest,Category2"));
+
+ // Make sure that upon an empty string, we fall back to the default filter.
+ default_cf = CategoryFilter("");
+ category_filter_str = default_cf.ToString();
+ EXPECT_STREQ("-*Debug,-*Test", category_filter_str.c_str());
+ EXPECT_TRUE(default_cf.IsCategoryGroupEnabled("not-excluded-category"));
+ EXPECT_FALSE(default_cf.IsCategoryGroupEnabled("Category1,CategoryDebug"));
+ EXPECT_FALSE(default_cf.IsCategoryGroupEnabled("CategoryDebug,Category1"));
+ EXPECT_FALSE(default_cf.IsCategoryGroupEnabled("CategoryTest,Category2"));
+
+ // Using an arbitrary non-empty filter.
+ CategoryFilter cf("included,-excluded,inc_pattern*,-exc_pattern*");
+ category_filter_str = cf.ToString();
+ EXPECT_STREQ("included,inc_pattern*,-excluded,-exc_pattern*",
+ category_filter_str.c_str());
+ EXPECT_TRUE(cf.IsCategoryGroupEnabled("included"));
+ EXPECT_TRUE(cf.IsCategoryGroupEnabled("inc_pattern_category"));
+ EXPECT_FALSE(cf.IsCategoryGroupEnabled("exc_pattern_category"));
+ EXPECT_FALSE(cf.IsCategoryGroupEnabled("excluded"));
+ EXPECT_FALSE(cf.IsCategoryGroupEnabled("not-excluded-nor-included"));
+ EXPECT_FALSE(cf.IsCategoryGroupEnabled("Category1,CategoryDebug"));
+ EXPECT_FALSE(cf.IsCategoryGroupEnabled("CategoryDebug,Category1"));
+ EXPECT_FALSE(cf.IsCategoryGroupEnabled("CategoryTest,Category2"));
+
+ cf.Merge(default_cf);
+ category_filter_str = cf.ToString();
+ EXPECT_STREQ("included,inc_pattern*,-excluded,-exc_pattern*,-*Debug,-*Test",
+ category_filter_str.c_str());
+ cf.Clear();
+ EXPECT_FALSE(cf.HasIncludedPatterns());
+
+ CategoryFilter reconstructed_cf(category_filter_str);
+ category_filter_str = reconstructed_cf.ToString();
+ EXPECT_STREQ("included,inc_pattern*,-excluded,-exc_pattern*,-*Debug,-*Test",
+ category_filter_str.c_str());
+
+ // One included category.
+ CategoryFilter one_inc_cf("only_inc_cat");
+ category_filter_str = one_inc_cf.ToString();
+ EXPECT_STREQ("only_inc_cat", category_filter_str.c_str());
+
+ // One excluded category.
+ CategoryFilter one_exc_cf("-only_exc_cat");
+ category_filter_str = one_exc_cf.ToString();
+ EXPECT_STREQ("-only_exc_cat", category_filter_str.c_str());
+
+ // Test that IsEmptyOrContainsLeadingOrTrailingWhitespace actually catches
+ // categories that are explicitly forbiden.
+ // This method is called in a DCHECK to assert that we don't have these types
+ // of strings as categories.
+ EXPECT_TRUE(CategoryFilter::IsEmptyOrContainsLeadingOrTrailingWhitespace(
+ " bad_category "));
+ EXPECT_TRUE(CategoryFilter::IsEmptyOrContainsLeadingOrTrailingWhitespace(
+ " bad_category"));
+ EXPECT_TRUE(CategoryFilter::IsEmptyOrContainsLeadingOrTrailingWhitespace(
+ "bad_category "));
+ EXPECT_TRUE(CategoryFilter::IsEmptyOrContainsLeadingOrTrailingWhitespace(
+ " bad_category"));
+ EXPECT_TRUE(CategoryFilter::IsEmptyOrContainsLeadingOrTrailingWhitespace(
+ "bad_category "));
+ EXPECT_TRUE(CategoryFilter::IsEmptyOrContainsLeadingOrTrailingWhitespace(
+ " bad_category "));
+ EXPECT_TRUE(CategoryFilter::IsEmptyOrContainsLeadingOrTrailingWhitespace(
+ ""));
+ EXPECT_FALSE(CategoryFilter::IsEmptyOrContainsLeadingOrTrailingWhitespace(
+ "good_category"));
+}
+
} // namespace debug
} // namespace base
diff --git a/base/deferred_sequenced_task_runner.cc b/base/deferred_sequenced_task_runner.cc
new file mode 100644
index 0000000..c96704c
--- /dev/null
+++ b/base/deferred_sequenced_task_runner.cc
@@ -0,0 +1,99 @@
+// Copyright (c) 2013 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/deferred_sequenced_task_runner.h"
+
+#include "base/bind.h"
+#include "base/logging.h"
+
+namespace base {
+
+DeferredSequencedTaskRunner::DeferredTask::DeferredTask() {
+}
+
+DeferredSequencedTaskRunner::DeferredTask::~DeferredTask() {
+}
+
+DeferredSequencedTaskRunner::DeferredSequencedTaskRunner(
+ const scoped_refptr<SequencedTaskRunner>& target_task_runner)
+ : started_(false),
+ target_task_runner_(target_task_runner) {
+}
+
+DeferredSequencedTaskRunner::~DeferredSequencedTaskRunner() {
+}
+
+bool DeferredSequencedTaskRunner::PostDelayedTask(
+ const tracked_objects::Location& from_here,
+ const Closure& task,
+ TimeDelta delay) {
+ AutoLock lock(lock_);
+ if (started_) {
+ DCHECK(deferred_tasks_queue_.empty());
+ return target_task_runner_->PostDelayedTask(from_here, task, delay);
+ }
+
+ QueueDeferredTask(from_here, task, delay, false /* is_non_nestable */);
+ return true;
+}
+
+bool DeferredSequencedTaskRunner::RunsTasksOnCurrentThread() const {
+ return target_task_runner_->RunsTasksOnCurrentThread();
+}
+
+bool DeferredSequencedTaskRunner::PostNonNestableDelayedTask(
+ const tracked_objects::Location& from_here,
+ const Closure& task,
+ TimeDelta delay) {
+ AutoLock lock(lock_);
+ if (started_) {
+ DCHECK(deferred_tasks_queue_.empty());
+ return target_task_runner_->PostNonNestableDelayedTask(from_here,
+ task,
+ delay);
+ }
+ QueueDeferredTask(from_here, task, delay, true /* is_non_nestable */);
+ return true;
+}
+
+void DeferredSequencedTaskRunner::QueueDeferredTask(
+ const tracked_objects::Location& from_here,
+ const Closure& task,
+ TimeDelta delay,
+ bool is_non_nestable) {
+ DeferredTask deferred_task;
+ deferred_task.posted_from = from_here;
+ deferred_task.task = task;
+ deferred_task.delay = delay;
+ deferred_task.is_non_nestable = is_non_nestable;
+ deferred_tasks_queue_.push_back(deferred_task);
+}
+
+
+void DeferredSequencedTaskRunner::Start() {
+ AutoLock lock(lock_);
+ DCHECK(!started_);
+ started_ = true;
+ for (std::vector<DeferredTask>::iterator i = deferred_tasks_queue_.begin();
+ i != deferred_tasks_queue_.end();
+ ++i) {
+ const DeferredTask& task = *i;
+ if (task.is_non_nestable) {
+ target_task_runner_->PostNonNestableDelayedTask(task.posted_from,
+ task.task,
+ task.delay);
+ } else {
+ target_task_runner_->PostDelayedTask(task.posted_from,
+ task.task,
+ task.delay);
+ }
+ // Replace the i-th element in the |deferred_tasks_queue_| with an empty
+ // |DelayedTask| to ensure that |task| is destroyed before the next task
+ // is posted.
+ *i = DeferredTask();
+ }
+ deferred_tasks_queue_.clear();
+}
+
+} // namespace base
diff --git a/base/deferred_sequenced_task_runner.h b/base/deferred_sequenced_task_runner.h
new file mode 100644
index 0000000..d1cdb43
--- /dev/null
+++ b/base/deferred_sequenced_task_runner.h
@@ -0,0 +1,79 @@
+// Copyright (c) 2013 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 BASE_DEFERRED_SEQUENCED_TASKRUNNER_H_
+#define BASE_DEFERRED_SEQUENCED_TASKRUNNER_H_
+
+#include <vector>
+
+#include "base/base_export.h"
+#include "base/basictypes.h"
+#include "base/callback.h"
+#include "base/compiler_specific.h"
+#include "base/memory/ref_counted.h"
+#include "base/sequenced_task_runner.h"
+#include "base/synchronization/lock.h"
+#include "base/time.h"
+#include "base/tracked_objects.h"
+
+namespace base {
+
+// A DeferredSequencedTaskRunner is a subclass of SequencedTaskRunner that
+// queues up all requests until the first call to Start() is issued.
+class BASE_EXPORT DeferredSequencedTaskRunner : public SequencedTaskRunner {
+ public:
+ explicit DeferredSequencedTaskRunner(
+ const scoped_refptr<SequencedTaskRunner>& target_runner);
+
+ // TaskRunner implementation
+ virtual bool PostDelayedTask(const tracked_objects::Location& from_here,
+ const Closure& task,
+ TimeDelta delay) OVERRIDE;
+ virtual bool RunsTasksOnCurrentThread() const OVERRIDE;
+
+ // SequencedTaskRunner implementation
+ virtual bool PostNonNestableDelayedTask(
+ const tracked_objects::Location& from_here,
+ const Closure& task,
+ TimeDelta delay) OVERRIDE;
+
+ // Start the execution - posts all queued tasks to the target executor. The
+ // deferred tasks are posted with their initial delay, meaning that the task
+ // execution delay is actually measured from Start.
+ // Fails when called a second time.
+ void Start();
+
+ private:
+ struct DeferredTask {
+ DeferredTask();
+ ~DeferredTask();
+
+ tracked_objects::Location posted_from;
+ Closure task;
+ // The delay this task was initially posted with.
+ TimeDelta delay;
+ bool is_non_nestable;
+ };
+
+ virtual ~DeferredSequencedTaskRunner();
+
+ // Creates a |Task| object and adds it to |deferred_tasks_queue_|.
+ void QueueDeferredTask(const tracked_objects::Location& from_here,
+ const Closure& task,
+ TimeDelta delay,
+ bool is_non_nestable);
+
+ // // Protects |started_| and |deferred_tasks_queue_|.
+ mutable Lock lock_;
+
+ bool started_;
+ const scoped_refptr<SequencedTaskRunner> target_task_runner_;
+ std::vector<DeferredTask> deferred_tasks_queue_;
+
+ DISALLOW_COPY_AND_ASSIGN(DeferredSequencedTaskRunner);
+};
+
+} // namespace base
+
+#endif // BASE_DEFERRED_SEQUENCED_TASKRUNNER_H_
diff --git a/base/deferred_sequenced_task_runner_unittest.cc b/base/deferred_sequenced_task_runner_unittest.cc
new file mode 100644
index 0000000..c033ba8
--- /dev/null
+++ b/base/deferred_sequenced_task_runner_unittest.cc
@@ -0,0 +1,184 @@
+// Copyright (c) 2013 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/deferred_sequenced_task_runner.h"
+
+#include "base/basictypes.h"
+#include "base/bind.h"
+#include "base/bind_helpers.h"
+#include "base/memory/ref_counted.h"
+#include "base/message_loop.h"
+#include "base/message_loop_proxy.h"
+#include "base/threading/non_thread_safe.h"
+#include "base/threading/thread.h"
+#include "testing/gmock/include/gmock/gmock.h"
+#include "testing/gtest/include/gtest/gtest.h"
+
+namespace {
+
+class DeferredSequencedTaskRunnerTest : public testing::Test,
+ public base::NonThreadSafe {
+ public:
+ class ExecuteTaskOnDestructor :
+ public base::RefCounted<ExecuteTaskOnDestructor> {
+ public:
+ ExecuteTaskOnDestructor(
+ DeferredSequencedTaskRunnerTest* executor,
+ int task_id)
+ : executor_(executor),
+ task_id_(task_id) {
+ }
+ private:
+ friend class base::RefCounted<ExecuteTaskOnDestructor>;
+ virtual ~ExecuteTaskOnDestructor() {
+ executor_->ExecuteTask(task_id_);
+ }
+ DeferredSequencedTaskRunnerTest* executor_;
+ int task_id_;
+ };
+
+ void ExecuteTask(int task_id) {
+ base::AutoLock lock(lock_);
+ executed_task_ids_.push_back(task_id);
+ }
+
+ void PostExecuteTask(int task_id) {
+ runner_->PostTask(FROM_HERE,
+ base::Bind(&DeferredSequencedTaskRunnerTest::ExecuteTask,
+ base::Unretained(this),
+ task_id));
+ }
+
+ void StartRunner() {
+ runner_->Start();
+ }
+
+ void DoNothing(ExecuteTaskOnDestructor* object) {
+ }
+
+ protected:
+ DeferredSequencedTaskRunnerTest() :
+ loop_(),
+ runner_(
+ new base::DeferredSequencedTaskRunner(loop_.message_loop_proxy())) {
+ }
+
+ MessageLoop loop_;
+ scoped_refptr<base::DeferredSequencedTaskRunner> runner_;
+ mutable base::Lock lock_;
+ std::vector<int> executed_task_ids_;
+};
+
+TEST_F(DeferredSequencedTaskRunnerTest, Stopped) {
+ PostExecuteTask(1);
+ loop_.RunUntilIdle();
+ EXPECT_THAT(executed_task_ids_, testing::ElementsAre());
+}
+
+TEST_F(DeferredSequencedTaskRunnerTest, Start) {
+ StartRunner();
+ PostExecuteTask(1);
+ loop_.RunUntilIdle();
+ EXPECT_THAT(executed_task_ids_, testing::ElementsAre(1));
+}
+
+TEST_F(DeferredSequencedTaskRunnerTest, StartWithMultipleElements) {
+ StartRunner();
+ for (int i = 1; i < 5; ++i)
+ PostExecuteTask(i);
+
+ loop_.RunUntilIdle();
+ EXPECT_THAT(executed_task_ids_, testing::ElementsAre(1, 2, 3, 4));
+}
+
+TEST_F(DeferredSequencedTaskRunnerTest, DeferredStart) {
+ PostExecuteTask(1);
+ loop_.RunUntilIdle();
+ EXPECT_THAT(executed_task_ids_, testing::ElementsAre());
+
+ StartRunner();
+ loop_.RunUntilIdle();
+ EXPECT_THAT(executed_task_ids_, testing::ElementsAre(1));
+
+ PostExecuteTask(2);
+ loop_.RunUntilIdle();
+ EXPECT_THAT(executed_task_ids_, testing::ElementsAre(1, 2));
+}
+
+TEST_F(DeferredSequencedTaskRunnerTest, DeferredStartWithMultipleElements) {
+ for (int i = 1; i < 5; ++i)
+ PostExecuteTask(i);
+ loop_.RunUntilIdle();
+ EXPECT_THAT(executed_task_ids_, testing::ElementsAre());
+
+ StartRunner();
+ for (int i = 5; i < 9; ++i)
+ PostExecuteTask(i);
+ loop_.RunUntilIdle();
+ EXPECT_THAT(executed_task_ids_, testing::ElementsAre(1, 2, 3, 4, 5, 6, 7, 8));
+}
+
+TEST_F(DeferredSequencedTaskRunnerTest, DeferredStartWithMultipleThreads) {
+ {
+ base::Thread thread1("DeferredSequencedTaskRunnerTestThread1");
+ base::Thread thread2("DeferredSequencedTaskRunnerTestThread2");
+ thread1.Start();
+ thread2.Start();
+ for (int i = 0; i < 5; ++i) {
+ thread1.message_loop()->PostTask(
+ FROM_HERE,
+ base::Bind(&DeferredSequencedTaskRunnerTest::PostExecuteTask,
+ base::Unretained(this),
+ 2 * i));
+ thread2.message_loop()->PostTask(
+ FROM_HERE,
+ base::Bind(&DeferredSequencedTaskRunnerTest::PostExecuteTask,
+ base::Unretained(this),
+ 2 * i + 1));
+ if (i == 2) {
+ thread1.message_loop()->PostTask(
+ FROM_HERE,
+ base::Bind(&DeferredSequencedTaskRunnerTest::StartRunner,
+ base::Unretained(this)));
+ }
+ }
+ }
+
+ loop_.RunUntilIdle();
+ EXPECT_THAT(executed_task_ids_,
+ testing::WhenSorted(testing::ElementsAre(0, 1, 2, 3, 4, 5, 6, 7, 8, 9)));
+}
+
+TEST_F(DeferredSequencedTaskRunnerTest, ObjectDestructionOrder) {
+ {
+ base::Thread thread("DeferredSequencedTaskRunnerTestThread");
+ thread.Start();
+ runner_ =
+ new base::DeferredSequencedTaskRunner(thread.message_loop_proxy());
+ for (int i = 0; i < 5; ++i) {
+ {
+ // Use a block to ensure that no reference to |short_lived_object|
+ // is kept on the main thread after it is posted to |runner_|.
+ scoped_refptr<ExecuteTaskOnDestructor> short_lived_object =
+ new ExecuteTaskOnDestructor(this, 2 * i);
+ runner_->PostTask(
+ FROM_HERE,
+ base::Bind(&DeferredSequencedTaskRunnerTest::DoNothing,
+ base::Unretained(this),
+ short_lived_object));
+ }
+ // |short_lived_object| with id |2 * i| should be destroyed before the
+ // task |2 * i + 1| is executed.
+ PostExecuteTask(2 * i + 1);
+ }
+ StartRunner();
+ }
+
+ // All |short_lived_object| with id |2 * i| are destroyed before the task
+ // |2 * i + 1| is executed.
+ EXPECT_THAT(executed_task_ids_,
+ testing::ElementsAre(0, 1, 2, 3, 4, 5, 6, 7, 8, 9));
+}
+
+} // namespace
diff --git a/base/file_util.cc b/base/file_util.cc
index 5567f74..e76c5c2 100644
--- a/base/file_util.cc
+++ b/base/file_util.cc
@@ -13,9 +13,9 @@
#include "base/files/file_path.h"
#include "base/logging.h"
-#include "base/string_piece.h"
#include "base/string_util.h"
#include "base/stringprintf.h"
+#include "base/strings/string_piece.h"
#include "base/utf_string_conversions.h"
using base::FilePath;
@@ -37,28 +37,6 @@
bool g_bug108724_debug = false;
-bool EndsWithSeparator(const FilePath& path) {
- FilePath::StringType value = path.value();
- if (value.empty())
- return false;
-
- return FilePath::IsSeparator(value[value.size() - 1]);
-}
-
-bool EnsureEndsWithSeparator(FilePath* path) {
- if (!DirectoryExists(*path))
- return false;
-
- if (EndsWithSeparator(*path))
- return true;
-
- FilePath::StringType& path_str =
- const_cast<FilePath::StringType&>(path->value());
- path_str.append(&FilePath::kSeparators[0], 1);
-
- return true;
-}
-
void InsertBeforeExtension(FilePath* path, const FilePath::StringType& suffix) {
FilePath::StringType& value =
const_cast<FilePath::StringType&>(path->value());
@@ -208,14 +186,6 @@
return true;
}
-bool IsDot(const FilePath& path) {
- return FILE_PATH_LITERAL(".") == path.BaseName().value();
-}
-
-bool IsDotDot(const FilePath& path) {
- return FILE_PATH_LITERAL("..") == path.BaseName().value();
-}
-
bool TouchFile(const FilePath& path,
const base::Time& last_accessed,
const base::Time& last_modified) {
@@ -289,33 +259,6 @@
return -1;
}
-bool ContainsPath(const FilePath &parent, const FilePath& child) {
- FilePath abs_parent = FilePath(parent);
- FilePath abs_child = FilePath(child);
-
- if (!file_util::AbsolutePath(&abs_parent) ||
- !file_util::AbsolutePath(&abs_child))
- return false;
-
-#if defined(OS_WIN)
- // file_util::AbsolutePath() does not flatten case on Windows, so we must do
- // a case-insensitive compare.
- if (!StartsWith(abs_child.value(), abs_parent.value(), false))
-#else
- if (!StartsWithASCII(abs_child.value(), abs_parent.value(), true))
-#endif
- return false;
-
- // file_util::AbsolutePath() normalizes '/' to '\' on Windows, so we only need
- // to check kSeparators[0].
- if (abs_child.value().length() <= abs_parent.value().length() ||
- abs_child.value()[abs_parent.value().length()] !=
- FilePath::kSeparators[0])
- return false;
-
- return true;
-}
-
int64 ComputeDirectorySize(const FilePath& root_path) {
int64 running_size = 0;
FileEnumerator file_iter(root_path, true, FileEnumerator::FILES);
@@ -333,24 +276,6 @@
return running_size;
}
-int64 ComputeFilesSize(const FilePath& directory,
- const FilePath::StringType& pattern) {
- int64 running_size = 0;
- FileEnumerator file_iter(directory, false, FileEnumerator::FILES, pattern);
- for (FilePath current = file_iter.Next(); !current.empty();
- current = file_iter.Next()) {
- FileEnumerator::FindInfo info;
- file_iter.GetFindInfo(&info);
-#if defined(OS_WIN)
- LARGE_INTEGER li = { info.nFileSizeLow, info.nFileSizeHigh };
- running_size += li.QuadPart;
-#else
- running_size += info.stat.st_size;
-#endif
- }
- return running_size;
-}
-
///////////////////////////////////////////////
// FileEnumerator
//
@@ -358,7 +283,9 @@
bool FileEnumerator::ShouldSkip(const FilePath& path) {
FilePath::StringType basename = path.BaseName().value();
- return IsDot(path) || (IsDotDot(path) && !(INCLUDE_DOT_DOT & file_type_));
+ return basename == FILE_PATH_LITERAL(".") ||
+ (basename == FILE_PATH_LITERAL("..") &&
+ !(INCLUDE_DOT_DOT & file_type_));
}
} // namespace
diff --git a/base/file_util.h b/base/file_util.h
index bd4b33d..4ffd05b 100644
--- a/base/file_util.h
+++ b/base/file_util.h
@@ -39,45 +39,21 @@
namespace base {
class Time;
-}
+
+// Returns an absolute version of a relative path. Returns an empty path on
+// error. On POSIX, this function fails if the path does not exist. This
+// function can result in I/O so it can be slow.
+BASE_EXPORT FilePath MakeAbsoluteFilePath(const FilePath& input);
+
+} // namespace base
namespace file_util {
extern bool g_bug108724_debug;
//-----------------------------------------------------------------------------
-// Functions that operate purely on a path string w/o touching the filesystem:
-
-// Returns true if the given path ends with a path separator character.
-BASE_EXPORT bool EndsWithSeparator(const base::FilePath& path);
-
-// Makes sure that |path| ends with a separator IFF path is a directory that
-// exists. Returns true if |path| is an existing directory, false otherwise.
-BASE_EXPORT bool EnsureEndsWithSeparator(base::FilePath* path);
-
-// Convert provided relative path into an absolute path. Returns false on
-// error. On POSIX, this function fails if the path does not exist.
-BASE_EXPORT bool AbsolutePath(base::FilePath* path);
-
-// Returns true if |parent| contains |child|. Both paths are converted to
-// absolute paths before doing the comparison.
-BASE_EXPORT bool ContainsPath(const base::FilePath& parent,
- const base::FilePath& child);
-
-//-----------------------------------------------------------------------------
// Functions that involve filesystem access or modification:
-// Returns the number of files matching the current path that were
-// created on or after the given |file_time|. Doesn't count ".." or ".".
-//
-// Note for POSIX environments: a file created before |file_time|
-// can be mis-detected as a newer file due to low precision of
-// timestmap of file creation time. If you need to avoid such
-// mis-detection perfectly, you should wait one second before
-// obtaining |file_time|.
-BASE_EXPORT int CountFilesCreatedAfter(const base::FilePath& path,
- const base::Time& file_time);
-
// Returns the total number of bytes used by all the files under |root_path|.
// If the path does not exist the function returns 0.
//
@@ -85,20 +61,12 @@
// particularly speedy in any platform.
BASE_EXPORT int64 ComputeDirectorySize(const base::FilePath& root_path);
-// Returns the total number of bytes used by all files matching the provided
-// |pattern|, on this |directory| (without recursion). If the path does not
-// exist the function returns 0.
-//
-// This function is implemented using the FileEnumerator class so it is not
-// particularly speedy in any platform.
-BASE_EXPORT int64 ComputeFilesSize(const base::FilePath& directory,
- const base::FilePath::StringType& pattern);
-
// Deletes the given path, whether it's a file or a directory.
// If it's a directory, it's perfectly happy to delete all of the
// directory's contents. Passing true to recursive deletes
// subdirectories and their contents as well.
-// Returns true if successful, false otherwise.
+// Returns true if successful, false otherwise. It is considered successful
+// to attempt to delete a file that does not exist.
//
// In posix environment and if |path| is a symbolic link, this deletes only
// the symlink. (even if the symlink points to a non-existent file)
@@ -301,12 +269,6 @@
// Returns the file size. Returns true on success.
BASE_EXPORT bool GetFileSize(const base::FilePath& file_path, int64* file_size);
-// Returns true if the given path's base name is ".".
-BASE_EXPORT bool IsDot(const base::FilePath& path);
-
-// Returns true if the given path's base name is "..".
-BASE_EXPORT bool IsDotDot(const base::FilePath& path);
-
// Sets |real_path| to |path| with symbolic links and junctions expanded.
// On windows, make sure the path starts with a lettered drive.
// |path| must reference a file. Function will fail if |path| points to
@@ -394,6 +356,13 @@
const base::FilePath::StringType& suffix);
#if defined(OS_POSIX)
+// Creates a directory with a guaranteed unique name based on |path|, returning
+// the pathname if successful, or an empty path if there was an error creating
+// the directory. Does not create parent directories.
+BASE_EXPORT base::FilePath MakeUniqueDirectory(const base::FilePath& path);
+#endif
+
+#if defined(OS_POSIX)
// Test that |path| can only be changed by a given user and members of
// a given set of groups.
// Specifically, test that all parts of |path| under (and including) |base|:
@@ -560,11 +529,6 @@
DISALLOW_COPY_AND_ASSIGN(FileEnumerator);
};
-// Returns whether the file has been modified since a particular date.
-BASE_EXPORT bool HasFileBeenModifiedSince(
- const FileEnumerator::FindInfo& find_info,
- const base::Time& cutoff_time);
-
#if defined(OS_LINUX)
// Broad categories of file systems as returned by statfs() on Linux.
enum FileSystemType {
diff --git a/base/file_util_posix.cc b/base/file_util_posix.cc
index c7014b6..8b36812 100644
--- a/base/file_util_posix.cc
+++ b/base/file_util_posix.cc
@@ -59,6 +59,19 @@
#endif
using base::FilePath;
+using base::MakeAbsoluteFilePath;
+
+namespace base {
+
+FilePath MakeAbsoluteFilePath(const FilePath& input) {
+ base::ThreadRestrictions::AssertIOAllowed();
+ char full_path[PATH_MAX];
+ if (realpath(input.value().c_str(), full_path) == NULL)
+ return FilePath();
+ return FilePath(full_path);
+}
+
+} // namespace base
namespace file_util {
@@ -150,63 +163,6 @@
#endif
}
-bool AbsolutePath(FilePath* path) {
- base::ThreadRestrictions::AssertIOAllowed(); // For realpath().
- char full_path[PATH_MAX];
- if (realpath(path->value().c_str(), full_path) == NULL)
- return false;
- *path = FilePath(full_path);
- return true;
-}
-
-int CountFilesCreatedAfter(const FilePath& path,
- const base::Time& comparison_time) {
- base::ThreadRestrictions::AssertIOAllowed();
- int file_count = 0;
-
- DIR* dir = opendir(path.value().c_str());
- if (dir) {
-#if !defined(OS_LINUX) && !defined(OS_MACOSX) && !defined(OS_BSD) && \
- !defined(OS_SOLARIS) && !defined(OS_ANDROID)
- #error Port warning: depending on the definition of struct dirent, \
- additional space for pathname may be needed
-#endif
- struct dirent ent_buf;
- struct dirent* ent;
- while (readdir_r(dir, &ent_buf, &ent) == 0 && ent) {
- if ((strcmp(ent->d_name, ".") == 0) ||
- (strcmp(ent->d_name, "..") == 0))
- continue;
-
- stat_wrapper_t st;
- int test = CallStat(path.Append(ent->d_name).value().c_str(), &st);
- if (test != 0) {
- DPLOG(ERROR) << "stat64 failed";
- continue;
- }
- // Here, we use Time::TimeT(), which discards microseconds. This
- // means that files which are newer than |comparison_time| may
- // be considered older. If we don't discard microseconds, it
- // introduces another issue. Suppose the following case:
- //
- // 1. Get |comparison_time| by Time::Now() and the value is 10.1 (secs).
- // 2. Create a file and the current time is 10.3 (secs).
- //
- // As POSIX doesn't have microsecond precision for |st_ctime|,
- // the creation time of the file created in the step 2 is 10 and
- // the file is considered older than |comparison_time|. After
- // all, we may have to accept either of the two issues: 1. files
- // which are older than |comparison_time| are considered newer
- // (current implementation) 2. files newer than
- // |comparison_time| are considered older.
- if (static_cast<time_t>(st.st_ctime) >= comparison_time.ToTimeT())
- ++file_count;
- }
- closedir(dir);
- }
- return file_count;
-}
-
// TODO(erikkay): The Windows version of this accepts paths like "foo/bar/*"
// which works both with and without the recursive flag. I'm not sure we need
// that functionality. If not, remove from file_util_win.cc, otherwise add it
@@ -301,15 +257,16 @@
// This function does not properly handle destinations within the source
FilePath real_to_path = to_path;
if (PathExists(real_to_path)) {
- if (!AbsolutePath(&real_to_path))
+ real_to_path = MakeAbsoluteFilePath(real_to_path);
+ if (real_to_path.empty())
return false;
} else {
- real_to_path = real_to_path.DirName();
- if (!AbsolutePath(&real_to_path))
+ real_to_path = MakeAbsoluteFilePath(real_to_path.DirName());
+ if (real_to_path.empty())
return false;
}
- FilePath real_from_path = from_path;
- if (!AbsolutePath(&real_from_path))
+ FilePath real_from_path = MakeAbsoluteFilePath(from_path);
+ if (real_from_path.empty())
return false;
if (real_to_path.value().size() >= real_from_path.value().size() &&
real_to_path.value().compare(0, real_from_path.value().size(),
@@ -586,6 +543,24 @@
return true;
}
+base::FilePath MakeUniqueDirectory(const base::FilePath& path) {
+ const int kMaxAttempts = 20;
+ for (int attempts = 0; attempts < kMaxAttempts; attempts++) {
+ int uniquifier =
+ GetUniquePathNumber(path, base::FilePath::StringType());
+ if (uniquifier < 0)
+ break;
+ base::FilePath test_path = (uniquifier == 0) ? path :
+ path.InsertBeforeExtensionASCII(
+ base::StringPrintf(" (%d)", uniquifier));
+ if (mkdir(test_path.value().c_str(), 0777) == 0)
+ return test_path;
+ else if (errno != EEXIST)
+ break;
+ }
+ return base::FilePath();
+}
+
// TODO(rkc): Refactor GetFileInfo and FileEnumerator to handle symlinks
// correctly. http://code.google.com/p/chromium-os/issues/detail?id=15948
bool IsLink(const FilePath& file_path) {
@@ -859,11 +834,6 @@
return true;
}
-bool HasFileBeenModifiedSince(const FileEnumerator::FindInfo& find_info,
- const base::Time& cutoff_time) {
- return static_cast<time_t>(find_info.stat.st_mtime) >= cutoff_time.ToTimeT();
-}
-
bool NormalizeFilePath(const FilePath& path, FilePath* normalized_path) {
FilePath real_path_result;
if (!RealPath(path, &real_path_result))
diff --git a/base/file_util_unittest.cc b/base/file_util_unittest.cc
index b905654..5cfc677 100644
--- a/base/file_util_unittest.cc
+++ b/base/file_util_unittest.cc
@@ -310,28 +310,6 @@
#endif
};
-TEST_F(FileUtilTest, CountFilesCreatedAfter) {
- FilePath file_name =
- temp_dir_.path().Append(FILE_PATH_LITERAL("f.txt"));
- CreateTextFile(file_name, L"test");
-
- base::PlatformFileInfo info;
- file_util::GetFileInfo(file_name, &info);
- base::Time file_time = info.creation_time;
-
- base::TimeDelta two_secs = base::TimeDelta::FromSeconds(2);
- base::Time after = file_time + two_secs;
- EXPECT_EQ(0, file_util::CountFilesCreatedAfter(temp_dir_.path(), after));
-
- base::Time before = file_time - two_secs;
- EXPECT_EQ(1, file_util::CountFilesCreatedAfter(temp_dir_.path(), before));
-
- // After deleting the file, shouldn't find it any more.
- EXPECT_TRUE(file_util::Delete(file_name, false));
- EXPECT_EQ(0, file_util::CountFilesCreatedAfter(temp_dir_.path(), before));
- EXPECT_EQ(0, file_util::CountFilesCreatedAfter(temp_dir_.path(), after));
-}
-
TEST_F(FileUtilTest, FileAndDirectorySize) {
// Create three files of 20, 30 and 3 chars (utf8). ComputeDirectorySize
// should return 53 bytes.
@@ -358,13 +336,6 @@
int64 computed_size = file_util::ComputeDirectorySize(temp_dir_.path());
EXPECT_EQ(size_f1 + size_f2 + 3, computed_size);
-
- computed_size =
- file_util::ComputeFilesSize(temp_dir_.path(), FPL("The file*"));
- EXPECT_EQ(size_f1, computed_size);
-
- computed_size = file_util::ComputeFilesSize(temp_dir_.path(), FPL("bla*"));
- EXPECT_EQ(0, computed_size);
}
TEST_F(FileUtilTest, NormalizeFilePathBasic) {
@@ -1560,10 +1531,8 @@
TEST_F(ReadOnlyFileUtilTest, ContentsEqual) {
FilePath data_dir;
- ASSERT_TRUE(PathService::Get(base::DIR_SOURCE_ROOT, &data_dir));
- data_dir = data_dir.Append(FILE_PATH_LITERAL("base"))
- .Append(FILE_PATH_LITERAL("data"))
- .Append(FILE_PATH_LITERAL("file_util_unittest"));
+ ASSERT_TRUE(PathService::Get(base::DIR_TEST_DATA, &data_dir));
+ data_dir = data_dir.AppendASCII("file_util");
ASSERT_TRUE(file_util::PathExists(data_dir));
FilePath original_file =
@@ -1609,10 +1578,8 @@
TEST_F(ReadOnlyFileUtilTest, TextContentsEqual) {
FilePath data_dir;
- ASSERT_TRUE(PathService::Get(base::DIR_SOURCE_ROOT, &data_dir));
- data_dir = data_dir.Append(FILE_PATH_LITERAL("base"))
- .Append(FILE_PATH_LITERAL("data"))
- .Append(FILE_PATH_LITERAL("file_util_unittest"));
+ ASSERT_TRUE(PathService::Get(base::DIR_TEST_DATA, &data_dir));
+ data_dir = data_dir.AppendASCII("file_util");
ASSERT_TRUE(file_util::PathExists(data_dir));
FilePath original_file =
@@ -1879,15 +1846,14 @@
// create the files
FilePath dir2file = dir2.Append(FILE_PATH_LITERAL("dir2file.txt"));
- CreateTextFile(dir2file, L"");
+ CreateTextFile(dir2file, std::wstring());
FilePath dir2innerfile = dir2inner.Append(FILE_PATH_LITERAL("innerfile.txt"));
- CreateTextFile(dir2innerfile, L"");
+ CreateTextFile(dir2innerfile, std::wstring());
FilePath file1 = temp_dir_.path().Append(FILE_PATH_LITERAL("file1.txt"));
- CreateTextFile(file1, L"");
- FilePath file2_rel =
- dir2.Append(FilePath::kParentDirectory)
- .Append(FILE_PATH_LITERAL("file2.txt"));
- CreateTextFile(file2_rel, L"");
+ CreateTextFile(file1, std::wstring());
+ FilePath file2_rel = dir2.Append(FilePath::kParentDirectory)
+ .Append(FILE_PATH_LITERAL("file2.txt"));
+ CreateTextFile(file2_rel, std::wstring());
FilePath file2_abs = temp_dir_.path().Append(FILE_PATH_LITERAL("file2.txt"));
// Only enumerate files.
@@ -1995,50 +1961,6 @@
EXPECT_EQ(L"hellohello", read_content);
}
-TEST_F(FileUtilTest, Contains) {
- FilePath data_dir =
- temp_dir_.path().Append(FILE_PATH_LITERAL("FilePathTest"));
-
- // Create a fresh, empty copy of this directory.
- if (file_util::PathExists(data_dir)) {
- ASSERT_TRUE(file_util::Delete(data_dir, true));
- }
- ASSERT_TRUE(file_util::CreateDirectory(data_dir));
-
- FilePath foo(data_dir.Append(FILE_PATH_LITERAL("foo")));
- FilePath bar(foo.Append(FILE_PATH_LITERAL("bar.txt")));
- FilePath baz(data_dir.Append(FILE_PATH_LITERAL("baz.txt")));
- FilePath foobar(data_dir.Append(FILE_PATH_LITERAL("foobar.txt")));
-
- // Annoyingly, the directories must actually exist in order for realpath(),
- // which Contains() relies on in posix, to work.
- ASSERT_TRUE(file_util::CreateDirectory(foo));
- std::string data("hello");
- ASSERT_TRUE(file_util::WriteFile(bar, data.c_str(), data.length()));
- ASSERT_TRUE(file_util::WriteFile(baz, data.c_str(), data.length()));
- ASSERT_TRUE(file_util::WriteFile(foobar, data.c_str(), data.length()));
-
- EXPECT_TRUE(file_util::ContainsPath(foo, bar));
- EXPECT_FALSE(file_util::ContainsPath(foo, baz));
- EXPECT_FALSE(file_util::ContainsPath(foo, foobar));
- EXPECT_FALSE(file_util::ContainsPath(foo, foo));
-
- // Platform-specific concerns.
- FilePath foo_caps(data_dir.Append(FILE_PATH_LITERAL("FOO")));
-#if defined(OS_WIN)
- EXPECT_TRUE(file_util::ContainsPath(foo,
- foo_caps.Append(FILE_PATH_LITERAL("bar.txt"))));
- EXPECT_TRUE(file_util::ContainsPath(foo,
- FilePath(foo.value() + FILE_PATH_LITERAL("/bar.txt"))));
-#elif defined(OS_MACOSX)
- // We can't really do this test on OS X since the case-sensitivity of the
- // filesystem is configurable.
-#elif defined(OS_POSIX)
- EXPECT_FALSE(file_util::ContainsPath(foo,
- foo_caps.Append(FILE_PATH_LITERAL("bar.txt"))));
-#endif
-}
-
TEST_F(FileUtilTest, TouchFile) {
FilePath data_dir =
temp_dir_.path().Append(FILE_PATH_LITERAL("FilePathTest"));
diff --git a/base/file_util_win.cc b/base/file_util_win.cc
index f7897a0..964302a 100644
--- a/base/file_util_win.cc
+++ b/base/file_util_win.cc
@@ -28,6 +28,18 @@
using base::FilePath;
+namespace base {
+
+FilePath MakeAbsoluteFilePath(const FilePath& input) {
+ base::ThreadRestrictions::AssertIOAllowed();
+ wchar_t file_path[MAX_PATH];
+ if (!_wfullpath(file_path, input.value().c_str(), MAX_PATH))
+ return FilePath();
+ return FilePath(file_path);
+}
+
+} // namespace base
+
namespace file_util {
namespace {
@@ -37,45 +49,6 @@
} // namespace
-bool AbsolutePath(FilePath* path) {
- base::ThreadRestrictions::AssertIOAllowed();
- wchar_t file_path_buf[MAX_PATH];
- if (!_wfullpath(file_path_buf, path->value().c_str(), MAX_PATH))
- return false;
- *path = FilePath(file_path_buf);
- return true;
-}
-
-int CountFilesCreatedAfter(const FilePath& path,
- const base::Time& comparison_time) {
- base::ThreadRestrictions::AssertIOAllowed();
-
- int file_count = 0;
- FILETIME comparison_filetime(comparison_time.ToFileTime());
-
- WIN32_FIND_DATA find_file_data;
- // All files in given dir
- std::wstring filename_spec = path.Append(L"*").value();
- HANDLE find_handle = FindFirstFile(filename_spec.c_str(), &find_file_data);
- if (find_handle != INVALID_HANDLE_VALUE) {
- do {
- // Don't count current or parent directories.
- if ((wcscmp(find_file_data.cFileName, L"..") == 0) ||
- (wcscmp(find_file_data.cFileName, L".") == 0))
- continue;
-
- long result = CompareFileTime(&find_file_data.ftCreationTime, // NOLINT
- &comparison_filetime);
- // File was created after or on comparison time
- if ((result == 1) || (result == 0))
- ++file_count;
- } while (FindNextFile(find_handle, &find_file_data));
- FindClose(find_handle);
- }
-
- return file_count;
-}
-
bool Delete(const FilePath& path, bool recursive) {
base::ThreadRestrictions::AssertIOAllowed();
@@ -755,15 +728,6 @@
return FilePath();
}
-bool HasFileBeenModifiedSince(const FileEnumerator::FindInfo& find_info,
- const base::Time& cutoff_time) {
- base::ThreadRestrictions::AssertIOAllowed();
- FILETIME file_time = cutoff_time.ToFileTime();
- long result = CompareFileTime(&find_info.ftLastWriteTime, // NOLINT
- &file_time);
- return result == 1 || result == 0;
-}
-
bool NormalizeFilePath(const FilePath& path, FilePath* real_path) {
base::ThreadRestrictions::AssertIOAllowed();
FilePath mapped_file;
diff --git a/base/files/file_path.cc b/base/files/file_path.cc
index 407ec85..e9495a1 100644
--- a/base/files/file_path.cc
+++ b/base/files/file_path.cc
@@ -13,8 +13,8 @@
// These includes are just for the *Hack functions, and should be removed
// when those functions are removed.
-#include "base/string_piece.h"
#include "base/string_util.h"
+#include "base/strings/string_piece.h"
#include "base/strings/sys_string_conversions.h"
#include "base/utf_string_conversions.h"
@@ -521,6 +521,24 @@
return IsPathAbsolute(path_);
}
+bool FilePath::EndsWithSeparator() const {
+ if (empty())
+ return false;
+ return IsSeparator(path_[path_.size() - 1]);
+}
+
+FilePath FilePath::AsEndingWithSeparator() const {
+ if (EndsWithSeparator() || path_.empty())
+ return *this;
+
+ StringType path_str;
+ path_str.reserve(path_.length() + 1); // Only allocate string once.
+
+ path_str = path_;
+ path_str.append(&kSeparators[0], 1);
+ return FilePath(path_str);
+}
+
FilePath FilePath::StripTrailingSeparators() const {
FilePath new_path(path_);
new_path.StripTrailingSeparatorsInternal();
@@ -552,7 +570,7 @@
std::string FilePath::MaybeAsASCII() const {
if (IsStringASCII(path_))
return path_;
- return "";
+ return std::string();
}
std::string FilePath::AsUTF8Unsafe() const {
diff --git a/base/files/file_path.h b/base/files/file_path.h
index 2e0009d..d66d631 100644
--- a/base/files/file_path.h
+++ b/base/files/file_path.h
@@ -110,7 +110,7 @@
#include "base/compiler_specific.h"
#include "base/hash_tables.h"
#include "base/string16.h"
-#include "base/string_piece.h" // For implicit conversions.
+#include "base/strings/string_piece.h" // For implicit conversions.
#include "build/build_config.h"
// Windows-style drive letter support and pathname separator characters can be
@@ -285,6 +285,13 @@
// platforms, an absolute path begins with a separator character.
bool IsAbsolute() const;
+ // Returns true if the patch ends with a path separator character.
+ bool EndsWithSeparator() const WARN_UNUSED_RESULT;
+
+ // Returns a copy of this FilePath that ends with a trailing separator. If
+ // the input path is empty, an empty FilePath will be returned.
+ FilePath AsEndingWithSeparator() const WARN_UNUSED_RESULT;
+
// Returns a copy of this FilePath that does not end with a trailing
// separator.
FilePath StripTrailingSeparators() const WARN_UNUSED_RESULT;
diff --git a/base/files/file_path_unittest.cc b/base/files/file_path_unittest.cc
index 9a690a9..28778d9 100644
--- a/base/files/file_path_unittest.cc
+++ b/base/files/file_path_unittest.cc
@@ -1196,7 +1196,34 @@
"i: " << i << ", input: " << input.value();
}
}
-
#endif
+TEST_F(FilePathTest, EndsWithSeparator) {
+ const UnaryBooleanTestData cases[] = {
+ { FPL(""), false },
+ { FPL("/"), true },
+ { FPL("foo/"), true },
+ { FPL("bar"), false },
+ { FPL("/foo/bar"), false },
+ };
+ for (size_t i = 0; i < arraysize(cases); ++i) {
+ FilePath input = FilePath(cases[i].input).NormalizePathSeparators();
+ EXPECT_EQ(cases[i].expected, input.EndsWithSeparator());
+ }
+}
+
+TEST_F(FilePathTest, AsEndingWithSeparator) {
+ const UnaryTestData cases[] = {
+ { FPL(""), FPL("") },
+ { FPL("/"), FPL("/") },
+ { FPL("foo"), FPL("foo/") },
+ { FPL("foo/"), FPL("foo/") }
+ };
+ for (size_t i = 0; i < arraysize(cases); ++i) {
+ FilePath input = FilePath(cases[i].input).NormalizePathSeparators();
+ FilePath expected = FilePath(cases[i].expected).NormalizePathSeparators();
+ EXPECT_EQ(expected.value(), input.AsEndingWithSeparator().value());
+ }
+}
+
} // namespace base
diff --git a/base/files/file_path_watcher.h b/base/files/file_path_watcher.h
index 896601c..3e5c7fc 100644
--- a/base/files/file_path_watcher.h
+++ b/base/files/file_path_watcher.h
@@ -17,7 +17,7 @@
namespace base {
// This class lets you register interest in changes on a FilePath.
-// The delegate will get called whenever the file or directory referenced by the
+// The callback will get called whenever the file or directory referenced by the
// FilePath is changed, including created or deleted. Due to limitations in the
// underlying OS APIs, FilePathWatcher has slightly different semantics on OS X
// than on Windows or Linux. FilePathWatcher on Linux and Windows will detect
@@ -33,8 +33,6 @@
typedef base::Callback<void(const FilePath& path, bool error)> Callback;
// Used internally to encapsulate different members on different platforms.
- // TODO(jhawkins): Move this into its own file. Also fix the confusing naming
- // wrt Delegate vs PlatformDelegate.
class PlatformDelegate : public base::RefCountedThreadSafe<PlatformDelegate> {
public:
PlatformDelegate();
diff --git a/base/files/file_path_watcher_kqueue.cc b/base/files/file_path_watcher_kqueue.cc
index c348ebd..1c086de 100644
--- a/base/files/file_path_watcher_kqueue.cc
+++ b/base/files/file_path_watcher_kqueue.cc
@@ -94,7 +94,7 @@
bool* target_file_affected,
bool* update_watches);
- // Respond to a move of deletion of the path component represented by
+ // Respond to a move or deletion of the path component represented by
// |event|. Sets |target_file_affected| to true if |target_| is affected.
// Sets |update_watches| to true if |events_| need to be updated.
void HandleDeleteOrMoveChange(const EventVector::iterator& event,
@@ -123,14 +123,16 @@
// Returns a file descriptor that will not block the system from deleting
// the file it references.
- static int FileDescriptorForPath(const FilePath& path);
+ static uintptr_t FileDescriptorForPath(const FilePath& path);
+
+ static const uintptr_t kNoFileDescriptor = static_cast<uintptr_t>(-1);
// Closes |*fd| and sets |*fd| to -1.
- static void CloseFileDescriptor(int* fd);
+ static void CloseFileDescriptor(uintptr_t* fd);
// Returns true if kevent has open file descriptor.
static bool IsKeventFileDescriptorOpen(const struct kevent& event) {
- return event.ident != static_cast<uintptr_t>(-1);
+ return event.ident != kNoFileDescriptor;
}
static EventData* EventDataForKevent(const struct kevent& event) {
@@ -148,7 +150,7 @@
};
void FilePathWatcherImpl::ReleaseEvent(struct kevent& event) {
- CloseFileDescriptor(reinterpret_cast<int*>(&event.ident));
+ CloseFileDescriptor(&event.ident);
EventData* entry = EventDataForKevent(event);
delete entry;
event.udata = NULL;
@@ -176,10 +178,10 @@
} else {
built_path = built_path.Append(*i);
}
- int fd = -1;
+ uintptr_t fd = kNoFileDescriptor;
if (path_still_exists) {
fd = FileDescriptorForPath(built_path);
- if (fd == -1) {
+ if (fd == kNoFileDescriptor) {
path_still_exists = false;
} else {
++last_existing_entry;
@@ -196,19 +198,22 @@
return last_existing_entry;
}
-int FilePathWatcherImpl::FileDescriptorForPath(const FilePath& path) {
- return HANDLE_EINTR(open(path.value().c_str(), O_EVTONLY));
+uintptr_t FilePathWatcherImpl::FileDescriptorForPath(const FilePath& path) {
+ int fd = HANDLE_EINTR(open(path.value().c_str(), O_EVTONLY));
+ if (fd == -1)
+ return kNoFileDescriptor;
+ return fd;
}
-void FilePathWatcherImpl::CloseFileDescriptor(int *fd) {
- if (*fd == -1) {
+void FilePathWatcherImpl::CloseFileDescriptor(uintptr_t* fd) {
+ if (*fd == kNoFileDescriptor) {
return;
}
if (HANDLE_EINTR(close(*fd)) != 0) {
DPLOG(ERROR) << "close";
}
- *fd = -1;
+ *fd = kNoFileDescriptor;
}
bool FilePathWatcherImpl::AreKeventValuesValid(struct kevent* kevents,
@@ -236,7 +241,7 @@
}
if (path_name.empty()) {
path_name = base::StringPrintf(
- "fd %d", *reinterpret_cast<int*>(&kevents[i].ident));
+ "fd %ld", reinterpret_cast<long>(&kevents[i].ident));
}
DLOG(ERROR) << "Error: " << kevents[i].data << " for " << path_name;
valid = false;
@@ -252,8 +257,8 @@
EventVector::iterator next_event = event + 1;
EventData* next_event_data = EventDataForKevent(*next_event);
// Check to see if the next item in path is still accessible.
- int have_access = FileDescriptorForPath(next_event_data->path_);
- if (have_access == -1) {
+ uintptr_t have_access = FileDescriptorForPath(next_event_data->path_);
+ if (have_access == kNoFileDescriptor) {
*target_file_affected = true;
*update_watches = true;
EventVector::iterator local_event(event);
@@ -262,7 +267,7 @@
// potentially rendering other events in |updates| invalid.
// There is no need to remove the events from |kqueue_| because this
// happens as a side effect of closing the file descriptor.
- CloseFileDescriptor(reinterpret_cast<int*>(&local_event->ident));
+ CloseFileDescriptor(&local_event->ident);
}
} else {
CloseFileDescriptor(&have_access);
@@ -281,7 +286,7 @@
// potentially rendering other events in |updates| invalid.
// There is no need to remove the events from |kqueue_| because this
// happens as a side effect of closing the file descriptor.
- CloseFileDescriptor(reinterpret_cast<int*>(&local_event->ident));
+ CloseFileDescriptor(&local_event->ident);
}
}
@@ -291,10 +296,9 @@
bool* update_watches) {
// Get the next item in the path.
EventVector::iterator next_event = event + 1;
- EventData* next_event_data = EventDataForKevent(*next_event);
-
// Check to see if it already has a valid file descriptor.
if (!IsKeventFileDescriptorOpen(*next_event)) {
+ EventData* next_event_data = EventDataForKevent(*next_event);
// If not, attempt to open a file descriptor for it.
next_event->ident = FileDescriptorForPath(next_event_data->path_);
if (IsKeventFileDescriptorOpen(*next_event)) {
@@ -381,7 +385,7 @@
break;
}
}
- if (!IsKeventFileDescriptorOpen(*event) || event == events_.end()) {
+ if (event == events_.end() || !IsKeventFileDescriptorOpen(*event)) {
// The event may no longer exist in |events_| because another event
// modified |events_| in such a way to make it invalid. For example if
// the path is /foo/bar/bam and foo is deleted, NOTE_DELETE events for
@@ -493,7 +497,10 @@
if (!is_cancelled()) {
set_cancelled();
kqueue_watcher_.StopWatchingFileDescriptor();
- CloseFileDescriptor(&kqueue_);
+ if (HANDLE_EINTR(close(kqueue_)) != 0) {
+ DPLOG(ERROR) << "close kqueue";
+ }
+ kqueue_ = -1;
std::for_each(events_.begin(), events_.end(), ReleaseEvent);
events_.clear();
io_message_loop_ = NULL;
diff --git a/base/files/file_util_proxy_unittest.cc b/base/files/file_util_proxy_unittest.cc
index 447c43b..9a5a0d6 100644
--- a/base/files/file_util_proxy_unittest.cc
+++ b/base/files/file_util_proxy_unittest.cc
@@ -26,7 +26,7 @@
created_(false),
file_(kInvalidPlatformFileValue),
bytes_written_(-1),
- weak_factory_(ALLOW_THIS_IN_INITIALIZER_LIST(this)) {}
+ weak_factory_(this) {}
virtual void SetUp() OVERRIDE {
ASSERT_TRUE(dir_.CreateUniqueTempDir());
diff --git a/base/float_util.h b/base/float_util.h
index 31a307d..458e859 100644
--- a/base/float_util.h
+++ b/base/float_util.h
@@ -8,16 +8,14 @@
#include "build/build_config.h"
#include <float.h>
-#include <math.h>
+
+#include <cmath>
namespace base {
inline bool IsFinite(const double& number) {
-#if defined(OS_ANDROID)
- // isfinite isn't available on Android: http://b.android.com/34793
- return finite(number) != 0;
-#elif defined(OS_POSIX)
- return isfinite(number) != 0;
+#if defined(OS_POSIX)
+ return std::isfinite(number) != 0;
#elif defined(OS_WIN)
return _finite(number) != 0;
#endif
diff --git a/base/hi_res_timer_manager.h b/base/hi_res_timer_manager.h
index 1bd5538..763aede 100644
--- a/base/hi_res_timer_manager.h
+++ b/base/hi_res_timer_manager.h
@@ -6,17 +6,17 @@
#define BASE_HI_RES_TIMER_MANAGER_H_
#include "base/base_export.h"
-#include "base/system_monitor/system_monitor.h"
+#include "base/basictypes.h"
+#include "base/power_monitor/power_observer.h"
// Ensures that the Windows high resolution timer is only used
// when not running on battery power.
-class BASE_EXPORT HighResolutionTimerManager
- : public base::SystemMonitor::PowerObserver {
+class BASE_EXPORT HighResolutionTimerManager : public base::PowerObserver {
public:
HighResolutionTimerManager();
virtual ~HighResolutionTimerManager();
- // base::SystemMonitor::PowerObserver:
+ // base::PowerObserver method.
virtual void OnPowerStateChange(bool on_battery_power) OVERRIDE;
// Returns true if the hi resolution clock could be used right now.
diff --git a/base/hi_res_timer_manager_unittest.cc b/base/hi_res_timer_manager_unittest.cc
index 07651ce..601586d 100644
--- a/base/hi_res_timer_manager_unittest.cc
+++ b/base/hi_res_timer_manager_unittest.cc
@@ -5,7 +5,8 @@
#include "base/hi_res_timer_manager.h"
#include "base/memory/scoped_ptr.h"
-#include "base/system_monitor/system_monitor.h"
+#include "base/message_loop.h"
+#include "base/power_monitor/power_monitor.h"
#include "base/time.h"
#include "testing/gtest/include/gtest/gtest.h"
@@ -13,12 +14,12 @@
// http://crbug.com/114048
TEST(HiResTimerManagerTest, DISABLED_ToggleOnOff) {
MessageLoop loop;
- scoped_ptr<base::SystemMonitor> system_monitor(new base::SystemMonitor());
+ scoped_ptr<base::PowerMonitor> power_monitor(new base::PowerMonitor());
HighResolutionTimerManager manager;
// At this point, we don't know if the high resolution timers are on or off,
// it depends on what system the tests are running on (for example, if this
- // test is running on a laptop/battery, then the SystemMonitor would have
+ // test is running on a laptop/battery, then the PowerMonitor would have
// already set the PowerState to battery power; but if we're running on a
// desktop, then the PowerState will be non-battery power). Simulate a power
// level change to get to a deterministic state.
diff --git a/base/hi_res_timer_manager_win.cc b/base/hi_res_timer_manager_win.cc
index 1a92394..2a297dc 100644
--- a/base/hi_res_timer_manager_win.cc
+++ b/base/hi_res_timer_manager_win.cc
@@ -4,17 +4,18 @@
#include "base/hi_res_timer_manager.h"
+#include "base/power_monitor/power_monitor.h"
#include "base/time.h"
HighResolutionTimerManager::HighResolutionTimerManager()
: hi_res_clock_available_(false) {
- base::SystemMonitor* system_monitor = base::SystemMonitor::Get();
- system_monitor->AddPowerObserver(this);
- UseHiResClock(!system_monitor->BatteryPower());
+ base::PowerMonitor* power_monitor = base::PowerMonitor::Get();
+ power_monitor->AddObserver(this);
+ UseHiResClock(!power_monitor->BatteryPower());
}
HighResolutionTimerManager::~HighResolutionTimerManager() {
- base::SystemMonitor::Get()->RemovePowerObserver(this);
+ base::PowerMonitor::Get()->RemoveObserver(this);
UseHiResClock(false);
}
diff --git a/base/i18n/break_iterator_unittest.cc b/base/i18n/break_iterator_unittest.cc
index afb780c..cf2bf22 100644
--- a/base/i18n/break_iterator_unittest.cc
+++ b/base/i18n/break_iterator_unittest.cc
@@ -4,8 +4,8 @@
#include "base/i18n/break_iterator.h"
-#include "base/string_piece.h"
#include "base/stringprintf.h"
+#include "base/strings/string_piece.h"
#include "base/utf_string_conversions.h"
#include "testing/gtest/include/gtest/gtest.h"
diff --git a/base/i18n/case_conversion.h b/base/i18n/case_conversion.h
index 14fef00..890508d 100644
--- a/base/i18n/case_conversion.h
+++ b/base/i18n/case_conversion.h
@@ -7,7 +7,7 @@
#include "base/i18n/base_i18n_export.h"
#include "base/string16.h"
-#include "base/string_piece.h"
+#include "base/strings/string_piece.h"
namespace base {
namespace i18n {
diff --git a/base/i18n/char_iterator_unittest.cc b/base/i18n/char_iterator_unittest.cc
index 6d1294e..509e27c 100644
--- a/base/i18n/char_iterator_unittest.cc
+++ b/base/i18n/char_iterator_unittest.cc
@@ -11,7 +11,7 @@
namespace i18n {
TEST(CharIteratorsTest, TestUTF8) {
- std::string empty("");
+ std::string empty;
UTF8CharIterator empty_iter(&empty);
ASSERT_TRUE(empty_iter.end());
ASSERT_EQ(0, empty_iter.array_pos());
diff --git a/base/i18n/file_util_icu.cc b/base/i18n/file_util_icu.cc
index f023a4f..a29eb4b 100644
--- a/base/i18n/file_util_icu.cc
+++ b/base/i18n/file_util_icu.cc
@@ -8,6 +8,7 @@
#include "base/files/file_path.h"
#include "base/i18n/icu_string_conversions.h"
+#include "base/i18n/string_compare.h"
#include "base/logging.h"
#include "base/memory/scoped_ptr.h"
#include "base/memory/singleton.h"
@@ -79,56 +80,6 @@
set->freeze();
}
-class LocaleAwareComparator {
- public:
- static LocaleAwareComparator* GetInstance() {
- return Singleton<LocaleAwareComparator,
- LeakySingletonTraits<LocaleAwareComparator> >::get();
- }
-
- // Note: A similar function is available in l10n_util.
- // We cannot use it because base should not depend on l10n_util.
- // TODO(yuzo): Move some of l10n_util to base.
- int Compare(const string16& a, const string16& b) {
- // We are not sure if Collator::compare is thread-safe.
- // Use an AutoLock just in case.
- base::AutoLock auto_lock(lock_);
-
- UErrorCode error_code = U_ZERO_ERROR;
- UCollationResult result = collator_->compare(
- static_cast<const UChar*>(a.c_str()),
- static_cast<int>(a.length()),
- static_cast<const UChar*>(b.c_str()),
- static_cast<int>(b.length()),
- error_code);
- DCHECK(U_SUCCESS(error_code));
- return result;
- }
-
- private:
- friend struct DefaultSingletonTraits<LocaleAwareComparator>;
-
- LocaleAwareComparator() {
- UErrorCode error_code = U_ZERO_ERROR;
- // Use the default collator. The default locale should have been properly
- // set by the time this constructor is called.
- collator_.reset(icu::Collator::createInstance(error_code));
- DCHECK(U_SUCCESS(error_code));
- // Make it case-sensitive.
- collator_->setStrength(icu::Collator::TERTIARY);
- // Note: We do not set UCOL_NORMALIZATION_MODE attribute. In other words, we
- // do not pay performance penalty to guarantee sort order correctness for
- // non-FCD (http://unicode.org/notes/tn5/#FCD) file names. This should be a
- // reasonable tradeoff because such file names should be rare and the sort
- // order doesn't change much anyway.
- }
-
- scoped_ptr<icu::Collator> collator_;
- base::Lock lock_;
-
- DISALLOW_COPY_AND_ASSIGN(LocaleAwareComparator);
-};
-
} // namespace
namespace file_util {
@@ -182,20 +133,24 @@
bool LocaleAwareCompareFilenames(const base::FilePath& a,
const base::FilePath& b) {
+ UErrorCode error_code = U_ZERO_ERROR;
+ // Use the default collator. The default locale should have been properly
+ // set by the time this constructor is called.
+ scoped_ptr<icu::Collator> collator(icu::Collator::createInstance(error_code));
+ DCHECK(U_SUCCESS(error_code));
+ // Make it case-sensitive.
+ collator->setStrength(icu::Collator::TERTIARY);
+
#if defined(OS_WIN)
- return LocaleAwareComparator::GetInstance()->Compare(a.value().c_str(),
- b.value().c_str()) < 0;
+ return base::i18n::CompareString16WithCollator(collator.get(),
+ WideToUTF16(a.value()), WideToUTF16(b.value())) == UCOL_LESS;
#elif defined(OS_POSIX)
// On linux, the file system encoding is not defined. We assume
// SysNativeMBToWide takes care of it.
- //
- // ICU's collator can take strings in OS native encoding. But we convert the
- // strings to UTF-16 ourselves to ensure conversion consistency.
- // TODO(yuzo): Perhaps we should define SysNativeMBToUTF16?
- return LocaleAwareComparator::GetInstance()->Compare(
+ return base::i18n::CompareString16WithCollator(collator.get(),
WideToUTF16(base::SysNativeMBToWide(a.value().c_str())),
- WideToUTF16(base::SysNativeMBToWide(b.value().c_str()))) < 0;
+ WideToUTF16(base::SysNativeMBToWide(b.value().c_str()))) == UCOL_LESS;
#else
#error Not implemented on your system
#endif
diff --git a/base/i18n/icu_string_conversions_unittest.cc b/base/i18n/icu_string_conversions_unittest.cc
index af2d709..4b53435 100644
--- a/base/i18n/icu_string_conversions_unittest.cc
+++ b/base/i18n/icu_string_conversions_unittest.cc
@@ -13,7 +13,7 @@
#include "base/i18n/icu_string_conversions.h"
#include "base/logging.h"
#include "base/stringprintf.h"
-#include "base/string_piece.h"
+#include "base/strings/string_piece.h"
#include "base/utf_string_conversions.h"
#include "testing/gtest/include/gtest/gtest.h"
diff --git a/base/i18n/icu_util.cc b/base/i18n/icu_util.cc
index 42aa8ad..4e7ecdd 100644
--- a/base/i18n/icu_util.cc
+++ b/base/i18n/icu_util.cc
@@ -112,7 +112,7 @@
// Chrome doesn't normally shut down ICU, so the mapped data shouldn't ever
// be released.
- static base::MemoryMappedFile mapped_file;
+ CR_DEFINE_STATIC_LOCAL(base::MemoryMappedFile, mapped_file, ());
if (!mapped_file.IsValid()) {
// Assume it is in the framework bundle's Resources directory.
FilePath data_path =
diff --git a/base/i18n/rtl.h b/base/i18n/rtl.h
index d4e364b..6a79dbd 100644
--- a/base/i18n/rtl.h
+++ b/base/i18n/rtl.h
@@ -26,10 +26,11 @@
const char16 kLeftToRightOverride = 0x202D;
const char16 kRightToLeftOverride = 0x202E;
+// Locale.java mirrored this enum TextDirection. Please keep in sync.
enum TextDirection {
- UNKNOWN_DIRECTION,
- RIGHT_TO_LEFT,
- LEFT_TO_RIGHT,
+ UNKNOWN_DIRECTION = 0,
+ RIGHT_TO_LEFT = 1,
+ LEFT_TO_RIGHT = 2,
};
// Get the locale that the currently running process has been configured to use.
diff --git a/base/i18n/string_compare.cc b/base/i18n/string_compare.cc
new file mode 100644
index 0000000..41d19d8
--- /dev/null
+++ b/base/i18n/string_compare.cc
@@ -0,0 +1,29 @@
+// Copyright (c) 2013 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/i18n/string_compare.h"
+
+#include "base/logging.h"
+#include "base/utf_string_conversions.h"
+
+namespace base {
+namespace i18n {
+
+// Compares the character data stored in two different string16 strings by
+// specified Collator instance.
+UCollationResult CompareString16WithCollator(const icu::Collator* collator,
+ const string16& lhs,
+ const string16& rhs) {
+ DCHECK(collator);
+ UErrorCode error = U_ZERO_ERROR;
+ UCollationResult result = collator->compare(
+ static_cast<const UChar*>(lhs.c_str()), static_cast<int>(lhs.length()),
+ static_cast<const UChar*>(rhs.c_str()), static_cast<int>(rhs.length()),
+ error);
+ DCHECK(U_SUCCESS(error));
+ return result;
+}
+
+} // namespace i18n
+} // namespace base
diff --git a/base/i18n/string_compare.h b/base/i18n/string_compare.h
new file mode 100644
index 0000000..3c3d010
--- /dev/null
+++ b/base/i18n/string_compare.h
@@ -0,0 +1,28 @@
+// Copyright (c) 2013 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 BASE_I18N_STRING_COMPARE_H_
+#define BASE_I18N_STRING_COMPARE_H_
+
+#include <algorithm>
+#include <string>
+#include <vector>
+
+#include "base/i18n/base_i18n_export.h"
+#include "base/string16.h"
+#include "third_party/icu/public/i18n/unicode/coll.h"
+
+namespace base {
+namespace i18n {
+
+// Compares the two strings using the specified collator.
+BASE_I18N_EXPORT UCollationResult CompareString16WithCollator(
+ const icu::Collator* collator,
+ const string16& lhs,
+ const string16& rhs);
+
+} // namespace i18n
+} // namespace base
+
+#endif // BASE_I18N_STRING_COMPARATOR_H_
diff --git a/base/json/json_parser.cc b/base/json/json_parser.cc
index cc669f4..3f5bc1c 100644
--- a/base/json/json_parser.cc
+++ b/base/json/json_parser.cc
@@ -7,10 +7,10 @@
#include "base/float_util.h"
#include "base/logging.h"
#include "base/memory/scoped_ptr.h"
-#include "base/string_piece.h"
#include "base/string_util.h"
#include "base/stringprintf.h"
#include "base/strings/string_number_conversions.h"
+#include "base/strings/string_piece.h"
#include "base/strings/utf_string_conversion_utils.h"
#include "base/third_party/icu/icu_utf.h"
#include "base/utf_string_conversions.h"
diff --git a/base/json/json_parser.h b/base/json/json_parser.h
index 020ac25..b4d0b1b 100644
--- a/base/json/json_parser.h
+++ b/base/json/json_parser.h
@@ -11,7 +11,7 @@
#include "base/basictypes.h"
#include "base/compiler_specific.h"
#include "base/json/json_reader.h"
-#include "base/string_piece.h"
+#include "base/strings/string_piece.h"
#if !defined(OS_CHROMEOS)
#include "base/gtest_prod_util.h"
diff --git a/base/json/json_reader.h b/base/json/json_reader.h
index a5a6ac2..e602846 100644
--- a/base/json/json_reader.h
+++ b/base/json/json_reader.h
@@ -33,7 +33,7 @@
#include "base/base_export.h"
#include "base/basictypes.h"
#include "base/memory/scoped_ptr.h"
-#include "base/string_piece.h"
+#include "base/strings/string_piece.h"
namespace base {
class Value;
diff --git a/base/json/json_reader_unittest.cc b/base/json/json_reader_unittest.cc
index 353e095..ab38b04 100644
--- a/base/json/json_reader_unittest.cc
+++ b/base/json/json_reader_unittest.cc
@@ -9,7 +9,7 @@
#include "base/logging.h"
#include "base/memory/scoped_ptr.h"
#include "base/path_service.h"
-#include "base/string_piece.h"
+#include "base/strings/string_piece.h"
#include "base/utf_string_conversions.h"
#include "base/values.h"
#include "build/build_config.h"
@@ -542,10 +542,9 @@
TEST(JSONReaderTest, ReadFromFile) {
FilePath path;
- ASSERT_TRUE(PathService::Get(base::DIR_SOURCE_ROOT, &path));
- path = path.Append(FILE_PATH_LITERAL("base"))
- .Append(FILE_PATH_LITERAL("data"))
- .Append(FILE_PATH_LITERAL("json"));
+ ASSERT_TRUE(PathService::Get(base::DIR_TEST_DATA, &path));
+ path = path.AppendASCII("json");
+ ASSERT_TRUE(file_util::PathExists(path));
std::string input;
ASSERT_TRUE(file_util::ReadFileToString(
diff --git a/base/json/json_value_converter.h b/base/json/json_value_converter.h
index 69da0d8..59778e5 100644
--- a/base/json/json_value_converter.h
+++ b/base/json/json_value_converter.h
@@ -14,7 +14,7 @@
#include "base/memory/scoped_vector.h"
#include "base/stl_util.h"
#include "base/string16.h"
-#include "base/string_piece.h"
+#include "base/strings/string_piece.h"
#include "base/values.h"
// JSONValueConverter converts a JSON value into a C++ struct in a
diff --git a/base/json/json_value_converter_unittest.cc b/base/json/json_value_converter_unittest.cc
index 0018a4f..7d48f39 100644
--- a/base/json/json_value_converter_unittest.cc
+++ b/base/json/json_value_converter_unittest.cc
@@ -10,7 +10,7 @@
#include "base/json/json_reader.h"
#include "base/memory/scoped_ptr.h"
#include "base/memory/scoped_vector.h"
-#include "base/string_piece.h"
+#include "base/strings/string_piece.h"
#include "base/values.h"
#include "testing/gtest/include/gtest/gtest.h"
diff --git a/base/json/json_value_serializer_unittest.cc b/base/json/json_value_serializer_unittest.cc
index c5bef81..9df0435 100644
--- a/base/json/json_value_serializer_unittest.cc
+++ b/base/json/json_value_serializer_unittest.cc
@@ -11,6 +11,7 @@
#include "base/json/json_string_value_serializer.h"
#include "base/json/json_writer.h"
#include "base/memory/scoped_ptr.h"
+#include "base/path_service.h"
#include "base/string_util.h"
#include "base/utf_string_conversions.h"
#include "base/values.h"
@@ -195,7 +196,7 @@
// initialized with a const string.
ASSERT_FALSE(serializer.Serialize(*root_dict));
- std::string test_serialization = "";
+ std::string test_serialization;
JSONStringValueSerializer mutable_serializer(&test_serialization);
ASSERT_TRUE(mutable_serializer.Serialize(*root_dict));
ASSERT_EQ(original_serialization, test_serialization);
@@ -369,6 +370,104 @@
ASSERT_FALSE(root.get());
}
+class JSONFileValueSerializerTest : public testing::Test {
+ protected:
+ virtual void SetUp() OVERRIDE {
+ ASSERT_TRUE(temp_dir_.CreateUniqueTempDir());
+ }
+
+ base::ScopedTempDir temp_dir_;
+};
+
+TEST_F(JSONFileValueSerializerTest, Roundtrip) {
+ base::FilePath original_file_path;
+ ASSERT_TRUE(PathService::Get(DIR_TEST_DATA, &original_file_path));
+ original_file_path =
+ original_file_path.Append(FILE_PATH_LITERAL("serializer_test.json"));
+
+ ASSERT_TRUE(file_util::PathExists(original_file_path));
+
+ JSONFileValueSerializer deserializer(original_file_path);
+ scoped_ptr<Value> root;
+ root.reset(deserializer.Deserialize(NULL, NULL));
+
+ ASSERT_TRUE(root.get());
+ ASSERT_TRUE(root->IsType(Value::TYPE_DICTIONARY));
+
+ DictionaryValue* root_dict = static_cast<DictionaryValue*>(root.get());
+
+ Value* null_value = NULL;
+ ASSERT_TRUE(root_dict->Get("null", &null_value));
+ ASSERT_TRUE(null_value);
+ ASSERT_TRUE(null_value->IsType(Value::TYPE_NULL));
+
+ bool bool_value = false;
+ ASSERT_TRUE(root_dict->GetBoolean("bool", &bool_value));
+ ASSERT_TRUE(bool_value);
+
+ int int_value = 0;
+ ASSERT_TRUE(root_dict->GetInteger("int", &int_value));
+ ASSERT_EQ(42, int_value);
+
+ std::string string_value;
+ ASSERT_TRUE(root_dict->GetString("string", &string_value));
+ ASSERT_EQ("hello", string_value);
+
+ // Now try writing.
+ const base::FilePath written_file_path =
+ temp_dir_.path().Append(FILE_PATH_LITERAL("test_output.js"));
+
+ ASSERT_FALSE(file_util::PathExists(written_file_path));
+ JSONFileValueSerializer serializer(written_file_path);
+ ASSERT_TRUE(serializer.Serialize(*root));
+ ASSERT_TRUE(file_util::PathExists(written_file_path));
+
+ // Now compare file contents.
+ EXPECT_TRUE(file_util::TextContentsEqual(original_file_path,
+ written_file_path));
+ EXPECT_TRUE(file_util::Delete(written_file_path, false));
+}
+
+TEST_F(JSONFileValueSerializerTest, RoundtripNested) {
+ base::FilePath original_file_path;
+ ASSERT_TRUE(PathService::Get(DIR_TEST_DATA, &original_file_path));
+ original_file_path = original_file_path.Append(
+ FILE_PATH_LITERAL("serializer_nested_test.json"));
+
+ ASSERT_TRUE(file_util::PathExists(original_file_path));
+
+ JSONFileValueSerializer deserializer(original_file_path);
+ scoped_ptr<Value> root;
+ root.reset(deserializer.Deserialize(NULL, NULL));
+ ASSERT_TRUE(root.get());
+
+ // Now try writing.
+ base::FilePath written_file_path = temp_dir_.path().Append(
+ FILE_PATH_LITERAL("test_output.json"));
+
+ ASSERT_FALSE(file_util::PathExists(written_file_path));
+ JSONFileValueSerializer serializer(written_file_path);
+ ASSERT_TRUE(serializer.Serialize(*root));
+ ASSERT_TRUE(file_util::PathExists(written_file_path));
+
+ // Now compare file contents.
+ EXPECT_TRUE(file_util::TextContentsEqual(original_file_path,
+ written_file_path));
+ EXPECT_TRUE(file_util::Delete(written_file_path, false));
+}
+
+TEST_F(JSONFileValueSerializerTest, NoWhitespace) {
+ base::FilePath source_file_path;
+ ASSERT_TRUE(PathService::Get(DIR_TEST_DATA, &source_file_path));
+ source_file_path = source_file_path.Append(
+ FILE_PATH_LITERAL("serializer_test_nowhitespace.json"));
+ ASSERT_TRUE(file_util::PathExists(source_file_path));
+ JSONFileValueSerializer serializer(source_file_path);
+ scoped_ptr<Value> root;
+ root.reset(serializer.Deserialize(NULL, NULL));
+ ASSERT_TRUE(root.get());
+}
+
} // namespace
} // namespace base
diff --git a/base/logging.cc b/base/logging.cc
index 462ac8b..0c4a302 100644
--- a/base/logging.cc
+++ b/base/logging.cc
@@ -29,8 +29,8 @@
#if defined(OS_POSIX)
#include <errno.h>
#include <pthread.h>
-#include <stdlib.h>
#include <stdio.h>
+#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#define MAX_PATH PATH_MAX
@@ -50,7 +50,7 @@
#include "base/debug/debugger.h"
#include "base/debug/stack_trace.h"
#include "base/posix/eintr_wrapper.h"
-#include "base/string_piece.h"
+#include "base/strings/string_piece.h"
#include "base/synchronization/lock_impl.h"
#include "base/threading/platform_thread.h"
#include "base/utf_string_conversions.h"
@@ -163,6 +163,8 @@
void DeleteFilePath(const PathString& log_name) {
#if defined(OS_WIN)
DeleteFile(log_name.c_str());
+#elif defined (OS_NACL)
+ // Do nothing; unlink() isn't supported on NaCl.
#else
unlink(log_name.c_str());
#endif
@@ -348,9 +350,11 @@
LogLockingState lock_log,
OldFileDeletionState delete_old,
DcheckState dcheck_state) {
+#if defined(OS_NACL)
+ CHECK(logging_dest == LOG_NONE ||
+ logging_dest == LOG_ONLY_TO_SYSTEM_DEBUG_LOG);
+#endif
g_dcheck_state = dcheck_state;
-// TODO(bbudge) Hook this up to NaCl logging.
-#if !defined(OS_NACL)
CommandLine* command_line = CommandLine::ForCurrentProcess();
// Don't bother initializing g_vlog_info unless we use one of the
// vlog switches.
@@ -393,10 +397,6 @@
DeleteFilePath(*log_file_name);
return InitializeLogFileHandle();
-#else
- (void) g_vlog_info_prev;
- return true;
-#endif // !defined(OS_NACL)
}
void SetMinLogLevel(int level) {
diff --git a/base/logging_unittest.cc b/base/logging_unittest.cc
index 760cc24..10517a5 100644
--- a/base/logging_unittest.cc
+++ b/base/logging_unittest.cc
@@ -65,7 +65,7 @@
// As of g++-4.5, the first argument to EXPECT_EQ cannot be a
// constant expression.
const bool kIsDebugMode = (DEBUG_MODE != 0);
- EXPECT_EQ(kIsDebugMode, DLOG_IS_ON(INFO));
+ EXPECT_TRUE(kIsDebugMode == DLOG_IS_ON(INFO));
EXPECT_TRUE(VLOG_IS_ON(0));
LOG(INFO) << mock_log_source.Log();
@@ -120,7 +120,7 @@
EXPECT_FALSE(LOG_IS_ON(ERROR));
EXPECT_TRUE(LOG_IS_ON(ERROR_REPORT));
EXPECT_TRUE(LOG_IS_ON(FATAL));
- EXPECT_EQ(kDfatalIsFatal, LOG_IS_ON(DFATAL));
+ EXPECT_TRUE(kDfatalIsFatal == LOG_IS_ON(DFATAL));
// LOG_IS_ON(ERROR_REPORT) should always be true.
SetMinLogLevel(LOG_FATAL);
@@ -129,7 +129,7 @@
EXPECT_FALSE(LOG_IS_ON(ERROR));
EXPECT_TRUE(LOG_IS_ON(ERROR_REPORT));
EXPECT_TRUE(LOG_IS_ON(FATAL));
- EXPECT_EQ(kDfatalIsFatal, LOG_IS_ON(DFATAL));
+ EXPECT_TRUE(kDfatalIsFatal == LOG_IS_ON(DFATAL));
// So should LOG_IS_ON(FATAL).
SetMinLogLevel(LOG_FATAL + 1);
@@ -138,7 +138,7 @@
EXPECT_FALSE(LOG_IS_ON(ERROR));
EXPECT_TRUE(LOG_IS_ON(ERROR_REPORT));
EXPECT_TRUE(LOG_IS_ON(FATAL));
- EXPECT_EQ(kDfatalIsFatal, LOG_IS_ON(DFATAL));
+ EXPECT_TRUE(kDfatalIsFatal == LOG_IS_ON(DFATAL));
}
TEST_F(LoggingTest, LoggingIsLazy) {
diff --git a/base/mac/bind_objc_block.h b/base/mac/bind_objc_block.h
index ee1fe12..75da437 100644
--- a/base/mac/bind_objc_block.h
+++ b/base/mac/bind_objc_block.h
@@ -20,21 +20,33 @@
namespace internal {
-// Helper function to run the block contained in the parameter.
-template<typename ReturnType>
-ReturnType RunBlock(base::mac::ScopedBlock<ReturnType(^)()> block) {
- ReturnType(^extracted_block)() = block.get();
+// Helper functions to run the block contained in the parameter.
+template<typename R>
+R RunBlock(base::mac::ScopedBlock<R(^)()> block) {
+ R(^extracted_block)() = block.get();
return extracted_block();
}
+template<typename R, typename A1>
+R RunBlock(base::mac::ScopedBlock<R(^)(A1)> block, A1 a) {
+ R(^extracted_block)(A1) = block.get();
+ return extracted_block(a);
+}
+
} // namespace internal
-// Construct a callback from an objective-C block.
-template<typename ReturnType>
-base::Callback<ReturnType(void)> BindBlock(ReturnType(^block)()) {
- return base::Bind(&base::internal::RunBlock<ReturnType>,
- base::mac::ScopedBlock<ReturnType(^)()>(
- Block_copy(block)));
+// Construct a callback with no argument from an objective-C block.
+template<typename R>
+base::Callback<R(void)> BindBlock(R(^block)()) {
+ return base::Bind(&base::internal::RunBlock<R>,
+ base::mac::ScopedBlock<R(^)()>(Block_copy(block)));
+}
+
+// Construct a callback with one argument from an objective-C block.
+template<typename R, typename A1>
+base::Callback<R(A1)> BindBlock(R(^block)(A1)) {
+ return base::Bind(&base::internal::RunBlock<R, A1>,
+ base::mac::ScopedBlock<R(^)(A1)>(Block_copy(block)));
}
} // namespace base
diff --git a/base/mac/bind_objc_block_unittest.mm b/base/mac/bind_objc_block_unittest.mm
index a44e4c7..888b3dc 100644
--- a/base/mac/bind_objc_block_unittest.mm
+++ b/base/mac/bind_objc_block_unittest.mm
@@ -45,4 +45,10 @@
EXPECT_EQ(kReturnValue, c.Run());
}
+TEST(BindObjcBlockTest, TestArgument) {
+ const int kArgument = 42;
+ base::Callback<int(int)> c = base::BindBlock(^(int a){return a + 1;});
+ EXPECT_EQ(kArgument + 1, c.Run(kArgument));
+}
+
} // namespace
diff --git a/base/mac/foundation_util.h b/base/mac/foundation_util.h
index 0d78c55..447f7bf 100644
--- a/base/mac/foundation_util.h
+++ b/base/mac/foundation_util.h
@@ -28,12 +28,22 @@
#include <ApplicationServices/ApplicationServices.h>
#endif
+// Adapted from NSObjCRuntime.h NS_ENUM definition (used in Foundation starting
+// with the OS X 10.8 SDK and the iOS 6.0 SDK).
+#if __has_extension(cxx_strong_enums) && \
+ (defined(OS_IOS) || (defined(MAC_OS_X_VERSION_10_8) && \
+ MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_8))
+#define CR_FORWARD_ENUM(_type, _name) enum _name : _type _name
+#else
+#define CR_FORWARD_ENUM(_type, _name) _type _name
+#endif
+
// Adapted from NSPathUtilities.h and NSObjCRuntime.h.
#if __LP64__ || NS_BUILD_32_LIKE_64
-typedef unsigned long NSSearchPathDirectory;
+typedef CR_FORWARD_ENUM(unsigned long, NSSearchPathDirectory);
typedef unsigned long NSSearchPathDomainMask;
#else
-typedef unsigned int NSSearchPathDirectory;
+typedef CR_FORWARD_ENUM(unsigned int, NSSearchPathDirectory);
typedef unsigned int NSSearchPathDomainMask;
#endif
diff --git a/base/mac/launch_services_util.cc b/base/mac/launch_services_util.cc
new file mode 100644
index 0000000..c24d864
--- /dev/null
+++ b/base/mac/launch_services_util.cc
@@ -0,0 +1,67 @@
+// Copyright 2013 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/mac/launch_services_util.h"
+
+#include <ApplicationServices/ApplicationServices.h>
+
+#include "base/logging.h"
+#include "base/mac/mac_logging.h"
+#include "base/mac/mac_util.h"
+#include "base/strings/sys_string_conversions.h"
+
+namespace base {
+namespace mac {
+
+bool OpenApplicationWithPath(const base::FilePath& bundle_path,
+ const CommandLine& command_line,
+ ProcessSerialNumber* out_psn) {
+ FSRef app_fsref;
+ if (!base::mac::FSRefFromPath(bundle_path.value(), &app_fsref)) {
+ LOG(ERROR) << "base::mac::FSRefFromPath failed for " << bundle_path.value();
+ return false;
+ }
+
+ std::vector<std::string> argv = command_line.argv();
+ int argc = argv.size();
+ base::mac::ScopedCFTypeRef<CFMutableArrayRef> launch_args(
+ CFArrayCreateMutable(NULL, argc - 1, &kCFTypeArrayCallBacks));
+ if (!launch_args) {
+ LOG(ERROR) << "CFArrayCreateMutable failed, size was " << argc;
+ return false;
+ }
+
+ for (int i = 1; i < argc; ++i) {
+ const std::string& arg(argv[i]);
+
+ base::mac::ScopedCFTypeRef<CFStringRef> arg_cf(
+ base::SysUTF8ToCFStringRef(arg));
+ if (!arg_cf) {
+ LOG(ERROR) << "base::SysUTF8ToCFStringRef failed for " << arg;
+ return false;
+ }
+ CFArrayAppendValue(launch_args, arg_cf);
+ }
+
+ LSApplicationParameters ls_parameters = {
+ 0, // version
+ kLSLaunchDefaults,
+ &app_fsref,
+ NULL, // asyncLaunchRefCon
+ NULL, // environment
+ launch_args,
+ NULL // initialEvent
+ };
+ // TODO(jeremya): this opens a new browser window if Chrome is already
+ // running without any windows open.
+ OSStatus status = LSOpenApplication(&ls_parameters, out_psn);
+ if (status != noErr) {
+ OSSTATUS_LOG(ERROR, status) << "LSOpenApplication";
+ return false;
+ }
+ return true;
+}
+
+} // namespace mac
+} // namespace base
diff --git a/base/mac/launch_services_util.h b/base/mac/launch_services_util.h
new file mode 100644
index 0000000..cd17950
--- /dev/null
+++ b/base/mac/launch_services_util.h
@@ -0,0 +1,29 @@
+// Copyright (c) 2013 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 BASE_MAC_LAUNCH_SERVICES_UTIL_H_
+#define BASE_MAC_LAUNCH_SERVICES_UTIL_H_
+
+#include "base/base_export.h"
+#include "base/command_line.h"
+#include "base/files/file_path.h"
+
+struct ProcessSerialNumber;
+
+namespace base {
+namespace mac {
+
+// Launches the application bundle at |bundle_path|, passing argv[1..] from
+// |command_line| as command line arguments if the app isn't already running.
+// |out_psn|, if not NULL, will be set to the process serial number of the
+// application's main process if the app was successfully launched.
+// Returns true if the app was successfully launched.
+BASE_EXPORT bool OpenApplicationWithPath(const base::FilePath& bundle_path,
+ const CommandLine& command_line,
+ ProcessSerialNumber* out_psn);
+
+} // namespace mac
+} // namespace base
+
+#endif // BASE_MAC_LAUNCH_SERVICES_UTIL_H_
diff --git a/base/mac/mac_util.mm b/base/mac/mac_util.mm
index d3594a4..f758b52 100644
--- a/base/mac/mac_util.mm
+++ b/base/mac/mac_util.mm
@@ -20,13 +20,23 @@
#include "base/mac/scoped_cftyperef.h"
#include "base/memory/scoped_generic_obj.h"
#include "base/memory/scoped_nsobject.h"
-#include "base/string_piece.h"
#include "base/strings/string_number_conversions.h"
+#include "base/strings/string_piece.h"
#include "base/strings/sys_string_conversions.h"
namespace base {
namespace mac {
+// Replicate specific 10.7 SDK declarations for building with prior SDKs.
+#if !defined(MAC_OS_X_VERSION_10_7) || \
+ MAC_OS_X_VERSION_MAX_ALLOWED < MAC_OS_X_VERSION_10_7
+
+enum {
+ NSApplicationPresentationFullScreen = 1 << 10
+};
+
+#endif // MAC_OS_X_VERSION_10_7
+
namespace {
// The current count of outstanding requests for full screen mode from browser
@@ -60,6 +70,19 @@
NSApplicationPresentationHideMenuBar;
}
+ // Mac OS X bug: if the window is fullscreened (Lion-style) and
+ // NSApplicationPresentationDefault is requested, the result is that the menu
+ // bar doesn't auto-hide. rdar://13576498 http://www.openradar.me/13576498
+ //
+ // As a workaround, in that case, explicitly set the presentation options to
+ // the ones that are set by the system as it fullscreens a window.
+ if (desired_options == NSApplicationPresentationDefault &&
+ current_options & NSApplicationPresentationFullScreen) {
+ desired_options |= NSApplicationPresentationFullScreen |
+ NSApplicationPresentationAutoHideMenuBar |
+ NSApplicationPresentationAutoHideDock;
+ }
+
if (current_options != desired_options)
[NSApp setPresentationOptions:desired_options];
}
@@ -157,6 +180,9 @@
return;
DCHECK_GE(g_full_screen_requests[mode], 0);
+ if (mode < 0)
+ return;
+
g_full_screen_requests[mode] = std::max(g_full_screen_requests[mode] + 1, 1);
SetUIMode();
}
@@ -167,7 +193,10 @@
if (mode >= kNumFullScreenModes)
return;
- DCHECK_GT(g_full_screen_requests[mode], 0);
+ DCHECK_GE(g_full_screen_requests[mode], 0);
+ if (mode < 0)
+ return;
+
g_full_screen_requests[mode] = std::max(g_full_screen_requests[mode] - 1, 0);
SetUIMode();
}
diff --git a/base/mac/scoped_mach_port.cc b/base/mac/scoped_mach_port.cc
index 652e3f4..9e45a85 100644
--- a/base/mac/scoped_mach_port.cc
+++ b/base/mac/scoped_mach_port.cc
@@ -11,9 +11,14 @@
}
ScopedMachPort::~ScopedMachPort() {
+ reset();
+}
+
+void ScopedMachPort::reset(mach_port_t port) {
if (port_ != MACH_PORT_NULL) {
mach_port_deallocate(mach_task_self(), port_);
}
+ port_ = port;
}
} // namespace mac
diff --git a/base/mac/scoped_mach_port.h b/base/mac/scoped_mach_port.h
index d2aa2f7..cc2ef20 100644
--- a/base/mac/scoped_mach_port.h
+++ b/base/mac/scoped_mach_port.h
@@ -22,6 +22,8 @@
~ScopedMachPort();
+ void reset(mach_port_t port = MACH_PORT_NULL);
+
operator mach_port_t() const {
return port_;
}
diff --git a/base/mach_ipc_mac.h b/base/mach_ipc_mac.h
deleted file mode 100644
index 7f5f7d6..0000000
--- a/base/mach_ipc_mac.h
+++ /dev/null
@@ -1,328 +0,0 @@
-// Copyright (c) 2012 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 BASE_MACH_IPC_MAC_H_
-#define BASE_MACH_IPC_MAC_H_
-
-#include <mach/mach.h>
-#include <mach/message.h>
-#include <servers/bootstrap.h>
-#include <sys/types.h>
-
-#include <CoreServices/CoreServices.h>
-
-#include "base/base_export.h"
-#include "base/basictypes.h"
-
-//==============================================================================
-// DISCUSSION:
-//
-// The three main classes of interest are
-//
-// MachMessage: a wrapper for a Mach message of the following form
-// mach_msg_header_t
-// mach_msg_body_t
-// optional descriptors
-// optional extra message data
-//
-// MachReceiveMessage and MachSendMessage subclass MachMessage
-// and are used instead of MachMessage which is an abstract base class
-//
-// ReceivePort:
-// Represents a Mach port for which we have receive rights
-//
-// MachPortSender:
-// Represents a Mach port for which we have send rights
-//
-// Here's an example to receive a message on a server port:
-//
-// // This creates our named server port
-// ReceivePort receivePort("com.Google.MyService");
-//
-// MachReceiveMessage message;
-// kern_return_t result = receivePort.WaitForMessage(&message, 0);
-//
-// if (result == KERN_SUCCESS && message.GetMessageID() == 57) {
-// mach_port_t task = message.GetTranslatedPort(0);
-// mach_port_t thread = message.GetTranslatedPort(1);
-//
-// char *messageString = message.GetData();
-//
-// printf("message string = %s\n", messageString);
-// }
-//
-// Here is an example of using these classes to send a message to this port:
-//
-// // send to already named port
-// MachPortSender sender("com.Google.MyService");
-// MachSendMessage message(57); // our message ID is 57
-//
-// // add some ports to be translated for us
-// message.AddDescriptor(mach_task_self()); // our task
-// message.AddDescriptor(mach_thread_self()); // this thread
-//
-// char messageString[] = "Hello server!\n";
-// message.SetData(messageString, strlen(messageString)+1);
-// // timeout 1000ms
-// kern_return_t result = sender.SendMessage(message, 1000);
-//
-
-#define PRINT_MACH_RESULT(result_, message_) \
- printf(message_" %s (%d)\n", mach_error_string(result_), result_ );
-
-namespace base {
-
-//==============================================================================
-// A wrapper class for mach_msg_port_descriptor_t (with same memory layout)
-// with convenient constructors and accessors
-class MachMsgPortDescriptor : public mach_msg_port_descriptor_t {
- public:
- // General-purpose constructor
- MachMsgPortDescriptor(mach_port_t in_name,
- mach_msg_type_name_t in_disposition) {
- name = in_name;
- pad1 = 0;
- pad2 = 0;
- disposition = in_disposition;
- type = MACH_MSG_PORT_DESCRIPTOR;
- }
-
- // For passing send rights to a port
- MachMsgPortDescriptor(mach_port_t in_name) {
- name = in_name;
- pad1 = 0;
- pad2 = 0;
- disposition = MACH_MSG_TYPE_PORT_SEND;
- type = MACH_MSG_PORT_DESCRIPTOR;
- }
-
- // Copy constructor
- MachMsgPortDescriptor(const MachMsgPortDescriptor& desc) {
- name = desc.name;
- pad1 = desc.pad1;
- pad2 = desc.pad2;
- disposition = desc.disposition;
- type = desc.type;
- }
-
- mach_port_t GetMachPort() const {
- return name;
- }
-
- mach_msg_type_name_t GetDisposition() const {
- return disposition;
- }
-
- // For convenience
- operator mach_port_t() const {
- return GetMachPort();
- }
-};
-
-//==============================================================================
-// MachMessage: a wrapper for a Mach message
-// (mach_msg_header_t, mach_msg_body_t, extra data)
-//
-// This considerably simplifies the construction of a message for sending
-// and the getting at relevant data and descriptors for the receiver.
-//
-// This class can be initialized using external storage of an arbitrary size
-// or it can manage storage internally.
-// 1. If storage is allocated internally, the combined size of the descriptors
-// plus data must be less than 1024. But as a benefit no memory allocation is
-// necessary.
-// 2. For external storage, a buffer of at least EmptyMessageSize() must be
-// provided.
-//
-// A MachMessage object is used by ReceivePort::WaitForMessage
-// and MachPortSender::SendMessage
-//
-class BASE_EXPORT MachMessage {
- public:
- static const size_t kEmptyMessageSize;
-
- virtual ~MachMessage();
-
- // The receiver of the message can retrieve the raw data this way
- u_int8_t *GetData() const {
- return GetDataLength() > 0 ? GetDataPacket()->data : NULL;
- }
-
- u_int32_t GetDataLength() const {
- return EndianU32_LtoN(GetDataPacket()->data_length);
- }
-
- // The message ID may be used as a code identifying the type of message
- void SetMessageID(int32_t message_id) {
- GetDataPacket()->id = EndianU32_NtoL(message_id);
- }
-
- int32_t GetMessageID() const { return EndianU32_LtoN(GetDataPacket()->id); }
-
- // Adds a descriptor (typically a Mach port) to be translated
- // returns true if successful, otherwise not enough space
- bool AddDescriptor(const MachMsgPortDescriptor &desc);
-
- int GetDescriptorCount() const {
- return storage_->body.msgh_descriptor_count;
- }
-
- MachMsgPortDescriptor *GetDescriptor(int n) const;
-
- // Convenience method which gets the Mach port described by the descriptor
- mach_port_t GetTranslatedPort(int n) const;
-
- // A simple message is one with no descriptors
- bool IsSimpleMessage() const { return GetDescriptorCount() == 0; }
-
- // Sets raw data for the message (returns false if not enough space)
- bool SetData(const void* data, int32_t data_length);
-
- protected:
- // Consider this an abstract base class - must create an actual instance
- // of MachReceiveMessage or MachSendMessage
- MachMessage();
-
- // Constructor for use with preallocate storage.
- // storage_length must be >= EmptyMessageSize()
- MachMessage(void *storage, size_t storage_length);
-
- friend class ReceivePort;
- friend class MachPortSender;
-
- // Represents raw data in our message
- struct MessageDataPacket {
- int32_t id; // little-endian
- int32_t data_length; // little-endian
- u_int8_t data[1]; // actual size limited by storage_length_bytes_
- };
-
- MessageDataPacket* GetDataPacket() const;
-
- void SetDescriptorCount(int n);
- void SetDescriptor(int n, const MachMsgPortDescriptor &desc);
-
- // Returns total message size setting msgh_size in the header to this value
- int CalculateSize();
-
- // Returns total storage size that this object can grow to, this is inclusive
- // of the Mach header.
- size_t MaxSize() const { return storage_length_bytes_; }
-
- mach_msg_header_t *Head() const { return &(storage_->head); }
-
- private:
- struct MachMessageData {
- mach_msg_header_t head;
- mach_msg_body_t body;
- // descriptors and data may be embedded here.
- u_int8_t padding[1024];
- };
-
- MachMessageData *storage_;
- size_t storage_length_bytes_;
- bool own_storage_; // Is storage owned by this object?
-};
-
-//==============================================================================
-// MachReceiveMessage and MachSendMessage are useful to separate the idea
-// of a Mach message being sent and being received, and adds increased type
-// safety:
-// ReceivePort::WaitForMessage() only accepts a MachReceiveMessage
-// MachPortSender::SendMessage() only accepts a MachSendMessage
-
-//==============================================================================
-class MachReceiveMessage : public MachMessage {
- public:
- MachReceiveMessage() : MachMessage() {}
- MachReceiveMessage(void *storage, size_t storage_length)
- : MachMessage(storage, storage_length) {}
-
- private:
- DISALLOW_COPY_AND_ASSIGN(MachReceiveMessage);
-};
-
-//==============================================================================
-class BASE_EXPORT MachSendMessage : public MachMessage {
- public:
- explicit MachSendMessage(int32_t message_id);
- MachSendMessage(void *storage, size_t storage_length, int32_t message_id);
-
- private:
- void Initialize(int32_t message_id);
-
- DISALLOW_COPY_AND_ASSIGN(MachSendMessage);
-};
-
-//==============================================================================
-// Represents a Mach port for which we have receive rights
-class BASE_EXPORT ReceivePort {
- public:
- // Creates a new Mach port for receiving messages and registers a name for it
- explicit ReceivePort(const char *receive_port_name);
-
- // Given an already existing Mach port, use it. We take ownership of the
- // port and deallocate it in our destructor.
- explicit ReceivePort(mach_port_t receive_port);
-
- // Create a new Mach port for receiving messages
- ReceivePort();
-
- ~ReceivePort();
-
- // Waits on the Mach port until message received or timeout. If |timeout| is
- // MACH_MSG_TIMEOUT_NONE, this method waits forever.
- kern_return_t WaitForMessage(MachReceiveMessage *out_message,
- mach_msg_timeout_t timeout);
-
- // The underlying Mach port that we wrap
- mach_port_t GetPort() const { return port_; }
-
- private:
- mach_port_t port_;
- kern_return_t init_result_;
-
- DISALLOW_COPY_AND_ASSIGN(ReceivePort);
-};
-
-//==============================================================================
-// Represents a Mach port for which we have send rights
-class BASE_EXPORT MachPortSender {
- public:
- // get a port with send rights corresponding to a named registered service
- explicit MachPortSender(const char *receive_port_name);
-
-
- // Given an already existing Mach port, use it. Does not take ownership of
- // |send_port|.
- explicit MachPortSender(mach_port_t send_port);
-
- kern_return_t SendMessage(const MachSendMessage& message,
- mach_msg_timeout_t timeout);
-
- mach_port_t GetPort() const { return send_port_; }
-
- private:
- mach_port_t send_port_;
- kern_return_t init_result_;
-
- DISALLOW_COPY_AND_ASSIGN(MachPortSender);
-};
-
-//==============================================================================
-// Static utility functions.
-
-namespace mac {
-
-// Returns the number of Mach ports to which the given task has a right.
-// Note that unless the calling task has send rights to the passed task port,
-// this will fail unless the calling task is running as root.
-kern_return_t BASE_EXPORT GetNumberOfMachPorts(mach_port_t task_port,
- int* port_count);
-
-} // namespace mac
-
-} // namespace base
-
-#endif // BASE_MACH_IPC_MAC_H_
diff --git a/base/mach_ipc_mac.mm b/base/mach_ipc_mac.mm
deleted file mode 100644
index 6f2575e..0000000
--- a/base/mach_ipc_mac.mm
+++ /dev/null
@@ -1,358 +0,0 @@
-// Copyright (c) 2012 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/mach_ipc_mac.h"
-
-#import <Foundation/Foundation.h>
-#include <mach/vm_map.h>
-
-#include <stdio.h>
-#include "base/logging.h"
-
-namespace base {
-
-// static
-const size_t MachMessage::kEmptyMessageSize = sizeof(mach_msg_header_t) +
- sizeof(mach_msg_body_t) + sizeof(MessageDataPacket);
-
-//==============================================================================
-MachSendMessage::MachSendMessage(int32_t message_id) : MachMessage() {
- Initialize(message_id);
-}
-
-MachSendMessage::MachSendMessage(void *storage, size_t storage_length,
- int32_t message_id)
- : MachMessage(storage, storage_length) {
- Initialize(message_id);
-}
-
-void MachSendMessage::Initialize(int32_t message_id) {
- Head()->msgh_bits = MACH_MSGH_BITS(MACH_MSG_TYPE_COPY_SEND, 0);
-
- // head.msgh_remote_port = ...; // filled out in MachPortSender::SendMessage()
- Head()->msgh_local_port = MACH_PORT_NULL;
- Head()->msgh_reserved = 0;
- Head()->msgh_id = 0;
-
- SetDescriptorCount(0); // start out with no descriptors
-
- SetMessageID(message_id);
- SetData(NULL, 0); // client may add data later
-}
-
-//==============================================================================
-MachMessage::MachMessage()
- : storage_(new MachMessageData), // Allocate storage_ ourselves
- storage_length_bytes_(sizeof(MachMessageData)),
- own_storage_(true) {
- memset(storage_, 0, storage_length_bytes_);
-}
-
-//==============================================================================
-MachMessage::MachMessage(void *storage, size_t storage_length)
- : storage_(static_cast<MachMessageData*>(storage)),
- storage_length_bytes_(storage_length),
- own_storage_(false) {
- DCHECK(storage);
- DCHECK_GE(storage_length, kEmptyMessageSize);
-}
-
-//==============================================================================
-MachMessage::~MachMessage() {
- if (own_storage_) {
- delete storage_;
- storage_ = NULL;
- }
-}
-
-//==============================================================================
-// returns true if successful
-bool MachMessage::SetData(const void* data,
- int32_t data_length) {
- // Enforce the fact that it's only safe to call this method once on a
- // message.
- DCHECK(GetDataPacket()->data_length == 0);
-
- // first check to make sure we have enough space
- int size = CalculateSize();
- int new_size = size + data_length;
-
- if ((unsigned)new_size > storage_length_bytes_) {
- return false; // not enough space
- }
-
- GetDataPacket()->data_length = EndianU32_NtoL(data_length);
- if (data) memcpy(GetDataPacket()->data, data, data_length);
-
- // Update the Mach header with the new aligned size of the message.
- CalculateSize();
-
- return true;
-}
-
-//==============================================================================
-// calculates and returns the total size of the message
-// Currently, the entire message MUST fit inside of the MachMessage
-// messsage size <= EmptyMessageSize()
-int MachMessage::CalculateSize() {
- int size = sizeof(mach_msg_header_t) + sizeof(mach_msg_body_t);
-
- // add space for MessageDataPacket
- int32_t alignedDataLength = (GetDataLength() + 3) & ~0x3;
- size += 2*sizeof(int32_t) + alignedDataLength;
-
- // add space for descriptors
- size += GetDescriptorCount() * sizeof(MachMsgPortDescriptor);
-
- Head()->msgh_size = size;
-
- return size;
-}
-
-//==============================================================================
-MachMessage::MessageDataPacket *MachMessage::GetDataPacket() const {
- int desc_size = sizeof(MachMsgPortDescriptor)*GetDescriptorCount();
- MessageDataPacket *packet =
- reinterpret_cast<MessageDataPacket*>(storage_->padding + desc_size);
-
- return packet;
-}
-
-//==============================================================================
-void MachMessage::SetDescriptor(int n,
- const MachMsgPortDescriptor &desc) {
- MachMsgPortDescriptor *desc_array =
- reinterpret_cast<MachMsgPortDescriptor*>(storage_->padding);
- desc_array[n] = desc;
-}
-
-//==============================================================================
-// returns true if successful otherwise there was not enough space
-bool MachMessage::AddDescriptor(const MachMsgPortDescriptor &desc) {
- // first check to make sure we have enough space
- int size = CalculateSize();
- int new_size = size + sizeof(MachMsgPortDescriptor);
-
- if ((unsigned)new_size > storage_length_bytes_) {
- return false; // not enough space
- }
-
- // unfortunately, we need to move the data to allow space for the
- // new descriptor
- u_int8_t *p = reinterpret_cast<u_int8_t*>(GetDataPacket());
- bcopy(p, p+sizeof(MachMsgPortDescriptor), GetDataLength()+2*sizeof(int32_t));
-
- SetDescriptor(GetDescriptorCount(), desc);
- SetDescriptorCount(GetDescriptorCount() + 1);
-
- CalculateSize();
-
- return true;
-}
-
-//==============================================================================
-void MachMessage::SetDescriptorCount(int n) {
- storage_->body.msgh_descriptor_count = n;
-
- if (n > 0) {
- Head()->msgh_bits |= MACH_MSGH_BITS_COMPLEX;
- } else {
- Head()->msgh_bits &= ~MACH_MSGH_BITS_COMPLEX;
- }
-}
-
-//==============================================================================
-MachMsgPortDescriptor *MachMessage::GetDescriptor(int n) const {
- if (n < GetDescriptorCount()) {
- MachMsgPortDescriptor *desc =
- reinterpret_cast<MachMsgPortDescriptor*>(storage_->padding);
- return desc + n;
- }
-
- return nil;
-}
-
-//==============================================================================
-mach_port_t MachMessage::GetTranslatedPort(int n) const {
- if (n < GetDescriptorCount()) {
- return GetDescriptor(n)->GetMachPort();
- }
- return MACH_PORT_NULL;
-}
-
-#pragma mark -
-
-//==============================================================================
-// create a new mach port for receiving messages and register a name for it
-ReceivePort::ReceivePort(const char *receive_port_name) {
- mach_port_t current_task = mach_task_self();
-
- init_result_ = mach_port_allocate(current_task,
- MACH_PORT_RIGHT_RECEIVE,
- &port_);
-
- if (init_result_ != KERN_SUCCESS)
- return;
-
- init_result_ = mach_port_insert_right(current_task,
- port_,
- port_,
- MACH_MSG_TYPE_MAKE_SEND);
-
- if (init_result_ != KERN_SUCCESS)
- return;
-
- // Without |NSMachPortDeallocateNone|, the NSMachPort seems to deallocate
- // receive rights on port when it is eventually released. It is not necessary
- // to deallocate any rights here as |port_| is fully deallocated in the
- // ReceivePort destructor.
- NSPort *ns_port = [NSMachPort portWithMachPort:port_
- options:NSMachPortDeallocateNone];
- NSString *port_name = [NSString stringWithUTF8String:receive_port_name];
- [[NSMachBootstrapServer sharedInstance] registerPort:ns_port name:port_name];
-}
-
-//==============================================================================
-// create a new mach port for receiving messages
-ReceivePort::ReceivePort() {
- mach_port_t current_task = mach_task_self();
-
- init_result_ = mach_port_allocate(current_task,
- MACH_PORT_RIGHT_RECEIVE,
- &port_);
-
- if (init_result_ != KERN_SUCCESS)
- return;
-
- init_result_ = mach_port_insert_right(current_task,
- port_,
- port_,
- MACH_MSG_TYPE_MAKE_SEND);
-}
-
-//==============================================================================
-// Given an already existing mach port, use it. We take ownership of the
-// port and deallocate it in our destructor.
-ReceivePort::ReceivePort(mach_port_t receive_port)
- : port_(receive_port),
- init_result_(KERN_SUCCESS) {
-}
-
-//==============================================================================
-ReceivePort::~ReceivePort() {
- if (init_result_ == KERN_SUCCESS)
- mach_port_deallocate(mach_task_self(), port_);
-}
-
-//==============================================================================
-kern_return_t ReceivePort::WaitForMessage(MachReceiveMessage *out_message,
- mach_msg_timeout_t timeout) {
- if (!out_message) {
- return KERN_INVALID_ARGUMENT;
- }
-
- // return any error condition encountered in constructor
- if (init_result_ != KERN_SUCCESS)
- return init_result_;
-
- out_message->Head()->msgh_bits = 0;
- out_message->Head()->msgh_local_port = port_;
- out_message->Head()->msgh_remote_port = MACH_PORT_NULL;
- out_message->Head()->msgh_reserved = 0;
- out_message->Head()->msgh_id = 0;
-
- mach_msg_option_t rcv_options = MACH_RCV_MSG;
- if (timeout != MACH_MSG_TIMEOUT_NONE)
- rcv_options |= MACH_RCV_TIMEOUT;
-
- kern_return_t result = mach_msg(out_message->Head(),
- rcv_options,
- 0,
- out_message->MaxSize(),
- port_,
- timeout, // timeout in ms
- MACH_PORT_NULL);
-
- return result;
-}
-
-#pragma mark -
-
-//==============================================================================
-// get a port with send rights corresponding to a named registered service
-MachPortSender::MachPortSender(const char *receive_port_name) {
- mach_port_t bootstrap_port = 0;
- init_result_ = task_get_bootstrap_port(mach_task_self(), &bootstrap_port);
-
- if (init_result_ != KERN_SUCCESS)
- return;
-
- init_result_ = bootstrap_look_up(bootstrap_port,
- const_cast<char*>(receive_port_name),
- &send_port_);
-}
-
-//==============================================================================
-MachPortSender::MachPortSender(mach_port_t send_port)
- : send_port_(send_port),
- init_result_(KERN_SUCCESS) {
-}
-
-//==============================================================================
-kern_return_t MachPortSender::SendMessage(const MachSendMessage& message,
- mach_msg_timeout_t timeout) {
- if (message.Head()->msgh_size == 0) {
- NOTREACHED();
- return KERN_INVALID_VALUE; // just for safety -- never should occur
- };
-
- if (init_result_ != KERN_SUCCESS)
- return init_result_;
-
- message.Head()->msgh_remote_port = send_port_;
-
- kern_return_t result = mach_msg(message.Head(),
- MACH_SEND_MSG | MACH_SEND_TIMEOUT,
- message.Head()->msgh_size,
- 0,
- MACH_PORT_NULL,
- timeout, // timeout in ms
- MACH_PORT_NULL);
-
- return result;
-}
-
-//==============================================================================
-
-namespace mac {
-
-kern_return_t GetNumberOfMachPorts(mach_port_t task_port, int* num_ports) {
- mach_port_name_array_t names;
- mach_msg_type_number_t names_count;
- mach_port_type_array_t types;
- mach_msg_type_number_t types_count;
-
- // A friendlier interface would allow NULL buffers to only get the counts.
- kern_return_t kr = mach_port_names(task_port, &names, &names_count,
- &types, &types_count);
- if (kr != KERN_SUCCESS)
- return kr;
-
- // The documentation states this is an invariant.
- DCHECK_EQ(names_count, types_count);
- *num_ports = names_count;
-
- kr = vm_deallocate(mach_task_self(),
- reinterpret_cast<vm_address_t>(names),
- names_count * sizeof(mach_port_name_array_t));
- kr = vm_deallocate(mach_task_self(),
- reinterpret_cast<vm_address_t>(types),
- types_count * sizeof(mach_port_type_array_t));
-
- return kr;
-}
-
-} // namespace mac
-
-} // namespace base
diff --git a/base/md5.h b/base/md5.h
index 4a29a2d..fba02bd 100644
--- a/base/md5.h
+++ b/base/md5.h
@@ -6,7 +6,7 @@
#define BASE_MD5_H_
#include "base/base_export.h"
-#include "base/string_piece.h"
+#include "base/strings/string_piece.h"
namespace base {
diff --git a/base/memory/ref_counted_unittest.cc b/base/memory/ref_counted_unittest.cc
index 8ddd5be..e8eb0fd 100644
--- a/base/memory/ref_counted_unittest.cc
+++ b/base/memory/ref_counted_unittest.cc
@@ -24,9 +24,7 @@
class ScopedRefPtrToSelf : public base::RefCounted<ScopedRefPtrToSelf> {
public:
- ScopedRefPtrToSelf()
- : ALLOW_THIS_IN_INITIALIZER_LIST(self_ptr_(this)) {
- }
+ ScopedRefPtrToSelf() : self_ptr_(this) {}
static bool was_destroyed() { return was_destroyed_; }
diff --git a/base/memory/scoped_ptr.h b/base/memory/scoped_ptr.h
index 7098e14..5edde8f 100644
--- a/base/memory/scoped_ptr.h
+++ b/base/memory/scoped_ptr.h
@@ -7,7 +7,7 @@
// end of a scope. There are two main classes you will use, which correspond
// to the operators new/delete and new[]/delete[].
//
-// Example usage (scoped_ptr):
+// Example usage (scoped_ptr<T>):
// {
// scoped_ptr<Foo> foo(new Foo("wee"));
// } // foo goes out of scope, releasing the pointer with it.
@@ -26,9 +26,9 @@
// // manages a pointer.
// } // foo wasn't managing a pointer, so nothing was destroyed.
//
-// Example usage (scoped_array):
+// Example usage (scoped_ptr<T[]>):
// {
-// scoped_array<Foo> foo(new Foo[100]);
+// scoped_ptr<Foo[]> foo(new Foo[100]);
// foo.get()->Method(); // Foo::Method on the 0th element.
// foo[10].Method(); // Foo::Method on the 10th element.
// }
@@ -81,15 +81,14 @@
// return result.PassAs<Foo>();
// }
//
-// Note that PassAs<>() is implemented only for scoped_ptr, but not for
-// scoped_array. This is because casting array pointers may not be safe.
+// Note that PassAs<>() is implemented only for scoped_ptr<T>, but not for
+// scoped_ptr<T[]>. This is because casting array pointers may not be safe.
#ifndef BASE_MEMORY_SCOPED_PTR_H_
#define BASE_MEMORY_SCOPED_PTR_H_
// This is an implementation designed to match the anticipated future TR2
-// implementation of the scoped_ptr class, and its closely-related brethren,
-// scoped_array, scoped_ptr_malloc.
+// implementation of the scoped_ptr class and scoped_ptr_malloc (deprecated).
#include <assert.h>
#include <stddef.h>
@@ -563,127 +562,6 @@
return p1 != p2.get();
}
-// DEPRECATED: Use scoped_ptr<C[]> instead.
-//
-// scoped_array<C> is like scoped_ptr<C>, except that the caller must allocate
-// with new [] and the destructor deletes objects with delete [].
-//
-// As with scoped_ptr<C>, a scoped_array<C> either points to an object
-// or is NULL. A scoped_array<C> owns the object that it points to.
-// scoped_array<T> is thread-compatible, and once you index into it,
-// the returned objects have only the thread safety guarantees of T.
-//
-// Size: sizeof(scoped_array<C>) == sizeof(C*)
-template <class C>
-class scoped_array {
- MOVE_ONLY_TYPE_FOR_CPP_03(scoped_array, RValue)
-
- public:
-
- // The element type
- typedef C element_type;
-
- // Constructor. Defaults to initializing with NULL.
- // There is no way to create an uninitialized scoped_array.
- // The input parameter must be allocated with new [].
- explicit scoped_array(C* p = NULL) : array_(p) { }
-
- // Constructor. Move constructor for C++03 move emulation of this type.
- scoped_array(RValue rvalue)
- : array_(rvalue.object->release()) {
- }
-
- // Destructor. If there is a C object, delete it.
- // We don't need to test ptr_ == NULL because C++ does that for us.
- ~scoped_array() {
- enum { type_must_be_complete = sizeof(C) };
- delete[] array_;
- }
-
- // operator=. Move operator= for C++03 move emulation of this type.
- scoped_array& operator=(RValue rhs) {
- reset(rhs.object->release());
- return *this;
- }
-
- // Reset. Deletes the current owned object, if any.
- // Then takes ownership of a new object, if given.
- // this->reset(this->get()) works.
- void reset(C* p = NULL) {
- if (p != array_) {
- enum { type_must_be_complete = sizeof(C) };
- delete[] array_;
- array_ = p;
- }
- }
-
- // Get one element of the current object.
- // Will assert() if there is no current object, or index i is negative.
- C& operator[](ptrdiff_t i) const {
- assert(i >= 0);
- assert(array_ != NULL);
- return array_[i];
- }
-
- // Get a pointer to the zeroth element of the current object.
- // If there is no current object, return NULL.
- C* get() const {
- return array_;
- }
-
- // Allow scoped_array<C> to be used in boolean expressions, but not
- // implicitly convertible to a real bool (which is dangerous).
- typedef C* scoped_array::*Testable;
- operator Testable() const { return array_ ? &scoped_array::array_ : NULL; }
-
- // Comparison operators.
- // These return whether two scoped_array refer to the same object, not just to
- // two different but equal objects.
- bool operator==(C* p) const { return array_ == p; }
- bool operator!=(C* p) const { return array_ != p; }
-
- // Swap two scoped arrays.
- void swap(scoped_array& p2) {
- C* tmp = array_;
- array_ = p2.array_;
- p2.array_ = tmp;
- }
-
- // Release an array.
- // The return value is the current pointer held by this object.
- // If this object holds a NULL pointer, the return value is NULL.
- // After this operation, this object will hold a NULL pointer,
- // and will not own the object any more.
- C* release() WARN_UNUSED_RESULT {
- C* retVal = array_;
- array_ = NULL;
- return retVal;
- }
-
- private:
- C* array_;
-
- // Forbid comparison of different scoped_array types.
- template <class C2> bool operator==(scoped_array<C2> const& p2) const;
- template <class C2> bool operator!=(scoped_array<C2> const& p2) const;
-};
-
-// Free functions
-template <class C>
-void swap(scoped_array<C>& p1, scoped_array<C>& p2) {
- p1.swap(p2);
-}
-
-template <class C>
-bool operator==(C* p1, const scoped_array<C>& p2) {
- return p1 == p2.get();
-}
-
-template <class C>
-bool operator!=(C* p1, const scoped_array<C>& p2) {
- return p1 != p2.get();
-}
-
// DEPRECATED: Use scoped_ptr<C, base::FreeDeleter> instead.
//
// scoped_ptr_malloc<> is similar to scoped_ptr<>, but it accepts a
diff --git a/base/memory/scoped_ptr_unittest.cc b/base/memory/scoped_ptr_unittest.cc
index 59b3e1c..22da53d 100644
--- a/base/memory/scoped_ptr_unittest.cc
+++ b/base/memory/scoped_ptr_unittest.cc
@@ -378,82 +378,6 @@
EXPECT_EQ(0, constructed);
}
-TEST(ScopedPtrTest, ScopedArray) {
- static const int kNumLoggers = 12;
-
- int constructed = 0;
-
- {
- scoped_array<ConDecLogger> scoper(new ConDecLogger[kNumLoggers]);
- EXPECT_TRUE(scoper.get());
- EXPECT_EQ(&scoper[0], scoper.get());
- for (int i = 0; i < kNumLoggers; ++i) {
- scoper[i].SetPtr(&constructed);
- }
- EXPECT_EQ(12, constructed);
-
- EXPECT_EQ(10, scoper.get()->SomeMeth(10));
- EXPECT_EQ(10, scoper[2].SomeMeth(10));
- }
- EXPECT_EQ(0, constructed);
-
- // Test reset() and release()
- {
- scoped_array<ConDecLogger> scoper;
- EXPECT_FALSE(scoper.get());
- EXPECT_FALSE(scoper.release());
- EXPECT_FALSE(scoper.get());
- scoper.reset();
- EXPECT_FALSE(scoper.get());
-
- scoper.reset(new ConDecLogger[kNumLoggers]);
- for (int i = 0; i < kNumLoggers; ++i) {
- scoper[i].SetPtr(&constructed);
- }
- EXPECT_EQ(12, constructed);
- scoper.reset();
- EXPECT_EQ(0, constructed);
-
- scoper.reset(new ConDecLogger[kNumLoggers]);
- for (int i = 0; i < kNumLoggers; ++i) {
- scoper[i].SetPtr(&constructed);
- }
- EXPECT_EQ(12, constructed);
- ConDecLogger* ptr = scoper.release();
- EXPECT_EQ(12, constructed);
- delete[] ptr;
- EXPECT_EQ(0, constructed);
- }
- EXPECT_EQ(0, constructed);
-
- // Test swap(), ==, !=, and type-safe Boolean.
- {
- scoped_array<ConDecLogger> scoper1;
- scoped_array<ConDecLogger> scoper2;
- EXPECT_TRUE(scoper1 == scoper2.get());
- EXPECT_FALSE(scoper1 != scoper2.get());
-
- ConDecLogger* loggers = new ConDecLogger[kNumLoggers];
- for (int i = 0; i < kNumLoggers; ++i) {
- loggers[i].SetPtr(&constructed);
- }
- scoper1.reset(loggers);
- EXPECT_TRUE(scoper1);
- EXPECT_EQ(loggers, scoper1.get());
- EXPECT_FALSE(scoper2);
- EXPECT_FALSE(scoper2.get());
- EXPECT_FALSE(scoper1 == scoper2.get());
- EXPECT_TRUE(scoper1 != scoper2.get());
-
- scoper2.swap(scoper1);
- EXPECT_EQ(loggers, scoper2.get());
- EXPECT_FALSE(scoper1.get());
- EXPECT_FALSE(scoper1 == scoper2.get());
- EXPECT_TRUE(scoper1 != scoper2.get());
- }
- EXPECT_EQ(0, constructed);
-}
-
TEST(ScopedPtrTest, PassBehavior) {
int constructed = 0;
{
diff --git a/base/memory/shared_memory.h b/base/memory/shared_memory.h
new file mode 100644
index 0000000..0e90c6e
--- /dev/null
+++ b/base/memory/shared_memory.h
@@ -0,0 +1,278 @@
+// Copyright (c) 2012 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 BASE_MEMORY_SHARED_MEMORY_H_
+#define BASE_MEMORY_SHARED_MEMORY_H_
+
+#include "build/build_config.h"
+
+#include <string>
+
+#if defined(OS_POSIX)
+#include <stdio.h>
+#include <sys/types.h>
+#include <semaphore.h>
+#endif
+
+#include "base/base_export.h"
+#include "base/basictypes.h"
+#include "base/process.h"
+
+#if defined(OS_POSIX)
+#include "base/file_descriptor_posix.h"
+#endif
+
+namespace base {
+
+class FilePath;
+
+// SharedMemoryHandle is a platform specific type which represents
+// the underlying OS handle to a shared memory segment.
+#if defined(OS_WIN)
+typedef HANDLE SharedMemoryHandle;
+typedef HANDLE SharedMemoryLock;
+#elif defined(OS_POSIX)
+// A SharedMemoryId is sufficient to identify a given shared memory segment on a
+// system, but insufficient to map it.
+typedef FileDescriptor SharedMemoryHandle;
+typedef ino_t SharedMemoryId;
+// On POSIX, the lock is implemented as a lockf() on the mapped file,
+// so no additional member (or definition of SharedMemoryLock) is
+// needed.
+#endif
+
+// Options for creating a shared memory object.
+struct SharedMemoryCreateOptions {
+ SharedMemoryCreateOptions() : name(NULL), size(0), open_existing(false),
+ executable(false) {}
+
+ // If NULL, the object is anonymous. This pointer is owned by the caller
+ // and must live through the call to Create().
+ const std::string* name;
+
+ // Size of the shared memory object to be created.
+ // When opening an existing object, this has no effect.
+ size_t size;
+
+ // If true, and the shared memory already exists, Create() will open the
+ // existing shared memory and ignore the size parameter. If false,
+ // shared memory must not exist. This flag is meaningless unless name is
+ // non-NULL.
+ bool open_existing;
+
+ // If true, mappings might need to be made executable later.
+ bool executable;
+};
+
+// Platform abstraction for shared memory. Provides a C++ wrapper
+// around the OS primitive for a memory mapped file.
+class BASE_EXPORT SharedMemory {
+ public:
+ SharedMemory();
+
+#if defined(OS_WIN)
+ // Similar to the default constructor, except that this allows for
+ // calling Lock() to acquire the named mutex before either Create or Open
+ // are called on Windows.
+ explicit SharedMemory(const std::wstring& name);
+#endif
+
+ // Create a new SharedMemory object from an existing, open
+ // shared memory file.
+ SharedMemory(SharedMemoryHandle handle, bool read_only);
+
+ // Create a new SharedMemory object from an existing, open
+ // shared memory file that was created by a remote process and not shared
+ // to the current process.
+ SharedMemory(SharedMemoryHandle handle, bool read_only,
+ ProcessHandle process);
+
+ // Closes any open files.
+ ~SharedMemory();
+
+ // Return true iff the given handle is valid (i.e. not the distingished
+ // invalid value; NULL for a HANDLE and -1 for a file descriptor)
+ static bool IsHandleValid(const SharedMemoryHandle& handle);
+
+ // Returns invalid handle (see comment above for exact definition).
+ static SharedMemoryHandle NULLHandle();
+
+ // Closes a shared memory handle.
+ static void CloseHandle(const SharedMemoryHandle& handle);
+
+ // Creates a shared memory object as described by the options struct.
+ // Returns true on success and false on failure.
+ bool Create(const SharedMemoryCreateOptions& options);
+
+ // Creates and maps an anonymous shared memory segment of size size.
+ // Returns true on success and false on failure.
+ bool CreateAndMapAnonymous(size_t size);
+
+ // Creates an anonymous shared memory segment of size size.
+ // Returns true on success and false on failure.
+ bool CreateAnonymous(size_t size) {
+ SharedMemoryCreateOptions options;
+ options.size = size;
+ return Create(options);
+ }
+
+ // Creates or opens a shared memory segment based on a name.
+ // If open_existing is true, and the shared memory already exists,
+ // opens the existing shared memory and ignores the size parameter.
+ // If open_existing is false, shared memory must not exist.
+ // size is the size of the block to be created.
+ // Returns true on success, false on failure.
+ bool CreateNamed(const std::string& name, bool open_existing, size_t size) {
+ SharedMemoryCreateOptions options;
+ options.name = &name;
+ options.open_existing = open_existing;
+ options.size = size;
+ return Create(options);
+ }
+
+ // Deletes resources associated with a shared memory segment based on name.
+ // Not all platforms require this call.
+ bool Delete(const std::string& name);
+
+ // Opens a shared memory segment based on a name.
+ // If read_only is true, opens for read-only access.
+ // Returns true on success, false on failure.
+ bool Open(const std::string& name, bool read_only);
+
+ // Maps the shared memory into the caller's address space.
+ // Returns true on success, false otherwise. The memory address
+ // is accessed via the memory() accessor. The mapped address is guaranteed to
+ // have an alignment of at least MAP_MINIMUM_ALIGNMENT.
+ bool Map(size_t bytes) {
+ return MapAt(0, bytes);
+ }
+
+ // Same as above, but with |offset| to specify from begining of the shared
+ // memory block to map.
+ // |offset| must be alignent to value of |SysInfo::VMAllocationGranularity()|.
+ bool MapAt(off_t offset, size_t bytes);
+ enum { MAP_MINIMUM_ALIGNMENT = 32 };
+
+ // Unmaps the shared memory from the caller's address space.
+ // Returns true if successful; returns false on error or if the
+ // memory is not mapped.
+ bool Unmap();
+
+ // The size requested when the map is first created.
+ size_t requested_size() const { return requested_size_; }
+
+ // The actual size of the mapped memory (may be larger than requested).
+ size_t mapped_size() const { return mapped_size_; }
+
+ // Gets a pointer to the opened memory space if it has been
+ // Mapped via Map(). Returns NULL if it is not mapped.
+ void *memory() const { return memory_; }
+
+ // Returns the underlying OS handle for this segment.
+ // Use of this handle for anything other than an opaque
+ // identifier is not portable.
+ SharedMemoryHandle handle() const;
+
+#if defined(OS_POSIX) && !defined(OS_NACL)
+ // Returns a unique identifier for this shared memory segment. Inode numbers
+ // are technically only unique to a single filesystem. However, we always
+ // allocate shared memory backing files from the same directory, so will end
+ // up on the same filesystem.
+ SharedMemoryId id() const { return inode_; }
+#endif
+
+ // Closes the open shared memory segment.
+ // It is safe to call Close repeatedly.
+ void Close();
+
+ // Shares the shared memory to another process. Attempts
+ // to create a platform-specific new_handle which can be
+ // used in a remote process to access the shared memory
+ // file. new_handle is an ouput parameter to receive
+ // the handle for use in the remote process.
+ // Returns true on success, false otherwise.
+ bool ShareToProcess(ProcessHandle process,
+ SharedMemoryHandle* new_handle) {
+ return ShareToProcessCommon(process, new_handle, false);
+ }
+
+ // Logically equivalent to:
+ // bool ok = ShareToProcess(process, new_handle);
+ // Close();
+ // return ok;
+ // Note that the memory is unmapped by calling this method, regardless of the
+ // return value.
+ bool GiveToProcess(ProcessHandle process,
+ SharedMemoryHandle* new_handle) {
+ return ShareToProcessCommon(process, new_handle, true);
+ }
+
+ // Locks the shared memory.
+ //
+ // WARNING: on POSIX the memory locking primitive only works across
+ // processes, not across threads. The Lock method is not currently
+ // used in inner loops, so we protect against multiple threads in a
+ // critical section using a class global lock.
+ void Lock();
+
+#if defined(OS_WIN)
+ // A Lock() implementation with a timeout that also allows setting
+ // security attributes on the mutex. sec_attr may be NULL.
+ // Returns true if the Lock() has been acquired, false if the timeout was
+ // reached.
+ bool Lock(uint32 timeout_ms, SECURITY_ATTRIBUTES* sec_attr);
+#endif
+
+ // Releases the shared memory lock.
+ void Unlock();
+
+ private:
+#if defined(OS_POSIX) && !defined(OS_NACL)
+ bool PrepareMapFile(FILE *fp);
+ bool FilePathForMemoryName(const std::string& mem_name, FilePath* path);
+ void LockOrUnlockCommon(int function);
+#endif
+ bool ShareToProcessCommon(ProcessHandle process,
+ SharedMemoryHandle* new_handle,
+ bool close_self);
+
+#if defined(OS_WIN)
+ std::wstring name_;
+ HANDLE mapped_file_;
+#elif defined(OS_POSIX)
+ int mapped_file_;
+ ino_t inode_;
+#endif
+ size_t mapped_size_;
+ void* memory_;
+ bool read_only_;
+ size_t requested_size_;
+#if !defined(OS_POSIX)
+ SharedMemoryLock lock_;
+#endif
+
+ DISALLOW_COPY_AND_ASSIGN(SharedMemory);
+};
+
+// A helper class that acquires the shared memory lock while
+// the SharedMemoryAutoLock is in scope.
+class SharedMemoryAutoLock {
+ public:
+ explicit SharedMemoryAutoLock(SharedMemory* shared_memory)
+ : shared_memory_(shared_memory) {
+ shared_memory_->Lock();
+ }
+
+ ~SharedMemoryAutoLock() {
+ shared_memory_->Unlock();
+ }
+
+ private:
+ SharedMemory* shared_memory_;
+ DISALLOW_COPY_AND_ASSIGN(SharedMemoryAutoLock);
+};
+
+} // namespace base
+
+#endif // BASE_MEMORY_SHARED_MEMORY_H_
diff --git a/base/shared_memory_android.cc b/base/memory/shared_memory_android.cc
similarity index 95%
rename from base/shared_memory_android.cc
rename to base/memory/shared_memory_android.cc
index e2c683c..3ca3c8f 100644
--- a/base/shared_memory_android.cc
+++ b/base/memory/shared_memory_android.cc
@@ -2,7 +2,7 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-#include "base/shared_memory.h"
+#include "base/memory/shared_memory.h"
#include <sys/mman.h>
@@ -37,7 +37,7 @@
DLOG(ERROR) << "Error " << err << " when setting protection of ashmem";
return false;
}
- created_size_ = options.size;
+ requested_size_ = options.size;
return true;
}
diff --git a/base/shared_memory_nacl.cc b/base/memory/shared_memory_nacl.cc
similarity index 96%
rename from base/shared_memory_nacl.cc
rename to base/memory/shared_memory_nacl.cc
index 291527e..bc2a98d 100644
--- a/base/shared_memory_nacl.cc
+++ b/base/memory/shared_memory_nacl.cc
@@ -2,7 +2,7 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-#include "base/shared_memory.h"
+#include "base/memory/shared_memory.h"
#include <errno.h>
#include <fcntl.h>
@@ -18,30 +18,30 @@
SharedMemory::SharedMemory()
: mapped_file_(-1),
- mapped_size_(0),
inode_(0),
+ mapped_size_(0),
memory_(NULL),
read_only_(false),
- created_size_(0) {
+ requested_size_(0) {
}
SharedMemory::SharedMemory(SharedMemoryHandle handle, bool read_only)
: mapped_file_(handle.fd),
- mapped_size_(0),
inode_(0),
+ mapped_size_(0),
memory_(NULL),
read_only_(read_only),
- created_size_(0) {
+ requested_size_(0) {
}
SharedMemory::SharedMemory(SharedMemoryHandle handle, bool read_only,
ProcessHandle process)
: mapped_file_(handle.fd),
- mapped_size_(0),
inode_(0),
+ mapped_size_(0),
memory_(NULL),
read_only_(read_only),
- created_size_(0) {
+ requested_size_(0) {
NOTREACHED();
}
diff --git a/base/shared_memory_posix.cc b/base/memory/shared_memory_posix.cc
similarity index 94%
rename from base/shared_memory_posix.cc
rename to base/memory/shared_memory_posix.cc
index 25d141f..7da1777 100644
--- a/base/shared_memory_posix.cc
+++ b/base/memory/shared_memory_posix.cc
@@ -2,7 +2,7 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-#include "base/shared_memory.h"
+#include "base/memory/shared_memory.h"
#include <errno.h>
#include <fcntl.h>
@@ -42,20 +42,20 @@
SharedMemory::SharedMemory()
: mapped_file_(-1),
- mapped_size_(0),
inode_(0),
+ mapped_size_(0),
memory_(NULL),
read_only_(false),
- created_size_(0) {
+ requested_size_(0) {
}
SharedMemory::SharedMemory(SharedMemoryHandle handle, bool read_only)
: mapped_file_(handle.fd),
- mapped_size_(0),
inode_(0),
+ mapped_size_(0),
memory_(NULL),
read_only_(read_only),
- created_size_(0) {
+ requested_size_(0) {
struct stat st;
if (fstat(handle.fd, &st) == 0) {
// If fstat fails, then the file descriptor is invalid and we'll learn this
@@ -67,11 +67,11 @@
SharedMemory::SharedMemory(SharedMemoryHandle handle, bool read_only,
ProcessHandle process)
: mapped_file_(handle.fd),
- mapped_size_(0),
inode_(0),
+ mapped_size_(0),
memory_(NULL),
read_only_(read_only),
- created_size_(0) {
+ requested_size_(0) {
// We don't handle this case yet (note the ignored parameter); let's die if
// someone comes calling.
NOTREACHED();
@@ -164,7 +164,7 @@
return false;
}
}
- created_size_ = options.size;
+ requested_size_ = options.size;
}
if (fp == NULL) {
#if !defined(OS_MACOSX)
@@ -224,18 +224,14 @@
return false;
#if defined(OS_ANDROID)
+ // On Android, Map can be called with a size and offset of zero to use the
+ // ashmem-determined size.
if (bytes == 0) {
+ DCHECK_EQ(0, offset);
int ashmem_bytes = ashmem_get_size_region(mapped_file_);
if (ashmem_bytes < 0)
return false;
-
- DCHECK_GE(static_cast<uint32>(ashmem_bytes), bytes);
- // The caller wants to determine the map region size from ashmem.
- bytes = ashmem_bytes - offset;
- // TODO(port): we set the created size here so that it is available in
- // transport_dib_android.cc. We should use ashmem_get_size_region()
- // in transport_dib_android.cc.
- created_size_ = ashmem_bytes;
+ bytes = ashmem_bytes;
}
#endif
diff --git a/base/shared_memory_unittest.cc b/base/memory/shared_memory_unittest.cc
similarity index 93%
rename from base/shared_memory_unittest.cc
rename to base/memory/shared_memory_unittest.cc
index 3f83248..5c0cc8b 100644
--- a/base/shared_memory_unittest.cc
+++ b/base/memory/shared_memory_unittest.cc
@@ -7,7 +7,7 @@
#include "base/mac/scoped_nsautorelease_pool.h"
#endif
#include "base/memory/scoped_ptr.h"
-#include "base/shared_memory.h"
+#include "base/memory/shared_memory.h"
#include "base/sys_info.h"
#include "base/test/multiprocess_test.h"
#include "base/threading/platform_thread.h"
@@ -197,11 +197,18 @@
EXPECT_TRUE(rv);
// Memory1 knows it's size because it created it.
- EXPECT_EQ(memory1.created_size(), kDataSize);
+ EXPECT_EQ(memory1.requested_size(), kDataSize);
rv = memory1.Map(kDataSize);
EXPECT_TRUE(rv);
+ // The mapped memory1 must be at least the size we asked for.
+ EXPECT_GE(memory1.mapped_size(), kDataSize);
+
+ // The mapped memory1 shouldn't exceed rounding for allocation granularity.
+ EXPECT_LT(memory1.mapped_size(),
+ kDataSize + base::SysInfo::VMAllocationGranularity());
+
memset(memory1.memory(), 'G', kDataSize);
SharedMemory memory2;
@@ -214,12 +221,19 @@
EXPECT_TRUE(rv);
// Memory2 shouldn't know the size because we didn't create it.
- EXPECT_EQ(memory2.created_size(), 0U);
+ EXPECT_EQ(memory2.requested_size(), 0U);
// We should be able to map the original size.
rv = memory2.Map(kDataSize);
EXPECT_TRUE(rv);
+ // The mapped memory2 must be at least the size of the original.
+ EXPECT_GE(memory2.mapped_size(), kDataSize);
+
+ // The mapped memory2 shouldn't exceed rounding for allocation granularity.
+ EXPECT_LT(memory2.mapped_size(),
+ kDataSize2 + base::SysInfo::VMAllocationGranularity());
+
// Verify that opening memory2 didn't truncate or delete memory 1.
char *start_ptr = static_cast<char *>(memory2.memory());
char *end_ptr = start_ptr + kDataSize;
@@ -382,9 +396,9 @@
options.executable = true;
EXPECT_TRUE(shared_memory.Create(options));
- EXPECT_TRUE(shared_memory.Map(shared_memory.created_size()));
+ EXPECT_TRUE(shared_memory.Map(shared_memory.requested_size()));
- EXPECT_EQ(0, mprotect(shared_memory.memory(), shared_memory.created_size(),
+ EXPECT_EQ(0, mprotect(shared_memory.memory(), shared_memory.requested_size(),
PROT_READ | PROT_EXEC));
}
#endif
diff --git a/base/shared_memory_win.cc b/base/memory/shared_memory_win.cc
similarity index 81%
rename from base/shared_memory_win.cc
rename to base/memory/shared_memory_win.cc
index f64e3c8..ca0d00f 100644
--- a/base/shared_memory_win.cc
+++ b/base/memory/shared_memory_win.cc
@@ -2,18 +2,32 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-#include "base/shared_memory.h"
+#include "base/memory/shared_memory.h"
#include "base/logging.h"
#include "base/utf_string_conversions.h"
+namespace {
+
+// Returns the length of the memory section starting at the supplied address.
+size_t GetMemorySectionSize(void* address) {
+ MEMORY_BASIC_INFORMATION memory_info;
+ if (!::VirtualQuery(address, &memory_info, sizeof(memory_info)))
+ return 0;
+ return memory_info.RegionSize - (static_cast<char*>(address) -
+ static_cast<char*>(memory_info.AllocationBase));
+}
+
+} // namespace.
+
namespace base {
SharedMemory::SharedMemory()
: mapped_file_(NULL),
memory_(NULL),
read_only_(false),
- created_size_(0),
+ mapped_size_(0),
+ requested_size_(0),
lock_(NULL) {
}
@@ -21,7 +35,8 @@
: mapped_file_(NULL),
memory_(NULL),
read_only_(false),
- created_size_(0),
+ requested_size_(0),
+ mapped_size_(0),
lock_(NULL),
name_(name) {
}
@@ -30,7 +45,8 @@
: mapped_file_(handle),
memory_(NULL),
read_only_(read_only),
- created_size_(0),
+ requested_size_(0),
+ mapped_size_(0),
lock_(NULL) {
}
@@ -39,7 +55,8 @@
: mapped_file_(NULL),
memory_(NULL),
read_only_(read_only),
- created_size_(0),
+ requested_size_(0),
+ mapped_size_(0),
lock_(NULL) {
::DuplicateHandle(process, handle,
GetCurrentProcess(), &mapped_file_,
@@ -75,22 +92,20 @@
}
bool SharedMemory::Create(const SharedMemoryCreateOptions& options) {
+ // TODO(bsy,sehr): crbug.com/210609 NaCl forces us to round up 64k here,
+ // wasting 32k per mapping on average.
+ static const size_t kSectionMask = 65536 - 1;
DCHECK(!options.executable);
DCHECK(!mapped_file_);
if (options.size == 0)
return false;
- if (options.size > static_cast<size_t>(std::numeric_limits<int>::max()))
+ // Check maximum accounting for overflow.
+ if (options.size >
+ static_cast<size_t>(std::numeric_limits<int>::max()) - kSectionMask)
return false;
- // NaCl's memory allocator requires 0mod64K alignment and size for
- // shared memory objects. To allow passing shared memory to NaCl,
- // therefore we round the size actually created to the nearest 64K unit.
- // To avoid client impact, we continue to retain the size as the
- // actual requested size.
- uint32 rounded_size = (options.size + 0xffff) & ~0xffff;
- if (rounded_size < options.size)
- return false;
+ size_t rounded_size = (options.size + kSectionMask) & ~kSectionMask;
name_ = ASCIIToWide(options.name == NULL ? "" : *options.name);
mapped_file_ = CreateFileMapping(INVALID_HANDLE_VALUE, NULL,
PAGE_READWRITE, 0, static_cast<DWORD>(rounded_size),
@@ -98,13 +113,13 @@
if (!mapped_file_)
return false;
- created_size_ = options.size;
+ requested_size_ = options.size;
// Check if the shared memory pre-exists.
if (GetLastError() == ERROR_ALREADY_EXISTS) {
- // If the file already existed, set created_size_ to 0 to show that
+ // If the file already existed, set requested_size_ to 0 to show that
// we don't know the size.
- created_size_ = 0;
+ requested_size_ = 0;
if (!options.open_existing) {
Close();
return false;
@@ -149,6 +164,7 @@
if (memory_ != NULL) {
DCHECK_EQ(0U, reinterpret_cast<uintptr_t>(memory_) &
(SharedMemory::MAP_MINIMUM_ALIGNMENT - 1));
+ mapped_size_ = GetMemorySectionSize(memory_);
return true;
}
return false;
diff --git a/base/memory/weak_ptr.h b/base/memory/weak_ptr.h
index d0a2a3a..19def01 100644
--- a/base/memory/weak_ptr.h
+++ b/base/memory/weak_ptr.h
@@ -2,24 +2,24 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-// Weak pointers help in cases where you have many objects referring back to a
-// shared object and you wish for the lifetime of the shared object to not be
-// bound to the lifetime of the referrers. In other words, this is useful when
-// reference counting is not a good fit.
-//
-// A common alternative to weak pointers is to have the shared object hold a
-// list of all referrers, and then when the shared object is destroyed, it
-// calls a method on the referrers to tell them to drop their references. This
-// approach also requires the referrers to tell the shared object when they get
-// destroyed so that the shared object can remove the referrer from its list of
-// referrers. Such a solution works, but it is a bit complex.
-//
+// Weak pointers are pointers to an object that do not affect its lifetime,
+// and which may be invalidated (i.e. reset to NULL) by the object, or its
+// owner, at any time, most commonly when the object is about to be deleted.
+
+// Weak pointers are useful when an object needs to be accessed safely by one
+// or more objects other than its owner, and those callers can cope with the
+// object vanishing and e.g. tasks posted to it being silently dropped.
+// Reference-counting such an object would complicate the ownership graph and
+// make it harder to reason about the object's lifetime.
+
// EXAMPLE:
//
-// class Controller : public SupportsWeakPtr<Controller> {
+// class Controller {
// public:
-// void SpawnWorker() { Worker::StartNew(AsWeakPtr()); }
+// void SpawnWorker() { Worker::StartNew(weak_factory_.GetWeakPtr()); }
// void WorkComplete(const Result& result) { ... }
+// private:
+// WeakPtrFactory<Controller> weak_factory_;
// };
//
// class Worker {
@@ -38,34 +38,23 @@
// WeakPtr<Controller> controller_;
// };
//
-// Given the above classes, a consumer may allocate a Controller object, call
-// SpawnWorker several times, and then destroy the Controller object before all
-// of the workers have completed. Because the Worker class only holds a weak
-// pointer to the Controller, we don't have to worry about the Worker
-// dereferencing the Controller back pointer after the Controller has been
-// destroyed.
-//
-// ------------------------ Thread-safety notes ------------------------
-// When you get a WeakPtr (from a WeakPtrFactory or SupportsWeakPtr), if it's
-// the only one pointing to the object, the object become bound to the
-// current thread, as well as this WeakPtr and all later ones get created.
-//
-// You may only dereference the WeakPtr on the thread it binds to. However, it
-// is safe to destroy the WeakPtr object on another thread. Because of this,
-// querying WeakPtrFactory's HasWeakPtrs() method can be racy.
-//
-// On the other hand, the object that supports WeakPtr (extends SupportsWeakPtr)
-// can only be deleted from the thread it binds to, until all WeakPtrs are
-// deleted.
-//
+// With this implementation a caller may use SpawnWorker() to dispatch multiple
+// Workers and subsequently delete the Controller, without waiting for all
+// Workers to have completed.
+
+// ------------------------- IMPORTANT: Thread-safety -------------------------
+
+// Weak pointers must always be dereferenced and invalidated on the same thread
+// otherwise checking the pointer would be racey. WeakPtrFactory enforces this
+// by binding itself to the current thread when a WeakPtr is first created
+// and un-binding only when those pointers are invalidated. WeakPtrs may still
+// be handed off to other threads, however, so long as they are only actually
+// dereferenced on the originating thread. This includes posting tasks to the
+// thread using base::Bind() to invoke a method on the object via the WeakPtr.
+
// Calling SupportsWeakPtr::DetachFromThread() can work around the limitations
// above and cancel the thread binding of the object and all WeakPtrs pointing
-// to it, but it's not recommended and unsafe.
-//
-// WeakPtrs may be copy-constructed or assigned on threads other than the thread
-// they are bound to. This does not change the thread binding. So these WeakPtrs
-// may only be dereferenced on the thread that the original WeakPtr was bound
-// to.
+// to it, but it's not recommended and unsafe. See crbug.com/232143.
#ifndef BASE_MEMORY_WEAK_PTR_H_
#define BASE_MEMORY_WEAK_PTR_H_
@@ -132,6 +121,7 @@
void Invalidate();
// Indicates that this object will be used on another thread from now on.
+ // Do not use this in new code. See crbug.com/232143.
void DetachFromThread() {
if (flag_) flag_->DetachFromThread();
}
@@ -247,10 +237,56 @@
T* ptr_;
};
-// A class may extend from SupportsWeakPtr to expose weak pointers to itself.
-// This is useful in cases where you want others to be able to get a weak
-// pointer to your class. It also has the property that you don't need to
-// initialize it from your constructor.
+// A class may be composed of a WeakPtrFactory and thereby
+// control how it exposes weak pointers to itself. This is helpful if you only
+// need weak pointers within the implementation of a class. This class is also
+// useful when working with primitive types. For example, you could have a
+// WeakPtrFactory<bool> that is used to pass around a weak reference to a bool.
+template <class T>
+class WeakPtrFactory {
+ public:
+ explicit WeakPtrFactory(T* ptr) : ptr_(ptr) {
+ }
+
+ ~WeakPtrFactory() {
+ ptr_ = NULL;
+ }
+
+ WeakPtr<T> GetWeakPtr() {
+ DCHECK(ptr_);
+ return WeakPtr<T>(weak_reference_owner_.GetRef(), ptr_);
+ }
+
+ // Call this method to invalidate all existing weak pointers.
+ void InvalidateWeakPtrs() {
+ DCHECK(ptr_);
+ weak_reference_owner_.Invalidate();
+ }
+
+ // Call this method to determine if any weak pointers exist.
+ bool HasWeakPtrs() const {
+ DCHECK(ptr_);
+ return weak_reference_owner_.HasRefs();
+ }
+
+ // Indicates that this object will be used on another thread from now on.
+ // Do not use this in new code. See crbug.com/232143.
+ void DetachFromThread() {
+ DCHECK(ptr_);
+ weak_reference_owner_.DetachFromThread();
+ }
+
+ private:
+ internal::WeakReferenceOwner weak_reference_owner_;
+ T* ptr_;
+ DISALLOW_IMPLICIT_CONSTRUCTORS(WeakPtrFactory);
+};
+
+// A class may extend from SupportsWeakPtr to let others take weak pointers to
+// it. This avoids the class itself implementing boilerplate to dispense weak
+// pointers. However, since SupportsWeakPtr's destructor won't invalidate
+// weak pointers to the class until after the derived class' members have been
+// destroyed, its use can lead to subtle use-after-destroy issues.
template <class T>
class SupportsWeakPtr : public internal::SupportsWeakPtrBase {
public:
@@ -261,6 +297,7 @@
}
// Indicates that this object will be used on another thread from now on.
+ // Do not use this in new code. See crbug.com/232143.
void DetachFromThread() {
weak_reference_owner_.DetachFromThread();
}
@@ -296,50 +333,6 @@
return internal::SupportsWeakPtrBase::StaticAsWeakPtr<Derived>(t);
}
-// A class may alternatively be composed of a WeakPtrFactory and thereby
-// control how it exposes weak pointers to itself. This is helpful if you only
-// need weak pointers within the implementation of a class. This class is also
-// useful when working with primitive types. For example, you could have a
-// WeakPtrFactory<bool> that is used to pass around a weak reference to a bool.
-template <class T>
-class WeakPtrFactory {
- public:
- explicit WeakPtrFactory(T* ptr) : ptr_(ptr) {
- }
-
- ~WeakPtrFactory() {
- ptr_ = NULL;
- }
-
- WeakPtr<T> GetWeakPtr() {
- DCHECK(ptr_);
- return WeakPtr<T>(weak_reference_owner_.GetRef(), ptr_);
- }
-
- // Call this method to invalidate all existing weak pointers.
- void InvalidateWeakPtrs() {
- DCHECK(ptr_);
- weak_reference_owner_.Invalidate();
- }
-
- // Call this method to determine if any weak pointers exist.
- bool HasWeakPtrs() const {
- DCHECK(ptr_);
- return weak_reference_owner_.HasRefs();
- }
-
- // Indicates that this object will be used on another thread from now on.
- void DetachFromThread() {
- DCHECK(ptr_);
- weak_reference_owner_.DetachFromThread();
- }
-
- private:
- internal::WeakReferenceOwner weak_reference_owner_;
- T* ptr_;
- DISALLOW_IMPLICIT_CONSTRUCTORS(WeakPtrFactory);
-};
-
} // namespace base
#endif // BASE_MEMORY_WEAK_PTR_H_
diff --git a/base/message_loop.cc b/base/message_loop.cc
index f9ecd41..0d8a8ef 100644
--- a/base/message_loop.cc
+++ b/base/message_loop.cc
@@ -13,7 +13,7 @@
#include "base/lazy_instance.h"
#include "base/logging.h"
#include "base/memory/scoped_ptr.h"
-#include "base/message_loop_proxy_impl.h"
+#include "base/message_loop/message_loop_proxy_impl.h"
#include "base/message_pump_default.h"
#include "base/metrics/histogram.h"
#include "base/metrics/statistics_recorder.h"
@@ -39,15 +39,13 @@
#include <gdk/gdkx.h>
#endif
-using base::PendingTask;
-using base::TimeDelta;
-using base::TimeTicks;
+namespace base {
namespace {
// A lazily created thread local storage for quick access to a thread's message
// loop, if one exists. This should be safe and free of static constructors.
-base::LazyInstance<base::ThreadLocalPointer<MessageLoop> > lazy_tls_ptr =
+LazyInstance<base::ThreadLocalPointer<MessageLoop> > lazy_tls_ptr =
LAZY_INSTANCE_INITIALIZER;
// Logical events for Histogram profiling. Run with -message-loop-histogrammer
@@ -76,7 +74,7 @@
// in the pair (i.e., the quoted string) when printing out a histogram.
#define VALUE_TO_NUMBER_AND_NAME(name) {name, #name},
-const base::LinearHistogram::DescriptionPair event_descriptions_[] = {
+const LinearHistogram::DescriptionPair event_descriptions_[] = {
// Provide some pretty print capability in our histogram for our internal
// messages.
@@ -149,30 +147,30 @@
DCHECK(!current()) << "should only have one message loop per thread";
lazy_tls_ptr.Pointer()->Set(this);
- message_loop_proxy_ = new base::MessageLoopProxyImpl();
+ message_loop_proxy_ = new MessageLoopProxyImpl();
thread_task_runner_handle_.reset(
- new base::ThreadTaskRunnerHandle(message_loop_proxy_));
+ new ThreadTaskRunnerHandle(message_loop_proxy_));
// TODO(rvargas): Get rid of the OS guards.
#if defined(OS_WIN)
-#define MESSAGE_PUMP_UI new base::MessagePumpForUI()
-#define MESSAGE_PUMP_IO new base::MessagePumpForIO()
+#define MESSAGE_PUMP_UI new MessagePumpForUI()
+#define MESSAGE_PUMP_IO new MessagePumpForIO()
#elif defined(OS_IOS)
-#define MESSAGE_PUMP_UI base::MessagePumpMac::Create()
-#define MESSAGE_PUMP_IO new base::MessagePumpIOSForIO()
+#define MESSAGE_PUMP_UI MessagePumpMac::Create()
+#define MESSAGE_PUMP_IO new MessagePumpIOSForIO()
#elif defined(OS_MACOSX)
-#define MESSAGE_PUMP_UI base::MessagePumpMac::Create()
-#define MESSAGE_PUMP_IO new base::MessagePumpLibevent()
+#define MESSAGE_PUMP_UI MessagePumpMac::Create()
+#define MESSAGE_PUMP_IO new MessagePumpLibevent()
#elif defined(OS_NACL)
// Currently NaCl doesn't have a UI MessageLoop.
// TODO(abarth): Figure out if we need this.
#define MESSAGE_PUMP_UI NULL
// ipc_channel_nacl.cc uses a worker thread to do socket reads currently, and
// doesn't require extra support for watching file descriptors.
-#define MESSAGE_PUMP_IO new base::MessagePumpDefault();
+#define MESSAGE_PUMP_IO new MessagePumpDefault();
#elif defined(OS_POSIX) // POSIX but not MACOSX.
-#define MESSAGE_PUMP_UI new base::MessagePumpForUI()
-#define MESSAGE_PUMP_IO new base::MessagePumpLibevent()
+#define MESSAGE_PUMP_UI new MessagePumpForUI()
+#define MESSAGE_PUMP_IO new MessagePumpLibevent()
#else
#error Not implemented
#endif
@@ -186,7 +184,7 @@
pump_ = MESSAGE_PUMP_IO;
} else {
DCHECK_EQ(TYPE_DEFAULT, type_);
- pump_ = new base::MessagePumpDefault();
+ pump_ = new MessagePumpDefault();
}
}
@@ -219,7 +217,7 @@
thread_task_runner_handle_.reset();
// Tell the message_loop_proxy that we are dying.
- static_cast<base::MessageLoopProxyImpl*>(message_loop_proxy_.get())->
+ static_cast<MessageLoopProxyImpl*>(message_loop_proxy_.get())->
WillDestroyCurrentMessageLoop();
message_loop_proxy_ = NULL;
@@ -231,8 +229,8 @@
// Doing this is not-critical, it is mainly to make sure we track
// the high resolution timer activations properly in our unit tests.
if (!high_resolution_timer_expiration_.is_null()) {
- base::Time::ActivateHighResolutionTimer(false);
- high_resolution_timer_expiration_ = base::TimeTicks();
+ Time::ActivateHighResolutionTimer(false);
+ high_resolution_timer_expiration_ = TimeTicks();
}
#endif
}
@@ -272,49 +270,59 @@
}
void MessageLoop::PostTask(
- const tracked_objects::Location& from_here, const base::Closure& task) {
+ const tracked_objects::Location& from_here,
+ const Closure& task) {
DCHECK(!task.is_null()) << from_here.ToString();
PendingTask pending_task(
from_here, task, CalculateDelayedRuntime(TimeDelta()), true);
- AddToIncomingQueue(&pending_task);
+ AddToIncomingQueue(&pending_task, false);
+}
+
+bool MessageLoop::TryPostTask(
+ const tracked_objects::Location& from_here,
+ const Closure& task) {
+ DCHECK(!task.is_null()) << from_here.ToString();
+ PendingTask pending_task(
+ from_here, task, CalculateDelayedRuntime(TimeDelta()), true);
+ return AddToIncomingQueue(&pending_task, true);
}
void MessageLoop::PostDelayedTask(
const tracked_objects::Location& from_here,
- const base::Closure& task,
+ const Closure& task,
TimeDelta delay) {
DCHECK(!task.is_null()) << from_here.ToString();
PendingTask pending_task(
from_here, task, CalculateDelayedRuntime(delay), true);
- AddToIncomingQueue(&pending_task);
+ AddToIncomingQueue(&pending_task, false);
}
void MessageLoop::PostNonNestableTask(
const tracked_objects::Location& from_here,
- const base::Closure& task) {
+ const Closure& task) {
DCHECK(!task.is_null()) << from_here.ToString();
PendingTask pending_task(
from_here, task, CalculateDelayedRuntime(TimeDelta()), false);
- AddToIncomingQueue(&pending_task);
+ AddToIncomingQueue(&pending_task, false);
}
void MessageLoop::PostNonNestableDelayedTask(
const tracked_objects::Location& from_here,
- const base::Closure& task,
+ const Closure& task,
TimeDelta delay) {
DCHECK(!task.is_null()) << from_here.ToString();
PendingTask pending_task(
from_here, task, CalculateDelayedRuntime(delay), false);
- AddToIncomingQueue(&pending_task);
+ AddToIncomingQueue(&pending_task, false);
}
void MessageLoop::Run() {
- base::RunLoop run_loop;
+ RunLoop run_loop;
run_loop.Run();
}
void MessageLoop::RunUntilIdle() {
- base::RunLoop run_loop;
+ RunLoop run_loop;
run_loop.RunUntilIdle();
}
@@ -345,8 +353,8 @@
}
// static
-base::Closure MessageLoop::QuitWhenIdleClosure() {
- return base::Bind(&QuitCurrentWhenIdle);
+Closure MessageLoop::QuitWhenIdleClosure() {
+ return Bind(&QuitCurrentWhenIdle);
}
void MessageLoop::SetNestableTasksAllowed(bool allowed) {
@@ -379,7 +387,7 @@
void MessageLoop::AssertIdle() const {
// We only check |incoming_queue_|, since we don't want to lock |work_queue_|.
- base::AutoLock lock(incoming_queue_lock_);
+ AutoLock lock(incoming_queue_lock_);
DCHECK(incoming_queue_.empty());
}
@@ -424,7 +432,7 @@
#if !defined(OS_MACOSX) && !defined(OS_ANDROID)
if (run_loop_->dispatcher_ && type() == TYPE_UI) {
- static_cast<base::MessagePumpForUI*>(pump_.get())->
+ static_cast<MessagePumpForUI*>(pump_.get())->
RunWithDispatcher(this, run_loop_->dispatcher_);
return;
}
@@ -464,7 +472,7 @@
// Look at a memory dump of the stack.
const void* program_counter =
pending_task.posted_from.program_counter();
- base::debug::Alias(&program_counter);
+ debug::Alias(&program_counter);
HistogramEvent(kTaskRunEvent);
@@ -512,7 +520,7 @@
// Acquire all we can from the inter-thread queue with one lock acquisition.
{
- base::AutoLock lock(incoming_queue_lock_);
+ AutoLock lock(incoming_queue_lock_);
if (incoming_queue_.empty())
return;
incoming_queue_.Swap(&work_queue_); // Constant time
@@ -562,9 +570,9 @@
// res timers for any timer which is within 2x of the granularity.
// This is a tradeoff between accuracy and power management.
bool needs_high_res_timers = delay.InMilliseconds() <
- (2 * base::Time::kMinLowResolutionThresholdMs);
+ (2 * Time::kMinLowResolutionThresholdMs);
if (needs_high_res_timers) {
- if (base::Time::ActivateHighResolutionTimer(true)) {
+ if (Time::ActivateHighResolutionTimer(true)) {
high_resolution_timer_expiration_ = TimeTicks::Now() +
TimeDelta::FromMilliseconds(kHighResolutionTimerModeLeaseTimeMs);
}
@@ -578,7 +586,7 @@
#if defined(OS_WIN)
if (!high_resolution_timer_expiration_.is_null()) {
if (TimeTicks::Now() > high_resolution_timer_expiration_) {
- base::Time::ActivateHighResolutionTimer(false);
+ Time::ActivateHighResolutionTimer(false);
high_resolution_timer_expiration_ = TimeTicks();
}
}
@@ -588,15 +596,23 @@
}
// Possibly called on a background thread!
-void MessageLoop::AddToIncomingQueue(PendingTask* pending_task) {
+bool MessageLoop::AddToIncomingQueue(PendingTask* pending_task,
+ bool use_try_lock) {
// Warning: Don't try to short-circuit, and handle this thread's tasks more
// directly, as it could starve handling of foreign threads. Put every task
// into this queue.
- scoped_refptr<base::MessagePump> pump;
+ scoped_refptr<MessagePump> pump;
{
- base::AutoLock locked(incoming_queue_lock_);
-
+ if (use_try_lock) {
+ if (!incoming_queue_lock_.Try()) {
+ pending_task->task.Reset();
+ return false;
+ }
+ } else {
+ incoming_queue_lock_.Acquire();
+ }
+ AutoLock locked(incoming_queue_lock_, AutoLock::AlreadyAcquired());
// Initialize the sequence number. The sequence number is used for delayed
// tasks (to faciliate FIFO sorting when two tasks have the same
// delayed_run_time value) and for identifying the task in about:tracing.
@@ -609,7 +625,7 @@
incoming_queue_.push(*pending_task);
pending_task->task.Reset();
if (!was_empty)
- return; // Someone else should have started the sub-pump.
+ return true; // Someone else should have started the sub-pump.
pump = pump_;
}
@@ -619,6 +635,7 @@
// ScheduleWork outside of incoming_queue_lock_.
pump->ScheduleWork();
+ return true;
}
//------------------------------------------------------------------------------
@@ -628,9 +645,9 @@
void MessageLoop::StartHistogrammer() {
#if !defined(OS_NACL) // NaCl build has no metrics code.
if (enable_histogrammer_ && !message_histogram_
- && base::StatisticsRecorder::IsActive()) {
+ && StatisticsRecorder::IsActive()) {
DCHECK(!thread_name_.empty());
- message_histogram_ = base::LinearHistogram::FactoryGetWithRangeDescription(
+ message_histogram_ = LinearHistogram::FactoryGetWithRangeDescription(
"MsgLoop:" + thread_name_,
kLeastNonZeroMessageId, kMaxMessageId,
kNumberOfDistinctMessagesDisplayed,
@@ -722,14 +739,14 @@
void MessageLoop::DeleteSoonInternal(const tracked_objects::Location& from_here,
void(*deleter)(const void*),
const void* object) {
- PostNonNestableTask(from_here, base::Bind(deleter, object));
+ PostNonNestableTask(from_here, Bind(deleter, object));
}
void MessageLoop::ReleaseSoonInternal(
const tracked_objects::Location& from_here,
void(*releaser)(const void*),
const void* object) {
- PostNonNestableTask(from_here, base::Bind(releaser, object));
+ PostNonNestableTask(from_here, Bind(releaser, object));
}
//------------------------------------------------------------------------------
@@ -744,13 +761,13 @@
#if defined(OS_ANDROID)
void MessageLoopForUI::Start() {
// No Histogram support for UI message loop as it is managed by Java side
- static_cast<base::MessagePumpForUI*>(pump_.get())->Start(this);
+ static_cast<MessagePumpForUI*>(pump_.get())->Start(this);
}
#endif
#if defined(OS_IOS)
void MessageLoopForUI::Attach() {
- static_cast<base::MessagePumpUIApplication*>(pump_.get())->Attach(this);
+ static_cast<MessagePumpUIApplication*>(pump_.get())->Attach(this);
}
#endif
@@ -813,3 +830,5 @@
}
#endif
+
+} // namespace base
diff --git a/base/message_loop.h b/base/message_loop.h
index 13bf621..f3ad3a5 100644
--- a/base/message_loop.h
+++ b/base/message_loop.h
@@ -34,6 +34,8 @@
#if defined(USE_AURA) && defined(USE_X11) && !defined(OS_NACL)
#include "base/message_pump_aurax11.h"
+#elif defined(USE_OZONE) && !defined(OS_NACL)
+#include "base/message_pump_ozone.h"
#else
#include "base/message_pump_gtk.h"
#endif
@@ -43,12 +45,12 @@
namespace base {
class HistogramBase;
+class MessageLoopLockTest;
class RunLoop;
class ThreadTaskRunnerHandle;
#if defined(OS_ANDROID)
class MessagePumpForUI;
#endif
-} // namespace base
// A MessageLoop is used to process events for a particular thread. There is
// at most one MessageLoop instance per thread.
@@ -166,12 +168,20 @@
// PostTask(from_here, task) is equivalent to
// PostDelayedTask(from_here, task, 0).
//
+ // The TryPostTask is meant for the cases where the calling thread cannot
+ // block. If posting the task will block, the call returns false, the task
+ // is not posted but the task is consumed anyways.
+ //
// NOTE: These methods may be called on any thread. The Task will be invoked
// on the thread that executes MessageLoop::Run().
void PostTask(
const tracked_objects::Location& from_here,
const base::Closure& task);
+ bool TryPostTask(
+ const tracked_objects::Location& from_here,
+ const base::Closure& task);
+
void PostDelayedTask(
const tracked_objects::Location& from_here,
const base::Closure& task,
@@ -400,6 +410,7 @@
private:
friend class base::RunLoop;
+ friend class base::MessageLoopLockTest;
// A function to encapsulate all the exception handling capability in the
// stacks around the running of a main message loop. It will run the message
@@ -429,13 +440,21 @@
// Adds the pending task to delayed_work_queue_.
void AddToDelayedWorkQueue(const base::PendingTask& pending_task);
- // Adds the pending task to our incoming_queue_.
+ // This function attempts to add pending task to our incoming_queue_.
+ // The append can only possibly fail when |use_try_lock| is true.
//
- // Caller retains ownership of |pending_task|, but this function will
- // reset the value of pending_task->task. This is needed to ensure
- // that the posting call stack does not retain pending_task->task
+ // When |use_try_lock| is true, then this call will avoid blocking if
+ // the related lock is already held, and will in that case (when the
+ // lock is contended) fail to perform the append, and will return false.
+ //
+ // If the call succeeds to append to the queue, then this call
+ // will return true.
+ //
+ // In all cases, the caller retains ownership of |pending_task|, but this
+ // function will reset the value of pending_task->task. This is needed to
+ // ensure that the posting call stack does not retain pending_task->task
// beyond this function call.
- void AddToIncomingQueue(base::PendingTask* pending_task);
+ bool AddToIncomingQueue(base::PendingTask* pending_task, bool use_try_lock);
// Load tasks from the incoming_queue_ into work_queue_ if the latter is
// empty. The former requires a lock to access, while the latter is directly
@@ -573,6 +592,7 @@
// events to the Java message loop.
void Start();
#elif !defined(OS_MACOSX)
+
// Please see message_pump_win/message_pump_glib for definitions of these
// methods.
void AddObserver(Observer* observer);
@@ -589,6 +609,9 @@
#if defined(USE_AURA) && defined(USE_X11) && !defined(OS_NACL)
friend class base::MessagePumpAuraX11;
#endif
+#if defined(USE_MESSAGEPUMP_LINUX) && !defined(OS_NACL)
+ friend class base::MessagePumpLinux;
+#endif
// TODO(rvargas): Make this platform independent.
base::MessagePumpForUI* pump_ui() {
@@ -705,4 +728,12 @@
COMPILE_ASSERT(sizeof(MessageLoop) == sizeof(MessageLoopForIO),
MessageLoopForIO_should_not_have_extra_member_variables);
+} // namespace base
+
+// TODO(brettw) remove this when all users are updated to explicitly use the
+// namespace
+using base::MessageLoop;
+using base::MessageLoopForIO;
+using base::MessageLoopForUI;
+
#endif // BASE_MESSAGE_LOOP_H_
diff --git a/base/message_loop_proxy.cc b/base/message_loop/message_loop_proxy.cc
similarity index 86%
rename from base/message_loop_proxy.cc
rename to base/message_loop/message_loop_proxy.cc
index 755564b..e5f0142 100644
--- a/base/message_loop_proxy.cc
+++ b/base/message_loop/message_loop_proxy.cc
@@ -2,7 +2,7 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-#include "base/message_loop_proxy.h"
+#include "base/message_loop/message_loop_proxy.h"
#include "base/bind.h"
diff --git a/base/message_loop/message_loop_proxy.h b/base/message_loop/message_loop_proxy.h
new file mode 100644
index 0000000..4ace802
--- /dev/null
+++ b/base/message_loop/message_loop_proxy.h
@@ -0,0 +1,38 @@
+// Copyright (c) 2012 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 BASE_MESSAGE_LOOP_MESSAGE_LOOP_PROXY_H_
+#define BASE_MESSAGE_LOOP_MESSAGE_LOOP_PROXY_H_
+
+#include "base/base_export.h"
+#include "base/compiler_specific.h"
+#include "base/memory/ref_counted.h"
+#include "base/single_thread_task_runner.h"
+
+namespace base {
+
+// This class provides a thread-safe refcounted interface to the Post* methods
+// of a message loop. This class can outlive the target message loop.
+// MessageLoopProxy objects are constructed automatically for all MessageLoops.
+// So, to access them, you can use any of the following:
+// Thread::message_loop_proxy()
+// MessageLoop::current()->message_loop_proxy()
+// MessageLoopProxy::current()
+//
+// TODO(akalin): Now that we have the *TaskRunner interfaces, we can
+// merge this with MessageLoopProxyImpl.
+class BASE_EXPORT MessageLoopProxy : public SingleThreadTaskRunner {
+ public:
+ // Gets the MessageLoopProxy for the current message loop, creating one if
+ // needed.
+ static scoped_refptr<MessageLoopProxy> current();
+
+ protected:
+ MessageLoopProxy();
+ virtual ~MessageLoopProxy();
+};
+
+} // namespace base
+
+#endif // BASE_MESSAGE_LOOP_MESSAGE_LOOP_PROXY_H_
diff --git a/base/message_loop_proxy_impl.cc b/base/message_loop/message_loop_proxy_impl.cc
similarity index 97%
rename from base/message_loop_proxy_impl.cc
rename to base/message_loop/message_loop_proxy_impl.cc
index b4ca210..7dc8caa 100644
--- a/base/message_loop_proxy_impl.cc
+++ b/base/message_loop/message_loop_proxy_impl.cc
@@ -2,7 +2,7 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-#include "base/message_loop_proxy_impl.h"
+#include "base/message_loop/message_loop_proxy_impl.h"
#include "base/location.h"
#include "base/threading/thread_restrictions.h"
diff --git a/base/message_loop_proxy_impl.h b/base/message_loop/message_loop_proxy_impl.h
similarity index 90%
rename from base/message_loop_proxy_impl.h
rename to base/message_loop/message_loop_proxy_impl.h
index 2bcd8fd..9f76794 100644
--- a/base/message_loop_proxy_impl.h
+++ b/base/message_loop/message_loop_proxy_impl.h
@@ -2,8 +2,8 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-#ifndef BASE_MESSAGE_LOOP_PROXY_IMPL_H_
-#define BASE_MESSAGE_LOOP_PROXY_IMPL_H_
+#ifndef BASE_MESSAGE_LOOP_MESSAGE_LOOP_PROXY_IMPL_H_
+#define BASE_MESSAGE_LOOP_MESSAGE_LOOP_PROXY_IMPL_H_
#include "base/base_export.h"
#include "base/message_loop.h"
@@ -36,7 +36,7 @@
private:
// Allow the MessageLoop to create a MessageLoopProxyImpl.
- friend class ::MessageLoop;
+ friend class MessageLoop;
friend class DeleteHelper<MessageLoopProxyImpl>;
MessageLoopProxyImpl();
@@ -59,4 +59,4 @@
} // namespace base
-#endif // BASE_MESSAGE_LOOP_PROXY_IMPL_H_
+#endif // BASE_MESSAGE_LOOP_MESSAGE_LOOP_PROXY_IMPL_H_
diff --git a/base/message_loop_proxy_impl_unittest.cc b/base/message_loop/message_loop_proxy_impl_unittest.cc
similarity index 72%
rename from base/message_loop_proxy_impl_unittest.cc
rename to base/message_loop/message_loop_proxy_impl_unittest.cc
index e120b39..4c88887 100644
--- a/base/message_loop_proxy_impl_unittest.cc
+++ b/base/message_loop/message_loop_proxy_impl_unittest.cc
@@ -2,16 +2,17 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-#include "base/message_loop_proxy_impl.h"
+#include "base/message_loop/message_loop_proxy_impl.h"
#include "base/bind.h"
#include "base/memory/scoped_ptr.h"
#include "base/message_loop.h"
-#include "base/message_loop_proxy.h"
+#include "base/message_loop/message_loop_proxy.h"
#include "base/threading/thread.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "testing/platform_test.h"
+namespace base {
class MessageLoopProxyImplTest : public testing::Test {
public:
@@ -27,19 +28,19 @@
void AssertOnIOThread() const {
ASSERT_TRUE(io_thread_->message_loop_proxy()->BelongsToCurrentThread());
ASSERT_EQ(io_thread_->message_loop_proxy(),
- base::MessageLoopProxy::current());
+ MessageLoopProxy::current());
}
void AssertOnFileThread() const {
ASSERT_TRUE(file_thread_->message_loop_proxy()->BelongsToCurrentThread());
ASSERT_EQ(file_thread_->message_loop_proxy(),
- base::MessageLoopProxy::current());
+ MessageLoopProxy::current());
}
protected:
virtual void SetUp() OVERRIDE {
- io_thread_.reset(new base::Thread("MessageLoopProxyImplTest_IO"));
- file_thread_.reset(new base::Thread("MessageLoopProxyImplTest_File"));
+ io_thread_.reset(new Thread("MessageLoopProxyImplTest_IO"));
+ file_thread_.reset(new Thread("MessageLoopProxyImplTest_File"));
io_thread_->Start();
file_thread_->Start();
}
@@ -71,8 +72,8 @@
MessageLoopProxyImplTest* test_;
};
- scoped_ptr<base::Thread> io_thread_;
- scoped_ptr<base::Thread> file_thread_;
+ scoped_ptr<Thread> io_thread_;
+ scoped_ptr<Thread> file_thread_;
private:
mutable MessageLoop loop_;
@@ -92,35 +93,37 @@
TEST_F(MessageLoopProxyImplTest, PostTask) {
EXPECT_TRUE(file_thread_->message_loop_proxy()->PostTask(
- FROM_HERE, base::Bind(&MessageLoopProxyImplTest::BasicFunction,
- base::Unretained(this))));
+ FROM_HERE, Bind(&MessageLoopProxyImplTest::BasicFunction,
+ Unretained(this))));
MessageLoop::current()->Run();
}
TEST_F(MessageLoopProxyImplTest, PostTaskAfterThreadExits) {
- scoped_ptr<base::Thread> test_thread(
- new base::Thread("MessageLoopProxyImplTest_Dummy"));
+ scoped_ptr<Thread> test_thread(
+ new Thread("MessageLoopProxyImplTest_Dummy"));
test_thread->Start();
- scoped_refptr<base::MessageLoopProxy> message_loop_proxy =
+ scoped_refptr<MessageLoopProxy> message_loop_proxy =
test_thread->message_loop_proxy();
test_thread->Stop();
bool ret = message_loop_proxy->PostTask(
FROM_HERE,
- base::Bind(&MessageLoopProxyImplTest::AssertNotRun));
+ Bind(&MessageLoopProxyImplTest::AssertNotRun));
EXPECT_FALSE(ret);
}
TEST_F(MessageLoopProxyImplTest, PostTaskAfterThreadIsDeleted) {
- scoped_refptr<base::MessageLoopProxy> message_loop_proxy;
+ scoped_refptr<MessageLoopProxy> message_loop_proxy;
{
- scoped_ptr<base::Thread> test_thread(
- new base::Thread("MessageLoopProxyImplTest_Dummy"));
+ scoped_ptr<Thread> test_thread(
+ new Thread("MessageLoopProxyImplTest_Dummy"));
test_thread->Start();
message_loop_proxy = test_thread->message_loop_proxy();
}
bool ret = message_loop_proxy->PostTask(
FROM_HERE,
- base::Bind(&MessageLoopProxyImplTest::AssertNotRun));
+ Bind(&MessageLoopProxyImplTest::AssertNotRun));
EXPECT_FALSE(ret);
}
+
+} // namespace base
diff --git a/base/message_loop_proxy_unittest.cc b/base/message_loop/message_loop_proxy_unittest.cc
similarity index 98%
rename from base/message_loop_proxy_unittest.cc
rename to base/message_loop/message_loop_proxy_unittest.cc
index aaabef6..e373059 100644
--- a/base/message_loop_proxy_unittest.cc
+++ b/base/message_loop/message_loop_proxy_unittest.cc
@@ -2,7 +2,7 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-#include "base/message_loop_proxy.h"
+#include "base/message_loop/message_loop_proxy.h"
#include "base/atomic_sequence_num.h"
#include "base/bind.h"
diff --git a/base/message_loop_proxy.h b/base/message_loop_proxy.h
index ce949dd..d8a3641 100644
--- a/base/message_loop_proxy.h
+++ b/base/message_loop_proxy.h
@@ -1,38 +1,7 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
+// Copyright (c) 2013 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 BASE_MESSAGE_LOOP_PROXY_H_
-#define BASE_MESSAGE_LOOP_PROXY_H_
-
-#include "base/base_export.h"
-#include "base/compiler_specific.h"
-#include "base/memory/ref_counted.h"
-#include "base/single_thread_task_runner.h"
-
-namespace base {
-
-// This class provides a thread-safe refcounted interface to the Post* methods
-// of a message loop. This class can outlive the target message loop.
-// MessageLoopProxy objects are constructed automatically for all MessageLoops.
-// So, to access them, you can use any of the following:
-// Thread::message_loop_proxy()
-// MessageLoop::current()->message_loop_proxy()
-// MessageLoopProxy::current()
-//
-// TODO(akalin): Now that we have the *TaskRunner interfaces, we can
-// merge this with MessageLoopProxyImpl.
-class BASE_EXPORT MessageLoopProxy : public SingleThreadTaskRunner {
- public:
- // Gets the MessageLoopProxy for the current message loop, creating one if
- // needed.
- static scoped_refptr<MessageLoopProxy> current();
-
- protected:
- MessageLoopProxy();
- virtual ~MessageLoopProxy();
-};
-
-} // namespace base
-
-#endif // BASE_MESSAGE_LOOP_PROXY_H_
+// TODO(brettw) remove this forwarding file when all users reference the new
+// location.
+#include "base/message_loop/message_loop_proxy.h"
diff --git a/base/message_loop_unittest.cc b/base/message_loop_unittest.cc
index 984a025..ec182d1 100644
--- a/base/message_loop_unittest.cc
+++ b/base/message_loop_unittest.cc
@@ -13,6 +13,7 @@
#include "base/pending_task.h"
#include "base/posix/eintr_wrapper.h"
#include "base/run_loop.h"
+#include "base/synchronization/waitable_event.h"
#include "base/thread_task_runner_handle.h"
#include "base/threading/platform_thread.h"
#include "base/threading/thread.h"
@@ -23,18 +24,27 @@
#include "base/win/scoped_handle.h"
#endif
-using base::PlatformThread;
-using base::Thread;
-using base::Time;
-using base::TimeDelta;
-using base::TimeTicks;
+namespace base {
+
+class MessageLoopLockTest {
+ public:
+ static void LockWaitUnLock(MessageLoop* loop,
+ base::WaitableEvent* caller_wait,
+ base::WaitableEvent* caller_signal) {
+
+ loop->incoming_queue_lock_.Acquire();
+ caller_wait->Signal();
+ caller_signal->Wait();
+ loop->incoming_queue_lock_.Release();
+ }
+};
// TODO(darin): Platform-specific MessageLoop tests should be grouped together
// to avoid chopping this file up with so many #ifdefs.
namespace {
-class Foo : public base::RefCounted<Foo> {
+class Foo : public RefCounted<Foo> {
public:
Foo() : test_count_(0) {
}
@@ -73,7 +83,7 @@
const std::string& result() const { return result_; }
private:
- friend class base::RefCounted<Foo>;
+ friend class RefCounted<Foo>;
~Foo() {}
@@ -87,22 +97,43 @@
// Add tests to message loop
scoped_refptr<Foo> foo(new Foo());
std::string a("a"), b("b"), c("c"), d("d");
- MessageLoop::current()->PostTask(FROM_HERE, base::Bind(
+ MessageLoop::current()->PostTask(FROM_HERE, Bind(
&Foo::Test0, foo.get()));
- MessageLoop::current()->PostTask(FROM_HERE, base::Bind(
+ MessageLoop::current()->PostTask(FROM_HERE, Bind(
&Foo::Test1ConstRef, foo.get(), a));
- MessageLoop::current()->PostTask(FROM_HERE, base::Bind(
+ MessageLoop::current()->PostTask(FROM_HERE, Bind(
&Foo::Test1Ptr, foo.get(), &b));
- MessageLoop::current()->PostTask(FROM_HERE, base::Bind(
+ MessageLoop::current()->PostTask(FROM_HERE, Bind(
&Foo::Test1Int, foo.get(), 100));
- MessageLoop::current()->PostTask(FROM_HERE, base::Bind(
+ MessageLoop::current()->PostTask(FROM_HERE, Bind(
&Foo::Test2Ptr, foo.get(), &a, &c));
- MessageLoop::current()->PostTask(FROM_HERE, base::Bind(
- &Foo::Test2Mixed, foo.get(), a, &d));
+
+ // TryPost with no contention. It must succeed.
+ EXPECT_TRUE(MessageLoop::current()->TryPostTask(FROM_HERE, Bind(
+ &Foo::Test2Mixed, foo.get(), a, &d)));
+
+ // TryPost with simulated contention. It must fail. We wait for a helper
+ // thread to lock the queue, we TryPost on this thread and finally we
+ // signal the helper to unlock and exit.
+ WaitableEvent wait(true, false);
+ WaitableEvent signal(true, false);
+ Thread thread("RunTest_PostTask_helper");
+ thread.Start();
+ thread.message_loop()->PostTask(
+ FROM_HERE,
+ base::Bind(&MessageLoopLockTest::LockWaitUnLock,
+ MessageLoop::current(),
+ &wait,
+ &signal));
+
+ wait.Wait();
+ EXPECT_FALSE(MessageLoop::current()->TryPostTask(FROM_HERE, Bind(
+ &Foo::Test2Mixed, foo.get(), a, &d)));
+ signal.Signal();
// After all tests, post a message that will shut down the message loop
- MessageLoop::current()->PostTask(FROM_HERE, base::Bind(
- &MessageLoop::Quit, base::Unretained(MessageLoop::current())));
+ MessageLoop::current()->PostTask(FROM_HERE, Bind(
+ &MessageLoop::Quit, Unretained(MessageLoop::current())));
// Now kick things off
MessageLoop::current()->Run();
@@ -117,22 +148,22 @@
// Add tests to message loop
scoped_refptr<Foo> foo(new Foo());
std::string a("a"), b("b"), c("c"), d("d");
- MessageLoop::current()->PostTask(FROM_HERE, base::Bind(
+ MessageLoop::current()->PostTask(FROM_HERE, Bind(
&Foo::Test0, foo.get()));
- MessageLoop::current()->PostTask(FROM_HERE, base::Bind(
+ MessageLoop::current()->PostTask(FROM_HERE, Bind(
&Foo::Test1ConstRef, foo.get(), a));
- MessageLoop::current()->PostTask(FROM_HERE, base::Bind(
+ MessageLoop::current()->PostTask(FROM_HERE, Bind(
&Foo::Test1Ptr, foo.get(), &b));
- MessageLoop::current()->PostTask(FROM_HERE, base::Bind(
+ MessageLoop::current()->PostTask(FROM_HERE, Bind(
&Foo::Test1Int, foo.get(), 100));
- MessageLoop::current()->PostTask(FROM_HERE, base::Bind(
+ MessageLoop::current()->PostTask(FROM_HERE, Bind(
&Foo::Test2Ptr, foo.get(), &a, &c));
- MessageLoop::current()->PostTask(FROM_HERE, base::Bind(
+ MessageLoop::current()->PostTask(FROM_HERE, Bind(
&Foo::Test2Mixed, foo.get(), a, &d));
// After all tests, post a message that will shut down the message loop
- MessageLoop::current()->PostTask(FROM_HERE, base::Bind(
- &MessageLoop::Quit, base::Unretained(MessageLoop::current())));
+ MessageLoop::current()->PostTask(FROM_HERE, Bind(
+ &MessageLoop::Quit, Unretained(MessageLoop::current())));
// Now kick things off with the SEH block active.
MessageLoop::current()->set_exception_restoration(true);
@@ -172,7 +203,7 @@
Time run_time;
loop.PostDelayedTask(
- FROM_HERE, base::Bind(&RecordRunTimeFunc, &run_time, &num_tasks),
+ FROM_HERE, Bind(&RecordRunTimeFunc, &run_time, &num_tasks),
kDelay);
Time time_before_run = Time::Now();
@@ -193,13 +224,13 @@
loop.PostDelayedTask(
FROM_HERE,
- base::Bind(&RecordRunTimeFunc, &run_time1, &num_tasks),
+ Bind(&RecordRunTimeFunc, &run_time1, &num_tasks),
TimeDelta::FromMilliseconds(200));
// If we get a large pause in execution (due to a context switch) here, this
// test could fail.
loop.PostDelayedTask(
FROM_HERE,
- base::Bind(&RecordRunTimeFunc, &run_time2, &num_tasks),
+ Bind(&RecordRunTimeFunc, &run_time2, &num_tasks),
TimeDelta::FromMilliseconds(10));
loop.Run();
@@ -227,10 +258,10 @@
loop.PostDelayedTask(
FROM_HERE,
- base::Bind(&RecordRunTimeFunc, &run_time1, &num_tasks), kDelay);
+ Bind(&RecordRunTimeFunc, &run_time1, &num_tasks), kDelay);
loop.PostDelayedTask(
FROM_HERE,
- base::Bind(&RecordRunTimeFunc, &run_time2, &num_tasks), kDelay);
+ Bind(&RecordRunTimeFunc, &run_time2, &num_tasks), kDelay);
loop.Run();
EXPECT_EQ(0, num_tasks);
@@ -250,10 +281,10 @@
int num_tasks = 2;
Time run_time;
- loop.PostTask(FROM_HERE, base::Bind(&SlowFunc, kPause, &num_tasks));
+ loop.PostTask(FROM_HERE, Bind(&SlowFunc, kPause, &num_tasks));
loop.PostDelayedTask(
FROM_HERE,
- base::Bind(&RecordRunTimeFunc, &run_time, &num_tasks),
+ Bind(&RecordRunTimeFunc, &run_time, &num_tasks),
TimeDelta::FromMilliseconds(10));
Time time_before_run = Time::Now();
@@ -281,10 +312,10 @@
// Clutter the ML with tasks.
for (int i = 1; i < num_tasks; ++i)
loop.PostTask(FROM_HERE,
- base::Bind(&RecordRunTimeFunc, &run_time1, &num_tasks));
+ Bind(&RecordRunTimeFunc, &run_time1, &num_tasks));
loop.PostDelayedTask(
- FROM_HERE, base::Bind(&RecordRunTimeFunc, &run_time2, &num_tasks),
+ FROM_HERE, Bind(&RecordRunTimeFunc, &run_time2, &num_tasks),
TimeDelta::FromMilliseconds(1));
loop.Run();
@@ -307,11 +338,11 @@
loop.PostDelayedTask(
FROM_HERE,
- base::Bind(&RecordRunTimeFunc, &run_time1, &num_tasks),
+ Bind(&RecordRunTimeFunc, &run_time1, &num_tasks),
TimeDelta::FromSeconds(1000));
loop.PostDelayedTask(
FROM_HERE,
- base::Bind(&RecordRunTimeFunc, &run_time2, &num_tasks),
+ Bind(&RecordRunTimeFunc, &run_time2, &num_tasks),
TimeDelta::FromMilliseconds(10));
Time start_time = Time::Now();
@@ -327,7 +358,7 @@
// and then run all pending to force them both to have run. This is just
// encouraging flakiness if there is any.
PlatformThread::Sleep(TimeDelta::FromMilliseconds(100));
- base::RunLoop().RunUntilIdle();
+ RunLoop().RunUntilIdle();
EXPECT_TRUE(run_time1.is_null());
EXPECT_FALSE(run_time2.is_null());
@@ -356,18 +387,18 @@
int num_tasks = 1;
Time run_time;
- loop.PostTask(FROM_HERE, base::Bind(&SubPumpFunc));
+ loop.PostTask(FROM_HERE, Bind(&SubPumpFunc));
// This very delayed task should never run.
loop.PostDelayedTask(
FROM_HERE,
- base::Bind(&RecordRunTimeFunc, &run_time, &num_tasks),
+ Bind(&RecordRunTimeFunc, &run_time, &num_tasks),
TimeDelta::FromSeconds(1000));
// This slightly delayed task should run from within SubPumpFunc).
loop.PostDelayedTask(
FROM_HERE,
- base::Bind(&PostQuitMessage, 0),
+ Bind(&PostQuitMessage, 0),
TimeDelta::FromMilliseconds(10));
Time start_time = Time::Now();
@@ -383,7 +414,7 @@
// and then run all pending to force them both to have run. This is just
// encouraging flakiness if there is any.
PlatformThread::Sleep(TimeDelta::FromMilliseconds(100));
- base::RunLoop().RunUntilIdle();
+ RunLoop().RunUntilIdle();
EXPECT_TRUE(run_time.is_null());
}
@@ -393,7 +424,7 @@
// This is used to inject a test point for recording the destructor calls for
// Closure objects send to MessageLoop::PostTask(). It is awkward usage since we
// are trying to hook the actual destruction, which is not a common operation.
-class RecordDeletionProbe : public base::RefCounted<RecordDeletionProbe> {
+class RecordDeletionProbe : public RefCounted<RecordDeletionProbe> {
public:
RecordDeletionProbe(RecordDeletionProbe* post_on_delete, bool* was_deleted)
: post_on_delete_(post_on_delete), was_deleted_(was_deleted) {
@@ -401,14 +432,14 @@
void Run() {}
private:
- friend class base::RefCounted<RecordDeletionProbe>;
+ friend class RefCounted<RecordDeletionProbe>;
~RecordDeletionProbe() {
*was_deleted_ = true;
if (post_on_delete_)
MessageLoop::current()->PostTask(
FROM_HERE,
- base::Bind(&RecordDeletionProbe::Run, post_on_delete_.get()));
+ Bind(&RecordDeletionProbe::Run, post_on_delete_.get()));
}
scoped_refptr<RecordDeletionProbe> post_on_delete_;
@@ -421,11 +452,11 @@
{
MessageLoop loop(message_loop_type);
loop.PostTask(
- FROM_HERE, base::Bind(&RecordDeletionProbe::Run,
+ FROM_HERE, Bind(&RecordDeletionProbe::Run,
new RecordDeletionProbe(NULL, &a_was_deleted)));
// TODO(ajwong): Do we really need 1000ms here?
loop.PostDelayedTask(
- FROM_HERE, base::Bind(&RecordDeletionProbe::Run,
+ FROM_HERE, Bind(&RecordDeletionProbe::Run,
new RecordDeletionProbe(NULL, &b_was_deleted)),
TimeDelta::FromMilliseconds(1000));
}
@@ -444,7 +475,7 @@
RecordDeletionProbe* a = new RecordDeletionProbe(NULL, &a_was_deleted);
RecordDeletionProbe* b = new RecordDeletionProbe(a, &b_was_deleted);
RecordDeletionProbe* c = new RecordDeletionProbe(b, &c_was_deleted);
- loop.PostTask(FROM_HERE, base::Bind(&RecordDeletionProbe::Run, c));
+ loop.PostTask(FROM_HERE, Bind(&RecordDeletionProbe::Run, c));
}
EXPECT_TRUE(a_was_deleted);
EXPECT_TRUE(b_was_deleted);
@@ -455,7 +486,7 @@
if (*depth > 0) {
*depth -= 1;
MessageLoop::current()->PostTask(FROM_HERE,
- base::Bind(&NestingFunc, depth));
+ Bind(&NestingFunc, depth));
MessageLoop::current()->SetNestableTasksAllowed(true);
MessageLoop::current()->Run();
@@ -473,7 +504,7 @@
// This task throws an SEH exception: initially write to an invalid address.
// If the right SEH filter is installed, it will fix the error.
-class Crasher : public base::RefCounted<Crasher> {
+class Crasher : public RefCounted<Crasher> {
public:
// Ctor. If trash_SEH_handler is true, the task will override the unhandled
// exception handler with one sure to crash this test.
@@ -552,7 +583,7 @@
MessageLoop::current()->PostTask(
FROM_HERE,
- base::Bind(&Crasher::Run, new Crasher(false)));
+ Bind(&Crasher::Run, new Crasher(false)));
MessageLoop::current()->set_exception_restoration(true);
MessageLoop::current()->Run();
MessageLoop::current()->set_exception_restoration(false);
@@ -571,7 +602,7 @@
MessageLoop::current()->PostTask(
FROM_HERE,
- base::Bind(&Crasher::Run, new Crasher(true)));
+ Bind(&Crasher::Run, new Crasher(true)));
MessageLoop::current()->set_exception_restoration(true);
MessageLoop::current()->Run();
MessageLoop::current()->set_exception_restoration(false);
@@ -586,7 +617,7 @@
int depth = 100;
MessageLoop::current()->PostTask(FROM_HERE,
- base::Bind(&NestingFunc, &depth));
+ Bind(&NestingFunc, &depth));
MessageLoop::current()->Run();
EXPECT_EQ(depth, 0);
}
@@ -714,7 +745,7 @@
MessageLoop::current()->SetNestableTasksAllowed(true);
MessageLoop::current()->PostTask(
FROM_HERE,
- base::Bind(&RecursiveFunc, order, cookie, depth - 1, is_reentrant));
+ Bind(&RecursiveFunc, order, cookie, depth - 1, is_reentrant));
}
order->RecordEnd(RECURSIVE, cookie);
}
@@ -744,11 +775,11 @@
TaskList* order,
bool is_reentrant) {
target->PostTask(FROM_HERE,
- base::Bind(&RecursiveFunc, order, 1, 2, is_reentrant));
+ Bind(&RecursiveFunc, order, 1, 2, is_reentrant));
target->PostTask(FROM_HERE,
- base::Bind(&MessageBoxFunc, order, 2, is_reentrant));
+ Bind(&MessageBoxFunc, order, 2, is_reentrant));
target->PostTask(FROM_HERE,
- base::Bind(&RecursiveFunc, order, 3, 2, is_reentrant));
+ Bind(&RecursiveFunc, order, 3, 2, is_reentrant));
// The trick here is that for recursive task processing, this task will be
// ran _inside_ the MessageBox message loop, dismissing the MessageBox
// without a chance.
@@ -756,9 +787,9 @@
// MessageBox will have been dismissed by the code below, where
// expect_window_ is true.
target->PostTask(FROM_HERE,
- base::Bind(&EndDialogFunc, order, 4));
+ Bind(&EndDialogFunc, order, 4));
target->PostTask(FROM_HERE,
- base::Bind(&QuitFunc, order, 5));
+ Bind(&QuitFunc, order, 5));
// Enforce that every tasks are sent before starting to run the main thread
// message loop.
@@ -792,13 +823,13 @@
TaskList order;
MessageLoop::current()->PostTask(
FROM_HERE,
- base::Bind(&RecursiveFunc, &order, 1, 2, false));
+ Bind(&RecursiveFunc, &order, 1, 2, false));
MessageLoop::current()->PostTask(
FROM_HERE,
- base::Bind(&RecursiveFunc, &order, 2, 2, false));
+ Bind(&RecursiveFunc, &order, 2, 2, false));
MessageLoop::current()->PostTask(
FROM_HERE,
- base::Bind(&QuitFunc, &order, 3));
+ Bind(&QuitFunc, &order, 3));
MessageLoop::current()->Run();
@@ -826,16 +857,16 @@
EXPECT_TRUE(MessageLoop::current()->NestableTasksAllowed());
TaskList order;
MessageLoop::current()->PostTask(
- FROM_HERE, base::Bind(&RecursiveSlowFunc, &order, 1, 2, false));
+ FROM_HERE, Bind(&RecursiveSlowFunc, &order, 1, 2, false));
MessageLoop::current()->PostTask(
- FROM_HERE, base::Bind(&RecursiveSlowFunc, &order, 2, 2, false));
+ FROM_HERE, Bind(&RecursiveSlowFunc, &order, 2, 2, false));
MessageLoop::current()->PostDelayedTask(
FROM_HERE,
- base::Bind(&OrderedFunc, &order, 3),
+ Bind(&OrderedFunc, &order, 3),
TimeDelta::FromMilliseconds(5));
MessageLoop::current()->PostDelayedTask(
FROM_HERE,
- base::Bind(&QuitFunc, &order, 4),
+ Bind(&QuitFunc, &order, 4),
TimeDelta::FromMilliseconds(5));
MessageLoop::current()->Run();
@@ -865,11 +896,11 @@
TaskList order;
MessageLoop::current()->PostTask(
- FROM_HERE, base::Bind(&RecursiveFunc, &order, 1, 2, true));
+ FROM_HERE, Bind(&RecursiveFunc, &order, 1, 2, true));
MessageLoop::current()->PostTask(
- FROM_HERE, base::Bind(&RecursiveFunc, &order, 2, 2, true));
+ FROM_HERE, Bind(&RecursiveFunc, &order, 2, 2, true));
MessageLoop::current()->PostTask(
- FROM_HERE, base::Bind(&QuitFunc, &order, 3));
+ FROM_HERE, Bind(&QuitFunc, &order, 3));
MessageLoop::current()->Run();
@@ -904,9 +935,9 @@
options.message_loop_type = message_loop_type;
ASSERT_EQ(true, worker.StartWithOptions(options));
TaskList order;
- base::win::ScopedHandle event(CreateEvent(NULL, FALSE, FALSE, NULL));
+ win::ScopedHandle event(CreateEvent(NULL, FALSE, FALSE, NULL));
worker.message_loop()->PostTask(FROM_HERE,
- base::Bind(&RecursiveFuncWin,
+ Bind(&RecursiveFuncWin,
MessageLoop::current(),
event.Get(),
true,
@@ -948,9 +979,9 @@
options.message_loop_type = message_loop_type;
ASSERT_EQ(true, worker.StartWithOptions(options));
TaskList order;
- base::win::ScopedHandle event(CreateEvent(NULL, FALSE, FALSE, NULL));
+ win::ScopedHandle event(CreateEvent(NULL, FALSE, FALSE, NULL));
worker.message_loop()->PostTask(FROM_HERE,
- base::Bind(&RecursiveFuncWin,
+ Bind(&RecursiveFuncWin,
MessageLoop::current(),
event.Get(),
false,
@@ -972,7 +1003,7 @@
EXPECT_EQ(order.Get(7), TaskItem(MESSAGEBOX, 2, false));
/* The order can subtly change here. The reason is that when RecursiveFunc(1)
is called in the main thread, if it is faster than getting to the
- PostTask(FROM_HERE, base::Bind(&QuitFunc) execution, the order of task
+ PostTask(FROM_HERE, Bind(&QuitFunc) execution, the order of task
execution can change. We don't care anyway that the order isn't correct.
EXPECT_EQ(order.Get(8), TaskItem(QUITMESSAGELOOP, 5, true));
EXPECT_EQ(order.Get(9), TaskItem(QUITMESSAGELOOP, 5, false));
@@ -993,12 +1024,12 @@
order->RecordStart(PUMPS, cookie);
{
MessageLoop::ScopedNestableTaskAllower allow(MessageLoop::current());
- base::RunLoop().RunUntilIdle();
+ RunLoop().RunUntilIdle();
}
order->RecordEnd(PUMPS, cookie);
}
-void FuncThatRuns(TaskList* order, int cookie, base::RunLoop* run_loop) {
+void FuncThatRuns(TaskList* order, int cookie, RunLoop* run_loop) {
order->RecordStart(RUNS, cookie);
{
MessageLoop::ScopedNestableTaskAllower allow(MessageLoop::current());
@@ -1020,11 +1051,11 @@
MessageLoop::current()->PostNonNestableTask(
FROM_HERE,
- base::Bind(&OrderedFunc, &order, 1));
+ Bind(&OrderedFunc, &order, 1));
MessageLoop::current()->PostTask(FROM_HERE,
- base::Bind(&OrderedFunc, &order, 2));
+ Bind(&OrderedFunc, &order, 2));
MessageLoop::current()->PostTask(FROM_HERE,
- base::Bind(&QuitFunc, &order, 3));
+ Bind(&QuitFunc, &order, 3));
MessageLoop::current()->Run();
// FIFO order.
@@ -1046,33 +1077,33 @@
MessageLoop::current()->PostTask(
FROM_HERE,
- base::Bind(&FuncThatPumps, &order, 1));
+ Bind(&FuncThatPumps, &order, 1));
if (use_delayed) {
MessageLoop::current()->PostNonNestableDelayedTask(
FROM_HERE,
- base::Bind(&OrderedFunc, &order, 2),
+ Bind(&OrderedFunc, &order, 2),
TimeDelta::FromMilliseconds(1));
} else {
MessageLoop::current()->PostNonNestableTask(
FROM_HERE,
- base::Bind(&OrderedFunc, &order, 2));
+ Bind(&OrderedFunc, &order, 2));
}
MessageLoop::current()->PostTask(FROM_HERE,
- base::Bind(&OrderedFunc, &order, 3));
+ Bind(&OrderedFunc, &order, 3));
MessageLoop::current()->PostTask(
FROM_HERE,
- base::Bind(&SleepFunc, &order, 4, TimeDelta::FromMilliseconds(50)));
+ Bind(&SleepFunc, &order, 4, TimeDelta::FromMilliseconds(50)));
MessageLoop::current()->PostTask(FROM_HERE,
- base::Bind(&OrderedFunc, &order, 5));
+ Bind(&OrderedFunc, &order, 5));
if (use_delayed) {
MessageLoop::current()->PostNonNestableDelayedTask(
FROM_HERE,
- base::Bind(&QuitFunc, &order, 6),
+ Bind(&QuitFunc, &order, 6),
TimeDelta::FromMilliseconds(2));
} else {
MessageLoop::current()->PostNonNestableTask(
FROM_HERE,
- base::Bind(&QuitFunc, &order, 6));
+ Bind(&QuitFunc, &order, 6));
}
MessageLoop::current()->Run();
@@ -1099,20 +1130,20 @@
TaskList order;
- base::RunLoop run_loop;
+ RunLoop run_loop;
MessageLoop::current()->PostTask(FROM_HERE,
- base::Bind(&FuncThatRuns, &order, 1, base::Unretained(&run_loop)));
+ Bind(&FuncThatRuns, &order, 1, Unretained(&run_loop)));
MessageLoop::current()->PostTask(
- FROM_HERE, base::Bind(&OrderedFunc, &order, 2));
+ FROM_HERE, Bind(&OrderedFunc, &order, 2));
MessageLoop::current()->PostTask(
- FROM_HERE, base::Bind(&FuncThatQuitsNow));
+ FROM_HERE, Bind(&FuncThatQuitsNow));
MessageLoop::current()->PostTask(
- FROM_HERE, base::Bind(&OrderedFunc, &order, 3));
+ FROM_HERE, Bind(&OrderedFunc, &order, 3));
MessageLoop::current()->PostTask(
- FROM_HERE, base::Bind(&FuncThatQuitsNow));
+ FROM_HERE, Bind(&FuncThatQuitsNow));
MessageLoop::current()->PostTask(
- FROM_HERE, base::Bind(&OrderedFunc, &order, 4)); // never runs
+ FROM_HERE, Bind(&OrderedFunc, &order, 4)); // never runs
MessageLoop::current()->Run();
@@ -1133,14 +1164,14 @@
TaskList order;
- base::RunLoop run_loop;
+ RunLoop run_loop;
run_loop.Quit();
MessageLoop::current()->PostTask(
- FROM_HERE, base::Bind(&OrderedFunc, &order, 1)); // never runs
+ FROM_HERE, Bind(&OrderedFunc, &order, 1)); // never runs
MessageLoop::current()->PostTask(
- FROM_HERE, base::Bind(&FuncThatQuitsNow)); // never runs
+ FROM_HERE, Bind(&FuncThatQuitsNow)); // never runs
run_loop.Run();
@@ -1153,16 +1184,16 @@
TaskList order;
- base::RunLoop run_loop;
+ RunLoop run_loop;
MessageLoop::current()->PostTask(
- FROM_HERE, base::Bind(&OrderedFunc, &order, 1));
+ FROM_HERE, Bind(&OrderedFunc, &order, 1));
MessageLoop::current()->PostTask(
FROM_HERE, run_loop.QuitClosure());
MessageLoop::current()->PostTask(
- FROM_HERE, base::Bind(&OrderedFunc, &order, 2)); // never runs
+ FROM_HERE, Bind(&OrderedFunc, &order, 2)); // never runs
MessageLoop::current()->PostTask(
- FROM_HERE, base::Bind(&FuncThatQuitsNow)); // never runs
+ FROM_HERE, Bind(&FuncThatQuitsNow)); // never runs
run_loop.Run();
@@ -1179,24 +1210,24 @@
TaskList order;
- base::RunLoop run_loop;
+ RunLoop run_loop;
MessageLoop::current()->PostTask(FROM_HERE,
- base::Bind(&FuncThatRuns, &order, 1, base::Unretained(&run_loop)));
+ Bind(&FuncThatRuns, &order, 1, Unretained(&run_loop)));
MessageLoop::current()->PostTask(
- FROM_HERE, base::Bind(&OrderedFunc, &order, 2));
+ FROM_HERE, Bind(&OrderedFunc, &order, 2));
MessageLoop::current()->PostTask(
- FROM_HERE, base::Bind(&FuncThatQuitsNow));
+ FROM_HERE, Bind(&FuncThatQuitsNow));
MessageLoop::current()->PostTask(
- FROM_HERE, base::Bind(&OrderedFunc, &order, 3));
+ FROM_HERE, Bind(&OrderedFunc, &order, 3));
MessageLoop::current()->PostTask(
FROM_HERE, run_loop.QuitClosure()); // has no affect
MessageLoop::current()->PostTask(
- FROM_HERE, base::Bind(&OrderedFunc, &order, 4));
+ FROM_HERE, Bind(&OrderedFunc, &order, 4));
MessageLoop::current()->PostTask(
- FROM_HERE, base::Bind(&FuncThatQuitsNow));
+ FROM_HERE, Bind(&FuncThatQuitsNow));
- base::RunLoop outer_run_loop;
+ RunLoop outer_run_loop;
outer_run_loop.Run();
ASSERT_EQ(8U, order.Size());
@@ -1218,15 +1249,15 @@
TaskList order;
- base::RunLoop outer_run_loop;
- base::RunLoop nested_run_loop;
+ RunLoop outer_run_loop;
+ RunLoop nested_run_loop;
MessageLoop::current()->PostTask(FROM_HERE,
- base::Bind(&FuncThatRuns, &order, 1, base::Unretained(&nested_run_loop)));
+ Bind(&FuncThatRuns, &order, 1, Unretained(&nested_run_loop)));
MessageLoop::current()->PostTask(
FROM_HERE, outer_run_loop.QuitClosure());
MessageLoop::current()->PostTask(
- FROM_HERE, base::Bind(&OrderedFunc, &order, 2));
+ FROM_HERE, Bind(&OrderedFunc, &order, 2));
MessageLoop::current()->PostTask(
FROM_HERE, nested_run_loop.QuitClosure());
@@ -1247,15 +1278,15 @@
TaskList order;
- base::RunLoop outer_run_loop;
- base::RunLoop nested_run_loop;
+ RunLoop outer_run_loop;
+ RunLoop nested_run_loop;
MessageLoop::current()->PostTask(FROM_HERE,
- base::Bind(&FuncThatRuns, &order, 1, base::Unretained(&nested_run_loop)));
+ Bind(&FuncThatRuns, &order, 1, Unretained(&nested_run_loop)));
MessageLoop::current()->PostTask(
FROM_HERE, nested_run_loop.QuitClosure());
MessageLoop::current()->PostTask(
- FROM_HERE, base::Bind(&OrderedFunc, &order, 2));
+ FROM_HERE, Bind(&OrderedFunc, &order, 2));
MessageLoop::current()->PostTask(
FROM_HERE, outer_run_loop.QuitClosure());
@@ -1276,16 +1307,16 @@
TaskList order;
- base::RunLoop outer_run_loop;
- base::RunLoop nested_run_loop;
- base::RunLoop bogus_run_loop;
+ RunLoop outer_run_loop;
+ RunLoop nested_run_loop;
+ RunLoop bogus_run_loop;
MessageLoop::current()->PostTask(FROM_HERE,
- base::Bind(&FuncThatRuns, &order, 1, base::Unretained(&nested_run_loop)));
+ Bind(&FuncThatRuns, &order, 1, Unretained(&nested_run_loop)));
MessageLoop::current()->PostTask(
FROM_HERE, bogus_run_loop.QuitClosure());
MessageLoop::current()->PostTask(
- FROM_HERE, base::Bind(&OrderedFunc, &order, 2));
+ FROM_HERE, Bind(&OrderedFunc, &order, 2));
MessageLoop::current()->PostTask(
FROM_HERE, outer_run_loop.QuitClosure());
MessageLoop::current()->PostTask(
@@ -1308,42 +1339,42 @@
TaskList order;
- base::RunLoop outer_run_loop;
- base::RunLoop nested_loop1;
- base::RunLoop nested_loop2;
- base::RunLoop nested_loop3;
- base::RunLoop nested_loop4;
+ RunLoop outer_run_loop;
+ RunLoop nested_loop1;
+ RunLoop nested_loop2;
+ RunLoop nested_loop3;
+ RunLoop nested_loop4;
MessageLoop::current()->PostTask(FROM_HERE,
- base::Bind(&FuncThatRuns, &order, 1, base::Unretained(&nested_loop1)));
+ Bind(&FuncThatRuns, &order, 1, Unretained(&nested_loop1)));
MessageLoop::current()->PostTask(FROM_HERE,
- base::Bind(&FuncThatRuns, &order, 2, base::Unretained(&nested_loop2)));
+ Bind(&FuncThatRuns, &order, 2, Unretained(&nested_loop2)));
MessageLoop::current()->PostTask(FROM_HERE,
- base::Bind(&FuncThatRuns, &order, 3, base::Unretained(&nested_loop3)));
+ Bind(&FuncThatRuns, &order, 3, Unretained(&nested_loop3)));
MessageLoop::current()->PostTask(FROM_HERE,
- base::Bind(&FuncThatRuns, &order, 4, base::Unretained(&nested_loop4)));
+ Bind(&FuncThatRuns, &order, 4, Unretained(&nested_loop4)));
MessageLoop::current()->PostTask(
- FROM_HERE, base::Bind(&OrderedFunc, &order, 5));
+ FROM_HERE, Bind(&OrderedFunc, &order, 5));
MessageLoop::current()->PostTask(
FROM_HERE, outer_run_loop.QuitClosure());
MessageLoop::current()->PostTask(
- FROM_HERE, base::Bind(&OrderedFunc, &order, 6));
+ FROM_HERE, Bind(&OrderedFunc, &order, 6));
MessageLoop::current()->PostTask(
FROM_HERE, nested_loop1.QuitClosure());
MessageLoop::current()->PostTask(
- FROM_HERE, base::Bind(&OrderedFunc, &order, 7));
+ FROM_HERE, Bind(&OrderedFunc, &order, 7));
MessageLoop::current()->PostTask(
FROM_HERE, nested_loop2.QuitClosure());
MessageLoop::current()->PostTask(
- FROM_HERE, base::Bind(&OrderedFunc, &order, 8));
+ FROM_HERE, Bind(&OrderedFunc, &order, 8));
MessageLoop::current()->PostTask(
FROM_HERE, nested_loop3.QuitClosure());
MessageLoop::current()->PostTask(
- FROM_HERE, base::Bind(&OrderedFunc, &order, 9));
+ FROM_HERE, Bind(&OrderedFunc, &order, 9));
MessageLoop::current()->PostTask(
FROM_HERE, nested_loop4.QuitClosure());
MessageLoop::current()->PostTask(
- FROM_HERE, base::Bind(&OrderedFunc, &order, 10));
+ FROM_HERE, Bind(&OrderedFunc, &order, 10));
outer_run_loop.Run();
@@ -1374,7 +1405,7 @@
if (posts_remaining > 1) {
MessageLoop::current()->PostTask(
FROM_HERE,
- base::Bind(&PostNTasksThenQuit, posts_remaining - 1));
+ Bind(&PostNTasksThenQuit, posts_remaining - 1));
} else {
MessageLoop::current()->QuitWhenIdle();
}
@@ -1383,7 +1414,7 @@
void RunTest_RecursivePosts(MessageLoop::Type message_loop_type,
int num_times) {
MessageLoop loop(message_loop_type);
- loop.PostTask(FROM_HERE, base::Bind(&PostNTasksThenQuit, num_times));
+ loop.PostTask(FROM_HERE, Bind(&PostNTasksThenQuit, num_times));
loop.Run();
}
@@ -1393,7 +1424,7 @@
public:
DispatcherImpl() : dispatch_count_(0) {}
- virtual bool Dispatch(const base::NativeEvent& msg) OVERRIDE {
+ virtual bool Dispatch(const NativeEvent& msg) OVERRIDE {
::TranslateMessage(&msg);
::DispatchMessage(&msg);
// Do not count WM_TIMER since it is not what we post and it will cause
@@ -1417,16 +1448,16 @@
MessageLoop::current()->PostDelayedTask(
FROM_HERE,
- base::Bind(&MouseDownUp),
+ Bind(&MouseDownUp),
TimeDelta::FromMilliseconds(100));
DispatcherImpl dispatcher;
- base::RunLoop run_loop(&dispatcher);
+ RunLoop run_loop(&dispatcher);
run_loop.Run();
ASSERT_EQ(2, dispatcher.dispatch_count_);
}
LRESULT CALLBACK MsgFilterProc(int code, WPARAM wparam, LPARAM lparam) {
- if (code == base::MessagePumpForUI::kMessageFilterCode) {
+ if (code == MessagePumpForUI::kMessageFilterCode) {
MSG* msg = reinterpret_cast<MSG*>(lparam);
if (msg->message == WM_LBUTTONDOWN)
return TRUE;
@@ -1439,14 +1470,14 @@
MessageLoop::current()->PostDelayedTask(
FROM_HERE,
- base::Bind(&MouseDownUp),
+ Bind(&MouseDownUp),
TimeDelta::FromMilliseconds(100));
HHOOK msg_hook = SetWindowsHookEx(WH_MSGFILTER,
MsgFilterProc,
NULL,
GetCurrentThreadId());
DispatcherImpl dispatcher;
- base::RunLoop run_loop(&dispatcher);
+ RunLoop run_loop(&dispatcher);
run_loop.Run();
ASSERT_EQ(1, dispatcher.dispatch_count_);
UnhookWindowsHookEx(msg_hook);
@@ -1468,7 +1499,7 @@
char buffer_[48];
MessageLoopForIO::IOContext context_;
HANDLE signal_;
- base::win::ScopedHandle file_;
+ win::ScopedHandle file_;
bool wait_;
};
@@ -1505,11 +1536,11 @@
}
void RunTest_IOHandler() {
- base::win::ScopedHandle callback_called(CreateEvent(NULL, TRUE, FALSE, NULL));
+ win::ScopedHandle callback_called(CreateEvent(NULL, TRUE, FALSE, NULL));
ASSERT_TRUE(callback_called.IsValid());
const wchar_t* kPipeName = L"\\\\.\\pipe\\iohandler_pipe";
- base::win::ScopedHandle server(
+ win::ScopedHandle server(
CreateNamedPipe(kPipeName, PIPE_ACCESS_OUTBOUND, 0, 1, 0, 0, 0, NULL));
ASSERT_TRUE(server.IsValid());
@@ -1522,10 +1553,10 @@
ASSERT_TRUE(NULL != thread_loop);
TestIOHandler handler(kPipeName, callback_called, false);
- thread_loop->PostTask(FROM_HERE, base::Bind(&TestIOHandler::Init,
- base::Unretained(&handler)));
+ thread_loop->PostTask(FROM_HERE, Bind(&TestIOHandler::Init,
+ Unretained(&handler)));
// Make sure the thread runs and sleeps for lack of work.
- base::PlatformThread::Sleep(TimeDelta::FromMilliseconds(100));
+ PlatformThread::Sleep(TimeDelta::FromMilliseconds(100));
const char buffer[] = "Hello there!";
DWORD written;
@@ -1538,18 +1569,18 @@
}
void RunTest_WaitForIO() {
- base::win::ScopedHandle callback1_called(
+ win::ScopedHandle callback1_called(
CreateEvent(NULL, TRUE, FALSE, NULL));
- base::win::ScopedHandle callback2_called(
+ win::ScopedHandle callback2_called(
CreateEvent(NULL, TRUE, FALSE, NULL));
ASSERT_TRUE(callback1_called.IsValid());
ASSERT_TRUE(callback2_called.IsValid());
const wchar_t* kPipeName1 = L"\\\\.\\pipe\\iohandler_pipe1";
const wchar_t* kPipeName2 = L"\\\\.\\pipe\\iohandler_pipe2";
- base::win::ScopedHandle server1(
+ win::ScopedHandle server1(
CreateNamedPipe(kPipeName1, PIPE_ACCESS_OUTBOUND, 0, 1, 0, 0, 0, NULL));
- base::win::ScopedHandle server2(
+ win::ScopedHandle server2(
CreateNamedPipe(kPipeName2, PIPE_ACCESS_OUTBOUND, 0, 1, 0, 0, 0, NULL));
ASSERT_TRUE(server1.IsValid());
ASSERT_TRUE(server2.IsValid());
@@ -1564,15 +1595,15 @@
TestIOHandler handler1(kPipeName1, callback1_called, false);
TestIOHandler handler2(kPipeName2, callback2_called, true);
- thread_loop->PostTask(FROM_HERE, base::Bind(&TestIOHandler::Init,
- base::Unretained(&handler1)));
+ thread_loop->PostTask(FROM_HERE, Bind(&TestIOHandler::Init,
+ Unretained(&handler1)));
// TODO(ajwong): Do we really need such long Sleeps in ths function?
// Make sure the thread runs and sleeps for lack of work.
TimeDelta delay = TimeDelta::FromMilliseconds(100);
- base::PlatformThread::Sleep(delay);
- thread_loop->PostTask(FROM_HERE, base::Bind(&TestIOHandler::Init,
- base::Unretained(&handler2)));
- base::PlatformThread::Sleep(delay);
+ PlatformThread::Sleep(delay);
+ thread_loop->PostTask(FROM_HERE, Bind(&TestIOHandler::Init,
+ Unretained(&handler2)));
+ PlatformThread::Sleep(delay);
// At this time handler1 is waiting to be called, and the thread is waiting
// on the Init method of handler2, filtering only handler2 callbacks.
@@ -1580,7 +1611,7 @@
const char buffer[] = "Hello there!";
DWORD written;
EXPECT_TRUE(WriteFile(server1, buffer, sizeof(buffer), &written, NULL));
- base::PlatformThread::Sleep(2 * delay);
+ PlatformThread::Sleep(2 * delay);
EXPECT_EQ(WAIT_TIMEOUT, WaitForSingleObject(callback1_called, 0)) <<
"handler1 has not been called";
@@ -1801,14 +1832,14 @@
virtual ~DummyTaskObserver() {}
- virtual void WillProcessTask(const base::PendingTask& pending_task) OVERRIDE {
+ virtual void WillProcessTask(const PendingTask& pending_task) OVERRIDE {
num_tasks_started_++;
EXPECT_TRUE(pending_task.time_posted != TimeTicks());
EXPECT_LE(num_tasks_started_, num_tasks_);
EXPECT_EQ(num_tasks_started_, num_tasks_processed_ + 1);
}
- virtual void DidProcessTask(const base::PendingTask& pending_task) OVERRIDE {
+ virtual void DidProcessTask(const PendingTask& pending_task) OVERRIDE {
num_tasks_processed_++;
EXPECT_TRUE(pending_task.time_posted != TimeTicks());
EXPECT_LE(num_tasks_started_, num_tasks_);
@@ -1832,7 +1863,7 @@
MessageLoop loop;
loop.AddTaskObserver(&observer);
- loop.PostTask(FROM_HERE, base::Bind(&PostNTasksThenQuit, kNumPosts));
+ loop.PostTask(FROM_HERE, Bind(&PostNTasksThenQuit, kNumPosts));
loop.Run();
loop.RemoveTaskObserver(&observer);
@@ -1868,24 +1899,24 @@
EXPECT_FALSE(loop.high_resolution_timers_enabled());
// Post a fast task to enable the high resolution timers.
- loop.PostDelayedTask(FROM_HERE, base::Bind(&PostNTasksThenQuit, 1),
+ loop.PostDelayedTask(FROM_HERE, Bind(&PostNTasksThenQuit, 1),
kFastTimer);
loop.Run();
EXPECT_TRUE(loop.high_resolution_timers_enabled());
// Post a slow task and verify high resolution timers
// are still enabled.
- loop.PostDelayedTask(FROM_HERE, base::Bind(&PostNTasksThenQuit, 1),
+ loop.PostDelayedTask(FROM_HERE, Bind(&PostNTasksThenQuit, 1),
kSlowTimer);
loop.Run();
EXPECT_TRUE(loop.high_resolution_timers_enabled());
// Wait for a while so that high-resolution mode elapses.
- base::PlatformThread::Sleep(TimeDelta::FromMilliseconds(
+ PlatformThread::Sleep(TimeDelta::FromMilliseconds(
MessageLoop::kHighResolutionTimerModeLeaseTimeMs));
// Post a slow task to disable the high resolution timers.
- loop.PostDelayedTask(FROM_HERE, base::Bind(&PostNTasksThenQuit, 1),
+ loop.PostDelayedTask(FROM_HERE, Bind(&PostNTasksThenQuit, 1),
kSlowTimer);
loop.Run();
EXPECT_FALSE(loop.high_resolution_timers_enabled());
@@ -1970,7 +2001,7 @@
// send to MessageLoop::PostTask(). It is awkward usage since we are trying to
// hook the actual destruction, which is not a common operation.
class DestructionObserverProbe :
- public base::RefCounted<DestructionObserverProbe> {
+ public RefCounted<DestructionObserverProbe> {
public:
DestructionObserverProbe(bool* task_destroyed,
bool* destruction_observer_called)
@@ -1982,7 +2013,7 @@
ADD_FAILURE();
}
private:
- friend class base::RefCounted<DestructionObserverProbe>;
+ friend class RefCounted<DestructionObserverProbe>;
virtual ~DestructionObserverProbe() {
EXPECT_FALSE(*destruction_observer_called_);
@@ -2028,7 +2059,7 @@
loop->AddDestructionObserver(&observer);
loop->PostDelayedTask(
FROM_HERE,
- base::Bind(&DestructionObserverProbe::Run,
+ Bind(&DestructionObserverProbe::Run,
new DestructionObserverProbe(&task_destroyed,
&destruction_observer_called)),
kDelay);
@@ -2047,12 +2078,12 @@
scoped_refptr<Foo> foo(new Foo());
std::string a("a");
- base::ThreadTaskRunnerHandle::Get()->PostTask(FROM_HERE, base::Bind(
+ ThreadTaskRunnerHandle::Get()->PostTask(FROM_HERE, Bind(
&Foo::Test1ConstRef, foo.get(), a));
// Post quit task;
- MessageLoop::current()->PostTask(FROM_HERE, base::Bind(
- &MessageLoop::Quit, base::Unretained(MessageLoop::current())));
+ MessageLoop::current()->PostTask(FROM_HERE, Bind(
+ &MessageLoop::Quit, Unretained(MessageLoop::current())));
// Now kick things off
MessageLoop::current()->Run();
@@ -2082,3 +2113,5 @@
RunTest_RecursivePosts(MessageLoop::TYPE_UI, kNumTimes);
RunTest_RecursivePosts(MessageLoop::TYPE_IO, kNumTimes);
}
+
+} // namespace base
diff --git a/base/message_pump_aurax11.cc b/base/message_pump_aurax11.cc
index 8c764d5..9ba7989 100644
--- a/base/message_pump_aurax11.cc
+++ b/base/message_pump_aurax11.cc
@@ -91,14 +91,7 @@
if (xev->type == GenericEvent &&
static_cast<XIEvent*>(xev->xcookie.data)->extension == g_xinput_opcode) {
target = static_cast<XIDeviceEvent*>(xev->xcookie.data)->event;
- } else if (xev->type == MapNotify) {
- target = xev->xmap.window;
- } else if (xev->type == UnmapNotify) {
- target = xev->xunmap.window;
}
- // TODO(erg): Are there other events that we aren't reacting to properly
- // because xev->xany.window != xev->eventname.window?
-
return target;
}
diff --git a/base/message_pump_libevent.cc b/base/message_pump_libevent.cc
index bf3c7af..364f44a 100644
--- a/base/message_pump_libevent.cc
+++ b/base/message_pump_libevent.cc
@@ -57,7 +57,7 @@
: event_(NULL),
pump_(NULL),
watcher_(NULL),
- ALLOW_THIS_IN_INITIALIZER_LIST(weak_factory_(this)) {
+ weak_factory_(this) {
}
MessagePumpLibevent::FileDescriptorWatcher::~FileDescriptorWatcher() {
diff --git a/base/message_pump_ozone.cc b/base/message_pump_ozone.cc
new file mode 100644
index 0000000..ca7f45d
--- /dev/null
+++ b/base/message_pump_ozone.cc
@@ -0,0 +1,61 @@
+// Copyright (c) 2013 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/message_pump_ozone.h"
+
+#include "base/logging.h"
+#include "base/message_loop.h"
+
+namespace base {
+
+MessagePumpOzone::MessagePumpOzone()
+ : MessagePumpLibevent() {
+}
+
+MessagePumpOzone::~MessagePumpOzone() {
+}
+
+void MessagePumpOzone::AddObserver(MessagePumpObserver* /* observer */) {
+ NOTIMPLEMENTED();
+}
+
+void MessagePumpOzone::RemoveObserver(MessagePumpObserver* /* observer */) {
+ NOTIMPLEMENTED();
+}
+
+// static
+MessagePumpOzone* MessagePumpOzone::Current() {
+ MessageLoopForUI* loop = MessageLoopForUI::current();
+ return static_cast<MessagePumpOzone*>(loop->pump_ui());
+}
+
+void MessagePumpOzone::AddDispatcherForRootWindow(
+ MessagePumpDispatcher* dispatcher) {
+ // Only one root window is supported.
+ DCHECK(dispatcher_.size() == 0);
+ dispatcher_.insert(dispatcher_.begin(),dispatcher);
+}
+
+void MessagePumpOzone::RemoveDispatcherForRootWindow(
+ MessagePumpDispatcher* dispatcher) {
+ DCHECK(dispatcher_.size() == 1);
+ dispatcher_.pop_back();
+}
+
+bool MessagePumpOzone::Dispatch(const base::NativeEvent& dev) {
+ if (dispatcher_.size() > 0)
+ return dispatcher_[0]->Dispatch(dev);
+ else
+ return true;
+}
+
+// This code assumes that the caller tracks the lifetime of the |dispatcher|.
+void MessagePumpOzone::RunWithDispatcher(
+ Delegate* delegate, MessagePumpDispatcher* dispatcher) {
+ dispatcher_.push_back(dispatcher);
+ Run(delegate);
+ dispatcher_.pop_back();
+}
+
+} // namespace base
diff --git a/base/message_pump_ozone.h b/base/message_pump_ozone.h
new file mode 100644
index 0000000..8fb2f1d
--- /dev/null
+++ b/base/message_pump_ozone.h
@@ -0,0 +1,52 @@
+// Copyright (c) 2013 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 BASE_MESSAGE_PUMP_OZONE_H_
+#define BASE_MESSAGE_PUMP_OZONE_H_
+
+#include "base/memory/scoped_ptr.h"
+#include "base/memory/scoped_vector.h"
+#include "base/message_pump_dispatcher.h"
+#include "base/message_pump_libevent.h"
+#include "base/message_pump_observer.h"
+#include "base/observer_list.h"
+
+namespace base {
+
+// This class implements a message-pump for processing events from input devices
+// Refer to MessagePump for further documentation.
+class BASE_EXPORT MessagePumpOzone : public MessagePumpLibevent,
+ public MessagePumpDispatcher {
+ public:
+ MessagePumpOzone();
+
+ // Returns the UI message pump.
+ static MessagePumpOzone* Current();
+
+ // Add/Remove the root window dispatcher.
+ void AddDispatcherForRootWindow(MessagePumpDispatcher* dispatcher);
+ void RemoveDispatcherForRootWindow(MessagePumpDispatcher* dispatcher);
+
+ void RunWithDispatcher(Delegate* delegate, MessagePumpDispatcher* dispatcher);
+
+ // Add / remove an Observer, which will start receiving notifications
+ // immediately.
+ void AddObserver(MessagePumpObserver* observer);
+ void RemoveObserver(MessagePumpObserver* observer);
+
+ // Overridden from MessagePumpDispatcher.
+ virtual bool Dispatch(const base::NativeEvent& event) OVERRIDE;
+
+ private:
+ virtual ~MessagePumpOzone();
+ std::vector<MessagePumpDispatcher*> dispatcher_;
+
+ DISALLOW_COPY_AND_ASSIGN(MessagePumpOzone);
+};
+
+typedef MessagePumpOzone MessagePumpForUI;
+
+} // namespace base
+
+#endif // BASE_MESSAGE_PUMP_OZONE_H_
diff --git a/base/metrics/field_trial.cc b/base/metrics/field_trial.cc
index 4ab5ff9..c87935e 100644
--- a/base/metrics/field_trial.cc
+++ b/base/metrics/field_trial.cc
@@ -75,6 +75,11 @@
}
void FieldTrial::UseOneTimeRandomization() {
+ UseOneTimeRandomizationWithCustomSeed(0);
+}
+
+void FieldTrial::UseOneTimeRandomizationWithCustomSeed(
+ uint32 randomization_seed) {
// No need to specify randomization when the group choice was forced.
if (forced_)
return;
@@ -89,7 +94,8 @@
}
random_ = static_cast<Probability>(
- divisor_ * entropy_provider->GetEntropyForTrial(trial_name_));
+ divisor_ * entropy_provider->GetEntropyForTrial(trial_name_,
+ randomization_seed));
}
void FieldTrial::Disable() {
@@ -318,7 +324,7 @@
FieldTrial* field_trial = Find(name);
if (field_trial)
return field_trial->group_name();
- return "";
+ return std::string();
}
// static
diff --git a/base/metrics/field_trial.h b/base/metrics/field_trial.h
index a4e1f53..b9a5b66 100644
--- a/base/metrics/field_trial.h
+++ b/base/metrics/field_trial.h
@@ -101,10 +101,13 @@
public:
virtual ~EntropyProvider();
- // Returns a double in the range of [0, 1) based on |trial_name| that will
- // be used for the dice roll for the specified field trial. A given instance
- // should always return the same value given the same input |trial_name|.
- virtual double GetEntropyForTrial(const std::string& trial_name) const = 0;
+ // Returns a double in the range of [0, 1) to be used for the dice roll for
+ // the specified field trial. If |randomization_seed| is not 0, it will be
+ // used in preference to |trial_name| for generating the entropy by entropy
+ // providers that support it. A given instance should always return the same
+ // value given the same input |trial_name| and |randomization_seed| values.
+ virtual double GetEntropyForTrial(const std::string& trial_name,
+ uint32 randomization_seed) const = 0;
};
// A pair representing a Field Trial and its selected group.
@@ -121,9 +124,17 @@
// Changes the field trial to use one-time randomization, i.e. produce the
// same result for the current trial on every run of this client. Must be
- // called right after construction.
+ // called right after construction, before any groups are added.
void UseOneTimeRandomization();
+ // Changes the field trial to use one-time randomization, i.e. produce the
+ // same result for the current trial on every run of this client, with a
+ // custom randomization seed for the trial. The |randomization_seed| value
+ // should never be the same for two trials, else this would result in
+ // correlated group assignments. Must be called right after construction,
+ // before any groups are added.
+ void UseOneTimeRandomizationWithCustomSeed(uint32 randomization_seed);
+
// Disables this trial, meaning it always determines the default group
// has been selected. May be called immediately after construction, or
// at any time after initialization (should not be interleaved with
diff --git a/base/metrics/field_trial_unittest.cc b/base/metrics/field_trial_unittest.cc
index 81c4f37..bb2c39f 100644
--- a/base/metrics/field_trial_unittest.cc
+++ b/base/metrics/field_trial_unittest.cc
@@ -86,7 +86,7 @@
EXPECT_EQ(name1, trial1->trial_name());
EXPECT_EQ("", trial1->group_name_internal());
- trial1->AppendGroup("", 7);
+ trial1->AppendGroup(std::string(), 7);
EXPECT_EQ(trial1, FieldTrialList::Find(name1));
EXPECT_FALSE(FieldTrialList::Find(name2));
@@ -221,7 +221,7 @@
std::string winner_name;
for (int i = 1; i <= group_count; ++i) {
- int might_win = trial->AppendGroup("", 1);
+ int might_win = trial->AppendGroup(std::string(), 1);
// Because we keep appending groups, we want to see if the last group that
// was added has been assigned or not.
diff --git a/base/metrics/histogram.cc b/base/metrics/histogram.cc
index 1f26829..da12ccb 100644
--- a/base/metrics/histogram.cc
+++ b/base/metrics/histogram.cc
@@ -314,11 +314,6 @@
}
Histogram::~Histogram() {
- if (StatisticsRecorder::dump_on_exit()) {
- string output;
- WriteAsciiImpl(true, "\n", &output);
- DLOG(INFO) << output;
- }
}
bool Histogram::PrintEmptyBucket(size_t index) const {
@@ -340,12 +335,7 @@
}
const string Histogram::GetAsciiBucketRange(size_t i) const {
- string result;
- if (kHexRangePrintingFlag & flags())
- StringAppendF(&result, "%#x", ranges(i));
- else
- StringAppendF(&result, "%d", ranges(i));
- return result;
+ return GetSimpleAsciiBucketRange(ranges(i));
}
//------------------------------------------------------------------------------
@@ -490,27 +480,6 @@
}
}
-void Histogram::WriteAsciiBucketValue(Count current,
- double scaled_sum,
- string* output) const {
- StringAppendF(output, " (%d = %3.1f%%)", current, current/scaled_sum);
-}
-
-void Histogram::WriteAsciiBucketGraph(double current_size,
- double max_size,
- string* output) const {
- const int k_line_length = 72; // Maximal horizontal width of graph.
- int x_count = static_cast<int>(k_line_length * (current_size / max_size)
- + 0.5);
- int x_remainder = k_line_length - x_count;
-
- while (0 < x_count--)
- output->append("-");
- output->append("O");
- while (0 < x_remainder--)
- output->append(" ");
-}
-
void Histogram::GetParameters(DictionaryValue* params) const {
params->SetString("type", HistogramTypeToString(GetHistogramType()));
params->SetInteger("min", declared_min());
diff --git a/base/metrics/histogram.h b/base/metrics/histogram.h
index fe7b794..8d059f9 100644
--- a/base/metrics/histogram.h
+++ b/base/metrics/histogram.h
@@ -511,15 +511,6 @@
const int64 remaining, const size_t i,
std::string* output) const;
- // Write textual description of the bucket contents (relative to histogram).
- // Output is the count in the buckets, as well as the percentage.
- void WriteAsciiBucketValue(Count current, double scaled_sum,
- std::string* output) const;
-
- // Produce actual graph (set of blank vs non blank char's) for a bucket.
- void WriteAsciiBucketGraph(double current_size, double max_size,
- std::string* output) const;
-
// WriteJSON calls these.
virtual void GetParameters(DictionaryValue* params) const OVERRIDE;
diff --git a/base/metrics/histogram_base.cc b/base/metrics/histogram_base.cc
index 835a05b..51689a8 100644
--- a/base/metrics/histogram_base.cc
+++ b/base/metrics/histogram_base.cc
@@ -13,6 +13,8 @@
#include "base/metrics/histogram_samples.h"
#include "base/metrics/sparse_histogram.h"
#include "base/pickle.h"
+#include "base/process_util.h"
+#include "base/stringprintf.h"
#include "base/values.h"
namespace base {
@@ -119,7 +121,39 @@
root.SetInteger("flags", flags());
root.Set("params", parameters.release());
root.Set("buckets", buckets.release());
+ root.SetInteger("pid", GetCurrentProcId());
serializer.Serialize(root);
}
+void HistogramBase::WriteAsciiBucketGraph(double current_size,
+ double max_size,
+ std::string* output) const {
+ const int k_line_length = 72; // Maximal horizontal width of graph.
+ int x_count = static_cast<int>(k_line_length * (current_size / max_size)
+ + 0.5);
+ int x_remainder = k_line_length - x_count;
+
+ while (0 < x_count--)
+ output->append("-");
+ output->append("O");
+ while (0 < x_remainder--)
+ output->append(" ");
+}
+
+const std::string HistogramBase::GetSimpleAsciiBucketRange(
+ Sample sample) const {
+ std::string result;
+ if (kHexRangePrintingFlag & flags())
+ StringAppendF(&result, "%#x", sample);
+ else
+ StringAppendF(&result, "%d", sample);
+ return result;
+}
+
+void HistogramBase::WriteAsciiBucketValue(Count current,
+ double scaled_sum,
+ std::string* output) const {
+ StringAppendF(output, " (%d = %3.1f%%)", current, current/scaled_sum);
+}
+
} // namespace base
diff --git a/base/metrics/histogram_base.h b/base/metrics/histogram_base.h
index 12d126d..2fa846e 100644
--- a/base/metrics/histogram_base.h
+++ b/base/metrics/histogram_base.h
@@ -142,6 +142,21 @@
// counts to |buckets| and the total sample count to |count|.
virtual void GetCountAndBucketData(Count* count,
ListValue* buckets) const = 0;
+
+ //// Produce actual graph (set of blank vs non blank char's) for a bucket.
+ void WriteAsciiBucketGraph(double current_size,
+ double max_size,
+ std::string* output) const;
+
+ // Return a string description of what goes in a given bucket.
+ const std::string GetSimpleAsciiBucketRange(Sample sample) const;
+
+ // Write textual description of the bucket contents (relative to histogram).
+ // Output is the count in the buckets, as well as the percentage.
+ void WriteAsciiBucketValue(Count current,
+ double scaled_sum,
+ std::string* output) const;
+
private:
const std::string histogram_name_;
int32 flags_;
diff --git a/base/metrics/sample_vector.cc b/base/metrics/sample_vector.cc
index f90d80b..8f14510 100644
--- a/base/metrics/sample_vector.cc
+++ b/base/metrics/sample_vector.cc
@@ -43,7 +43,7 @@
}
Count SampleVector::GetCountAtIndex(size_t bucket_index) const {
- DCHECK(bucket_index >= 0 && bucket_index < counts_.size());
+ DCHECK(bucket_index < counts_.size());
return counts_[bucket_index];
}
diff --git a/base/metrics/sparse_histogram.cc b/base/metrics/sparse_histogram.cc
index 2952673..df361f7 100644
--- a/base/metrics/sparse_histogram.cc
+++ b/base/metrics/sparse_histogram.cc
@@ -7,6 +7,7 @@
#include "base/metrics/sample_map.h"
#include "base/metrics/statistics_recorder.h"
#include "base/pickle.h"
+#include "base/stringprintf.h"
#include "base/synchronization/lock.h"
using std::map;
@@ -69,11 +70,13 @@
}
void SparseHistogram::WriteHTMLGraph(string* output) const {
- // TODO(kaiwang): Implement.
+ output->append("<PRE>");
+ WriteAsciiImpl(true, "<br>", output);
+ output->append("</PRE>");
}
void SparseHistogram::WriteAscii(string* output) const {
- // TODO(kaiwang): Implement.
+ WriteAsciiImpl(true, "\n", output);
}
bool SparseHistogram::SerializeInfoImpl(Pickle* pickle) const {
@@ -106,4 +109,69 @@
// TODO(kaiwang): Implement. (See HistogramBase::WriteJSON.)
}
+void SparseHistogram::WriteAsciiImpl(bool graph_it,
+ const std::string& newline,
+ std::string* output) const {
+ // Get a local copy of the data so we are consistent.
+ scoped_ptr<HistogramSamples> snapshot = SnapshotSamples();
+ Count total_count = snapshot->TotalCount();
+ double scaled_total_count = total_count / 100.0;
+
+ WriteAsciiHeader(total_count, output);
+ output->append(newline);
+
+ // Determine how wide the largest bucket range is (how many digits to print),
+ // so that we'll be able to right-align starts for the graphical bars.
+ // Determine which bucket has the largest sample count so that we can
+ // normalize the graphical bar-width relative to that sample count.
+ Count largest_count = 0;
+ Sample largest_sample = 0;
+ scoped_ptr<SampleCountIterator> it = snapshot->Iterator();
+ while (!it->Done())
+ {
+ Sample min;
+ Sample max;
+ Count count;
+ it->Get(&min, &max, &count);
+ if (min > largest_sample)
+ largest_sample = min;
+ if (count > largest_count)
+ largest_count = count;
+ it->Next();
+ }
+ size_t print_width = GetSimpleAsciiBucketRange(largest_sample).size() + 1;
+
+ // iterate over each item and display them
+ it = snapshot->Iterator();
+ while (!it->Done())
+ {
+ Sample min;
+ Sample max;
+ Count count;
+ it->Get(&min, &max, &count);
+
+ // value is min, so display it
+ string range = GetSimpleAsciiBucketRange(min);
+ output->append(range);
+ for (size_t j = 0; range.size() + j < print_width + 1; ++j)
+ output->push_back(' ');
+
+ if (graph_it)
+ WriteAsciiBucketGraph(count, largest_count, output);
+ WriteAsciiBucketValue(count, scaled_total_count, output);
+ output->append(newline);
+ it->Next();
+ }
+}
+
+void SparseHistogram::WriteAsciiHeader(const Count total_count,
+ std::string* output) const {
+ StringAppendF(output,
+ "Histogram: %s recorded %d samples",
+ histogram_name().c_str(),
+ total_count);
+ if (flags() & ~kHexRangePrintingFlag)
+ StringAppendF(output, " (flags = 0x%x)", flags() & ~kHexRangePrintingFlag);
+}
+
} // namespace base
diff --git a/base/metrics/sparse_histogram.h b/base/metrics/sparse_histogram.h
index 9c20766..4de2002 100644
--- a/base/metrics/sparse_histogram.h
+++ b/base/metrics/sparse_histogram.h
@@ -90,6 +90,15 @@
virtual void GetCountAndBucketData(Count* count,
ListValue* buckets) const OVERRIDE;
+ // Helpers for emitting Ascii graphic. Each method appends data to output.
+ void WriteAsciiImpl(bool graph_it,
+ const std::string& newline,
+ std::string* output) const;
+
+ // Write a common header message describing this histogram.
+ void WriteAsciiHeader(const Count total_count,
+ std::string* output) const;
+
// For constuctor calling.
friend class SparseHistogramTest;
diff --git a/base/metrics/statistics_recorder.cc b/base/metrics/statistics_recorder.cc
index f6174f3..3176f26 100644
--- a/base/metrics/statistics_recorder.cc
+++ b/base/metrics/statistics_recorder.cc
@@ -4,6 +4,7 @@
#include "base/metrics/statistics_recorder.h"
+#include "base/at_exit.h"
#include "base/debug/leak_annotations.h"
#include "base/logging.h"
#include "base/memory/scoped_ptr.h"
@@ -302,15 +303,23 @@
base::AutoLock auto_lock(*lock_);
histograms_ = new HistogramMap;
ranges_ = new RangesMap;
+
+ if (VLOG_IS_ON(1))
+ AtExitManager::RegisterCallback(&DumpHistogramsToVlog, this);
+}
+
+// static
+void StatisticsRecorder::DumpHistogramsToVlog(void* instance) {
+ DCHECK(VLOG_IS_ON(1));
+
+ StatisticsRecorder* me = reinterpret_cast<StatisticsRecorder*>(instance);
+ string output;
+ me->WriteGraph(std::string(), &output);
+ VLOG(1) << output;
}
StatisticsRecorder::~StatisticsRecorder() {
DCHECK(histograms_ && ranges_ && lock_);
- if (dump_on_exit_) {
- string output;
- WriteGraph("", &output);
- DLOG(INFO) << output;
- }
// Clean up.
scoped_ptr<HistogramMap> histograms_deleter;
@@ -334,7 +343,5 @@
StatisticsRecorder::RangesMap* StatisticsRecorder::ranges_ = NULL;
// static
base::Lock* StatisticsRecorder::lock_ = NULL;
-// static
-bool StatisticsRecorder::dump_on_exit_ = false;
} // namespace base
diff --git a/base/metrics/statistics_recorder.h b/base/metrics/statistics_recorder.h
index 4738802..c7c0983 100644
--- a/base/metrics/statistics_recorder.h
+++ b/base/metrics/statistics_recorder.h
@@ -70,10 +70,6 @@
// safe. It returns NULL if a matching histogram is not found.
static HistogramBase* FindHistogram(const std::string& name);
- static bool dump_on_exit() { return dump_on_exit_; }
-
- static void set_dump_on_exit(bool enable) { dump_on_exit_ = enable; }
-
// GetSnapshot copies some of the pointers to registered histograms into the
// caller supplied vector (Histograms). Only histograms with names matching
// query are returned. The query must be a substring of histogram name for its
@@ -101,15 +97,14 @@
StatisticsRecorder();
~StatisticsRecorder();
+ static void DumpHistogramsToVlog(void* instance);
+
static HistogramMap* histograms_;
static RangesMap* ranges_;
// Lock protects access to above maps.
static base::Lock* lock_;
- // Dump all known histograms to log.
- static bool dump_on_exit_;
-
DISALLOW_COPY_AND_ASSIGN(StatisticsRecorder);
};
diff --git a/base/metrics/stats_counters.cc b/base/metrics/stats_counters.cc
index f763220..12416d9 100644
--- a/base/metrics/stats_counters.cc
+++ b/base/metrics/stats_counters.cc
@@ -45,7 +45,7 @@
if (counter_id_ == -1) {
counter_id_ = table->FindCounter(name_);
if (table->GetSlot() == 0) {
- if (!table->RegisterThread("")) {
+ if (!table->RegisterThread(std::string())) {
// There is no room for this thread. This thread
// cannot use counters.
counter_id_ = 0;
diff --git a/base/metrics/stats_table.cc b/base/metrics/stats_table.cc
index 2bccc90..9585863 100644
--- a/base/metrics/stats_table.cc
+++ b/base/metrics/stats_table.cc
@@ -8,8 +8,8 @@
#include "base/memory/scoped_ptr.h"
#include "base/process_util.h"
#include "base/shared_memory.h"
-#include "base/string_piece.h"
#include "base/string_util.h"
+#include "base/strings/string_piece.h"
#include "base/threading/platform_thread.h"
#include "base/threading/thread_local_storage.h"
#include "base/utf_string_conversions.h"
@@ -431,8 +431,8 @@
// Get the slot for this thread. Try to register
// it if none exists.
int slot = table->GetSlot();
- if (!slot && !(slot = table->RegisterThread("")))
- return NULL;
+ if (!slot && !(slot = table->RegisterThread(std::string())))
+ return NULL;
// Find the counter id for the counter.
std::string str_name(name);
diff --git a/base/metrics/stats_table_unittest.cc b/base/metrics/stats_table_unittest.cc
index 579bab7..713fff0 100644
--- a/base/metrics/stats_table_unittest.cc
+++ b/base/metrics/stats_table_unittest.cc
@@ -6,7 +6,7 @@
#include "base/metrics/stats_table.h"
#include "base/shared_memory.h"
#include "base/stringprintf.h"
-#include "base/string_piece.h"
+#include "base/strings/string_piece.h"
#include "base/test/multiprocess_test.h"
#include "base/threading/platform_thread.h"
#include "base/threading/simple_thread.h"
@@ -109,7 +109,7 @@
// Create a few threads and have them poke on their counters.
// See http://crbug.com/10611 for more information.
-#if defined(OS_MACOSX)
+#if defined(OS_MACOSX) || defined(THREAD_SANITIZER)
#define MAYBE_MultipleThreads DISABLED_MultipleThreads
#else
#define MAYBE_MultipleThreads MultipleThreads
diff --git a/base/nix/mime_util_xdg.cc b/base/nix/mime_util_xdg.cc
index 00dcafa..5794b6d 100644
--- a/base/nix/mime_util_xdg.cc
+++ b/base/nix/mime_util_xdg.cc
@@ -344,9 +344,9 @@
std::string IconTheme::ReadLine(FILE* fp) {
if (!fp)
- return "";
+ return std::string();
- std::string result = "";
+ std::string result;
const size_t kBufferSize = 100;
char buffer[kBufferSize];
while ((fgets(buffer, kBufferSize - 1, fp)) != NULL) {
diff --git a/base/observer_list_threadsafe.h b/base/observer_list_threadsafe.h
index 14488ec..85b9e6c 100644
--- a/base/observer_list_threadsafe.h
+++ b/base/observer_list_threadsafe.h
@@ -108,7 +108,7 @@
void AddObserver(ObserverType* obs) {
// If there is not a current MessageLoop, it is impossible to notify on it,
// so do not add the observer.
- if (!MessageLoop::current())
+ if (!base::MessageLoop::current())
return;
ObserverList<ObserverType>* list = NULL;
diff --git a/base/observer_list_unittest.cc b/base/observer_list_unittest.cc
index 591d230..99c9e5f 100644
--- a/base/observer_list_unittest.cc
+++ b/base/observer_list_unittest.cc
@@ -106,7 +106,7 @@
count_observes_(0),
count_addtask_(0),
do_notifies_(notify),
- ALLOW_THIS_IN_INITIALIZER_LIST(weak_factory_(this)) {
+ weak_factory_(this) {
}
virtual ~AddRemoveThread() {
diff --git a/base/os_compat_android.cc b/base/os_compat_android.cc
index 118ad5e..c4ea463 100644
--- a/base/os_compat_android.cc
+++ b/base/os_compat_android.cc
@@ -10,8 +10,8 @@
#include <time64.h>
#include "base/rand_util.h"
-#include "base/string_piece.h"
#include "base/stringprintf.h"
+#include "base/strings/string_piece.h"
// There is no futimes() avaiable in Bionic, so we provide our own
// implementation until it is there.
diff --git a/base/path_service.cc b/base/path_service.cc
index 1fd2f6f..32c6909 100644
--- a/base/path_service.cc
+++ b/base/path_service.cc
@@ -18,6 +18,7 @@
#include "base/synchronization/lock.h"
using base::FilePath;
+using base::MakeAbsoluteFilePath;
namespace base {
bool PathProvider(int key, FilePath* result);
@@ -217,9 +218,9 @@
if (path.ReferencesParent()) {
// Make sure path service never returns a path with ".." in it.
- if (!file_util::AbsolutePath(&path)) {
+ path = MakeAbsoluteFilePath(path);
+ if (path.empty())
return false;
- }
}
*result = path;
@@ -250,17 +251,16 @@
// fore we protect this call with a flag.
if (create) {
// Make sure the directory exists. We need to do this before we translate
- // this to the absolute path because on POSIX, AbsolutePath fails if called
- // on a non-existent path.
+ // this to the absolute path because on POSIX, MakeAbsoluteFilePath fails
+ // if called on a non-existent path.
if (!file_util::PathExists(file_path) &&
!file_util::CreateDirectory(file_path))
return false;
}
- // We need to have an absolute path, as extensions and plugins don't like
- // relative paths, and will gladly crash the browser in CHECK()s if they get a
- // relative path.
- if (!file_util::AbsolutePath(&file_path))
+ // We need to have an absolute path.
+ file_path = MakeAbsoluteFilePath(file_path);
+ if (file_path.empty())
return false;
base::AutoLock scoped_lock(path_data->lock);
diff --git a/base/pickle_unittest.cc b/base/pickle_unittest.cc
index d418fdf..d252dae 100644
--- a/base/pickle_unittest.cc
+++ b/base/pickle_unittest.cc
@@ -134,7 +134,7 @@
TEST(PickleTest, ZeroLenStr) {
Pickle pickle;
- EXPECT_TRUE(pickle.WriteString(""));
+ EXPECT_TRUE(pickle.WriteString(std::string()));
PickleIterator iter(pickle);
std::string outstr;
@@ -144,7 +144,7 @@
TEST(PickleTest, ZeroLenWStr) {
Pickle pickle;
- EXPECT_TRUE(pickle.WriteWString(L""));
+ EXPECT_TRUE(pickle.WriteWString(std::wstring()));
PickleIterator iter(pickle);
std::string outstr;
diff --git a/base/platform_file.h b/base/platform_file.h
index 300a30c..43758c5 100644
--- a/base/platform_file.h
+++ b/base/platform_file.h
@@ -55,6 +55,8 @@
PLATFORM_FILE_TERMINAL_DEVICE = 1 << 16, // Serial port flags
PLATFORM_FILE_BACKUP_SEMANTICS = 1 << 17, // Used on Windows only
+
+ PLATFORM_FILE_EXECUTE = 1 << 18, // Used on Windows only
};
// PLATFORM_FILE_ERROR_ACCESS_DENIED is returned when a call fails because of
@@ -77,8 +79,9 @@
PLATFORM_FILE_ERROR_NOT_A_FILE = -13,
PLATFORM_FILE_ERROR_NOT_EMPTY = -14,
PLATFORM_FILE_ERROR_INVALID_URL = -15,
+ PLATFORM_FILE_ERROR_IO = -16,
// Put new entries here and increment PLATFORM_FILE_ERROR_MAX.
- PLATFORM_FILE_ERROR_MAX = -16
+ PLATFORM_FILE_ERROR_MAX = -17
};
// This explicit mapping matches both FILE_ on Windows and SEEK_ on Linux.
diff --git a/base/platform_file_posix.cc b/base/platform_file_posix.cc
index 646c82e..fa8fc62 100644
--- a/base/platform_file_posix.cc
+++ b/base/platform_file_posix.cc
@@ -301,7 +301,21 @@
timeval times[2];
times[0] = last_access_time.ToTimeVal();
times[1] = last_modified_time.ToTimeVal();
+
+#ifdef __USE_XOPEN2K8
+ // futimens should be available, but futimes might not be
+ // http://pubs.opengroup.org/onlinepubs/9699919799/
+
+ timespec ts_times[2];
+ ts_times[0].tv_sec = times[0].tv_sec;
+ ts_times[0].tv_nsec = times[0].tv_usec * 1000;
+ ts_times[1].tv_sec = times[1].tv_sec;
+ ts_times[1].tv_nsec = times[1].tv_usec * 1000;
+
+ return !futimens(file, ts_times);
+#else
return !futimes(file, times);
+#endif
}
bool GetPlatformFileInfo(PlatformFile file, PlatformFileInfo* info) {
diff --git a/base/platform_file_unittest.cc b/base/platform_file_unittest.cc
index 36ec3ee..7483876 100644
--- a/base/platform_file_unittest.cc
+++ b/base/platform_file_unittest.cc
@@ -262,7 +262,11 @@
}
// Flakily fails: http://crbug.com/86494
+#if defined(OS_ANDROID)
+TEST(PlatformFile, TouchGetInfoPlatformFile) {
+#else
TEST(PlatformFile, DISABLED_TouchGetInfoPlatformFile) {
+#endif
base::ScopedTempDir temp_dir;
ASSERT_TRUE(temp_dir.CreateUniqueTempDir());
base::PlatformFile file = base::CreatePlatformFile(
diff --git a/base/platform_file_win.cc b/base/platform_file_win.cc
index 8c98183..2d25d33 100644
--- a/base/platform_file_win.cc
+++ b/base/platform_file_win.cc
@@ -8,6 +8,7 @@
#include "base/files/file_path.h"
#include "base/logging.h"
+#include "base/metrics/sparse_histogram.h"
#include "base/threading/thread_restrictions.h"
namespace base {
@@ -55,6 +56,8 @@
access |= GENERIC_WRITE;
if (flags & PLATFORM_FILE_WRITE_ATTRIBUTES)
access |= FILE_WRITE_ATTRIBUTES;
+ if (flags & PLATFORM_FILE_EXECUTE)
+ access |= GENERIC_EXECUTE;
DWORD sharing = (flags & PLATFORM_FILE_EXCLUSIVE_READ) ? 0 : FILE_SHARE_READ;
if (!(flags & PLATFORM_FILE_EXCLUSIVE_WRITE))
@@ -97,12 +100,38 @@
*error = PLATFORM_FILE_ERROR_EXISTS;
break;
case ERROR_FILE_NOT_FOUND:
+ case ERROR_PATH_NOT_FOUND:
*error = PLATFORM_FILE_ERROR_NOT_FOUND;
break;
case ERROR_ACCESS_DENIED:
*error = PLATFORM_FILE_ERROR_ACCESS_DENIED;
break;
+ case ERROR_TOO_MANY_OPEN_FILES:
+ *error = PLATFORM_FILE_ERROR_TOO_MANY_OPENED;
+ break;
+ case ERROR_OUTOFMEMORY:
+ case ERROR_NOT_ENOUGH_MEMORY:
+ *error = PLATFORM_FILE_ERROR_NO_MEMORY;
+ break;
+ case ERROR_HANDLE_DISK_FULL:
+ case ERROR_DISK_FULL:
+ case ERROR_DISK_RESOURCES_EXHAUSTED:
+ *error = PLATFORM_FILE_ERROR_NO_SPACE;
+ break;
+ case ERROR_USER_MAPPED_FILE:
+ *error = PLATFORM_FILE_ERROR_INVALID_OPERATION;
+ break;
+ case ERROR_NOT_READY:
+ case ERROR_SECTOR_NOT_FOUND:
+ case ERROR_DEV_NOT_EXIST:
+ case ERROR_IO_DEVICE:
+ case ERROR_FILE_CORRUPT:
+ case ERROR_DISK_CORRUPT:
+ *error = PLATFORM_FILE_ERROR_IO;
+ break;
default:
+ UMA_HISTOGRAM_SPARSE_SLOWLY("PlatformFile.UnknownCreateFileErrors",
+ last_error);
*error = PLATFORM_FILE_ERROR_FAILED;
}
}
diff --git a/base/posix/unix_domain_socket_linux.cc b/base/posix/unix_domain_socket_linux.cc
index 603459f..757db98 100644
--- a/base/posix/unix_domain_socket_linux.cc
+++ b/base/posix/unix_domain_socket_linux.cc
@@ -58,6 +58,15 @@
void* buf,
size_t length,
std::vector<int>* fds) {
+ return UnixDomainSocket::RecvMsgWithFlags(fd, buf, length, 0, fds);
+}
+
+// static
+ssize_t UnixDomainSocket::RecvMsgWithFlags(int fd,
+ void* buf,
+ size_t length,
+ int flags,
+ std::vector<int>* fds) {
fds->clear();
struct msghdr msg = {};
@@ -69,7 +78,7 @@
msg.msg_control = control_buffer;
msg.msg_controllen = sizeof(control_buffer);
- const ssize_t r = HANDLE_EINTR(recvmsg(fd, &msg, 0));
+ const ssize_t r = HANDLE_EINTR(recvmsg(fd, &msg, flags));
if (r == -1)
return -1;
@@ -109,6 +118,18 @@
unsigned max_reply_len,
int* result_fd,
const Pickle& request) {
+ return UnixDomainSocket::SendRecvMsgWithFlags(fd, reply, max_reply_len,
+ 0, /* recvmsg_flags */
+ result_fd, request);
+}
+
+// static
+ssize_t UnixDomainSocket::SendRecvMsgWithFlags(int fd,
+ uint8_t* reply,
+ unsigned max_reply_len,
+ int recvmsg_flags,
+ int* result_fd,
+ const Pickle& request) {
int fds[2];
// This socketpair is only used for the IPC and is cleaned up before
@@ -128,7 +149,8 @@
fd_vector.clear();
// When porting to OSX keep in mind it doesn't support MSG_NOSIGNAL, so the
// sender might get a SIGPIPE.
- const ssize_t reply_len = RecvMsg(fds[0], reply, max_reply_len, &fd_vector);
+ const ssize_t reply_len = RecvMsgWithFlags(fds[0], reply, max_reply_len,
+ recvmsg_flags, &fd_vector);
close(fds[0]);
if (reply_len == -1)
return -1;
diff --git a/base/posix/unix_domain_socket_linux.h b/base/posix/unix_domain_socket_linux.h
index b8ba460..66fb8bb 100644
--- a/base/posix/unix_domain_socket_linux.h
+++ b/base/posix/unix_domain_socket_linux.h
@@ -55,6 +55,22 @@
unsigned reply_len,
int* result_fd,
const Pickle& request);
+
+ // Similar to SendRecvMsg(), but |recvmsg_flags| allows to control the flags
+ // of the recvmsg(2) call.
+ static ssize_t SendRecvMsgWithFlags(int fd,
+ uint8_t* reply,
+ unsigned reply_len,
+ int recvmsg_flags,
+ int* result_fd,
+ const Pickle& request);
+ private:
+ // Similar to RecvMsg, but allows to specify |flags| for recvmsg(2).
+ static ssize_t RecvMsgWithFlags(int fd,
+ void* msg,
+ size_t length,
+ int flags,
+ std::vector<int>* fds);
};
#endif // BASE_POSIX_UNIX_DOMAIN_SOCKET_LINUX_H_
diff --git a/base/power_monitor/power_monitor.cc b/base/power_monitor/power_monitor.cc
new file mode 100644
index 0000000..13e91c7
--- /dev/null
+++ b/base/power_monitor/power_monitor.cc
@@ -0,0 +1,106 @@
+// Copyright 2013 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/power_monitor/power_monitor.h"
+
+#include "base/time.h"
+
+namespace base {
+
+static PowerMonitor* g_power_monitor = NULL;
+
+#if defined(ENABLE_BATTERY_MONITORING)
+// The amount of time (in ms) to wait before running the initial
+// battery check.
+static int kDelayedBatteryCheckMs = 10 * 1000;
+#endif // defined(ENABLE_BATTERY_MONITORING)
+
+PowerMonitor::PowerMonitor()
+ : observers_(new ObserverListThreadSafe<PowerObserver>()),
+ battery_in_use_(false),
+ suspended_(false) {
+ DCHECK(!g_power_monitor);
+ g_power_monitor = this;
+
+ DCHECK(MessageLoop::current());
+#if defined(ENABLE_BATTERY_MONITORING)
+ delayed_battery_check_.Start(FROM_HERE,
+ base::TimeDelta::FromMilliseconds(kDelayedBatteryCheckMs), this,
+ &PowerMonitor::BatteryCheck);
+#endif // defined(ENABLE_BATTERY_MONITORING)
+#if defined(OS_MACOSX)
+ PlatformInit();
+#endif
+}
+
+PowerMonitor::~PowerMonitor() {
+#if defined(OS_MACOSX)
+ PlatformDestroy();
+#endif
+ DCHECK_EQ(this, g_power_monitor);
+ g_power_monitor = NULL;
+}
+
+// static
+PowerMonitor* PowerMonitor::Get() {
+ return g_power_monitor;
+}
+
+void PowerMonitor::AddObserver(PowerObserver* obs) {
+ observers_->AddObserver(obs);
+}
+
+void PowerMonitor::RemoveObserver(PowerObserver* obs) {
+ observers_->RemoveObserver(obs);
+}
+
+void PowerMonitor::ProcessPowerEvent(PowerEvent event_id) {
+ // Suppress duplicate notifications. Some platforms may
+ // send multiple notifications of the same event.
+ switch (event_id) {
+ case POWER_STATE_EVENT:
+ {
+ bool on_battery = IsBatteryPower();
+ if (on_battery != battery_in_use_) {
+ battery_in_use_ = on_battery;
+ NotifyPowerStateChange();
+ }
+ }
+ break;
+ case RESUME_EVENT:
+ if (suspended_) {
+ suspended_ = false;
+ NotifyResume();
+ }
+ break;
+ case SUSPEND_EVENT:
+ if (!suspended_) {
+ suspended_ = true;
+ NotifySuspend();
+ }
+ break;
+ }
+}
+
+void PowerMonitor::BatteryCheck() {
+ ProcessPowerEvent(PowerMonitor::POWER_STATE_EVENT);
+}
+
+void PowerMonitor::NotifyPowerStateChange() {
+ DVLOG(1) << "PowerStateChange: " << (BatteryPower() ? "On" : "Off")
+ << " battery";
+ observers_->Notify(&PowerObserver::OnPowerStateChange, BatteryPower());
+}
+
+void PowerMonitor::NotifySuspend() {
+ DVLOG(1) << "Power Suspending";
+ observers_->Notify(&PowerObserver::OnSuspend);
+}
+
+void PowerMonitor::NotifyResume() {
+ DVLOG(1) << "Power Resuming";
+ observers_->Notify(&PowerObserver::OnResume);
+}
+
+} // namespace base
diff --git a/base/power_monitor/power_monitor.h b/base/power_monitor/power_monitor.h
new file mode 100644
index 0000000..e893547
--- /dev/null
+++ b/base/power_monitor/power_monitor.h
@@ -0,0 +1,146 @@
+// Copyright 2013 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 BASE_POWER_MONITOR_POWER_MONITOR_H_
+#define BASE_POWER_MONITOR_POWER_MONITOR_H_
+
+#include "base/base_export.h"
+#include "base/basictypes.h"
+#include "base/memory/ref_counted.h"
+#include "base/observer_list_threadsafe.h"
+#include "base/power_monitor/power_observer.h"
+
+#if defined(OS_WIN)
+#include <windows.h>
+
+// Windows HiRes timers drain the battery faster so we need to know the battery
+// status. This isn't true for other platforms.
+#define ENABLE_BATTERY_MONITORING 1
+#else
+#undef ENABLE_BATTERY_MONITORING
+#endif // !OS_WIN
+
+#if defined(ENABLE_BATTERY_MONITORING)
+#include "base/timer.h"
+#endif // defined(ENABLE_BATTERY_MONITORING)
+
+#if defined(OS_IOS)
+#include <objc/runtime.h>
+#endif // OS_IOS
+
+namespace base {
+
+// A class used to monitor the power state change and notify the observers about
+// the change event.
+class BASE_EXPORT PowerMonitor {
+ public:
+ // Normalized list of power events.
+ enum PowerEvent {
+ POWER_STATE_EVENT, // The Power status of the system has changed.
+ SUSPEND_EVENT, // The system is being suspended.
+ RESUME_EVENT // The system is being resumed.
+ };
+
+ PowerMonitor();
+ ~PowerMonitor();
+
+ // Get the application-wide PowerMonitor (if not present, returns NULL).
+ static PowerMonitor* Get();
+
+#if defined(OS_MACOSX)
+ // Allocate system resources needed by the PowerMonitor class.
+ //
+ // This function must be called before instantiating an instance of the class
+ // and before the Sandbox is initialized.
+#if !defined(OS_IOS)
+ static void AllocateSystemIOPorts();
+#else
+ static void AllocateSystemIOPorts() {}
+#endif // OS_IOS
+#endif // OS_MACOSX
+
+ // Add and remove an observer.
+ // Can be called from any thread.
+ // Must not be called from within a notification callback.
+ void AddObserver(PowerObserver* observer);
+ void RemoveObserver(PowerObserver* observer);
+
+ // Is the computer currently on battery power. Can be called on any thread.
+ bool BatteryPower() const {
+ // Using a lock here is not necessary for just a bool.
+ return battery_in_use_;
+ }
+
+ private:
+ friend class PowerMonitorTest;
+ // A friend function that is allowed to access the private ProcessPowerEvent.
+ friend void ProcessPowerEventHelper(PowerEvent);
+
+#if defined(OS_WIN)
+ // Represents a message-only window for power message handling on Windows.
+ // Only allow PowerMonitor to create it.
+ class PowerMessageWindow {
+ public:
+ PowerMessageWindow();
+ ~PowerMessageWindow();
+
+ private:
+ void ProcessWmPowerBroadcastMessage(int event_id);
+ LRESULT CALLBACK WndProc(HWND hwnd, UINT message,
+ WPARAM wparam, LPARAM lparam);
+ static LRESULT CALLBACK WndProcThunk(HWND hwnd,
+ UINT message,
+ WPARAM wparam,
+ LPARAM lparam);
+ // Instance of the module containing the window procedure.
+ HMODULE instance_;
+ // A hidden message-only window.
+ HWND message_hwnd_;
+ };
+#endif // OS_WIN
+
+#if defined(OS_MACOSX)
+ void PlatformInit();
+ void PlatformDestroy();
+#endif
+
+ // Cross-platform handling of a power event.
+ void ProcessPowerEvent(PowerEvent event_id);
+
+ // Platform-specific method to check whether the system is currently
+ // running on battery power. Returns true if running on batteries,
+ // false otherwise.
+ bool IsBatteryPower();
+
+ // Checks the battery status and notifies observers if the battery
+ // status has changed.
+ void BatteryCheck();
+
+ void NotifyPowerStateChange();
+ void NotifySuspend();
+ void NotifyResume();
+
+#if defined(OS_IOS)
+ // Holds pointers to system event notification observers.
+ std::vector<id> notification_observers_;
+#endif
+
+#if defined(ENABLE_BATTERY_MONITORING)
+ base::OneShotTimer<PowerMonitor> delayed_battery_check_;
+#endif
+
+ scoped_refptr<ObserverListThreadSafe<PowerObserver> > observers_;
+ bool battery_in_use_;
+ bool suspended_;
+
+#if defined(OS_WIN)
+ PowerMessageWindow power_message_window_;
+#endif
+
+ DISALLOW_COPY_AND_ASSIGN(PowerMonitor);
+};
+
+} // namespace base
+
+#endif // BASE_POWER_MONITOR_POWER_MONITOR_H_
diff --git a/base/power_monitor/power_monitor_android.cc b/base/power_monitor/power_monitor_android.cc
new file mode 100644
index 0000000..4900f6c
--- /dev/null
+++ b/base/power_monitor/power_monitor_android.cc
@@ -0,0 +1,42 @@
+// Copyright 2013 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/power_monitor/power_monitor.h"
+#include "jni/PowerMonitor_jni.h"
+
+namespace base {
+
+// A helper function which is a friend of PowerMonitor.
+void ProcessPowerEventHelper(PowerMonitor::PowerEvent event) {
+ if (base::PowerMonitor::Get())
+ base::PowerMonitor::Get()->ProcessPowerEvent(event);
+}
+
+namespace android {
+
+// Native implementation of PowerMonitor.java.
+void OnBatteryChargingChanged(JNIEnv* env, jclass clazz) {
+ ProcessPowerEventHelper(PowerMonitor::POWER_STATE_EVENT);
+}
+
+void OnMainActivityResumed(JNIEnv* env, jclass clazz) {
+ ProcessPowerEventHelper(PowerMonitor::RESUME_EVENT);
+}
+
+void OnMainActivitySuspended(JNIEnv* env, jclass clazz) {
+ ProcessPowerEventHelper(PowerMonitor::SUSPEND_EVENT);
+}
+
+} // namespace android
+
+bool PowerMonitor::IsBatteryPower() {
+ JNIEnv* env = base::android::AttachCurrentThread();
+ return base::android::Java_PowerMonitor_isBatteryPower(env);
+}
+
+bool RegisterPowerMonitor(JNIEnv* env) {
+ return base::android::RegisterNativesImpl(env);
+}
+
+} // namespace base
diff --git a/base/power_monitor/power_monitor_android.h b/base/power_monitor/power_monitor_android.h
new file mode 100644
index 0000000..7f43164
--- /dev/null
+++ b/base/power_monitor/power_monitor_android.h
@@ -0,0 +1,17 @@
+// Copyright 2013 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 BASE_POWER_MONITOR_POWER_MONITOR_ANDROID_H_
+#define BASE_POWER_MONITOR_POWER_MONITOR_ANDROID_H_
+
+#include <jni.h>
+
+namespace base {
+
+// Registers the JNI bindings for PowerMonitor.
+bool RegisterPowerMonitor(JNIEnv* env);
+
+} // namespace base
+
+#endif // BASE_POWER_MONITOR_POWER_MONITOR_ANDROID_H_
diff --git a/base/system_monitor/system_monitor_ios.mm b/base/power_monitor/power_monitor_ios.mm
similarity index 77%
rename from base/system_monitor/system_monitor_ios.mm
rename to base/power_monitor/power_monitor_ios.mm
index f3251b6..f7c0b92 100644
--- a/base/system_monitor/system_monitor_ios.mm
+++ b/base/power_monitor/power_monitor_ios.mm
@@ -1,34 +1,34 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
+// Copyright 2013 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/system_monitor/system_monitor.h"
+#include "base/power_monitor/power_monitor.h"
#import <UIKit/UIKit.h>
namespace base {
-void SystemMonitor::PlatformInit() {
+void PowerMonitor::PlatformInit() {
NSNotificationCenter* nc = [NSNotificationCenter defaultCenter];
id foreground =
[nc addObserverForName:UIApplicationWillEnterForegroundNotification
object:nil
queue:nil
usingBlock:^(NSNotification* notification) {
- ProcessPowerMessage(RESUME_EVENT);
+ ProcessPowerEvent(RESUME_EVENT);
}];
id background =
[nc addObserverForName:UIApplicationDidEnterBackgroundNotification
object:nil
queue:nil
usingBlock:^(NSNotification* notification) {
- ProcessPowerMessage(SUSPEND_EVENT);
+ ProcessPowerEvent(SUSPEND_EVENT);
}];
notification_observers_.push_back(foreground);
notification_observers_.push_back(background);
}
-void SystemMonitor::PlatformDestroy() {
+void PowerMonitor::PlatformDestroy() {
NSNotificationCenter* nc = [NSNotificationCenter defaultCenter];
for (std::vector<id>::iterator it = notification_observers_.begin();
it != notification_observers_.end(); ++it) {
diff --git a/base/system_monitor/system_monitor_mac.mm b/base/power_monitor/power_monitor_mac.mm
similarity index 80%
rename from base/system_monitor/system_monitor_mac.mm
rename to base/power_monitor/power_monitor_mac.mm
index d0dbaab..ee906f6 100644
--- a/base/system_monitor/system_monitor_mac.mm
+++ b/base/power_monitor/power_monitor_mac.mm
@@ -1,17 +1,23 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
+// Copyright 2013 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.
// Implementation based on sample code from
// http://developer.apple.com/library/mac/#qa/qa1340/_index.html.
-#include "base/system_monitor/system_monitor.h"
+#include "base/power_monitor/power_monitor.h"
#include <IOKit/pwr_mgt/IOPMLib.h>
#include <IOKit/IOMessage.h>
namespace base {
+void ProcessPowerEventHelper(PowerMonitor::PowerEvent event) {
+ DCHECK(PowerMonitor::Get());
+ if (PowerMonitor::Get())
+ PowerMonitor::Get()->ProcessPowerEvent(event);
+}
+
namespace {
io_connect_t g_system_power_io_port = 0;
@@ -22,17 +28,15 @@
io_service_t service,
natural_t message_type,
void* message_argument) {
- SystemMonitor* sys_monitor = SystemMonitor::Get();
- DCHECK(sys_monitor);
switch (message_type) {
case kIOMessageSystemWillSleep:
- sys_monitor->ProcessPowerMessage(SystemMonitor::SUSPEND_EVENT);
+ ProcessPowerEventHelper(base::PowerMonitor::SUSPEND_EVENT);
IOAllowPowerChange(g_system_power_io_port,
reinterpret_cast<intptr_t>(message_argument));
break;
case kIOMessageSystemWillPowerOn:
- sys_monitor->ProcessPowerMessage(SystemMonitor::RESUME_EVENT);
+ ProcessPowerEventHelper(PowerMonitor::RESUME_EVENT);
break;
}
}
@@ -45,11 +49,10 @@
// See crbug.com/83783 .
// static
-void SystemMonitor::AllocateSystemIOPorts() {
+void PowerMonitor::AllocateSystemIOPorts() {
DCHECK_EQ(g_system_power_io_port, 0u);
// Notification port allocated by IORegisterForSystemPower.
-
g_system_power_io_port = IORegisterForSystemPower(
NULL, &g_notification_port_ref, SystemPowerEventCallback,
&g_notifier_object);
@@ -57,8 +60,8 @@
DCHECK_NE(g_system_power_io_port, 0u);
}
-void SystemMonitor::PlatformInit() {
- // Need to call AllocateSystemIOPorts() before constructing a SystemMonitor
+void PowerMonitor::PlatformInit() {
+ // Need to call AllocateSystemIOPorts() before creating a PowerMonitor
// object.
DCHECK_NE(g_system_power_io_port, 0u);
if (g_system_power_io_port == 0)
@@ -71,7 +74,7 @@
kCFRunLoopCommonModes);
}
-void SystemMonitor::PlatformDestroy() {
+void PowerMonitor::PlatformDestroy() {
DCHECK_NE(g_system_power_io_port, 0u);
if (g_system_power_io_port == 0)
return;
diff --git a/base/power_monitor/power_monitor_posix.cc b/base/power_monitor/power_monitor_posix.cc
new file mode 100644
index 0000000..affebea
--- /dev/null
+++ b/base/power_monitor/power_monitor_posix.cc
@@ -0,0 +1,14 @@
+// Copyright 2013 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/power_monitor/power_monitor.h"
+
+namespace base {
+
+bool PowerMonitor::IsBatteryPower() {
+ NOTIMPLEMENTED();
+ return false;
+}
+
+} // namespace base
diff --git a/base/power_monitor/power_monitor_unittest.cc b/base/power_monitor/power_monitor_unittest.cc
new file mode 100644
index 0000000..af3ed41
--- /dev/null
+++ b/base/power_monitor/power_monitor_unittest.cc
@@ -0,0 +1,106 @@
+// Copyright 2013 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/power_monitor/power_monitor.h"
+
+#include "base/message_loop.h"
+#include "testing/gtest/include/gtest/gtest.h"
+
+namespace base {
+
+class PowerTest : public PowerObserver {
+ public:
+ PowerTest()
+ : power_state_changes_(0),
+ suspends_(0),
+ resumes_(0) {
+ }
+
+ // PowerObserver callbacks.
+ virtual void OnPowerStateChange(bool on_battery_power) OVERRIDE {
+ power_state_changes_++;
+ }
+
+ virtual void OnSuspend() OVERRIDE {
+ suspends_++;
+ }
+
+ virtual void OnResume() OVERRIDE {
+ resumes_++;
+ }
+
+ // Test status counts.
+ int power_state_changes() { return power_state_changes_; }
+ int suspends() { return suspends_; }
+ int resumes() { return resumes_; }
+
+ private:
+ int power_state_changes_; // Count of OnPowerStateChange notifications.
+ int suspends_; // Count of OnSuspend notifications.
+ int resumes_; // Count of OnResume notifications.
+};
+
+class PowerMonitorTest : public testing::Test {
+ protected:
+ PowerMonitorTest() {
+#if defined(OS_MACOSX)
+ // This needs to happen before PowerMonitor's ctor.
+ PowerMonitor::AllocateSystemIOPorts();
+#endif
+ power_monitor_.reset(new PowerMonitor);
+ }
+
+ void ProcessPowerEvent(PowerMonitor::PowerEvent event_id) {
+ power_monitor_->ProcessPowerEvent(event_id);
+ }
+
+ virtual ~PowerMonitorTest() {}
+
+ MessageLoop message_loop_;
+ scoped_ptr<PowerMonitor> power_monitor_;
+
+ DISALLOW_COPY_AND_ASSIGN(PowerMonitorTest);
+};
+
+TEST_F(PowerMonitorTest, PowerNotifications) {
+ const int kObservers = 5;
+
+ PowerTest test[kObservers];
+ for (int index = 0; index < kObservers; ++index)
+ power_monitor_->AddObserver(&test[index]);
+
+ // Send a bunch of power changes. Since the battery power hasn't
+ // actually changed, we shouldn't get notifications.
+ for (int index = 0; index < 5; index++) {
+ ProcessPowerEvent(PowerMonitor::POWER_STATE_EVENT);
+ EXPECT_EQ(test[0].power_state_changes(), 0);
+ }
+
+ // Sending resume when not suspended should have no effect.
+ ProcessPowerEvent(PowerMonitor::RESUME_EVENT);
+ message_loop_.RunUntilIdle();
+ EXPECT_EQ(test[0].resumes(), 0);
+
+ // Pretend we suspended.
+ ProcessPowerEvent(PowerMonitor::SUSPEND_EVENT);
+ message_loop_.RunUntilIdle();
+ EXPECT_EQ(test[0].suspends(), 1);
+
+ // Send a second suspend notification. This should be suppressed.
+ ProcessPowerEvent(PowerMonitor::SUSPEND_EVENT);
+ message_loop_.RunUntilIdle();
+ EXPECT_EQ(test[0].suspends(), 1);
+
+ // Pretend we were awakened.
+ ProcessPowerEvent(PowerMonitor::RESUME_EVENT);
+ message_loop_.RunUntilIdle();
+ EXPECT_EQ(test[0].resumes(), 1);
+
+ // Send a duplicate resume notification. This should be suppressed.
+ ProcessPowerEvent(PowerMonitor::RESUME_EVENT);
+ message_loop_.RunUntilIdle();
+ EXPECT_EQ(test[0].resumes(), 1);
+}
+
+} // namespace base
diff --git a/base/system_monitor/system_monitor_win.cc b/base/power_monitor/power_monitor_win.cc
similarity index 70%
rename from base/system_monitor/system_monitor_win.cc
rename to base/power_monitor/power_monitor_win.cc
index 562b69b..156ee2b 100644
--- a/base/system_monitor/system_monitor_win.cc
+++ b/base/power_monitor/power_monitor_win.cc
@@ -1,8 +1,8 @@
-// Copyright (c) 2011 The Chromium Authors. All rights reserved.
+// Copyright 2013 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/system_monitor/system_monitor.h"
+#include "base/power_monitor/power_monitor.h"
#include "base/win/wrapped_window_proc.h"
@@ -16,7 +16,7 @@
// Function to query the system to see if it is currently running on
// battery power. Returns true if running on battery.
-bool SystemMonitor::IsBatteryPower() {
+bool PowerMonitor::IsBatteryPower() {
SYSTEM_POWER_STATUS status;
if (!GetSystemPowerStatus(&status)) {
DLOG_GETLASTERROR(ERROR) << "GetSystemPowerStatus failed";
@@ -25,13 +25,20 @@
return (status.ACLineStatus == 0);
}
-SystemMonitor::PowerMessageWindow::PowerMessageWindow()
+PowerMonitor::PowerMessageWindow::PowerMessageWindow()
: instance_(NULL), message_hwnd_(NULL) {
+ if (MessageLoop::current()->type() != MessageLoop::TYPE_UI) {
+ // Creating this window in (e.g.) a renderer inhibits shutdown on Windows.
+ // See http://crbug.com/230122. TODO(vandebo): http://crbug.com/236031
+ DLOG(ERROR)
+ << "Cannot create windows on non-UI thread, power monitor disabled!";
+ return;
+ }
WNDCLASSEX window_class;
base::win::InitializeWindowClass(
kWindowClassName,
&base::win::WrappedWindowProc<
- SystemMonitor::PowerMessageWindow::WndProcThunk>,
+ PowerMonitor::PowerMessageWindow::WndProcThunk>,
0, 0, 0, NULL, NULL, NULL, NULL, NULL,
&window_class);
instance_ = window_class.hInstance;
@@ -44,29 +51,29 @@
reinterpret_cast<LONG_PTR>(this));
}
-SystemMonitor::PowerMessageWindow::~PowerMessageWindow() {
+PowerMonitor::PowerMessageWindow::~PowerMessageWindow() {
if (message_hwnd_) {
DestroyWindow(message_hwnd_);
UnregisterClass(kWindowClassName, instance_);
}
}
-void SystemMonitor::PowerMessageWindow::ProcessWmPowerBroadcastMessage(
+void PowerMonitor::PowerMessageWindow::ProcessWmPowerBroadcastMessage(
int event_id) {
- SystemMonitor::PowerEvent power_event;
+ PowerMonitor::PowerEvent power_event;
switch (event_id) {
case PBT_APMPOWERSTATUSCHANGE: // The power status changed.
- power_event = SystemMonitor::POWER_STATE_EVENT;
+ power_event = PowerMonitor::POWER_STATE_EVENT;
break;
case PBT_APMRESUMEAUTOMATIC: // Resume from suspend.
//case PBT_APMRESUMESUSPEND: // User-initiated resume from suspend.
// We don't notify for this latter event
// because if it occurs it is always sent as a
// second event after PBT_APMRESUMEAUTOMATIC.
- power_event = SystemMonitor::RESUME_EVENT;
+ power_event = PowerMonitor::RESUME_EVENT;
break;
case PBT_APMSUSPEND: // System has been suspended.
- power_event = SystemMonitor::SUSPEND_EVENT;
+ power_event = PowerMonitor::SUSPEND_EVENT;
break;
default:
return;
@@ -80,10 +87,10 @@
// PBT_POWERSETTINGCHANGE - user changed the power settings.
}
- SystemMonitor::Get()->ProcessPowerMessage(power_event);
+ PowerMonitor::Get()->ProcessPowerEvent(power_event);
}
-LRESULT CALLBACK SystemMonitor::PowerMessageWindow::WndProc(
+LRESULT CALLBACK PowerMonitor::PowerMessageWindow::WndProc(
HWND hwnd, UINT message, WPARAM wparam, LPARAM lparam) {
switch (message) {
case WM_POWERBROADCAST: {
@@ -98,10 +105,10 @@
}
// static
-LRESULT CALLBACK SystemMonitor::PowerMessageWindow::WndProcThunk(
+LRESULT CALLBACK PowerMonitor::PowerMessageWindow::WndProcThunk(
HWND hwnd, UINT message, WPARAM wparam, LPARAM lparam) {
- SystemMonitor::PowerMessageWindow* message_hwnd =
- reinterpret_cast<SystemMonitor::PowerMessageWindow*>(
+ PowerMonitor::PowerMessageWindow* message_hwnd =
+ reinterpret_cast<PowerMonitor::PowerMessageWindow*>(
GetWindowLongPtr(hwnd, GWLP_USERDATA));
if (message_hwnd)
return message_hwnd->WndProc(hwnd, message, wparam, lparam);
diff --git a/base/power_monitor/power_observer.h b/base/power_monitor/power_observer.h
new file mode 100644
index 0000000..6be70bb
--- /dev/null
+++ b/base/power_monitor/power_observer.h
@@ -0,0 +1,31 @@
+// Copyright 2013 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 BASE_POWER_MONITOR_POWER_OBSERVER_H_
+#define BASE_POWER_MONITOR_POWER_OBSERVER_H_
+
+#include "base/base_export.h"
+#include "base/compiler_specific.h"
+
+namespace base {
+
+class BASE_EXPORT PowerObserver {
+ public:
+ // Notification of a change in power status of the computer, such
+ // as from switching between battery and A/C power.
+ virtual void OnPowerStateChange(bool on_battery_power) {};
+
+ // Notification that the system is suspending.
+ virtual void OnSuspend() {}
+
+ // Notification that the system is resuming.
+ virtual void OnResume() {}
+
+ protected:
+ virtual ~PowerObserver() {}
+};
+
+} // namespace base
+
+#endif // BASE_POWER_MONITOR_POWER_OBSERVER_H_
diff --git a/base/prefs/json_pref_store_unittest.cc b/base/prefs/json_pref_store_unittest.cc
index 175ef2c..1368b3f 100644
--- a/base/prefs/json_pref_store_unittest.cc
+++ b/base/prefs/json_pref_store_unittest.cc
@@ -42,13 +42,8 @@
virtual void SetUp() OVERRIDE {
ASSERT_TRUE(temp_dir_.CreateUniqueTempDir());
- ASSERT_TRUE(PathService::Get(base::DIR_SOURCE_ROOT, &data_dir_));
- data_dir_ = data_dir_.AppendASCII("base");
+ ASSERT_TRUE(PathService::Get(base::DIR_TEST_DATA, &data_dir_));
data_dir_ = data_dir_.AppendASCII("prefs");
- data_dir_ = data_dir_.AppendASCII("test");
- data_dir_ = data_dir_.AppendASCII("data");
- data_dir_ = data_dir_.AppendASCII("pref_service");
- LOG(WARNING) << data_dir_.value().c_str();
ASSERT_TRUE(file_util::PathExists(data_dir_));
}
diff --git a/base/prefs/pref_change_registrar_unittest.cc b/base/prefs/pref_change_registrar_unittest.cc
index 49da721..f353a8f 100644
--- a/base/prefs/pref_change_registrar_unittest.cc
+++ b/base/prefs/pref_change_registrar_unittest.cc
@@ -132,7 +132,7 @@
PrefRegistrySimple* registry = pref_service_->registry();
registry->RegisterStringPref(kHomePage, "http://google.com");
registry->RegisterBooleanPref(kHomePageIsNewTabPage, false);
- registry->RegisterStringPref(kApplicationLocale, "");
+ registry->RegisterStringPref(kApplicationLocale, std::string());
}
PrefChangeRegistrar* CreatePrefChangeRegistrar() {
diff --git a/base/prefs/pref_notifier_impl.cc b/base/prefs/pref_notifier_impl.cc
index 1fa495d..c02a7b3 100644
--- a/base/prefs/pref_notifier_impl.cc
+++ b/base/prefs/pref_notifier_impl.cc
@@ -17,7 +17,7 @@
}
PrefNotifierImpl::~PrefNotifierImpl() {
- DCHECK(CalledOnValidThread());
+ DCHECK(thread_checker_.CalledOnValidThread());
// Verify that there are no pref observers when we shut down.
for (PrefObserverMap::iterator it = pref_observers_.begin();
@@ -58,7 +58,7 @@
void PrefNotifierImpl::RemovePrefObserver(const char* path,
PrefObserver* obs) {
- DCHECK(CalledOnValidThread());
+ DCHECK(thread_checker_.CalledOnValidThread());
const PrefObserverMap::iterator observer_iterator =
pref_observers_.find(path);
@@ -79,7 +79,7 @@
}
void PrefNotifierImpl::OnInitializationCompleted(bool succeeded) {
- DCHECK(CalledOnValidThread());
+ DCHECK(thread_checker_.CalledOnValidThread());
// We must make a copy of init_observers_ and clear it before we run
// observers, or we can end up in this method re-entrantly before
@@ -95,7 +95,7 @@
}
void PrefNotifierImpl::FireObservers(const std::string& path) {
- DCHECK(CalledOnValidThread());
+ DCHECK(thread_checker_.CalledOnValidThread());
// Only send notifications for registered preferences.
if (!pref_service_->FindPreference(path.c_str()))
diff --git a/base/prefs/pref_notifier_impl.h b/base/prefs/pref_notifier_impl.h
index 8e6f090..8f5120a 100644
--- a/base/prefs/pref_notifier_impl.h
+++ b/base/prefs/pref_notifier_impl.h
@@ -15,14 +15,13 @@
#include "base/prefs/base_prefs_export.h"
#include "base/prefs/pref_notifier.h"
#include "base/prefs/pref_observer.h"
-#include "base/threading/non_thread_safe.h"
+#include "base/threading/thread_checker.h"
class PrefService;
// The PrefNotifier implementation used by the PrefService.
class BASE_PREFS_EXPORT PrefNotifierImpl
- : public NON_EXPORTED_BASE(PrefNotifier),
- public base::NonThreadSafe {
+ : public NON_EXPORTED_BASE(PrefNotifier) {
public:
PrefNotifierImpl();
explicit PrefNotifierImpl(PrefService* pref_service);
@@ -66,6 +65,8 @@
PrefObserverMap pref_observers_;
PrefInitObserverList init_observers_;
+ base::ThreadChecker thread_checker_;
+
DISALLOW_COPY_AND_ASSIGN(PrefNotifierImpl);
};
diff --git a/base/prefs/pref_service.cc b/base/prefs/pref_service.cc
index 3b0e2cb..babe40a 100644
--- a/base/prefs/pref_service.cc
+++ b/base/prefs/pref_service.cc
@@ -217,7 +217,7 @@
case PersistentPrefStore::PREF_READ_ERROR_NONE:
return INITIALIZATION_STATUS_SUCCESS;
case PersistentPrefStore::PREF_READ_ERROR_NO_FILE:
- return INITIALIZATION_STATUS_CREATED_NEW_PROFILE;
+ return INITIALIZATION_STATUS_CREATED_NEW_PREF_STORE;
default:
return INITIALIZATION_STATUS_ERROR;
}
diff --git a/base/prefs/pref_service.h b/base/prefs/pref_service.h
index d88dc91..97ad15e 100644
--- a/base/prefs/pref_service.h
+++ b/base/prefs/pref_service.h
@@ -53,7 +53,7 @@
enum PrefInitializationStatus {
INITIALIZATION_STATUS_WAITING,
INITIALIZATION_STATUS_SUCCESS,
- INITIALIZATION_STATUS_CREATED_NEW_PROFILE,
+ INITIALIZATION_STATUS_CREATED_NEW_PREF_STORE,
INITIALIZATION_STATUS_ERROR
};
diff --git a/base/prefs/pref_service_unittest.cc b/base/prefs/pref_service_unittest.cc
index 26fe19a..927f2f7 100644
--- a/base/prefs/pref_service_unittest.cc
+++ b/base/prefs/pref_service_unittest.cc
@@ -45,7 +45,7 @@
Mock::VerifyAndClearExpectations(&obs);
// Clearing the pref should cause the pref to fire.
- const StringValue expected_default_value("");
+ const StringValue expected_default_value((std::string()));
obs.Expect(pref_name, &expected_default_value);
prefs.ClearPref(pref_name);
Mock::VerifyAndClearExpectations(&obs);
diff --git a/base/process_util.h b/base/process_util.h
index 54d8533..a06f689 100644
--- a/base/process_util.h
+++ b/base/process_util.h
@@ -232,13 +232,6 @@
typedef std::vector<std::pair<std::string, std::string> > EnvironmentVector;
typedef std::vector<std::pair<int, int> > FileHandleMappingVector;
-#if defined(OS_MACOSX)
-// Used with LaunchOptions::synchronize and LaunchSynchronize, a
-// LaunchSynchronizationHandle is an opaque value that LaunchProcess will
-// create and set, and that LaunchSynchronize will consume and destroy.
-typedef int* LaunchSynchronizationHandle;
-#endif // defined(OS_MACOSX)
-
// Options for launching a subprocess that are passed to LaunchProcess().
// The default constructor constructs the object with default options.
struct LaunchOptions {
@@ -266,9 +259,6 @@
#if defined(OS_CHROMEOS)
, ctrl_terminal_fd(-1)
#endif // OS_CHROMEOS
-#if defined(OS_MACOSX)
- , synchronize(NULL)
-#endif // defined(OS_MACOSX)
#endif // !defined(OS_WIN)
{}
@@ -350,27 +340,6 @@
int ctrl_terminal_fd;
#endif // defined(OS_CHROMEOS)
-#if defined(OS_MACOSX)
- // When non-NULL, a new LaunchSynchronizationHandle will be created and
- // stored in *synchronize whenever LaunchProcess returns true in the parent
- // process. The child process will have been created (with fork) but will
- // be waiting (before exec) for the parent to call LaunchSynchronize with
- // this handle. Only when LaunchSynchronize is called will the child be
- // permitted to continue execution and call exec. LaunchSynchronize
- // destroys the handle created by LaunchProcess.
- //
- // When synchronize is non-NULL, the parent must call LaunchSynchronize
- // whenever LaunchProcess returns true. No exceptions.
- //
- // Synchronization is useful when the parent process needs to guarantee that
- // it can take some action (such as recording the newly-forked child's
- // process ID) before the child does something (such as using its process ID
- // to communicate with its parent).
- //
- // |synchronize| and |wait| must not both be set simultaneously.
- LaunchSynchronizationHandle* synchronize;
-#endif // defined(OS_MACOSX)
-
#endif // !defined(OS_WIN)
};
@@ -442,15 +411,6 @@
// The returned array is allocated using new[] and must be freed by the caller.
BASE_EXPORT char** AlterEnvironment(const EnvironmentVector& changes,
const char* const* const env);
-
-#if defined(OS_MACOSX)
-
-// After a successful call to LaunchProcess with LaunchOptions::synchronize
-// set, the parent process must call LaunchSynchronize to allow the child
-// process to proceed, and to destroy the LaunchSynchronizationHandle.
-BASE_EXPORT void LaunchSynchronize(LaunchSynchronizationHandle handle);
-
-#endif // defined(OS_MACOSX)
#endif // defined(OS_POSIX)
#if defined(OS_WIN)
diff --git a/base/process_util_ios.mm b/base/process_util_ios.mm
index 161d396..9d96990 100644
--- a/base/process_util_ios.mm
+++ b/base/process_util_ios.mm
@@ -57,6 +57,13 @@
return new ProcessMetrics(process);
}
+size_t ProcessMetrics::GetPagefileUsage() const {
+ task_basic_info_64 task_info_data;
+ if (!GetTaskInfo(&task_info_data))
+ return 0;
+ return task_info_data.virtual_size;
+}
+
size_t ProcessMetrics::GetWorkingSetSize() const {
task_basic_info_64 task_info_data;
if (!GetTaskInfo(&task_info_data))
diff --git a/base/process_util_linux.cc b/base/process_util_linux.cc
index 2af9227..2c2824f 100644
--- a/base/process_util_linux.cc
+++ b/base/process_util_linux.cc
@@ -161,7 +161,7 @@
ProcStatsFields field_num) {
if (field_num < VM_COMM || field_num > VM_STATE) {
NOTREACHED();
- return "";
+ return std::string();
}
if (proc_stats.size() > static_cast<size_t>(field_num))
@@ -391,10 +391,7 @@
entry_.ppid_ = GetProcStatsFieldAsInt(proc_stats, VM_PPID);
entry_.gid_ = GetProcStatsFieldAsInt(proc_stats, VM_PGRP);
entry_.cmd_line_args_.assign(cmd_line_args.begin(), cmd_line_args.end());
-
- // TODO(port): read pid's commandline's $0, like killall does. Using the
- // short name between openparen and closeparen won't work for long names!
- entry_.exe_file_ = GetProcStatsFieldAsString(proc_stats, VM_COMM);
+ entry_.exe_file_ = GetProcessExecutablePath(pid).BaseName().value();
return true;
}
diff --git a/base/process_util_mac.mm b/base/process_util_mac.mm
index 925f21e..e0174b4 100644
--- a/base/process_util_mac.mm
+++ b/base/process_util_mac.mm
@@ -6,14 +6,12 @@
#import <Cocoa/Cocoa.h>
#include <crt_externs.h>
-#include <dlfcn.h>
#include <errno.h>
#include <mach/mach.h>
#include <mach/mach_init.h>
#include <mach/mach_vm.h>
#include <mach/shared_region.h>
#include <mach/task.h>
-#include <mach-o/nlist.h>
#include <malloc/malloc.h>
#import <objc/runtime.h>
#include <signal.h>
@@ -34,12 +32,19 @@
#include "base/mac/mac_util.h"
#include "base/mac/scoped_mach_port.h"
#include "base/posix/eintr_wrapper.h"
+#include "base/scoped_clear_errno.h"
#include "base/string_util.h"
#include "base/sys_info.h"
-#include "base/threading/thread_local.h"
#include "third_party/apple_apsl/CFBase.h"
#include "third_party/apple_apsl/malloc.h"
+
+#if ARCH_CPU_32_BITS
+#include <dlfcn.h>
+#include <mach-o/nlist.h>
+
+#include "base/threading/thread_local.h"
#include "third_party/mach_override/mach_override.h"
+#endif // ARCH_CPU_32_BITS
namespace base {
@@ -486,6 +491,9 @@
return (data.active_count * page_size) / 1024;
}
+// These are helpers for EnableTerminationOnHeapCorruption, which is a no-op
+// on 64 bit Macs.
+#if ARCH_CPU_32_BITS
namespace {
// Finds the library path for malloc() and thus the libC part of libSystem,
@@ -508,7 +516,6 @@
// as __private_extern__ and cannot be dlsym()ed. Instead, use nlist() to
// get it.
malloc_error_break_t LookUpMallocErrorBreak() {
-#if ARCH_CPU_32_BITS
const char* lib_c_path = LookUpLibCPath();
if (!lib_c_path)
return NULL;
@@ -538,30 +545,8 @@
reference_addr += nl[0].n_value;
return reinterpret_cast<malloc_error_break_t>(reference_addr);
-#endif // ARCH_CPU_32_BITS
-
- return NULL;
}
-// Simple scoper that saves the current value of errno, resets it to 0, and on
-// destruction puts the old value back. This is so that CrMallocErrorBreak can
-// safely test errno free from the effects of other routines.
-class ScopedClearErrno {
- public:
- ScopedClearErrno() : old_errno_(errno) {
- errno = 0;
- }
- ~ScopedClearErrno() {
- if (errno == 0)
- errno = old_errno_;
- }
-
- private:
- int old_errno_;
-
- DISALLOW_COPY_AND_ASSIGN(ScopedClearErrno);
-};
-
// Combines ThreadLocalBoolean with AutoReset. It would be convenient
// to compose ThreadLocalPointer<bool> with base::AutoReset<bool>, but that
// would require allocating some storage for the bool.
@@ -624,14 +609,14 @@
}
} // namespace
+#endif // ARCH_CPU_32_BITS
void EnableTerminationOnHeapCorruption() {
-#ifdef ADDRESS_SANITIZER
- // Don't do anything special on heap corruption, because it should be handled
- // by AddressSanitizer.
+#if defined(ADDRESS_SANITIZER) || ARCH_CPU_64_BITS
+ // AddressSanitizer handles heap corruption, and on 64 bit Macs, the malloc
+ // system automatically abort()s on heap corruption.
return;
-#endif
-
+#else
// Only override once, otherwise CrMallocErrorBreak() will recurse
// to itself.
if (g_original_malloc_error_break)
@@ -650,6 +635,7 @@
if (err != err_none)
DLOG(WARNING) << "Could not override malloc_error_break; error = " << err;
+#endif // defined(ADDRESS_SANITIZER) || ARCH_CPU_64_BITS
}
// ------------------------------------------------------------------------
@@ -748,7 +734,9 @@
void* oom_killer_malloc(struct _malloc_zone_t* zone,
size_t size) {
+#if ARCH_CPU_32_BITS
ScopedClearErrno clear_errno;
+#endif // ARCH_CPU_32_BITS
void* result = g_old_malloc(zone, size);
if (!result && size)
debug::BreakDebugger();
@@ -758,7 +746,9 @@
void* oom_killer_calloc(struct _malloc_zone_t* zone,
size_t num_items,
size_t size) {
+#if ARCH_CPU_32_BITS
ScopedClearErrno clear_errno;
+#endif // ARCH_CPU_32_BITS
void* result = g_old_calloc(zone, num_items, size);
if (!result && num_items && size)
debug::BreakDebugger();
@@ -767,7 +757,9 @@
void* oom_killer_valloc(struct _malloc_zone_t* zone,
size_t size) {
+#if ARCH_CPU_32_BITS
ScopedClearErrno clear_errno;
+#endif // ARCH_CPU_32_BITS
void* result = g_old_valloc(zone, size);
if (!result && size)
debug::BreakDebugger();
@@ -776,14 +768,18 @@
void oom_killer_free(struct _malloc_zone_t* zone,
void* ptr) {
+#if ARCH_CPU_32_BITS
ScopedClearErrno clear_errno;
+#endif // ARCH_CPU_32_BITS
g_old_free(zone, ptr);
}
void* oom_killer_realloc(struct _malloc_zone_t* zone,
void* ptr,
size_t size) {
+#if ARCH_CPU_32_BITS
ScopedClearErrno clear_errno;
+#endif // ARCH_CPU_32_BITS
void* result = g_old_realloc(zone, ptr, size);
if (!result && size)
debug::BreakDebugger();
@@ -793,7 +789,9 @@
void* oom_killer_memalign(struct _malloc_zone_t* zone,
size_t alignment,
size_t size) {
+#if ARCH_CPU_32_BITS
ScopedClearErrno clear_errno;
+#endif // ARCH_CPU_32_BITS
void* result = g_old_memalign(zone, alignment, size);
// Only die if posix_memalign would have returned ENOMEM, since there are
// other reasons why NULL might be returned (see
@@ -807,7 +805,9 @@
void* oom_killer_malloc_purgeable(struct _malloc_zone_t* zone,
size_t size) {
+#if ARCH_CPU_32_BITS
ScopedClearErrno clear_errno;
+#endif // ARCH_CPU_32_BITS
void* result = g_old_malloc_purgeable(zone, size);
if (!result && size)
debug::BreakDebugger();
@@ -817,7 +817,9 @@
void* oom_killer_calloc_purgeable(struct _malloc_zone_t* zone,
size_t num_items,
size_t size) {
+#if ARCH_CPU_32_BITS
ScopedClearErrno clear_errno;
+#endif // ARCH_CPU_32_BITS
void* result = g_old_calloc_purgeable(zone, num_items, size);
if (!result && num_items && size)
debug::BreakDebugger();
@@ -826,7 +828,9 @@
void* oom_killer_valloc_purgeable(struct _malloc_zone_t* zone,
size_t size) {
+#if ARCH_CPU_32_BITS
ScopedClearErrno clear_errno;
+#endif // ARCH_CPU_32_BITS
void* result = g_old_valloc_purgeable(zone, size);
if (!result && size)
debug::BreakDebugger();
@@ -835,14 +839,18 @@
void oom_killer_free_purgeable(struct _malloc_zone_t* zone,
void* ptr) {
+#if ARCH_CPU_32_BITS
ScopedClearErrno clear_errno;
+#endif // ARCH_CPU_32_BITS
g_old_free_purgeable(zone, ptr);
}
void* oom_killer_realloc_purgeable(struct _malloc_zone_t* zone,
void* ptr,
size_t size) {
+#if ARCH_CPU_32_BITS
ScopedClearErrno clear_errno;
+#endif // ARCH_CPU_32_BITS
void* result = g_old_realloc_purgeable(zone, ptr, size);
if (!result && size)
debug::BreakDebugger();
@@ -852,7 +860,9 @@
void* oom_killer_memalign_purgeable(struct _malloc_zone_t* zone,
size_t alignment,
size_t size) {
+#if ARCH_CPU_32_BITS
ScopedClearErrno clear_errno;
+#endif // ARCH_CPU_32_BITS
void* result = g_old_memalign_purgeable(zone, alignment, size);
// Only die if posix_memalign would have returned ENOMEM, since there are
// other reasons why NULL might be returned (see
@@ -940,8 +950,10 @@
void* UncheckedMalloc(size_t size) {
if (g_old_malloc) {
+#if ARCH_CPU_32_BITS
ScopedClearErrno clear_errno;
ThreadLocalBooleanAutoReset flag(g_unchecked_malloc.Pointer(), true);
+#endif // ARCH_CPU_32_BITS
return g_old_malloc(malloc_default_zone(), size);
}
return malloc(size);
diff --git a/base/process_util_posix.cc b/base/process_util_posix.cc
index 52e964b..98ec183 100644
--- a/base/process_util_posix.cc
+++ b/base/process_util_posix.cc
@@ -604,15 +604,6 @@
fd_shuffle_size = options.fds_to_remap->size();
}
-#if defined(OS_MACOSX)
- if (options.synchronize) {
- // When synchronizing, the "read" end of the synchronization pipe needs
- // to make it to the child process. This is handled by mapping it back to
- // itself.
- ++fd_shuffle_size;
- }
-#endif // defined(OS_MACOSX)
-
InjectiveMultimap fd_shuffle1;
InjectiveMultimap fd_shuffle2;
fd_shuffle1.reserve(fd_shuffle_size);
@@ -623,34 +614,6 @@
if (options.environ)
new_environ.reset(AlterEnvironment(*options.environ, GetEnvironment()));
-#if defined(OS_MACOSX)
- int synchronization_pipe_fds[2];
- file_util::ScopedFD synchronization_read_fd;
- file_util::ScopedFD synchronization_write_fd;
-
- if (options.synchronize) {
- // wait means "don't return from LaunchProcess until the child exits", and
- // synchronize means "return from LaunchProcess but don't let the child
- // run until LaunchSynchronize is called". These two options are highly
- // incompatible.
- DCHECK(!options.wait);
-
- // Create the pipe used for synchronization.
- if (HANDLE_EINTR(pipe(synchronization_pipe_fds)) != 0) {
- DPLOG(ERROR) << "pipe";
- return false;
- }
-
- // The parent process will only use synchronization_write_fd as the write
- // side of the pipe. It can close the read side as soon as the child
- // process has forked off. The child process will only use
- // synchronization_read_fd as the read side of the pipe. In that process,
- // the write side can be closed as soon as it has forked.
- synchronization_read_fd.reset(&synchronization_pipe_fds[0]);
- synchronization_write_fd.reset(&synchronization_pipe_fds[1]);
- }
-#endif // OS_MACOSX
-
pid_t pid;
#if defined(OS_LINUX)
if (options.clone_flags) {
@@ -743,13 +706,6 @@
RAW_LOG(INFO, "Right after signal/exception handler restoration.");
}
-#if defined(OS_MACOSX)
- if (options.synchronize) {
- // The "write" side of the synchronization pipe belongs to the parent.
- synchronization_write_fd.reset(); // closes synchronization_pipe_fds[1]
- }
-#endif // defined(OS_MACOSX)
-
#if 0
// When debugging it can be helpful to check that we really aren't making
// any hidden calls to malloc.
@@ -789,16 +745,6 @@
RAW_LOG(INFO, "Right after fd_shuffle push_backs.");
}
-#if defined(OS_MACOSX)
- if (options.synchronize) {
- // Remap the read side of the synchronization pipe back onto itself,
- // ensuring that it won't be closed by CloseSuperfluousFds.
- int keep_fd = *synchronization_read_fd.get();
- fd_shuffle1.push_back(InjectionArc(keep_fd, keep_fd, false));
- fd_shuffle2.push_back(InjectionArc(keep_fd, keep_fd, false));
- }
-#endif // defined(OS_MACOSX)
-
if (options.environ)
SetEnvironment(new_environ.get());
@@ -816,24 +762,6 @@
RAW_LOG(INFO, "Right after CloseSuperfluousFds");
}
-#if defined(OS_MACOSX)
- if (options.synchronize) {
- // Do a blocking read to wait until the parent says it's OK to proceed.
- // The byte that's read here is written by LaunchSynchronize.
- char read_char;
- int read_result =
- HANDLE_EINTR(read(*synchronization_read_fd.get(), &read_char, 1));
- if (read_result != 1) {
- RAW_LOG(ERROR, "LaunchProcess: synchronization read: error");
- _exit(127);
- }
-
- // The pipe is no longer useful. Don't let it live on in the new process
- // after exec.
- synchronization_read_fd.reset(); // closes synchronization_pipe_fds[0]
- }
-#endif // defined(OS_MACOSX)
-
if (options.debug) {
RAW_LOG(INFO, "Right before execvp");
}
@@ -858,14 +786,6 @@
if (process_handle)
*process_handle = pid;
-
-#if defined(OS_MACOSX)
- if (options.synchronize) {
- // The "read" side of the synchronization pipe belongs to the child.
- synchronization_read_fd.reset(); // closes synchronization_pipe_fds[0]
- *options.synchronize = new int(*synchronization_write_fd.release());
- }
-#endif // defined(OS_MACOSX)
}
return true;
@@ -878,19 +798,6 @@
return LaunchProcess(cmdline.argv(), options, process_handle);
}
-#if defined(OS_MACOSX)
-void LaunchSynchronize(LaunchSynchronizationHandle handle) {
- int synchronization_fd = *handle;
- file_util::ScopedFD synchronization_fd_closer(&synchronization_fd);
- delete handle;
-
- // Write a '\0' character to the pipe.
- if (HANDLE_EINTR(write(synchronization_fd, "", 1)) != 1) {
- DPLOG(ERROR) << "write";
- }
-}
-#endif // defined(OS_MACOSX)
-
ProcessMetrics::~ProcessMetrics() { }
void RaiseProcessToHighPriority() {
diff --git a/base/process_util_unittest.cc b/base/process_util_unittest.cc
index d109fba..3ce9942 100644
--- a/base/process_util_unittest.cc
+++ b/base/process_util_unittest.cc
@@ -543,9 +543,6 @@
// The following code tests the system implementation of malloc() thus no need
// to test it under AddressSanitizer.
TEST_F(ProcessUtilTest, MacMallocFailureDoesNotTerminate) {
- // Install the OOM killer.
- base::EnableTerminationOnOutOfMemory();
-
// Test that ENOMEM doesn't crash via CrMallocErrorBreak two ways: the exit
// code and lack of the error string. The number of bytes is one less than
// MALLOC_ABSOLUTE_MAX_SIZE, more than which the system early-returns NULL and
@@ -553,7 +550,11 @@
// EnableTerminationOnOutOfMemory() for more information.
void* buf = NULL;
ASSERT_EXIT(
- buf = malloc(std::numeric_limits<size_t>::max() - (2 * PAGE_SIZE) - 1),
+ {
+ base::EnableTerminationOnOutOfMemory();
+
+ buf = malloc(std::numeric_limits<size_t>::max() - (2 * PAGE_SIZE) - 1);
+ },
testing::KilledBySignal(SIGTRAP),
"\\*\\*\\* error: can't allocate region.*"
"(Terminating process due to a potential for future heap "
@@ -567,16 +568,20 @@
// Assert that freeing an unallocated pointer will crash the process.
char buf[3];
asm("" : "=r" (buf)); // Prevent clang from being too smart.
-#if !defined(ADDRESS_SANITIZER)
- ASSERT_DEATH(free(buf), "being freed.*"
- "\\*\\*\\* set a breakpoint in malloc_error_break to debug.*"
- "Terminating process due to a potential for future heap corruption");
-#else
+#if ARCH_CPU_64_BITS
+ // On 64 bit Macs, the malloc system automatically abort()s on heap corruption
+ // but does not output anything.
+ ASSERT_DEATH(free(buf), "");
+#elif defined(ADDRESS_SANITIZER)
// AddressSanitizer replaces malloc() and prints a different error message on
// heap corruption.
ASSERT_DEATH(free(buf), "attempting free on address which "
"was not malloc\\(\\)-ed");
-#endif // !defined(ADDRESS_SANITIZER)
+#else
+ ASSERT_DEATH(free(buf), "being freed.*"
+ "\\*\\*\\* set a breakpoint in malloc_error_break to debug.*"
+ "Terminating process due to a potential for future heap corruption");
+#endif // ARCH_CPU_64_BITS || defined(ADDRESS_SANITIZER)
}
#endif // defined(OS_MACOSX)
@@ -664,7 +669,15 @@
return num_open_files;
}
-TEST_F(ProcessUtilTest, FDRemapping) {
+#if defined(ADDRESS_SANITIZER) || defined(THREAD_SANITIZER)
+// ProcessUtilTest.FDRemapping is flaky when ran under xvfb-run on Precise.
+// The problem is 100% reproducible with both ASan and TSan.
+// See http://crbug.com/136720.
+#define MAYBE_FDRemapping DISABLED_FDRemapping
+#else
+#define MAYBE_FDRemapping FDRemapping
+#endif
+TEST_F(ProcessUtilTest, MAYBE_FDRemapping) {
int fds_before = CountOpenFDsInChild();
// open some dummy fds to make sure they don't propagate over to the
@@ -745,8 +758,8 @@
EXPECT_EQ(0, setenv("BASE_TEST", "testing", 1 /* override */));
EXPECT_EQ("testing\n", TestLaunchProcess(env_changes, no_clone_flags));
- env_changes.push_back(std::make_pair(std::string("BASE_TEST"),
- std::string("")));
+ env_changes.push_back(
+ std::make_pair(std::string("BASE_TEST"), std::string()));
EXPECT_EQ("\n", TestLaunchProcess(env_changes, no_clone_flags));
env_changes[0].second = "foo";
@@ -787,7 +800,7 @@
delete[] e;
changes.clear();
- changes.push_back(std::make_pair(std::string("A"), std::string("")));
+ changes.push_back(std::make_pair(std::string("A"), std::string()));
e = base::AlterEnvironment(changes, empty);
EXPECT_TRUE(e[0] == NULL);
delete[] e;
@@ -806,7 +819,7 @@
delete[] e;
changes.clear();
- changes.push_back(std::make_pair(std::string("A"), std::string("")));
+ changes.push_back(std::make_pair(std::string("A"), std::string()));
e = base::AlterEnvironment(changes, a2);
EXPECT_TRUE(e[0] == NULL);
delete[] e;
diff --git a/base/process_util_win.cc b/base/process_util_win.cc
index 2861d30..0dd679b 100644
--- a/base/process_util_win.cc
+++ b/base/process_util_win.cc
@@ -201,7 +201,9 @@
// We try to limit privileges granted to the handle. If you need this
// for test code, consider using OpenPrivilegedProcessHandle instead of
// adding more privileges here.
- ProcessHandle result = OpenProcess(PROCESS_DUP_HANDLE | PROCESS_TERMINATE,
+ ProcessHandle result = OpenProcess(PROCESS_TERMINATE |
+ PROCESS_QUERY_INFORMATION |
+ SYNCHRONIZE,
FALSE, pid);
if (result == NULL)
diff --git a/base/run_loop.h b/base/run_loop.h
index 8314737..380c8bf 100644
--- a/base/run_loop.h
+++ b/base/run_loop.h
@@ -73,7 +73,7 @@
base::Closure QuitClosure();
private:
- friend class ::MessageLoop;
+ friend class MessageLoop;
#if defined(OS_ANDROID)
// Android doesn't support the blocking MessageLoop::Run, so it calls
// BeforeRun and AfterRun directly.
diff --git a/base/scoped_clear_errno.h b/base/scoped_clear_errno.h
new file mode 100644
index 0000000..7b972fc
--- /dev/null
+++ b/base/scoped_clear_errno.h
@@ -0,0 +1,34 @@
+// Copyright (c) 2013 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 BASE_SCOPED_CLEAR_ERRNO_H_
+#define BASE_SCOPED_CLEAR_ERRNO_H_
+
+#include <errno.h>
+
+#include "base/basictypes.h"
+
+namespace base {
+
+// Simple scoper that saves the current value of errno, resets it to 0, and on
+// destruction puts the old value back.
+class ScopedClearErrno {
+ public:
+ ScopedClearErrno() : old_errno_(errno) {
+ errno = 0;
+ }
+ ~ScopedClearErrno() {
+ if (errno == 0)
+ errno = old_errno_;
+ }
+
+ private:
+ const int old_errno_;
+
+ DISALLOW_COPY_AND_ASSIGN(ScopedClearErrno);
+};
+
+} // namespace base
+
+#endif // BASE_SCOPED_CLEAR_ERRNO_H_
diff --git a/base/scoped_clear_errno_unittest.cc b/base/scoped_clear_errno_unittest.cc
new file mode 100644
index 0000000..8afb33e
--- /dev/null
+++ b/base/scoped_clear_errno_unittest.cc
@@ -0,0 +1,30 @@
+// Copyright (c) 2013 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 <errno.h>
+
+#include "base/scoped_clear_errno.h"
+#include "testing/gtest/include/gtest/gtest.h"
+
+namespace base {
+
+TEST(ScopedClearErrno, TestNoError) {
+ errno = 1;
+ {
+ ScopedClearErrno clear_error;
+ EXPECT_EQ(0, errno);
+ }
+ EXPECT_EQ(1, errno);
+}
+
+TEST(ScopedClearErrno, TestError) {
+ errno = 1;
+ {
+ ScopedClearErrno clear_error;
+ errno = 2;
+ }
+ EXPECT_EQ(2, errno);
+}
+
+} // namespace base
diff --git a/base/security_unittest.cc b/base/security_unittest.cc
index 2e865bc..e6e22a0 100644
--- a/base/security_unittest.cc
+++ b/base/security_unittest.cc
@@ -34,6 +34,11 @@
// as something we don't need (see the comment with calloc below).
template <typename Type>
Type HideValueFromCompiler(volatile Type value) {
+#if defined(__GNUC__)
+ // In a GCC compatible compiler (GCC or Clang), make this compiler barrier
+ // more robust than merely using "volatile".
+ __asm__ volatile ("" : "+r" (value));
+#endif // __GNUC__
return value;
}
@@ -145,10 +150,10 @@
#define DISABLE_ON_IOS_AND_WIN(function) function
#endif
-#if defined(ADDRESS_SANITIZER)
- #define DISABLE_ON_ASAN(function) DISABLED_##function
+#if defined(ADDRESS_SANITIZER) && defined(OS_MACOSX)
+ #define DISABLE_ON_MAC_WITH_ASAN(function) DISABLED_##function
#else
- #define DISABLE_ON_ASAN(function) function
+ #define DISABLE_ON_MAC_WITH_ASAN(function) function
#endif
// There are platforms where these tests are known to fail. We would like to
@@ -169,12 +174,9 @@
}
}
-// TODO(jln): crbug.com/174947 This can't even compile on Win64.
-#if !(defined(OS_WIN) && defined(ARCH_CPU_X86_64))
-
// Test array[TooBig][X] and array[X][TooBig] allocations for int overflows.
// IOS doesn't honor nothrow, so disable the test there.
-// Disable on Windows, we suspect some are failing because of it.
+// Crashes on Windows Dbg builds, disable there as well.
TEST(SecurityTest, DISABLE_ON_IOS_AND_WIN(NewOverflow)) {
const size_t kArraySize = 4096;
// We want something "dynamic" here, so that the compiler doesn't
@@ -191,13 +193,16 @@
char[kDynamicArraySize2][kArraySize]);
OverflowTestsSoftExpectTrue(!array_pointer);
}
+ // On windows, the compiler prevents static array sizes of more than
+ // 0x7fffffff (error C2148).
+#if !defined(OS_WIN) || !defined(ARCH_CPU_64_BITS)
{
scoped_ptr<char[][kArraySize2]> array_pointer(new (nothrow)
char[kDynamicArraySize][kArraySize2]);
OverflowTestsSoftExpectTrue(!array_pointer);
}
+#endif // !defined(OS_WIN) || !defined(ARCH_CPU_64_BITS)
}
-#endif
// Call calloc(), eventually free the memory and return whether or not
// calloc() did succeed.
@@ -210,9 +215,8 @@
return HideValueFromCompiler(array_pointer.get()) == NULL;
}
-// Test if calloc() can overflow. Disable on ASAN for now since the
-// overflow seems present there (crbug.com/175554).
-TEST(SecurityTest, DISABLE_ON_ASAN(CallocOverflow)) {
+// Test if calloc() can overflow.
+TEST(SecurityTest, DISABLE_ON_MAC_WITH_ASAN(CallocOverflow)) {
const size_t kArraySize = 4096;
const size_t kMaxSizeT = numeric_limits<size_t>::max();
const size_t kArraySize2 = kMaxSizeT / kArraySize + 10;
diff --git a/base/shared_memory.h b/base/shared_memory.h
index da6f5b7..feb04ea 100644
--- a/base/shared_memory.h
+++ b/base/shared_memory.h
@@ -1,282 +1,7 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
+// Copyright (c) 2013 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 BASE_SHARED_MEMORY_H_
-#define BASE_SHARED_MEMORY_H_
-
-#include "build/build_config.h"
-
-#include <string>
-
-#if defined(OS_POSIX)
-#include <stdio.h>
-#include <sys/types.h>
-#include <semaphore.h>
-#endif
-
-#include "base/base_export.h"
-#include "base/basictypes.h"
-#include "base/process.h"
-
-#if defined(OS_POSIX)
-#include "base/file_descriptor_posix.h"
-#endif
-
-namespace base {
-
-class FilePath;
-
-// SharedMemoryHandle is a platform specific type which represents
-// the underlying OS handle to a shared memory segment.
-#if defined(OS_WIN)
-typedef HANDLE SharedMemoryHandle;
-typedef HANDLE SharedMemoryLock;
-#elif defined(OS_POSIX)
-// A SharedMemoryId is sufficient to identify a given shared memory segment on a
-// system, but insufficient to map it.
-typedef FileDescriptor SharedMemoryHandle;
-typedef ino_t SharedMemoryId;
-// On POSIX, the lock is implemented as a lockf() on the mapped file,
-// so no additional member (or definition of SharedMemoryLock) is
-// needed.
-#endif
-
-// Options for creating a shared memory object.
-struct SharedMemoryCreateOptions {
- SharedMemoryCreateOptions() : name(NULL), size(0), open_existing(false),
- executable(false) {}
-
- // If NULL, the object is anonymous. This pointer is owned by the caller
- // and must live through the call to Create().
- const std::string* name;
-
- // Size of the shared memory object to be created.
- // When opening an existing object, this has no effect.
- size_t size;
-
- // If true, and the shared memory already exists, Create() will open the
- // existing shared memory and ignore the size parameter. If false,
- // shared memory must not exist. This flag is meaningless unless name is
- // non-NULL.
- bool open_existing;
-
- // If true, mappings might need to be made executable later.
- bool executable;
-};
-
-// Platform abstraction for shared memory. Provides a C++ wrapper
-// around the OS primitive for a memory mapped file.
-class BASE_EXPORT SharedMemory {
- public:
- SharedMemory();
-
-#if defined(OS_WIN)
- // Similar to the default constructor, except that this allows for
- // calling Lock() to acquire the named mutex before either Create or Open
- // are called on Windows.
- explicit SharedMemory(const std::wstring& name);
-#endif
-
- // Create a new SharedMemory object from an existing, open
- // shared memory file.
- SharedMemory(SharedMemoryHandle handle, bool read_only);
-
- // Create a new SharedMemory object from an existing, open
- // shared memory file that was created by a remote process and not shared
- // to the current process.
- SharedMemory(SharedMemoryHandle handle, bool read_only,
- ProcessHandle process);
-
- // Closes any open files.
- ~SharedMemory();
-
- // Return true iff the given handle is valid (i.e. not the distingished
- // invalid value; NULL for a HANDLE and -1 for a file descriptor)
- static bool IsHandleValid(const SharedMemoryHandle& handle);
-
- // Returns invalid handle (see comment above for exact definition).
- static SharedMemoryHandle NULLHandle();
-
- // Closes a shared memory handle.
- static void CloseHandle(const SharedMemoryHandle& handle);
-
- // Creates a shared memory object as described by the options struct.
- // Returns true on success and false on failure.
- bool Create(const SharedMemoryCreateOptions& options);
-
- // Creates and maps an anonymous shared memory segment of size size.
- // Returns true on success and false on failure.
- bool CreateAndMapAnonymous(size_t size);
-
- // Creates an anonymous shared memory segment of size size.
- // Returns true on success and false on failure.
- bool CreateAnonymous(size_t size) {
- SharedMemoryCreateOptions options;
- options.size = size;
- return Create(options);
- }
-
- // Creates or opens a shared memory segment based on a name.
- // If open_existing is true, and the shared memory already exists,
- // opens the existing shared memory and ignores the size parameter.
- // If open_existing is false, shared memory must not exist.
- // size is the size of the block to be created.
- // Returns true on success, false on failure.
- bool CreateNamed(const std::string& name, bool open_existing, size_t size) {
- SharedMemoryCreateOptions options;
- options.name = &name;
- options.open_existing = open_existing;
- options.size = size;
- return Create(options);
- }
-
- // Deletes resources associated with a shared memory segment based on name.
- // Not all platforms require this call.
- bool Delete(const std::string& name);
-
- // Opens a shared memory segment based on a name.
- // If read_only is true, opens for read-only access.
- // Returns true on success, false on failure.
- bool Open(const std::string& name, bool read_only);
-
- // Maps the shared memory into the caller's address space.
- // Returns true on success, false otherwise. The memory address
- // is accessed via the memory() accessor. The mapped address is guaranteed to
- // have an alignment of at least MAP_MINIMUM_ALIGNMENT.
- bool Map(size_t bytes) {
- return MapAt(0, bytes);
- }
-
- // Same as above, but with |offset| to specify from begining of the shared
- // memory block to map.
- // |offset| must be alignent to value of |SysInfo::VMAllocationGranularity()|.
- bool MapAt(off_t offset, size_t bytes);
- enum { MAP_MINIMUM_ALIGNMENT = 32 };
-
- // Unmaps the shared memory from the caller's address space.
- // Returns true if successful; returns false on error or if the
- // memory is not mapped.
- bool Unmap();
-
- // Get the size of the shared memory backing file.
- // Note: This size is only available to the creator of the
- // shared memory, and not to those that opened shared memory
- // created externally.
- // Returns 0 if not created or unknown.
- // Deprecated method, please keep track of the size yourself if you created
- // it.
- // http://crbug.com/60821
- size_t created_size() const { return created_size_; }
-
- // Gets a pointer to the opened memory space if it has been
- // Mapped via Map(). Returns NULL if it is not mapped.
- void *memory() const { return memory_; }
-
- // Returns the underlying OS handle for this segment.
- // Use of this handle for anything other than an opaque
- // identifier is not portable.
- SharedMemoryHandle handle() const;
-
-#if defined(OS_POSIX) && !defined(OS_NACL)
- // Returns a unique identifier for this shared memory segment. Inode numbers
- // are technically only unique to a single filesystem. However, we always
- // allocate shared memory backing files from the same directory, so will end
- // up on the same filesystem.
- SharedMemoryId id() const { return inode_; }
-#endif
-
- // Closes the open shared memory segment.
- // It is safe to call Close repeatedly.
- void Close();
-
- // Shares the shared memory to another process. Attempts
- // to create a platform-specific new_handle which can be
- // used in a remote process to access the shared memory
- // file. new_handle is an ouput parameter to receive
- // the handle for use in the remote process.
- // Returns true on success, false otherwise.
- bool ShareToProcess(ProcessHandle process,
- SharedMemoryHandle* new_handle) {
- return ShareToProcessCommon(process, new_handle, false);
- }
-
- // Logically equivalent to:
- // bool ok = ShareToProcess(process, new_handle);
- // Close();
- // return ok;
- // Note that the memory is unmapped by calling this method, regardless of the
- // return value.
- bool GiveToProcess(ProcessHandle process,
- SharedMemoryHandle* new_handle) {
- return ShareToProcessCommon(process, new_handle, true);
- }
-
- // Locks the shared memory.
- //
- // WARNING: on POSIX the memory locking primitive only works across
- // processes, not across threads. The Lock method is not currently
- // used in inner loops, so we protect against multiple threads in a
- // critical section using a class global lock.
- void Lock();
-
-#if defined(OS_WIN)
- // A Lock() implementation with a timeout that also allows setting
- // security attributes on the mutex. sec_attr may be NULL.
- // Returns true if the Lock() has been acquired, false if the timeout was
- // reached.
- bool Lock(uint32 timeout_ms, SECURITY_ATTRIBUTES* sec_attr);
-#endif
-
- // Releases the shared memory lock.
- void Unlock();
-
- private:
-#if defined(OS_POSIX) && !defined(OS_NACL)
- bool PrepareMapFile(FILE *fp);
- bool FilePathForMemoryName(const std::string& mem_name, FilePath* path);
- void LockOrUnlockCommon(int function);
-#endif
- bool ShareToProcessCommon(ProcessHandle process,
- SharedMemoryHandle* new_handle,
- bool close_self);
-
-#if defined(OS_WIN)
- std::wstring name_;
- HANDLE mapped_file_;
-#elif defined(OS_POSIX)
- int mapped_file_;
- size_t mapped_size_;
- ino_t inode_;
-#endif
- void* memory_;
- bool read_only_;
- size_t created_size_;
-#if !defined(OS_POSIX)
- SharedMemoryLock lock_;
-#endif
-
- DISALLOW_COPY_AND_ASSIGN(SharedMemory);
-};
-
-// A helper class that acquires the shared memory lock while
-// the SharedMemoryAutoLock is in scope.
-class SharedMemoryAutoLock {
- public:
- explicit SharedMemoryAutoLock(SharedMemory* shared_memory)
- : shared_memory_(shared_memory) {
- shared_memory_->Lock();
- }
-
- ~SharedMemoryAutoLock() {
- shared_memory_->Unlock();
- }
-
- private:
- SharedMemory* shared_memory_;
- DISALLOW_COPY_AND_ASSIGN(SharedMemoryAutoLock);
-};
-
-} // namespace base
-
-#endif // BASE_SHARED_MEMORY_H_
+// TODO(brettw) remove this forwarding file when all users reference the new
+// location.
+#include "base/memory/shared_memory.h"
diff --git a/base/single_thread_task_runner.h b/base/single_thread_task_runner.h
index a9ba6fd..e82941a 100644
--- a/base/single_thread_task_runner.h
+++ b/base/single_thread_task_runner.h
@@ -13,17 +13,14 @@
// A SingleThreadTaskRunner is a SequencedTaskRunner with one more
// guarantee; namely, that all tasks are run on a single dedicated
// thread. Most use cases require only a SequencedTaskRunner, unless
-// there is a specific need to run tasks on only a single dedicated.
+// there is a specific need to run tasks on only a single thread.
//
-// Some theoretical implementations of SingleThreadTaskRunner:
-//
-// - A SingleThreadTaskRunner that uses a single worker thread to
-// run posted tasks (i.e., a message loop).
-//
-// - A SingleThreadTaskRunner that stores the list of posted tasks
-// and has a method Run() that runs each runnable task in FIFO
-// order that must be run only from the thread the
-// SingleThreadTaskRunner was created on.
+// SingleThreadTaskRunner implementations might:
+// - Post tasks to an existing thread's MessageLoop (see MessageLoopProxy).
+// - Create their own worker thread and MessageLoop to post tasks to.
+// - Add tasks to a FIFO and signal to a non-MessageLoop thread for them to
+// be processed. This allows TaskRunner-oriented code run on threads
+// running other kinds of message loop, e.g. Jingle threads.
class BASE_EXPORT SingleThreadTaskRunner : public SequencedTaskRunner {
public:
// A more explicit alias to RunsTasksOnCurrentThread().
diff --git a/base/string16.cc b/base/string16.cc
index 930e09f..54d00fb 100644
--- a/base/string16.cc
+++ b/base/string16.cc
@@ -67,11 +67,6 @@
return s_orig;
}
-} // namespace base
-
-template class std::basic_string<char16, base::string16_char_traits>;
-
-namespace base {
std::ostream& operator<<(std::ostream& out, const string16& str) {
return out << UTF16ToUTF8(str);
}
@@ -79,6 +74,9 @@
void PrintTo(const string16& str, std::ostream* out) {
*out << str;
}
-}
+
+} // namespace base
+
+template class std::basic_string<char16, base::string16_char_traits>;
#endif // WCHAR_T_IS_UTF32
diff --git a/base/string16.h b/base/string16.h
index e5d8e35..f7a35d0 100644
--- a/base/string16.h
+++ b/base/string16.h
@@ -34,19 +34,20 @@
#if defined(WCHAR_T_IS_UTF16)
+namespace base {
+
typedef wchar_t char16;
typedef std::wstring string16;
-
-namespace base {
typedef std::char_traits<wchar_t> string16_char_traits;
-}
+
+} // namespace base
#elif defined(WCHAR_T_IS_UTF32)
-typedef uint16 char16;
-
namespace base {
+typedef uint16 char16;
+
// char16 versions of the functions required by string16_char_traits; these
// are based on the wide character functions of similar names ("w" or "wcs"
// instead of "c16").
@@ -126,6 +127,14 @@
}
};
+typedef std::basic_string<char16, base::string16_char_traits> string16;
+
+BASE_EXPORT extern std::ostream& operator<<(std::ostream& out,
+ const string16& str);
+
+// This is required by googletest to print a readable output on test failures.
+BASE_EXPORT extern void PrintTo(const string16& str, std::ostream* out);
+
} // namespace base
// The string class will be explicitly instantiated only once, in string16.cc.
@@ -168,18 +177,13 @@
// TODO(mark): File this bug with Apple and update this note with a bug number.
extern template
-class BASE_EXPORT std::basic_string<char16, base::string16_char_traits>;
-
-typedef std::basic_string<char16, base::string16_char_traits> string16;
-
-namespace base {
-BASE_EXPORT extern std::ostream& operator<<(std::ostream& out,
- const string16& str);
-
-// This is required by googletest to print a readable output on test failures.
-BASE_EXPORT extern void PrintTo(const string16& str, std::ostream* out);
-}
+class BASE_EXPORT std::basic_string<base::char16, base::string16_char_traits>;
#endif // WCHAR_T_IS_UTF32
+// TODO(brettw) update users of string16 to use the namespace and remove
+// this "using".
+using base::char16;
+using base::string16;
+
#endif // BASE_STRING16_H_
diff --git a/base/string_piece.h b/base/string_piece.h
index 416fca8..12b9a34 100644
--- a/base/string_piece.h
+++ b/base/string_piece.h
@@ -1,451 +1,6 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
+// Copyright (c) 2013 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.
-// Copied from strings/stringpiece.h with modifications
-//
-// A string-like object that points to a sized piece of memory.
-//
-// Functions or methods may use const StringPiece& parameters to accept either
-// a "const char*" or a "string" value that will be implicitly converted to
-// a StringPiece. The implicit conversion means that it is often appropriate
-// to include this .h file in other files rather than forward-declaring
-// StringPiece as would be appropriate for most other Google classes.
-//
-// Systematic usage of StringPiece is encouraged as it will reduce unnecessary
-// conversions from "const char*" to "string" and back again.
-//
-// StringPiece16 is similar to StringPiece but for base::string16 instead of
-// std::string. We do not define as large of a subset of the STL functions
-// from basic_string as in StringPiece, but this can be changed if these
-// functions (find, find_first_of, etc.) are found to be useful in this context.
-//
-#ifndef BASE_STRING_PIECE_H_
-#define BASE_STRING_PIECE_H_
-
-#include <stddef.h>
-
-#include <iosfwd>
-#include <string>
-
-#include "base/base_export.h"
-#include "base/basictypes.h"
-#include "base/hash_tables.h"
-#include "base/string16.h"
-
-namespace base {
-
-template <typename STRING_TYPE> class BasicStringPiece;
-typedef BasicStringPiece<std::string> StringPiece;
-typedef BasicStringPiece<string16> StringPiece16;
-
-namespace internal {
-
-// Defines the types, methods, operators, and data members common to both
-// StringPiece and StringPiece16. Do not refer to this class directly, but
-// rather to BasicStringPiece, StringPiece, or StringPiece16.
-template <typename STRING_TYPE> class StringPieceDetail {
- public:
- // standard STL container boilerplate
- typedef size_t size_type;
- typedef typename STRING_TYPE::value_type value_type;
- typedef const value_type* pointer;
- typedef const value_type& reference;
- typedef const value_type& const_reference;
- typedef ptrdiff_t difference_type;
- typedef const value_type* const_iterator;
- typedef std::reverse_iterator<const_iterator> const_reverse_iterator;
-
- static const size_type npos;
-
- public:
- // We provide non-explicit singleton constructors so users can pass
- // in a "const char*" or a "string" wherever a "StringPiece" is
- // expected (likewise for char16, string16, StringPiece16).
- StringPieceDetail() : ptr_(NULL), length_(0) {}
- StringPieceDetail(const value_type* str)
- : ptr_(str),
- length_((str == NULL) ? 0 : STRING_TYPE::traits_type::length(str)) {}
- StringPieceDetail(const STRING_TYPE& str)
- : ptr_(str.data()), length_(str.size()) {}
- StringPieceDetail(const value_type* offset, size_type len)
- : ptr_(offset), length_(len) {}
- StringPieceDetail(const typename STRING_TYPE::const_iterator& begin,
- const typename STRING_TYPE::const_iterator& end)
- : ptr_((end > begin) ? &(*begin) : NULL),
- length_((end > begin) ? (size_type)(end - begin) : 0) {}
-
- // data() may return a pointer to a buffer with embedded NULs, and the
- // returned buffer may or may not be null terminated. Therefore it is
- // typically a mistake to pass data() to a routine that expects a NUL
- // terminated string.
- const value_type* data() const { return ptr_; }
- size_type size() const { return length_; }
- size_type length() const { return length_; }
- bool empty() const { return length_ == 0; }
-
- void clear() {
- ptr_ = NULL;
- length_ = 0;
- }
- void set(const value_type* data, size_type len) {
- ptr_ = data;
- length_ = len;
- }
- void set(const value_type* str) {
- ptr_ = str;
- length_ = str ? STRING_TYPE::traits_type::length(str) : 0;
- }
-
- value_type operator[](size_type i) const { return ptr_[i]; }
-
- void remove_prefix(size_type n) {
- ptr_ += n;
- length_ -= n;
- }
-
- void remove_suffix(size_type n) {
- length_ -= n;
- }
-
- int compare(const BasicStringPiece<STRING_TYPE>& x) const {
- int r = wordmemcmp(
- ptr_, x.ptr_, (length_ < x.length_ ? length_ : x.length_));
- if (r == 0) {
- if (length_ < x.length_) r = -1;
- else if (length_ > x.length_) r = +1;
- }
- return r;
- }
-
- STRING_TYPE as_string() const {
- // std::string doesn't like to take a NULL pointer even with a 0 size.
- return empty() ? STRING_TYPE() : STRING_TYPE(data(), size());
- }
-
- const_iterator begin() const { return ptr_; }
- const_iterator end() const { return ptr_ + length_; }
- const_reverse_iterator rbegin() const {
- return const_reverse_iterator(ptr_ + length_);
- }
- const_reverse_iterator rend() const {
- return const_reverse_iterator(ptr_);
- }
-
- size_type max_size() const { return length_; }
- size_type capacity() const { return length_; }
-
- static int wordmemcmp(const value_type* p,
- const value_type* p2,
- size_type N) {
- return STRING_TYPE::traits_type::compare(p, p2, N);
- }
-
- protected:
- const value_type* ptr_;
- size_type length_;
-};
-
-template <typename STRING_TYPE>
-const typename StringPieceDetail<STRING_TYPE>::size_type
-StringPieceDetail<STRING_TYPE>::npos =
- typename StringPieceDetail<STRING_TYPE>::size_type(-1);
-
-// MSVC doesn't like complex extern templates and DLLs.
-#if !defined(COMPILER_MSVC)
-extern template class BASE_EXPORT StringPieceDetail<std::string>;
-extern template class BASE_EXPORT StringPieceDetail<string16>;
-#endif
-
-BASE_EXPORT void CopyToString(const StringPiece& self, std::string* target);
-BASE_EXPORT void AppendToString(const StringPiece& self, std::string* target);
-BASE_EXPORT StringPieceDetail<std::string>::size_type copy(
- const StringPiece& self,
- char* buf,
- StringPieceDetail<std::string>::size_type n,
- StringPieceDetail<std::string>::size_type pos);
-BASE_EXPORT StringPieceDetail<std::string>::size_type find(
- const StringPiece& self,
- const StringPiece& s,
- StringPieceDetail<std::string>::size_type pos);
-BASE_EXPORT StringPieceDetail<std::string>::size_type find(
- const StringPiece& self,
- char c,
- StringPieceDetail<std::string>::size_type pos);
-BASE_EXPORT StringPieceDetail<std::string>::size_type rfind(
- const StringPiece& self,
- const StringPiece& s,
- StringPieceDetail<std::string>::size_type pos);
-BASE_EXPORT StringPieceDetail<std::string>::size_type rfind(
- const StringPiece& self,
- char c,
- StringPieceDetail<std::string>::size_type pos);
-BASE_EXPORT StringPieceDetail<std::string>::size_type find_first_of(
- const StringPiece& self,
- const StringPiece& s,
- StringPieceDetail<std::string>::size_type pos);
-BASE_EXPORT StringPieceDetail<std::string>::size_type find_first_not_of(
- const StringPiece& self,
- const StringPiece& s,
- StringPieceDetail<std::string>::size_type pos);
-BASE_EXPORT StringPieceDetail<std::string>::size_type find_first_not_of(
- const StringPiece& self,
- char c,
- StringPieceDetail<std::string>::size_type pos);
-BASE_EXPORT StringPieceDetail<std::string>::size_type find_last_of(
- const StringPiece& self,
- const StringPiece& s,
- StringPieceDetail<std::string>::size_type pos);
-BASE_EXPORT StringPieceDetail<std::string>::size_type find_last_of(
- const StringPiece& self,
- char c,
- StringPieceDetail<std::string>::size_type pos);
-BASE_EXPORT StringPieceDetail<std::string>::size_type find_last_not_of(
- const StringPiece& self,
- const StringPiece& s,
- StringPieceDetail<std::string>::size_type pos);
-BASE_EXPORT StringPieceDetail<std::string>::size_type find_last_not_of(
- const StringPiece& self,
- char c,
- StringPieceDetail<std::string>::size_type pos);
-BASE_EXPORT StringPiece substr(const StringPiece& self,
- StringPieceDetail<std::string>::size_type pos,
- StringPieceDetail<std::string>::size_type n);
-} // namespace internal
-
-// Defines the template type that is instantiated as either StringPiece or
-// StringPiece16.
-template <typename STRING_TYPE> class BasicStringPiece :
- public internal::StringPieceDetail<STRING_TYPE> {
- public:
- typedef typename internal::StringPieceDetail<STRING_TYPE>::value_type
- value_type;
- typedef typename internal::StringPieceDetail<STRING_TYPE>::size_type
- size_type;
-
- BasicStringPiece() {}
- BasicStringPiece(const value_type*str)
- : internal::StringPieceDetail<STRING_TYPE>(str) {}
- BasicStringPiece(const STRING_TYPE& str)
- : internal::StringPieceDetail<STRING_TYPE>(str) {}
- BasicStringPiece(const value_type* offset, size_type len)
- : internal::StringPieceDetail<STRING_TYPE>(offset, len) {}
- BasicStringPiece(const typename STRING_TYPE::const_iterator& begin,
- const typename STRING_TYPE::const_iterator& end)
- : internal::StringPieceDetail<STRING_TYPE>(begin, end) {}
-};
-
-// Specializes BasicStringPiece for std::string to add a few operations that
-// are not needed for string16.
-template <> class BasicStringPiece<std::string> :
- public internal::StringPieceDetail<std::string> {
- public:
- BasicStringPiece() {}
- BasicStringPiece(const char* str)
- : internal::StringPieceDetail<std::string>(str) {}
- BasicStringPiece(const std::string& str)
- : internal::StringPieceDetail<std::string>(str) {}
- BasicStringPiece(const char* offset, size_type len)
- : internal::StringPieceDetail<std::string>(offset, len) {}
- BasicStringPiece(const std::string::const_iterator& begin,
- const std::string::const_iterator& end)
- : internal::StringPieceDetail<std::string>(begin, end) {}
-
- // Prevent the following overload of set() from hiding the definitions in the
- // base class.
- using internal::StringPieceDetail<std::string>::set;
-
- void set(const void* data, size_type len) {
- ptr_ = reinterpret_cast<const value_type*>(data);
- length_ = len;
- }
-
- void CopyToString(std::string* target) const {
- internal::CopyToString(*this, target);
- }
-
- void AppendToString(std::string* target) const {
- internal::AppendToString(*this, target);
- }
-
- // Does "this" start with "x"
- bool starts_with(const BasicStringPiece& x) const {
- return ((length_ >= x.length_) &&
- (wordmemcmp(ptr_, x.ptr_, x.length_) == 0));
- }
-
- // Does "this" end with "x"
- bool ends_with(const BasicStringPiece& x) const {
- return ((length_ >= x.length_) &&
- (wordmemcmp(ptr_ + (length_-x.length_), x.ptr_, x.length_) == 0));
- }
-
- size_type copy(char* buf, size_type n, size_type pos = 0) const {
- return internal::copy(*this, buf, n, pos);
- }
-
- size_type find(const BasicStringPiece& s, size_type pos = 0) const {
- return internal::find(*this, s, pos);
- }
-
- size_type find(char c, size_type pos = 0) const {
- return internal::find(*this, c, pos);
- }
-
- size_type rfind(const BasicStringPiece& s, size_type pos = npos) const {
- return internal::rfind(*this, s, pos);
- }
-
- size_type rfind(char c, size_type pos = npos) const {
- return internal::rfind(*this, c, pos);
- }
-
- size_type find_first_of(const BasicStringPiece& s, size_type pos = 0) const {
- return internal::find_first_of(*this, s, pos);
- }
-
- size_type find_first_of(char c, size_type pos = 0) const {
- return find(c, pos);
- }
-
- size_type find_first_not_of(const BasicStringPiece& s,
- size_type pos = 0) const {
- return internal::find_first_not_of(*this, s, pos);
- }
-
- size_type find_first_not_of(char c, size_type pos = 0) const {
- return internal::find_first_not_of(*this, c, pos);
- }
-
- size_type find_last_of(const BasicStringPiece& s,
- size_type pos = npos) const {
- return internal::find_last_of(*this, s, pos);
- }
-
- size_type find_last_of(char c, size_type pos = npos) const {
- return rfind(c, pos);
- }
-
- size_type find_last_not_of(const BasicStringPiece& s,
- size_type pos = npos) const {
- return internal::find_last_not_of(*this, s, pos);
- }
-
- size_type find_last_not_of(char c, size_type pos = npos) const {
- return internal::find_last_not_of(*this, c, pos);
- }
-
- BasicStringPiece substr(size_type pos, size_type n = npos) const {
- return internal::substr(*this, pos, n);
- }
-};
-
-// MSVC doesn't like complex extern templates and DLLs.
-#if !defined(COMPILER_MSVC)
-// We can't explicitly declare the std::string instantiation here because it was
-// already instantiated when specialized, above. Not only is it a no-op, but
-// currently it also crashes Clang (see http://crbug.com/107412).
-extern template class BASE_EXPORT BasicStringPiece<string16>;
-#endif
-
-BASE_EXPORT bool operator==(const StringPiece& x, const StringPiece& y);
-
-inline bool operator!=(const StringPiece& x, const StringPiece& y) {
- return !(x == y);
-}
-
-inline bool operator<(const StringPiece& x, const StringPiece& y) {
- const int r = StringPiece::wordmemcmp(
- x.data(), y.data(), (x.size() < y.size() ? x.size() : y.size()));
- return ((r < 0) || ((r == 0) && (x.size() < y.size())));
-}
-
-inline bool operator>(const StringPiece& x, const StringPiece& y) {
- return y < x;
-}
-
-inline bool operator<=(const StringPiece& x, const StringPiece& y) {
- return !(x > y);
-}
-
-inline bool operator>=(const StringPiece& x, const StringPiece& y) {
- return !(x < y);
-}
-
-inline bool operator==(const StringPiece16& x, const StringPiece16& y) {
- if (x.size() != y.size())
- return false;
-
- return StringPiece16::wordmemcmp(x.data(), y.data(), x.size()) == 0;
-}
-
-inline bool operator!=(const StringPiece16& x, const StringPiece16& y) {
- return !(x == y);
-}
-
-inline bool operator<(const StringPiece16& x, const StringPiece16& y) {
- const int r = StringPiece16::wordmemcmp(
- x.data(), y.data(), (x.size() < y.size() ? x.size() : y.size()));
- return ((r < 0) || ((r == 0) && (x.size() < y.size())));
-}
-
-inline bool operator>(const StringPiece16& x, const StringPiece16& y) {
- return y < x;
-}
-
-inline bool operator<=(const StringPiece16& x, const StringPiece16& y) {
- return !(x > y);
-}
-
-inline bool operator>=(const StringPiece16& x, const StringPiece16& y) {
- return !(x < y);
-}
-
-BASE_EXPORT std::ostream& operator<<(std::ostream& o,
- const StringPiece& piece);
-
-} // namespace base
-
-// We provide appropriate hash functions so StringPiece and StringPiece16 can
-// be used as keys in hash sets and maps.
-
-// This hash function is copied from base/hash_tables.h. We don't use the
-// ones already defined for string and string16 directly because it would
-// require the string constructors to be called, which we don't want.
-#define HASH_STRING_PIECE(StringPieceType, string_piece) \
- std::size_t result = 0; \
- for (StringPieceType::const_iterator i = string_piece.begin(); \
- i != string_piece.end(); ++i) \
- result = (result * 131) + *i; \
- return result; \
-
-namespace BASE_HASH_NAMESPACE {
-#if defined(COMPILER_GCC)
-
-template<>
-struct hash<base::StringPiece> {
- std::size_t operator()(const base::StringPiece& sp) const {
- HASH_STRING_PIECE(base::StringPiece, sp);
- }
-};
-template<>
-struct hash<base::StringPiece16> {
- std::size_t operator()(const base::StringPiece16& sp16) const {
- HASH_STRING_PIECE(base::StringPiece16, sp16);
- }
-};
-
-#elif defined(COMPILER_MSVC)
-
-inline size_t hash_value(const base::StringPiece& sp) {
- HASH_STRING_PIECE(base::StringPiece, sp);
-}
-inline size_t hash_value(const base::StringPiece16& sp16) {
- HASH_STRING_PIECE(base::StringPiece16, sp16);
-}
-
-#endif // COMPILER
-
-} // namespace BASE_HASH_NAMESPACE
-
-#endif // BASE_STRING_PIECE_H_
+// TODO(brettw) move callers to using the new location
+#include "base/strings/string_piece.h"
diff --git a/base/string_util.h b/base/string_util.h
index 367eaa8..99ba091 100644
--- a/base/string_util.h
+++ b/base/string_util.h
@@ -17,7 +17,7 @@
#include "base/basictypes.h"
#include "base/compiler_specific.h"
#include "base/string16.h"
-#include "base/string_piece.h" // For implicit conversions.
+#include "base/strings/string_piece.h" // For implicit conversions.
// Safe standard library wrappers for all platforms.
diff --git a/base/string_util_unittest.cc b/base/string_util_unittest.cc
index d36b955..d580fba 100644
--- a/base/string_util_unittest.cc
+++ b/base/string_util_unittest.cc
@@ -70,7 +70,7 @@
std::string output;
// Empty strings and invalid byte_size arguments
- EXPECT_FALSE(Truncated("", 0, &output));
+ EXPECT_FALSE(Truncated(std::string(), 0, &output));
EXPECT_EQ(output, "");
EXPECT_TRUE(Truncated("\xe1\x80\xbf", 0, &output));
EXPECT_EQ(output, "");
@@ -319,7 +319,7 @@
}
TEST(StringUtilTest, ContainsOnlyWhitespaceASCII) {
- EXPECT_TRUE(ContainsOnlyWhitespaceASCII(""));
+ EXPECT_TRUE(ContainsOnlyWhitespaceASCII(std::string()));
EXPECT_TRUE(ContainsOnlyWhitespaceASCII(" "));
EXPECT_TRUE(ContainsOnlyWhitespaceASCII("\t"));
EXPECT_TRUE(ContainsOnlyWhitespaceASCII("\t \r \n "));
@@ -712,7 +712,7 @@
EXPECT_EQ(r[2], STR(" three"));
r.clear();
- size = Tokenize(STR(""), STR(","), &r);
+ size = Tokenize(STR(), STR(","), &r);
EXPECT_EQ(0U, size);
ASSERT_EQ(0U, r.size());
r.clear();
@@ -761,7 +761,7 @@
in.push_back("c");
EXPECT_EQ("a,b,c", JoinString(in, ','));
- in.push_back("");
+ in.push_back(std::string());
EXPECT_EQ("a,b,c,", JoinString(in, ','));
in.push_back(" ");
EXPECT_EQ("a|b|c|| ", JoinString(in, '|'));
@@ -780,7 +780,7 @@
parts.push_back("c");
EXPECT_EQ("a, b, c", JoinString(parts, separator));
- parts.push_back("");
+ parts.push_back(std::string());
EXPECT_EQ("a, b, c, ", JoinString(parts, separator));
parts.push_back(" ");
EXPECT_EQ("a|b|c|| ", JoinString(parts, "|"));
@@ -812,10 +812,10 @@
EXPECT_TRUE(StartsWithASCII("JavaScript:url", "javascript", false));
EXPECT_FALSE(StartsWithASCII("java", "javascript", true));
EXPECT_FALSE(StartsWithASCII("java", "javascript", false));
- EXPECT_FALSE(StartsWithASCII("", "javascript", false));
- EXPECT_FALSE(StartsWithASCII("", "javascript", true));
- EXPECT_TRUE(StartsWithASCII("java", "", false));
- EXPECT_TRUE(StartsWithASCII("java", "", true));
+ EXPECT_FALSE(StartsWithASCII(std::string(), "javascript", false));
+ EXPECT_FALSE(StartsWithASCII(std::string(), "javascript", true));
+ EXPECT_TRUE(StartsWithASCII("java", std::string(), false));
+ EXPECT_TRUE(StartsWithASCII("java", std::string(), true));
EXPECT_TRUE(StartsWith(L"javascript:url", L"javascript", true));
EXPECT_FALSE(StartsWith(L"JavaScript:url", L"javascript", true));
@@ -823,10 +823,10 @@
EXPECT_TRUE(StartsWith(L"JavaScript:url", L"javascript", false));
EXPECT_FALSE(StartsWith(L"java", L"javascript", true));
EXPECT_FALSE(StartsWith(L"java", L"javascript", false));
- EXPECT_FALSE(StartsWith(L"", L"javascript", false));
- EXPECT_FALSE(StartsWith(L"", L"javascript", true));
- EXPECT_TRUE(StartsWith(L"java", L"", false));
- EXPECT_TRUE(StartsWith(L"java", L"", true));
+ EXPECT_FALSE(StartsWith(std::wstring(), L"javascript", false));
+ EXPECT_FALSE(StartsWith(std::wstring(), L"javascript", true));
+ EXPECT_TRUE(StartsWith(L"java", std::wstring(), false));
+ EXPECT_TRUE(StartsWith(L"java", std::wstring(), true));
}
TEST(StringUtilTest, EndsWith) {
@@ -838,14 +838,14 @@
EXPECT_FALSE(EndsWith(L".plug", L".plugin", false));
EXPECT_FALSE(EndsWith(L"Foo.plugin Bar", L".plugin", true));
EXPECT_FALSE(EndsWith(L"Foo.plugin Bar", L".plugin", false));
- EXPECT_FALSE(EndsWith(L"", L".plugin", false));
- EXPECT_FALSE(EndsWith(L"", L".plugin", true));
- EXPECT_TRUE(EndsWith(L"Foo.plugin", L"", false));
- EXPECT_TRUE(EndsWith(L"Foo.plugin", L"", true));
+ EXPECT_FALSE(EndsWith(std::wstring(), L".plugin", false));
+ EXPECT_FALSE(EndsWith(std::wstring(), L".plugin", true));
+ EXPECT_TRUE(EndsWith(L"Foo.plugin", std::wstring(), false));
+ EXPECT_TRUE(EndsWith(L"Foo.plugin", std::wstring(), true));
EXPECT_TRUE(EndsWith(L".plugin", L".plugin", false));
EXPECT_TRUE(EndsWith(L".plugin", L".plugin", true));
- EXPECT_TRUE(EndsWith(L"", L"", false));
- EXPECT_TRUE(EndsWith(L"", L"", true));
+ EXPECT_TRUE(EndsWith(std::wstring(), std::wstring(), false));
+ EXPECT_TRUE(EndsWith(std::wstring(), std::wstring(), true));
}
TEST(StringUtilTest, GetStringFWithOffsets) {
@@ -1142,10 +1142,10 @@
TEST(StringUtilTest, ContainsOnlyChars) {
// Providing an empty list of characters should return false but for the empty
// string.
- EXPECT_TRUE(ContainsOnlyChars("", ""));
- EXPECT_FALSE(ContainsOnlyChars("Hello", ""));
+ EXPECT_TRUE(ContainsOnlyChars(std::string(), std::string()));
+ EXPECT_FALSE(ContainsOnlyChars("Hello", std::string()));
- EXPECT_TRUE(ContainsOnlyChars("", "1234"));
+ EXPECT_TRUE(ContainsOnlyChars(std::string(), "1234"));
EXPECT_TRUE(ContainsOnlyChars("1", "1234"));
EXPECT_TRUE(ContainsOnlyChars("1", "4321"));
EXPECT_TRUE(ContainsOnlyChars("123", "4321"));
diff --git a/base/stringprintf.cc b/base/stringprintf.cc
index 79c6562..814fe99 100644
--- a/base/stringprintf.cc
+++ b/base/stringprintf.cc
@@ -6,6 +6,7 @@
#include <errno.h>
+#include "base/scoped_clear_errno.h"
#include "base/string_util.h"
#include "base/utf_string_conversions.h"
@@ -50,7 +51,7 @@
GG_VA_COPY(ap_copy, ap);
#if !defined(OS_WIN)
- errno = 0;
+ ScopedClearErrno clear_errno;
#endif
int result = vsnprintfT(stack_buf, arraysize(stack_buf), format, ap_copy);
va_end(ap_copy);
diff --git a/base/stringprintf_unittest.cc b/base/stringprintf_unittest.cc
index 305d24a..c04b17e 100644
--- a/base/stringprintf_unittest.cc
+++ b/base/stringprintf_unittest.cc
@@ -2,6 +2,8 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
+#include <errno.h>
+
#include "base/basictypes.h"
#include "base/stringprintf.h"
#include "testing/gtest/include/gtest/gtest.h"
@@ -172,4 +174,14 @@
#endif
}
+// Test that StringPrintf and StringAppendV do not change errno.
+TEST(StringPrintfTest, StringPrintfErrno) {
+ errno = 1;
+ EXPECT_EQ("", StringPrintf("%s", ""));
+ EXPECT_EQ(1, errno);
+ std::string out;
+ StringAppendVTestHelper(&out, "%d foo %s", 1, "bar");
+ EXPECT_EQ(1, errno);
+}
+
} // namespace base
diff --git a/base/strings/string_number_conversions.cc b/base/strings/string_number_conversions.cc
index bad7c2b..39daece 100644
--- a/base/strings/string_number_conversions.cc
+++ b/base/strings/string_number_conversions.cc
@@ -12,6 +12,7 @@
#include <limits>
#include "base/logging.h"
+#include "base/scoped_clear_errno.h"
#include "base/third_party/dmg_fp/dmg_fp.h"
#include "base/utf_string_conversions.h"
@@ -186,7 +187,9 @@
}
if (begin != end && *begin == '-') {
- if (!Negative::Invoke(begin + 1, end, output)) {
+ if (!std::numeric_limits<value_type>::is_signed) {
+ valid = false;
+ } else if (!Negative::Invoke(begin + 1, end, output)) {
valid = false;
}
} else {
@@ -302,12 +305,20 @@
: public BaseIteratorRangeToNumberTraits<ITERATOR, int64, 16> {
};
+template<typename ITERATOR>
+class BaseHexIteratorRangeToUInt64Traits
+ : public BaseIteratorRangeToNumberTraits<ITERATOR, uint64, 16> {
+};
+
typedef BaseHexIteratorRangeToIntTraits<StringPiece::const_iterator>
HexIteratorRangeToIntTraits;
typedef BaseHexIteratorRangeToInt64Traits<StringPiece::const_iterator>
HexIteratorRangeToInt64Traits;
+typedef BaseHexIteratorRangeToUInt64Traits<StringPiece::const_iterator>
+ HexIteratorRangeToUInt64Traits;
+
template<typename STR>
bool HexStringToBytesT(const STR& input, std::vector<uint8>* output) {
DCHECK_EQ(output->size(), 0u);
@@ -440,7 +451,9 @@
}
bool StringToDouble(const std::string& input, double* output) {
- errno = 0; // Thread-safe? It is on at least Mac, Linux, and Windows.
+ // Thread-safe? It is on at least Mac, Linux, and Windows.
+ ScopedClearErrno clear_errno;
+
char* endptr = NULL;
*output = dmg_fp::strtod(input.c_str(), &endptr);
@@ -491,6 +504,11 @@
input.begin(), input.end(), output);
}
+bool HexStringToUInt64(const StringPiece& input, uint64* output) {
+ return IteratorRangeToNumber<HexIteratorRangeToUInt64Traits>::Invoke(
+ input.begin(), input.end(), output);
+}
+
bool HexStringToBytes(const std::string& input, std::vector<uint8>* output) {
return HexStringToBytesT(input, output);
}
diff --git a/base/strings/string_number_conversions.h b/base/strings/string_number_conversions.h
index 97a33c8..2a75741 100644
--- a/base/strings/string_number_conversions.h
+++ b/base/strings/string_number_conversions.h
@@ -11,7 +11,7 @@
#include "base/base_export.h"
#include "base/basictypes.h"
#include "base/string16.h"
-#include "base/string_piece.h"
+#include "base/strings/string_piece.h"
// ----------------------------------------------------------------------------
// IMPORTANT MESSAGE FROM YOUR SPONSOR
@@ -50,7 +50,9 @@
// Perform a best-effort conversion of the input string to a numeric type,
// setting |*output| to the result of the conversion. Returns true for
// "perfect" conversions; returns false in the following cases:
-// - Overflow/underflow. |*output| will be set to the maximum value supported
+// - Overflow. |*output| will be set to the maximum value supported
+// by the data type.
+// - Underflow. |*output| will be set to the minimum value supported
// by the data type.
// - Trailing characters in the string after parsing the number. |*output|
// will be set to the value of the number that was parsed.
@@ -102,6 +104,12 @@
// -0x8000000000000000 < |input| < 0x7FFFFFFFFFFFFFFF.
BASE_EXPORT bool HexStringToInt64(const StringPiece& input, int64* output);
+// Best effort conversion, see StringToInt above for restrictions.
+// Will only successful parse hex values that will fit into |output|, i.e.
+// 0x0000000000000000 < |input| < 0xFFFFFFFFFFFFFFFF.
+// The string is not required to start with 0x.
+BASE_EXPORT bool HexStringToUInt64(const StringPiece& input, uint64* output);
+
// Similar to the previous functions, except that output is a vector of bytes.
// |*output| will contain as many bytes as were successfully parsed prior to the
// error. There is no overflow, but input.size() must be evenly divisible by 2.
@@ -112,4 +120,3 @@
} // namespace base
#endif // BASE_STRINGS_STRING_NUMBER_CONVERSIONS_H_
-
diff --git a/base/strings/string_number_conversions_unittest.cc b/base/strings/string_number_conversions_unittest.cc
index ac74e9f..5ae59d3 100644
--- a/base/strings/string_number_conversions_unittest.cc
+++ b/base/strings/string_number_conversions_unittest.cc
@@ -2,6 +2,7 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
+#include <errno.h>
#include <math.h>
#include <limits>
@@ -309,6 +310,68 @@
EXPECT_EQ(0xc0ffee, output);
}
+TEST(StringNumberConversionsTest, HexStringToUInt64) {
+ static const struct {
+ std::string input;
+ uint64 output;
+ bool success;
+ } cases[] = {
+ {"0", 0, true},
+ {"42", 66, true},
+ {"-42", 0, false},
+ {"+42", 66, true},
+ {"40acd88557b", GG_INT64_C(4444444448123), true},
+ {"7fffffff", INT_MAX, true},
+ {"-80000000", 0, false},
+ {"ffffffff", 0xffffffff, true},
+ {"DeadBeef", 0xdeadbeef, true},
+ {"0x42", 66, true},
+ {"-0x42", 0, false},
+ {"+0x42", 66, true},
+ {"0x40acd88557b", GG_INT64_C(4444444448123), true},
+ {"0x7fffffff", INT_MAX, true},
+ {"-0x80000000", 0, false},
+ {"0xffffffff", 0xffffffff, true},
+ {"0XDeadBeef", 0xdeadbeef, true},
+ {"0x7fffffffffffffff", kint64max, true},
+ {"-0x8000000000000000", 0, false},
+ {"0x8000000000000000", GG_UINT64_C(0x8000000000000000), true},
+ {"-0x8000000000000001", 0, false},
+ {"0xFFFFFFFFFFFFFFFF", kuint64max, true},
+ {"FFFFFFFFFFFFFFFF", kuint64max, true},
+ {"0x0000000000000000", 0, true},
+ {"0000000000000000", 0, true},
+ {"1FFFFFFFFFFFFFFFF", kuint64max, false}, // Overflow test.
+ {"0x0f", 15, true},
+ {"0f", 15, true},
+ {" 45", 0x45, false},
+ {"\t\n\v\f\r 0x45", 0x45, false},
+ {" 45", 0x45, false},
+ {"45 ", 0x45, false},
+ {"45:", 0x45, false},
+ {"efgh", 0xef, false},
+ {"0xefgh", 0xef, false},
+ {"hgfe", 0, false},
+ {"-", 0, false},
+ {"", 0, false},
+ {"0x", 0, false},
+ };
+
+ for (size_t i = 0; i < ARRAYSIZE_UNSAFE(cases); ++i) {
+ uint64 output = 0;
+ EXPECT_EQ(cases[i].success, HexStringToUInt64(cases[i].input, &output));
+ EXPECT_EQ(cases[i].output, output);
+ }
+ // One additional test to verify that conversion of numbers in strings with
+ // embedded NUL characters. The NUL and extra data after it should be
+ // interpreted as junk after the number.
+ const char input[] = "0xc0ffee\09";
+ std::string input_string(input, arraysize(input) - 1);
+ uint64 output;
+ EXPECT_FALSE(HexStringToUInt64(input_string, &output));
+ EXPECT_EQ(0xc0ffeeU, output);
+}
+
TEST(StringNumberConversionsTest, HexStringToBytes) {
static const struct {
const std::string input;
@@ -387,7 +450,10 @@
for (size_t i = 0; i < ARRAYSIZE_UNSAFE(cases); ++i) {
double output;
+ errno = 1;
EXPECT_EQ(cases[i].success, StringToDouble(cases[i].input, &output));
+ if (cases[i].success)
+ EXPECT_EQ(1, errno) << i; // confirm that errno is unchanged.
EXPECT_DOUBLE_EQ(cases[i].output, output);
}
diff --git a/base/string_piece.cc b/base/strings/string_piece.cc
similarity index 99%
rename from base/string_piece.cc
rename to base/strings/string_piece.cc
index 7a41361..79a42d7 100644
--- a/base/string_piece.cc
+++ b/base/strings/string_piece.cc
@@ -3,11 +3,11 @@
// found in the LICENSE file.
// Copied from strings/stringpiece.cc with modifications
+#include "base/strings/string_piece.h"
+
#include <algorithm>
#include <ostream>
-#include "base/string_piece.h"
-
namespace base {
// MSVC doesn't like complex extern templates and DLLs.
diff --git a/base/strings/string_piece.h b/base/strings/string_piece.h
new file mode 100644
index 0000000..13ca009
--- /dev/null
+++ b/base/strings/string_piece.h
@@ -0,0 +1,451 @@
+// Copyright (c) 2012 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.
+// Copied from strings/stringpiece.h with modifications
+//
+// A string-like object that points to a sized piece of memory.
+//
+// Functions or methods may use const StringPiece& parameters to accept either
+// a "const char*" or a "string" value that will be implicitly converted to
+// a StringPiece. The implicit conversion means that it is often appropriate
+// to include this .h file in other files rather than forward-declaring
+// StringPiece as would be appropriate for most other Google classes.
+//
+// Systematic usage of StringPiece is encouraged as it will reduce unnecessary
+// conversions from "const char*" to "string" and back again.
+//
+// StringPiece16 is similar to StringPiece but for base::string16 instead of
+// std::string. We do not define as large of a subset of the STL functions
+// from basic_string as in StringPiece, but this can be changed if these
+// functions (find, find_first_of, etc.) are found to be useful in this context.
+//
+
+#ifndef BASE_STRINGS_STRING_PIECE_H_
+#define BASE_STRINGS_STRING_PIECE_H_
+
+#include <stddef.h>
+
+#include <iosfwd>
+#include <string>
+
+#include "base/base_export.h"
+#include "base/basictypes.h"
+#include "base/hash_tables.h"
+#include "base/string16.h"
+
+namespace base {
+
+template <typename STRING_TYPE> class BasicStringPiece;
+typedef BasicStringPiece<std::string> StringPiece;
+typedef BasicStringPiece<string16> StringPiece16;
+
+namespace internal {
+
+// Defines the types, methods, operators, and data members common to both
+// StringPiece and StringPiece16. Do not refer to this class directly, but
+// rather to BasicStringPiece, StringPiece, or StringPiece16.
+template <typename STRING_TYPE> class StringPieceDetail {
+ public:
+ // standard STL container boilerplate
+ typedef size_t size_type;
+ typedef typename STRING_TYPE::value_type value_type;
+ typedef const value_type* pointer;
+ typedef const value_type& reference;
+ typedef const value_type& const_reference;
+ typedef ptrdiff_t difference_type;
+ typedef const value_type* const_iterator;
+ typedef std::reverse_iterator<const_iterator> const_reverse_iterator;
+
+ static const size_type npos;
+
+ public:
+ // We provide non-explicit singleton constructors so users can pass
+ // in a "const char*" or a "string" wherever a "StringPiece" is
+ // expected (likewise for char16, string16, StringPiece16).
+ StringPieceDetail() : ptr_(NULL), length_(0) {}
+ StringPieceDetail(const value_type* str)
+ : ptr_(str),
+ length_((str == NULL) ? 0 : STRING_TYPE::traits_type::length(str)) {}
+ StringPieceDetail(const STRING_TYPE& str)
+ : ptr_(str.data()), length_(str.size()) {}
+ StringPieceDetail(const value_type* offset, size_type len)
+ : ptr_(offset), length_(len) {}
+ StringPieceDetail(const typename STRING_TYPE::const_iterator& begin,
+ const typename STRING_TYPE::const_iterator& end)
+ : ptr_((end > begin) ? &(*begin) : NULL),
+ length_((end > begin) ? (size_type)(end - begin) : 0) {}
+
+ // data() may return a pointer to a buffer with embedded NULs, and the
+ // returned buffer may or may not be null terminated. Therefore it is
+ // typically a mistake to pass data() to a routine that expects a NUL
+ // terminated string.
+ const value_type* data() const { return ptr_; }
+ size_type size() const { return length_; }
+ size_type length() const { return length_; }
+ bool empty() const { return length_ == 0; }
+
+ void clear() {
+ ptr_ = NULL;
+ length_ = 0;
+ }
+ void set(const value_type* data, size_type len) {
+ ptr_ = data;
+ length_ = len;
+ }
+ void set(const value_type* str) {
+ ptr_ = str;
+ length_ = str ? STRING_TYPE::traits_type::length(str) : 0;
+ }
+
+ value_type operator[](size_type i) const { return ptr_[i]; }
+
+ void remove_prefix(size_type n) {
+ ptr_ += n;
+ length_ -= n;
+ }
+
+ void remove_suffix(size_type n) {
+ length_ -= n;
+ }
+
+ int compare(const BasicStringPiece<STRING_TYPE>& x) const {
+ int r = wordmemcmp(
+ ptr_, x.ptr_, (length_ < x.length_ ? length_ : x.length_));
+ if (r == 0) {
+ if (length_ < x.length_) r = -1;
+ else if (length_ > x.length_) r = +1;
+ }
+ return r;
+ }
+
+ STRING_TYPE as_string() const {
+ // std::string doesn't like to take a NULL pointer even with a 0 size.
+ return empty() ? STRING_TYPE() : STRING_TYPE(data(), size());
+ }
+
+ const_iterator begin() const { return ptr_; }
+ const_iterator end() const { return ptr_ + length_; }
+ const_reverse_iterator rbegin() const {
+ return const_reverse_iterator(ptr_ + length_);
+ }
+ const_reverse_iterator rend() const {
+ return const_reverse_iterator(ptr_);
+ }
+
+ size_type max_size() const { return length_; }
+ size_type capacity() const { return length_; }
+
+ static int wordmemcmp(const value_type* p,
+ const value_type* p2,
+ size_type N) {
+ return STRING_TYPE::traits_type::compare(p, p2, N);
+ }
+
+ protected:
+ const value_type* ptr_;
+ size_type length_;
+};
+
+template <typename STRING_TYPE>
+const typename StringPieceDetail<STRING_TYPE>::size_type
+StringPieceDetail<STRING_TYPE>::npos =
+ typename StringPieceDetail<STRING_TYPE>::size_type(-1);
+
+// MSVC doesn't like complex extern templates and DLLs.
+#if !defined(COMPILER_MSVC)
+extern template class BASE_EXPORT StringPieceDetail<std::string>;
+extern template class BASE_EXPORT StringPieceDetail<string16>;
+#endif
+
+BASE_EXPORT void CopyToString(const StringPiece& self, std::string* target);
+BASE_EXPORT void AppendToString(const StringPiece& self, std::string* target);
+BASE_EXPORT StringPieceDetail<std::string>::size_type copy(
+ const StringPiece& self,
+ char* buf,
+ StringPieceDetail<std::string>::size_type n,
+ StringPieceDetail<std::string>::size_type pos);
+BASE_EXPORT StringPieceDetail<std::string>::size_type find(
+ const StringPiece& self,
+ const StringPiece& s,
+ StringPieceDetail<std::string>::size_type pos);
+BASE_EXPORT StringPieceDetail<std::string>::size_type find(
+ const StringPiece& self,
+ char c,
+ StringPieceDetail<std::string>::size_type pos);
+BASE_EXPORT StringPieceDetail<std::string>::size_type rfind(
+ const StringPiece& self,
+ const StringPiece& s,
+ StringPieceDetail<std::string>::size_type pos);
+BASE_EXPORT StringPieceDetail<std::string>::size_type rfind(
+ const StringPiece& self,
+ char c,
+ StringPieceDetail<std::string>::size_type pos);
+BASE_EXPORT StringPieceDetail<std::string>::size_type find_first_of(
+ const StringPiece& self,
+ const StringPiece& s,
+ StringPieceDetail<std::string>::size_type pos);
+BASE_EXPORT StringPieceDetail<std::string>::size_type find_first_not_of(
+ const StringPiece& self,
+ const StringPiece& s,
+ StringPieceDetail<std::string>::size_type pos);
+BASE_EXPORT StringPieceDetail<std::string>::size_type find_first_not_of(
+ const StringPiece& self,
+ char c,
+ StringPieceDetail<std::string>::size_type pos);
+BASE_EXPORT StringPieceDetail<std::string>::size_type find_last_of(
+ const StringPiece& self,
+ const StringPiece& s,
+ StringPieceDetail<std::string>::size_type pos);
+BASE_EXPORT StringPieceDetail<std::string>::size_type find_last_of(
+ const StringPiece& self,
+ char c,
+ StringPieceDetail<std::string>::size_type pos);
+BASE_EXPORT StringPieceDetail<std::string>::size_type find_last_not_of(
+ const StringPiece& self,
+ const StringPiece& s,
+ StringPieceDetail<std::string>::size_type pos);
+BASE_EXPORT StringPieceDetail<std::string>::size_type find_last_not_of(
+ const StringPiece& self,
+ char c,
+ StringPieceDetail<std::string>::size_type pos);
+BASE_EXPORT StringPiece substr(const StringPiece& self,
+ StringPieceDetail<std::string>::size_type pos,
+ StringPieceDetail<std::string>::size_type n);
+} // namespace internal
+
+// Defines the template type that is instantiated as either StringPiece or
+// StringPiece16.
+template <typename STRING_TYPE> class BasicStringPiece :
+ public internal::StringPieceDetail<STRING_TYPE> {
+ public:
+ typedef typename internal::StringPieceDetail<STRING_TYPE>::value_type
+ value_type;
+ typedef typename internal::StringPieceDetail<STRING_TYPE>::size_type
+ size_type;
+
+ BasicStringPiece() {}
+ BasicStringPiece(const value_type*str)
+ : internal::StringPieceDetail<STRING_TYPE>(str) {}
+ BasicStringPiece(const STRING_TYPE& str)
+ : internal::StringPieceDetail<STRING_TYPE>(str) {}
+ BasicStringPiece(const value_type* offset, size_type len)
+ : internal::StringPieceDetail<STRING_TYPE>(offset, len) {}
+ BasicStringPiece(const typename STRING_TYPE::const_iterator& begin,
+ const typename STRING_TYPE::const_iterator& end)
+ : internal::StringPieceDetail<STRING_TYPE>(begin, end) {}
+};
+
+// Specializes BasicStringPiece for std::string to add a few operations that
+// are not needed for string16.
+template <> class BasicStringPiece<std::string> :
+ public internal::StringPieceDetail<std::string> {
+ public:
+ BasicStringPiece() {}
+ BasicStringPiece(const char* str)
+ : internal::StringPieceDetail<std::string>(str) {}
+ BasicStringPiece(const std::string& str)
+ : internal::StringPieceDetail<std::string>(str) {}
+ BasicStringPiece(const char* offset, size_type len)
+ : internal::StringPieceDetail<std::string>(offset, len) {}
+ BasicStringPiece(const std::string::const_iterator& begin,
+ const std::string::const_iterator& end)
+ : internal::StringPieceDetail<std::string>(begin, end) {}
+
+ // Prevent the following overload of set() from hiding the definitions in the
+ // base class.
+ using internal::StringPieceDetail<std::string>::set;
+
+ void set(const void* data, size_type len) {
+ ptr_ = reinterpret_cast<const value_type*>(data);
+ length_ = len;
+ }
+
+ void CopyToString(std::string* target) const {
+ internal::CopyToString(*this, target);
+ }
+
+ void AppendToString(std::string* target) const {
+ internal::AppendToString(*this, target);
+ }
+
+ // Does "this" start with "x"
+ bool starts_with(const BasicStringPiece& x) const {
+ return ((length_ >= x.length_) &&
+ (wordmemcmp(ptr_, x.ptr_, x.length_) == 0));
+ }
+
+ // Does "this" end with "x"
+ bool ends_with(const BasicStringPiece& x) const {
+ return ((length_ >= x.length_) &&
+ (wordmemcmp(ptr_ + (length_-x.length_), x.ptr_, x.length_) == 0));
+ }
+
+ size_type copy(char* buf, size_type n, size_type pos = 0) const {
+ return internal::copy(*this, buf, n, pos);
+ }
+
+ size_type find(const BasicStringPiece& s, size_type pos = 0) const {
+ return internal::find(*this, s, pos);
+ }
+
+ size_type find(char c, size_type pos = 0) const {
+ return internal::find(*this, c, pos);
+ }
+
+ size_type rfind(const BasicStringPiece& s, size_type pos = npos) const {
+ return internal::rfind(*this, s, pos);
+ }
+
+ size_type rfind(char c, size_type pos = npos) const {
+ return internal::rfind(*this, c, pos);
+ }
+
+ size_type find_first_of(const BasicStringPiece& s, size_type pos = 0) const {
+ return internal::find_first_of(*this, s, pos);
+ }
+
+ size_type find_first_of(char c, size_type pos = 0) const {
+ return find(c, pos);
+ }
+
+ size_type find_first_not_of(const BasicStringPiece& s,
+ size_type pos = 0) const {
+ return internal::find_first_not_of(*this, s, pos);
+ }
+
+ size_type find_first_not_of(char c, size_type pos = 0) const {
+ return internal::find_first_not_of(*this, c, pos);
+ }
+
+ size_type find_last_of(const BasicStringPiece& s,
+ size_type pos = npos) const {
+ return internal::find_last_of(*this, s, pos);
+ }
+
+ size_type find_last_of(char c, size_type pos = npos) const {
+ return rfind(c, pos);
+ }
+
+ size_type find_last_not_of(const BasicStringPiece& s,
+ size_type pos = npos) const {
+ return internal::find_last_not_of(*this, s, pos);
+ }
+
+ size_type find_last_not_of(char c, size_type pos = npos) const {
+ return internal::find_last_not_of(*this, c, pos);
+ }
+
+ BasicStringPiece substr(size_type pos, size_type n = npos) const {
+ return internal::substr(*this, pos, n);
+ }
+};
+
+// MSVC doesn't like complex extern templates and DLLs.
+#if !defined(COMPILER_MSVC)
+// We can't explicitly declare the std::string instantiation here because it was
+// already instantiated when specialized, above. Not only is it a no-op, but
+// currently it also crashes Clang (see http://crbug.com/107412).
+extern template class BASE_EXPORT BasicStringPiece<string16>;
+#endif
+
+BASE_EXPORT bool operator==(const StringPiece& x, const StringPiece& y);
+
+inline bool operator!=(const StringPiece& x, const StringPiece& y) {
+ return !(x == y);
+}
+
+inline bool operator<(const StringPiece& x, const StringPiece& y) {
+ const int r = StringPiece::wordmemcmp(
+ x.data(), y.data(), (x.size() < y.size() ? x.size() : y.size()));
+ return ((r < 0) || ((r == 0) && (x.size() < y.size())));
+}
+
+inline bool operator>(const StringPiece& x, const StringPiece& y) {
+ return y < x;
+}
+
+inline bool operator<=(const StringPiece& x, const StringPiece& y) {
+ return !(x > y);
+}
+
+inline bool operator>=(const StringPiece& x, const StringPiece& y) {
+ return !(x < y);
+}
+
+inline bool operator==(const StringPiece16& x, const StringPiece16& y) {
+ if (x.size() != y.size())
+ return false;
+
+ return StringPiece16::wordmemcmp(x.data(), y.data(), x.size()) == 0;
+}
+
+inline bool operator!=(const StringPiece16& x, const StringPiece16& y) {
+ return !(x == y);
+}
+
+inline bool operator<(const StringPiece16& x, const StringPiece16& y) {
+ const int r = StringPiece16::wordmemcmp(
+ x.data(), y.data(), (x.size() < y.size() ? x.size() : y.size()));
+ return ((r < 0) || ((r == 0) && (x.size() < y.size())));
+}
+
+inline bool operator>(const StringPiece16& x, const StringPiece16& y) {
+ return y < x;
+}
+
+inline bool operator<=(const StringPiece16& x, const StringPiece16& y) {
+ return !(x > y);
+}
+
+inline bool operator>=(const StringPiece16& x, const StringPiece16& y) {
+ return !(x < y);
+}
+
+BASE_EXPORT std::ostream& operator<<(std::ostream& o,
+ const StringPiece& piece);
+
+} // namespace base
+
+// We provide appropriate hash functions so StringPiece and StringPiece16 can
+// be used as keys in hash sets and maps.
+
+// This hash function is copied from base/hash_tables.h. We don't use the
+// ones already defined for string and string16 directly because it would
+// require the string constructors to be called, which we don't want.
+#define HASH_STRING_PIECE(StringPieceType, string_piece) \
+ std::size_t result = 0; \
+ for (StringPieceType::const_iterator i = string_piece.begin(); \
+ i != string_piece.end(); ++i) \
+ result = (result * 131) + *i; \
+ return result; \
+
+namespace BASE_HASH_NAMESPACE {
+#if defined(COMPILER_GCC)
+
+template<>
+struct hash<base::StringPiece> {
+ std::size_t operator()(const base::StringPiece& sp) const {
+ HASH_STRING_PIECE(base::StringPiece, sp);
+ }
+};
+template<>
+struct hash<base::StringPiece16> {
+ std::size_t operator()(const base::StringPiece16& sp16) const {
+ HASH_STRING_PIECE(base::StringPiece16, sp16);
+ }
+};
+
+#elif defined(COMPILER_MSVC)
+
+inline size_t hash_value(const base::StringPiece& sp) {
+ HASH_STRING_PIECE(base::StringPiece, sp);
+}
+inline size_t hash_value(const base::StringPiece16& sp16) {
+ HASH_STRING_PIECE(base::StringPiece16, sp16);
+}
+
+#endif // COMPILER
+
+} // namespace BASE_HASH_NAMESPACE
+
+#endif // BASE_STRINGS_STRING_PIECE_H_
diff --git a/base/string_piece_unittest.cc b/base/strings/string_piece_unittest.cc
similarity index 99%
rename from base/string_piece_unittest.cc
rename to base/strings/string_piece_unittest.cc
index e93dba8..6265888 100644
--- a/base/string_piece_unittest.cc
+++ b/base/strings/string_piece_unittest.cc
@@ -5,7 +5,7 @@
#include <string>
#include "base/string16.h"
-#include "base/string_piece.h"
+#include "base/strings/string_piece.h"
#include "base/utf_string_conversions.h"
#include "testing/gtest/include/gtest/gtest.h"
diff --git a/base/strings/string_split.cc b/base/strings/string_split.cc
index f5f19e9..819fdba 100644
--- a/base/strings/string_split.cc
+++ b/base/strings/string_split.cc
@@ -107,7 +107,8 @@
success = false;
}
DCHECK_LE(value.size(), 1U);
- kv_pairs->push_back(make_pair(key, value.empty()? "" : value[0]));
+ kv_pairs->push_back(
+ make_pair(key, value.empty() ? std::string() : value[0]));
}
return success;
}
diff --git a/base/strings/string_split_unittest.cc b/base/strings/string_split_unittest.cc
index a950cac..6729497 100644
--- a/base/strings/string_split_unittest.cc
+++ b/base/strings/string_split_unittest.cc
@@ -36,9 +36,10 @@
};
TEST_F(SplitStringIntoKeyValuesTest, EmptyInputMultipleValues) {
- EXPECT_FALSE(SplitStringIntoKeyValues("", // Empty input
- '\t', // Key separators
- &key, &values));
+ EXPECT_FALSE(SplitStringIntoKeyValues(std::string(), // Empty input
+ '\t', // Key separators
+ &key,
+ &values));
EXPECT_TRUE(key.empty());
EXPECT_TRUE(values.empty());
}
@@ -69,9 +70,10 @@
}
TEST_F(SplitStringIntoKeyValuesTest, EmptyInputSingleValue) {
- EXPECT_FALSE(SplitStringIntoKeyValues("", // Empty input
- '\t', // Key separators
- &key, &values));
+ EXPECT_FALSE(SplitStringIntoKeyValues(std::string(), // Empty input
+ '\t', // Key separators
+ &key,
+ &values));
EXPECT_TRUE(key.empty());
EXPECT_TRUE(values.empty());
}
@@ -108,9 +110,9 @@
};
TEST_F(SplitStringIntoKeyValuePairsTest, EmptyString) {
- EXPECT_TRUE(SplitStringIntoKeyValuePairs("",
- ':', // Key-value delimiters
- ',', // Key-value pair delims
+ EXPECT_TRUE(SplitStringIntoKeyValuePairs(std::string(),
+ ':', // Key-value delimiters
+ ',', // Key-value pair delims
&kv_pairs));
EXPECT_TRUE(kv_pairs.empty());
}
@@ -153,7 +155,7 @@
TEST(SplitStringUsingSubstrTest, EmptyString) {
std::vector<std::string> results;
- SplitStringUsingSubstr("", "DELIMITER", &results);
+ SplitStringUsingSubstr(std::string(), "DELIMITER", &results);
ASSERT_EQ(1u, results.size());
EXPECT_THAT(results, ElementsAre(""));
}
@@ -162,7 +164,7 @@
TEST(StringUtilTest, SplitString) {
std::vector<std::wstring> r;
- SplitString(L"", L',', &r);
+ SplitString(std::wstring(), L',', &r);
EXPECT_EQ(0U, r.size());
r.clear();
diff --git a/base/strings/string_tokenizer.h b/base/strings/string_tokenizer.h
index 791051a..8defbac 100644
--- a/base/strings/string_tokenizer.h
+++ b/base/strings/string_tokenizer.h
@@ -8,7 +8,7 @@
#include <algorithm>
#include <string>
-#include "base/string_piece.h"
+#include "base/strings/string_piece.h"
namespace base {
diff --git a/base/strings/sys_string_conversions.h b/base/strings/sys_string_conversions.h
index 8c800c0..9cdb7a4 100644
--- a/base/strings/sys_string_conversions.h
+++ b/base/strings/sys_string_conversions.h
@@ -14,7 +14,7 @@
#include "base/base_export.h"
#include "base/basictypes.h"
#include "base/string16.h"
-#include "base/string_piece.h"
+#include "base/strings/string_piece.h"
#if defined(OS_MACOSX)
#include <CoreFoundation/CoreFoundation.h>
diff --git a/base/strings/sys_string_conversions_mac.mm b/base/strings/sys_string_conversions_mac.mm
index 4a38ad8..3650e4ef 100644
--- a/base/strings/sys_string_conversions_mac.mm
+++ b/base/strings/sys_string_conversions_mac.mm
@@ -10,7 +10,7 @@
#include "base/mac/foundation_util.h"
#include "base/mac/scoped_cftyperef.h"
-#include "base/string_piece.h"
+#include "base/strings/string_piece.h"
namespace base {
diff --git a/base/strings/sys_string_conversions_posix.cc b/base/strings/sys_string_conversions_posix.cc
index e5be290..d58026c 100644
--- a/base/strings/sys_string_conversions_posix.cc
+++ b/base/strings/sys_string_conversions_posix.cc
@@ -6,7 +6,7 @@
#include <wchar.h>
-#include "base/string_piece.h"
+#include "base/strings/string_piece.h"
#include "base/utf_string_conversions.h"
namespace base {
diff --git a/base/strings/sys_string_conversions_unittest.cc b/base/strings/sys_string_conversions_unittest.cc
index 0c9c924..5c15a76 100644
--- a/base/strings/sys_string_conversions_unittest.cc
+++ b/base/strings/sys_string_conversions_unittest.cc
@@ -5,7 +5,7 @@
#include <string>
#include "base/basictypes.h"
-#include "base/string_piece.h"
+#include "base/strings/string_piece.h"
#include "base/strings/sys_string_conversions.h"
#include "base/test/scoped_locale.h"
#include "base/utf_string_conversions.h"
diff --git a/base/strings/sys_string_conversions_win.cc b/base/strings/sys_string_conversions_win.cc
index 67c5437..94d4466 100644
--- a/base/strings/sys_string_conversions_win.cc
+++ b/base/strings/sys_string_conversions_win.cc
@@ -6,7 +6,7 @@
#include <windows.h>
-#include "base/string_piece.h"
+#include "base/strings/string_piece.h"
namespace base {
diff --git a/base/strings/utf_offset_string_conversions.cc b/base/strings/utf_offset_string_conversions.cc
index 5a6f0c0..bb402e4 100644
--- a/base/strings/utf_offset_string_conversions.cc
+++ b/base/strings/utf_offset_string_conversions.cc
@@ -7,7 +7,7 @@
#include <algorithm>
#include "base/memory/scoped_ptr.h"
-#include "base/string_piece.h"
+#include "base/strings/string_piece.h"
#include "base/strings/utf_string_conversion_utils.h"
namespace base {
diff --git a/base/strings/utf_offset_string_conversions.h b/base/strings/utf_offset_string_conversions.h
index 98f29b9..618cebd 100644
--- a/base/strings/utf_offset_string_conversions.h
+++ b/base/strings/utf_offset_string_conversions.h
@@ -10,7 +10,7 @@
#include "base/base_export.h"
#include "base/string16.h"
-#include "base/string_piece.h"
+#include "base/strings/string_piece.h"
namespace base {
diff --git a/base/strings/utf_offset_string_conversions_unittest.cc b/base/strings/utf_offset_string_conversions_unittest.cc
index 885357b..5545c0d 100644
--- a/base/strings/utf_offset_string_conversions_unittest.cc
+++ b/base/strings/utf_offset_string_conversions_unittest.cc
@@ -5,7 +5,7 @@
#include <algorithm>
#include "base/logging.h"
-#include "base/string_piece.h"
+#include "base/strings/string_piece.h"
#include "base/strings/utf_offset_string_conversions.h"
#include "testing/gtest/include/gtest/gtest.h"
diff --git a/base/utf_string_conversions.cc b/base/strings/utf_string_conversions.cc
similarity index 90%
rename from base/utf_string_conversions.cc
rename to base/strings/utf_string_conversions.cc
index 9af79e2..b75ed0c 100644
--- a/base/utf_string_conversions.cc
+++ b/base/strings/utf_string_conversions.cc
@@ -2,16 +2,13 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-#include "base/utf_string_conversions.h"
+#include "base/strings/utf_string_conversions.h"
-#include "base/string_piece.h"
#include "base/string_util.h"
+#include "base/strings/string_piece.h"
#include "base/strings/utf_string_conversion_utils.h"
-using base::PrepareForUTF8Output;
-using base::PrepareForUTF16Or32Output;
-using base::ReadUnicodeCharacter;
-using base::WriteUnicodeCharacter;
+namespace base {
namespace {
@@ -63,7 +60,7 @@
return ConvertUnicode(src, src_len, output);
}
-std::wstring UTF8ToWide(const base::StringPiece& utf8) {
+std::wstring UTF8ToWide(const StringPiece& utf8) {
std::wstring ret;
UTF8ToWide(utf8.data(), utf8.length(), &ret);
return ret;
@@ -133,7 +130,7 @@
return ConvertUnicode(src, src_len, output);
}
-string16 UTF8ToUTF16(const base::StringPiece& utf8) {
+string16 UTF8ToUTF16(const StringPiece& utf8) {
string16 ret;
// Ignore the success flag of this call, it will do the best it can for
// invalid input, which is what we want here.
@@ -161,7 +158,7 @@
return UTF8ToWide(src, src_len, output);
}
-string16 UTF8ToUTF16(const base::StringPiece& utf8) {
+string16 UTF8ToUTF16(const StringPiece& utf8) {
return UTF8ToWide(utf8);
}
@@ -175,12 +172,14 @@
#endif
-std::wstring ASCIIToWide(const base::StringPiece& ascii) {
+std::wstring ASCIIToWide(const StringPiece& ascii) {
DCHECK(IsStringASCII(ascii)) << ascii;
return std::wstring(ascii.begin(), ascii.end());
}
-string16 ASCIIToUTF16(const base::StringPiece& ascii) {
+string16 ASCIIToUTF16(const StringPiece& ascii) {
DCHECK(IsStringASCII(ascii)) << ascii;
return string16(ascii.begin(), ascii.end());
}
+
+} // namespace base
diff --git a/base/strings/utf_string_conversions.h b/base/strings/utf_string_conversions.h
new file mode 100644
index 0000000..ec6a87f
--- /dev/null
+++ b/base/strings/utf_string_conversions.h
@@ -0,0 +1,72 @@
+// Copyright (c) 2011 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 BASE_STRINGS_UTF_STRING_CONVERSIONS_H_
+#define BASE_STRINGS_UTF_STRING_CONVERSIONS_H_
+
+#include <string>
+
+#include "base/base_export.h"
+#include "base/string16.h"
+#include "base/strings/string_piece.h"
+
+namespace base {
+
+// These convert between UTF-8, -16, and -32 strings. They are potentially slow,
+// so avoid unnecessary conversions. The low-level versions return a boolean
+// indicating whether the conversion was 100% valid. In this case, it will still
+// do the best it can and put the result in the output buffer. The versions that
+// return strings ignore this error and just return the best conversion
+// possible.
+BASE_EXPORT bool WideToUTF8(const wchar_t* src, size_t src_len,
+ std::string* output);
+BASE_EXPORT std::string WideToUTF8(const std::wstring& wide);
+BASE_EXPORT bool UTF8ToWide(const char* src, size_t src_len,
+ std::wstring* output);
+BASE_EXPORT std::wstring UTF8ToWide(const StringPiece& utf8);
+
+BASE_EXPORT bool WideToUTF16(const wchar_t* src, size_t src_len,
+ string16* output);
+BASE_EXPORT string16 WideToUTF16(const std::wstring& wide);
+BASE_EXPORT bool UTF16ToWide(const char16* src, size_t src_len,
+ std::wstring* output);
+BASE_EXPORT std::wstring UTF16ToWide(const string16& utf16);
+
+BASE_EXPORT bool UTF8ToUTF16(const char* src, size_t src_len, string16* output);
+BASE_EXPORT string16 UTF8ToUTF16(const StringPiece& utf8);
+BASE_EXPORT bool UTF16ToUTF8(const char16* src, size_t src_len,
+ std::string* output);
+BASE_EXPORT std::string UTF16ToUTF8(const string16& utf16);
+
+// We are trying to get rid of wstring as much as possible, but it's too big
+// a mess to do it all at once. These conversions should be used when we
+// really should just be passing a string16 around, but we haven't finished
+// porting whatever module uses wstring and the conversion is being used as a
+// stopcock. This makes it easy to grep for the ones that should be removed.
+#if defined(OS_WIN)
+# define WideToUTF16Hack
+# define UTF16ToWideHack
+#else
+# define WideToUTF16Hack WideToUTF16
+# define UTF16ToWideHack UTF16ToWide
+#endif
+
+// These convert an ASCII string, typically a hardcoded constant, to a
+// UTF16/Wide string.
+BASE_EXPORT std::wstring ASCIIToWide(const StringPiece& ascii);
+BASE_EXPORT string16 ASCIIToUTF16(const StringPiece& ascii);
+
+} // namespace base
+
+// TODO(brettw) remove these when callers are fixed up.
+using base::WideToUTF8;
+using base::UTF8ToWide;
+using base::WideToUTF16;
+using base::UTF16ToWide;
+using base::UTF8ToUTF16;
+using base::UTF16ToUTF8;
+using base::ASCIIToWide;
+using base::ASCIIToUTF16;
+
+#endif // BASE_STRINGS_UTF_STRING_CONVERSIONS_H_
diff --git a/base/utf_string_conversions_unittest.cc b/base/strings/utf_string_conversions_unittest.cc
similarity index 98%
rename from base/utf_string_conversions_unittest.cc
rename to base/strings/utf_string_conversions_unittest.cc
index 7c180a6..974184e 100644
--- a/base/utf_string_conversions_unittest.cc
+++ b/base/strings/utf_string_conversions_unittest.cc
@@ -4,9 +4,9 @@
#include "base/basictypes.h"
#include "base/logging.h"
-#include "base/string_piece.h"
#include "base/string_util.h"
-#include "base/utf_string_conversions.h"
+#include "base/strings/string_piece.h"
+#include "base/strings/utf_string_conversions.h"
#include "testing/gtest/include/gtest/gtest.h"
namespace base {
diff --git a/base/symbolize.target.darwin-arm.mk b/base/symbolize.target.darwin-arm.mk
new file mode 100644
index 0000000..85e1ce1
--- /dev/null
+++ b/base/symbolize.target.darwin-arm.mk
@@ -0,0 +1,144 @@
+# This file is generated by gyp; do not edit.
+
+include $(CLEAR_VARS)
+
+LOCAL_MODULE_CLASS := STATIC_LIBRARIES
+LOCAL_MODULE := base_symbolize_gyp
+LOCAL_MODULE_SUFFIX := .a
+LOCAL_MODULE_TAGS := optional
+gyp_intermediate_dir := $(call local-intermediates-dir)
+gyp_shared_intermediate_dir := $(call intermediates-dir-for,GYP,shared)
+
+# Make sure our deps are built first.
+GYP_TARGET_DEPENDENCIES :=
+
+GYP_GENERATED_OUTPUTS :=
+
+# Make sure our deps and generated files are built first.
+LOCAL_ADDITIONAL_DEPENDENCIES := $(GYP_TARGET_DEPENDENCIES) $(GYP_GENERATED_OUTPUTS)
+
+LOCAL_CPP_EXTENSION := .cc
+LOCAL_GENERATED_SOURCES :=
+
+GYP_COPIED_SOURCE_ORIGIN_DIRS :=
+
+LOCAL_SRC_FILES := \
+ base/third_party/symbolize/demangle.cc \
+ base/third_party/symbolize/symbolize.cc
+
+
+# Flags passed to both C and C++ files.
+MY_CFLAGS := \
+ -fstack-protector \
+ --param=ssp-buffer-size=4 \
+ -fno-exceptions \
+ -fno-strict-aliasing \
+ -Wno-unused-parameter \
+ -Wno-missing-field-initializers \
+ -fvisibility=hidden \
+ -pipe \
+ -fPIC \
+ -Wno-sign-compare \
+ -Wno-format \
+ -fno-tree-sra \
+ -fuse-ld=gold \
+ -Wno-psabi \
+ -ffunction-sections \
+ -funwind-tables \
+ -g \
+ -fstack-protector \
+ -fno-short-enums \
+ -finline-limit=64 \
+ -Wa,--noexecstack \
+ -U_FORTIFY_SOURCE \
+ -Wno-extra \
+ -Wno-ignored-qualifiers \
+ -Wno-type-limits \
+ -Os \
+ -g \
+ -fomit-frame-pointer \
+ -fdata-sections \
+ -ffunction-sections
+
+MY_CFLAGS_C :=
+
+MY_DEFS := \
+ '-D_FILE_OFFSET_BITS=64' \
+ '-DUSE_LINUX_BREAKPAD' \
+ '-DNO_TCMALLOC' \
+ '-DDISABLE_NACL' \
+ '-DCHROMIUM_BUILD' \
+ '-DUSE_LIBJPEG_TURBO=1' \
+ '-DUSE_PROPRIETARY_CODECS' \
+ '-DENABLE_GPU=1' \
+ '-DUSE_OPENSSL=1' \
+ '-DENABLE_EGLIMAGE=1' \
+ '-DENABLE_LANGUAGE_DETECTION=1' \
+ '-DANDROID' \
+ '-D__GNU_SOURCE=1' \
+ '-DUSE_STLPORT=1' \
+ '-D_STLP_USE_PTR_SPECIALIZATIONS=1' \
+ '-DCHROME_BUILD_ID=""' \
+ '-DDYNAMIC_ANNOTATIONS_ENABLED=1' \
+ '-DWTF_USE_DYNAMIC_ANNOTATIONS=1' \
+ '-D_DEBUG'
+
+LOCAL_CFLAGS := $(MY_CFLAGS_C) $(MY_CFLAGS) $(MY_DEFS)
+
+# Include paths placed before CFLAGS/CPPFLAGS
+LOCAL_C_INCLUDES := \
+ $(LOCAL_PATH) \
+ $(GYP_ABS_ANDROID_TOP_DIR)/frameworks/wilhelm/include \
+ $(GYP_ABS_ANDROID_TOP_DIR)/bionic \
+ $(GYP_ABS_ANDROID_TOP_DIR)/external/stlport/stlport
+
+LOCAL_C_INCLUDES := $(GYP_COPIED_SOURCE_ORIGIN_DIRS) $(LOCAL_C_INCLUDES)
+
+# Flags passed to only C++ (and not C) files.
+LOCAL_CPPFLAGS := \
+ -fno-rtti \
+ -fno-threadsafe-statics \
+ -fvisibility-inlines-hidden \
+ -Wno-deprecated \
+ -Wno-abi \
+ -Wno-error=c++0x-compat \
+ -Wno-non-virtual-dtor \
+ -Wno-sign-promo
+
+### Rules for final target.
+
+LOCAL_LDFLAGS := \
+ -Wl,-z,now \
+ -Wl,-z,relro \
+ -Wl,-z,noexecstack \
+ -fPIC \
+ -Wl,-z,relro \
+ -Wl,-z,now \
+ -fuse-ld=gold \
+ -nostdlib \
+ -Wl,--no-undefined \
+ -Wl,--exclude-libs=ALL \
+ -Wl,--icf=safe \
+ -Wl,--gc-sections \
+ -Wl,-O1 \
+ -Wl,--as-needed
+
+
+LOCAL_STATIC_LIBRARIES :=
+
+# Enable grouping to fix circular references
+LOCAL_GROUP_STATIC_LIBRARIES := true
+
+LOCAL_SHARED_LIBRARIES := \
+ libstlport \
+ libdl
+
+# Add target alias to "gyp_all_modules" target.
+.PHONY: gyp_all_modules
+gyp_all_modules: base_symbolize_gyp
+
+# Alias gyp target name.
+.PHONY: symbolize
+symbolize: base_symbolize_gyp
+
+include $(BUILD_STATIC_LIBRARY)
diff --git a/base/symbolize.target.darwin-x86.mk b/base/symbolize.target.darwin-x86.mk
new file mode 100644
index 0000000..783ff31
--- /dev/null
+++ b/base/symbolize.target.darwin-x86.mk
@@ -0,0 +1,143 @@
+# This file is generated by gyp; do not edit.
+
+include $(CLEAR_VARS)
+
+LOCAL_MODULE_CLASS := STATIC_LIBRARIES
+LOCAL_MODULE := base_symbolize_gyp
+LOCAL_MODULE_SUFFIX := .a
+LOCAL_MODULE_TAGS := optional
+gyp_intermediate_dir := $(call local-intermediates-dir)
+gyp_shared_intermediate_dir := $(call intermediates-dir-for,GYP,shared)
+
+# Make sure our deps are built first.
+GYP_TARGET_DEPENDENCIES :=
+
+GYP_GENERATED_OUTPUTS :=
+
+# Make sure our deps and generated files are built first.
+LOCAL_ADDITIONAL_DEPENDENCIES := $(GYP_TARGET_DEPENDENCIES) $(GYP_GENERATED_OUTPUTS)
+
+LOCAL_CPP_EXTENSION := .cc
+LOCAL_GENERATED_SOURCES :=
+
+GYP_COPIED_SOURCE_ORIGIN_DIRS :=
+
+LOCAL_SRC_FILES := \
+ base/third_party/symbolize/demangle.cc \
+ base/third_party/symbolize/symbolize.cc
+
+
+# Flags passed to both C and C++ files.
+MY_CFLAGS := \
+ --param=ssp-buffer-size=4 \
+ -fno-exceptions \
+ -fno-strict-aliasing \
+ -Wno-unused-parameter \
+ -Wno-missing-field-initializers \
+ -fvisibility=hidden \
+ -pipe \
+ -fPIC \
+ -Wno-sign-compare \
+ -Wno-format \
+ -m32 \
+ -mmmx \
+ -march=pentium4 \
+ -msse2 \
+ -mfpmath=sse \
+ -fuse-ld=gold \
+ -ffunction-sections \
+ -funwind-tables \
+ -g \
+ -fno-short-enums \
+ -finline-limit=64 \
+ -Wa,--noexecstack \
+ -U_FORTIFY_SOURCE \
+ -Wno-extra \
+ -Wno-ignored-qualifiers \
+ -Wno-type-limits \
+ -fno-stack-protector \
+ -Os \
+ -g \
+ -fomit-frame-pointer \
+ -fdata-sections \
+ -ffunction-sections
+
+MY_CFLAGS_C :=
+
+MY_DEFS := \
+ '-D_FILE_OFFSET_BITS=64' \
+ '-DUSE_LINUX_BREAKPAD' \
+ '-DNO_TCMALLOC' \
+ '-DDISABLE_NACL' \
+ '-DCHROMIUM_BUILD' \
+ '-DUSE_LIBJPEG_TURBO=1' \
+ '-DUSE_PROPRIETARY_CODECS' \
+ '-DENABLE_GPU=1' \
+ '-DUSE_OPENSSL=1' \
+ '-DENABLE_EGLIMAGE=1' \
+ '-DENABLE_LANGUAGE_DETECTION=1' \
+ '-DANDROID' \
+ '-D__GNU_SOURCE=1' \
+ '-DUSE_STLPORT=1' \
+ '-D_STLP_USE_PTR_SPECIALIZATIONS=1' \
+ '-DCHROME_BUILD_ID=""' \
+ '-DDYNAMIC_ANNOTATIONS_ENABLED=1' \
+ '-DWTF_USE_DYNAMIC_ANNOTATIONS=1' \
+ '-D_DEBUG'
+
+LOCAL_CFLAGS := $(MY_CFLAGS_C) $(MY_CFLAGS) $(MY_DEFS)
+
+# Include paths placed before CFLAGS/CPPFLAGS
+LOCAL_C_INCLUDES := \
+ $(LOCAL_PATH) \
+ $(GYP_ABS_ANDROID_TOP_DIR)/frameworks/wilhelm/include \
+ $(GYP_ABS_ANDROID_TOP_DIR)/bionic \
+ $(GYP_ABS_ANDROID_TOP_DIR)/external/stlport/stlport
+
+LOCAL_C_INCLUDES := $(GYP_COPIED_SOURCE_ORIGIN_DIRS) $(LOCAL_C_INCLUDES)
+
+# Flags passed to only C++ (and not C) files.
+LOCAL_CPPFLAGS := \
+ -fno-rtti \
+ -fno-threadsafe-statics \
+ -fvisibility-inlines-hidden \
+ -Wno-deprecated \
+ -Wno-error=c++0x-compat \
+ -Wno-non-virtual-dtor \
+ -Wno-sign-promo
+
+### Rules for final target.
+
+LOCAL_LDFLAGS := \
+ -Wl,-z,now \
+ -Wl,-z,relro \
+ -Wl,-z,noexecstack \
+ -fPIC \
+ -m32 \
+ -fuse-ld=gold \
+ -nostdlib \
+ -Wl,--no-undefined \
+ -Wl,--exclude-libs=ALL \
+ -Wl,--gc-sections \
+ -Wl,-O1 \
+ -Wl,--as-needed
+
+
+LOCAL_STATIC_LIBRARIES :=
+
+# Enable grouping to fix circular references
+LOCAL_GROUP_STATIC_LIBRARIES := true
+
+LOCAL_SHARED_LIBRARIES := \
+ libstlport \
+ libdl
+
+# Add target alias to "gyp_all_modules" target.
+.PHONY: gyp_all_modules
+gyp_all_modules: base_symbolize_gyp
+
+# Alias gyp target name.
+.PHONY: symbolize
+symbolize: base_symbolize_gyp
+
+include $(BUILD_STATIC_LIBRARY)
diff --git a/base/symbolize.target.linux-arm.mk b/base/symbolize.target.linux-arm.mk
index ae7b320..85e1ce1 100644
--- a/base/symbolize.target.linux-arm.mk
+++ b/base/symbolize.target.linux-arm.mk
@@ -63,7 +63,6 @@
MY_CFLAGS_C :=
MY_DEFS := \
- '-DUSE_SKIA' \
'-D_FILE_OFFSET_BITS=64' \
'-DUSE_LINUX_BREAKPAD' \
'-DNO_TCMALLOC' \
@@ -71,7 +70,6 @@
'-DCHROMIUM_BUILD' \
'-DUSE_LIBJPEG_TURBO=1' \
'-DUSE_PROPRIETARY_CODECS' \
- '-DENABLE_PEPPER_THREADING' \
'-DENABLE_GPU=1' \
'-DUSE_OPENSSL=1' \
'-DENABLE_EGLIMAGE=1' \
@@ -121,9 +119,9 @@
-Wl,--no-undefined \
-Wl,--exclude-libs=ALL \
-Wl,--icf=safe \
+ -Wl,--gc-sections \
-Wl,-O1 \
- -Wl,--as-needed \
- -Wl,--gc-sections
+ -Wl,--as-needed
LOCAL_STATIC_LIBRARIES :=
diff --git a/base/symbolize.target.linux-x86.mk b/base/symbolize.target.linux-x86.mk
index a986a5e..783ff31 100644
--- a/base/symbolize.target.linux-x86.mk
+++ b/base/symbolize.target.linux-x86.mk
@@ -44,6 +44,7 @@
-march=pentium4 \
-msse2 \
-mfpmath=sse \
+ -fuse-ld=gold \
-ffunction-sections \
-funwind-tables \
-g \
@@ -64,7 +65,6 @@
MY_CFLAGS_C :=
MY_DEFS := \
- '-DUSE_SKIA' \
'-D_FILE_OFFSET_BITS=64' \
'-DUSE_LINUX_BREAKPAD' \
'-DNO_TCMALLOC' \
@@ -72,7 +72,6 @@
'-DCHROMIUM_BUILD' \
'-DUSE_LIBJPEG_TURBO=1' \
'-DUSE_PROPRIETARY_CODECS' \
- '-DENABLE_PEPPER_THREADING' \
'-DENABLE_GPU=1' \
'-DUSE_OPENSSL=1' \
'-DENABLE_EGLIMAGE=1' \
@@ -115,12 +114,13 @@
-Wl,-z,noexecstack \
-fPIC \
-m32 \
+ -fuse-ld=gold \
-nostdlib \
-Wl,--no-undefined \
-Wl,--exclude-libs=ALL \
+ -Wl,--gc-sections \
-Wl,-O1 \
- -Wl,--as-needed \
- -Wl,--gc-sections
+ -Wl,--as-needed
LOCAL_STATIC_LIBRARIES :=
diff --git a/base/synchronization/lock.cc b/base/synchronization/lock.cc
index 6445ce8..49efbe9 100644
--- a/base/synchronization/lock.cc
+++ b/base/synchronization/lock.cc
@@ -13,9 +13,16 @@
namespace base {
+const PlatformThreadId kNoThreadId = static_cast<PlatformThreadId>(0);
+
Lock::Lock() : lock_() {
owned_by_thread_ = false;
- owning_thread_id_ = static_cast<PlatformThreadId>(0);
+ owning_thread_id_ = kNoThreadId;
+}
+
+Lock::~Lock() {
+ DCHECK(!owned_by_thread_);
+ DCHECK_EQ(kNoThreadId, owning_thread_id_);
}
void Lock::AssertAcquired() const {
@@ -27,7 +34,7 @@
DCHECK(owned_by_thread_);
DCHECK_EQ(owning_thread_id_, PlatformThread::CurrentId());
owned_by_thread_ = false;
- owning_thread_id_ = static_cast<PlatformThreadId>(0);
+ owning_thread_id_ = kNoThreadId;
}
void Lock::CheckUnheldAndMark() {
diff --git a/base/synchronization/lock.h b/base/synchronization/lock.h
index 15de446..7e8ffe7 100644
--- a/base/synchronization/lock.h
+++ b/base/synchronization/lock.h
@@ -32,7 +32,7 @@
void AssertAcquired() const {}
#else
Lock();
- ~Lock() {}
+ ~Lock();
// NOTE: Although windows critical sections support recursive locks, we do not
// allow this, and we will commonly fire a DCHECK() if a thread attempts to
@@ -96,10 +96,16 @@
// A helper class that acquires the given Lock while the AutoLock is in scope.
class AutoLock {
public:
+ struct AlreadyAcquired {};
+
explicit AutoLock(Lock& lock) : lock_(lock) {
lock_.Acquire();
}
+ AutoLock(Lock& lock, const AlreadyAcquired&) : lock_(lock) {
+ lock_.AssertAcquired();
+ }
+
~AutoLock() {
lock_.AssertAcquired();
lock_.Release();
diff --git a/base/sys_info_android.cc b/base/sys_info_android.cc
index 5d4eff0..80c1517 100644
--- a/base/sys_info_android.cc
+++ b/base/sys_info_android.cc
@@ -7,8 +7,8 @@
#include <sys/system_properties.h>
#include "base/logging.h"
-#include "base/string_piece.h"
#include "base/strings/string_number_conversions.h"
+#include "base/strings/string_piece.h"
namespace {
diff --git a/base/sys_info_chromeos.cc b/base/sys_info_chromeos.cc
index ef7b3dc..d5476fb 100644
--- a/base/sys_info_chromeos.cc
+++ b/base/sys_info_chromeos.cc
@@ -8,8 +8,8 @@
#include "base/file_util.h"
#include "base/files/file_path.h"
#include "base/lazy_instance.h"
-#include "base/string_piece.h"
#include "base/strings/string_number_conversions.h"
+#include "base/strings/string_piece.h"
#include "base/strings/string_tokenizer.h"
#include "base/threading/thread_restrictions.h"
diff --git a/base/sys_info_linux.cc b/base/sys_info_linux.cc
index 09ac3d6..58a0aef 100644
--- a/base/sys_info_linux.cc
+++ b/base/sys_info_linux.cc
@@ -10,28 +10,30 @@
#include "base/logging.h"
#include "base/strings/string_number_conversions.h"
-namespace base {
+namespace {
-int64 SysInfo::AmountOfPhysicalMemory() {
- long pages = sysconf(_SC_PHYS_PAGES);
- long page_size = sysconf(_SC_PAGE_SIZE);
+int64 AmountOfMemory(int pages_name) {
+ long pages = sysconf(pages_name);
+ long page_size = sysconf(_SC_PAGESIZE);
if (pages == -1 || page_size == -1) {
NOTREACHED();
return 0;
}
-
return static_cast<int64>(pages) * page_size;
}
+} // namespace
+
+namespace base {
+
+// static
+int64 SysInfo::AmountOfPhysicalMemory() {
+ return AmountOfMemory(_SC_PHYS_PAGES);
+}
+
// static
int64 SysInfo::AmountOfAvailablePhysicalMemory() {
- long available_pages = sysconf(_SC_AVPHYS_PAGES);
- long page_size = sysconf(_SC_PAGE_SIZE);
- if (available_pages == -1 || page_size == -1) {
- NOTREACHED();
- return 0;
- }
- return static_cast<int64>(available_pages) * page_size;
+ return AmountOfMemory(_SC_AVPHYS_PAGES);
}
// static
@@ -59,15 +61,19 @@
// static
std::string SysInfo::CPUModelName() {
- const char kModelNamePrefix[] = "model name";
+#if defined(OS_CHROMEOS) && defined(ARCH_CPU_ARMEL)
+ const char kCpuModelPrefix[] = "Hardware";
+#else
+ const char kCpuModelPrefix[] = "model name";
+#endif
std::string contents;
file_util::ReadFileToString(FilePath("/proc/cpuinfo"), &contents);
DCHECK(!contents.empty());
if (!contents.empty()) {
std::istringstream iss(contents);
std::string line;
- while (std::getline(iss, line)){
- if (line.compare(0, strlen(kModelNamePrefix), kModelNamePrefix) == 0) {
+ while (std::getline(iss, line)) {
+ if (line.compare(0, strlen(kCpuModelPrefix), kCpuModelPrefix) == 0) {
size_t pos = line.find(": ");
return line.substr(pos + 2);
}
diff --git a/base/sys_info_openbsd.cc b/base/sys_info_openbsd.cc
index b9aec20..edbb2c9 100644
--- a/base/sys_info_openbsd.cc
+++ b/base/sys_info_openbsd.cc
@@ -10,30 +10,45 @@
#include "base/logging.h"
+namespace {
+
+int64 AmountOfMemory(int pages_name) {
+ long pages = sysconf(pages_name);
+ long page_size = sysconf(_SC_PAGESIZE);
+ if (pages == -1 || page_size == -1) {
+ NOTREACHED();
+ return 0;
+ }
+ return static_cast<int64>(pages) * page_size;
+}
+
+} // namespace
+
namespace base {
+// static
int SysInfo::NumberOfProcessors() {
int mib[] = { CTL_HW, HW_NCPU };
int ncpu;
size_t size = sizeof(ncpu);
- if (sysctl(mib, arraysize(mib), &ncpu, &size, NULL, 0) == -1) {
+ if (sysctl(mib, arraysize(mib), &ncpu, &size, NULL, 0) < 0) {
NOTREACHED();
return 1;
}
return ncpu;
}
+// static
int64 SysInfo::AmountOfPhysicalMemory() {
- long pages = sysconf(_SC_PHYS_PAGES);
- long page_size = sysconf(_SC_PAGESIZE);
- if (pages == -1 || page_size == -1) {
- NOTREACHED();
- return 0;
- }
-
- return static_cast<int64>(pages) * page_size;
+ return AmountOfMemory(_SC_PHYS_PAGES);
}
+// static
+int64 SysInfo::AmountOfAvailablePhysicalMemory() {
+ return AmountOfMemory(_SC_AVPHYS_PAGES);
+}
+
+// static
size_t SysInfo::MaxSharedMemorySize() {
int mib[] = { CTL_KERN, KERN_SHMINFO, KERN_SHMINFO_SHMMAX };
size_t limit;
@@ -45,4 +60,16 @@
return limit;
}
+// static
+std::string SysInfo::CPUModelName() {
+ int mib[] = { CTL_HW, HW_MODEL };
+ char name[256];
+ size_t len = arraysize(name);
+ if (sysctl(mib, arraysize(mib), name, &len, NULL, 0) < 0) {
+ NOTREACHED();
+ return std::string();
+ }
+ return name;
+}
+
} // namespace base
diff --git a/base/sys_info_posix.cc b/base/sys_info_posix.cc
index 854f123..57b7af6 100644
--- a/base/sys_info_posix.cc
+++ b/base/sys_info_posix.cc
@@ -55,7 +55,7 @@
struct utsname info;
if (uname(&info) < 0) {
NOTREACHED();
- return "";
+ return std::string();
}
return std::string(info.sysname);
}
@@ -67,7 +67,7 @@
struct utsname info;
if (uname(&info) < 0) {
NOTREACHED();
- return "";
+ return std::string();
}
return std::string(info.release);
}
@@ -78,7 +78,7 @@
struct utsname info;
if (uname(&info) < 0) {
NOTREACHED();
- return "";
+ return std::string();
}
std::string arch(info.machine);
if (arch == "i386" || arch == "i486" || arch == "i586" || arch == "i686") {
diff --git a/base/sys_info_win.cc b/base/sys_info_win.cc
index af0ce7e..1d15b62 100644
--- a/base/sys_info_win.cc
+++ b/base/sys_info_win.cc
@@ -13,6 +13,24 @@
#include "base/threading/thread_restrictions.h"
#include "base/win/windows_version.h"
+namespace {
+
+int64 AmountOfMemory(DWORDLONG MEMORYSTATUSEX::* memory_field) {
+ MEMORYSTATUSEX memory_info;
+ memory_info.dwLength = sizeof(memory_info);
+ if (!GlobalMemoryStatusEx(&memory_info)) {
+ NOTREACHED();
+ return 0;
+ }
+
+ int64 rv = static_cast<int64>(memory_info.*memory_field);
+ if (rv < 0)
+ rv = kint64max;
+ return rv;
+}
+
+} // namespace
+
namespace base {
// static
@@ -22,32 +40,12 @@
// static
int64 SysInfo::AmountOfPhysicalMemory() {
- MEMORYSTATUSEX memory_info;
- memory_info.dwLength = sizeof(memory_info);
- if (!GlobalMemoryStatusEx(&memory_info)) {
- NOTREACHED();
- return 0;
- }
-
- int64 rv = static_cast<int64>(memory_info.ullTotalPhys);
- if (rv < 0)
- rv = kint64max;
- return rv;
+ return AmountOfMemory(&MEMORYSTATUSEX::ullTotalPhys);
}
// static
int64 SysInfo::AmountOfAvailablePhysicalMemory() {
- MEMORYSTATUSEX memory_info;
- memory_info.dwLength = sizeof(memory_info);
- if (!GlobalMemoryStatusEx(&memory_info)) {
- NOTREACHED();
- return 0;
- }
-
- int64 rv = static_cast<int64>(memory_info.ullAvailPhys);
- if (rv < 0)
- rv = kint64max;
- return rv;
+ return AmountOfMemory(&MEMORYSTATUSEX::ullAvailPhys);
}
// static
diff --git a/base/sys_string_conversions.h b/base/sys_string_conversions.h
deleted file mode 100644
index 36e51c8..0000000
--- a/base/sys_string_conversions.h
+++ /dev/null
@@ -1,7 +0,0 @@
-// Copyright (c) 2013 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.
-
-// TODO(brettw) remove this file when all callers are updated to the new
-// location.
-#include "base/strings/sys_string_conversions.h"
diff --git a/base/system_monitor/system_monitor.cc b/base/system_monitor/system_monitor.cc
index 7c960cc..b934139 100644
--- a/base/system_monitor/system_monitor.cc
+++ b/base/system_monitor/system_monitor.cc
@@ -14,36 +14,14 @@
static SystemMonitor* g_system_monitor = NULL;
-#if defined(ENABLE_BATTERY_MONITORING)
-// The amount of time (in ms) to wait before running the initial
-// battery check.
-static int kDelayedBatteryCheckMs = 10 * 1000;
-#endif // defined(ENABLE_BATTERY_MONITORING)
-
SystemMonitor::SystemMonitor()
- : power_observer_list_(new ObserverListThreadSafe<PowerObserver>()),
- devices_changed_observer_list_(
- new ObserverListThreadSafe<DevicesChangedObserver>()),
- battery_in_use_(false),
- suspended_(false) {
+ : devices_changed_observer_list_(
+ new ObserverListThreadSafe<DevicesChangedObserver>()) {
DCHECK(!g_system_monitor);
g_system_monitor = this;
-
- DCHECK(MessageLoop::current());
-#if defined(ENABLE_BATTERY_MONITORING)
- delayed_battery_check_.Start(FROM_HERE,
- base::TimeDelta::FromMilliseconds(kDelayedBatteryCheckMs), this,
- &SystemMonitor::BatteryCheck);
-#endif // defined(ENABLE_BATTERY_MONITORING)
-#if defined(OS_MACOSX)
- PlatformInit();
-#endif
}
SystemMonitor::~SystemMonitor() {
-#if defined(OS_MACOSX)
- PlatformDestroy();
-#endif
DCHECK_EQ(this, g_system_monitor);
g_system_monitor = NULL;
}
@@ -53,46 +31,10 @@
return g_system_monitor;
}
-void SystemMonitor::ProcessPowerMessage(PowerEvent event_id) {
- // Suppress duplicate notifications. Some platforms may
- // send multiple notifications of the same event.
- switch (event_id) {
- case POWER_STATE_EVENT:
- {
- bool on_battery = IsBatteryPower();
- if (on_battery != battery_in_use_) {
- battery_in_use_ = on_battery;
- NotifyPowerStateChange();
- }
- }
- break;
- case RESUME_EVENT:
- if (suspended_) {
- suspended_ = false;
- NotifyResume();
- }
- break;
- case SUSPEND_EVENT:
- if (!suspended_) {
- suspended_ = true;
- NotifySuspend();
- }
- break;
- }
-}
-
void SystemMonitor::ProcessDevicesChanged(DeviceType device_type) {
NotifyDevicesChanged(device_type);
}
-void SystemMonitor::AddPowerObserver(PowerObserver* obs) {
- power_observer_list_->AddObserver(obs);
-}
-
-void SystemMonitor::RemovePowerObserver(PowerObserver* obs) {
- power_observer_list_->RemoveObserver(obs);
-}
-
void SystemMonitor::AddDevicesChangedObserver(DevicesChangedObserver* obs) {
devices_changed_observer_list_->AddObserver(obs);
}
@@ -107,25 +49,4 @@
&DevicesChangedObserver::OnDevicesChanged, device_type);
}
-void SystemMonitor::NotifyPowerStateChange() {
- DVLOG(1) << "PowerStateChange: " << (BatteryPower() ? "On" : "Off")
- << " battery";
- power_observer_list_->Notify(&PowerObserver::OnPowerStateChange,
- BatteryPower());
-}
-
-void SystemMonitor::NotifySuspend() {
- DVLOG(1) << "Power Suspending";
- power_observer_list_->Notify(&PowerObserver::OnSuspend);
-}
-
-void SystemMonitor::NotifyResume() {
- DVLOG(1) << "Power Resuming";
- power_observer_list_->Notify(&PowerObserver::OnResume);
-}
-
-void SystemMonitor::BatteryCheck() {
- ProcessPowerMessage(SystemMonitor::POWER_STATE_EVENT);
-}
-
} // namespace base
diff --git a/base/system_monitor/system_monitor.h b/base/system_monitor/system_monitor.h
index 10f279f..5dd849f 100644
--- a/base/system_monitor/system_monitor.h
+++ b/base/system_monitor/system_monitor.h
@@ -5,35 +5,11 @@
#ifndef BASE_SYSTEM_MONITOR_SYSTEM_MONITOR_H_
#define BASE_SYSTEM_MONITOR_SYSTEM_MONITOR_H_
-#include <map>
-#include <string>
-#include <vector>
-
#include "base/base_export.h"
#include "base/basictypes.h"
-#include "build/build_config.h"
-
-// Windows HiRes timers drain the battery faster so we need to know the battery
-// status. This isn't true for other platforms.
-#if defined(OS_WIN)
-#define ENABLE_BATTERY_MONITORING 1
-#else
-#undef ENABLE_BATTERY_MONITORING
-#endif // !OS_WIN
-
+#include "base/memory/ref_counted.h"
#include "base/observer_list_threadsafe.h"
-#if defined(ENABLE_BATTERY_MONITORING)
-#include "base/timer.h"
-#endif // defined(ENABLE_BATTERY_MONITORING)
-
-#if defined(OS_MACOSX) && !defined(OS_IOS)
-#include <IOKit/pwr_mgt/IOPMLib.h>
-#include <IOKit/IOMessage.h>
-#endif // OS_MACOSX && !OS_IOS
-
-#if defined(OS_IOS)
-#include <objc/runtime.h>
-#endif // OS_IOS
+#include "build/build_config.h"
namespace base {
@@ -42,13 +18,6 @@
// TODO(mbelshe): Add support beyond just power management.
class BASE_EXPORT SystemMonitor {
public:
- // Normalized list of power events.
- enum PowerEvent {
- POWER_STATE_EVENT, // The Power status of the system has changed.
- SUSPEND_EVENT, // The system is being suspended.
- RESUME_EVENT // The system is being resumed.
- };
-
// Type of devices whose change need to be monitored, such as add/remove.
enum DeviceType {
DEVTYPE_AUDIO_CAPTURE, // Audio capture device, e.g., microphone.
@@ -64,50 +33,6 @@
// Get the application-wide SystemMonitor (if not present, returns NULL).
static SystemMonitor* Get();
-#if defined(OS_MACOSX)
- // Allocate system resources needed by the SystemMonitor class.
- //
- // This function must be called before instantiating an instance of the class
- // and before the Sandbox is initialized.
-#if !defined(OS_IOS)
- static void AllocateSystemIOPorts();
-#else
- static void AllocateSystemIOPorts() {}
-#endif // OS_IOS
-#endif // OS_MACOSX
-
- //
- // Power-related APIs
- //
-
- // Is the computer currently on battery power.
- // Can be called on any thread.
- bool BatteryPower() const {
- // Using a lock here is not necessary for just a bool.
- return battery_in_use_;
- }
-
- // Callbacks will be called on the thread which creates the SystemMonitor.
- // During the callback, Add/RemoveObserver will block until the callbacks
- // are finished. Observers should implement quick callback functions; if
- // lengthy operations are needed, the observer should take care to invoke
- // the operation on an appropriate thread.
- class BASE_EXPORT PowerObserver {
- public:
- // Notification of a change in power status of the computer, such
- // as from switching between battery and A/C power.
- virtual void OnPowerStateChange(bool on_battery_power) {}
-
- // Notification that the system is suspending.
- virtual void OnSuspend() {}
-
- // Notification that the system is resuming.
- virtual void OnResume() {}
-
- protected:
- virtual ~PowerObserver() {}
- };
-
class BASE_EXPORT DevicesChangedObserver {
public:
// Notification that the devices connected to the system have changed.
@@ -121,87 +46,26 @@
// Add a new observer.
// Can be called from any thread.
// Must not be called from within a notification callback.
- void AddPowerObserver(PowerObserver* obs);
void AddDevicesChangedObserver(DevicesChangedObserver* obs);
// Remove an existing observer.
// Can be called from any thread.
// Must not be called from within a notification callback.
- void RemovePowerObserver(PowerObserver* obs);
void RemoveDevicesChangedObserver(DevicesChangedObserver* obs);
// The ProcessFoo() style methods are a broken pattern and should not
// be copied. Any significant addition to this class is blocked on
// refactoring to improve the state of affairs. See http://crbug.com/149059
- // Cross-platform handling of a power event.
- void ProcessPowerMessage(PowerEvent event_id);
-
// Cross-platform handling of a device change event.
void ProcessDevicesChanged(DeviceType device_type);
private:
-#if defined(OS_WIN)
- // Represents a message-only window for power message handling on Windows.
- // Only allow SystemMonitor to create it.
- class PowerMessageWindow {
- public:
- PowerMessageWindow();
- ~PowerMessageWindow();
-
- private:
- void ProcessWmPowerBroadcastMessage(int event_id);
- LRESULT CALLBACK WndProc(HWND hwnd, UINT message,
- WPARAM wparam, LPARAM lparam);
- static LRESULT CALLBACK WndProcThunk(HWND hwnd,
- UINT message,
- WPARAM wparam,
- LPARAM lparam);
- // Instance of the module containing the window procedure.
- HMODULE instance_;
- // A hidden message-only window.
- HWND message_hwnd_;
- };
-#endif
-
-#if defined(OS_MACOSX)
- void PlatformInit();
- void PlatformDestroy();
-#endif
-
- // Platform-specific method to check whether the system is currently
- // running on battery power. Returns true if running on batteries,
- // false otherwise.
- bool IsBatteryPower();
-
- // Checks the battery status and notifies observers if the battery
- // status has changed.
- void BatteryCheck();
-
// Functions to trigger notifications.
void NotifyDevicesChanged(DeviceType device_type);
- void NotifyPowerStateChange();
- void NotifySuspend();
- void NotifyResume();
- scoped_refptr<ObserverListThreadSafe<PowerObserver> > power_observer_list_;
scoped_refptr<ObserverListThreadSafe<DevicesChangedObserver> >
devices_changed_observer_list_;
- bool battery_in_use_;
- bool suspended_;
-
-#if defined(ENABLE_BATTERY_MONITORING)
- base::OneShotTimer<SystemMonitor> delayed_battery_check_;
-#endif
-
-#if defined(OS_IOS)
- // Holds pointers to system event notification observers.
- std::vector<id> notification_observers_;
-#endif
-
-#if defined(OS_WIN)
- PowerMessageWindow power_message_window_;
-#endif
DISALLOW_COPY_AND_ASSIGN(SystemMonitor);
};
diff --git a/base/system_monitor/system_monitor_android.cc b/base/system_monitor/system_monitor_android.cc
deleted file mode 100644
index f29b7b0..0000000
--- a/base/system_monitor/system_monitor_android.cc
+++ /dev/null
@@ -1,36 +0,0 @@
-// Copyright (c) 2011 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/system_monitor/system_monitor.h"
-#include "jni/SystemMonitor_jni.h"
-
-namespace base {
-
-namespace android {
-
-// Native implementation of SystemMonitor.java.
-void OnBatteryChargingChanged(JNIEnv* env, jclass clazz) {
- SystemMonitor::Get()->ProcessPowerMessage(SystemMonitor::POWER_STATE_EVENT);
-}
-
-void OnMainActivityResumed(JNIEnv* env, jclass clazz) {
- SystemMonitor::Get()->ProcessPowerMessage(SystemMonitor::RESUME_EVENT);
-}
-
-void OnMainActivitySuspended(JNIEnv* env, jclass clazz) {
- SystemMonitor::Get()->ProcessPowerMessage(SystemMonitor::SUSPEND_EVENT);
-}
-
-} // namespace android
-
-bool SystemMonitor::IsBatteryPower() {
- JNIEnv* env = base::android::AttachCurrentThread();
- return base::android::Java_SystemMonitor_isBatteryPower(env);
-}
-
-bool RegisterSystemMonitor(JNIEnv* env) {
- return base::android::RegisterNativesImpl(env);
-}
-
-} // namespace base
diff --git a/base/system_monitor/system_monitor_android.h b/base/system_monitor/system_monitor_android.h
deleted file mode 100644
index 9f60560..0000000
--- a/base/system_monitor/system_monitor_android.h
+++ /dev/null
@@ -1,17 +0,0 @@
-// Copyright (c) 2012 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 BASE_SYSTEM_MONITOR_SYSTEM_MONITOR_ANDROID_H_
-#define BASE_SYSTEM_MONITOR_SYSTEM_MONITOR_ANDROID_H_
-
-#include <jni.h>
-
-namespace base {
-
-// Registers the JNI bindings for SystemMonitor.
-bool RegisterSystemMonitor(JNIEnv* env);
-
-} // namespace base
-
-#endif // BASE_SYSTEM_MONITOR_SYSTEM_MONITOR_ANDROID_H_
diff --git a/base/system_monitor/system_monitor_posix.cc b/base/system_monitor/system_monitor_posix.cc
deleted file mode 100644
index 6cf01bf..0000000
--- a/base/system_monitor/system_monitor_posix.cc
+++ /dev/null
@@ -1,14 +0,0 @@
-// Copyright (c) 2011 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/system_monitor/system_monitor.h"
-
-namespace base {
-
-bool SystemMonitor::IsBatteryPower() {
- NOTIMPLEMENTED();
- return false;
-}
-
-} // namespace base
diff --git a/base/system_monitor/system_monitor_unittest.cc b/base/system_monitor/system_monitor_unittest.cc
index 43f1dd6..b46e52f 100644
--- a/base/system_monitor/system_monitor_unittest.cc
+++ b/base/system_monitor/system_monitor_unittest.cc
@@ -14,45 +14,9 @@
namespace {
-class PowerTest : public SystemMonitor::PowerObserver {
- public:
- PowerTest()
- : power_state_changes_(0),
- suspends_(0),
- resumes_(0) {
- }
-
- // PowerObserver callbacks.
- virtual void OnPowerStateChange(bool on_battery_power) OVERRIDE {
- power_state_changes_++;
- }
-
- virtual void OnSuspend() OVERRIDE {
- suspends_++;
- }
-
- virtual void OnResume() OVERRIDE {
- resumes_++;
- }
-
- // Test status counts.
- int power_state_changes() { return power_state_changes_; }
- int suspends() { return suspends_; }
- int resumes() { return resumes_; }
-
- private:
- int power_state_changes_; // Count of OnPowerStateChange notifications.
- int suspends_; // Count of OnSuspend notifications.
- int resumes_; // Count of OnResume notifications.
-};
-
class SystemMonitorTest : public testing::Test {
protected:
SystemMonitorTest() {
-#if defined(OS_MACOSX)
- // This needs to happen before SystemMonitor's ctor.
- SystemMonitor::AllocateSystemIOPorts();
-#endif
system_monitor_.reset(new SystemMonitor);
}
virtual ~SystemMonitorTest() {}
@@ -63,46 +27,6 @@
DISALLOW_COPY_AND_ASSIGN(SystemMonitorTest);
};
-TEST_F(SystemMonitorTest, PowerNotifications) {
- const int kObservers = 5;
-
- PowerTest test[kObservers];
- for (int index = 0; index < kObservers; ++index)
- system_monitor_->AddPowerObserver(&test[index]);
-
- // Send a bunch of power changes. Since the battery power hasn't
- // actually changed, we shouldn't get notifications.
- for (int index = 0; index < 5; index++) {
- system_monitor_->ProcessPowerMessage(SystemMonitor::POWER_STATE_EVENT);
- EXPECT_EQ(test[0].power_state_changes(), 0);
- }
-
- // Sending resume when not suspended should have no effect.
- system_monitor_->ProcessPowerMessage(SystemMonitor::RESUME_EVENT);
- RunLoop().RunUntilIdle();
- EXPECT_EQ(test[0].resumes(), 0);
-
- // Pretend we suspended.
- system_monitor_->ProcessPowerMessage(SystemMonitor::SUSPEND_EVENT);
- RunLoop().RunUntilIdle();
- EXPECT_EQ(test[0].suspends(), 1);
-
- // Send a second suspend notification. This should be suppressed.
- system_monitor_->ProcessPowerMessage(SystemMonitor::SUSPEND_EVENT);
- RunLoop().RunUntilIdle();
- EXPECT_EQ(test[0].suspends(), 1);
-
- // Pretend we were awakened.
- system_monitor_->ProcessPowerMessage(SystemMonitor::RESUME_EVENT);
- RunLoop().RunUntilIdle();
- EXPECT_EQ(test[0].resumes(), 1);
-
- // Send a duplicate resume notification. This should be suppressed.
- system_monitor_->ProcessPowerMessage(SystemMonitor::RESUME_EVENT);
- RunLoop().RunUntilIdle();
- EXPECT_EQ(test[0].resumes(), 1);
-}
-
TEST_F(SystemMonitorTest, DeviceChangeNotifications) {
const int kObservers = 5;
diff --git a/base/test/android/javatests/src/org/chromium/base/test/util/PhoneOnly.java b/base/test/android/javatests/src/org/chromium/base/test/util/PhoneOnly.java
new file mode 100644
index 0000000..1c82e20
--- /dev/null
+++ b/base/test/android/javatests/src/org/chromium/base/test/util/PhoneOnly.java
@@ -0,0 +1,19 @@
+// Copyright (c) 2013 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.
+
+package org.chromium.base.test.util;
+
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+/**
+ * Annotation for specifying that the test should only be run on phones.
+ */
+@Target(ElementType.METHOD)
+@Retention(RetentionPolicy.RUNTIME)
+public @interface PhoneOnly {
+
+}
diff --git a/base/test/android/javatests/src/org/chromium/base/test/util/TabletOnly.java b/base/test/android/javatests/src/org/chromium/base/test/util/TabletOnly.java
new file mode 100644
index 0000000..36cdf81
--- /dev/null
+++ b/base/test/android/javatests/src/org/chromium/base/test/util/TabletOnly.java
@@ -0,0 +1,19 @@
+// Copyright (c) 2013 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.
+
+package org.chromium.base.test.util;
+
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+/**
+ * Annotation for specifying that the test should only be run on tablets.
+ */
+@Target(ElementType.METHOD)
+@Retention(RetentionPolicy.RUNTIME)
+public @interface TabletOnly {
+
+}
diff --git a/base/test/android/javatests/src/org/chromium/base/test/util/TimeoutScale.java b/base/test/android/javatests/src/org/chromium/base/test/util/TimeoutScale.java
new file mode 100644
index 0000000..a3b0641
--- /dev/null
+++ b/base/test/android/javatests/src/org/chromium/base/test/util/TimeoutScale.java
@@ -0,0 +1,22 @@
+// Copyright (c) 2012 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.
+
+package org.chromium.base.test.util;
+
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+/**
+ * This annotation can be used to scale a specific test timeout.
+ */
+@Target(ElementType.METHOD)
+@Retention(RetentionPolicy.RUNTIME)
+public @interface TimeoutScale {
+ /**
+ * @return A number to scale the test timeout.
+ */
+ public int value();
+}
diff --git a/base/data/file_util_unittest/binary_file.bin b/base/test/data/file_util/binary_file.bin
similarity index 100%
rename from base/data/file_util_unittest/binary_file.bin
rename to base/test/data/file_util/binary_file.bin
Binary files differ
diff --git a/base/data/file_util_unittest/binary_file_diff.bin b/base/test/data/file_util/binary_file_diff.bin
similarity index 100%
rename from base/data/file_util_unittest/binary_file_diff.bin
rename to base/test/data/file_util/binary_file_diff.bin
Binary files differ
diff --git a/base/data/file_util_unittest/binary_file_same.bin b/base/test/data/file_util/binary_file_same.bin
similarity index 100%
rename from base/data/file_util_unittest/binary_file_same.bin
rename to base/test/data/file_util/binary_file_same.bin
Binary files differ
diff --git a/base/data/file_util_unittest/blank_line.txt b/base/test/data/file_util/blank_line.txt
similarity index 100%
rename from base/data/file_util_unittest/blank_line.txt
rename to base/test/data/file_util/blank_line.txt
diff --git a/base/data/file_util_unittest/blank_line_crlf.txt b/base/test/data/file_util/blank_line_crlf.txt
similarity index 100%
rename from base/data/file_util_unittest/blank_line_crlf.txt
rename to base/test/data/file_util/blank_line_crlf.txt
diff --git a/base/data/file_util_unittest/crlf.txt b/base/test/data/file_util/crlf.txt
similarity index 100%
rename from base/data/file_util_unittest/crlf.txt
rename to base/test/data/file_util/crlf.txt
diff --git a/base/data/file_util_unittest/different.txt b/base/test/data/file_util/different.txt
similarity index 100%
rename from base/data/file_util_unittest/different.txt
rename to base/test/data/file_util/different.txt
diff --git a/base/data/file_util_unittest/different_first.txt b/base/test/data/file_util/different_first.txt
similarity index 100%
rename from base/data/file_util_unittest/different_first.txt
rename to base/test/data/file_util/different_first.txt
diff --git a/base/data/file_util_unittest/different_last.txt b/base/test/data/file_util/different_last.txt
similarity index 100%
rename from base/data/file_util_unittest/different_last.txt
rename to base/test/data/file_util/different_last.txt
diff --git a/base/data/file_util_unittest/empty1.txt b/base/test/data/file_util/empty1.txt
similarity index 100%
rename from base/data/file_util_unittest/empty1.txt
rename to base/test/data/file_util/empty1.txt
diff --git a/base/data/file_util_unittest/empty2.txt b/base/test/data/file_util/empty2.txt
similarity index 100%
rename from base/data/file_util_unittest/empty2.txt
rename to base/test/data/file_util/empty2.txt
diff --git a/base/data/file_util_unittest/first1.txt b/base/test/data/file_util/first1.txt
similarity index 100%
rename from base/data/file_util_unittest/first1.txt
rename to base/test/data/file_util/first1.txt
diff --git a/base/data/file_util_unittest/first2.txt b/base/test/data/file_util/first2.txt
similarity index 100%
rename from base/data/file_util_unittest/first2.txt
rename to base/test/data/file_util/first2.txt
diff --git a/base/data/file_util_unittest/original.txt b/base/test/data/file_util/original.txt
similarity index 100%
rename from base/data/file_util_unittest/original.txt
rename to base/test/data/file_util/original.txt
diff --git a/base/data/file_util_unittest/same.txt b/base/test/data/file_util/same.txt
similarity index 100%
rename from base/data/file_util_unittest/same.txt
rename to base/test/data/file_util/same.txt
diff --git a/base/data/file_util_unittest/same_length.txt b/base/test/data/file_util/same_length.txt
similarity index 100%
rename from base/data/file_util_unittest/same_length.txt
rename to base/test/data/file_util/same_length.txt
diff --git a/base/data/file_util_unittest/shortened.txt b/base/test/data/file_util/shortened.txt
similarity index 100%
rename from base/data/file_util_unittest/shortened.txt
rename to base/test/data/file_util/shortened.txt
diff --git a/base/data/json/bom_feff.json b/base/test/data/json/bom_feff.json
similarity index 100%
rename from base/data/json/bom_feff.json
rename to base/test/data/json/bom_feff.json
diff --git a/base/prefs/test/data/pref_service/invalid.json b/base/test/data/prefs/invalid.json
similarity index 100%
rename from base/prefs/test/data/pref_service/invalid.json
rename to base/test/data/prefs/invalid.json
diff --git a/base/prefs/test/data/pref_service/read.json b/base/test/data/prefs/read.json
similarity index 100%
rename from base/prefs/test/data/pref_service/read.json
rename to base/test/data/prefs/read.json
diff --git a/base/prefs/test/data/pref_service/read.need_empty_value.json b/base/test/data/prefs/read.need_empty_value.json
similarity index 100%
rename from base/prefs/test/data/pref_service/read.need_empty_value.json
rename to base/test/data/prefs/read.need_empty_value.json
diff --git a/base/prefs/test/data/pref_service/write.golden.json b/base/test/data/prefs/write.golden.json
similarity index 100%
rename from base/prefs/test/data/pref_service/write.golden.json
rename to base/test/data/prefs/write.golden.json
diff --git a/base/prefs/test/data/pref_service/write.golden.need_empty_value.json b/base/test/data/prefs/write.golden.need_empty_value.json
similarity index 100%
rename from base/prefs/test/data/pref_service/write.golden.need_empty_value.json
rename to base/test/data/prefs/write.golden.need_empty_value.json
diff --git a/base/test/data/serializer_nested_test.json b/base/test/data/serializer_nested_test.json
new file mode 100644
index 0000000..cfea8e8
--- /dev/null
+++ b/base/test/data/serializer_nested_test.json
@@ -0,0 +1,17 @@
+{
+ "bool": true,
+ "dict": {
+ "bool": true,
+ "dict": {
+ "bees": "knees",
+ "cats": "meow"
+ },
+ "foos": "bar",
+ "list": [ 3.4, "second", null ]
+ },
+ "int": 42,
+ "list": [ 1, 2 ],
+ "null": null,
+ "real": 3.14,
+ "string": "hello"
+}
diff --git a/base/test/data/serializer_test.json b/base/test/data/serializer_test.json
new file mode 100644
index 0000000..446925e
--- /dev/null
+++ b/base/test/data/serializer_test.json
@@ -0,0 +1,8 @@
+{
+ "bool": true,
+ "int": 42,
+ "list": [ 1, 2 ],
+ "null": null,
+ "real": 3.14,
+ "string": "hello"
+}
diff --git a/base/test/data/serializer_test_nowhitespace.json b/base/test/data/serializer_test_nowhitespace.json
new file mode 100644
index 0000000..a1afdc5
--- /dev/null
+++ b/base/test/data/serializer_test_nowhitespace.json
@@ -0,0 +1 @@
+{"bool":true,"int":42,"list":[1,2],"null":null,"real":3.14,"string":"hello"}
\ No newline at end of file
diff --git a/base/test/expectations/expectation.h b/base/test/expectations/expectation.h
index d86b08d..be5a9d7 100644
--- a/base/test/expectations/expectation.h
+++ b/base/test/expectations/expectation.h
@@ -10,7 +10,7 @@
#include "base/base_export.h"
#include "base/compiler_specific.h"
-#include "base/string_piece.h"
+#include "base/strings/string_piece.h"
namespace test_expectations {
diff --git a/base/test/expectations/parser.h b/base/test/expectations/parser.h
index 365943c..69a741a 100644
--- a/base/test/expectations/parser.h
+++ b/base/test/expectations/parser.h
@@ -8,7 +8,7 @@
#include <string>
#include "base/basictypes.h"
-#include "base/string_piece.h"
+#include "base/strings/string_piece.h"
#include "base/test/expectations/expectation.h"
namespace test_expectations {
diff --git a/base/test/sequenced_worker_pool_owner.cc b/base/test/sequenced_worker_pool_owner.cc
index afffe25..ea31441 100644
--- a/base/test/sequenced_worker_pool_owner.cc
+++ b/base/test/sequenced_worker_pool_owner.cc
@@ -13,9 +13,7 @@
size_t max_threads,
const std::string& thread_name_prefix)
: constructor_message_loop_(MessageLoop::current()),
- pool_(new SequencedWorkerPool(
- max_threads, thread_name_prefix,
- ALLOW_THIS_IN_INITIALIZER_LIST(this))),
+ pool_(new SequencedWorkerPool(max_threads, thread_name_prefix, this)),
has_work_call_count_(0) {}
SequencedWorkerPoolOwner::~SequencedWorkerPoolOwner() {
diff --git a/base/test/sequenced_worker_pool_owner.h b/base/test/sequenced_worker_pool_owner.h
index c6c8d67..1cc3fd6 100644
--- a/base/test/sequenced_worker_pool_owner.h
+++ b/base/test/sequenced_worker_pool_owner.h
@@ -15,10 +15,10 @@
#include "base/synchronization/lock.h"
#include "base/threading/sequenced_worker_pool.h"
-class MessageLoop;
-
namespace base {
+class MessageLoop;
+
// Wrapper around SequencedWorkerPool for testing that blocks destruction
// until the pool is actually destroyed. This is so that a
// SequencedWorkerPool from one test doesn't outlive its test and cause
diff --git a/base/test/test_file_util.cc b/base/test/test_file_util.cc
new file mode 100644
index 0000000..eef89de
--- /dev/null
+++ b/base/test/test_file_util.cc
@@ -0,0 +1,23 @@
+// Copyright (c) 2013 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/test/test_file_util.h"
+
+#include "base/test/test_timeouts.h"
+#include "base/threading/platform_thread.h"
+
+namespace base {
+
+bool EvictFileFromSystemCacheWithRetry(const FilePath& path) {
+ const int kCycles = 10;
+ const TimeDelta kDelay = TestTimeouts::action_timeout() / kCycles;
+ for (int i = 0; i < kCycles; i++) {
+ if (file_util::EvictFileFromSystemCache(path))
+ return true;
+ PlatformThread::Sleep(kDelay);
+ }
+ return false;
+}
+
+} // namespace base
diff --git a/base/test/test_file_util.h b/base/test/test_file_util.h
index 8d1be1c..418c480 100644
--- a/base/test/test_file_util.h
+++ b/base/test/test_file_util.h
@@ -13,9 +13,18 @@
#include "base/files/file_path.h"
namespace base {
-class FilePath;
-}
+class FilePath;
+
+// Clear a specific file from the system cache like EvictFileFromSystemCache,
+// but on failure it will sleep and retry. On the Windows buildbots, eviction
+// can fail if the file is marked in use, and this will throw off timings that
+// rely on uncached files.
+bool EvictFileFromSystemCacheWithRetry(const FilePath& file);
+
+} // namespace base
+
+// TODO(brettw) move all of this to the base namespace.
namespace file_util {
// Wrapper over file_util::Delete. On Windows repeatedly invokes Delete in case
@@ -27,15 +36,6 @@
// to access this file will result in a cold load from the hard drive.
bool EvictFileFromSystemCache(const base::FilePath& file);
-// Like CopyFileNoCache but recursively copies all files and subdirectories
-// in the given input directory to the output directory. Any files in the
-// destination that already exist will be overwritten.
-//
-// Returns true on success. False means there was some error copying, so the
-// state of the destination is unknown.
-bool CopyRecursiveDirNoCache(const base::FilePath& source_dir,
- const base::FilePath& dest_dir);
-
#if defined(OS_WIN)
// Returns true if the volume supports Alternate Data Streams.
bool VolumeSupportsADS(const base::FilePath& path);
diff --git a/base/test/test_file_util_posix.cc b/base/test/test_file_util_posix.cc
index 6be1c82..7c16cb1 100644
--- a/base/test/test_file_util_posix.cc
+++ b/base/test/test_file_util_posix.cc
@@ -17,6 +17,8 @@
#include "base/string_util.h"
#include "base/utf_string_conversions.h"
+using base::MakeAbsoluteFilePath;
+
namespace file_util {
namespace {
@@ -78,82 +80,6 @@
return file_util::Delete(file, recurse);
}
-// Mostly a verbatim copy of CopyDirectory
-bool CopyRecursiveDirNoCache(const base::FilePath& source_dir,
- const base::FilePath& dest_dir) {
- char top_dir[PATH_MAX];
- if (base::strlcpy(top_dir, source_dir.value().c_str(),
- arraysize(top_dir)) >= arraysize(top_dir)) {
- return false;
- }
-
- // This function does not properly handle destinations within the source
- base::FilePath real_to_path = dest_dir;
- if (PathExists(real_to_path)) {
- if (!AbsolutePath(&real_to_path))
- return false;
- } else {
- real_to_path = real_to_path.DirName();
- if (!AbsolutePath(&real_to_path))
- return false;
- }
- if (real_to_path.value().compare(0, source_dir.value().size(),
- source_dir.value()) == 0)
- return false;
-
- bool success = true;
- int traverse_type = FileEnumerator::FILES |
- FileEnumerator::SHOW_SYM_LINKS | FileEnumerator::DIRECTORIES;
- FileEnumerator traversal(source_dir, true, traverse_type);
-
- // dest_dir may not exist yet, start the loop with dest_dir
- FileEnumerator::FindInfo info;
- base::FilePath current = source_dir;
- if (stat(source_dir.value().c_str(), &info.stat) < 0) {
- DLOG(ERROR) << "CopyRecursiveDirNoCache() couldn't stat source directory: "
- << source_dir.value() << " errno = " << errno;
- success = false;
- }
-
- while (success && !current.empty()) {
- // |current| is the source path, including source_dir, so paste
- // the suffix after source_dir onto dest_dir to create the target_path.
- std::string suffix(¤t.value().c_str()[source_dir.value().size()]);
- // Strip the leading '/' (if any).
- if (!suffix.empty()) {
- DCHECK_EQ('/', suffix[0]);
- suffix.erase(0, 1);
- }
- const base::FilePath target_path = dest_dir.Append(suffix);
-
- if (S_ISDIR(info.stat.st_mode)) {
- if (mkdir(target_path.value().c_str(), info.stat.st_mode & 01777) != 0 &&
- errno != EEXIST) {
- DLOG(ERROR) << "CopyRecursiveDirNoCache() couldn't create directory: "
- << target_path.value() << " errno = " << errno;
- success = false;
- }
- } else if (S_ISREG(info.stat.st_mode)) {
- if (CopyFile(current, target_path)) {
- success = EvictFileFromSystemCache(target_path);
- DCHECK(success);
- } else {
- DLOG(ERROR) << "CopyRecursiveDirNoCache() couldn't create file: "
- << target_path.value();
- success = false;
- }
- } else {
- DLOG(WARNING) << "CopyRecursiveDirNoCache() skipping non-regular file: "
- << current.value();
- }
-
- current = traversal.Next();
- traversal.GetFindInfo(&info);
- }
-
- return success;
-}
-
#if !defined(OS_LINUX) && !defined(OS_MACOSX)
bool EvictFileFromSystemCache(const base::FilePath& file) {
// There doesn't seem to be a POSIX way to cool the disk cache.
diff --git a/base/test/test_file_util_win.cc b/base/test/test_file_util_win.cc
index 8d28aef..8e130d8 100644
--- a/base/test/test_file_util_win.cc
+++ b/base/test/test_file_util_win.cc
@@ -216,59 +216,6 @@
return true;
}
-// Like CopyFileNoCache but recursively copies all files and subdirectories
-// in the given input directory to the output directory.
-bool CopyRecursiveDirNoCache(const base::FilePath& source_dir,
- const base::FilePath& dest_dir) {
- // Try to create the directory if it doesn't already exist.
- if (!CreateDirectory(dest_dir)) {
- if (GetLastError() != ERROR_ALREADY_EXISTS)
- return false;
- }
-
- std::vector<std::wstring> files_copied;
-
- base::FilePath src(source_dir.AppendASCII("*"));
-
- WIN32_FIND_DATA fd;
- HANDLE fh = FindFirstFile(src.value().c_str(), &fd);
- if (fh == INVALID_HANDLE_VALUE)
- return false;
-
- do {
- std::wstring cur_file(fd.cFileName);
- if (cur_file == L"." || cur_file == L"..")
- continue; // Skip these special entries.
-
- base::FilePath cur_source_path = source_dir.Append(cur_file);
- base::FilePath cur_dest_path = dest_dir.Append(cur_file);
-
- if (fd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) {
- // Recursively copy a subdirectory. We stripped "." and ".." already.
- if (!CopyRecursiveDirNoCache(cur_source_path, cur_dest_path)) {
- FindClose(fh);
- return false;
- }
- } else {
- // Copy the file.
- if (!::CopyFile(cur_source_path.value().c_str(),
- cur_dest_path.value().c_str(), false)) {
- FindClose(fh);
- return false;
- }
-
- // We don't check for errors from this function, often, we are copying
- // files that are in the repository, and they will have read-only set.
- // This will prevent us from evicting from the cache, but these don't
- // matter anyway.
- EvictFileFromSystemCache(cur_dest_path);
- }
- } while (FindNextFile(fh, &fd));
-
- FindClose(fh);
- return true;
-}
-
// Checks if the volume supports Alternate Data Streams. This is required for
// the Zone Identifier implementation.
bool VolumeSupportsADS(const base::FilePath& path) {
diff --git a/base/test/test_support_ios.mm b/base/test/test_support_ios.mm
index 118ee32..cb07f00 100644
--- a/base/test/test_support_ios.mm
+++ b/base/test/test_support_ios.mm
@@ -55,7 +55,7 @@
// Add a label with the app name.
UILabel* label = [[[UILabel alloc] initWithFrame:bounds] autorelease];
label.text = [[NSProcessInfo processInfo] processName];
- label.textAlignment = UITextAlignmentCenter;
+ label.textAlignment = NSTextAlignmentCenter;
[window_ addSubview:label];
if ([self shouldRedirectOutputToFile])
diff --git a/base/test/test_timeouts.cc b/base/test/test_timeouts.cc
index 2c9e7de..e8e4153 100644
--- a/base/test/test_timeouts.cc
+++ b/base/test/test_timeouts.cc
@@ -11,7 +11,9 @@
namespace {
-#ifdef ADDRESS_SANITIZER
+// ASan and TSan instrument each memory access. This may slow the execution
+// down significantly.
+#if defined(ADDRESS_SANITIZER) || defined(THREAD_SANITIZER)
static const int kTimeoutMultiplier = 2;
#else
static const int kTimeoutMultiplier = 1;
diff --git a/base/test/trace_event_analyzer.cc b/base/test/trace_event_analyzer.cc
index 431945b..8457ce9 100644
--- a/base/test/trace_event_analyzer.cc
+++ b/base/test/trace_event_analyzer.cc
@@ -140,7 +140,7 @@
if (GetArgAsString(name, &arg_string))
return arg_string;
NOTREACHED();
- return "";
+ return std::string();
}
double TraceEvent::GetKnownArgAsDouble(const std::string& name) const {
diff --git a/base/test/trace_event_analyzer_unittest.cc b/base/test/trace_event_analyzer_unittest.cc
index 6004341..bb3e0fd 100644
--- a/base/test/trace_event_analyzer_unittest.cc
+++ b/base/test/trace_event_analyzer_unittest.cc
@@ -40,14 +40,12 @@
output_.json_output.clear();
buffer_.Start();
base::debug::TraceLog::GetInstance()->SetEnabled(
- true,
+ base::debug::CategoryFilter("*"),
base::debug::TraceLog::RECORD_UNTIL_FULL);
}
void TraceEventAnalyzerTest::EndTracing() {
- base::debug::TraceLog::GetInstance()->SetEnabled(
- false,
- base::debug::TraceLog::RECORD_UNTIL_FULL);
+ base::debug::TraceLog::GetInstance()->SetDisabled();
base::debug::TraceLog::GetInstance()->Flush(
base::Bind(&TraceEventAnalyzerTest::OnTraceDataCollected,
base::Unretained(this)));
@@ -208,10 +206,10 @@
BeginTracing();
{
- TRACE_EVENT_INSTANT1("cat1", "name1", "num", 1);
- TRACE_EVENT_INSTANT1("cat1", "name2", "num", 2);
- TRACE_EVENT_INSTANT1("cat2", "name3", "num", 3);
- TRACE_EVENT_INSTANT1("cat2", "name4", "num", 4);
+ TRACE_EVENT_INSTANT1("cat1", "name1", TRACE_EVENT_SCOPE_THREAD, "num", 1);
+ TRACE_EVENT_INSTANT1("cat1", "name2", TRACE_EVENT_SCOPE_THREAD, "num", 2);
+ TRACE_EVENT_INSTANT1("cat2", "name3", TRACE_EVENT_SCOPE_THREAD, "num", 3);
+ TRACE_EVENT_INSTANT1("cat2", "name4", TRACE_EVENT_SCOPE_THREAD, "num", 4);
}
EndTracing();
@@ -293,11 +291,15 @@
BeginTracing();
{
// These events are searched for:
- TRACE_EVENT_INSTANT2("cat1", "math1", "a", 10, "b", 5);
- TRACE_EVENT_INSTANT2("cat1", "math2", "a", 10, "b", 10);
+ TRACE_EVENT_INSTANT2("cat1", "math1", TRACE_EVENT_SCOPE_THREAD,
+ "a", 10, "b", 5);
+ TRACE_EVENT_INSTANT2("cat1", "math2", TRACE_EVENT_SCOPE_THREAD,
+ "a", 10, "b", 10);
// Extra events that never match, for noise:
- TRACE_EVENT_INSTANT2("noise", "math3", "a", 1, "b", 3);
- TRACE_EVENT_INSTANT2("noise", "math4", "c", 10, "d", 5);
+ TRACE_EVENT_INSTANT2("noise", "math3", TRACE_EVENT_SCOPE_THREAD,
+ "a", 1, "b", 3);
+ TRACE_EVENT_INSTANT2("noise", "math4", TRACE_EVENT_SCOPE_THREAD,
+ "c", 10, "d", 5);
}
EndTracing();
@@ -349,10 +351,10 @@
BeginTracing();
{
- TRACE_EVENT_INSTANT0("cat1", "name1");
- TRACE_EVENT_INSTANT0("cat1", "name2");
- TRACE_EVENT_INSTANT0("cat1", "no match");
- TRACE_EVENT_INSTANT0("cat1", "name3x");
+ TRACE_EVENT_INSTANT0("cat1", "name1", TRACE_EVENT_SCOPE_THREAD);
+ TRACE_EVENT_INSTANT0("cat1", "name2", TRACE_EVENT_SCOPE_THREAD);
+ TRACE_EVENT_INSTANT0("cat1", "no match", TRACE_EVENT_SCOPE_THREAD);
+ TRACE_EVENT_INSTANT0("cat1", "name3x", TRACE_EVENT_SCOPE_THREAD);
}
EndTracing();
@@ -393,7 +395,8 @@
TRACE_EVENT0("noise", "name2"); // not searched for, just noise
{
TRACE_EVENT0("cat2", "name3"); // found by duration query
- TRACE_EVENT_INSTANT0("noise", "name4"); // not searched for, just noise
+ // next event not searched for, just noise
+ TRACE_EVENT_INSTANT0("noise", "name4", TRACE_EVENT_SCOPE_THREAD);
base::debug::HighResSleepForTraceTest(kSleepTime);
TRACE_EVENT0("cat2", "name5"); // not found (duration too short)
}
@@ -426,7 +429,7 @@
{
TRACE_EVENT_END0("cat1", "name1"); // does not match out of order begin
TRACE_EVENT0("cat1", "name2");
- TRACE_EVENT_INSTANT0("cat1", "name3");
+ TRACE_EVENT_INSTANT0("cat1", "name3", TRACE_EVENT_SCOPE_THREAD);
TRACE_EVENT_BEGIN0("cat1", "name1");
}
EndTracing();
@@ -479,7 +482,7 @@
TRACE_EVENT_ASYNC_END0("cat1", "name1", 0xA); // no match / out of order
TRACE_EVENT_ASYNC_BEGIN0("cat1", "name1", 0xB);
TRACE_EVENT_ASYNC_BEGIN0("cat1", "name1", 0xC);
- TRACE_EVENT_INSTANT0("cat1", "name1"); // noise
+ TRACE_EVENT_INSTANT0("cat1", "name1", TRACE_EVENT_SCOPE_THREAD); // noise
TRACE_EVENT0("cat1", "name1"); // noise
TRACE_EVENT_ASYNC_END0("cat1", "name1", 0xB);
TRACE_EVENT_ASYNC_END0("cat1", "name1", 0xC);
@@ -495,8 +498,8 @@
TraceEventVector found;
analyzer->FindEvents(Query::MatchAsyncBeginWithNext(), &found);
ASSERT_EQ(2u, found.size());
- EXPECT_STRCASEEQ("B", found[0]->id.c_str());
- EXPECT_STRCASEEQ("C", found[1]->id.c_str());
+ EXPECT_STRCASEEQ("0xb", found[0]->id.c_str());
+ EXPECT_STRCASEEQ("0xc", found[1]->id.c_str());
}
// Test AssociateAsyncBeginEndEvents
@@ -528,13 +531,13 @@
analyzer->FindEvents(Query::MatchAsyncBeginWithNext(), &found);
ASSERT_EQ(3u, found.size());
- EXPECT_STRCASEEQ("B", found[0]->id.c_str());
+ EXPECT_STRCASEEQ("0xb", found[0]->id.c_str());
EXPECT_EQ(TRACE_EVENT_PHASE_ASYNC_STEP, found[0]->other_event->phase);
EXPECT_TRUE(found[0]->other_event->other_event);
EXPECT_EQ(TRACE_EVENT_PHASE_ASYNC_END,
found[0]->other_event->other_event->phase);
- EXPECT_STRCASEEQ("C", found[1]->id.c_str());
+ EXPECT_STRCASEEQ("0xc", found[1]->id.c_str());
EXPECT_EQ(TRACE_EVENT_PHASE_ASYNC_STEP, found[1]->other_event->phase);
EXPECT_TRUE(found[1]->other_event->other_event);
EXPECT_EQ(TRACE_EVENT_PHASE_ASYNC_STEP,
@@ -547,7 +550,7 @@
EXPECT_EQ(TRACE_EVENT_PHASE_ASYNC_END,
found[1]->other_event->other_event->other_event->phase);
- EXPECT_STRCASEEQ("A", found[2]->id.c_str());
+ EXPECT_STRCASEEQ("0xa", found[2]->id.c_str());
EXPECT_EQ(TRACE_EVENT_PHASE_ASYNC_STEP, found[2]->other_event->phase);
}
@@ -559,12 +562,16 @@
// to match up the begin/end pairs.
BeginTracing();
{
- TRACE_EVENT_INSTANT1("cat1", "end", "id", 1); // no begin match
- TRACE_EVENT_INSTANT1("cat2", "begin", "id", 2); // end is cat4
- TRACE_EVENT_INSTANT1("cat3", "begin", "id", 3); // end is cat5
- TRACE_EVENT_INSTANT1("cat4", "end", "id", 2);
- TRACE_EVENT_INSTANT1("cat5", "end", "id", 3);
- TRACE_EVENT_INSTANT1("cat6", "begin", "id", 1); // no end match
+ // no begin match
+ TRACE_EVENT_INSTANT1("cat1", "end", TRACE_EVENT_SCOPE_THREAD, "id", 1);
+ // end is cat4
+ TRACE_EVENT_INSTANT1("cat2", "begin", TRACE_EVENT_SCOPE_THREAD, "id", 2);
+ // end is cat5
+ TRACE_EVENT_INSTANT1("cat3", "begin", TRACE_EVENT_SCOPE_THREAD, "id", 3);
+ TRACE_EVENT_INSTANT1("cat4", "end", TRACE_EVENT_SCOPE_THREAD, "id", 2);
+ TRACE_EVENT_INSTANT1("cat5", "end", TRACE_EVENT_SCOPE_THREAD, "id", 3);
+ // no end match
+ TRACE_EVENT_INSTANT1("cat6", "begin", TRACE_EVENT_SCOPE_THREAD, "id", 1);
}
EndTracing();
@@ -777,7 +784,7 @@
events[0].name = "one";
events[2].name = "two";
events[4].name = "three";
- Query query_named = Query::EventName() != Query::String("");
+ Query query_named = Query::EventName() != Query::String(std::string());
Query query_one = Query::EventName() == Query::String("one");
// Only one event matches query_one, so two closest can't be found.
@@ -813,7 +820,7 @@
events[0].name = "one";
events[2].name = "two";
events[4].name = "three";
- Query query_named = Query::EventName() != Query::String("");
+ Query query_named = Query::EventName() != Query::String(std::string());
Query query_one = Query::EventName() == Query::String("one");
EXPECT_EQ(0u, CountMatches(event_ptrs, Query::Bool(false)));
diff --git a/base/test/values_test_util.h b/base/test/values_test_util.h
index ef4710d..86d91c3 100644
--- a/base/test/values_test_util.h
+++ b/base/test/values_test_util.h
@@ -8,7 +8,7 @@
#include <string>
#include "base/memory/scoped_ptr.h"
-#include "base/string_piece.h"
+#include "base/strings/string_piece.h"
namespace base {
class DictionaryValue;
diff --git a/base/third_party/dynamic_annotations/dynamic_annotations.target.darwin-arm.mk b/base/third_party/dynamic_annotations/dynamic_annotations.target.darwin-arm.mk
new file mode 100644
index 0000000..066328c
--- /dev/null
+++ b/base/third_party/dynamic_annotations/dynamic_annotations.target.darwin-arm.mk
@@ -0,0 +1,146 @@
+# This file is generated by gyp; do not edit.
+
+include $(CLEAR_VARS)
+
+LOCAL_MODULE_CLASS := STATIC_LIBRARIES
+LOCAL_MODULE := base_third_party_dynamic_annotations_dynamic_annotations_gyp
+LOCAL_MODULE_SUFFIX := .a
+LOCAL_MODULE_TAGS := optional
+gyp_intermediate_dir := $(call local-intermediates-dir)
+gyp_shared_intermediate_dir := $(call intermediates-dir-for,GYP,shared)
+
+# Make sure our deps are built first.
+GYP_TARGET_DEPENDENCIES :=
+
+GYP_GENERATED_OUTPUTS :=
+
+# Make sure our deps and generated files are built first.
+LOCAL_ADDITIONAL_DEPENDENCIES := $(GYP_TARGET_DEPENDENCIES) $(GYP_GENERATED_OUTPUTS)
+
+LOCAL_GENERATED_SOURCES :=
+
+GYP_COPIED_SOURCE_ORIGIN_DIRS :=
+
+LOCAL_SRC_FILES := \
+ base/third_party/dynamic_annotations/dynamic_annotations.c
+
+
+# Flags passed to both C and C++ files.
+MY_CFLAGS := \
+ -fstack-protector \
+ --param=ssp-buffer-size=4 \
+ -fno-exceptions \
+ -fno-strict-aliasing \
+ -Wno-unused-parameter \
+ -Wno-missing-field-initializers \
+ -fvisibility=hidden \
+ -pipe \
+ -fPIC \
+ -Wno-format \
+ -fno-tree-sra \
+ -fuse-ld=gold \
+ -Wno-psabi \
+ -ffunction-sections \
+ -funwind-tables \
+ -g \
+ -fstack-protector \
+ -fno-short-enums \
+ -finline-limit=64 \
+ -Wa,--noexecstack \
+ -U_FORTIFY_SOURCE \
+ -Wno-extra \
+ -Wno-ignored-qualifiers \
+ -Wno-type-limits \
+ -Wno-address \
+ -Wno-format-security \
+ -Wno-return-type \
+ -Wno-sequence-point \
+ -Os \
+ -g \
+ -fomit-frame-pointer \
+ -fdata-sections \
+ -ffunction-sections
+
+MY_CFLAGS_C :=
+
+MY_DEFS := \
+ '-D_FILE_OFFSET_BITS=64' \
+ '-DUSE_LINUX_BREAKPAD' \
+ '-DNO_TCMALLOC' \
+ '-DDISABLE_NACL' \
+ '-DCHROMIUM_BUILD' \
+ '-DUSE_LIBJPEG_TURBO=1' \
+ '-DUSE_PROPRIETARY_CODECS' \
+ '-DENABLE_GPU=1' \
+ '-DUSE_OPENSSL=1' \
+ '-DENABLE_EGLIMAGE=1' \
+ '-DENABLE_LANGUAGE_DETECTION=1' \
+ '-DANDROID' \
+ '-D__GNU_SOURCE=1' \
+ '-DUSE_STLPORT=1' \
+ '-D_STLP_USE_PTR_SPECIALIZATIONS=1' \
+ '-DCHROME_BUILD_ID=""' \
+ '-DDYNAMIC_ANNOTATIONS_ENABLED=1' \
+ '-DWTF_USE_DYNAMIC_ANNOTATIONS=1' \
+ '-D_DEBUG'
+
+LOCAL_CFLAGS := $(MY_CFLAGS_C) $(MY_CFLAGS) $(MY_DEFS)
+
+# Include paths placed before CFLAGS/CPPFLAGS
+LOCAL_C_INCLUDES := \
+ $(LOCAL_PATH) \
+ $(GYP_ABS_ANDROID_TOP_DIR)/frameworks/wilhelm/include \
+ $(GYP_ABS_ANDROID_TOP_DIR)/bionic \
+ $(GYP_ABS_ANDROID_TOP_DIR)/external/stlport/stlport
+
+LOCAL_C_INCLUDES := $(GYP_COPIED_SOURCE_ORIGIN_DIRS) $(LOCAL_C_INCLUDES)
+
+# Flags passed to only C++ (and not C) files.
+LOCAL_CPPFLAGS := \
+ -fno-rtti \
+ -fno-threadsafe-statics \
+ -fvisibility-inlines-hidden \
+ -Wno-deprecated \
+ -Wno-abi \
+ -Wno-error=c++0x-compat \
+ -Wno-non-virtual-dtor \
+ -Wno-sign-promo \
+ -Wno-non-virtual-dtor
+
+### Rules for final target.
+
+LOCAL_LDFLAGS := \
+ -Wl,-z,now \
+ -Wl,-z,relro \
+ -Wl,-z,noexecstack \
+ -fPIC \
+ -Wl,-z,relro \
+ -Wl,-z,now \
+ -fuse-ld=gold \
+ -nostdlib \
+ -Wl,--no-undefined \
+ -Wl,--exclude-libs=ALL \
+ -Wl,--icf=safe \
+ -Wl,--gc-sections \
+ -Wl,-O1 \
+ -Wl,--as-needed
+
+
+LOCAL_STATIC_LIBRARIES :=
+
+# Enable grouping to fix circular references
+LOCAL_GROUP_STATIC_LIBRARIES := true
+
+LOCAL_SHARED_LIBRARIES := \
+ libstlport \
+ libdl
+
+# Add target alias to "gyp_all_modules" target.
+.PHONY: gyp_all_modules
+gyp_all_modules: base_third_party_dynamic_annotations_dynamic_annotations_gyp
+
+# Alias gyp target name.
+.PHONY: dynamic_annotations
+dynamic_annotations: base_third_party_dynamic_annotations_dynamic_annotations_gyp
+
+include $(BUILD_STATIC_LIBRARY)
diff --git a/base/third_party/dynamic_annotations/dynamic_annotations.target.darwin-x86.mk b/base/third_party/dynamic_annotations/dynamic_annotations.target.darwin-x86.mk
new file mode 100644
index 0000000..97c6cd8
--- /dev/null
+++ b/base/third_party/dynamic_annotations/dynamic_annotations.target.darwin-x86.mk
@@ -0,0 +1,145 @@
+# This file is generated by gyp; do not edit.
+
+include $(CLEAR_VARS)
+
+LOCAL_MODULE_CLASS := STATIC_LIBRARIES
+LOCAL_MODULE := base_third_party_dynamic_annotations_dynamic_annotations_gyp
+LOCAL_MODULE_SUFFIX := .a
+LOCAL_MODULE_TAGS := optional
+gyp_intermediate_dir := $(call local-intermediates-dir)
+gyp_shared_intermediate_dir := $(call intermediates-dir-for,GYP,shared)
+
+# Make sure our deps are built first.
+GYP_TARGET_DEPENDENCIES :=
+
+GYP_GENERATED_OUTPUTS :=
+
+# Make sure our deps and generated files are built first.
+LOCAL_ADDITIONAL_DEPENDENCIES := $(GYP_TARGET_DEPENDENCIES) $(GYP_GENERATED_OUTPUTS)
+
+LOCAL_GENERATED_SOURCES :=
+
+GYP_COPIED_SOURCE_ORIGIN_DIRS :=
+
+LOCAL_SRC_FILES := \
+ base/third_party/dynamic_annotations/dynamic_annotations.c
+
+
+# Flags passed to both C and C++ files.
+MY_CFLAGS := \
+ --param=ssp-buffer-size=4 \
+ -fno-exceptions \
+ -fno-strict-aliasing \
+ -Wno-unused-parameter \
+ -Wno-missing-field-initializers \
+ -fvisibility=hidden \
+ -pipe \
+ -fPIC \
+ -Wno-format \
+ -m32 \
+ -mmmx \
+ -march=pentium4 \
+ -msse2 \
+ -mfpmath=sse \
+ -fuse-ld=gold \
+ -ffunction-sections \
+ -funwind-tables \
+ -g \
+ -fno-short-enums \
+ -finline-limit=64 \
+ -Wa,--noexecstack \
+ -U_FORTIFY_SOURCE \
+ -Wno-extra \
+ -Wno-ignored-qualifiers \
+ -Wno-type-limits \
+ -Wno-address \
+ -Wno-format-security \
+ -Wno-return-type \
+ -Wno-sequence-point \
+ -fno-stack-protector \
+ -Os \
+ -g \
+ -fomit-frame-pointer \
+ -fdata-sections \
+ -ffunction-sections
+
+MY_CFLAGS_C :=
+
+MY_DEFS := \
+ '-D_FILE_OFFSET_BITS=64' \
+ '-DUSE_LINUX_BREAKPAD' \
+ '-DNO_TCMALLOC' \
+ '-DDISABLE_NACL' \
+ '-DCHROMIUM_BUILD' \
+ '-DUSE_LIBJPEG_TURBO=1' \
+ '-DUSE_PROPRIETARY_CODECS' \
+ '-DENABLE_GPU=1' \
+ '-DUSE_OPENSSL=1' \
+ '-DENABLE_EGLIMAGE=1' \
+ '-DENABLE_LANGUAGE_DETECTION=1' \
+ '-DANDROID' \
+ '-D__GNU_SOURCE=1' \
+ '-DUSE_STLPORT=1' \
+ '-D_STLP_USE_PTR_SPECIALIZATIONS=1' \
+ '-DCHROME_BUILD_ID=""' \
+ '-DDYNAMIC_ANNOTATIONS_ENABLED=1' \
+ '-DWTF_USE_DYNAMIC_ANNOTATIONS=1' \
+ '-D_DEBUG'
+
+LOCAL_CFLAGS := $(MY_CFLAGS_C) $(MY_CFLAGS) $(MY_DEFS)
+
+# Include paths placed before CFLAGS/CPPFLAGS
+LOCAL_C_INCLUDES := \
+ $(LOCAL_PATH) \
+ $(GYP_ABS_ANDROID_TOP_DIR)/frameworks/wilhelm/include \
+ $(GYP_ABS_ANDROID_TOP_DIR)/bionic \
+ $(GYP_ABS_ANDROID_TOP_DIR)/external/stlport/stlport
+
+LOCAL_C_INCLUDES := $(GYP_COPIED_SOURCE_ORIGIN_DIRS) $(LOCAL_C_INCLUDES)
+
+# Flags passed to only C++ (and not C) files.
+LOCAL_CPPFLAGS := \
+ -fno-rtti \
+ -fno-threadsafe-statics \
+ -fvisibility-inlines-hidden \
+ -Wno-deprecated \
+ -Wno-error=c++0x-compat \
+ -Wno-non-virtual-dtor \
+ -Wno-sign-promo \
+ -Wno-non-virtual-dtor
+
+### Rules for final target.
+
+LOCAL_LDFLAGS := \
+ -Wl,-z,now \
+ -Wl,-z,relro \
+ -Wl,-z,noexecstack \
+ -fPIC \
+ -m32 \
+ -fuse-ld=gold \
+ -nostdlib \
+ -Wl,--no-undefined \
+ -Wl,--exclude-libs=ALL \
+ -Wl,--gc-sections \
+ -Wl,-O1 \
+ -Wl,--as-needed
+
+
+LOCAL_STATIC_LIBRARIES :=
+
+# Enable grouping to fix circular references
+LOCAL_GROUP_STATIC_LIBRARIES := true
+
+LOCAL_SHARED_LIBRARIES := \
+ libstlport \
+ libdl
+
+# Add target alias to "gyp_all_modules" target.
+.PHONY: gyp_all_modules
+gyp_all_modules: base_third_party_dynamic_annotations_dynamic_annotations_gyp
+
+# Alias gyp target name.
+.PHONY: dynamic_annotations
+dynamic_annotations: base_third_party_dynamic_annotations_dynamic_annotations_gyp
+
+include $(BUILD_STATIC_LIBRARY)
diff --git a/base/third_party/dynamic_annotations/dynamic_annotations.target.linux-arm.mk b/base/third_party/dynamic_annotations/dynamic_annotations.target.linux-arm.mk
index b815f1e..066328c 100644
--- a/base/third_party/dynamic_annotations/dynamic_annotations.target.linux-arm.mk
+++ b/base/third_party/dynamic_annotations/dynamic_annotations.target.linux-arm.mk
@@ -64,7 +64,6 @@
MY_CFLAGS_C :=
MY_DEFS := \
- '-DUSE_SKIA' \
'-D_FILE_OFFSET_BITS=64' \
'-DUSE_LINUX_BREAKPAD' \
'-DNO_TCMALLOC' \
@@ -72,7 +71,6 @@
'-DCHROMIUM_BUILD' \
'-DUSE_LIBJPEG_TURBO=1' \
'-DUSE_PROPRIETARY_CODECS' \
- '-DENABLE_PEPPER_THREADING' \
'-DENABLE_GPU=1' \
'-DUSE_OPENSSL=1' \
'-DENABLE_EGLIMAGE=1' \
@@ -123,9 +121,9 @@
-Wl,--no-undefined \
-Wl,--exclude-libs=ALL \
-Wl,--icf=safe \
+ -Wl,--gc-sections \
-Wl,-O1 \
- -Wl,--as-needed \
- -Wl,--gc-sections
+ -Wl,--as-needed
LOCAL_STATIC_LIBRARIES :=
diff --git a/base/third_party/dynamic_annotations/dynamic_annotations.target.linux-x86.mk b/base/third_party/dynamic_annotations/dynamic_annotations.target.linux-x86.mk
index 9514262..97c6cd8 100644
--- a/base/third_party/dynamic_annotations/dynamic_annotations.target.linux-x86.mk
+++ b/base/third_party/dynamic_annotations/dynamic_annotations.target.linux-x86.mk
@@ -41,6 +41,7 @@
-march=pentium4 \
-msse2 \
-mfpmath=sse \
+ -fuse-ld=gold \
-ffunction-sections \
-funwind-tables \
-g \
@@ -65,7 +66,6 @@
MY_CFLAGS_C :=
MY_DEFS := \
- '-DUSE_SKIA' \
'-D_FILE_OFFSET_BITS=64' \
'-DUSE_LINUX_BREAKPAD' \
'-DNO_TCMALLOC' \
@@ -73,7 +73,6 @@
'-DCHROMIUM_BUILD' \
'-DUSE_LIBJPEG_TURBO=1' \
'-DUSE_PROPRIETARY_CODECS' \
- '-DENABLE_PEPPER_THREADING' \
'-DENABLE_GPU=1' \
'-DUSE_OPENSSL=1' \
'-DENABLE_EGLIMAGE=1' \
@@ -117,12 +116,13 @@
-Wl,-z,noexecstack \
-fPIC \
-m32 \
+ -fuse-ld=gold \
-nostdlib \
-Wl,--no-undefined \
-Wl,--exclude-libs=ALL \
+ -Wl,--gc-sections \
-Wl,-O1 \
- -Wl,--as-needed \
- -Wl,--gc-sections
+ -Wl,--as-needed
LOCAL_STATIC_LIBRARIES :=
diff --git a/base/thread_task_runner_handle.cc b/base/thread_task_runner_handle.cc
index d1b07aa..860a0ec 100644
--- a/base/thread_task_runner_handle.cc
+++ b/base/thread_task_runner_handle.cc
@@ -24,6 +24,11 @@
return current->task_runner_;
}
+// static
+bool ThreadTaskRunnerHandle::IsSet() {
+ return lazy_tls_ptr.Pointer()->Get() != NULL;
+}
+
ThreadTaskRunnerHandle::ThreadTaskRunnerHandle(
const scoped_refptr<SingleThreadTaskRunner>& task_runner)
: task_runner_(task_runner) {
diff --git a/base/thread_task_runner_handle.h b/base/thread_task_runner_handle.h
index 348c071..238435f 100644
--- a/base/thread_task_runner_handle.h
+++ b/base/thread_task_runner_handle.h
@@ -12,16 +12,21 @@
class SingleThreadTaskRunner;
-// ThreadTaskRunnerHandle stores a reference to the main task runner
-// for each thread. Not more than one of these objects can be created
-// per thread. After an instance of this object is created the Get()
-// function will return the |task_runner| specified in the
-// constructor.
+// ThreadTaskRunnerHandle stores a reference to a thread's TaskRunner
+// in thread-local storage. Callers can then retrieve the TaskRunner
+// for the current thread by calling ThreadTaskRunnerHandle::Get().
+// At most one TaskRunner may be bound to each thread at a time.
class BASE_EXPORT ThreadTaskRunnerHandle {
public:
// Gets the SingleThreadTaskRunner for the current thread.
static scoped_refptr<SingleThreadTaskRunner> Get();
+ // Returns true if the SingleThreadTaskRunner is already created for
+ // the current thread.
+ static bool IsSet();
+
+ // Binds |task_runner| to the current thread. |task_runner| must belong
+ // to the current thread for this to succeed.
explicit ThreadTaskRunnerHandle(
const scoped_refptr<SingleThreadTaskRunner>& task_runner);
~ThreadTaskRunnerHandle();
diff --git a/base/threading/platform_thread_posix.cc b/base/threading/platform_thread_posix.cc
index 0fb2a8a..43e58b7 100644
--- a/base/threading/platform_thread_posix.cc
+++ b/base/threading/platform_thread_posix.cc
@@ -34,11 +34,6 @@
#include "jni/ThreadUtils_jni.h"
#endif
-// TODO(bbudge) Use time.h when NaCl toolchain supports _POSIX_TIMERS
-#if defined(OS_NACL)
-#include <sys/nacl_syscalls.h>
-#endif
-
namespace base {
#if defined(OS_MACOSX)
diff --git a/base/threading/sequenced_worker_pool.cc b/base/threading/sequenced_worker_pool.cc
index f89a582..e35242e 100644
--- a/base/threading/sequenced_worker_pool.cc
+++ b/base/threading/sequenced_worker_pool.cc
@@ -1094,8 +1094,7 @@
size_t max_threads,
const std::string& thread_name_prefix)
: constructor_message_loop_(MessageLoopProxy::current()),
- inner_(new Inner(ALLOW_THIS_IN_INITIALIZER_LIST(this),
- max_threads, thread_name_prefix, NULL)) {
+ inner_(new Inner(this, max_threads, thread_name_prefix, NULL)) {
}
SequencedWorkerPool::SequencedWorkerPool(
@@ -1103,8 +1102,7 @@
const std::string& thread_name_prefix,
TestingObserver* observer)
: constructor_message_loop_(MessageLoopProxy::current()),
- inner_(new Inner(ALLOW_THIS_IN_INITIALIZER_LIST(this),
- max_threads, thread_name_prefix, observer)) {
+ inner_(new Inner(this, max_threads, thread_name_prefix, observer)) {
}
SequencedWorkerPool::~SequencedWorkerPool() {}
diff --git a/base/threading/sequenced_worker_pool.h b/base/threading/sequenced_worker_pool.h
index a96cd76..7e04b07 100644
--- a/base/threading/sequenced_worker_pool.h
+++ b/base/threading/sequenced_worker_pool.h
@@ -57,10 +57,10 @@
// These will be executed in an unspecified order. The order of execution
// between tasks with different sequence tokens is also unspecified.
//
-// This class is designed to be leaked on shutdown to allow the
-// CONTINUE_ON_SHUTDOWN behavior to be implemented. To enforce the
-// BLOCK_SHUTDOWN behavior, you must call Shutdown() which will wait until
-// the necessary tasks have completed.
+// This class may be leaked on shutdown to facilitate fast shutdown. The
+// expected usage, however, is to call Shutdown(), which correctly accounts
+// for CONTINUE_ON_SHUTDOWN behavior and is required for BLOCK_SHUTDOWN
+// behavior.
//
// Implementation note: This does not use a base::WorkerPool since that does
// not enforce shutdown semantics or allow us to specify how many worker
diff --git a/base/threading/sequenced_worker_pool_unittest.cc b/base/threading/sequenced_worker_pool_unittest.cc
index f0caf1a..95e4f11 100644
--- a/base/threading/sequenced_worker_pool_unittest.cc
+++ b/base/threading/sequenced_worker_pool_unittest.cc
@@ -28,7 +28,7 @@
// IMPORTANT NOTE:
//
// Many of these tests have failure modes where they'll hang forever. These
-// tests should not be flaky, and hangling indicates a type of failure. Do not
+// tests should not be flaky, and hanging indicates a type of failure. Do not
// mark as flaky if they're hanging, it's likely an actual bug.
namespace {
@@ -781,7 +781,7 @@
true));
// We expect all except the delayed task to have been run. We verify all
- // closures have been deleted deleted by looking at the refcount of the
+ // closures have been deleted by looking at the refcount of the
// tracker.
EXPECT_FALSE(tracker()->HasOneRef());
pool()->FlushForTesting();
@@ -798,6 +798,18 @@
pool()->FlushForTesting();
}
+TEST(SequencedWorkerPoolRefPtrTest, ShutsDownCleanWithContinueOnShutdown) {
+ MessageLoop loop;
+ scoped_refptr<SequencedWorkerPool> pool(new SequencedWorkerPool(3, "Pool"));
+ scoped_refptr<SequencedTaskRunner> task_runner =
+ pool->GetSequencedTaskRunnerWithShutdownBehavior(
+ pool->GetSequenceToken(),
+ base::SequencedWorkerPool::CONTINUE_ON_SHUTDOWN);
+
+ // Upon test exit, should shut down without hanging.
+ pool->Shutdown();
+}
+
class SequencedWorkerPoolTaskRunnerTestDelegate {
public:
SequencedWorkerPoolTaskRunnerTestDelegate() {}
diff --git a/base/threading/watchdog.cc b/base/threading/watchdog.cc
index d060655..a18efec 100644
--- a/base/threading/watchdog.cc
+++ b/base/threading/watchdog.cc
@@ -41,7 +41,7 @@
state_(DISARMED),
duration_(duration),
thread_watched_name_(thread_watched_name),
- ALLOW_THIS_IN_INITIALIZER_LIST(delegate_(this)) {
+ delegate_(this) {
if (!enabled_)
return; // Don't start thread, or doing anything really.
enabled_ = PlatformThread::Create(0, // Default stack size.
diff --git a/base/timer.h b/base/timer.h
index 95cae12..bbcbae2 100644
--- a/base/timer.h
+++ b/base/timer.h
@@ -56,11 +56,10 @@
#include "base/location.h"
#include "base/time.h"
-class MessageLoop;
-
namespace base {
class BaseTimerTaskInternal;
+class MessageLoop;
//-----------------------------------------------------------------------------
// This class wraps MessageLoop::PostDelayedTask to manage delayed and repeating
diff --git a/base/utf_string_conversions.h b/base/utf_string_conversions.h
index 5a391fa..284f45c 100644
--- a/base/utf_string_conversions.h
+++ b/base/utf_string_conversions.h
@@ -2,57 +2,5 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-#ifndef BASE_UTF_STRING_CONVERSIONS_H_
-#define BASE_UTF_STRING_CONVERSIONS_H_
-
-#include <string>
-
-#include "base/base_export.h"
-#include "base/string16.h"
-#include "base/string_piece.h"
-
-// These convert between UTF-8, -16, and -32 strings. They are potentially slow,
-// so avoid unnecessary conversions. The low-level versions return a boolean
-// indicating whether the conversion was 100% valid. In this case, it will still
-// do the best it can and put the result in the output buffer. The versions that
-// return strings ignore this error and just return the best conversion
-// possible.
-BASE_EXPORT bool WideToUTF8(const wchar_t* src, size_t src_len,
- std::string* output);
-BASE_EXPORT std::string WideToUTF8(const std::wstring& wide);
-BASE_EXPORT bool UTF8ToWide(const char* src, size_t src_len,
- std::wstring* output);
-BASE_EXPORT std::wstring UTF8ToWide(const base::StringPiece& utf8);
-
-BASE_EXPORT bool WideToUTF16(const wchar_t* src, size_t src_len,
- string16* output);
-BASE_EXPORT string16 WideToUTF16(const std::wstring& wide);
-BASE_EXPORT bool UTF16ToWide(const char16* src, size_t src_len,
- std::wstring* output);
-BASE_EXPORT std::wstring UTF16ToWide(const string16& utf16);
-
-BASE_EXPORT bool UTF8ToUTF16(const char* src, size_t src_len, string16* output);
-BASE_EXPORT string16 UTF8ToUTF16(const base::StringPiece& utf8);
-BASE_EXPORT bool UTF16ToUTF8(const char16* src, size_t src_len,
- std::string* output);
-BASE_EXPORT std::string UTF16ToUTF8(const string16& utf16);
-
-// We are trying to get rid of wstring as much as possible, but it's too big
-// a mess to do it all at once. These conversions should be used when we
-// really should just be passing a string16 around, but we haven't finished
-// porting whatever module uses wstring and the conversion is being used as a
-// stopcock. This makes it easy to grep for the ones that should be removed.
-#if defined(OS_WIN)
-# define WideToUTF16Hack
-# define UTF16ToWideHack
-#else
-# define WideToUTF16Hack WideToUTF16
-# define UTF16ToWideHack UTF16ToWide
-#endif
-
-// These convert an ASCII string, typically a hardcoded constant, to a
-// UTF16/Wide string.
-BASE_EXPORT std::wstring ASCIIToWide(const base::StringPiece& ascii);
-BASE_EXPORT string16 ASCIIToUTF16(const base::StringPiece& ascii);
-
-#endif // BASE_UTF_STRING_CONVERSIONS_H_
+// TODO(brettw) remove this header once all callers are fixed up.
+#include "base/strings/utf_string_conversions.h"
diff --git a/base/values.h b/base/values.h
index ce2f77f..150b874 100644
--- a/base/values.h
+++ b/base/values.h
@@ -342,9 +342,6 @@
public:
explicit Iterator(const DictionaryValue& target);
- // DEPRECATED: use !IsAtEnd() instead.
- bool HasNext() const { return it_ != target_.dictionary_.end(); }
-
bool IsAtEnd() const { return it_ == target_.dictionary_.end(); }
void Advance() { ++it_; }
@@ -495,9 +492,32 @@
virtual Value* Deserialize(int* error_code, std::string* error_str) = 0;
};
-// Stream operator so Values can be used in assertion statements.
+// Stream operator so Values can be used in assertion statements. In order that
+// gtest uses this operator to print readable output on test failures, we must
+// override each specific type. Otherwise, the default template implementation
+// is preferred over an upcast.
BASE_EXPORT std::ostream& operator<<(std::ostream& out, const Value& value);
+BASE_EXPORT inline std::ostream& operator<<(std::ostream& out,
+ const FundamentalValue& value) {
+ return out << static_cast<const Value&>(value);
+}
+
+BASE_EXPORT inline std::ostream& operator<<(std::ostream& out,
+ const StringValue& value) {
+ return out << static_cast<const Value&>(value);
+}
+
+BASE_EXPORT inline std::ostream& operator<<(std::ostream& out,
+ const DictionaryValue& value) {
+ return out << static_cast<const Value&>(value);
+}
+
+BASE_EXPORT inline std::ostream& operator<<(std::ostream& out,
+ const ListValue& value) {
+ return out << static_cast<const Value&>(value);
+}
+
} // namespace base
// http://crbug.com/88666
diff --git a/base/values_unittest.cc b/base/values_unittest.cc
index 98bc73c..b3459ab 100644
--- a/base/values_unittest.cc
+++ b/base/values_unittest.cc
@@ -599,7 +599,7 @@
// Make sure we don't prune too much.
root->SetBoolean("bool", true);
root->Set("empty_dict", new DictionaryValue);
- root->SetString("empty_string", "");
+ root->SetString("empty_string", std::string());
root.reset(root->DeepCopyWithoutEmptyChildren());
EXPECT_EQ(2U, root->size());
@@ -740,14 +740,14 @@
TEST(ValuesTest, DictionaryIterator) {
DictionaryValue dict;
- for (DictionaryValue::Iterator it(dict); it.HasNext(); it.Advance()) {
+ for (DictionaryValue::Iterator it(dict); !it.IsAtEnd(); it.Advance()) {
ADD_FAILURE();
}
StringValue value1("value1");
dict.Set("key1", value1.DeepCopy());
bool seen1 = false;
- for (DictionaryValue::Iterator it(dict); it.HasNext(); it.Advance()) {
+ for (DictionaryValue::Iterator it(dict); !it.IsAtEnd(); it.Advance()) {
EXPECT_FALSE(seen1);
EXPECT_EQ("key1", it.key());
EXPECT_TRUE(value1.Equals(&it.value()));
@@ -758,7 +758,7 @@
StringValue value2("value2");
dict.Set("key2", value2.DeepCopy());
bool seen2 = seen1 = false;
- for (DictionaryValue::Iterator it(dict); it.HasNext(); it.Advance()) {
+ for (DictionaryValue::Iterator it(dict); !it.IsAtEnd(); it.Advance()) {
if (it.key() == "key1") {
EXPECT_FALSE(seen1);
EXPECT_TRUE(value1.Equals(&it.value()));
diff --git a/base/version.cc b/base/version.cc
index f758733..eb1806e 100644
--- a/base/version.cc
+++ b/base/version.cc
@@ -11,6 +11,8 @@
#include "base/strings/string_number_conversions.h"
#include "base/strings/string_split.h"
+namespace base {
+
namespace {
// Parses the |numbers| vector representing the different numbers
@@ -21,14 +23,14 @@
bool ParseVersionNumbers(const std::string& version_str,
std::vector<uint16>* parsed) {
std::vector<std::string> numbers;
- base::SplitString(version_str, '.', &numbers);
+ SplitString(version_str, '.', &numbers);
if (numbers.empty())
return false;
for (std::vector<std::string>::const_iterator it = numbers.begin();
it != numbers.end(); ++it) {
int num;
- if (!base::StringToInt(*it, &num))
+ if (!StringToInt(*it, &num))
return false;
if (num < 0)
@@ -39,7 +41,7 @@
return false;
// This throws out things like +3, or 032.
- if (base::IntToString(num) != *it)
+ if (IntToString(num) != *it)
return false;
parsed->push_back(static_cast<uint16>(num));
@@ -164,9 +166,11 @@
std::string version_str;
size_t count = components_.size();
for (size_t i = 0; i < count - 1; ++i) {
- version_str.append(base::IntToString(components_[i]));
+ version_str.append(IntToString(components_[i]));
version_str.append(".");
}
- version_str.append(base::IntToString(components_[count - 1]));
+ version_str.append(IntToString(components_[count - 1]));
return version_str;
}
+
+} // namespace base
diff --git a/base/version.h b/base/version.h
index ab7145e..b3012eb 100644
--- a/base/version.h
+++ b/base/version.h
@@ -11,6 +11,8 @@
#include "base/base_export.h"
#include "base/basictypes.h"
+namespace base {
+
// Version represents a dotted version number, like "1.2.3.4", supporting
// parsing and comparison.
class BASE_EXPORT Version {
@@ -61,4 +63,10 @@
std::vector<uint16> components_;
};
+} // namespace base
+
+// TODO(xhwang) remove this when all users are updated to explicitly use the
+// namespace
+using base::Version;
+
#endif // BASE_VERSION_H_
diff --git a/base/vlog.h b/base/vlog.h
index 987730f..4ef173e 100644
--- a/base/vlog.h
+++ b/base/vlog.h
@@ -11,7 +11,7 @@
#include "base/base_export.h"
#include "base/basictypes.h"
-#include "base/string_piece.h"
+#include "base/strings/string_piece.h"
namespace logging {
diff --git a/base/vlog_unittest.cc b/base/vlog_unittest.cc
index ef7247f..3a508f4 100644
--- a/base/vlog_unittest.cc
+++ b/base/vlog_unittest.cc
@@ -16,12 +16,20 @@
TEST(VlogTest, NoVmodule) {
int min_log_level = 0;
- EXPECT_EQ(0, VlogInfo("", "", &min_log_level).GetVlogLevel("test1"));
- EXPECT_EQ(0, VlogInfo("0", "", &min_log_level).GetVlogLevel("test2"));
- EXPECT_EQ(0, VlogInfo("blah", "", &min_log_level).GetVlogLevel("test3"));
- EXPECT_EQ(0, VlogInfo("0blah1", "", &min_log_level).GetVlogLevel("test4"));
- EXPECT_EQ(1, VlogInfo("1", "", &min_log_level).GetVlogLevel("test5"));
- EXPECT_EQ(5, VlogInfo("5", "", &min_log_level).GetVlogLevel("test6"));
+ EXPECT_EQ(0,
+ VlogInfo(std::string(), std::string(), &min_log_level)
+ .GetVlogLevel("test1"));
+ EXPECT_EQ(0,
+ VlogInfo("0", std::string(), &min_log_level).GetVlogLevel("test2"));
+ EXPECT_EQ(
+ 0, VlogInfo("blah", std::string(), &min_log_level).GetVlogLevel("test3"));
+ EXPECT_EQ(
+ 0,
+ VlogInfo("0blah1", std::string(), &min_log_level).GetVlogLevel("test4"));
+ EXPECT_EQ(1,
+ VlogInfo("1", std::string(), &min_log_level).GetVlogLevel("test5"));
+ EXPECT_EQ(5,
+ VlogInfo("5", std::string(), &min_log_level).GetVlogLevel("test6"));
}
TEST(VlogTest, MatchVlogPattern) {
@@ -92,7 +100,7 @@
const char kVModuleSwitch[] =
"foo/bar.cc=1,baz\\*\\qux.cc=2,*quux/*=3,*/*-inl.h=4";
int min_log_level = 0;
- VlogInfo vlog_info("", kVModuleSwitch, &min_log_level);
+ VlogInfo vlog_info(std::string(), kVModuleSwitch, &min_log_level);
EXPECT_EQ(0, vlog_info.GetVlogLevel("/foo/bar.cc"));
EXPECT_EQ(0, vlog_info.GetVlogLevel("bar.cc"));
EXPECT_EQ(1, vlog_info.GetVlogLevel("foo/bar.cc"));
diff --git a/base/win/metro.cc b/base/win/metro.cc
index c9f16a9..2e02f01 100644
--- a/base/win/metro.cc
+++ b/base/win/metro.cc
@@ -71,6 +71,10 @@
}
bool IsTSFAwareRequired() {
+#if defined(USE_AURA)
+ if (base::win::GetVersion() >= base::win::VERSION_WIN8)
+ return true;
+#endif
// Although this function is equal to IsMetroProcess at this moment,
// Chrome for Win7 and Vista may support TSF in the future.
return g_should_tsf_aware_required || IsMetroProcess();
diff --git a/base/win/scoped_comptr.h b/base/win/scoped_comptr.h
index 9d5301f..98cea0f 100644
--- a/base/win/scoped_comptr.h
+++ b/base/win/scoped_comptr.h
@@ -139,7 +139,7 @@
// Provides direct access to the interface.
// Here we use a well known trick to make sure we block access to
- // IUknown methods so that something bad like this doesn't happen:
+ // IUnknown methods so that something bad like this doesn't happen:
// ScopedComPtr<IUnknown> p(Foo());
// p->Release();
// ... later the destructor runs, which will Release() again.
diff --git a/base/win/win_util.cc b/base/win/win_util.cc
index acdc907..3d12f77 100644
--- a/base/win/win_util.cc
+++ b/base/win/win_util.cc
@@ -214,20 +214,13 @@
signal(SIGABRT, ForceCrashOnSigAbort);
}
-bool IsMachineATablet() {
+bool IsTouchEnabledDevice() {
if (base::win::GetVersion() < base::win::VERSION_WIN7)
return false;
const int kMultiTouch = NID_INTEGRATED_TOUCH | NID_MULTI_INPUT | NID_READY;
- const int kMaxTabletScreenWidth = 1366;
- const int kMaxTabletScreenHeight = 768;
int sm = GetSystemMetrics(SM_DIGITIZER);
if ((sm & kMultiTouch) == kMultiTouch) {
- int cx = GetSystemMetrics(SM_CXSCREEN);
- int cy = GetSystemMetrics(SM_CYSCREEN);
- // Handle landscape and portrait modes.
- return cx > cy ?
- (cx <= kMaxTabletScreenWidth && cy <= kMaxTabletScreenHeight) :
- (cy <= kMaxTabletScreenWidth && cx <= kMaxTabletScreenHeight);
+ return true;
}
return false;
}
diff --git a/base/win/win_util.h b/base/win/win_util.h
index 0404ef0..78390be 100644
--- a/base/win/win_util.h
+++ b/base/win/win_util.h
@@ -102,9 +102,9 @@
// process is aborted.
BASE_EXPORT void SetAbortBehaviorForCrashReporting();
-// A tablet by this definition is something that has integrated multi-touch
-// ready to use and also has screen resolution not greater than 1366x768.
-BASE_EXPORT bool IsMachineATablet();
+// A touch enabled device by this definition is something that has
+// integrated multi-touch ready to use and has Windows version > Windows7.
+BASE_EXPORT bool IsTouchEnabledDevice();
// Get the size of a struct up to and including the specified member.
// This is necessary to set compatible struct sizes for different versions