Update Chromium files
Revision: 2b39aaf5dc7d0b0e00ce680b553f369753c0aa7e
diff --git a/AUTHORS b/AUTHORS
index 14b2e43..4810a10 100644
--- a/AUTHORS
+++ b/AUTHORS
@@ -421,6 +421,7 @@
Qing Zhang <qing.zhang@intel.com>
Qi Yang <qi1988.yang@samsung.com>
Radu Stavila <stavila@adobe.com>
+Radu Velea <radu.velea@intel.com>
Rafael Antognolli <rafael.antognolli@intel.com>
Raghavendra Ghatage <r.ghatage@samsung.com>
Rahul Gupta <rahul.g@samsung.com>
diff --git a/base/BUILD.gn b/base/BUILD.gn
index f4eb27f..de282cf 100644
--- a/base/BUILD.gn
+++ b/base/BUILD.gn
@@ -167,8 +167,8 @@
"callback_internal.cc",
"callback_internal.h",
"cancelable_callback.h",
- "chromeos/memory_pressure_monitor_chromeos.cc",
- "chromeos/memory_pressure_monitor_chromeos.h",
+ "chromeos/memory_pressure_monitor.cc",
+ "chromeos/memory_pressure_monitor.h",
"command_line.cc",
"command_line.h",
"compiler_specific.h",
@@ -271,6 +271,8 @@
"mac/bundle_locations.h",
"mac/bundle_locations.mm",
"mac/cocoa_protocols.h",
+ "mac/dispatch_source_mach.cc",
+ "mac/dispatch_source_mach.h",
"mac/foundation_util.h",
"mac/foundation_util.mm",
"mac/launch_services_util.cc",
@@ -285,8 +287,8 @@
"mac/mac_util.mm",
"mac/mach_logging.cc",
"mac/mach_logging.h",
- "mac/memory_pressure_monitor_mac.cc",
- "mac/memory_pressure_monitor_mac.h",
+ "mac/memory_pressure_monitor.cc",
+ "mac/memory_pressure_monitor.h",
"mac/objc_property_releaser.h",
"mac/objc_property_releaser.mm",
"mac/os_crash_dumps.cc",
@@ -1096,7 +1098,7 @@
"callback_unittest.cc",
"callback_unittest.nc",
"cancelable_callback_unittest.cc",
- "chromeos/memory_pressure_monitor_chromeos_unittest.cc",
+ "chromeos/memory_pressure_monitor_unittest.cc",
"command_line_unittest.cc",
"containers/adapters_unittest.cc",
"containers/hash_tables_unittest.cc",
@@ -1150,6 +1152,7 @@
"lazy_instance_unittest.cc",
"logging_unittest.cc",
"mac/bind_objc_block_unittest.mm",
+ "mac/dispatch_source_mach_unittest.cc",
"mac/foundation_util_unittest.mm",
"mac/libdispatch_task_runner_unittest.cc",
"mac/mac_util_unittest.mm",
diff --git a/base/android/java/src/org/chromium/base/BaseChromiumApplication.java b/base/android/java/src/org/chromium/base/BaseChromiumApplication.java
index 2946f6f..c87d02d 100644
--- a/base/android/java/src/org/chromium/base/BaseChromiumApplication.java
+++ b/base/android/java/src/org/chromium/base/BaseChromiumApplication.java
@@ -11,6 +11,10 @@
import android.view.KeyEvent;
import android.view.Window;
+import java.lang.reflect.InvocationHandler;
+import java.lang.reflect.Method;
+import java.lang.reflect.Proxy;
+
/**
* Basic application functionality that should be shared among all browser applications.
*/
@@ -30,66 +34,94 @@
private ObserverList<WindowFocusChangedListener> mWindowFocusListeners =
new ObserverList<WindowFocusChangedListener>();
+ /**
+ * Intercepts calls to an existing Window.Callback. Most invocations are passed on directly
+ * to the composed Window.Callback but enables intercepting/manipulating others.
+ *
+ * This is used to relay window focus changes throughout the app and remedy a bug in the
+ * appcompat library.
+ */
+ private class WindowCallbackProxy implements InvocationHandler {
+ private final Window.Callback mCallback;
+ private final Activity mActivity;
+
+ public WindowCallbackProxy(Activity activity, Window.Callback callback) {
+ mCallback = callback;
+ mActivity = activity;
+ }
+
+ @Override
+ public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
+ if (method.getName().equals("onWindowFocusChanged") && args.length == 1
+ && args[0] instanceof Boolean) {
+ onWindowFocusChanged((boolean) args[0]);
+ return null;
+ } else if (method.getName().equals("dispatchKeyEvent") && args.length == 1
+ && args[0] instanceof KeyEvent) {
+ return dispatchKeyEvent((KeyEvent) args[0]);
+ } else {
+ return method.invoke(mCallback, args);
+ }
+ }
+
+ public void onWindowFocusChanged(boolean hasFocus) {
+ mCallback.onWindowFocusChanged(hasFocus);
+
+ for (WindowFocusChangedListener listener : mWindowFocusListeners) {
+ listener.onWindowFocusChanged(mActivity, hasFocus);
+ }
+ }
+
+ public boolean dispatchKeyEvent(KeyEvent event) {
+ // TODO(aurimas): remove this once AppCompatDelegateImpl no longer steals
+ // KEYCODE_MENU. (see b/20529185)
+ if (event.getKeyCode() == KeyEvent.KEYCODE_MENU && mActivity.dispatchKeyEvent(event)) {
+ return true;
+ }
+ return mCallback.dispatchKeyEvent(event);
+ }
+ }
@Override
public void onCreate() {
super.onCreate();
ApplicationStatus.initialize(this);
-
registerActivityLifecycleCallbacks(new ActivityLifecycleCallbacks() {
@Override
public void onActivityCreated(final Activity activity, Bundle savedInstanceState) {
Window.Callback callback = activity.getWindow().getCallback();
- activity.getWindow().setCallback(new WindowCallbackWrapper(callback) {
- @Override
- public void onWindowFocusChanged(boolean hasFocus) {
- super.onWindowFocusChanged(hasFocus);
-
- for (WindowFocusChangedListener listener : mWindowFocusListeners) {
- listener.onWindowFocusChanged(activity, hasFocus);
- }
- }
-
- @Override
- public boolean dispatchKeyEvent(KeyEvent event) {
- // TODO(aurimas): remove this once AppCompatDelegateImpl no longer steals
- // KEYCODE_MENU. (see b/20529185)
- if (event.getKeyCode() == KeyEvent.KEYCODE_MENU
- && activity.dispatchKeyEvent(event)) {
- return true;
- }
- return super.dispatchKeyEvent(event);
- }
- });
+ activity.getWindow().setCallback((Window.Callback) Proxy.newProxyInstance(
+ Window.Callback.class.getClassLoader(), new Class[] {Window.Callback.class},
+ new WindowCallbackProxy(activity, callback)));
}
@Override
public void onActivityDestroyed(Activity activity) {
- assert activity.getWindow().getCallback() instanceof WindowCallbackWrapper;
+ assert Proxy.isProxyClass(activity.getWindow().getCallback().getClass());
}
@Override
public void onActivityPaused(Activity activity) {
- assert activity.getWindow().getCallback() instanceof WindowCallbackWrapper;
+ assert Proxy.isProxyClass(activity.getWindow().getCallback().getClass());
}
@Override
public void onActivityResumed(Activity activity) {
- assert activity.getWindow().getCallback() instanceof WindowCallbackWrapper;
+ assert Proxy.isProxyClass(activity.getWindow().getCallback().getClass());
}
@Override
public void onActivitySaveInstanceState(Activity activity, Bundle outState) {
- assert activity.getWindow().getCallback() instanceof WindowCallbackWrapper;
+ assert Proxy.isProxyClass(activity.getWindow().getCallback().getClass());
}
@Override
public void onActivityStarted(Activity activity) {
- assert activity.getWindow().getCallback() instanceof WindowCallbackWrapper;
+ assert Proxy.isProxyClass(activity.getWindow().getCallback().getClass());
}
@Override
public void onActivityStopped(Activity activity) {
- assert activity.getWindow().getCallback() instanceof WindowCallbackWrapper;
+ assert Proxy.isProxyClass(activity.getWindow().getCallback().getClass());
}
});
}
diff --git a/base/android/java/src/org/chromium/base/WindowCallbackWrapper.java b/base/android/java/src/org/chromium/base/WindowCallbackWrapper.java
deleted file mode 100644
index 0718c22..0000000
--- a/base/android/java/src/org/chromium/base/WindowCallbackWrapper.java
+++ /dev/null
@@ -1,140 +0,0 @@
-// Copyright 2014 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-package org.chromium.base;
-
-import android.annotation.SuppressLint;
-import android.view.ActionMode;
-import android.view.ActionMode.Callback;
-import android.view.KeyEvent;
-import android.view.Menu;
-import android.view.MenuItem;
-import android.view.MotionEvent;
-import android.view.View;
-import android.view.Window;
-import android.view.WindowManager.LayoutParams;
-import android.view.accessibility.AccessibilityEvent;
-
-/**
- * A wrapper for a Window.Callback instance, allowing subclasses to listen to or override specific
- * window messages.
- */
-class WindowCallbackWrapper implements Window.Callback {
- private final Window.Callback mCallback;
-
- public WindowCallbackWrapper(Window.Callback callback) {
- mCallback = callback;
- }
-
- @Override
- public boolean dispatchGenericMotionEvent(MotionEvent event) {
- return mCallback.dispatchGenericMotionEvent(event);
- }
-
- @Override
- public boolean dispatchKeyEvent(KeyEvent event) {
- return mCallback.dispatchKeyEvent(event);
- }
-
- @Override
- public boolean dispatchKeyShortcutEvent(KeyEvent event) {
- return mCallback.dispatchKeyShortcutEvent(event);
- }
-
- @Override
- public boolean dispatchPopulateAccessibilityEvent(AccessibilityEvent event) {
- return mCallback.dispatchPopulateAccessibilityEvent(event);
- }
-
- @Override
- public boolean dispatchTouchEvent(MotionEvent event) {
- return mCallback.dispatchTouchEvent(event);
- }
-
- @Override
- public boolean dispatchTrackballEvent(MotionEvent event) {
- return mCallback.dispatchTrackballEvent(event);
- }
-
- @Override
- public void onActionModeFinished(ActionMode mode) {
- mCallback.onActionModeFinished(mode);
- }
-
- @Override
- public void onActionModeStarted(ActionMode mode) {
- mCallback.onActionModeStarted(mode);
- }
-
- @Override
- public void onAttachedToWindow() {
- mCallback.onAttachedToWindow();
- }
-
- @Override
- public void onContentChanged() {
- mCallback.onContentChanged();
- }
-
- @Override
- public boolean onCreatePanelMenu(int featureId, Menu menu) {
- return mCallback.onCreatePanelMenu(featureId, menu);
- }
-
- @Override
- public View onCreatePanelView(int featureId) {
- return mCallback.onCreatePanelView(featureId);
- }
-
- @Override
- @SuppressLint("MissingSuperCall")
- public void onDetachedFromWindow() {
- mCallback.onDetachedFromWindow();
- }
-
- @Override
- public boolean onMenuItemSelected(int featureId, MenuItem item) {
- return mCallback.onMenuItemSelected(featureId, item);
- }
-
- @Override
- public boolean onMenuOpened(int featureId, Menu menu) {
- return mCallback.onMenuOpened(featureId, menu);
- }
-
- @Override
- public void onPanelClosed(int featureId, Menu menu) {
- mCallback.onPanelClosed(featureId, menu);
- }
-
- @Override
- public boolean onPreparePanel(int featureId, View view, Menu menu) {
- return mCallback.onPreparePanel(featureId, view, menu);
- }
-
- @Override
- public boolean onSearchRequested() {
- return mCallback.onSearchRequested();
- }
-
- @Override
- public void onWindowAttributesChanged(LayoutParams attrs) {
- mCallback.onWindowAttributesChanged(attrs);
- }
-
- @Override
- public void onWindowFocusChanged(boolean hasFocus) {
- mCallback.onWindowFocusChanged(hasFocus);
- }
-
- @Override
- public ActionMode onWindowStartingActionMode(Callback callback) {
- return mCallback.onWindowStartingActionMode(callback);
- }
-
- public void onWindowDismissed() {
- // TODO(benm): implement me.
- }
-
-}
diff --git a/base/android/java_runtime.h b/base/android/java_runtime.h
index bde4c5c..4ca889e 100644
--- a/base/android/java_runtime.h
+++ b/base/android/java_runtime.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_ANDROID_JAVA_RUNTIME_H
-#define BASE_ANDROID_JAVA_RUNTIME_H
+#ifndef BASE_ANDROID_JAVA_RUNTIME_H_
+#define BASE_ANDROID_JAVA_RUNTIME_H_
#include "base/android/scoped_java_ref.h"
#include "base/base_export.h"
@@ -25,4 +25,4 @@
} // namespace android
} // namespace base
-#endif // BASE_ANDROID_JAVA_RUNTIME_H
+#endif // BASE_ANDROID_JAVA_RUNTIME_H_
diff --git a/base/android/junit/src/org/chromium/base/BaseChromiumApplicationTest.java b/base/android/junit/src/org/chromium/base/BaseChromiumApplicationTest.java
new file mode 100644
index 0000000..d3441f7
--- /dev/null
+++ b/base/android/junit/src/org/chromium/base/BaseChromiumApplicationTest.java
@@ -0,0 +1,94 @@
+// Copyright 2015 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 static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.verify;
+
+import android.app.Activity;
+import android.view.KeyEvent;
+
+import junit.framework.Assert;
+
+import org.chromium.base.BaseChromiumApplication.WindowFocusChangedListener;
+import org.chromium.testing.local.LocalRobolectricTestRunner;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.robolectric.Robolectric;
+import org.robolectric.annotation.Config;
+import org.robolectric.annotation.Implementation;
+import org.robolectric.annotation.Implements;
+import org.robolectric.shadows.ShadowActivity;
+import org.robolectric.util.ActivityController;
+
+/** Unit tests for {@link BaseChromiumApplication}. */
+@RunWith(LocalRobolectricTestRunner.class)
+@Config(manifest = Config.NONE, application = BaseChromiumApplication.class,
+ shadows = {BaseChromiumApplicationTest.TrackingShadowActivity.class})
+public class BaseChromiumApplicationTest {
+
+ @Implements(Activity.class)
+ public static class TrackingShadowActivity extends ShadowActivity {
+ private int mWindowFocusCalls;
+ private int mDispatchKeyEventCalls;
+ private boolean mReturnValueForKeyDispatch;
+
+ @Implementation
+ public void onWindowFocusChanged(@SuppressWarnings("unused") boolean hasFocus) {
+ mWindowFocusCalls++;
+ }
+
+ @Implementation
+ public boolean dispatchKeyEvent(@SuppressWarnings("unused") KeyEvent event) {
+ mDispatchKeyEventCalls++;
+ return mReturnValueForKeyDispatch;
+ }
+ }
+
+ @Test
+ public void testWindowsFocusChanged() throws Exception {
+ BaseChromiumApplication app = (BaseChromiumApplication) Robolectric.application;
+
+ WindowFocusChangedListener mock = mock(WindowFocusChangedListener.class);
+ app.registerWindowFocusChangedListener(mock);
+
+ ActivityController<Activity> controller =
+ Robolectric.buildActivity(Activity.class).create().start().visible();
+ TrackingShadowActivity shadow =
+ (TrackingShadowActivity) Robolectric.shadowOf(controller.get());
+
+ controller.get().getWindow().getCallback().onWindowFocusChanged(true);
+ // Assert that listeners were notified.
+ verify(mock).onWindowFocusChanged(controller.get(), true);
+ // Also ensure that the original activity is forwarded the notification.
+ Assert.assertEquals(1, shadow.mWindowFocusCalls);
+ }
+
+ @Test
+ public void testDispatchKeyEvent() throws Exception {
+ ActivityController<Activity> controller =
+ Robolectric.buildActivity(Activity.class).create().start().visible();
+ TrackingShadowActivity shadow =
+ (TrackingShadowActivity) Robolectric.shadowOf(controller.get());
+
+ final KeyEvent menuKey = new KeyEvent(KeyEvent.ACTION_DOWN, KeyEvent.KEYCODE_MENU);
+
+ // Ensure that key events are forwarded.
+ Assert.assertFalse(controller.get().getWindow().getCallback().dispatchKeyEvent(menuKey));
+ // This gets called twice - once to see if the activity is swallowing it, and again to
+ // dispatch it.
+ Assert.assertEquals(2, shadow.mDispatchKeyEventCalls);
+
+ // Ensure that our activity can swallow the event.
+ shadow.mReturnValueForKeyDispatch = true;
+ Assert.assertTrue(controller.get().getWindow().getCallback().dispatchKeyEvent(menuKey));
+ Assert.assertEquals(3, shadow.mDispatchKeyEventCalls);
+
+ // A non-enter key only dispatches once.
+ Assert.assertTrue(controller.get().getWindow().getCallback().dispatchKeyEvent(
+ new KeyEvent(KeyEvent.ACTION_DOWN, KeyEvent.KEYCODE_SPACE)));
+ Assert.assertEquals(4, shadow.mDispatchKeyEventCalls);
+ }
+}
diff --git a/base/android/scoped_java_ref.h b/base/android/scoped_java_ref.h
index 7863c0b..8047ee8 100644
--- a/base/android/scoped_java_ref.h
+++ b/base/android/scoped_java_ref.h
@@ -178,6 +178,8 @@
this->Reset(other);
}
+ ScopedJavaGlobalRef(JNIEnv* env, T obj) { this->Reset(env, obj); }
+
template<typename U>
explicit ScopedJavaGlobalRef(const U& other) {
this->Reset(other);
diff --git a/base/base.gyp b/base/base.gyp
index 1078434..ff6ce00 100644
--- a/base/base.gyp
+++ b/base/base.gyp
@@ -458,7 +458,7 @@
'callback_unittest.cc',
'callback_unittest.nc',
'cancelable_callback_unittest.cc',
- 'chromeos/memory_pressure_monitor_chromeos_unittest.cc',
+ 'chromeos/memory_pressure_monitor_unittest.cc',
'command_line_unittest.cc',
'containers/adapters_unittest.cc',
'containers/hash_tables_unittest.cc',
@@ -514,10 +514,11 @@
'lazy_instance_unittest.cc',
'logging_unittest.cc',
'mac/bind_objc_block_unittest.mm',
+ 'mac/dispatch_source_mach_unittest.cc',
'mac/foundation_util_unittest.mm',
'mac/libdispatch_task_runner_unittest.cc',
'mac/mac_util_unittest.mm',
- 'mac/memory_pressure_monitor_mac_unittest.cc',
+ 'mac/memory_pressure_monitor_unittest.cc',
'mac/objc_property_releaser_unittest.mm',
'mac/scoped_nsobject_unittest.mm',
'mac/scoped_objc_class_swizzler_unittest.mm',
diff --git a/base/base.gypi b/base/base.gypi
index d1ab7b3..82d810e 100644
--- a/base/base.gypi
+++ b/base/base.gypi
@@ -128,8 +128,8 @@
'callback_internal.h',
'callback_list.h',
'cancelable_callback.h',
- 'chromeos/memory_pressure_monitor_chromeos.cc',
- 'chromeos/memory_pressure_monitor_chromeos.h',
+ 'chromeos/memory_pressure_monitor.cc',
+ 'chromeos/memory_pressure_monitor.h',
'command_line.cc',
'command_line.h',
'compiler_specific.h',
@@ -280,6 +280,8 @@
'mac/bundle_locations.mm',
'mac/close_nocancel.cc',
'mac/cocoa_protocols.h',
+ 'mac/dispatch_source_mach.cc',
+ 'mac/dispatch_source_mach.h',
'mac/foundation_util.h',
'mac/foundation_util.mm',
'mac/launch_services_util.cc',
@@ -294,8 +296,8 @@
'mac/mac_util.mm',
'mac/mach_logging.cc',
'mac/mach_logging.h',
- 'mac/memory_pressure_monitor_mac.cc',
- 'mac/memory_pressure_monitor_mac.h',
+ 'mac/memory_pressure_monitor.cc',
+ 'mac/memory_pressure_monitor.h',
'mac/objc_property_releaser.h',
'mac/objc_property_releaser.mm',
'mac/os_crash_dumps.cc',
diff --git a/base/base64.h b/base/base64.h
index def9b67..dd72c39 100644
--- a/base/base64.h
+++ b/base/base64.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_BASE64_H__
-#define BASE_BASE64_H__
+#ifndef BASE_BASE64_H_
+#define BASE_BASE64_H_
#include <string>
@@ -22,4 +22,4 @@
} // namespace base
-#endif // BASE_BASE64_H__
+#endif // BASE_BASE64_H_
diff --git a/base/base_paths_win.h b/base/base_paths_win.h
index 4ab6af1..9ac9e45 100644
--- a/base/base_paths_win.h
+++ b/base/base_paths_win.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_BASE_PATHS_WIN_H__
-#define BASE_BASE_PATHS_WIN_H__
+#ifndef BASE_BASE_PATHS_WIN_H_
+#define BASE_BASE_PATHS_WIN_H_
// This file declares windows-specific path keys for the base module.
// These can be used with the PathService to access various special
@@ -51,4 +51,4 @@
} // namespace base
-#endif // BASE_BASE_PATHS_WIN_H__
+#endif // BASE_BASE_PATHS_WIN_H_
diff --git a/base/bind_internal.h b/base/bind_internal.h
index 5fc1459..e053218 100644
--- a/base/bind_internal.h
+++ b/base/bind_internal.h
@@ -364,9 +364,10 @@
struct BindState;
template <typename Runnable,
- typename R, typename... Args,
+ typename R,
+ typename... Args,
typename... BoundArgs>
-struct BindState<Runnable, R(Args...), TypeList<BoundArgs...>>
+struct BindState<Runnable, R(Args...), TypeList<BoundArgs...>> final
: public BindStateBase {
private:
using StorageType = BindState<Runnable, R(Args...), TypeList<BoundArgs...>>;
@@ -398,14 +399,21 @@
using UnboundRunType = MakeFunctionType<R, UnboundArgs>;
BindState(const Runnable& runnable, const BoundArgs&... bound_args)
- : runnable_(runnable), ref_(bound_args...), bound_args_(bound_args...) {}
+ : BindStateBase(&Destroy),
+ runnable_(runnable),
+ ref_(bound_args...),
+ bound_args_(bound_args...) {}
RunnableType runnable_;
MaybeScopedRefPtr<HasIsMethodTag<Runnable>::value, BoundArgs...> ref_;
Tuple<BoundArgs...> bound_args_;
private:
- ~BindState() override {}
+ ~BindState() {}
+
+ static void Destroy(BindStateBase* self) {
+ delete static_cast<BindState*>(self);
+ }
};
} // namespace internal
diff --git a/base/callback_internal.cc b/base/callback_internal.cc
index f360388..2553fe7 100644
--- a/base/callback_internal.cc
+++ b/base/callback_internal.cc
@@ -9,6 +9,15 @@
namespace base {
namespace internal {
+void BindStateBase::AddRef() {
+ AtomicRefCountInc(&ref_count_);
+}
+
+void BindStateBase::Release() {
+ if (!AtomicRefCountDec(&ref_count_))
+ destructor_(this);
+}
+
CallbackBase::CallbackBase(const CallbackBase& c) = default;
CallbackBase& CallbackBase::operator=(const CallbackBase& c) = default;
@@ -27,7 +36,7 @@
CallbackBase::CallbackBase(BindStateBase* bind_state)
: bind_state_(bind_state),
polymorphic_invoke_(NULL) {
- DCHECK(!bind_state_.get() || bind_state_->HasOneRef());
+ DCHECK(!bind_state_.get() || bind_state_->ref_count_ == 1);
}
CallbackBase::~CallbackBase() {
diff --git a/base/callback_internal.h b/base/callback_internal.h
index 8a5c437..fefd7a2 100644
--- a/base/callback_internal.h
+++ b/base/callback_internal.h
@@ -10,15 +10,19 @@
#include <stddef.h>
+#include "base/atomic_ref_count.h"
#include "base/base_export.h"
+#include "base/macros.h"
#include "base/memory/ref_counted.h"
#include "base/memory/scoped_ptr.h"
+#include "base/template_util.h"
template <typename T>
class ScopedVector;
namespace base {
namespace internal {
+class CallbackBase;
// BindStateBase is used to provide an opaque handle that the Callback
// class can use to represent a function object with bound arguments. It
@@ -26,10 +30,30 @@
// DoInvoke function to perform the function execution. This allows
// us to shield the Callback class from the types of the bound argument via
// "type erasure."
-class BindStateBase : public RefCountedThreadSafe<BindStateBase> {
+// At the base level, the only task is to add reference counting data. Don't use
+// RefCountedThreadSafe since it requires the destructor to be a virtual method.
+// Creating a vtable for every BindState template instantiation results in a lot
+// of bloat. Its only task is to call the destructor which can be done with a
+// function pointer.
+class BindStateBase {
protected:
- friend class RefCountedThreadSafe<BindStateBase>;
- virtual ~BindStateBase() {}
+ explicit BindStateBase(void (*destructor)(BindStateBase*))
+ : ref_count_(0), destructor_(destructor) {}
+ ~BindStateBase() = default;
+
+ private:
+ friend class scoped_refptr<BindStateBase>;
+ friend class CallbackBase;
+
+ void AddRef();
+ void Release();
+
+ AtomicRefCount ref_count_;
+
+ // Pointer to a function that will properly destroy |this|.
+ void (*destructor_)(BindStateBase*);
+
+ DISALLOW_COPY_AND_ASSIGN(BindStateBase);
};
// Holds the Callback methods that don't require specialization to reduce
diff --git a/base/callback_unittest.cc b/base/callback_unittest.cc
index 5644b85..2844aa9 100644
--- a/base/callback_unittest.cc
+++ b/base/callback_unittest.cc
@@ -35,9 +35,13 @@
struct BindState<void(void), void(void), void(FakeInvoker)>
: public BindStateBase {
public:
+ BindState() : BindStateBase(&Destroy) {}
typedef FakeInvoker InvokerType;
private:
- ~BindState() override {}
+ ~BindState() {}
+ static void Destroy(BindStateBase* self) {
+ delete static_cast<BindState*>(self);
+ }
};
template <>
@@ -45,9 +49,13 @@
void(FakeInvoker, FakeInvoker)>
: public BindStateBase {
public:
+ BindState() : BindStateBase(&Destroy) {}
typedef FakeInvoker InvokerType;
private:
- ~BindState() override {}
+ ~BindState() {}
+ static void Destroy(BindStateBase* self) {
+ delete static_cast<BindState*>(self);
+ }
};
} // namespace internal
diff --git a/base/chromeos/memory_pressure_monitor_chromeos.cc b/base/chromeos/memory_pressure_monitor.cc
similarity index 88%
rename from base/chromeos/memory_pressure_monitor_chromeos.cc
rename to base/chromeos/memory_pressure_monitor.cc
index 82bc6a1..5e8aadf 100644
--- a/base/chromeos/memory_pressure_monitor_chromeos.cc
+++ b/base/chromeos/memory_pressure_monitor.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/chromeos/memory_pressure_monitor_chromeos.h"
+#include "base/chromeos/memory_pressure_monitor.h"
#include <fcntl.h>
#include <sys/select.h>
@@ -15,6 +15,7 @@
#include "base/time/time.h"
namespace base {
+namespace chromeos {
namespace {
@@ -53,10 +54,10 @@
// Converts a |MemoryPressureThreshold| value into a used memory percentage for
// the moderate pressure event.
int GetModerateMemoryThresholdInPercent(
- MemoryPressureMonitorChromeOS::MemoryPressureThresholds thresholds) {
- return thresholds == MemoryPressureMonitorChromeOS::
+ MemoryPressureMonitor::MemoryPressureThresholds thresholds) {
+ return thresholds == MemoryPressureMonitor::
THRESHOLD_AGGRESSIVE_CACHE_DISCARD ||
- thresholds == MemoryPressureMonitorChromeOS::THRESHOLD_AGGRESSIVE
+ thresholds == MemoryPressureMonitor::THRESHOLD_AGGRESSIVE
? kAggressiveMemoryPressureModerateThresholdPercent
: kNormalMemoryPressureModerateThresholdPercent;
}
@@ -64,10 +65,10 @@
// Converts a |MemoryPressureThreshold| value into a used memory percentage for
// the critical pressure event.
int GetCriticalMemoryThresholdInPercent(
- MemoryPressureMonitorChromeOS::MemoryPressureThresholds thresholds) {
- return thresholds == MemoryPressureMonitorChromeOS::
+ MemoryPressureMonitor::MemoryPressureThresholds thresholds) {
+ return thresholds == MemoryPressureMonitor::
THRESHOLD_AGGRESSIVE_TAB_DISCARD ||
- thresholds == MemoryPressureMonitorChromeOS::THRESHOLD_AGGRESSIVE
+ thresholds == MemoryPressureMonitor::THRESHOLD_AGGRESSIVE
? kAggressiveMemoryPressureCriticalThresholdPercent
: kNormalMemoryPressureCriticalThresholdPercent;
}
@@ -101,7 +102,7 @@
} // namespace
-MemoryPressureMonitorChromeOS::MemoryPressureMonitorChromeOS(
+MemoryPressureMonitor::MemoryPressureMonitor(
MemoryPressureThresholds thresholds)
: current_memory_pressure_level_(
MemoryPressureListener::MEMORY_PRESSURE_LEVEL_NONE),
@@ -116,35 +117,41 @@
LOG_IF(ERROR, !low_mem_file_.is_valid()) << "Cannot open kernel listener";
}
-MemoryPressureMonitorChromeOS::~MemoryPressureMonitorChromeOS() {
+MemoryPressureMonitor::~MemoryPressureMonitor() {
StopObserving();
}
-void MemoryPressureMonitorChromeOS::ScheduleEarlyCheck() {
+void MemoryPressureMonitor::ScheduleEarlyCheck() {
ThreadTaskRunnerHandle::Get()->PostTask(
- FROM_HERE, Bind(&MemoryPressureMonitorChromeOS::CheckMemoryPressure,
+ FROM_HERE, Bind(&MemoryPressureMonitor::CheckMemoryPressure,
weak_ptr_factory_.GetWeakPtr()));
}
MemoryPressureListener::MemoryPressureLevel
-MemoryPressureMonitorChromeOS::GetCurrentPressureLevel() const {
+MemoryPressureMonitor::GetCurrentPressureLevel() const {
return current_memory_pressure_level_;
}
-void MemoryPressureMonitorChromeOS::StartObserving() {
+// static
+MemoryPressureMonitor* MemoryPressureMonitor::Get() {
+ return static_cast<MemoryPressureMonitor*>(
+ base::MemoryPressureMonitor::Get());
+}
+
+void MemoryPressureMonitor::StartObserving() {
timer_.Start(FROM_HERE,
TimeDelta::FromMilliseconds(kMemoryPressureIntervalMs),
- Bind(&MemoryPressureMonitorChromeOS::
+ Bind(&MemoryPressureMonitor::
CheckMemoryPressureAndRecordStatistics,
weak_ptr_factory_.GetWeakPtr()));
}
-void MemoryPressureMonitorChromeOS::StopObserving() {
+void MemoryPressureMonitor::StopObserving() {
// If StartObserving failed, StopObserving will still get called.
timer_.Stop();
}
-void MemoryPressureMonitorChromeOS::CheckMemoryPressureAndRecordStatistics() {
+void MemoryPressureMonitor::CheckMemoryPressureAndRecordStatistics() {
CheckMemoryPressure();
// Record UMA histogram statistics for the current memory pressure level.
@@ -166,7 +173,7 @@
NUM_MEMORY_PRESSURE_LEVELS);
}
-void MemoryPressureMonitorChromeOS::CheckMemoryPressure() {
+void MemoryPressureMonitor::CheckMemoryPressure() {
MemoryPressureListener::MemoryPressureLevel old_pressure =
current_memory_pressure_level_;
@@ -224,7 +231,7 @@
}
// Gets the used ChromeOS memory in percent.
-int MemoryPressureMonitorChromeOS::GetUsedMemoryInPercent() {
+int MemoryPressureMonitor::GetUsedMemoryInPercent() {
base::SystemMemoryInfoKB info;
if (!base::GetSystemMemoryInfo(&info)) {
VLOG(1) << "Cannot determine the free memory of the system.";
@@ -261,4 +268,5 @@
return percentage;
}
+} // namespace chromeos
} // namespace base
diff --git a/base/chromeos/memory_pressure_monitor_chromeos.h b/base/chromeos/memory_pressure_monitor.h
similarity index 83%
rename from base/chromeos/memory_pressure_monitor_chromeos.h
rename to base/chromeos/memory_pressure_monitor.h
index 45855eb..bed1ec3 100644
--- a/base/chromeos/memory_pressure_monitor_chromeos.h
+++ b/base/chromeos/memory_pressure_monitor.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_CHROMEOS_MEMORY_PRESSURE_MONITOR_CHROMEOS_H_
-#define BASE_CHROMEOS_MEMORY_PRESSURE_MONITOR_CHROMEOS_H_
+#ifndef BASE_CHROMEOS_MEMORY_PRESSURE_MONITOR_H_
+#define BASE_CHROMEOS_MEMORY_PRESSURE_MONITOR_H_
#include "base/base_export.h"
#include "base/files/scoped_file.h"
@@ -15,17 +15,18 @@
#include "base/timer/timer.h"
namespace base {
+namespace chromeos {
class TestMemoryPressureMonitor;
////////////////////////////////////////////////////////////////////////////////
-// MemoryPressureMonitorChromeOS
+// MemoryPressureMonitor
//
// A class to handle the observation of our free memory. It notifies the
// MemoryPressureListener of memory fill level changes, so that it can take
// action to reduce memory resources accordingly.
//
-class BASE_EXPORT MemoryPressureMonitorChromeOS : public MemoryPressureMonitor {
+class BASE_EXPORT MemoryPressureMonitor : public base::MemoryPressureMonitor {
public:
using GetUsedMemoryInPercentCallback = int (*)();
@@ -49,8 +50,8 @@
THRESHOLD_AGGRESSIVE = 4
};
- explicit MemoryPressureMonitorChromeOS(MemoryPressureThresholds thresholds);
- ~MemoryPressureMonitorChromeOS() override;
+ explicit MemoryPressureMonitor(MemoryPressureThresholds thresholds);
+ ~MemoryPressureMonitor() override;
// Redo the memory pressure calculation soon and call again if a critical
// memory pressure prevails. Note that this call will trigger an asynchronous
@@ -61,6 +62,10 @@
MemoryPressureListener::MemoryPressureLevel GetCurrentPressureLevel() const
override;
+ // Returns a type-casted version of the current memory pressure monitor. A
+ // simple wrapper to base::MemoryPressureMonitor::Get.
+ static MemoryPressureMonitor* Get();
+
private:
friend TestMemoryPressureMonitor;
// Starts observing the memory fill level.
@@ -90,7 +95,7 @@
// A periodic timer to check for resource pressure changes. This will get
// replaced by a kernel triggered event system (see crbug.com/381196).
- base::RepeatingTimer<MemoryPressureMonitorChromeOS> timer_;
+ base::RepeatingTimer<MemoryPressureMonitor> timer_;
// To slow down the amount of moderate pressure event calls, this counter
// gets used to count the number of events since the last event occured.
@@ -103,11 +108,12 @@
// File descriptor used to detect low memory condition.
ScopedFD low_mem_file_;
- base::WeakPtrFactory<MemoryPressureMonitorChromeOS> weak_ptr_factory_;
+ base::WeakPtrFactory<MemoryPressureMonitor> weak_ptr_factory_;
- DISALLOW_COPY_AND_ASSIGN(MemoryPressureMonitorChromeOS);
+ DISALLOW_COPY_AND_ASSIGN(MemoryPressureMonitor);
};
+} // namespace chromeos
} // namespace base
-#endif // BASE_CHROMEOS_MEMORY_PRESSURE_MONITOR_CHROMEOS_H_
+#endif // BASE_CHROMEOS_MEMORY_PRESSURE_MONITOR_H_
diff --git a/base/chromeos/memory_pressure_monitor_chromeos_unittest.cc b/base/chromeos/memory_pressure_monitor_unittest.cc
similarity index 93%
rename from base/chromeos/memory_pressure_monitor_chromeos_unittest.cc
rename to base/chromeos/memory_pressure_monitor_unittest.cc
index 72e00d3..4fb8332 100644
--- a/base/chromeos/memory_pressure_monitor_chromeos_unittest.cc
+++ b/base/chromeos/memory_pressure_monitor_unittest.cc
@@ -3,12 +3,13 @@
// found in the LICENSE file.
#include "base/basictypes.h"
-#include "base/chromeos/memory_pressure_monitor_chromeos.h"
+#include "base/chromeos/memory_pressure_monitor.h"
#include "base/memory/memory_pressure_listener.h"
#include "base/message_loop/message_loop.h"
#include "testing/gtest/include/gtest/gtest.h"
namespace base {
+namespace chromeos {
namespace {
@@ -40,12 +41,11 @@
} // namespace
-class TestMemoryPressureMonitor : public MemoryPressureMonitorChromeOS {
+class TestMemoryPressureMonitor : public MemoryPressureMonitor {
public:
- TestMemoryPressureMonitor() :
- MemoryPressureMonitorChromeOS(
- MemoryPressureMonitorChromeOS::THRESHOLD_DEFAULT),
- memory_in_percent_override_(0) {
+ TestMemoryPressureMonitor()
+ : MemoryPressureMonitor(THRESHOLD_DEFAULT),
+ memory_in_percent_override_(0) {
// Disable any timers which are going on and set a special memory reporting
// function.
StopObserving();
@@ -71,7 +71,7 @@
// This test tests the various transition states from memory pressure, looking
// for the correct behavior on event reposting as well as state updates.
-TEST(MemoryPressureMonitorChromeOSTest, CheckMemoryPressure) {
+TEST(ChromeOSMemoryPressureMonitorTest, CheckMemoryPressure) {
base::MessageLoopForUI message_loop;
scoped_ptr<TestMemoryPressureMonitor> monitor(
new TestMemoryPressureMonitor);
@@ -161,4 +161,5 @@
EXPECT_EQ(j, i);
}
+} // namespace chromeos
} // namespace base
diff --git a/base/debug/profiler.h b/base/debug/profiler.h
index c50555e..2920d8a 100644
--- a/base/debug/profiler.h
+++ b/base/debug/profiler.h
@@ -87,4 +87,4 @@
} // namespace debug
} // namespace base
-#endif // BASE_DEBUG_PROFILER_H__
+#endif // BASE_DEBUG_PROFILER_H_
diff --git a/base/file_version_info.h b/base/file_version_info.h
index 5bc577c..57b837c 100644
--- a/base/file_version_info.h
+++ b/base/file_version_info.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_FILE_VERSION_INFO_H__
-#define BASE_FILE_VERSION_INFO_H__
+#ifndef BASE_FILE_VERSION_INFO_H_
+#define BASE_FILE_VERSION_INFO_H_
#include "build/build_config.h"
@@ -83,4 +83,4 @@
virtual bool is_official_build() = 0;
};
-#endif // BASE_FILE_VERSION_INFO_H__
+#endif // BASE_FILE_VERSION_INFO_H_
diff --git a/base/files/dir_reader_linux.h b/base/files/dir_reader_linux.h
index cb0cbd3..abf2595 100644
--- a/base/files/dir_reader_linux.h
+++ b/base/files/dir_reader_linux.h
@@ -95,4 +95,4 @@
} // namespace base
-#endif // BASE_FILES_DIR_READER_LINUX_H_
+#endif // BASE_FILES_DIR_READER_LINUX_H_
diff --git a/base/files/dir_reader_posix.h b/base/files/dir_reader_posix.h
index 6a20ced..6a32d9f 100644
--- a/base/files/dir_reader_posix.h
+++ b/base/files/dir_reader_posix.h
@@ -33,4 +33,4 @@
} // namespace base
-#endif // BASE_FILES_DIR_READER_POSIX_H_
+#endif // BASE_FILES_DIR_READER_POSIX_H_
diff --git a/base/json/json_parser.cc b/base/json/json_parser.cc
index e9a27bc..4d79be3 100644
--- a/base/json/json_parser.cc
+++ b/base/json/json_parser.cc
@@ -932,7 +932,7 @@
return NULL;
}
NextNChars(kNullLen - 1);
- return Value::CreateNullValue();
+ return Value::CreateNullValue().release();
}
default:
ReportError(JSONReader::JSON_UNEXPECTED_TOKEN, 1);
diff --git a/base/json/json_writer_unittest.cc b/base/json/json_writer_unittest.cc
index 802876c..5ac2590 100644
--- a/base/json/json_writer_unittest.cc
+++ b/base/json/json_writer_unittest.cc
@@ -12,8 +12,7 @@
std::string output_js;
// Test null.
- scoped_ptr<Value> root(Value::CreateNullValue());
- EXPECT_TRUE(JSONWriter::Write(root.get(), &output_js));
+ EXPECT_TRUE(JSONWriter::Write(Value::CreateNullValue().get(), &output_js));
EXPECT_EQ("null", output_js);
// Test empty dict.
@@ -57,7 +56,6 @@
EXPECT_EQ("\"foo\"", output_js);
}
-
TEST(JSONWriterTest, NestedTypes) {
std::string output_js;
diff --git a/base/json/string_escape_unittest.cc b/base/json/string_escape_unittest.cc
index 3eb4e8e..100373f 100644
--- a/base/json/string_escape_unittest.cc
+++ b/base/json/string_escape_unittest.cc
@@ -159,7 +159,7 @@
const char* escaped;
} cases[] = {
{"b\x0f\x7f\xf0\xff!", "b\\u000F\\u007F\\u00F0\\u00FF!"},
- {"\xe5\xc4\x4f\x05\xb6\xfd\0", "\\u00E5\\u00C4O\\u0005\\u00B6\\u00FD"},
+ {"\xe5\xc4\x4f\x05\xb6\xfd", "\\u00E5\\u00C4O\\u0005\\u00B6\\u00FD"},
};
for (size_t i = 0; i < arraysize(cases); ++i) {
diff --git a/sandbox/mac/dispatch_source_mach.cc b/base/mac/dispatch_source_mach.cc
similarity index 94%
rename from sandbox/mac/dispatch_source_mach.cc
rename to base/mac/dispatch_source_mach.cc
index a6f3ac8..745c9de 100644
--- a/sandbox/mac/dispatch_source_mach.cc
+++ b/base/mac/dispatch_source_mach.cc
@@ -2,9 +2,9 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-#include "sandbox/mac/dispatch_source_mach.h"
+#include "base/mac/dispatch_source_mach.h"
-namespace sandbox {
+namespace base {
DispatchSourceMach::DispatchSourceMach(const char* name,
mach_port_t port,
@@ -59,4 +59,4 @@
}
}
-} // namespace sandbox
+} // namespace base
diff --git a/sandbox/mac/dispatch_source_mach.h b/base/mac/dispatch_source_mach.h
similarity index 87%
rename from sandbox/mac/dispatch_source_mach.h
rename to base/mac/dispatch_source_mach.h
index e3a3aa0..e7d5cb2 100644
--- a/sandbox/mac/dispatch_source_mach.h
+++ b/base/mac/dispatch_source_mach.h
@@ -2,21 +2,21 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-#ifndef SANDBOX_MAC_DISPATCH_SOURCE_MACH_H_
-#define SANDBOX_MAC_DISPATCH_SOURCE_MACH_H_
+#ifndef BASE_MAC_DISPATCH_SOURCE_MACH_H_
+#define BASE_MAC_DISPATCH_SOURCE_MACH_H_
#include <dispatch/dispatch.h>
+#include "base/base_export.h"
#include "base/macros.h"
-#include "sandbox/sandbox_export.h"
-namespace sandbox {
+namespace base {
// This class encapsulates a MACH_RECV dispatch source. When this object is
// destroyed, the source will be cancelled and it will wait for the source
// to stop executing work. The source can run on either a user-supplied queue,
// or it can create its own for the source.
-class SANDBOX_EXPORT DispatchSourceMach {
+class BASE_EXPORT DispatchSourceMach {
public:
// Creates a new dispatch source for the |port| and schedules it on a new
// queue that will be created with |name|. When a Mach message is received,
@@ -56,6 +56,6 @@
DISALLOW_COPY_AND_ASSIGN(DispatchSourceMach);
};
-} // namespace sandbox
+} // namespace base
-#endif // SANDBOX_MAC_DISPATCH_SOURCE_MACH_H_
+#endif // BASE_MAC_DISPATCH_SOURCE_MACH_H_
diff --git a/sandbox/mac/dispatch_source_mach_unittest.cc b/base/mac/dispatch_source_mach_unittest.cc
similarity index 82%
rename from sandbox/mac/dispatch_source_mach_unittest.cc
rename to base/mac/dispatch_source_mach_unittest.cc
index 123a44c..82dc136 100644
--- a/sandbox/mac/dispatch_source_mach_unittest.cc
+++ b/base/mac/dispatch_source_mach_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 "sandbox/mac/dispatch_source_mach.h"
+#include "base/mac/dispatch_source_mach.h"
#include <mach/mach.h>
@@ -12,7 +12,7 @@
#include "base/test/test_timeouts.h"
#include "testing/gtest/include/gtest/gtest.h"
-namespace sandbox {
+namespace base {
class DispatchSourceMachTest : public testing::Test {
public:
@@ -27,7 +27,7 @@
send_right_.reset(port);
}
- mach_port_t port() { return receive_right_.get(); }
+ mach_port_t GetPort() { return receive_right_.get(); }
void WaitForSemaphore(dispatch_semaphore_t semaphore) {
dispatch_semaphore_wait(semaphore, dispatch_time(
@@ -42,13 +42,14 @@
TEST_F(DispatchSourceMachTest, ReceiveAfterResume) {
dispatch_semaphore_t signal = dispatch_semaphore_create(0);
+ mach_port_t port = GetPort();
bool __block did_receive = false;
- DispatchSourceMach source("org.chromium.sandbox.test.ReceiveAfterResume",
- port(), ^{
+ DispatchSourceMach source("org.chromium.base.test.ReceiveAfterResume",
+ port, ^{
mach_msg_empty_rcv_t msg = {{0}};
msg.header.msgh_size = sizeof(msg);
- msg.header.msgh_local_port = port();
+ msg.header.msgh_local_port = port;
mach_msg_receive(&msg.header);
did_receive = true;
@@ -57,7 +58,7 @@
mach_msg_empty_send_t msg = {{0}};
msg.header.msgh_size = sizeof(msg);
- msg.header.msgh_remote_port = port();
+ msg.header.msgh_remote_port = port;
msg.header.msgh_bits = MACH_MSGH_BITS_REMOTE(MACH_MSG_TYPE_COPY_SEND);
ASSERT_EQ(KERN_SUCCESS, mach_msg_send(&msg.header));
@@ -66,20 +67,23 @@
source.Resume();
WaitForSemaphore(signal);
+ dispatch_release(signal);
EXPECT_TRUE(did_receive);
}
TEST_F(DispatchSourceMachTest, NoMessagesAfterDestruction) {
+ mach_port_t port = GetPort();
+
scoped_ptr<int> count(new int(0));
int* __block count_ptr = count.get();
scoped_ptr<DispatchSourceMach> source(new DispatchSourceMach(
- "org.chromium.sandbox.test.NoMessagesAfterDestruction",
- port(), ^{
+ "org.chromium.base.test.NoMessagesAfterDestruction",
+ port, ^{
mach_msg_empty_rcv_t msg = {{0}};
msg.header.msgh_size = sizeof(msg);
- msg.header.msgh_local_port = port();
+ msg.header.msgh_local_port = port;
mach_msg_receive(&msg.header);
LOG(INFO) << "Receieve " << *count_ptr;
++(*count_ptr);
@@ -87,13 +91,13 @@
source->Resume();
dispatch_queue_t queue =
- dispatch_queue_create("org.chromium.sandbox.test.MessageSend", NULL);
+ dispatch_queue_create("org.chromium.base.test.MessageSend", NULL);
dispatch_semaphore_t signal = dispatch_semaphore_create(0);
for (int i = 0; i < 30; ++i) {
dispatch_async(queue, ^{
mach_msg_empty_send_t msg = {{0}};
msg.header.msgh_size = sizeof(msg);
- msg.header.msgh_remote_port = port();
+ msg.header.msgh_remote_port = port;
msg.header.msgh_bits =
MACH_MSGH_BITS_REMOTE(MACH_MSG_TYPE_COPY_SEND);
mach_msg_send(&msg.header);
@@ -113,7 +117,9 @@
}
WaitForSemaphore(signal);
+ dispatch_release(signal);
+
dispatch_release(queue);
}
-} // namespace sandbox
+} // namespace base
diff --git a/base/mac/memory_pressure_monitor_mac.cc b/base/mac/memory_pressure_monitor.cc
similarity index 87%
rename from base/mac/memory_pressure_monitor_mac.cc
rename to base/mac/memory_pressure_monitor.cc
index 81727bb..5667aa6 100644
--- a/base/mac/memory_pressure_monitor_mac.cc
+++ b/base/mac/memory_pressure_monitor.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/mac/memory_pressure_monitor_mac.h"
+#include "base/mac/memory_pressure_monitor.h"
#include <dlfcn.h>
#include <sys/sysctl.h>
@@ -10,9 +10,10 @@
#include "base/mac/mac_util.h"
namespace base {
+namespace mac {
MemoryPressureListener::MemoryPressureLevel
-MemoryPressureMonitorMac::MemoryPressureLevelForMacMemoryPressure(
+MemoryPressureMonitor::MemoryPressureLevelForMacMemoryPressure(
int mac_memory_pressure) {
switch (mac_memory_pressure) {
case DISPATCH_MEMORYPRESSURE_NORMAL:
@@ -25,7 +26,7 @@
return MemoryPressureListener::MEMORY_PRESSURE_LEVEL_NONE;
}
-void MemoryPressureMonitorMac::NotifyMemoryPressureChanged(
+void MemoryPressureMonitor::NotifyMemoryPressureChanged(
dispatch_source_s* event_source) {
int mac_memory_pressure = dispatch_source_get_data(event_source);
MemoryPressureListener::MemoryPressureLevel memory_pressure_level =
@@ -33,7 +34,7 @@
MemoryPressureListener::NotifyMemoryPressure(memory_pressure_level);
}
-MemoryPressureMonitorMac::MemoryPressureMonitorMac()
+MemoryPressureMonitor::MemoryPressureMonitor()
: memory_level_event_source_(nullptr) {
// _dispatch_source_type_memorypressure is not available prior to 10.9.
dispatch_source_type_t dispatch_source_memorypressure =
@@ -58,11 +59,11 @@
}
}
-MemoryPressureMonitorMac::~MemoryPressureMonitorMac() {
+MemoryPressureMonitor::~MemoryPressureMonitor() {
}
MemoryPressureListener::MemoryPressureLevel
-MemoryPressureMonitorMac::GetCurrentPressureLevel() const {
+MemoryPressureMonitor::GetCurrentPressureLevel() const {
if (base::mac::IsOSMountainLionOrEarlier()) {
return MemoryPressureListener::MEMORY_PRESSURE_LEVEL_NONE;
}
@@ -73,4 +74,5 @@
return MemoryPressureLevelForMacMemoryPressure(mac_memory_pressure);
}
+} // namespace mac
} // namespace base
diff --git a/base/mac/memory_pressure_monitor_mac.h b/base/mac/memory_pressure_monitor.h
similarity index 73%
rename from base/mac/memory_pressure_monitor_mac.h
rename to base/mac/memory_pressure_monitor.h
index aebdd65..afaec27 100644
--- a/base/mac/memory_pressure_monitor_mac.h
+++ b/base/mac/memory_pressure_monitor.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_MEMORY_MEMORY_PRESSURE_MONITOR_MAC_H_
-#define BASE_MEMORY_MEMORY_PRESSURE_MONITOR_MAC_H_
+#ifndef BASE_MAC_MEMORY_PRESSURE_MONITOR_H_
+#define BASE_MAC_MEMORY_PRESSURE_MONITOR_H_
#include <dispatch/dispatch.h>
@@ -23,8 +23,9 @@
#endif // DISPATCH_MEMORYPRESSURE_NORMAL
namespace base {
+namespace mac {
-class TestMemoryPressureMonitorMac;
+class TestMemoryPressureMonitor;
struct DispatchSourceSDeleter {
void operator()(dispatch_source_s* ptr) {
@@ -35,17 +36,16 @@
// Declares the interface for the Mac MemoryPressureMonitor, which reports
// memory pressure events and status.
-class BASE_EXPORT MemoryPressureMonitorMac : public MemoryPressureMonitor {
+class BASE_EXPORT MemoryPressureMonitor : public base::MemoryPressureMonitor {
public:
- using MemoryPressureLevel = base::MemoryPressureListener::MemoryPressureLevel;
- MemoryPressureMonitorMac();
- ~MemoryPressureMonitorMac() override;
+ MemoryPressureMonitor();
+ ~MemoryPressureMonitor() override;
// Returns the currently-observed memory pressure.
MemoryPressureLevel GetCurrentPressureLevel() const override;
private:
- friend TestMemoryPressureMonitorMac;
+ friend TestMemoryPressureMonitor;
static MemoryPressureLevel
MemoryPressureLevelForMacMemoryPressure(int mac_memory_pressure);
@@ -54,9 +54,10 @@
scoped_ptr<dispatch_source_s, DispatchSourceSDeleter>
memory_level_event_source_;
- DISALLOW_COPY_AND_ASSIGN(MemoryPressureMonitorMac);
+ DISALLOW_COPY_AND_ASSIGN(MemoryPressureMonitor);
};
+} // namespace mac
} // namespace base
-#endif // BASE_MEMORY_MEMORY_PRESSURE_MONITOR_MAC_H_
+#endif // BASE_MAC_MEMORY_PRESSURE_MONITOR_H_
diff --git a/base/mac/memory_pressure_monitor_mac_unittest.cc b/base/mac/memory_pressure_monitor_unittest.cc
similarity index 69%
rename from base/mac/memory_pressure_monitor_mac_unittest.cc
rename to base/mac/memory_pressure_monitor_unittest.cc
index 24ee09a..acb3666 100644
--- a/base/mac/memory_pressure_monitor_mac_unittest.cc
+++ b/base/mac/memory_pressure_monitor_unittest.cc
@@ -2,50 +2,51 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-#include "base/mac/memory_pressure_monitor_mac.h"
+#include "base/mac/memory_pressure_monitor.h"
#include "testing/gtest/include/gtest/gtest.h"
namespace base {
+namespace mac {
-class TestMemoryPressureMonitorMac : public MemoryPressureMonitorMac {
+class TestMemoryPressureMonitor : public MemoryPressureMonitor {
public:
- using MemoryPressureMonitorMac::MemoryPressureLevelForMacMemoryPressure;
+ using MemoryPressureMonitor::MemoryPressureLevelForMacMemoryPressure;
- TestMemoryPressureMonitorMac() { }
+ TestMemoryPressureMonitor() { }
private:
- DISALLOW_COPY_AND_ASSIGN(TestMemoryPressureMonitorMac);
+ DISALLOW_COPY_AND_ASSIGN(TestMemoryPressureMonitor);
};
-TEST(TestMemoryPressureMonitorMac, MemoryPressureFromMacMemoryPressure) {
+TEST(MacMemoryPressureMonitorTest, MemoryPressureFromMacMemoryPressure) {
EXPECT_EQ(MemoryPressureListener::MEMORY_PRESSURE_LEVEL_NONE,
- TestMemoryPressureMonitorMac::
+ TestMemoryPressureMonitor::
MemoryPressureLevelForMacMemoryPressure(
DISPATCH_MEMORYPRESSURE_NORMAL));
EXPECT_EQ(MemoryPressureListener::MEMORY_PRESSURE_LEVEL_MODERATE,
- TestMemoryPressureMonitorMac::
+ TestMemoryPressureMonitor::
MemoryPressureLevelForMacMemoryPressure(
DISPATCH_MEMORYPRESSURE_WARN));
EXPECT_EQ(MemoryPressureListener::MEMORY_PRESSURE_LEVEL_CRITICAL,
- TestMemoryPressureMonitorMac::
+ TestMemoryPressureMonitor::
MemoryPressureLevelForMacMemoryPressure(
DISPATCH_MEMORYPRESSURE_CRITICAL));
EXPECT_EQ(MemoryPressureListener::MEMORY_PRESSURE_LEVEL_NONE,
- TestMemoryPressureMonitorMac::
+ TestMemoryPressureMonitor::
MemoryPressureLevelForMacMemoryPressure(0));
EXPECT_EQ(MemoryPressureListener::MEMORY_PRESSURE_LEVEL_NONE,
- TestMemoryPressureMonitorMac::
+ TestMemoryPressureMonitor::
MemoryPressureLevelForMacMemoryPressure(3));
EXPECT_EQ(MemoryPressureListener::MEMORY_PRESSURE_LEVEL_NONE,
- TestMemoryPressureMonitorMac::
+ TestMemoryPressureMonitor::
MemoryPressureLevelForMacMemoryPressure(5));
EXPECT_EQ(MemoryPressureListener::MEMORY_PRESSURE_LEVEL_NONE,
- TestMemoryPressureMonitorMac::
+ TestMemoryPressureMonitor::
MemoryPressureLevelForMacMemoryPressure(-1));
}
-TEST(TestMemoryPressureMonitorMac, CurrentMemoryPressure) {
- TestMemoryPressureMonitorMac monitor;
+TEST(MacMemoryPressureMonitorTest, CurrentMemoryPressure) {
+ TestMemoryPressureMonitor monitor;
MemoryPressureListener::MemoryPressureLevel memory_pressure =
monitor.GetCurrentPressureLevel();
EXPECT_TRUE(memory_pressure ==
@@ -56,4 +57,5 @@
MemoryPressureListener::MEMORY_PRESSURE_LEVEL_CRITICAL);
}
+} // namespace mac
} // namespace base
diff --git a/base/mac/sdk_forward_declarations.h b/base/mac/sdk_forward_declarations.h
index d7be320..d70a6aa 100644
--- a/base/mac/sdk_forward_declarations.h
+++ b/base/mac/sdk_forward_declarations.h
@@ -244,6 +244,8 @@
BASE_EXPORT extern NSString* const
NSWindowDidChangeBackingPropertiesNotification;
BASE_EXPORT extern NSString* const CBAdvertisementDataServiceDataKey;
+BASE_EXPORT extern NSString* const
+ NSPreferredScrollerStyleDidChangeNotification;
#endif // MAC_OS_X_VERSION_10_7
#if !defined(MAC_OS_X_VERSION_10_9) || \
diff --git a/base/mac/sdk_forward_declarations.mm b/base/mac/sdk_forward_declarations.mm
index 347e87c..2e4b2d9 100644
--- a/base/mac/sdk_forward_declarations.mm
+++ b/base/mac/sdk_forward_declarations.mm
@@ -22,6 +22,9 @@
@"NSWindowDidChangeBackingPropertiesNotification";
NSString* const CBAdvertisementDataServiceDataKey = @"kCBAdvDataServiceData";
+
+NSString* const NSPreferredScrollerStyleDidChangeNotification =
+ @"NSPreferredScrollerStyleDidChangeNotification";
#endif // MAC_OS_X_VERSION_10_7
#if !defined(MAC_OS_X_VERSION_10_9) || \
diff --git a/base/memory/memory_pressure_monitor.h b/base/memory/memory_pressure_monitor.h
index 50260c4..90c9420 100644
--- a/base/memory/memory_pressure_monitor.h
+++ b/base/memory/memory_pressure_monitor.h
@@ -10,6 +10,9 @@
namespace base {
+// TODO(chrisha): Make this a concrete class with per-OS implementations rather
+// than an abstract base class.
+
// Declares the interface for a MemoryPressureMonitor. There are multiple
// OS specific implementations of this class. An instance of the memory
// pressure observer is created at the process level, tracks memory usage, and
diff --git a/base/message_loop/message_pump_default.cc b/base/message_loop/message_pump_default.cc
index 27c19e0..bb9d8ce 100644
--- a/base/message_loop/message_pump_default.cc
+++ b/base/message_loop/message_pump_default.cc
@@ -52,7 +52,8 @@
event_.Wait();
} else {
TimeDelta delay = delayed_work_time_ - TimeTicks::Now();
- if (delay > TimeDelta()) {
+ // If the delay is under 1 ms we need to execute the task right away.
+ if (delay.InMilliseconds() >= 1) {
event_.TimedWait(delay);
} else {
// It looks like delayed_work_time_ indicates a time in the past, so we
diff --git a/base/metrics/statistics_recorder.cc b/base/metrics/statistics_recorder.cc
index 39ecc30..fb069a5 100644
--- a/base/metrics/statistics_recorder.cc
+++ b/base/metrics/statistics_recorder.cc
@@ -286,8 +286,6 @@
// static
void StatisticsRecorder::DumpHistogramsToVlog(void* instance) {
- DCHECK(VLOG_IS_ON(1));
-
string output;
StatisticsRecorder::WriteGraph(std::string(), &output);
VLOG(1) << output;
diff --git a/base/observer_list.h b/base/observer_list.h
index 9ea344d..fb6f026 100644
--- a/base/observer_list.h
+++ b/base/observer_list.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_OBSERVER_LIST_H__
-#define BASE_OBSERVER_LIST_H__
+#ifndef BASE_OBSERVER_LIST_H_
+#define BASE_OBSERVER_LIST_H_
#include <algorithm>
#include <limits>
@@ -240,4 +240,4 @@
} \
} while (0)
-#endif // BASE_OBSERVER_LIST_H__
+#endif // BASE_OBSERVER_LIST_H_
diff --git a/base/pickle.h b/base/pickle.h
index e6b9d81..9589e2a 100644
--- a/base/pickle.h
+++ b/base/pickle.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_PICKLE_H__
-#define BASE_PICKLE_H__
+#ifndef BASE_PICKLE_H_
+#define BASE_PICKLE_H_
#include <string>
@@ -304,4 +304,4 @@
FRIEND_TEST_ALL_PREFIXES(PickleTest, FindNextOverflow);
};
-#endif // BASE_PICKLE_H__
+#endif // BASE_PICKLE_H_
diff --git a/base/prefs/json_pref_store.cc b/base/prefs/json_pref_store.cc
index 8ce5974..da545b8 100644
--- a/base/prefs/json_pref_store.cc
+++ b/base/prefs/json_pref_store.cc
@@ -150,17 +150,10 @@
const base::FilePath& filename,
const scoped_refptr<base::SequencedTaskRunner>& sequenced_task_runner,
scoped_ptr<PrefFilter> pref_filter)
- : path_(filename),
- sequenced_task_runner_(sequenced_task_runner),
- prefs_(new base::DictionaryValue()),
- read_only_(false),
- writer_(filename, sequenced_task_runner),
- pref_filter_(pref_filter.Pass()),
- initialized_(false),
- filtering_in_progress_(false),
- read_error_(PREF_READ_ERROR_NONE),
- write_count_histogram_(writer_.commit_interval(), path_) {
- DCHECK(!path_.empty());
+ : JsonPrefStore(filename,
+ base::FilePath(),
+ sequenced_task_runner,
+ pref_filter.Pass()) {
}
JsonPrefStore::JsonPrefStore(
@@ -177,6 +170,7 @@
pref_filter_(pref_filter.Pass()),
initialized_(false),
filtering_in_progress_(false),
+ pending_lossy_write_(false),
read_error_(PREF_READ_ERROR_NONE),
write_count_histogram_(writer_.commit_interval(), path_) {
DCHECK(!path_.empty());
@@ -236,7 +230,7 @@
base::Value* old_value = NULL;
prefs_->Get(key, &old_value);
if (!old_value || !value->Equals(old_value)) {
- prefs_->Set(key, new_value.release());
+ prefs_->Set(key, new_value.Pass());
ReportValueChanged(key, flags);
}
}
@@ -251,9 +245,8 @@
base::Value* old_value = NULL;
prefs_->Get(key, &old_value);
if (!old_value || !value->Equals(old_value)) {
- prefs_->Set(key, new_value.release());
- if (!read_only_)
- writer_.ScheduleWrite(this);
+ prefs_->Set(key, new_value.Pass());
+ ScheduleWrite(flags);
}
}
@@ -268,8 +261,7 @@
DCHECK(CalledOnValidThread());
prefs_->RemovePath(key, NULL);
- if (!read_only_)
- writer_.ScheduleWrite(this);
+ ScheduleWrite(flags);
}
bool JsonPrefStore::ReadOnly() const {
@@ -309,6 +301,11 @@
void JsonPrefStore::CommitPendingWrite() {
DCHECK(CalledOnValidThread());
+ // Schedule a write for any lossy writes that are outstanding to ensure that
+ // they get flushed when this function is called.
+ if (pending_lossy_write_)
+ writer_.ScheduleWrite(this);
+
if (writer_.HasPendingWrite() && !read_only_)
writer_.DoScheduledWrite();
}
@@ -321,8 +318,7 @@
FOR_EACH_OBSERVER(PrefStore::Observer, observers_, OnPrefValueChanged(key));
- if (!read_only_)
- writer_.ScheduleWrite(this);
+ ScheduleWrite(flags);
}
void JsonPrefStore::RegisterOnNextSuccessfulWriteCallback(
@@ -401,6 +397,8 @@
bool JsonPrefStore::SerializeData(std::string* output) {
DCHECK(CalledOnValidThread());
+ pending_lossy_write_ = false;
+
write_count_histogram_.RecordWriteOccured();
if (pref_filter_)
@@ -432,8 +430,8 @@
initialized_ = true;
- if (schedule_write && !read_only_)
- writer_.ScheduleWrite(this);
+ if (schedule_write)
+ ScheduleWrite(DEFAULT_PREF_WRITE_FLAGS);
if (error_delegate_ && read_error_ != PREF_READ_ERROR_NONE)
error_delegate_->OnError(read_error_);
@@ -445,6 +443,16 @@
return;
}
+void JsonPrefStore::ScheduleWrite(uint32 flags) {
+ if (read_only_)
+ return;
+
+ if (flags & LOSSY_PREF_WRITE_FLAG)
+ pending_lossy_write_ = true;
+ else
+ writer_.ScheduleWrite(this);
+}
+
// NOTE: This value should NOT be changed without renaming the histogram
// otherwise it will create incompatible buckets.
const int32_t
diff --git a/base/prefs/json_pref_store.h b/base/prefs/json_pref_store.h
index 2ad546d..ef260eb 100644
--- a/base/prefs/json_pref_store.h
+++ b/base/prefs/json_pref_store.h
@@ -29,6 +29,7 @@
class DictionaryValue;
class FilePath;
class HistogramBase;
+class JsonPrefStoreLossyWriteTest;
class SequencedTaskRunner;
class SequencedWorkerPool;
class Value;
@@ -165,6 +166,7 @@
WriteCountHistogramTestMultiplePeriods);
FRIEND_TEST_ALL_PREFIXES(base::JsonPrefStoreTest,
WriteCountHistogramTestPeriodWithGaps);
+ friend class base::JsonPrefStoreLossyWriteTest;
~JsonPrefStore() override;
@@ -190,6 +192,10 @@
scoped_ptr<base::DictionaryValue> prefs,
bool schedule_write);
+ // Schedule a write with the file writer as long as |flags| doesn't contain
+ // WriteablePrefStore::LOSSY_PREF_WRITE_FLAG.
+ void ScheduleWrite(uint32 flags);
+
const base::FilePath path_;
const base::FilePath alternate_path_;
const scoped_refptr<base::SequencedTaskRunner> sequenced_task_runner_;
@@ -208,6 +214,7 @@
bool initialized_;
bool filtering_in_progress_;
+ bool pending_lossy_write_;
PrefReadError read_error_;
std::set<std::string> keys_need_empty_value_;
diff --git a/base/prefs/json_pref_store_unittest.cc b/base/prefs/json_pref_store_unittest.cc
index 0fab868..67a8adb 100644
--- a/base/prefs/json_pref_store_unittest.cc
+++ b/base/prefs/json_pref_store_unittest.cc
@@ -108,9 +108,7 @@
void TearDown() override {
// Make sure all pending tasks have been processed (e.g., deleting the
// JsonPrefStore may post write tasks).
- message_loop_.task_runner()->PostTask(FROM_HERE,
- MessageLoop::QuitWhenIdleClosure());
- message_loop_.Run();
+ RunLoop().RunUntilIdle();
}
// The path to temporary directory used to contain the test operations.
@@ -127,7 +125,7 @@
// Test fallback behavior for a nonexistent file.
TEST_F(JsonPrefStoreTest, NonExistentFile) {
- base::FilePath bogus_input_file = data_dir_.AppendASCII("read.txt");
+ base::FilePath bogus_input_file = temp_dir_.path().AppendASCII("read.txt");
ASSERT_FALSE(PathExists(bogus_input_file));
scoped_refptr<JsonPrefStore> pref_store = new JsonPrefStore(
bogus_input_file, message_loop_.task_runner(), scoped_ptr<PrefFilter>());
@@ -138,9 +136,9 @@
// Test fallback behavior for a nonexistent file and alternate file.
TEST_F(JsonPrefStoreTest, NonExistentFileAndAlternateFile) {
- base::FilePath bogus_input_file = data_dir_.AppendASCII("read.txt");
+ base::FilePath bogus_input_file = temp_dir_.path().AppendASCII("read.txt");
base::FilePath bogus_alternate_input_file =
- data_dir_.AppendASCII("read_alternate.txt");
+ temp_dir_.path().AppendASCII("read_alternate.txt");
ASSERT_FALSE(PathExists(bogus_input_file));
ASSERT_FALSE(PathExists(bogus_alternate_input_file));
scoped_refptr<JsonPrefStore> pref_store =
@@ -321,7 +319,7 @@
// Write to file.
pref_store->CommitPendingWrite();
- MessageLoop::current()->RunUntilIdle();
+ RunLoop().RunUntilIdle();
// Reload.
pref_store = new JsonPrefStore(pref_file, message_loop_.task_runner(),
@@ -360,7 +358,7 @@
// Tests asynchronous reading of the file when there is no file.
TEST_F(JsonPrefStoreTest, AsyncNonExistingFile) {
- base::FilePath bogus_input_file = data_dir_.AppendASCII("read.txt");
+ base::FilePath bogus_input_file = temp_dir_.path().AppendASCII("read.txt");
ASSERT_FALSE(PathExists(bogus_input_file));
scoped_refptr<JsonPrefStore> pref_store = new JsonPrefStore(
bogus_input_file, message_loop_.task_runner(), scoped_ptr<PrefFilter>());
@@ -809,4 +807,125 @@
ASSERT_EQ(6, samples->TotalCount());
}
+class JsonPrefStoreLossyWriteTest : public JsonPrefStoreTest {
+ protected:
+ void SetUp() override {
+ JsonPrefStoreTest::SetUp();
+ test_file_ = temp_dir_.path().AppendASCII("test.json");
+ }
+
+ // Creates a JsonPrefStore with the given |file_writer|.
+ scoped_refptr<JsonPrefStore> CreatePrefStore() {
+ return new JsonPrefStore(test_file_, message_loop_.task_runner(),
+ scoped_ptr<PrefFilter>());
+ }
+
+ // Return the ImportantFileWriter for a given JsonPrefStore.
+ ImportantFileWriter* GetImportantFileWriter(
+ scoped_refptr<JsonPrefStore> pref_store) {
+ return &(pref_store->writer_);
+ }
+
+ // Get the contents of kTestFile. Pumps the message loop before returning the
+ // result.
+ std::string GetTestFileContents() {
+ RunLoop().RunUntilIdle();
+ std::string file_contents;
+ ReadFileToString(test_file_, &file_contents);
+ return file_contents;
+ }
+
+ private:
+ base::FilePath test_file_;
+};
+
+TEST_F(JsonPrefStoreLossyWriteTest, LossyWriteBasic) {
+ scoped_refptr<JsonPrefStore> pref_store = CreatePrefStore();
+ ImportantFileWriter* file_writer = GetImportantFileWriter(pref_store);
+
+ // Set a normal pref and check that it gets scheduled to be written.
+ ASSERT_FALSE(file_writer->HasPendingWrite());
+ pref_store->SetValue("normal", new base::StringValue("normal"),
+ WriteablePrefStore::DEFAULT_PREF_WRITE_FLAGS);
+ ASSERT_TRUE(file_writer->HasPendingWrite());
+ file_writer->DoScheduledWrite();
+ ASSERT_EQ("{\"normal\":\"normal\"}", GetTestFileContents());
+ ASSERT_FALSE(file_writer->HasPendingWrite());
+
+ // Set a lossy pref and check that it is not scheduled to be written.
+ // SetValue/RemoveValue.
+ pref_store->SetValue("lossy", new base::StringValue("lossy"),
+ WriteablePrefStore::LOSSY_PREF_WRITE_FLAG);
+ ASSERT_FALSE(file_writer->HasPendingWrite());
+ pref_store->RemoveValue("lossy", WriteablePrefStore::LOSSY_PREF_WRITE_FLAG);
+ ASSERT_FALSE(file_writer->HasPendingWrite());
+
+ // SetValueSilently/RemoveValueSilently.
+ pref_store->SetValueSilently("lossy", new base::StringValue("lossy"),
+ WriteablePrefStore::LOSSY_PREF_WRITE_FLAG);
+ ASSERT_FALSE(file_writer->HasPendingWrite());
+ pref_store->RemoveValueSilently("lossy",
+ WriteablePrefStore::LOSSY_PREF_WRITE_FLAG);
+ ASSERT_FALSE(file_writer->HasPendingWrite());
+
+ // ReportValueChanged.
+ pref_store->SetValue("lossy", new base::StringValue("lossy"),
+ WriteablePrefStore::LOSSY_PREF_WRITE_FLAG);
+ ASSERT_FALSE(file_writer->HasPendingWrite());
+ pref_store->ReportValueChanged("lossy",
+ WriteablePrefStore::LOSSY_PREF_WRITE_FLAG);
+ ASSERT_FALSE(file_writer->HasPendingWrite());
+
+ // Call CommitPendingWrite and check that the lossy pref and the normal pref
+ // are there with the last values set above.
+ pref_store->CommitPendingWrite();
+ ASSERT_FALSE(file_writer->HasPendingWrite());
+ ASSERT_EQ("{\"lossy\":\"lossy\",\"normal\":\"normal\"}",
+ GetTestFileContents());
+}
+
+TEST_F(JsonPrefStoreLossyWriteTest, LossyWriteMixedLossyFirst) {
+ scoped_refptr<JsonPrefStore> pref_store = CreatePrefStore();
+ ImportantFileWriter* file_writer = GetImportantFileWriter(pref_store);
+
+ // Set a lossy pref and check that it is not scheduled to be written.
+ ASSERT_FALSE(file_writer->HasPendingWrite());
+ pref_store->SetValue("lossy", new base::StringValue("lossy"),
+ WriteablePrefStore::LOSSY_PREF_WRITE_FLAG);
+ ASSERT_FALSE(file_writer->HasPendingWrite());
+
+ // Set a normal pref and check that it is scheduled to be written.
+ pref_store->SetValue("normal", new base::StringValue("normal"),
+ WriteablePrefStore::DEFAULT_PREF_WRITE_FLAGS);
+ ASSERT_TRUE(file_writer->HasPendingWrite());
+
+ // Call DoScheduledWrite and check both prefs get written.
+ file_writer->DoScheduledWrite();
+ ASSERT_EQ("{\"lossy\":\"lossy\",\"normal\":\"normal\"}",
+ GetTestFileContents());
+ ASSERT_FALSE(file_writer->HasPendingWrite());
+}
+
+TEST_F(JsonPrefStoreLossyWriteTest, LossyWriteMixedLossySecond) {
+ scoped_refptr<JsonPrefStore> pref_store = CreatePrefStore();
+ ImportantFileWriter* file_writer = GetImportantFileWriter(pref_store);
+
+ // Set a normal pref and check that it is scheduled to be written.
+ ASSERT_FALSE(file_writer->HasPendingWrite());
+ pref_store->SetValue("normal", new base::StringValue("normal"),
+ WriteablePrefStore::DEFAULT_PREF_WRITE_FLAGS);
+ ASSERT_TRUE(file_writer->HasPendingWrite());
+
+ // Set a lossy pref and check that the write is still scheduled.
+ pref_store->SetValue("lossy", new base::StringValue("lossy"),
+ WriteablePrefStore::LOSSY_PREF_WRITE_FLAG);
+ ASSERT_TRUE(file_writer->HasPendingWrite());
+
+ // Call DoScheduledWrite and check both prefs get written.
+ file_writer->DoScheduledWrite();
+ ASSERT_EQ("{\"lossy\":\"lossy\",\"normal\":\"normal\"}",
+ GetTestFileContents());
+ ASSERT_FALSE(file_writer->HasPendingWrite());
+}
+
} // namespace base
diff --git a/base/prefs/pref_service.cc b/base/prefs/pref_service.cc
index ad23157..6e1d58c 100644
--- a/base/prefs/pref_service.cc
+++ b/base/prefs/pref_service.cc
@@ -190,8 +190,7 @@
DCHECK(CalledOnValidThread());
scoped_ptr<base::DictionaryValue> out(new base::DictionaryValue);
for (const auto& it : *pref_registry_) {
- const base::Value* value = GetPreferenceValue(it.first);
- out->Set(it.first, value->DeepCopy());
+ out->Set(it.first, GetPreferenceValue(it.first)->CreateDeepCopy());
}
return out.Pass();
}
@@ -204,7 +203,7 @@
const Preference* pref = FindPreference(it.first);
if (pref->IsDefaultValue())
continue;
- out->Set(it.first, pref->GetValue()->DeepCopy());
+ out->Set(it.first, pref->GetValue()->CreateDeepCopy());
}
return out.Pass();
}
@@ -216,7 +215,7 @@
for (const auto& it : *pref_registry_) {
const base::Value* value = GetPreferenceValue(it.first);
DCHECK(value);
- out->SetWithoutPathExpansion(it.first, value->DeepCopy());
+ out->SetWithoutPathExpansion(it.first, value->CreateDeepCopy());
}
return out.Pass();
}
diff --git a/base/profiler/scoped_profile.h b/base/profiler/scoped_profile.h
index 6b0c800..2c4105d 100644
--- a/base/profiler/scoped_profile.h
+++ b/base/profiler/scoped_profile.h
@@ -62,4 +62,4 @@
} // namespace tracked_objects
-#endif // BASE_PROFILER_SCOPED_PROFILE_H_
+#endif // BASE_PROFILER_SCOPED_PROFILE_H_
diff --git a/base/test/values_test_util.cc b/base/test/values_test_util.cc
index c5dfd79..3e762b9 100644
--- a/base/test/values_test_util.cc
+++ b/base/test/values_test_util.cc
@@ -69,7 +69,7 @@
NULL, &error_msg));
if (!result) {
ADD_FAILURE() << "Failed to parse \"" << json << "\": " << error_msg;
- result.reset(Value::CreateNullValue());
+ result = Value::CreateNullValue();
}
return result.Pass();
}
diff --git a/base/trace_event/memory_dump_request_args.h b/base/trace_event/memory_dump_request_args.h
index 4fb0335..4d3763a 100644
--- a/base/trace_event/memory_dump_request_args.h
+++ b/base/trace_event/memory_dump_request_args.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_TRACE_EVENT_MEMORY_DUMP_REQUEST_H_
-#define BASE_TRACE_EVENT_MEMORY_DUMP_REQUEST_H_
+#ifndef BASE_TRACE_EVENT_MEMORY_DUMP_REQUEST_ARGS_H_
+#define BASE_TRACE_EVENT_MEMORY_DUMP_REQUEST_ARGS_H_
// This file defines the types and structs used to issue memory dump requests.
// These are also used in the IPCs for coordinating inter-process memory dumps.
@@ -38,4 +38,4 @@
} // namespace trace_event
} // namespace base
-#endif // BASE_TRACE_EVENT_MEMORY_DUMP_REQUEST_H_
+#endif // BASE_TRACE_EVENT_MEMORY_DUMP_REQUEST_ARGS_H_
diff --git a/base/trace_event/trace_event_etw_export_win.cc b/base/trace_event/trace_event_etw_export_win.cc
index 1cb3b8c..28c154c 100644
--- a/base/trace_event/trace_event_etw_export_win.cc
+++ b/base/trace_event/trace_event_etw_export_win.cc
@@ -132,7 +132,9 @@
!EventEnabledChromeEvent())
return;
- std::string phase_string;
+ const char* phase_string = nullptr;
+ // Space to store the phase identifier and null-terminator, when needed.
+ char phase_buffer[2];
switch (phase) {
case TRACE_EVENT_PHASE_BEGIN:
phase_string = "Begin";
@@ -195,14 +197,20 @@
phase_string = "Phase Delete Object";
break;
default:
- phase_string.push_back(phase);
+ phase_buffer[0] = phase;
+ phase_buffer[1] = 0;
+ phase_string = phase_buffer;
break;
}
std::string arg_values_string[3];
for (int i = 0; i < num_args; i++) {
if (arg_types[i] == TRACE_VALUE_TYPE_CONVERTABLE) {
- convertable_values[i]->AppendAsTraceFormat(arg_values_string + i);
+ // Temporarily do nothing here. This function consumes 1/3 to 1/2 of
+ // *total* process CPU time when ETW tracing, and many of the strings
+ // created exceed WPA's 4094 byte limit and are shown as:
+ // "Unable to parse data". See crbug.com/488257
+ //convertable_values[i]->AppendAsTraceFormat(arg_values_string + i);
} else {
TraceEvent::TraceValue trace_event;
trace_event.as_uint = arg_values[i];
@@ -212,7 +220,7 @@
}
EventWriteChromeEvent(
- name, phase_string.c_str(), num_args > 0 ? arg_names[0] : "",
+ name, phase_string, num_args > 0 ? arg_names[0] : "",
arg_values_string[0].c_str(), num_args > 1 ? arg_names[1] : "",
arg_values_string[1].c_str(), num_args > 2 ? arg_names[2] : "",
arg_values_string[2].c_str());
diff --git a/base/trace_event/trace_event_etw_export_win.h b/base/trace_event/trace_event_etw_export_win.h
index 3d26b33..eefe820 100644
--- a/base/trace_event/trace_event_etw_export_win.h
+++ b/base/trace_event/trace_event_etw_export_win.h
@@ -3,8 +3,8 @@
// found in the LICENSE file.
// This file contains the Windows-specific exporting to ETW.
-#ifndef BASE_TRACE_EVENT_TRACE_ETW_EXPORT_H_
-#define BASE_TRACE_EVENT_TRACE_ETW_EXPORT_H_
+#ifndef BASE_TRACE_EVENT_TRACE_EVENT_ETW_EXPORT_WIN_H_
+#define BASE_TRACE_EVENT_TRACE_EVENT_ETW_EXPORT_WIN_H_
#include "base/base_export.h"
#include "base/trace_event/trace_event_impl.h"
@@ -72,4 +72,4 @@
} // namespace trace_event
} // namespace base
-#endif // BASE_TRACE_EVENT_TRACE_ETW_EXPORT_H_
+#endif // BASE_TRACE_EVENT_TRACE_EVENT_ETW_EXPORT_WIN_H_
diff --git a/base/tuple.h b/base/tuple.h
index 88c3075..4628aa9 100644
--- a/base/tuple.h
+++ b/base/tuple.h
@@ -25,8 +25,8 @@
// DispatchToMethod(&foo, &Foo::SomeMeth, MakeTuple(1, 2, 3));
// // foo->SomeMeth(1, 2, 3);
-#ifndef BASE_TUPLE_H__
-#define BASE_TUPLE_H__
+#ifndef BASE_TUPLE_H_
+#define BASE_TUPLE_H_
#include "base/bind_helpers.h"
@@ -329,4 +329,4 @@
MakeIndexSequence<sizeof...(OutTs)>());
}
-#endif // BASE_TUPLE_H__
+#endif // BASE_TUPLE_H_
diff --git a/base/values.cc b/base/values.cc
index f448f51..4093eba 100644
--- a/base/values.cc
+++ b/base/values.cc
@@ -85,8 +85,8 @@
}
// static
-Value* Value::CreateNullValue() {
- return new Value(TYPE_NULL);
+scoped_ptr<Value> Value::CreateNullValue() {
+ return make_scoped_ptr(new Value(TYPE_NULL));
}
bool Value::GetAsBinary(const BinaryValue** out_value) const {
@@ -137,7 +137,7 @@
// This method should only be getting called for null Values--all subclasses
// need to provide their own implementation;.
DCHECK(IsType(TYPE_NULL));
- return CreateNullValue();
+ return CreateNullValue().release();
}
scoped_ptr<Value> Value::CreateDeepCopy() const {
@@ -1137,6 +1137,10 @@
return result;
}
+scoped_ptr<ListValue> ListValue::CreateDeepCopy() const {
+ return make_scoped_ptr(DeepCopy());
+}
+
bool ListValue::Equals(const Value* other) const {
if (other->GetType() != GetType())
return false;
diff --git a/base/values.h b/base/values.h
index ca046f1..e32edec 100644
--- a/base/values.h
+++ b/base/values.h
@@ -64,7 +64,7 @@
virtual ~Value();
- static Value* CreateNullValue();
+ static scoped_ptr<Value> CreateNullValue();
// Returns the type of the value stored by the current Value object.
// Each type will be implemented by only one subclass of Value, so it's
@@ -494,6 +494,9 @@
ListValue* DeepCopy() const override;
bool Equals(const Value* other) const override;
+ // Preferred version of DeepCopy. TODO(estade): remove DeepCopy.
+ scoped_ptr<ListValue> CreateDeepCopy() const;
+
private:
ValueVector list_;
diff --git a/base/values_unittest.cc b/base/values_unittest.cc
index b365a22..6466a96 100644
--- a/base/values_unittest.cc
+++ b/base/values_unittest.cc
@@ -320,9 +320,8 @@
TEST(ValuesTest, DictionaryWithoutPathExpansion) {
DictionaryValue dict;
- dict.Set("this.is.expanded", make_scoped_ptr(Value::CreateNullValue()));
- dict.SetWithoutPathExpansion("this.isnt.expanded",
- make_scoped_ptr(Value::CreateNullValue()));
+ dict.Set("this.is.expanded", Value::CreateNullValue());
+ dict.SetWithoutPathExpansion("this.isnt.expanded", Value::CreateNullValue());
EXPECT_FALSE(dict.HasKey("this.is.expanded"));
EXPECT_TRUE(dict.HasKey("this"));
@@ -392,7 +391,7 @@
TEST(ValuesTest, DeepCopy) {
DictionaryValue original_dict;
- scoped_ptr<Value> scoped_null(Value::CreateNullValue());
+ scoped_ptr<Value> scoped_null = Value::CreateNullValue();
Value* original_null = scoped_null.get();
original_dict.Set("null", scoped_null.Pass());
scoped_ptr<FundamentalValue> scoped_bool(new FundamentalValue(true));
@@ -549,8 +548,8 @@
EXPECT_NE(null1.get(), null2.get());
EXPECT_TRUE(null1->Equals(null2.get()));
- scoped_ptr<Value> boolean(new FundamentalValue(false));
- EXPECT_FALSE(null1->Equals(boolean.get()));
+ FundamentalValue boolean(false);
+ EXPECT_FALSE(null1->Equals(&boolean));
DictionaryValue dv;
dv.SetBoolean("a", false);
@@ -558,14 +557,14 @@
dv.SetDouble("c", 2.5);
dv.SetString("d1", "string");
dv.SetString("d2", ASCIIToUTF16("http://google.com"));
- dv.Set("e", make_scoped_ptr(Value::CreateNullValue()));
+ dv.Set("e", Value::CreateNullValue());
scoped_ptr<DictionaryValue> copy = dv.CreateDeepCopy();
EXPECT_TRUE(dv.Equals(copy.get()));
scoped_ptr<ListValue> list(new ListValue);
ListValue* original_list = list.get();
- list->Append(make_scoped_ptr(Value::CreateNullValue()));
+ list->Append(Value::CreateNullValue());
list->Append(make_scoped_ptr(new DictionaryValue));
scoped_ptr<Value> list_copy(list->CreateDeepCopy());
diff --git a/base/win/resource_util.h b/base/win/resource_util.h
index f3444ae..8a8baa0 100644
--- a/base/win/resource_util.h
+++ b/base/win/resource_util.h
@@ -5,8 +5,8 @@
// This file contains utility functions for accessing resources in external
// files (DLLs) or embedded in the executable itself.
-#ifndef BASE_WIN_RESOURCE_UTIL_H__
-#define BASE_WIN_RESOURCE_UTIL_H__
+#ifndef BASE_WIN_RESOURCE_UTIL_H_
+#define BASE_WIN_RESOURCE_UTIL_H_
#include <windows.h>
@@ -36,4 +36,4 @@
} // namespace win
} // namespace base
-#endif // BASE_WIN_RESOURCE_UTIL_H__
+#endif // BASE_WIN_RESOURCE_UTIL_H_
diff --git a/base/win/scoped_handle.cc b/base/win/scoped_handle.cc
index 2ebef32..ce944e4 100644
--- a/base/win/scoped_handle.cc
+++ b/base/win/scoped_handle.cc
@@ -152,6 +152,12 @@
if (!enabled_)
return;
+ // Idea here is to make our handles non-closable until we close it ourselves.
+ // Handles provided could be totally fabricated especially through our
+ // unittest, we are ignoring that for now by not checking return value.
+ ::SetHandleInformation(handle, HANDLE_FLAG_PROTECT_FROM_CLOSE,
+ HANDLE_FLAG_PROTECT_FROM_CLOSE);
+
// Grab the thread id before the lock.
DWORD thread_id = GetCurrentThreadId();
@@ -172,6 +178,15 @@
if (!enabled_)
return;
+ // We expect handle to be protected till this point.
+ DWORD flags = 0;
+ if (::GetHandleInformation(handle, &flags)) {
+ CHECK_NE(0U, (flags & HANDLE_FLAG_PROTECT_FROM_CLOSE));
+
+ // Unprotect handle so that it could be closed.
+ ::SetHandleInformation(handle, HANDLE_FLAG_PROTECT_FROM_CLOSE, 0);
+ }
+
AutoNativeLock lock(*lock_);
HandleMap::iterator i = map_.find(handle);
if (i == map_.end())
diff --git a/base/win/startup_information.h b/base/win/startup_information.h
index 73d9f3e..3f18ee5 100644
--- a/base/win/startup_information.h
+++ b/base/win/startup_information.h
@@ -47,4 +47,4 @@
} // namespace win
} // namespace base
-#endif // BASE_WIN_STARTUP_INFORMATION_H__
+#endif // BASE_WIN_STARTUP_INFORMATION_H_
diff --git a/build/all.gyp b/build/all.gyp
index 1866c2e..4d79a84 100644
--- a/build/all.gyp
+++ b/build/all.gyp
@@ -319,10 +319,14 @@
'../ui/base/ui_base_tests.gyp:ui_base_unittests',
'../ui/display/display.gyp:display_unittests',
'../ui/gfx/gfx_tests.gyp:gfx_unittests',
- '../ui/gl/gl_tests.gyp:gl_unittests',
'../url/url.gyp:url_unittests',
],
'conditions': [
+ ['OS!="ios"', {
+ 'dependencies': [
+ '../ui/gl/gl_tests.gyp:gl_unittests',
+ ],
+ }],
['OS!="ios" and OS!="mac"', {
'dependencies': [
'../ui/touch_selection/ui_touch_selection.gyp:ui_touch_selection_unittests',
@@ -485,6 +489,11 @@
'../components/nacl.gyp:nacl_loader_unittests',
],
}],
+ ['disable_nacl==0 and disable_nacl_untrusted==0 and OS=="linux"', {
+ 'dependencies': [
+ '../components/nacl_nonsfi.gyp:nacl_helper_nonsfi_unittests',
+ ],
+ }],
['disable_nacl==0 and disable_nacl_untrusted==0', {
'dependencies': [
'../mojo/mojo_nacl_untrusted.gyp:libmojo',
diff --git a/build/android/adb_install_apk.py b/build/android/adb_install_apk.py
index 7bc634c..00bd38e 100755
--- a/build/android/adb_install_apk.py
+++ b/build/android/adb_install_apk.py
@@ -11,6 +11,7 @@
import sys
from pylib import constants
+from pylib.device import device_errors
from pylib.device import device_utils
@@ -73,14 +74,11 @@
devices = device_utils.DeviceUtils.HealthyDevices()
if options.device:
- device_serials = [d.adb.GetDeviceSerial() for d in devices]
- if options.device not in device_serials:
- raise Exception('Error: %s not in attached devices %s' % (options.device,
- ','.join(device_serials)))
- devices = [options.device]
-
- if not devices:
- raise Exception('Error: no connected devices')
+ devices = [d for d in devices if d == options.device]
+ if not devices:
+ raise device_errors.DeviceUnreachableError(options.device)
+ elif not devices:
+ raise device_errors.NoDevicesError()
device_utils.DeviceUtils.parallel(devices).Install(
options.apk, reinstall=options.keep_data)
diff --git a/build/android/adb_reverse_forwarder.py b/build/android/adb_reverse_forwarder.py
index 6cae0cf..3ce5359 100755
--- a/build/android/adb_reverse_forwarder.py
+++ b/build/android/adb_reverse_forwarder.py
@@ -19,6 +19,7 @@
from pylib import constants
from pylib import forwarder
from pylib.device import adb_wrapper
+from pylib.device import device_errors
from pylib.device import device_utils
from pylib.utils import run_tests_helper
@@ -56,16 +57,15 @@
devices = device_utils.DeviceUtils.HealthyDevices()
if options.device:
- if options.device not in [str(d) for d in devices]:
- raise Exception('Error: %s not in attached devices %s' % (options.device,
- ','.join(devices)))
- devices = [options.device]
- else:
- if not devices:
- raise Exception('Error: no connected devices')
+ device = next((d for d in devices if d == options.device), None)
+ if not device:
+ raise device_errors.DeviceUnreachableError(options.device)
+ elif devices:
+ device = devices[0]
logging.info('No device specified. Defaulting to %s', devices[0])
+ else:
+ raise device_errors.NoDevicesError()
- device = devices[0]
constants.SetBuildType(options.build_type)
try:
forwarder.Forwarder.Map(port_pairs, device)
diff --git a/build/android/buildbot/bb_device_steps.py b/build/android/buildbot/bb_device_steps.py
index 53646e3..665c736 100755
--- a/build/android/buildbot/bb_device_steps.py
+++ b/build/android/buildbot/bb_device_steps.py
@@ -18,7 +18,6 @@
sys.path.append(os.path.join(os.path.dirname(__file__), '..'))
import provision_devices
-from pylib import android_commands
from pylib import constants
from pylib.device import device_utils
from pylib.gtest import gtest_config
@@ -100,6 +99,7 @@
'chrome_proxy',
'components_browsertests',
'gfx_unittests',
+ 'gl_unittests',
'gpu',
'python_unittests',
'telemetry_unittests',
@@ -214,9 +214,9 @@
"""
InstallApk(options, INSTRUMENTATION_TESTS['ChromeShell'], False)
args = ['--browser', 'android-chrome-shell']
- devices = android_commands.GetAttachedDevices()
+ devices = device_utils.DeviceUtils.HealthyDevices()
if devices:
- args = args + ['--device', devices[0]]
+ args = args + ['--device', devices[0].adb.GetDeviceSerial()]
bb_annotations.PrintNamedStep('chrome_proxy')
RunCmd(['tools/chrome_proxy/run_tests'] + args)
@@ -233,7 +233,7 @@
"""
InstallApk(options, INSTRUMENTATION_TESTS['ChromeShell'], False)
args = ['--browser', 'android-chrome-shell']
- devices = android_commands.GetAttachedDevices()
+ devices = device_utils.DeviceUtils.HealthyDevices()
if devices:
args = args + ['--device', 'android']
bb_annotations.PrintNamedStep(step_name)
@@ -585,6 +585,8 @@
lambda options: RunTestSuites(options, ['components_browsertests'])),
('gfx_unittests',
lambda options: RunTestSuites(options, ['gfx_unittests'])),
+ ('gl_unittests',
+ lambda options: RunTestSuites(options, ['gl_unittests'])),
('gpu', RunGPUTests),
('python_unittests', RunPythonUnitTests),
('telemetry_unittests', RunTelemetryUnitTests),
diff --git a/build/android/buildbot/bb_run_bot.py b/build/android/buildbot/bb_run_bot.py
index 2b5f31a..0c8a977 100755
--- a/build/android/buildbot/bb_run_bot.py
+++ b/build/android/buildbot/bb_run_bot.py
@@ -128,6 +128,7 @@
'base_junit_tests',
'components_browsertests',
'gfx_unittests',
+ 'gl_unittests',
]
flakiness_server = (
'--flakiness-server=%s' % constants.UPSTREAM_FLAKINESS_SERVER)
diff --git a/build/android/gyp/apk_install.py b/build/android/gyp/apk_install.py
index 19a217c..419dc17 100755
--- a/build/android/gyp/apk_install.py
+++ b/build/android/gyp/apk_install.py
@@ -58,6 +58,10 @@
parser = optparse.OptionParser()
parser.add_option('--apk-path',
help='Path to .apk to install.')
+ parser.add_option('--split-apk-path',
+ help='Path to .apk splits (can specify multiple times, causes '
+ '--install-multiple to be used.',
+ action='append')
parser.add_option('--install-record',
help='Path to install record (touched only when APK is installed).')
parser.add_option('--build-device-configuration',
@@ -85,7 +89,15 @@
force_install = HasInstallMetadataChanged(device, apk_package, metadata_path)
def Install():
- device.Install(options.apk_path, reinstall=True)
+ # TODO: Filter splits using split-select.
+ active_splits = options.split_apk_path
+ if active_splits:
+ device.adb.InstallMultiple(
+ [options.apk_path] + active_splits,
+ reinstall=True)
+ else:
+ device.Install(options.apk_path, reinstall=True)
+
RecordInstallMetadata(device, apk_package, metadata_path)
build_utils.Touch(options.install_record)
diff --git a/build/android/gyp/generate_split_manifest.py b/build/android/gyp/generate_split_manifest.py
new file mode 100755
index 0000000..1c84fe7
--- /dev/null
+++ b/build/android/gyp/generate_split_manifest.py
@@ -0,0 +1,96 @@
+#!/usr/bin/env python
+#
+# Copyright 2015 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.
+"""Creates an AndroidManifest.xml for an APK split.
+
+Given the manifest file for the main APK, generates an AndroidManifest.xml with
+the value required for a Split APK (package, versionCode, etc).
+"""
+
+import lxml.etree
+import optparse
+
+from util import build_utils
+
+MANIFEST_TEMPLATE = """<?xml version="1.0" encoding="utf-8"?>
+<manifest
+ xmlns:android="http://schemas.android.com/apk/res/android"
+ package="%(package)s"
+ split="%(split)s">
+ <application android:hasCode="%(has_code)s">
+ </application>
+</manifest>
+"""
+
+def ParseArgs():
+ """Parses command line options.
+
+ Returns:
+ An options object as from optparse.OptionsParser.parse_args()
+ """
+ parser = optparse.OptionParser()
+ build_utils.AddDepfileOption(parser)
+ parser.add_option('--main-manifest', help='The main manifest of the app')
+ parser.add_option('--out-manifest', help='The output manifest')
+ parser.add_option('--split', help='The name of the split')
+ parser.add_option(
+ '--has-code',
+ action='store_true',
+ default=False,
+ help='Whether the split will contain a .dex file')
+
+ (options, args) = parser.parse_args()
+
+ if args:
+ parser.error('No positional arguments should be given.')
+
+ # Check that required options have been provided.
+ required_options = ('main_manifest', 'out_manifest', 'split')
+ build_utils.CheckOptions(options, parser, required=required_options)
+
+ return options
+
+
+def Build(main_manifest, split, has_code):
+ """Builds a split manifest based on the manifest of the main APK.
+
+ Args:
+ main_manifest: the XML manifest of the main APK as a string
+ split: the name of the split as a string
+ has_code: whether this split APK will contain .dex files
+
+ Returns:
+ The XML split manifest as a string
+ """
+
+ doc = lxml.etree.fromstring(main_manifest)
+ package = doc.xpath('/manifest/@package')[0]
+
+ return MANIFEST_TEMPLATE % {
+ 'package': package,
+ 'split': split.replace('-', '_'),
+ 'has_code': str(has_code).lower()
+ }
+
+
+def main():
+ options = ParseArgs()
+ main_manifest = file(options.main_manifest).read()
+ split_manifest = Build(
+ main_manifest,
+ options.split,
+ options.has_code)
+
+ with file(options.out_manifest, 'w') as f:
+ f.write(split_manifest)
+
+ if options.depfile:
+ build_utils.WriteDepfile(
+ options.depfile,
+ [main_manifest] + build_utils.GetPythonDependencies())
+
+
+if __name__ == '__main__':
+ main()
diff --git a/build/android/gyp/jar.py b/build/android/gyp/jar.py
index 17f968c..48abf5e 100755
--- a/build/android/gyp/jar.py
+++ b/build/android/gyp/jar.py
@@ -27,16 +27,20 @@
jar_cmd.append(os.path.abspath(manifest_file))
jar_cmd.extend(class_files_rel)
- record_path = '%s.md5.stamp' % jar_path
- md5_check.CallAndRecordIfStale(
- lambda: build_utils.CheckOutput(jar_cmd, cwd=jar_cwd),
- record_path=record_path,
- input_paths=class_files,
- input_strings=jar_cmd,
- force=not os.path.exists(jar_path),
- )
+ with build_utils.TempDir() as temp_dir:
+ empty_file = os.path.join(temp_dir, '.empty')
+ build_utils.Touch(empty_file)
+ jar_cmd.append(os.path.relpath(empty_file, jar_cwd))
+ record_path = '%s.md5.stamp' % jar_path
+ md5_check.CallAndRecordIfStale(
+ lambda: build_utils.CheckOutput(jar_cmd, cwd=jar_cwd),
+ record_path=record_path,
+ input_paths=class_files,
+ input_strings=jar_cmd,
+ force=not os.path.exists(jar_path),
+ )
- build_utils.Touch(jar_path, fail_if_missing=True)
+ build_utils.Touch(jar_path, fail_if_missing=True)
def JarDirectory(classes_dir, excluded_classes, jar_path, manifest_file=None):
diff --git a/build/android/gyp/jar_toc.py b/build/android/gyp/jar_toc.py
index 3cafd6e..6d81008 100755
--- a/build/android/gyp/jar_toc.py
+++ b/build/android/gyp/jar_toc.py
@@ -72,8 +72,10 @@
def UpdateToc(jar_path, toc_path):
classes = GetClassesInZipFile(zipfile.ZipFile(jar_path))
- javap_output = CallJavap(classpath=jar_path, classes=classes)
- toc = ExtractToc(javap_output)
+ toc = ''
+ if len(classes) != 0:
+ javap_output = CallJavap(classpath=jar_path, classes=classes)
+ toc = ExtractToc(javap_output)
with open(toc_path, 'w') as tocfile:
tocfile.write(toc)
diff --git a/build/android/gyp/javac.py b/build/android/gyp/javac.py
index a0fcda8..e36fd43 100755
--- a/build/android/gyp/javac.py
+++ b/build/android/gyp/javac.py
@@ -236,11 +236,12 @@
break
java_files = filtered_java_files
- DoJavac(
- classpath,
- classes_dir,
- options.chromium_code,
- java_files)
+ if len(java_files) != 0:
+ DoJavac(
+ classpath,
+ classes_dir,
+ options.chromium_code,
+ java_files)
if options.jar_path:
if options.main_class or options.manifest_entry:
diff --git a/build/android/gyp/process_resources.py b/build/android/gyp/process_resources.py
index 7a5fdf8..4914189 100755
--- a/build/android/gyp/process_resources.py
+++ b/build/android/gyp/process_resources.py
@@ -73,6 +73,10 @@
help='Do not generate v14 resources. Instead, just verify that the '
'resources are already compatible with v14, i.e. they don\'t use '
'attributes that cause crashes on certain devices.')
+ parser.add_option(
+ '--v14-skip',
+ action="store_true",
+ help='Do not generate nor verify v14 resources')
parser.add_option(
'--extra-res-packages',
@@ -319,11 +323,12 @@
input_resource_dirs = build_utils.ParseGypList(options.resource_dirs)
- for resource_dir in input_resource_dirs:
- generate_v14_compatible_resources.GenerateV14Resources(
- resource_dir,
- v14_dir,
- options.v14_verify_only)
+ if not options.v14_skip:
+ for resource_dir in input_resource_dirs:
+ generate_v14_compatible_resources.GenerateV14Resources(
+ resource_dir,
+ v14_dir,
+ options.v14_verify_only)
dep_zips = build_utils.ParseGypList(options.dependencies_res_zips)
input_files += dep_zips
diff --git a/build/android/gyp/write_build_config.py b/build/android/gyp/write_build_config.py
index 0f3bfad..8507a95 100755
--- a/build/android/gyp/write_build_config.py
+++ b/build/android/gyp/write_build_config.py
@@ -79,9 +79,32 @@
def GetAllDepsConfigsInOrder(deps_config_paths):
- def Deps(path):
+ def GetDeps(path):
return set(GetDepConfig(path)['deps_configs'])
- return build_utils.GetSortedTransitiveDependencies(deps_config_paths, Deps)
+ return build_utils.GetSortedTransitiveDependencies(deps_config_paths, GetDeps)
+
+
+class Deps(object):
+ def __init__(self, direct_deps_config_paths):
+ self.all_deps_config_paths = GetAllDepsConfigsInOrder(
+ direct_deps_config_paths)
+ self.direct_deps_configs = [
+ GetDepConfig(p) for p in direct_deps_config_paths]
+ self.all_deps_configs = [
+ GetDepConfig(p) for p in self.all_deps_config_paths]
+
+ def All(self, wanted_type=None):
+ if type is None:
+ return self.all_deps_configs
+ return DepsOfType(wanted_type, self.all_deps_configs)
+
+ def Direct(self, wanted_type=None):
+ if wanted_type is None:
+ return self.direct_deps_configs
+ return DepsOfType(wanted_type, self.direct_deps_configs)
+
+ def AllConfigPaths(self):
+ return self.all_deps_config_paths
def main(argv):
@@ -166,20 +189,23 @@
direct_deps_config_paths = [
c for c in possible_deps_config_paths if not c in unknown_deps]
- all_deps_config_paths = GetAllDepsConfigsInOrder(direct_deps_config_paths)
- direct_deps_configs = [GetDepConfig(p) for p in direct_deps_config_paths]
- all_deps_configs = [GetDepConfig(p) for p in all_deps_config_paths]
+ deps = Deps(direct_deps_config_paths)
+ direct_library_deps = deps.Direct('java_library')
+ all_library_deps = deps.All('java_library')
- direct_library_deps = DepsOfType('java_library', direct_deps_configs)
- all_library_deps = DepsOfType('java_library', all_deps_configs)
-
- direct_resources_deps = DepsOfType('android_resources', direct_deps_configs)
- all_resources_deps = DepsOfType('android_resources', all_deps_configs)
+ direct_resources_deps = deps.Direct('android_resources')
+ all_resources_deps = deps.All('android_resources')
# Resources should be ordered with the highest-level dependency first so that
# overrides are done correctly.
all_resources_deps.reverse()
+ if options.type == 'android_apk' and options.tested_apk_config:
+ tested_apk_deps = Deps([options.tested_apk_config])
+ tested_apk_resources_deps = tested_apk_deps.All('android_resources')
+ all_resources_deps = [
+ d for d in all_resources_deps if not d in tested_apk_resources_deps]
+
# Initialize some common config.
config = {
'deps_info': {
@@ -265,10 +291,8 @@
# An instrumentation test apk should exclude the dex files that are in the apk
# under test.
if options.type == 'android_apk' and options.tested_apk_config:
- tested_apk_config_paths = GetAllDepsConfigsInOrder(
- [options.tested_apk_config])
- tested_apk_configs = [GetDepConfig(p) for p in tested_apk_config_paths]
- tested_apk_library_deps = DepsOfType('java_library', tested_apk_configs)
+ tested_apk_deps = Deps([options.tested_apk_config])
+ tested_apk_library_deps = tested_apk_deps.All('java_library')
tested_apk_deps_dex_files = [c['dex_path'] for c in tested_apk_library_deps]
deps_dex_files = [
p for p in deps_dex_files if not p in tested_apk_deps_dex_files]
@@ -325,7 +349,7 @@
if options.depfile:
build_utils.WriteDepfile(
options.depfile,
- all_deps_config_paths + build_utils.GetPythonDependencies())
+ deps.AllConfigPaths() + build_utils.GetPythonDependencies())
if __name__ == '__main__':
diff --git a/build/android/provision_devices.py b/build/android/provision_devices.py
index b366f0c..259bd55 100755
--- a/build/android/provision_devices.py
+++ b/build/android/provision_devices.py
@@ -50,10 +50,11 @@
def ProvisionDevices(options):
- if options.device is not None:
- devices = [options.device]
- else:
- devices = device_utils.DeviceUtils.HealthyDevices()
+ devices = device_utils.DeviceUtils.HealthyDevices()
+ if options.device:
+ devices = [d for d in devices if d == options.device]
+ if not devices:
+ raise device_errors.DeviceUnreachableError(options.device)
parallel_devices = device_utils.DeviceUtils.parallel(devices)
parallel_devices.pMap(ProvisionDevice, options)
diff --git a/build/android/pylib/android_commands.py b/build/android/pylib/android_commands.py
index 1ed1877..f7191f7 100644
--- a/build/android/pylib/android_commands.py
+++ b/build/android/pylib/android_commands.py
@@ -5,7 +5,11 @@
"""Provides an interface to communicate with the device via the adb command.
Assumes adb binary is currently on system path.
+
+Note that this module is deprecated.
"""
+# TODO(jbudorick): Delete this file once no clients use it.
+
# pylint: skip-file
import collections
diff --git a/build/android/pylib/device/adb_wrapper.py b/build/android/pylib/device/adb_wrapper.py
index 8e8abf8..f88eab3 100644
--- a/build/android/pylib/device/adb_wrapper.py
+++ b/build/android/pylib/device/adb_wrapper.py
@@ -415,6 +415,40 @@
raise device_errors.AdbCommandFailedError(
cmd, output, device_serial=self._device_serial)
+ def InstallMultiple(self, apk_paths, forward_lock=False, reinstall=False,
+ sd_card=False, allow_downgrade=False, partial=False,
+ timeout=60*2, retries=_DEFAULT_RETRIES):
+ """Install an apk with splits on the device.
+
+ Args:
+ apk_paths: Host path to the APK file.
+ forward_lock: (optional) If set forward-locks the app.
+ reinstall: (optional) If set reinstalls the app, keeping its data.
+ sd_card: (optional) If set installs on the SD card.
+ timeout: (optional) Timeout per try in seconds.
+ retries: (optional) Number of retries to attempt.
+ allow_downgrade: (optional) Allow versionCode downgrade.
+ partial: (optional) Package ID if apk_paths doesn't include all .apks.
+ """
+ for path in apk_paths:
+ _VerifyLocalFileExists(path)
+ cmd = ['install-multiple']
+ if forward_lock:
+ cmd.append('-l')
+ if reinstall:
+ cmd.append('-r')
+ if sd_card:
+ cmd.append('-s')
+ if allow_downgrade:
+ cmd.append('-d')
+ if partial:
+ cmd.extend(('-p', partial))
+ cmd.extend(apk_paths)
+ output = self._RunDeviceAdbCmd(cmd, timeout, retries)
+ if 'Success' not in output:
+ raise device_errors.AdbCommandFailedError(
+ cmd, output, device_serial=self._device_serial)
+
def Uninstall(self, package, keep_data=False, timeout=_DEFAULT_TIMEOUT,
retries=_DEFAULT_RETRIES):
"""Remove the app |package| from the device.
@@ -570,4 +604,3 @@
return self.GetState() == _READY_STATE
except device_errors.CommandFailedError:
return False
-
diff --git a/build/android/pylib/gtest/gtest_config.py b/build/android/pylib/gtest/gtest_config.py
index 6e332c7..76e0f50 100644
--- a/build/android/pylib/gtest/gtest_config.py
+++ b/build/android/pylib/gtest/gtest_config.py
@@ -29,6 +29,7 @@
'content_unittests',
'events_unittests',
'gl_tests',
+ 'gl_unittests',
'gpu_unittests',
'ipc_tests',
'media_unittests',
diff --git a/build/android/pylib/perf/perf_control.py b/build/android/pylib/perf/perf_control.py
index b6a0989..f89f397 100644
--- a/build/android/pylib/perf/perf_control.py
+++ b/build/android/pylib/perf/perf_control.py
@@ -6,8 +6,10 @@
import logging
from pylib import android_commands
+from pylib.device import device_errors
from pylib.device import device_utils
+
class PerfControl(object):
"""Provides methods for setting the performance mode of a device."""
_CPU_PATH = '/sys/devices/system/cpu'
@@ -28,7 +30,9 @@
def SetHighPerfMode(self):
"""Sets the highest stable performance mode for the device."""
- if not self._device.HasRoot():
+ try:
+ self._device.EnableRoot()
+ except device_errors.CommandFailedError:
message = 'Need root for performance mode. Results may be NOISY!!'
logging.warning(message)
# Add an additional warning at exit, such that it's clear that any results
diff --git a/build/android/pylib/perf/test_runner.py b/build/android/pylib/perf/test_runner.py
index 9d1f437..3bee602 100644
--- a/build/android/pylib/perf/test_runner.py
+++ b/build/android/pylib/perf/test_runner.py
@@ -66,11 +66,29 @@
from pylib.device import device_errors
+def GetPersistedResult(test_name):
+ file_name = os.path.join(constants.PERF_OUTPUT_DIR, test_name)
+ if not os.path.exists(file_name):
+ logging.error('File not found %s', file_name)
+ return None
+
+ with file(file_name, 'r') as f:
+ return pickle.loads(f.read())
+
+
def OutputJsonList(json_input, json_output):
with file(json_input, 'r') as i:
all_steps = json.load(i)
- step_values = [{'test': k, 'device_affinity': v['device_affinity']}
- for k, v in all_steps['steps'].iteritems()]
+
+ step_values = []
+ for k, v in all_steps['steps'].iteritems():
+ data = {'test': k, 'device_affinity': v['device_affinity']}
+
+ persisted_result = GetPersistedResult(k)
+ if persisted_result:
+ data['total_time'] = persisted_result['total_time']
+ step_values.append(data)
+
with file(json_output, 'w') as o:
o.write(json.dumps(step_values))
return 0
@@ -86,13 +104,9 @@
Returns:
exit code generated by the test step.
"""
- file_name = os.path.join(constants.PERF_OUTPUT_DIR, test_name)
- if not os.path.exists(file_name):
- logging.error('File not found %s', file_name)
+ persisted_result = GetPersistedResult(test_name)
+ if not persisted_result:
return 1
-
- with file(file_name, 'r') as f:
- persisted_result = pickle.loads(f.read())
logging.info('*' * 80)
logging.info('Output from:')
logging.info(persisted_result['cmd'])
diff --git a/build/android/screenshot.py b/build/android/screenshot.py
index c48a255..097739f 100755
--- a/build/android/screenshot.py
+++ b/build/android/screenshot.py
@@ -74,8 +74,11 @@
logging.getLogger().setLevel(logging.DEBUG)
devices = device_utils.DeviceUtils.HealthyDevices()
-
- if not options.device:
+ if options.device:
+ device = next((d for d in devices if d == options.device), None)
+ if not device:
+ raise device_errors.DeviceUnreachableError(options.device)
+ else:
if len(devices) > 1:
parser.error('Multiple devices are attached. '
'Please specify device serial number with --device.')
@@ -83,8 +86,6 @@
device = devices[0]
else:
raise device_errors.NoDevicesError()
- else:
- device = device_utils.DeviceUtils(options.device)
if options.video:
_CaptureVideo(device, host_file, options)
diff --git a/build/common.gypi b/build/common.gypi
index 5cab295..dfa4163 100644
--- a/build/common.gypi
+++ b/build/common.gypi
@@ -371,11 +371,11 @@
'configuration_policy%': 1,
# Variable safe_browsing is used to control the build time configuration
- # for safe browsing feature. Safe browsing can be compiled in 3 different
+ # for safe browsing feature. Safe browsing can be compiled in 4 different
# levels: 0 disables it, 1 enables it fully, and 2 enables only UI and
- # reporting features without enabling phishing and malware detection. This
- # is useful to integrate a third party phishing/malware detection to
- # existing safe browsing logic.
+ # reporting features for use with Data Saver on Mobile, and 3 enables
+ # extended mobile protection via an external API. When 3 is fully
+ # deployed, it will replace 2.
'safe_browsing%': 1,
# Web speech is enabled by default. Set to 0 to disable.
@@ -2174,23 +2174,17 @@
],
},
'clang_dynlib_flags%': '-Xclang -load -Xclang <(clang_lib_path) ',
- 'clang_plugin_args%': '',
}, { # OS == "win"
# On Windows, the plugin is built directly into clang, so there's
# no need to load it dynamically.
'clang_dynlib_flags%': '',
-
- # Don't error on plugin warnings on Windows until pre-existing warnings
- # are cleaned up. https://crbug.com/467287
- 'clang_plugin_args%': '-Xclang -plugin-arg-find-bad-constructs -Xclang warn-only',
}]
],
},
# If you change these, also change build/config/clang/BUILD.gn.
'clang_chrome_plugins_flags%':
'<(clang_dynlib_flags)'
- '-Xclang -add-plugin -Xclang find-bad-constructs '
- '<(clang_plugin_args)',
+ '-Xclang -add-plugin -Xclang find-bad-constructs ',
}],
['asan==1 or msan==1 or lsan==1 or tsan==1', {
'clang%': 1,
@@ -2934,6 +2928,8 @@
'defines': ['ENABLE_AUTOFILL_DIALOG=1'],
}],
['enable_prod_wallet_service==1', {
+ # In GN, this is set on the autofill tagets only. See
+ # //components/autofill/core/browser:wallet_service
'defines': ['ENABLE_PROD_WALLET_SERVICE=1'],
}],
['enable_background==1', {
@@ -3012,8 +3008,8 @@
# SAFE_BROWSING_DB_REMOTE - service talks via API to a database
# SAFE_BROWSING_CSD - enable client-side phishing detection.
['safe_browsing==1', {
- # TODO(nparker): Remove existing uses of FULL_SAFE_BROWSING
'defines': [
+ # TODO(nparker): Remove existing uses of FULL_SAFE_BROWSING
'FULL_SAFE_BROWSING',
'SAFE_BROWSING_CSD',
'SAFE_BROWSING_DB_LOCAL',
@@ -3027,6 +3023,14 @@
'SAFE_BROWSING_SERVICE',
],
}],
+ ['safe_browsing==3', {
+ 'defines': [
+ # TODO(nparker): Remove existing uses of MOBILE_SAFE_BROWSING
+ 'MOBILE_SAFE_BROWSING',
+ 'SAFE_BROWSING_DB_REMOTE',
+ 'SAFE_BROWSING_SERVICE',
+ ],
+ }],
], # conditions for 'target_defaults'
'target_conditions': [
['<(use_libpci)==1', {
@@ -3602,6 +3606,13 @@
],
},
}],
+ ['os_posix==1 and OS=="linux"', {
+ 'defines': [
+ '_LARGEFILE_SOURCE',
+ '_LARGEFILE64_SOURCE',
+ '_FILE_OFFSET_BITS=64',
+ ],
+ }],
['os_posix==1 and OS!="mac" and OS!="ios"', {
'target_defaults': {
# Enable -Werror by default, but put it in a variable so it can
@@ -3689,12 +3700,6 @@
'-fomit-frame-pointer',
],
}],
- ['OS!="android"', {
- 'defines': [
- '_LARGEFILE_SOURCE',
- '_LARGEFILE64_SOURCE',
- ],
- }],
['OS=="linux" and target_arch=="ia32"', {
'ldflags': [
'-Wl,--no-as-needed',
diff --git a/build/config/BUILD.gn b/build/config/BUILD.gn
index 2427b72..5eb5e0a 100644
--- a/build/config/BUILD.gn
+++ b/build/config/BUILD.gn
@@ -41,11 +41,8 @@
#
# For now we define these globally to match the current GYP build.
config("feature_flags") {
- # TODO(brettw) most of these need to be parameterized.
- defines = [
- "CHROMIUM_BUILD",
- "V8_DEPRECATION_WARNINGS", # Don't use deprecated V8 APIs anywhere.
- ]
+ # TODO(brettw) this probably needs to be parameterized.
+ defines = [ "V8_DEPRECATION_WARNINGS" ] # Don't use deprecated V8 APIs anywhere.
if (cld_version > 0) {
defines += [ "CLD_VERSION=$cld_version" ]
@@ -238,6 +235,18 @@
} else if (safe_browsing_mode == 2) {
defines += [ "MOBILE_SAFE_BROWSING" ]
defines += [ "SAFE_BROWSING_SERVICE" ]
+ } else if (safe_browsing_mode == 3) {
+ defines += [ "MOBILE_SAFE_BROWSING" ]
+ defines += [ "SAFE_BROWSING_DB_REMOTE" ]
+ defines += [ "SAFE_BROWSING_SERVICE" ]
+ }
+ if (is_official_build) {
+ defines += [ "OFFICIAL_BUILD" ]
+ }
+ if (is_chrome_branded) {
+ defines += [ "GOOGLE_CHROME_BUILD" ]
+ } else {
+ defines += [ "CHROMIUM_BUILD" ]
}
}
@@ -271,6 +280,18 @@
config("release") {
defines = [ "NDEBUG" ]
+
+ # Sanitizers.
+ # TODO(GYP) The GYP build has "release_valgrind_build == 0" for this
+ # condition. When Valgrind is set up, we need to do the same here.
+ if (!is_tsan) {
+ defines += [ "NVALGRIND" ]
+ if (!is_nacl) {
+ # NaCl always enables dynamic annotations. Currently this value is set to
+ # 1 for all .nexes.
+ defines += [ "DYNAMIC_ANNOTATIONS_ENABLED=0" ]
+ }
+ }
}
# Default libraries ------------------------------------------------------------
diff --git a/build/config/BUILDCONFIG.gn b/build/config/BUILDCONFIG.gn
index 2274c0e..ee32088 100644
--- a/build/config/BUILDCONFIG.gn
+++ b/build/config/BUILDCONFIG.gn
@@ -488,11 +488,17 @@
}
set_default_toolchain("$host_toolchain")
} else if (is_android) {
- # Use clang for the x86/64 Linux host builds.
- if (host_cpu == "x86" || host_cpu == "x64") {
- host_toolchain = "//build/toolchain/linux:clang_$host_cpu"
+ if (host_os == "linux") {
+ # Use clang for the x86/64 Linux host builds.
+ if (host_cpu == "x86" || host_cpu == "x64") {
+ host_toolchain = "//build/toolchain/linux:clang_$host_cpu"
+ } else {
+ host_toolchain = "//build/toolchain/linux:$host_cpu"
+ }
+ } else if (host_os == "mac") {
+ host_toolchain = "//build/toolchain/mac:clang_$host_cpu"
} else {
- host_toolchain = "//build/toolchain/linux:$host_cpu"
+ assert(false, "Unknown host for android cross compile")
}
set_default_toolchain("//build/toolchain/android:$current_cpu")
} else if (is_linux) {
@@ -507,11 +513,11 @@
set_default_toolchain("//build/toolchain/cros:target")
}
} else if (is_mac) {
- host_toolchain = "//build/toolchain/mac:clang"
+ host_toolchain = "//build/toolchain/mac:clang_x64"
set_default_toolchain(host_toolchain)
} else if (is_ios) {
- host_toolchain = "//build/toolchain/mac:host_clang"
- set_default_toolchain("//build/toolchain/mac:clang")
+ host_toolchain = "//build/toolchain/mac:clang_x64"
+ set_default_toolchain("//build/toolchain/mac:clang_$current_cpu")
} else if (is_nacl) {
# TODO(GYP): This will need to change when we get NaCl working
# on multiple platforms, but this whole block of code (how we define
diff --git a/build/config/android/config.gni b/build/config/android/config.gni
index 093e8b3..0e25a9a 100644
--- a/build/config/android/config.gni
+++ b/build/config/android/config.gni
@@ -60,6 +60,8 @@
# architecture, which is different than the names GN uses.
if (host_os == "linux") {
android_host_os = "linux"
+ } else if (host_os == "mac") {
+ android_host_os = "darwin"
} else {
assert(false, "Need Android toolchain support for your build OS.")
}
diff --git a/build/config/android/internal_rules.gni b/build/config/android/internal_rules.gni
index 2a7a892..07a05e1 100644
--- a/build/config/android/internal_rules.gni
+++ b/build/config/android/internal_rules.gni
@@ -1177,3 +1177,53 @@
}
}
}
+
+# Creates an AndroidManifest.xml for an APK split.
+template("generate_split_manifest") {
+ assert(defined(invoker.main_manifest))
+ assert(defined(invoker.out_manifest))
+ assert(defined(invoker.split_name))
+
+ action(target_name) {
+ depfile = "$target_gen_dir/$target_name.d"
+ args = [
+ "--main-manifest",
+ rebase_path(invoker.main_manifest, root_build_dir),
+ "--out-manifest",
+ rebase_path(invoker.out_manifest, root_build_dir),
+ "--split",
+ invoker.split_name,
+ ]
+ if (defined(invoker.version_code)) {
+ args += [
+ "--version-code",
+ invoker.version_code,
+ ]
+ }
+ if (defined(invoker.version_name)) {
+ args += [
+ "--version-name",
+ invoker.version_name,
+ ]
+ }
+ if (defined(invoker.has_code)) {
+ args += [
+ "--has-code",
+ invoker.has_code,
+ ]
+ }
+ args += [
+ "--depfile",
+ rebase_path(depfile, root_build_dir),
+ ]
+
+ script = "//build/android/gyp/generate_split_manifest.py"
+ outputs = [
+ depfile,
+ invoker.out_manifest,
+ ]
+ inputs = [
+ invoker.main_manifest,
+ ]
+ }
+}
diff --git a/build/config/android/rules.gni b/build/config/android/rules.gni
index 168ebb4..0b7593d 100644
--- a/build/config/android/rules.gni
+++ b/build/config/android/rules.gni
@@ -1582,9 +1582,11 @@
deps += invoker.deps
}
datadeps = [
- "//tools/android/forwarder2",
"//tools/android/md5sum",
]
+ if (host_os == "linux") {
+ datadeps += [ "//tools/android/forwarder2" ]
+ }
if (defined(invoker.datadeps)) {
datadeps += invoker.datadeps
}
diff --git a/build/config/compiler/BUILD.gn b/build/config/compiler/BUILD.gn
index 9ebb2e7..0e28e7d 100644
--- a/build/config/compiler/BUILD.gn
+++ b/build/config/compiler/BUILD.gn
@@ -336,6 +336,7 @@
"-fno-unwind-tables",
"-fno-asynchronous-unwind-tables",
]
+ defines += [ "NO_UNWIND_TABLES" ]
} else {
cflags += [ "-funwind-tables" ]
}
@@ -636,6 +637,18 @@
"__STDC_CONSTANT_MACROS",
"__STDC_FORMAT_MACROS",
]
+
+ if (using_sanitizer) {
+ # _FORTIFY_SOURCE isn't really supported by Clang now, see
+ # http://llvm.org/bugs/show_bug.cgi?id=16821.
+ # It seems to work fine with Ubuntu 12 headers though, so use it in
+ # official builds.
+ #
+ # Non-chromium code is not guaranteed to compile cleanly with
+ # _FORTIFY_SOURCE. Also, fortified build may fail when optimizations are
+ # disabled, so only do that for Release build.
+ defines += [ "_FORTIFY_SOURCE=2" ]
+ }
}
}
config("no_chromium_code") {
diff --git a/build/config/features.gni b/build/config/features.gni
index 3873458..82b7d06 100644
--- a/build/config/features.gni
+++ b/build/config/features.gni
@@ -51,7 +51,11 @@
enable_media_router = !is_ios && !is_android
# Enables proprietary codecs and demuxers; e.g. H264, MOV, AAC, and MP3.
- proprietary_codecs = false
+ # Android OS includes support for proprietary codecs regardless of building
+ # Chromium or Google Chrome. We also ship Google Chrome and Chromecast with
+ # proprietary codecs.
+ # TODO(GYP) The GYP build has || chromecast==1 for this:
+ proprietary_codecs = is_android || is_chrome_branded
enable_configuration_policy = true
@@ -85,12 +89,12 @@
# (e.g. Android and ChromeCast) that use a browser side CDM.
enable_browser_cdms = is_android
- # Variable safe_browsing is used to control the build time configuration for
- # safe browsing feature. Safe browsing can be compiled in 3 different levels:
- # 0 disables it, 1 enables it fully, and 2 enables only UI and reporting
- # features without enabling phishing and malware detection. This is useful to
- # integrate a third party phishing/malware detection to existing safe browsing
- # logic.
+ # Variable safe_browsing is used to control the build time configuration
+ # for safe browsing feature. Safe browsing can be compiled in 4 different
+ # levels: 0 disables it, 1 enables it fully, and 2 enables only UI and
+ # reporting features for use with Data Saver on Mobile, and 3 enables
+ # extended mobile protection via an external API. When 3 is fully deployed,
+ # it will replace 2.
if (is_android) {
safe_browsing_mode = 2
} else if (is_ios) {
diff --git a/build/config/gcc/BUILD.gn b/build/config/gcc/BUILD.gn
index c6cfe72..40243cd 100644
--- a/build/config/gcc/BUILD.gn
+++ b/build/config/gcc/BUILD.gn
@@ -20,21 +20,22 @@
# Settings for executables and shared libraries.
config("executable_ldconfig") {
- ldflags = [
- # Want to pass "\$". GN will re-escape as required for ninja.
- "-Wl,-rpath=\$ORIGIN/",
- "-Wl,-rpath-link=",
-
- # Newer binutils don't set DT_RPATH unless you disable "new" dtags
- # and the new DT_RUNPATH doesn't work without --no-as-needed flag.
- "-Wl,--disable-new-dtags",
- ]
-
if (is_android) {
- ldflags += [
+ ldflags = [
"-Bdynamic",
"-Wl,-z,nocopyreloc",
]
+ } else {
+ # Android doesn't support rpath.
+ ldflags = [
+ # Want to pass "\$". GN will re-escape as required for ninja.
+ "-Wl,-rpath=\$ORIGIN/",
+ "-Wl,-rpath-link=",
+
+ # Newer binutils don't set DT_RPATH unless you disable "new" dtags
+ # and the new DT_RUNPATH doesn't work without --no-as-needed flag.
+ "-Wl,--disable-new-dtags",
+ ]
}
}
diff --git a/build/gn_migration.gypi b/build/gn_migration.gypi
index 4257cc0..ab16c05 100644
--- a/build/gn_migration.gypi
+++ b/build/gn_migration.gypi
@@ -173,7 +173,10 @@
'../sync/tools/sync_tools.gyp:sync_client',
'../sync/tools/sync_tools.gyp:sync_listen_notifications',
'../testing/gmock.gyp:gmock_main',
- '../third_party/WebKit/public/all.gyp:blink_tests',
+ '../third_party/WebKit/Source/platform/blink_platform_tests.gyp:blink_heap_unittests',
+ '../third_party/WebKit/Source/platform/blink_platform_tests.gyp:blink_platform_unittests',
+ '../third_party/WebKit/Source/web/web_tests.gyp:webkit_unit_tests',
+ '../third_party/WebKit/Source/wtf/wtf_tests.gyp:wtf_unittests',
'../third_party/cacheinvalidation/cacheinvalidation.gyp:cacheinvalidation_unittests',
'../third_party/codesighs/codesighs.gyp:codesighs',
'../third_party/codesighs/codesighs.gyp:maptsvdifftool',
@@ -276,8 +279,6 @@
'../ui/ozone/ozone.gyp:ozone',
],
}],
-
-
['use_x11==1', {
'dependencies': [
'../tools/xdisplaycheck/xdisplaycheck.gyp:xdisplaycheck',
@@ -313,6 +314,10 @@
'../content/content_shell_and_tests.gyp:content_shell_apk',
+ '../third_party/WebKit/Source/platform/blink_platform_tests.gyp:blink_heap_unittests_apk',
+ '../third_party/WebKit/Source/platform/blink_platform_tests.gyp:blink_platform_unittests_apk',
+ '../third_party/WebKit/Source/web/web_tests.gyp:webkit_unit_tests_apk',
+ '../third_party/WebKit/Source/wtf/wtf_tests.gyp:wtf_unittests_apk',
# TODO(GYP): Are these needed, or will they be pulled in automatically?
#"//third_party/android_tools:android_gcm_java",
#"//third_party/android_tools:uiautomator_java",
diff --git a/build/java.gypi b/build/java.gypi
index 730fa22..716eb34 100644
--- a/build/java.gypi
+++ b/build/java.gypi
@@ -69,6 +69,7 @@
'has_java_resources%': 0,
'res_extra_dirs': [],
'res_extra_files': [],
+ 'res_v14_skip%': 0,
'res_v14_verify_only%': 0,
'resource_input_paths': ['>@(res_extra_files)'],
'intermediate_dir': '<(SHARED_INTERMEDIATE_DIR)/<(_target_name)',
@@ -157,6 +158,9 @@
'inputs_list_file': '>|(java_resources.<(_target_name).gypcmd >@(resource_input_paths))',
'process_resources_options': [],
'conditions': [
+ ['res_v14_skip == 1', {
+ 'process_resources_options': ['--v14-skip']
+ }],
['res_v14_verify_only == 1', {
'process_resources_options': ['--v14-verify-only']
}],
diff --git a/build/java_apk.gypi b/build/java_apk.gypi
index cece2be..154c16e 100644
--- a/build/java_apk.gypi
+++ b/build/java_apk.gypi
@@ -141,6 +141,7 @@
'symlink_script_host_path': '<(intermediate_dir)/create_symlinks.sh',
'symlink_script_device_path': '<(device_intermediate_dir)/create_symlinks.sh',
'create_standalone_apk%': 1,
+ 'res_v14_skip%': 0,
'res_v14_verify_only%': 0,
'variables': {
'variables': {
@@ -607,6 +608,9 @@
'dependencies_res_zip_paths=': [],
'additional_res_packages=': [],
}],
+ ['res_v14_skip == 1', {
+ 'process_resources_options+': ['--v14-skip']
+ }],
['res_v14_verify_only == 1', {
'process_resources_options+': ['--v14-verify-only']
}],
diff --git a/build/linux/system.gyp b/build/linux/system.gyp
index e7cc9dc..476476e 100644
--- a/build/linux/system.gyp
+++ b/build/linux/system.gyp
@@ -692,9 +692,6 @@
'cflags': [
'<!@(<(pkg-config) --cflags dbus-1)',
],
- 'defines': [
- 'USE_DBUS',
- ],
},
'link_settings': {
'ldflags': [
diff --git a/build/toolchain/android/BUILD.gn b/build/toolchain/android/BUILD.gn
index 53ad506..f7f47ff 100644
--- a/build/toolchain/android/BUILD.gn
+++ b/build/toolchain/android/BUILD.gn
@@ -49,6 +49,8 @@
cxx = compiler_prefix + tool_prefix + "g++"
ar = tool_prefix + "ar"
ld = cxx
+ readelf = compiler_prefix + tool_prefix + "readelf"
+ nm = compiler_prefix + tool_prefix + "nm"
toolchain_os = "android"
toolchain_cpu = invoker.toolchain_cpu
diff --git a/build/toolchain/gcc_toolchain.gni b/build/toolchain/gcc_toolchain.gni
index 0192faa..ae9599a 100644
--- a/build/toolchain/gcc_toolchain.gni
+++ b/build/toolchain/gcc_toolchain.gni
@@ -13,6 +13,8 @@
# - cxx
# - ar
# - ld
+# - readelf
+# - nm
# and the following which is used in the toolchain_args
# - toolchain_cpu (What "current_cpu" should be set to when invoking a
# build using this toolchain.)
@@ -40,6 +42,9 @@
assert(defined(invoker.cxx), "gcc_toolchain() must specify a \"cxx\" value")
assert(defined(invoker.ar), "gcc_toolchain() must specify a \"ar\" value")
assert(defined(invoker.ld), "gcc_toolchain() must specify a \"ld\" value")
+ assert(defined(invoker.readelf),
+ "gcc_toolchain() must specify a \"readelf\" value")
+ assert(defined(invoker.nm), "gcc_toolchain() must specify a \"nm\" value")
assert(defined(invoker.toolchain_cpu),
"gcc_toolchain() must specify a \"toolchain_cpu\"")
assert(defined(invoker.toolchain_os),
@@ -52,6 +57,8 @@
cxx = invoker.cxx
ar = invoker.ar
ld = invoker.ld
+ readelf = invoker.readelf
+ nm = invoker.nm
# Bring these into our scope for string interpolation with default values.
if (defined(invoker.libs_section_prefix)) {
@@ -138,7 +145,7 @@
temporary_tocname = sofile + ".tmp"
link_command =
"$ld -shared {{ldflags}} -o $sofile -Wl,-soname=$soname @$rspfile"
- toc_command = "{ readelf -d $sofile | grep SONAME ; nm -gD -f p $sofile | cut -f1-2 -d' '; } > $temporary_tocname"
+ toc_command = "{ $readelf -d $sofile | grep SONAME ; $nm -gD -f p $sofile | cut -f1-2 -d' '; } > $temporary_tocname"
replace_command = "if ! cmp -s $temporary_tocname $tocfile; then mv $temporary_tocname $tocfile; fi"
command = "$link_command && $toc_command && $replace_command"
diff --git a/build/toolchain/linux/BUILD.gn b/build/toolchain/linux/BUILD.gn
index 7bcd9d0..15ad5bd 100644
--- a/build/toolchain/linux/BUILD.gn
+++ b/build/toolchain/linux/BUILD.gn
@@ -23,6 +23,8 @@
ar = "arm-linux-gnueabi-ar"
ld = cxx
+ readelf = "arm-linux-gnueabi-readelf"
+ nm = "arm-linux-gnueabi-nm"
toolchain_cpu = "arm"
toolchain_os = "linux"
@@ -39,7 +41,8 @@
}
cc = "${compiler_prefix}$prefix/clang"
cxx = "${compiler_prefix}$prefix/clang++"
-
+ readelf = "readelf"
+ nm = "nm"
ar = "ar"
ld = cxx
@@ -52,6 +55,8 @@
cc = "${compiler_prefix}gcc"
cxx = "$compiler_prefix}g++"
+ readelf = "readelf"
+ nm = "nm"
ar = "ar"
ld = cxx
@@ -71,6 +76,8 @@
cc = "${compiler_prefix}$prefix/clang"
cxx = "${compiler_prefix}$prefix/clang++"
+ readelf = "readelf"
+ nm = "nm"
ar = "ar"
ld = cxx
@@ -83,6 +90,8 @@
cc = "${compiler_prefix}gcc"
cxx = "${compiler_prefix}g++"
+ readelf = "readelf"
+ nm = "nm"
ar = "ar"
ld = cxx
@@ -96,6 +105,8 @@
cxx = "mipsel-linux-gnu-g++"
ar = "mipsel-linux-gnu-ar"
ld = cxx
+ readelf = "mipsel-linux-gnu-readelf"
+ nm = "mipsel-linux-gnu-nm"
toolchain_cpu = "mipsel"
toolchain_os = "linux"
diff --git a/build/toolchain/mac/BUILD.gn b/build/toolchain/mac/BUILD.gn
index a4b8651..da4ca05 100644
--- a/build/toolchain/mac/BUILD.gn
+++ b/build/toolchain/mac/BUILD.gn
@@ -8,8 +8,7 @@
import("../goma.gni")
-# Should only be running on Mac.
-assert(is_mac || is_ios)
+assert(host_os == "mac")
import("//build/toolchain/clang.gni")
import("//build/toolchain/goma.gni")
@@ -20,19 +19,6 @@
goma_prefix = ""
}
-if (is_clang) {
- cc = rebase_path("//third_party/llvm-build/Release+Asserts/bin/clang",
- root_build_dir)
- cxx = rebase_path("//third_party/llvm-build/Release+Asserts/bin/clang++",
- root_build_dir)
-} else {
- cc = "gcc"
- cxx = "g++"
-}
-cc = goma_prefix + cc
-cxx = goma_prefix + cxx
-ld = cxx
-
# This will copy the gyp-mac-tool to the build directory. We pass in the source
# file of the win tool.
gyp_mac_tool_source =
@@ -41,16 +27,15 @@
# Shared toolchain definition. Invocations should set toolchain_os to set the
# build args in this definition.
-template("mac_clang_toolchain") {
+template("mac_toolchain") {
toolchain(target_name) {
- assert(defined(invoker.cc),
- "mac_clang_toolchain() must specify a \"cc\" value")
- assert(defined(invoker.cxx),
- "mac_clang_toolchain() must specify a \"cxx\" value")
- assert(defined(invoker.ld),
- "mac_clang_toolchain() must specify a \"ld\" value")
+ assert(defined(invoker.cc), "mac_toolchain() must specify a \"cc\" value")
+ assert(defined(invoker.cxx), "mac_toolchain() must specify a \"cxx\" value")
+ assert(defined(invoker.ld), "mac_toolchain() must specify a \"ld\" value")
+ assert(defined(invoker.toolchain_cpu),
+ "mac_toolchain() must specify a \"toolchain_cpu\"")
assert(defined(invoker.toolchain_os),
- "mac_clang_toolchain() must specify a \"toolchain_os\"")
+ "mac_toolchain() must specify a \"toolchain_os\"")
# We can't do string interpolation ($ in strings) on things with dots in
# them. To allow us to use $cc below, for example, we create copies of
@@ -194,18 +179,56 @@
}
toolchain_args() {
+ current_cpu = invoker.toolchain_cpu
current_os = invoker.toolchain_os
+
+ # These values need to be passed through unchanged.
+ target_os = target_os
+ target_cpu = target_cpu
+
+ if (defined(invoker.is_clang)) {
+ is_clang = invoker.is_clang
+ }
}
}
}
-# Toolchain representing the target build (either mac or iOS).
-mac_clang_toolchain("clang") {
- toolchain_os = current_os
+mac_toolchain("clang_arm") {
+ toolchain_cpu = "arm"
+ toolchain_os = "mac"
+ prefix = rebase_path("//third_party/llvm-build/Release+Asserts/bin",
+ root_build_dir)
+ cc = "${goma_prefix}$prefix/clang"
+ cxx = "${goma_prefix}$prefix/clang++"
+ ld = cxx
+ is_clang = true
}
-# This toolchain provides a way for iOS target compiles to reference targets
-# compiled for the host system. It just overrides the OS back to "mac".
-mac_clang_toolchain("host_clang") {
+mac_toolchain("arm") {
+ toolchain_cpu = "arm"
toolchain_os = "mac"
+ cc = "${goma_prefix}/gcc"
+ cxx = "${goma_prefix}/g++"
+ ld = cxx
+ is_clang = false
+}
+
+mac_toolchain("clang_x64") {
+ toolchain_cpu = "x64"
+ toolchain_os = "mac"
+ prefix = rebase_path("//third_party/llvm-build/Release+Asserts/bin",
+ root_build_dir)
+ cc = "${goma_prefix}$prefix/clang"
+ cxx = "${goma_prefix}$prefix/clang++"
+ ld = cxx
+ is_clang = true
+}
+
+mac_toolchain("x64") {
+ toolchain_cpu = "x64"
+ toolchain_os = "mac"
+ cc = "${goma_prefix}/gcc"
+ cxx = "${goma_prefix}/g++"
+ ld = cxx
+ is_clang = false
}
diff --git a/build/util/LASTCHANGE b/build/util/LASTCHANGE
new file mode 100644
index 0000000..58820c7
--- /dev/null
+++ b/build/util/LASTCHANGE
@@ -0,0 +1 @@
+LASTCHANGE=e8280f3afe7cff09bb5b23c959928ccbdc16da25-refs/heads/master@{#329263}
diff --git a/build/util/LASTCHANGE.blink b/build/util/LASTCHANGE.blink
new file mode 100644
index 0000000..ed95b02
--- /dev/null
+++ b/build/util/LASTCHANGE.blink
@@ -0,0 +1 @@
+LASTCHANGE=195119
diff --git a/sandbox/linux/BUILD.gn b/sandbox/linux/BUILD.gn
index 8496685..6cca0d3 100644
--- a/sandbox/linux/BUILD.gn
+++ b/sandbox/linux/BUILD.gn
@@ -10,8 +10,8 @@
compile_credentials = is_linux
- compile_seccomp_bpf_demo =
- is_linux && (current_cpu == "x86" || current_cpu == "x64")
+ # On Android, use plain GTest.
+ use_base_test_suite = is_linux
}
# We have two principal targets: sandbox and sandbox_linux_unittests
@@ -61,6 +61,11 @@
]
deps += [ ":seccomp_bpf" ]
}
+
+ if (use_base_test_suite) {
+ deps += [ "//base/test:test_support" ]
+ defines = [ "SANDBOX_USES_BASE_TEST_SUITE" ]
+ }
}
# Sources shared by sandbox_linux_unittests and sandbox_linux_jni_unittests.
@@ -88,10 +93,14 @@
":sandbox",
":sandbox_linux_test_utils",
"//base",
- "//base/test:test_support",
"//testing/gtest",
]
+ if (use_base_test_suite) {
+ deps += [ "//base/test:test_support" ]
+ defines = [ "SANDBOX_USES_BASE_TEST_SUITE" ]
+ }
+
if (is_linux) {
# Don't use this on Android.
libs = [ "rt" ]
@@ -124,10 +133,14 @@
sources += [
"integration_tests/namespace_unix_domain_socket_unittest.cc",
"services/credentials_unittest.cc",
- "services/namespace_sandbox_unittest.cc",
"services/namespace_utils_unittest.cc",
]
+ if (use_base_test_suite) {
+ # Tests that use advanced features not available in stock GTest.
+ sources += [ "services/namespace_sandbox_unittest.cc" ]
+ }
+
# For credentials_unittest.cc
configs += [ "//build/config/linux:libcap" ]
}
diff --git a/sandbox/linux/sandbox_linux.gypi b/sandbox/linux/sandbox_linux.gypi
index 7724223..e09ba39 100644
--- a/sandbox/linux/sandbox_linux.gypi
+++ b/sandbox/linux/sandbox_linux.gypi
@@ -8,9 +8,11 @@
['OS=="linux"', {
'compile_suid_client': 1,
'compile_credentials': 1,
+ 'use_base_test_suite': 1,
}, {
'compile_suid_client': 0,
'compile_credentials': 0,
+ 'use_base_test_suite': 0,
}],
['OS=="linux" and (target_arch=="ia32" or target_arch=="x64" or '
'target_arch=="mipsel")', {
@@ -88,6 +90,14 @@
'seccomp_bpf',
]
}],
+ [ 'use_base_test_suite==1', {
+ 'dependencies': [
+ '../base/base.gyp:test_support_base',
+ ],
+ 'defines': [
+ 'SANDBOX_USES_BASE_TEST_SUITE',
+ ],
+ }],
],
},
{
diff --git a/sandbox/linux/sandbox_linux_test_sources.gypi b/sandbox/linux/sandbox_linux_test_sources.gypi
index ce7817d..82d7532 100644
--- a/sandbox/linux/sandbox_linux_test_sources.gypi
+++ b/sandbox/linux/sandbox_linux_test_sources.gypi
@@ -10,7 +10,6 @@
'sandbox_linux_test_utils',
'sandbox_services',
'../base/base.gyp:base',
- '../base/base.gyp:test_support_base',
'../testing/gtest.gyp:gtest',
],
'include_dirs': [
@@ -60,12 +59,26 @@
'sources': [
'integration_tests/namespace_unix_domain_socket_unittest.cc',
'services/credentials_unittest.cc',
- 'services/namespace_sandbox_unittest.cc',
'services/namespace_utils_unittest.cc',
],
'dependencies': [
'../build/linux/system.gyp:libcap'
],
+ 'conditions': [
+ [ 'use_base_test_suite==1', {
+ 'sources': [
+ 'services/namespace_sandbox_unittest.cc',
+ ]
+ }]
+ ],
+ }],
+ [ 'use_base_test_suite==1', {
+ 'dependencies': [
+ '../base/base.gyp:test_support_base',
+ ],
+ 'defines': [
+ 'SANDBOX_USES_BASE_TEST_SUITE',
+ ],
}],
],
}
diff --git a/sandbox/linux/system_headers/arm_linux_syscalls.h b/sandbox/linux/system_headers/arm_linux_syscalls.h
index bfd5342..1addd53 100644
--- a/sandbox/linux/system_headers/arm_linux_syscalls.h
+++ b/sandbox/linux/system_headers/arm_linux_syscalls.h
@@ -1205,6 +1205,10 @@
#define __NR_arm_sync_file_range (__NR_SYSCALL_BASE+341)
#endif
+#if !defined(__NR_sync_file_range2)
+#define __NR_sync_file_range2 (__NR_SYSCALL_BASE+341)
+#endif
+
#if !defined(__NR_tee)
#define __NR_tee (__NR_SYSCALL_BASE+342)
#endif
diff --git a/sandbox/linux/tests/main.cc b/sandbox/linux/tests/main.cc
index 687c8bb..caeddee 100644
--- a/sandbox/linux/tests/main.cc
+++ b/sandbox/linux/tests/main.cc
@@ -36,7 +36,7 @@
} // namespace
} // namespace sandbox
-#if defined(OS_ANDROID)
+#if !defined(SANDBOX_USES_BASE_TEST_SUITE)
void UnitTestAssertHandler(const std::string& str) {
_exit(1);
}
@@ -44,9 +44,11 @@
int main(int argc, char* argv[]) {
base::CommandLine::Init(argc, argv);
- std::string client_func =
- base::CommandLine::ForCurrentProcess()->GetSwitchValueASCII(
- switches::kTestChildProcess);
+ std::string client_func;
+#if defined(SANDBOX_USES_BASE_TEST_SUITE)
+ client_func = base::CommandLine::ForCurrentProcess()->GetSwitchValueASCII(
+ switches::kTestChildProcess);
+#endif
if (!client_func.empty()) {
base::AtExitManager exit_manager;
return multi_process_function_list::InvokeChildProcessTest(client_func);
@@ -55,7 +57,7 @@
base::FilePath orig_cwd;
CHECK(GetCurrentDirectory(&orig_cwd));
-#if defined(OS_ANDROID)
+#if !defined(SANDBOX_USES_BASE_TEST_SUITE)
// The use of Callbacks requires an AtExitManager.
base::AtExitManager exit_manager;
testing::InitGoogleTest(&argc, argv);
@@ -69,7 +71,7 @@
// additional side effect of getting rid of gtest warnings about fork()
// safety.
::testing::FLAGS_gtest_death_test_style = "threadsafe";
-#if defined(OS_ANDROID)
+#if !defined(SANDBOX_USES_BASE_TEST_SUITE)
int tests_result = RUN_ALL_TESTS();
#else
int tests_result = base::RunUnitTestsUsingBaseTestSuite(argc, argv);
diff --git a/sandbox/linux/tests/unit_tests.cc b/sandbox/linux/tests/unit_tests.cc
index 5872e94..cfcec96 100644
--- a/sandbox/linux/tests/unit_tests.cc
+++ b/sandbox/linux/tests/unit_tests.cc
@@ -7,6 +7,8 @@
#include <signal.h>
#include <stdio.h>
#include <sys/resource.h>
+#include <sys/types.h>
+#include <sys/wait.h>
#include <sys/time.h>
#include <time.h>
#include <unistd.h>
@@ -18,6 +20,11 @@
#include "build/build_config.h"
#include "sandbox/linux/tests/unit_tests.h"
+// Specifically, PNaCl toolchain does not have this flag.
+#if !defined(POLLRDHUP)
+#define POLLRDHUP 0x2000
+#endif
+
namespace {
std::string TestFailedMessage(const std::string& msg) {
return msg.empty() ? std::string() : "Actual test failure: " + msg;
@@ -67,14 +74,20 @@
static const int kExpectedValue = 42;
static const int kIgnoreThisTest = 43;
static const int kExitWithAssertionFailure = 1;
+#if !defined(OS_NACL_NONSFI)
static const int kExitForTimeout = 2;
+#endif
-#if !defined(OS_ANDROID)
+#if defined(SANDBOX_USES_BASE_TEST_SUITE)
// This is due to StackDumpSignalHandler() performing _exit(1).
// TODO(jln): get rid of the collision with kExitWithAssertionFailure.
const int kExitAfterSIGSEGV = 1;
#endif
+// PNaCl toolchain's signal ABIs are incompatible with Linux's.
+// So, for simplicity, just drop the "timeout" feature from unittest framework
+// with relying on the buildbot's timeout feature.
+#if !defined(OS_NACL_NONSFI)
static void SigAlrmHandler(int) {
const char failure_message[] = "Timeout reached!\n";
// Make sure that we never block here.
@@ -106,6 +119,7 @@
SANDBOX_ASSERT(alarm(time_in_seconds) == 0); // There should be no previous
// alarm.
}
+#endif // !defined(OS_NACL_NONSFI)
// Runs a test in a sub-process. This is necessary for most of the code
// in the BPF sandbox, as it potentially makes global state changes and as
@@ -163,7 +177,9 @@
// Don't set a timeout if running on Valgrind, since it's generally much
// slower.
if (!IsRunningOnValgrind()) {
+#if !defined(OS_NACL_NONSFI)
SetProcessTimeout(GetSubProcessTimeoutTimeInSeconds());
+#endif
}
// Disable core files. They are not very useful for our individual test
@@ -282,10 +298,12 @@
std::string details(TestFailedMessage(msg));
const char* expected_msg = static_cast<const char*>(aux);
-#if defined(OS_ANDROID)
+#if !defined(SANDBOX_USES_BASE_TEST_SUITE)
const bool subprocess_got_sigsegv =
WIFSIGNALED(status) && (SIGSEGV == WTERMSIG(status));
#else
+ // This hack is required when a signal handler is installed
+ // for SEGV that will _exit(1).
const bool subprocess_got_sigsegv =
WIFEXITED(status) && (kExitAfterSIGSEGV == WEXITSTATUS(status));
#endif
diff --git a/sandbox/mac/BUILD.gn b/sandbox/mac/BUILD.gn
index d74bfcb..13960bf 100644
--- a/sandbox/mac/BUILD.gn
+++ b/sandbox/mac/BUILD.gn
@@ -48,8 +48,6 @@
sources = [
"bootstrap_sandbox.cc",
"bootstrap_sandbox.h",
- "dispatch_source_mach.cc",
- "dispatch_source_mach.h",
"launchd_interception_server.cc",
"launchd_interception_server.h",
"mach_message_server.cc",
@@ -85,7 +83,6 @@
test("sandbox_mac_unittests") {
sources = [
"bootstrap_sandbox_unittest.mm",
- "dispatch_source_mach_unittest.cc",
"policy_unittest.cc",
"xpc_message_server_unittest.cc",
]
diff --git a/sandbox/mac/mach_message_server.cc b/sandbox/mac/mach_message_server.cc
index 5a73357..7cfcecc 100644
--- a/sandbox/mac/mach_message_server.cc
+++ b/sandbox/mac/mach_message_server.cc
@@ -12,7 +12,6 @@
#include "base/logging.h"
#include "base/mac/mach_logging.h"
#include "base/strings/stringprintf.h"
-#include "sandbox/mac/dispatch_source_mach.h"
namespace sandbox {
@@ -69,7 +68,7 @@
// Set up the dispatch queue to service the bootstrap port.
std::string label = base::StringPrintf(
"org.chromium.sandbox.MachMessageServer.%p", demuxer_);
- dispatch_source_.reset(new DispatchSourceMach(
+ dispatch_source_.reset(new base::DispatchSourceMach(
label.c_str(), server_port_.get(), ^{ ReceiveMessage(); }));
dispatch_source_->Resume();
diff --git a/sandbox/mac/mach_message_server.h b/sandbox/mac/mach_message_server.h
index 645b691..20a543b 100644
--- a/sandbox/mac/mach_message_server.h
+++ b/sandbox/mac/mach_message_server.h
@@ -7,6 +7,7 @@
#include <mach/mach.h>
+#include "base/mac/dispatch_source_mach.h"
#include "base/mac/scoped_mach_port.h"
#include "base/mac/scoped_mach_vm.h"
#include "base/memory/scoped_ptr.h"
@@ -14,8 +15,6 @@
namespace sandbox {
-class DispatchSourceMach;
-
// A Mach message server that operates a receive port. Messages are received
// and then passed to the MessageDemuxer for handling. The Demuxer
// can use the server class to send a reply, forward the message to a
@@ -62,7 +61,7 @@
base::mac::ScopedMachVM reply_buffer_;
// MACH_RECV dispatch source that handles the |server_port_|.
- scoped_ptr<DispatchSourceMach> dispatch_source_;
+ scoped_ptr<base::DispatchSourceMach> dispatch_source_;
// Whether or not ForwardMessage() was called during ReceiveMessage().
bool did_forward_message_;
diff --git a/sandbox/mac/sandbox_mac.gypi b/sandbox/mac/sandbox_mac.gypi
index a2a616f..d5013f8 100644
--- a/sandbox/mac/sandbox_mac.gypi
+++ b/sandbox/mac/sandbox_mac.gypi
@@ -10,8 +10,6 @@
'sources': [
'bootstrap_sandbox.cc',
'bootstrap_sandbox.h',
- 'dispatch_source_mach.cc',
- 'dispatch_source_mach.h',
'launchd_interception_server.cc',
'launchd_interception_server.h',
'mach_message_server.cc',
@@ -93,7 +91,6 @@
'type': 'executable',
'sources': [
'bootstrap_sandbox_unittest.mm',
- 'dispatch_source_mach_unittest.cc',
'policy_unittest.cc',
'xpc_message_server_unittest.cc',
],
diff --git a/sandbox/mac/xpc_message_server.cc b/sandbox/mac/xpc_message_server.cc
index 45559dd..1cd5c63 100644
--- a/sandbox/mac/xpc_message_server.cc
+++ b/sandbox/mac/xpc_message_server.cc
@@ -10,7 +10,6 @@
#include "base/mac/mach_logging.h"
#include "base/strings/stringprintf.h"
-#include "sandbox/mac/dispatch_source_mach.h"
#include "sandbox/mac/xpc.h"
#if defined(MAC_OS_X_VERSION_10_7) && \
@@ -52,7 +51,7 @@
std::string label = base::StringPrintf(
"org.chromium.sandbox.XPCMessageServer.%p", demuxer_);
- dispatch_source_.reset(new DispatchSourceMach(
+ dispatch_source_.reset(new base::DispatchSourceMach(
label.c_str(), server_port_.get(), ^{ ReceiveMessage(); }));
dispatch_source_->Resume();
diff --git a/sandbox/mac/xpc_message_server.h b/sandbox/mac/xpc_message_server.h
index 2810097..5f5a9fa 100644
--- a/sandbox/mac/xpc_message_server.h
+++ b/sandbox/mac/xpc_message_server.h
@@ -7,6 +7,7 @@
#include <AvailabilityMacros.h>
+#include "base/mac/dispatch_source_mach.h"
#include "base/mac/scoped_mach_port.h"
#include "base/memory/scoped_ptr.h"
#include "sandbox/mac/message_server.h"
@@ -27,8 +28,6 @@
namespace sandbox {
-class DispatchSourceMach;
-
// An implementation of MessageServer that uses XPC pipes to read and write XPC
// messages from a Mach port.
class SANDBOX_EXPORT XPCMessageServer : public MessageServer {
@@ -62,7 +61,7 @@
base::mac::ScopedMachReceiveRight server_port_;
// MACH_RECV dispatch source that handles the |server_port_|.
- scoped_ptr<DispatchSourceMach> dispatch_source_;
+ scoped_ptr<base::DispatchSourceMach> dispatch_source_;
// The reply message, if one has been created.
xpc_object_t reply_message_;
diff --git a/sandbox/sandbox_nacl_nonsfi.gyp b/sandbox/sandbox_nacl_nonsfi.gyp
index 906fc7b..f56ad15 100644
--- a/sandbox/sandbox_nacl_nonsfi.gyp
+++ b/sandbox/sandbox_nacl_nonsfi.gyp
@@ -55,6 +55,29 @@
'../base/base_nacl.gyp:base_nacl_nonsfi',
],
},
+
+ {
+ 'target_name': 'sandbox_linux_test_utils_nacl_nonsfi',
+ 'type': 'none',
+ 'variables': {
+ 'nacl_untrusted_build': 1,
+ 'nlib_target': 'libsandbox_linux_test_utils_nacl_nonsfi.a',
+ 'build_glibc': 0,
+ 'build_newlib': 0,
+ 'build_irt': 0,
+ 'build_pnacl_newlib': 0,
+ 'build_nonsfi_helper': 1,
+
+ 'sources': [
+ 'linux/seccomp-bpf/sandbox_bpf_test_runner.cc',
+ 'linux/tests/sandbox_test_runner.cc',
+ 'linux/tests/unit_tests.cc',
+ ],
+ },
+ 'dependencies': [
+ '../testing/gtest_nacl.gyp:gtest_nacl',
+ ],
+ },
],
}],
],
diff --git a/sandbox/win/src/broker_services.cc b/sandbox/win/src/broker_services.cc
index 905c5fd..fec98f9 100644
--- a/sandbox/win/src/broker_services.cc
+++ b/sandbox/win/src/broker_services.cc
@@ -410,7 +410,9 @@
// its |lpValue| parameter persist until |DeleteProcThreadAttributeList| is
// called; StartupInformation's destructor makes such a call.
DWORD64 mitigations;
- HANDLE inherit_handle_list[2];
+
+ std::vector<HANDLE> inherited_handle_list;
+
base::string16 desktop = policy_base->GetAlternateDesktop();
if (!desktop.empty()) {
startup_info.startup_info()->lpDesktop =
@@ -434,18 +436,20 @@
HANDLE stdout_handle = policy_base->GetStdoutHandle();
HANDLE stderr_handle = policy_base->GetStderrHandle();
- int inherit_handle_count = 0;
+
if (stdout_handle != INVALID_HANDLE_VALUE)
- inherit_handle_list[inherit_handle_count++] = stdout_handle;
+ inherited_handle_list.push_back(stdout_handle);
+
// Handles in the list must be unique.
if (stderr_handle != stdout_handle && stderr_handle != INVALID_HANDLE_VALUE)
- inherit_handle_list[inherit_handle_count++] = stderr_handle;
+ inherited_handle_list.push_back(stderr_handle);
- HandleList handle_list = policy_base->GetHandlesBeingShared();
- for (auto handle : handle_list)
- inherit_handle_list[inherit_handle_count++] = handle;
+ HandleList policy_handle_list = policy_base->GetHandlesBeingShared();
- if (inherit_handle_count)
+ for (auto handle : policy_handle_list)
+ inherited_handle_list.push_back(handle);
+
+ if (inherited_handle_list.size())
++attribute_count;
if (!startup_info.InitializeProcThreadAttributeList(attribute_count))
@@ -465,11 +469,11 @@
}
}
- if (inherit_handle_count) {
+ if (inherited_handle_list.size()) {
if (!startup_info.UpdateProcThreadAttribute(
PROC_THREAD_ATTRIBUTE_HANDLE_LIST,
- inherit_handle_list,
- sizeof(inherit_handle_list[0]) * inherit_handle_count)) {
+ &inherited_handle_list[0],
+ sizeof(HANDLE) * inherited_handle_list.size())) {
return SBOX_ERROR_PROC_THREAD_ATTRIBUTES;
}
startup_info.startup_info()->dwFlags |= STARTF_USESTDHANDLES;
diff --git a/tools/clang/scripts/update.py b/tools/clang/scripts/update.py
index 34356e2..02488a6 100755
--- a/tools/clang/scripts/update.py
+++ b/tools/clang/scripts/update.py
@@ -295,6 +295,11 @@
CopyFile(os.path.join(sanitizer_include_dir, f),
aux_sanitizer_include_dir)
+ if args.run_tests:
+ os.chdir(LLVM_BUILD_DIR)
+ RunCommand(GetVSVersion().SetupScript('x64') +
+ ['&&', 'ninja', 'cr-check-all'])
+
WriteStampFile(LLVM_WIN_REVISION)
print 'Clang update was successful.'
return 0
@@ -329,6 +334,7 @@
# mad if it sees a flag it doesn't recognize.
parser.add_argument('--if-needed', action='store_true')
parser.add_argument('--print-revision', action='store_true')
+ parser.add_argument('--run-tests', action='store_true')
args = parser.parse_args()