diff --git a/DEPS b/DEPS index 25040a008..13e40394 100644 --- a/DEPS +++ b/DEPS
@@ -39,11 +39,11 @@ # Three lines of non-changing comments so that # the commit queue can handle CLs rolling Skia # and whatever else without interference from each other. - 'skia_revision': '4eeccc9de7d2381df85d68e0331a40cddf5989b1', + 'skia_revision': '85def2e0673f3b75c4500440b95ab3dac7435702', # Three lines of non-changing comments so that # the commit queue can handle CLs rolling V8 # and whatever else without interference from each other. - 'v8_revision': '9c51453ce0a6f1d93b45c2557c7011c8968a4176', + 'v8_revision': 'b914d669ee4ce4a3056bfe3437b28728cfada6db', # Three lines of non-changing comments so that # the commit queue can handle CLs rolling swarming_client # and whatever else without interference from each other. @@ -192,7 +192,7 @@ Var('chromium_git') + '/chromium/third_party/ffmpeg.git' + '@' + '01464a5194f066a2ea2016b02ca3ea2aad4e6376', 'src/third_party/libjingle/source/talk': - Var('chromium_git') + '/external/webrtc/trunk/talk.git' + '@' + 'a2ec0b628cdf9ea6f40b19101d765781382437b8', # commit position 12501 + Var('chromium_git') + '/external/webrtc/trunk/talk.git' + '@' + 'a3dc305df4e8b44cda3569eb77238b2f8cc0ba20', # commit position 12534 'src/third_party/usrsctp/usrsctplib': Var('chromium_git') + '/external/github.com/sctplab/usrsctp' + '@' + 'c60ec8b35c3fe6027d7a3faae89d1c8d7dd3ce98', @@ -216,7 +216,7 @@ Var('chromium_git') + '/native_client/src/third_party/scons-2.0.1.git' + '@' + '1c1550e17fc26355d08627fbdec13d8291227067', 'src/third_party/webrtc': - Var('chromium_git') + '/external/webrtc/trunk/webrtc.git' + '@' + 'de1eeeb3e322944d429cc0c44c4b736dfb9a18e8', # commit position 12519 + Var('chromium_git') + '/external/webrtc/trunk/webrtc.git' + '@' + '57f37afa99e3897f88029ae0edd3c89ddcb73e8e', # commit position 12543 'src/third_party/openmax_dl': Var('chromium_git') + '/external/webrtc/deps/third_party/openmax.git' + '@' + Var('openmax_dl_revision'),
diff --git a/PRESUBMIT.py b/PRESUBMIT.py index 949e03ae..874734e 100644 --- a/PRESUBMIT.py +++ b/PRESUBMIT.py
@@ -1054,6 +1054,9 @@ if input_api.tbr: return [output_api.PresubmitNotifyResult( '--tbr was specified, skipping OWNERS check for DEPS additions')] + if input_api.dry_run: + return [output_api.PresubmitNotifyResult( + 'This is a dry run, skipping OWNERS check for DEPS additions')] if not input_api.change.issue: return [output_api.PresubmitError( "DEPS approval by OWNERS check failed: this change has "
diff --git a/android_webview/glue/java/src/com/android/webview/chromium/WebViewChromiumFactoryProvider.java b/android_webview/glue/java/src/com/android/webview/chromium/WebViewChromiumFactoryProvider.java index 791c29df..4269b3a 100644 --- a/android_webview/glue/java/src/com/android/webview/chromium/WebViewChromiumFactoryProvider.java +++ b/android_webview/glue/java/src/com/android/webview/chromium/WebViewChromiumFactoryProvider.java
@@ -86,7 +86,6 @@ private WebStorageAdapter mWebStorage; private WebViewDatabaseAdapter mWebViewDatabase; private AwDevToolsServer mDevToolsServer; - private Context mWrappedAppContext; private ArrayList<WeakReference<WebViewChromium>> mWebViewsToStart = new ArrayList<WeakReference<WebViewChromium>>(); @@ -115,6 +114,11 @@ @SuppressFBWarnings("DMI_HARDCODED_ABSOLUTE_FILENAME") private void initialize(WebViewDelegate webViewDelegate) { mWebViewDelegate = webViewDelegate; + + // WebView needs to make sure to always use the wrapped application context. + ContextUtils.initApplicationContext( + ResourcesContextWrapperFactory.get(mWebViewDelegate.getApplication())); + if (isBuildDebuggable()) { // Suppress the StrictMode violation as this codepath is only hit on debugglable builds. StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskReads(); @@ -126,7 +130,7 @@ ThreadUtils.setWillOverrideUiThread(); // Load chromium library. - AwBrowserProcess.loadLibrary(getWrappedCurrentApplicationContext()); + AwBrowserProcess.loadLibrary(ContextUtils.getApplicationContext()); final PackageInfo packageInfo = WebViewFactory.getLoadedPackageInfo(); @@ -263,7 +267,7 @@ return; } - Context context = getWrappedCurrentApplicationContext(); + Context context = ContextUtils.getApplicationContext(); try { LibraryLoader.get(LibraryProcessType.PROCESS_WEBVIEW).ensureInitialized(context); } catch (ProcessInitException e) { @@ -321,14 +325,6 @@ } } - private Context getWrappedCurrentApplicationContext() { - if (mWrappedAppContext == null) { - mWrappedAppContext = ResourcesContextWrapperFactory.get( - mWebViewDelegate.getApplication()); - } - return mWrappedAppContext; - } - AwBrowserContext getBrowserContext() { synchronized (mLock) { return getBrowserContextLocked(); @@ -340,7 +336,7 @@ assert mStarted; if (mBrowserContext == null) { mBrowserContext = - new AwBrowserContext(mWebViewPrefs, getWrappedCurrentApplicationContext()); + new AwBrowserContext(mWebViewPrefs, ContextUtils.getApplicationContext()); } return mBrowserContext; } @@ -450,13 +446,6 @@ public CookieManager getCookieManager() { synchronized (mLock) { if (mCookieManager == null) { - if (!mStarted) { - // We can use CookieManager without starting Chromium; the native code - // will bring up just the parts it needs to make this work on a temporary - // basis until Chromium is started for real. The temporary cookie manager - // needs the application context to have been set. - ContextUtils.initApplicationContext(getWrappedCurrentApplicationContext()); - } mCookieManager = new CookieManagerAdapter(new AwCookieManager()); } }
diff --git a/android_webview/javatests/src/org/chromium/android_webview/test/AwTestBase.java b/android_webview/javatests/src/org/chromium/android_webview/test/AwTestBase.java index 993e988..61d9dd9 100644 --- a/android_webview/javatests/src/org/chromium/android_webview/test/AwTestBase.java +++ b/android_webview/javatests/src/org/chromium/android_webview/test/AwTestBase.java
@@ -4,14 +4,14 @@ package org.chromium.android_webview.test; +import static org.chromium.base.test.util.ScalableTimeout.scaleTimeout; + import android.app.Instrumentation; import android.content.Context; import android.graphics.Bitmap; import android.os.Build; import android.util.Log; -import static org.chromium.base.test.util.ScalableTimeout.scaleTimeout; - import org.chromium.android_webview.AwBrowserContext; import org.chromium.android_webview.AwBrowserProcess; import org.chromium.android_webview.AwContents; @@ -20,6 +20,7 @@ import org.chromium.android_webview.AwSwitches; import org.chromium.android_webview.test.util.GraphicsTestUtils; import org.chromium.android_webview.test.util.JSUtils; +import org.chromium.base.ContextUtils; import org.chromium.base.ThreadUtils; import org.chromium.base.test.BaseActivityInstrumentationTestCase; import org.chromium.base.test.util.CommandLineFlags; @@ -79,10 +80,11 @@ @Override protected void setUp() throws Exception { - mBrowserContext = new AwBrowserContext( - new InMemorySharedPreferences(), getInstrumentation().getTargetContext()); + Context appContext = getInstrumentation().getTargetContext().getApplicationContext(); + mBrowserContext = new AwBrowserContext(new InMemorySharedPreferences(), appContext); super.setUp(); + ContextUtils.initApplicationContext(appContext); if (needsBrowserProcessStarted()) { startBrowserProcess(); } @@ -98,8 +100,10 @@ }); } - /* Override this to return false if the test doesn't want the browser startup sequence to + /** + * Override this to return false if the test doesn't want the browser startup sequence to * be run automatically. + * @return Whether the instrumentation test requires the browser process to already be started. */ protected boolean needsBrowserProcessStarted() { return true;
diff --git a/android_webview/javatests/src/org/chromium/android_webview/test/CookieManagerStartupTest.java b/android_webview/javatests/src/org/chromium/android_webview/test/CookieManagerStartupTest.java index 6505102..9cb017f 100644 --- a/android_webview/javatests/src/org/chromium/android_webview/test/CookieManagerStartupTest.java +++ b/android_webview/javatests/src/org/chromium/android_webview/test/CookieManagerStartupTest.java
@@ -14,7 +14,6 @@ import org.chromium.android_webview.AwWebResourceResponse; import org.chromium.android_webview.test.util.CommonResources; import org.chromium.android_webview.test.util.CookieUtils; -import org.chromium.base.ContextUtils; import org.chromium.base.test.util.Feature; import org.chromium.net.test.util.TestWebServer; @@ -30,7 +29,10 @@ @Override protected void setUp() throws Exception { super.setUp(); - ContextUtils.initApplicationContext(getActivity().getApplicationContext()); + // CookeManager assumes that native is loaded, but webview browser should not be loaded for + // these tests as webview is not necessarily loaded when CookieManager is called. + AwBrowserProcess.loadLibrary( + getInstrumentation().getTargetContext().getApplicationContext()); } @Override
diff --git a/android_webview/javatests/src/org/chromium/android_webview/test/HttpCacheTest.java b/android_webview/javatests/src/org/chromium/android_webview/test/HttpCacheTest.java index ebde6683..55083d0 100644 --- a/android_webview/javatests/src/org/chromium/android_webview/test/HttpCacheTest.java +++ b/android_webview/javatests/src/org/chromium/android_webview/test/HttpCacheTest.java
@@ -10,6 +10,7 @@ import org.chromium.android_webview.AwBrowserProcess; import org.chromium.android_webview.AwContents; import org.chromium.android_webview.AwContentsStatics; +import org.chromium.base.ContextUtils; import org.chromium.base.PathUtils; import org.chromium.base.test.util.Feature; import org.chromium.net.test.util.TestWebServer; @@ -82,6 +83,7 @@ assertTrue(dummyCacheFile.exists()); // Set up JNI bindings. + ContextUtils.initApplicationContext(targetContext.getApplicationContext()); AwBrowserProcess.loadLibrary(targetContext); // No delay before removing the legacy cache files. AwContentsStatics.setLegacyCacheRemovalDelayForTest(0);
diff --git a/android_webview/test/shell/src/org/chromium/android_webview/test/AwTestRunnerActivity.java b/android_webview/test/shell/src/org/chromium/android_webview/test/AwTestRunnerActivity.java index d87b6302..c3d4ccb 100644 --- a/android_webview/test/shell/src/org/chromium/android_webview/test/AwTestRunnerActivity.java +++ b/android_webview/test/shell/src/org/chromium/android_webview/test/AwTestRunnerActivity.java
@@ -13,6 +13,7 @@ import org.chromium.android_webview.AwBrowserProcess; import org.chromium.android_webview.shell.AwShellResourceProvider; +import org.chromium.base.ContextUtils; /** * This is a lightweight activity for tests that only require WebView functionality. @@ -28,6 +29,7 @@ super.onCreate(savedInstanceState); AwShellResourceProvider.registerResources(this); + ContextUtils.initApplicationContext(getApplicationContext()); AwBrowserProcess.loadLibrary(this); mLinearLayout = new LinearLayout(this);
diff --git a/base/android/context_utils.cc b/base/android/context_utils.cc index fd62c45f..e9ab723 100644 --- a/base/android/context_utils.cc +++ b/base/android/context_utils.cc
@@ -38,11 +38,6 @@ return g_application_context.Get().obj(); } -void InitApplicationContext(JNIEnv* env, const JavaRef<jobject>& context) { - SetNativeApplicationContext(env, context); - Java_ContextUtils_initJavaSideApplicationContext(env, context.obj()); -} - static void InitNativeSideApplicationContext( JNIEnv* env, const JavaParamRef<jclass>& clazz,
diff --git a/base/android/context_utils.h b/base/android/context_utils.h index 52895a9..f172d93 100644 --- a/base/android/context_utils.h +++ b/base/android/context_utils.h
@@ -18,14 +18,6 @@ // must NOT release it. BASE_EXPORT jobject GetApplicationContext(); -// Initialize the global application context object. -// Either this or the Java equivalent ContextUtils.initApplicationContext must -// be called once during startup. JNI bindings must have been initialized, as -// the context is stored on both sides. -BASE_EXPORT void InitApplicationContext( - JNIEnv* env, - const base::android::JavaRef<jobject>& context); - bool RegisterContextUtils(JNIEnv* env); } // namespace android
diff --git a/base/android/java/src/org/chromium/base/ContextUtils.java b/base/android/java/src/org/chromium/base/ContextUtils.java index 51adcff..95cdc40 100644 --- a/base/android/java/src/org/chromium/base/ContextUtils.java +++ b/base/android/java/src/org/chromium/base/ContextUtils.java
@@ -6,7 +6,6 @@ import android.content.Context; -import org.chromium.base.annotations.CalledByNative; import org.chromium.base.annotations.JNINamespace; /** @@ -14,6 +13,7 @@ */ @JNINamespace("base::android") public class ContextUtils { + private static final String TAG = "ContextUtils"; private static Context sApplicationContext; /** @@ -29,34 +29,52 @@ * may make is that it is a Context whose lifetime is the same as the lifetime of the process. */ public static Context getApplicationContext() { - assert sApplicationContext != null; return sApplicationContext; } /** - * Initialize the Android application context. + * Initializes the java application context. * - * Either this or the native equivalent base::android::InitApplicationContext must be called - * once during startup. JNI bindings must have been initialized, as the context is stored on - * both sides. + * This should be called exactly once early on during startup, before native is loaded and + * before any other clients make use of the application context through this class. + * + * @param appContext The application context. */ public static void initApplicationContext(Context appContext) { - assert appContext != null; - assert sApplicationContext == null || sApplicationContext == appContext; + // Conceding that occasionally in tests, native is loaded before the browser process is + // started, in which case the browser process re-sets the application context. + if (sApplicationContext != null && sApplicationContext != appContext) { + throw new RuntimeException("Attempting to set multiple global application contexts."); + } initJavaSideApplicationContext(appContext); - nativeInitNativeSideApplicationContext(appContext); } /** - * JUnit Robolectric tests run without native code; allow them to set just the Java-side - * context. Do not use in configurations that actually run on Android! + * Initialize the native Android application context to be the same as the java counter-part. */ - public static void initApplicationContextForJUnitTests(Context appContext) { + public static void initApplicationContextForNative() { + if (sApplicationContext == null) { + throw new RuntimeException("Cannot have native global application context be null."); + } + nativeInitNativeSideApplicationContext(sApplicationContext); + } + + /** + * Occasionally tests cannot ensure the application context doesn't change between tests (junit) + * and sometimes specific tests has its own special needs, initApplicationContext should be used + * as much as possible, but this method can be used to override it. + * + * @param appContext The new application context. + */ + @VisibleForTesting + public static void initApplicationContextForTests(Context appContext) { initJavaSideApplicationContext(appContext); } - @CalledByNative private static void initJavaSideApplicationContext(Context appContext) { + if (appContext == null) { + throw new RuntimeException("Global application context cannot be set to null."); + } sApplicationContext = appContext; }
diff --git a/base/android/java/src/org/chromium/base/library_loader/LibraryLoader.java b/base/android/java/src/org/chromium/base/library_loader/LibraryLoader.java index 6665ddfd..7858271 100644 --- a/base/android/java/src/org/chromium/base/library_loader/LibraryLoader.java +++ b/base/android/java/src/org/chromium/base/library_loader/LibraryLoader.java
@@ -13,6 +13,7 @@ import android.os.SystemClock; import org.chromium.base.CommandLine; +import org.chromium.base.ContextUtils; import org.chromium.base.Log; import org.chromium.base.PackageUtils; import org.chromium.base.TraceEvent; @@ -132,6 +133,8 @@ * @param context The context in which the method is called. */ public void ensureInitialized(Context context) throws ProcessInitException { + // TODO(wnwen): Move this call appropriately down to the tests that need it. + ContextUtils.initApplicationContext(context.getApplicationContext()); synchronized (sLock) { if (mInitialized) { // Already initialized, nothing to do. @@ -360,6 +363,10 @@ nativeInitCommandLine(CommandLine.getJavaSwitchesOrNull()); CommandLine.enableNativeProxy(); mCommandLineSwitched = true; + + // Ensure that native side application context is loaded and in sync with java side. Must do + // this here so webview also gets its application context set before fully initializing. + ContextUtils.initApplicationContextForNative(); } // Invoke base::android::LibraryLoaded in library_loader_hooks.cc @@ -368,23 +375,13 @@ return; } - // Setup the native command line if necessary. - if (!mCommandLineSwitched) { - nativeInitCommandLine(CommandLine.getJavaSwitchesOrNull()); - } + ensureCommandLineSwitchedAlreadyLocked(); if (!nativeLibraryLoaded()) { Log.e(TAG, "error calling nativeLibraryLoaded"); throw new ProcessInitException(LoaderErrors.LOADER_ERROR_FAILED_TO_REGISTER_JNI); } - // The Chrome JNI is registered by now so we can switch the Java - // command line over to delegating to native if it's necessary. - if (!mCommandLineSwitched) { - CommandLine.enableNativeProxy(); - mCommandLineSwitched = true; - } - // From now on, keep tracing in sync with native. TraceEvent.registerNativeEnabledObserver();
diff --git a/base/task_scheduler/delayed_task_manager.cc b/base/task_scheduler/delayed_task_manager.cc index 0b8c2f9..6286d5e 100644 --- a/base/task_scheduler/delayed_task_manager.cc +++ b/base/task_scheduler/delayed_task_manager.cc
@@ -15,10 +15,12 @@ struct DelayedTaskManager::DelayedTask { DelayedTask(std::unique_ptr<Task> task, scoped_refptr<Sequence> sequence, + SchedulerWorkerThread* worker_thread, SchedulerThreadPool* thread_pool, uint64_t index) : task(std::move(task)), sequence(std::move(sequence)), + worker_thread(worker_thread), thread_pool(thread_pool), index(index) {} @@ -28,10 +30,11 @@ DelayedTask& operator=(DelayedTask&& other) = default; - // |task| will be posted to |thread_pool| as part of |sequence| when it - // becomes ripe for execution. + // |task| will be posted to |thread_pool| with |sequence| and |worker_thread| + // when it becomes ripe for execution. std::unique_ptr<Task> task; scoped_refptr<Sequence> sequence; + SchedulerWorkerThread* worker_thread; SchedulerThreadPool* thread_pool; // Ensures that tasks that have the same |delayed_run_time| are sorted @@ -52,6 +55,7 @@ void DelayedTaskManager::AddDelayedTask(std::unique_ptr<Task> task, scoped_refptr<Sequence> sequence, + SchedulerWorkerThread* worker_thread, SchedulerThreadPool* thread_pool) { DCHECK(task); DCHECK(sequence); @@ -66,8 +70,8 @@ if (!delayed_tasks_.empty()) current_delayed_run_time = delayed_tasks_.top().task->delayed_run_time; - delayed_tasks_.emplace(std::move(task), std::move(sequence), thread_pool, - ++delayed_task_index_); + delayed_tasks_.emplace(std::move(task), std::move(sequence), worker_thread, + thread_pool, ++delayed_task_index_); } if (current_delayed_run_time.is_null() || @@ -100,7 +104,8 @@ // Post delayed tasks that are ready for execution. for (auto& delayed_task : ready_tasks) { delayed_task.thread_pool->PostTaskWithSequenceNow( - std::move(delayed_task.task), std::move(delayed_task.sequence)); + std::move(delayed_task.task), std::move(delayed_task.sequence), + delayed_task.worker_thread); } }
diff --git a/base/task_scheduler/delayed_task_manager.h b/base/task_scheduler/delayed_task_manager.h index 9113fc5..0637026 100644 --- a/base/task_scheduler/delayed_task_manager.h +++ b/base/task_scheduler/delayed_task_manager.h
@@ -24,10 +24,10 @@ namespace internal { class SchedulerThreadPool; +class SchedulerWorkerThread; // A DelayedTaskManager holds delayed Tasks until they become ripe for -// execution. When they become ripe for execution, it posts them to their -// associated Sequence and SchedulerThreadPool. This class is thread-safe. +// execution. This class is thread-safe. class BASE_EXPORT DelayedTaskManager { public: // |on_delayed_run_time_updated| is invoked when the delayed run time is @@ -36,14 +36,17 @@ ~DelayedTaskManager(); // Adds |task| to a queue of delayed tasks. The task will be posted to - // |thread_pool| as part of |sequence| the first time that PostReadyTasks() is - // called while Now() is passed |task->delayed_run_time|. + // |thread_pool| with |sequence| and |worker_thread| the first time that + // PostReadyTasks() is called while Now() is passed |task->delayed_run_time|. + // |worker_thread| is a SchedulerWorkerThread owned by |thread_pool| or + // nullptr. // - // TODO(robliao): Find a concrete way to manage |thread_pool|'s memory. It is - // never deleted in production, but it is better not to spread this assumption - // throughout the scheduler. + // TODO(robliao): Find a concrete way to manage the memory of |worker_thread| + // and |thread_pool|. These objects are never deleted in production, but it is + // better not to spread this assumption throughout the scheduler. void AddDelayedTask(std::unique_ptr<Task> task, scoped_refptr<Sequence> sequence, + SchedulerWorkerThread* worker_thread, SchedulerThreadPool* thread_pool); // Posts delayed tasks that are ripe for execution.
diff --git a/base/task_scheduler/delayed_task_manager_unittest.cc b/base/task_scheduler/delayed_task_manager_unittest.cc index 706bb2b6..dc9c1577 100644 --- a/base/task_scheduler/delayed_task_manager_unittest.cc +++ b/base/task_scheduler/delayed_task_manager_unittest.cc
@@ -59,17 +59,22 @@ } bool PostTaskWithSequence(std::unique_ptr<Task> task, - scoped_refptr<Sequence> sequence) override { + scoped_refptr<Sequence> sequence, + SchedulerWorkerThread* worker_thread) override { NOTREACHED(); return true; } void PostTaskWithSequenceNow(std::unique_ptr<Task> task, - scoped_refptr<Sequence> sequence) override { - PostTaskWithSequenceNowMock(task.get(), sequence.get()); + scoped_refptr<Sequence> sequence, + SchedulerWorkerThread* worker_thread) override { + PostTaskWithSequenceNowMock(task.get(), sequence.get(), worker_thread); } - MOCK_METHOD2(PostTaskWithSequenceNowMock, void(const Task*, const Sequence*)); + MOCK_METHOD3(PostTaskWithSequenceNowMock, + void(const Task*, + const Sequence*, + const SchedulerWorkerThread* worker_thread)); }; } // namespace @@ -95,7 +100,7 @@ // Add |task| to the DelayedTaskManager. EXPECT_CALL(manager, OnDelayedRunTimeUpdated()); - manager.AddDelayedTask(std::move(task), sequence, &thread_pool); + manager.AddDelayedTask(std::move(task), sequence, nullptr, &thread_pool); testing::Mock::VerifyAndClear(&manager); EXPECT_EQ(task_raw->delayed_run_time, manager.GetDelayedRunTime()); @@ -121,7 +126,7 @@ // Add |task| to the DelayedTaskManager. EXPECT_CALL(manager, OnDelayedRunTimeUpdated()); - manager.AddDelayedTask(std::move(task), sequence, &thread_pool); + manager.AddDelayedTask(std::move(task), sequence, nullptr, &thread_pool); testing::Mock::VerifyAndClear(&manager); EXPECT_EQ(task_raw->delayed_run_time, manager.GetDelayedRunTime()); @@ -130,7 +135,7 @@ // Ask the DelayedTaskManager to post tasks that are ripe for execution. EXPECT_CALL(thread_pool, - PostTaskWithSequenceNowMock(task_raw, sequence.get())); + PostTaskWithSequenceNowMock(task_raw, sequence.get(), nullptr)); manager.PostReadyTasks(); testing::Mock::VerifyAndClear(&manager); EXPECT_EQ(TimeTicks(), manager.GetDelayedRunTime()); @@ -150,7 +155,7 @@ // Add |task| to the DelayedTaskManager. EXPECT_CALL(manager, OnDelayedRunTimeUpdated()); - manager.AddDelayedTask(std::move(task), sequence, &thread_pool); + manager.AddDelayedTask(std::move(task), sequence, nullptr, &thread_pool); testing::Mock::VerifyAndClear(&manager); EXPECT_EQ(task_raw->delayed_run_time, manager.GetDelayedRunTime()); @@ -160,7 +165,7 @@ // Ask the DelayedTaskManager to post tasks that are ripe for execution. EXPECT_CALL(thread_pool, - PostTaskWithSequenceNowMock(task_raw, sequence.get())); + PostTaskWithSequenceNowMock(task_raw, sequence.get(), nullptr)); manager.PostReadyTasks(); testing::Mock::VerifyAndClear(&manager); EXPECT_EQ(TimeTicks(), manager.GetDelayedRunTime()); @@ -192,20 +197,20 @@ // Add |task_a| to the DelayedTaskManager. The delayed run time should be // updated to |task_a|'s delayed run time. EXPECT_CALL(manager, OnDelayedRunTimeUpdated()); - manager.AddDelayedTask(std::move(task_a), sequence, &thread_pool); + manager.AddDelayedTask(std::move(task_a), sequence, nullptr, &thread_pool); testing::Mock::VerifyAndClear(&manager); EXPECT_EQ(task_a_raw->delayed_run_time, manager.GetDelayedRunTime()); // Add |task_b| to the DelayedTaskManager. The delayed run time shouldn't // change. - manager.AddDelayedTask(std::move(task_b), sequence, &thread_pool); + manager.AddDelayedTask(std::move(task_b), sequence, nullptr, &thread_pool); testing::Mock::VerifyAndClear(&manager); EXPECT_EQ(task_a_raw->delayed_run_time, manager.GetDelayedRunTime()); // Add |task_c| to the DelayedTaskManager. The delayed run time should be // updated to |task_c|'s delayed run time. EXPECT_CALL(manager, OnDelayedRunTimeUpdated()); - manager.AddDelayedTask(std::move(task_c), sequence, &thread_pool); + manager.AddDelayedTask(std::move(task_c), sequence, nullptr, &thread_pool); testing::Mock::VerifyAndClear(&manager); EXPECT_EQ(task_c_raw->delayed_run_time, manager.GetDelayedRunTime()); @@ -216,7 +221,7 @@ // |task_c_raw| should be posted and the delayed run time should become // |task_a_raw|'s delayed run time. EXPECT_CALL(thread_pool, - PostTaskWithSequenceNowMock(task_c_raw, sequence.get())); + PostTaskWithSequenceNowMock(task_c_raw, sequence.get(), nullptr)); manager.PostReadyTasks(); testing::Mock::VerifyAndClear(&thread_pool); EXPECT_EQ(task_a_raw->delayed_run_time, manager.GetDelayedRunTime()); @@ -228,9 +233,9 @@ // |task_a_raw| and |task_b_raw| should be posted and the delayed run time // should become a null TimeTicks. EXPECT_CALL(thread_pool, - PostTaskWithSequenceNowMock(task_a_raw, sequence.get())); + PostTaskWithSequenceNowMock(task_a_raw, sequence.get(), nullptr)); EXPECT_CALL(thread_pool, - PostTaskWithSequenceNowMock(task_b_raw, sequence.get())); + PostTaskWithSequenceNowMock(task_b_raw, sequence.get(), nullptr)); manager.PostReadyTasks(); testing::Mock::VerifyAndClear(&thread_pool); EXPECT_EQ(TimeTicks(), manager.GetDelayedRunTime());
diff --git a/base/task_scheduler/scheduler_thread_pool.h b/base/task_scheduler/scheduler_thread_pool.h index 2451474..9793162 100644 --- a/base/task_scheduler/scheduler_thread_pool.h +++ b/base/task_scheduler/scheduler_thread_pool.h
@@ -17,6 +17,7 @@ namespace base { namespace internal { +class SchedulerWorkerThread; struct SequenceSortKey; // Interface for a thread pool. @@ -37,16 +38,26 @@ virtual void ReEnqueueSequence(scoped_refptr<Sequence> sequence, const SequenceSortKey& sequence_sort_key) = 0; - // Posts |task| to be executed as part of |sequence|. Returns true if |task| - // is posted. + // Posts |task| to be executed as part of |sequence|. If |worker_thread| is + // non-null, |task| will be scheduled to run on it specifically (note: + // |worker_thread| must be owned by this SchedulerThreadPool); otherwise, + // |task| will be added to the pending shared work. Returns true if |task| is + // posted. virtual bool PostTaskWithSequence(std::unique_ptr<Task> task, - scoped_refptr<Sequence> sequence) = 0; + scoped_refptr<Sequence> sequence, + SchedulerWorkerThread* worker_thread) = 0; - // Posts |task| to be executed by this thread pool as part of |sequence|. The - // scheduler's TaskTracker must have allowed |task| to be posted before this - // is called. This must only be called after |task|'s delayed run time. - virtual void PostTaskWithSequenceNow(std::unique_ptr<Task> task, - scoped_refptr<Sequence> sequence) = 0; + // Posts |task| to be executed by this thread pool as part of |sequence|. If + // |worker_thread| is non-null, |task| will be scheduled to run on it + // specifically (note: |worker_thread| must be owned by this + // SchedulerThreadPool); otherwise, |task| will be added to the pending shared + // work. The scheduler's TaskTracker must have allowed |task| to be posted + // before this is called. This must only be called after |task|'s delayed run + // time. + virtual void PostTaskWithSequenceNow( + std::unique_ptr<Task> task, + scoped_refptr<Sequence> sequence, + SchedulerWorkerThread* worker_thread) = 0; }; } // namespace internal
diff --git a/base/task_scheduler/scheduler_thread_pool_impl.cc b/base/task_scheduler/scheduler_thread_pool_impl.cc index 599c46b..b64405d 100644 --- a/base/task_scheduler/scheduler_thread_pool_impl.cc +++ b/base/task_scheduler/scheduler_thread_pool_impl.cc
@@ -4,14 +4,15 @@ #include "base/task_scheduler/scheduler_thread_pool_impl.h" +#include <algorithm> #include <utility> #include "base/bind.h" #include "base/bind_helpers.h" #include "base/lazy_instance.h" -#include "base/logging.h" #include "base/memory/ptr_util.h" #include "base/sequenced_task_runner.h" +#include "base/single_thread_task_runner.h" #include "base/task_scheduler/delayed_task_manager.h" #include "base/task_scheduler/task_tracker.h" #include "base/threading/thread_local.h" @@ -25,6 +26,10 @@ LazyInstance<ThreadLocalPointer<const SchedulerThreadPool>>::Leaky tls_current_thread_pool = LAZY_INSTANCE_INITIALIZER; +// SchedulerWorkerThread that owns the current thread, if any. +LazyInstance<ThreadLocalPointer<const SchedulerWorkerThread>>::Leaky + tls_current_worker_thread = LAZY_INSTANCE_INITIALIZER; + // A task runner that runs tasks with the PARALLEL ExecutionMode. class SchedulerParallelTaskRunner : public TaskRunner { public: @@ -42,7 +47,7 @@ // Post the task as part of a one-off single-task Sequence. return thread_pool_->PostTaskWithSequence( WrapUnique(new Task(from_here, closure, traits_, delay)), - make_scoped_refptr(new Sequence)); + make_scoped_refptr(new Sequence), nullptr); } bool RunsTasksOnCurrentThread() const override { @@ -72,9 +77,10 @@ bool PostDelayedTask(const tracked_objects::Location& from_here, const Closure& closure, TimeDelta delay) override { - // Post the task as part of |sequence|. + // Post the task as part of |sequence_|. return thread_pool_->PostTaskWithSequence( - WrapUnique(new Task(from_here, closure, traits_, delay)), sequence_); + WrapUnique(new Task(from_here, closure, traits_, delay)), sequence_, + nullptr); } bool PostNonNestableDelayedTask(const tracked_objects::Location& from_here, @@ -100,18 +106,88 @@ DISALLOW_COPY_AND_ASSIGN(SchedulerSequencedTaskRunner); }; +// A task runner that runs tasks with the SINGLE_THREADED ExecutionMode. +class SchedulerSingleThreadTaskRunner : public SingleThreadTaskRunner { + public: + // Constructs a SchedulerSingleThreadTaskRunner which can be used to post + // tasks so long as |thread_pool| and |worker_thread| are alive. + // TODO(robliao): Find a concrete way to manage the memory of |thread_pool| + // and |worker_thread|. + SchedulerSingleThreadTaskRunner(const TaskTraits& traits, + SchedulerThreadPool* thread_pool, + SchedulerWorkerThread* worker_thread) + : traits_(traits), + thread_pool_(thread_pool), + worker_thread_(worker_thread) {} + + // SingleThreadTaskRunner: + bool PostDelayedTask(const tracked_objects::Location& from_here, + const Closure& closure, + TimeDelta delay) override { + // Post the task to be executed by |worker_thread_| as part of |sequence_|. + return thread_pool_->PostTaskWithSequence( + WrapUnique(new Task(from_here, closure, traits_, delay)), sequence_, + worker_thread_); + } + + bool PostNonNestableDelayedTask(const tracked_objects::Location& from_here, + const Closure& closure, + base::TimeDelta delay) override { + // Tasks are never nested within the task scheduler. + return PostDelayedTask(from_here, closure, delay); + } + + bool RunsTasksOnCurrentThread() const override { + return tls_current_worker_thread.Get().Get() == worker_thread_; + } + + private: + ~SchedulerSingleThreadTaskRunner() override = default; + + // Sequence for all Tasks posted through this TaskRunner. + const scoped_refptr<Sequence> sequence_ = new Sequence; + + const TaskTraits traits_; + SchedulerThreadPool* const thread_pool_; + SchedulerWorkerThread* const worker_thread_; + + DISALLOW_COPY_AND_ASSIGN(SchedulerSingleThreadTaskRunner); +}; + +// Only used in DCHECKs. +bool ContainsWorkerThread( + const std::vector<std::unique_ptr<SchedulerWorkerThread>>& worker_threads, + const SchedulerWorkerThread* worker_thread) { + auto it = std::find_if( + worker_threads.begin(), worker_threads.end(), + [worker_thread](const std::unique_ptr<SchedulerWorkerThread>& i) { + return i.get() == worker_thread; + }); + return it != worker_threads.end(); +} + } // namespace class SchedulerThreadPoolImpl::SchedulerWorkerThreadDelegateImpl : public SchedulerWorkerThread::Delegate { public: + // |outer| owns the worker thread for which this delegate is constructed. + // |re_enqueue_sequence_callback| is invoked when ReEnqueueSequence() is + // called with a non-single-threaded Sequence. |shared_priority_queue| is a + // PriorityQueue whose transactions may overlap with the worker thread's + // single-threaded PriorityQueue's transactions. SchedulerWorkerThreadDelegateImpl( SchedulerThreadPoolImpl* outer, - const ReEnqueueSequenceCallback& re_enqueue_sequence_callback); + const ReEnqueueSequenceCallback& re_enqueue_sequence_callback, + const PriorityQueue* shared_priority_queue); ~SchedulerWorkerThreadDelegateImpl() override; + PriorityQueue* single_threaded_priority_queue() { + return &single_threaded_priority_queue_; + } + // SchedulerWorkerThread::Delegate: - void OnMainEntry() override; + void OnMainEntry(SchedulerWorkerThread* worker_thread) override; scoped_refptr<Sequence> GetWork( SchedulerWorkerThread* worker_thread) override; void ReEnqueueSequence(scoped_refptr<Sequence> sequence) override; @@ -120,6 +196,13 @@ SchedulerThreadPoolImpl* outer_; const ReEnqueueSequenceCallback re_enqueue_sequence_callback_; + // Single-threaded PriorityQueue for the worker thread. + PriorityQueue single_threaded_priority_queue_; + + // True if the last Sequence returned by GetWork() was extracted from + // |single_threaded_priority_queue_|. + bool last_sequence_is_single_threaded_ = false; + DISALLOW_COPY_AND_ASSIGN(SchedulerWorkerThreadDelegateImpl); }; @@ -129,6 +212,7 @@ DCHECK(join_for_testing_returned_.IsSignaled() || worker_threads_.empty()); } +// static std::unique_ptr<SchedulerThreadPoolImpl> SchedulerThreadPoolImpl::Create( ThreadPriority thread_priority, size_t max_threads, @@ -168,10 +252,21 @@ case ExecutionMode::SEQUENCED: return make_scoped_refptr(new SchedulerSequencedTaskRunner(traits, this)); - case ExecutionMode::SINGLE_THREADED: - // TODO(fdoray): Support SINGLE_THREADED TaskRunners. - NOTREACHED(); - return nullptr; + case ExecutionMode::SINGLE_THREADED: { + // TODO(fdoray): Find a way to take load into account when assigning a + // SchedulerWorkerThread to a SingleThreadTaskRunner. Also, this code + // assumes that all SchedulerWorkerThreads are alive. Eventually, we might + // decide to tear down threads that haven't run tasks for a long time. + size_t worker_thread_index; + { + AutoSchedulerLock auto_lock(next_worker_thread_index_lock_); + worker_thread_index = next_worker_thread_index_; + next_worker_thread_index_ = + (next_worker_thread_index_ + 1) % worker_threads_.size(); + } + return make_scoped_refptr(new SchedulerSingleThreadTaskRunner( + traits, this, worker_threads_[worker_thread_index].get())); + } } NOTREACHED(); @@ -199,18 +294,22 @@ bool SchedulerThreadPoolImpl::PostTaskWithSequence( std::unique_ptr<Task> task, - scoped_refptr<Sequence> sequence) { + scoped_refptr<Sequence> sequence, + SchedulerWorkerThread* worker_thread) { DCHECK(task); DCHECK(sequence); + DCHECK(!worker_thread || + ContainsWorkerThread(worker_threads_, worker_thread)); if (!task_tracker_->WillPostTask(task.get())) return false; if (task->delayed_run_time.is_null()) { - PostTaskWithSequenceNow(std::move(task), std::move(sequence)); + PostTaskWithSequenceNow(std::move(task), std::move(sequence), + worker_thread); } else { delayed_task_manager_->AddDelayedTask(std::move(task), std::move(sequence), - this); + worker_thread, this); } return true; @@ -218,79 +317,151 @@ void SchedulerThreadPoolImpl::PostTaskWithSequenceNow( std::unique_ptr<Task> task, - scoped_refptr<Sequence> sequence) { + scoped_refptr<Sequence> sequence, + SchedulerWorkerThread* worker_thread) { DCHECK(task); DCHECK(sequence); + DCHECK(!worker_thread || + ContainsWorkerThread(worker_threads_, worker_thread)); // Confirm that |task| is ready to run (its delayed run time is either null or // in the past). DCHECK_LE(task->delayed_run_time, delayed_task_manager_->Now()); + // Because |worker_thread| belongs to this thread pool, we know that the type + // of its delegate is SchedulerWorkerThreadDelegateImpl. + PriorityQueue* const priority_queue = + worker_thread + ? static_cast<SchedulerWorkerThreadDelegateImpl*>( + worker_thread->delegate()) + ->single_threaded_priority_queue() + : &shared_priority_queue_; + DCHECK(priority_queue); + const bool sequence_was_empty = sequence->PushTask(std::move(task)); if (sequence_was_empty) { - // Insert |sequence| in |shared_priority_queue_| if it was empty before - // |task| was inserted into it. Otherwise, one of these must be true: + // Insert |sequence| in |priority_queue| if it was empty before |task| was + // inserted into it. Otherwise, one of these must be true: // - |sequence| is already in a PriorityQueue (not necessarily // |shared_priority_queue_|), or, // - A worker thread is running a Task from |sequence|. It will insert // |sequence| in a PriorityQueue once it's done running the Task. const auto sequence_sort_key = sequence->GetSortKey(); - shared_priority_queue_.BeginTransaction()->Push( + priority_queue->BeginTransaction()->Push( WrapUnique(new PriorityQueue::SequenceAndSortKey(std::move(sequence), sequence_sort_key))); // Wake up a worker thread to process |sequence|. - WakeUpOneThread(); + if (worker_thread) + worker_thread->WakeUp(); + else + WakeUpOneThread(); } } SchedulerThreadPoolImpl::SchedulerWorkerThreadDelegateImpl:: SchedulerWorkerThreadDelegateImpl( SchedulerThreadPoolImpl* outer, - const ReEnqueueSequenceCallback& re_enqueue_sequence_callback) + const ReEnqueueSequenceCallback& re_enqueue_sequence_callback, + const PriorityQueue* shared_priority_queue) : outer_(outer), - re_enqueue_sequence_callback_(re_enqueue_sequence_callback) {} + re_enqueue_sequence_callback_(re_enqueue_sequence_callback), + single_threaded_priority_queue_(shared_priority_queue) {} SchedulerThreadPoolImpl::SchedulerWorkerThreadDelegateImpl:: ~SchedulerWorkerThreadDelegateImpl() = default; -void SchedulerThreadPoolImpl::SchedulerWorkerThreadDelegateImpl::OnMainEntry() { +void SchedulerThreadPoolImpl::SchedulerWorkerThreadDelegateImpl::OnMainEntry( + SchedulerWorkerThread* worker_thread) { +#if DCHECK_IS_ON() + // Wait for |outer_->threads_created_| to avoid traversing + // |outer_->worker_threads_| while it is being filled by Initialize(). + outer_->threads_created_.Wait(); + DCHECK(ContainsWorkerThread(outer_->worker_threads_, worker_thread)); +#endif + + DCHECK(!tls_current_worker_thread.Get().Get()); DCHECK(!tls_current_thread_pool.Get().Get()); + tls_current_worker_thread.Get().Set(worker_thread); tls_current_thread_pool.Get().Set(outer_); } scoped_refptr<Sequence> SchedulerThreadPoolImpl::SchedulerWorkerThreadDelegateImpl::GetWork( SchedulerWorkerThread* worker_thread) { - std::unique_ptr<PriorityQueue::Transaction> transaction( - outer_->shared_priority_queue_.BeginTransaction()); - const auto& sequence_and_sort_key = transaction->Peek(); + DCHECK(ContainsWorkerThread(outer_->worker_threads_, worker_thread)); - if (sequence_and_sort_key.is_null()) { - // |transaction| is kept alive while |worker_thread| is added to - // |idle_worker_threads_stack_| to avoid this race: - // 1. This thread creates a Transaction, finds |shared_priority_queue_| - // empty and ends the Transaction. - // 2. Other thread creates a Transaction, inserts a Sequence into - // |shared_priority_queue_| and ends the Transaction. This can't happen - // if the Transaction of step 1 is still active because because there can - // only be one active Transaction per PriorityQueue at a time. - // 3. Other thread calls WakeUpOneThread(). No thread is woken up because - // |idle_worker_threads_stack_| is empty. - // 4. This thread adds itself to |idle_worker_threads_stack_| and goes to - // sleep. No thread runs the Sequence inserted in step 2. - outer_->AddToIdleWorkerThreadsStack(worker_thread); - return nullptr; + scoped_refptr<Sequence> sequence; + { + std::unique_ptr<PriorityQueue::Transaction> shared_transaction( + outer_->shared_priority_queue_.BeginTransaction()); + const auto& shared_sequence_and_sort_key = shared_transaction->Peek(); + + std::unique_ptr<PriorityQueue::Transaction> single_threaded_transaction( + single_threaded_priority_queue_.BeginTransaction()); + const auto& single_threaded_sequence_and_sort_key = + single_threaded_transaction->Peek(); + + if (shared_sequence_and_sort_key.is_null() && + single_threaded_sequence_and_sort_key.is_null()) { + single_threaded_transaction.reset(); + + // |shared_transaction| is kept alive while |worker_thread| is added to + // |idle_worker_threads_stack_| to avoid this race: + // 1. This thread creates a Transaction, finds |shared_priority_queue_| + // empty and ends the Transaction. + // 2. Other thread creates a Transaction, inserts a Sequence into + // |shared_priority_queue_| and ends the Transaction. This can't happen + // if the Transaction of step 1 is still active because because there + // can only be one active Transaction per PriorityQueue at a time. + // 3. Other thread calls WakeUpOneThread(). No thread is woken up because + // |idle_worker_threads_stack_| is empty. + // 4. This thread adds itself to |idle_worker_threads_stack_| and goes to + // sleep. No thread runs the Sequence inserted in step 2. + outer_->AddToIdleWorkerThreadsStack(worker_thread); + return nullptr; + } + + // True if both PriorityQueues have Sequences and the Sequence at the top of + // the shared PriorityQueue is more important. + const bool shared_sequence_is_more_important = + !shared_sequence_and_sort_key.is_null() && + !single_threaded_sequence_and_sort_key.is_null() && + shared_sequence_and_sort_key.sort_key > + single_threaded_sequence_and_sort_key.sort_key; + + if (single_threaded_sequence_and_sort_key.is_null() || + shared_sequence_is_more_important) { + sequence = shared_sequence_and_sort_key.sequence; + shared_transaction->Pop(); + last_sequence_is_single_threaded_ = false; + } else { + DCHECK(!single_threaded_sequence_and_sort_key.is_null()); + sequence = single_threaded_sequence_and_sort_key.sequence; + single_threaded_transaction->Pop(); + last_sequence_is_single_threaded_ = true; + } } + DCHECK(sequence); - scoped_refptr<Sequence> sequence = sequence_and_sort_key.sequence; - transaction->Pop(); + outer_->RemoveFromIdleWorkerThreadsStack(worker_thread); return sequence; } void SchedulerThreadPoolImpl::SchedulerWorkerThreadDelegateImpl:: ReEnqueueSequence(scoped_refptr<Sequence> sequence) { - re_enqueue_sequence_callback_.Run(std::move(sequence)); + if (last_sequence_is_single_threaded_) { + // A single-threaded Sequence is always re-enqueued in the single-threaded + // PriorityQueue from which it was extracted. + const SequenceSortKey sequence_sort_key = sequence->GetSortKey(); + single_threaded_priority_queue_.BeginTransaction()->Push( + WrapUnique(new PriorityQueue::SequenceAndSortKey(std::move(sequence), + sequence_sort_key))); + } else { + // |re_enqueue_sequence_callback_| will determine in which PriorityQueue + // |sequence| must be enqueued. + re_enqueue_sequence_callback_.Run(std::move(sequence)); + } } SchedulerThreadPoolImpl::SchedulerThreadPoolImpl( @@ -300,6 +471,9 @@ idle_worker_threads_stack_cv_for_testing_( idle_worker_threads_stack_lock_.CreateConditionVariable()), join_for_testing_returned_(true, false), +#if DCHECK_IS_ON() + threads_created_(true, false), +#endif task_tracker_(task_tracker), delayed_task_manager_(delayed_task_manager) { DCHECK(task_tracker_); @@ -317,8 +491,9 @@ for (size_t i = 0; i < max_threads; ++i) { std::unique_ptr<SchedulerWorkerThread> worker_thread = SchedulerWorkerThread::Create( - thread_priority, WrapUnique(new SchedulerWorkerThreadDelegateImpl( - this, re_enqueue_sequence_callback)), + thread_priority, + WrapUnique(new SchedulerWorkerThreadDelegateImpl( + this, re_enqueue_sequence_callback, &shared_priority_queue_)), task_tracker_); if (!worker_thread) break; @@ -326,6 +501,10 @@ worker_threads_.push_back(std::move(worker_thread)); } +#if DCHECK_IS_ON() + threads_created_.Signal(); +#endif + return !worker_threads_.empty(); } @@ -349,5 +528,11 @@ idle_worker_threads_stack_cv_for_testing_->Broadcast(); } +void SchedulerThreadPoolImpl::RemoveFromIdleWorkerThreadsStack( + SchedulerWorkerThread* worker_thread) { + AutoSchedulerLock auto_lock(idle_worker_threads_stack_lock_); + idle_worker_threads_stack_.Remove(worker_thread); +} + } // namespace internal } // namespace base
diff --git a/base/task_scheduler/scheduler_thread_pool_impl.h b/base/task_scheduler/scheduler_thread_pool_impl.h index b764f27..13fba7e5 100644 --- a/base/task_scheduler/scheduler_thread_pool_impl.h +++ b/base/task_scheduler/scheduler_thread_pool_impl.h
@@ -12,6 +12,7 @@ #include "base/base_export.h" #include "base/callback.h" +#include "base/logging.h" #include "base/macros.h" #include "base/memory/ref_counted.h" #include "base/synchronization/condition_variable.h" @@ -72,16 +73,17 @@ void ReEnqueueSequence(scoped_refptr<Sequence> sequence, const SequenceSortKey& sequence_sort_key) override; bool PostTaskWithSequence(std::unique_ptr<Task> task, - scoped_refptr<Sequence> sequence) override; + scoped_refptr<Sequence> sequence, + SchedulerWorkerThread* worker_thread) override; void PostTaskWithSequenceNow(std::unique_ptr<Task> task, - scoped_refptr<Sequence> sequence) override; + scoped_refptr<Sequence> sequence, + SchedulerWorkerThread* worker_thread) override; private: class SchedulerWorkerThreadDelegateImpl; - SchedulerThreadPoolImpl( - TaskTracker* task_tracker, - DelayedTaskManager* delayed_task_manager); + SchedulerThreadPoolImpl(TaskTracker* task_tracker, + DelayedTaskManager* delayed_task_manager); bool Initialize( ThreadPriority thread_priority, @@ -94,13 +96,23 @@ // Adds |worker_thread| to |idle_worker_threads_stack_|. void AddToIdleWorkerThreadsStack(SchedulerWorkerThread* worker_thread); - // PriorityQueue from which all threads of this thread pool get work. - PriorityQueue shared_priority_queue_; + // Removes |worker_thread| from |idle_worker_threads_stack_|. + void RemoveFromIdleWorkerThreadsStack(SchedulerWorkerThread* worker_thread); // All worker threads owned by this thread pool. Only modified during // initialization of the thread pool. std::vector<std::unique_ptr<SchedulerWorkerThread>> worker_threads_; + // Synchronizes access to |next_worker_thread_index_|. + SchedulerLock next_worker_thread_index_lock_; + + // Index of the worker thread that will be assigned to the next single- + // threaded TaskRunner returned by this pool. + size_t next_worker_thread_index_ = 0; + + // PriorityQueue from which all threads of this thread pool get work. + PriorityQueue shared_priority_queue_; + // Synchronizes access to |idle_worker_threads_stack_| and // |idle_worker_threads_stack_cv_for_testing_|. Has |shared_priority_queue_|'s // lock as its predecessor so that a thread can be pushed to @@ -117,6 +129,11 @@ // Signaled once JoinForTesting() has returned. WaitableEvent join_for_testing_returned_; +#if DCHECK_IS_ON() + // Signaled when all threads have been created. + WaitableEvent threads_created_; +#endif + TaskTracker* const task_tracker_; DelayedTaskManager* const delayed_task_manager_;
diff --git a/base/task_scheduler/scheduler_thread_pool_impl_unittest.cc b/base/task_scheduler/scheduler_thread_pool_impl_unittest.cc index 691d0dd..3eb003e 100644 --- a/base/task_scheduler/scheduler_thread_pool_impl_unittest.cc +++ b/base/task_scheduler/scheduler_thread_pool_impl_unittest.cc
@@ -314,6 +314,9 @@ INSTANTIATE_TEST_CASE_P(Sequenced, TaskSchedulerThreadPoolImplTest, ::testing::Values(ExecutionMode::SEQUENCED)); +INSTANTIATE_TEST_CASE_P(SingleThreaded, + TaskSchedulerThreadPoolImplTest, + ::testing::Values(ExecutionMode::SINGLE_THREADED)); } // namespace internal } // namespace base
diff --git a/base/task_scheduler/scheduler_worker_thread.cc b/base/task_scheduler/scheduler_worker_thread.cc index 11c88af..c015bd86 100644 --- a/base/task_scheduler/scheduler_worker_thread.cc +++ b/base/task_scheduler/scheduler_worker_thread.cc
@@ -59,7 +59,7 @@ } void SchedulerWorkerThread::ThreadMain() { - delegate_->OnMainEntry(); + delegate_->OnMainEntry(this); // A SchedulerWorkerThread starts out sleeping. wake_up_event_.Wait();
diff --git a/base/task_scheduler/scheduler_worker_thread.h b/base/task_scheduler/scheduler_worker_thread.h index 3022d100..5de245dc 100644 --- a/base/task_scheduler/scheduler_worker_thread.h +++ b/base/task_scheduler/scheduler_worker_thread.h
@@ -37,8 +37,8 @@ public: virtual ~Delegate() = default; - // Called when the main function of the SchedulerWorkerThread enters. - virtual void OnMainEntry() = 0; + // Called by |worker_thread| when it enters its main function. + virtual void OnMainEntry(SchedulerWorkerThread* worker_thread) = 0; // Called by |worker_thread| to get a Sequence from which to run a Task. virtual scoped_refptr<Sequence> GetWork( @@ -68,6 +68,8 @@ // returned by the GetWork() method of its delegate until it returns nullptr. void WakeUp(); + SchedulerWorkerThread::Delegate* delegate() { return delegate_.get(); } + // Joins this SchedulerWorkerThread. If a Task is already running, it will be // allowed to complete its execution. This can only be called once. void JoinForTesting();
diff --git a/base/task_scheduler/scheduler_worker_thread_stack_unittest.cc b/base/task_scheduler/scheduler_worker_thread_stack_unittest.cc index b39243d0..50422140 100644 --- a/base/task_scheduler/scheduler_worker_thread_stack_unittest.cc +++ b/base/task_scheduler/scheduler_worker_thread_stack_unittest.cc
@@ -22,7 +22,7 @@ class MockSchedulerWorkerThreadDelegate : public SchedulerWorkerThread::Delegate { public: - void OnMainEntry() override {} + void OnMainEntry(SchedulerWorkerThread* worker_thread) override {} scoped_refptr<Sequence> GetWork( SchedulerWorkerThread* worker_thread) override { return nullptr;
diff --git a/base/task_scheduler/scheduler_worker_thread_unittest.cc b/base/task_scheduler/scheduler_worker_thread_unittest.cc index 36fa423..2a9d5c6 100644 --- a/base/task_scheduler/scheduler_worker_thread_unittest.cc +++ b/base/task_scheduler/scheduler_worker_thread_unittest.cc
@@ -31,7 +31,8 @@ protected: TaskSchedulerWorkerThreadTest() : main_entry_called_(true, false), - num_get_work_cv_(lock_.CreateConditionVariable()) {} + num_get_work_cv_(lock_.CreateConditionVariable()), + worker_thread_set_(true, false) {} void SetUp() override { worker_thread_ = SchedulerWorkerThread::Create( @@ -39,6 +40,7 @@ WrapUnique(new TestSchedulerWorkerThreadDelegate(this)), &task_tracker_); ASSERT_TRUE(worker_thread_); + worker_thread_set_.Signal(); main_entry_called_.Wait(); } @@ -91,7 +93,10 @@ : outer_(outer) {} // SchedulerWorkerThread::Delegate: - void OnMainEntry() override { + void OnMainEntry(SchedulerWorkerThread* worker_thread) override { + outer_->worker_thread_set_.Wait(); + EXPECT_EQ(outer_->worker_thread_.get(), worker_thread); + // Without synchronization, OnMainEntry() could be called twice without // generating an error. AutoSchedulerLock auto_lock(outer_->lock_); @@ -200,6 +205,9 @@ // Number of times that RunTaskCallback() has been called. size_t num_run_tasks_ = 0; + // Signaled after |worker_thread_| is set. + WaitableEvent worker_thread_set_; + DISALLOW_COPY_AND_ASSIGN(TaskSchedulerWorkerThreadTest); };
diff --git a/blimp/client/app/android/java/src/org/chromium/blimp/BlimpLibraryLoader.java b/blimp/client/app/android/java/src/org/chromium/blimp/BlimpLibraryLoader.java index 3463887..290c4dbb 100644 --- a/blimp/client/app/android/java/src/org/chromium/blimp/BlimpLibraryLoader.java +++ b/blimp/client/app/android/java/src/org/chromium/blimp/BlimpLibraryLoader.java
@@ -7,7 +7,6 @@ import android.content.Context; import android.os.Handler; -import org.chromium.base.ContextUtils; import org.chromium.base.ObserverList; import org.chromium.base.ResourceExtractor; import org.chromium.base.ThreadUtils; @@ -91,7 +90,6 @@ extractor.addCompletionCallback(new Runnable() { @Override public void run() { - ContextUtils.initApplicationContext(context.getApplicationContext()); new Handler().post(new Runnable() { @Override public void run() {
diff --git a/cc/layers/draw_properties.cc b/cc/layers/draw_properties.cc index 909ef47..165dc26 100644 --- a/cc/layers/draw_properties.cc +++ b/cc/layers/draw_properties.cc
@@ -12,7 +12,6 @@ can_use_lcd_text(false), is_clipped(false), num_unclipped_descendants(0), - last_drawn_render_surface_layer_list_id(0), maximum_animation_contents_scale(0.f), starting_animation_contents_scale(0.f) {}
diff --git a/cc/layers/draw_properties.h b/cc/layers/draw_properties.h index 59acede..866bc53 100644 --- a/cc/layers/draw_properties.h +++ b/cc/layers/draw_properties.h
@@ -66,15 +66,6 @@ // does not include our clip children because they are clipped by us. size_t num_unclipped_descendants; - // Each time we generate a new render surface layer list, an ID is used to - // identify it. |last_drawn_render_surface_layer_list_id| is set to the ID - // that marked the render surface layer list generation which last updated - // these draw properties and determined that this layer will draw itself. - // If these draw properties are not a part of the render surface layer list, - // or the layer doesn't contribute anything, then this ID will be either out - // of date or 0. - int last_drawn_render_surface_layer_list_id; - // The maximum scale during the layers current animation at which content // should be rastered at to be crisp. float maximum_animation_contents_scale;
diff --git a/cc/layers/layer_impl.cc b/cc/layers/layer_impl.cc index d238c3c..9b7f532 100644 --- a/cc/layers/layer_impl.cc +++ b/cc/layers/layer_impl.cc
@@ -65,6 +65,7 @@ use_local_transform_for_backface_visibility_(false), should_check_backface_visibility_(false), draws_content_(false), + is_drawn_render_surface_layer_list_member_(false), hide_layer_and_subtree_(false), is_affected_by_page_scale_(true), was_ever_ready_since_last_transform_animation_(true), @@ -1294,11 +1295,6 @@ } } -bool LayerImpl::IsDrawnRenderSurfaceLayerListMember() const { - return draw_properties_.last_drawn_render_surface_layer_list_id == - layer_tree_impl_->current_render_surface_list_id(); -} - size_t LayerImpl::GPUMemoryUsageInBytes() const { return 0; } void LayerImpl::RunMicroBenchmark(MicroBenchmarkImpl* benchmark) { @@ -1318,7 +1314,7 @@ gfx::Transform LayerImpl::DrawTransform() const { // Only drawn layers have up-to-date draw properties. - if (!IsDrawnRenderSurfaceLayerListMember()) { + if (!is_drawn_render_surface_layer_list_member()) { if (layer_tree_impl()->property_trees()->non_root_surfaces_enabled) { return draw_property_utils::DrawTransform( this, layer_tree_impl()->property_trees()->transform_tree); @@ -1333,7 +1329,7 @@ gfx::Transform LayerImpl::ScreenSpaceTransform() const { // Only drawn layers have up-to-date draw properties. - if (!IsDrawnRenderSurfaceLayerListMember()) { + if (!is_drawn_render_surface_layer_list_member()) { return draw_property_utils::ScreenSpaceTransform( this, layer_tree_impl()->property_trees()->transform_tree); }
diff --git a/cc/layers/layer_impl.h b/cc/layers/layer_impl.h index 119cfbfb..8f72d02 100644 --- a/cc/layers/layer_impl.h +++ b/cc/layers/layer_impl.h
@@ -473,7 +473,13 @@ void SetDebugInfo( std::unique_ptr<base::trace_event::ConvertableToTraceFormat> debug_info); - bool IsDrawnRenderSurfaceLayerListMember() const; + void set_is_drawn_render_surface_layer_list_member(bool is_member) { + is_drawn_render_surface_layer_list_member_ = is_member; + } + + bool is_drawn_render_surface_layer_list_member() const { + return is_drawn_render_surface_layer_list_member_; + } void Set3dSortingContextId(int id); int sorting_context_id() { return sorting_context_id_; } @@ -595,6 +601,7 @@ bool use_local_transform_for_backface_visibility_ : 1; bool should_check_backface_visibility_ : 1; bool draws_content_ : 1; + bool is_drawn_render_surface_layer_list_member_ : 1; bool hide_layer_and_subtree_ : 1; bool is_affected_by_page_scale_ : 1;
diff --git a/cc/layers/layer_iterator_unittest.cc b/cc/layers/layer_iterator_unittest.cc index a8ad64b4..9c23d32 100644 --- a/cc/layers/layer_iterator_unittest.cc +++ b/cc/layers/layer_iterator_unittest.cc
@@ -139,10 +139,8 @@ host_impl_.active_tree()->SetRootLayer(std::move(root_layer)); LayerImplList render_surface_layer_list; - host_impl_.active_tree()->IncrementRenderSurfaceListIdForTesting(); LayerTreeHostCommon::CalcDrawPropsImplInputsForTesting inputs( - root_ptr, root_ptr->bounds(), &render_surface_layer_list, - host_impl_.active_tree()->current_render_surface_list_id()); + root_ptr, root_ptr->bounds(), &render_surface_layer_list); LayerTreeHostCommon::CalculateDrawProperties(&inputs); IterateFrontToBack(&render_surface_layer_list); @@ -186,10 +184,8 @@ host_impl_.active_tree()->SetRootLayer(std::move(root_layer)); LayerImplList render_surface_layer_list; - host_impl_.active_tree()->IncrementRenderSurfaceListIdForTesting(); LayerTreeHostCommon::CalcDrawPropsImplInputsForTesting inputs( - root_ptr, root_ptr->bounds(), &render_surface_layer_list, - host_impl_.active_tree()->current_render_surface_list_id()); + root_ptr, root_ptr->bounds(), &render_surface_layer_list); LayerTreeHostCommon::CalculateDrawProperties(&inputs); IterateFrontToBack(&render_surface_layer_list); @@ -241,10 +237,8 @@ host_impl_.active_tree()->SetRootLayer(std::move(root_layer)); LayerImplList render_surface_layer_list; - host_impl_.active_tree()->IncrementRenderSurfaceListIdForTesting(); LayerTreeHostCommon::CalcDrawPropsImplInputsForTesting inputs( - root_ptr, root_ptr->bounds(), &render_surface_layer_list, - host_impl_.active_tree()->current_render_surface_list_id()); + root_ptr, root_ptr->bounds(), &render_surface_layer_list); LayerTreeHostCommon::CalculateDrawProperties(&inputs); IterateFrontToBack(&render_surface_layer_list);
diff --git a/cc/layers/layer_position_constraint_unittest.cc b/cc/layers/layer_position_constraint_unittest.cc index c274383e..104d8e618 100644 --- a/cc/layers/layer_position_constraint_unittest.cc +++ b/cc/layers/layer_position_constraint_unittest.cc
@@ -48,10 +48,8 @@ void ExecuteCalculateDrawProperties(LayerImpl* root_layer) { std::vector<LayerImpl*> dummy_render_surface_layer_list; - root_layer->layer_tree_impl()->IncrementRenderSurfaceListIdForTesting(); LayerTreeHostCommon::CalcDrawPropsImplInputsForTesting inputs( - root_layer, root_layer->bounds(), &dummy_render_surface_layer_list, - root_layer->layer_tree_impl()->current_render_surface_list_id()); + root_layer, root_layer->bounds(), &dummy_render_surface_layer_list); inputs.inner_viewport_scroll_layer = root_layer->layer_tree_impl()->InnerViewportScrollLayer(); inputs.outer_viewport_scroll_layer =
diff --git a/cc/layers/picture_image_layer_impl_unittest.cc b/cc/layers/picture_image_layer_impl_unittest.cc index 8564d1c..35dd44b 100644 --- a/cc/layers/picture_image_layer_impl_unittest.cc +++ b/cc/layers/picture_image_layer_impl_unittest.cc
@@ -89,6 +89,7 @@ gfx::Transform scale_transform; scale_transform.Scale(ideal_contents_scale, ideal_contents_scale); layer->draw_properties().target_space_transform = scale_transform; + layer->set_is_drawn_render_surface_layer_list_member(true); DCHECK_EQ(layer->GetIdealContentsScale(), ideal_contents_scale); layer->draw_properties().maximum_animation_contents_scale = maximum_animation_contents_scale;
diff --git a/cc/layers/picture_layer_impl.cc b/cc/layers/picture_layer_impl.cc index 5f2c1dd..a96a90d 100644 --- a/cc/layers/picture_layer_impl.cc +++ b/cc/layers/picture_layer_impl.cc
@@ -1280,7 +1280,8 @@ } bool PictureLayerImpl::HasValidTilePriorities() const { - return IsOnActiveOrPendingTree() && IsDrawnRenderSurfaceLayerListMember(); + return IsOnActiveOrPendingTree() && + is_drawn_render_surface_layer_list_member(); } } // namespace cc
diff --git a/cc/layers/picture_layer_impl_unittest.cc b/cc/layers/picture_layer_impl_unittest.cc index 9fe181b..12fc720 100644 --- a/cc/layers/picture_layer_impl_unittest.cc +++ b/cc/layers/picture_layer_impl_unittest.cc
@@ -280,6 +280,7 @@ gfx::Transform scale_transform; scale_transform.Scale(ideal_contents_scale, ideal_contents_scale); layer->draw_properties().target_space_transform = scale_transform; + layer->set_is_drawn_render_surface_layer_list_member(true); DCHECK_EQ(layer->GetIdealContentsScale(), ideal_contents_scale); layer->draw_properties().maximum_animation_contents_scale = maximum_animation_contents_scale;
diff --git a/cc/layers/render_surface_unittest.cc b/cc/layers/render_surface_unittest.cc index 2c211779..da440c0b 100644 --- a/cc/layers/render_surface_unittest.cc +++ b/cc/layers/render_surface_unittest.cc
@@ -105,6 +105,8 @@ RenderSurfaceImpl* render_surface = owning_layer->render_surface(); root_layer->AddChild(std::move(owning_layer)); + host_impl.active_tree()->SetRootLayer(std::move(root_layer)); + host_impl.active_tree()->BuildPropertyTreesForTesting(); gfx::Rect content_rect(0, 0, 50, 50); gfx::Rect clip_rect(5, 5, 40, 40);
diff --git a/cc/layers/video_layer_impl_unittest.cc b/cc/layers/video_layer_impl_unittest.cc index eda59e7a..43df376d 100644 --- a/cc/layers/video_layer_impl_unittest.cc +++ b/cc/layers/video_layer_impl_unittest.cc
@@ -312,6 +312,7 @@ impl.AddChildToRoot<VideoLayerImpl>(&provider, media::VIDEO_ROTATION_0); video_layer_impl->SetBounds(layer_size); video_layer_impl->SetDrawsContent(true); + impl.host_impl()->active_tree()->BuildPropertyTreesForTesting(); gfx::Rect occluded; impl.AppendQuadsWithOcclusion(video_layer_impl, occluded); @@ -353,6 +354,7 @@ impl.AddChildToRoot<VideoLayerImpl>(&provider, media::VIDEO_ROTATION_0); video_layer_impl->SetBounds(layer_size); video_layer_impl->SetDrawsContent(true); + impl.host_impl()->active_tree()->BuildPropertyTreesForTesting(); gfx::Rect occluded; impl.AppendQuadsWithOcclusion(video_layer_impl, occluded);
diff --git a/cc/playback/image_hijack_canvas.cc b/cc/playback/image_hijack_canvas.cc index f0fc139..15c42a7 100644 --- a/cc/playback/image_hijack_canvas.cc +++ b/cc/playback/image_hijack_canvas.cc
@@ -4,9 +4,9 @@ #include "cc/playback/image_hijack_canvas.h" +#include "base/optional.h" #include "cc/playback/discardable_image_map.h" #include "cc/tiles/image_decode_controller.h" -#include "third_party/skia/include/core/SkTLazy.h" namespace cc { namespace { @@ -32,9 +32,10 @@ decoded_draw_image_( image_decode_controller_->GetDecodedImageForDraw(draw_image_)) { DCHECK(draw_image_.image()->isLazyGenerated()); - if (paint) - decoded_paint_.set(*paint)->setFilterQuality( - decoded_draw_image_.filter_quality()); + if (paint) { + decoded_paint_ = *paint; + decoded_paint_->setFilterQuality(decoded_draw_image_.filter_quality()); + } } ~ScopedDecodedImageLock() { @@ -43,14 +44,15 @@ } const DecodedDrawImage& decoded_image() const { return decoded_draw_image_; } - const SkPaint* decoded_paint() const { return decoded_paint_.getMaybeNull(); } + const SkPaint* decoded_paint() const { + return decoded_paint_ ? &decoded_paint_.value() : nullptr; + } private: ImageDecodeController* image_decode_controller_; DrawImage draw_image_; DecodedDrawImage decoded_draw_image_; - // TODO(fmalita): use base::Optional when it becomes available - SkTLazy<SkPaint> decoded_paint_; + base::Optional<SkPaint> decoded_paint_; }; } // namespace
diff --git a/cc/playback/raster_source.cc b/cc/playback/raster_source.cc index 38a83b9a3..7f80f9a 100644 --- a/cc/playback/raster_source.cc +++ b/cc/playback/raster_source.cc
@@ -18,7 +18,6 @@ #include "skia/ext/analysis_canvas.h" #include "third_party/skia/include/core/SkCanvas.h" #include "third_party/skia/include/core/SkPictureRecorder.h" -#include "third_party/skia/include/core/SkTLazy.h" #include "ui/gfx/geometry/rect_conversions.h" namespace cc {
diff --git a/cc/test/fake_picture_layer_impl.cc b/cc/test/fake_picture_layer_impl.cc index 87631cd..65297112 100644 --- a/cc/test/fake_picture_layer_impl.cc +++ b/cc/test/fake_picture_layer_impl.cc
@@ -119,12 +119,6 @@ UpdateRasterSource(raster_source, &invalidation_temp, pending_set); } -void FakePictureLayerImpl::SetIsDrawnRenderSurfaceLayerListMember(bool is) { - draw_properties().last_drawn_render_surface_layer_list_id = - is ? layer_tree_impl()->current_render_surface_list_id() - : layer_tree_impl()->current_render_surface_list_id() - 1; -} - void FakePictureLayerImpl::CreateAllTiles() { for (size_t i = 0; i < num_tilings(); ++i) tilings_->tiling_at(i)->CreateAllTilesForTesting();
diff --git a/cc/test/fake_picture_layer_impl.h b/cc/test/fake_picture_layer_impl.h index d9ae10b..3ae72a2a 100644 --- a/cc/test/fake_picture_layer_impl.h +++ b/cc/test/fake_picture_layer_impl.h
@@ -125,8 +125,6 @@ void set_fixed_tile_size(const gfx::Size& size) { fixed_tile_size_ = size; } - void SetIsDrawnRenderSurfaceLayerListMember(bool is); - void CreateAllTiles(); void SetAllTilesReady(); void SetAllTilesReadyInTiling(PictureLayerTiling* tiling);
diff --git a/cc/test/layer_test_common.cc b/cc/test/layer_test_common.cc index 23b4144..af7ffeb8 100644 --- a/cc/test/layer_test_common.cc +++ b/cc/test/layer_test_common.cc
@@ -150,10 +150,8 @@ void LayerTestCommon::LayerImplTest::CalcDrawProps( const gfx::Size& viewport_size) { LayerImplList layer_list; - host_->host_impl()->active_tree()->IncrementRenderSurfaceListIdForTesting(); LayerTreeHostCommon::CalcDrawPropsImplInputsForTesting inputs( - root_layer(), viewport_size, &layer_list, - host_->host_impl()->active_tree()->current_render_surface_list_id()); + root_layer(), viewport_size, &layer_list); LayerTreeHostCommon::CalculateDrawProperties(&inputs); }
diff --git a/cc/test/layer_tree_host_common_test.cc b/cc/test/layer_tree_host_common_test.cc index 9a4291c..6ac0c57 100644 --- a/cc/test/layer_tree_host_common_test.cc +++ b/cc/test/layer_tree_host_common_test.cc
@@ -16,9 +16,7 @@ namespace cc { LayerTreeHostCommonTestBase::LayerTreeHostCommonTestBase( const LayerTreeSettings& settings) - : LayerTestCommon::LayerImplTest(settings), - render_surface_layer_list_count_(0) { -} + : LayerTestCommon::LayerImplTest(settings) {} LayerTreeHostCommonTestBase::~LayerTreeHostCommonTestBase() { } @@ -191,10 +189,8 @@ // We are probably not testing what is intended if the root_layer bounds are // empty. DCHECK(!root_layer->bounds().IsEmpty()); - root_layer->layer_tree_impl()->IncrementRenderSurfaceListIdForTesting(); LayerTreeHostCommon::CalcDrawPropsImplInputsForTesting inputs( - root_layer, device_viewport_size, render_surface_layer_list_impl_.get(), - root_layer->layer_tree_impl()->current_render_surface_list_id()); + root_layer, device_viewport_size, render_surface_layer_list_impl_.get()); inputs.device_scale_factor = device_scale_factor; inputs.page_scale_factor = page_scale_factor; inputs.page_scale_layer = page_scale_layer; @@ -202,9 +198,6 @@ inputs.layers_always_allowed_lcd_text = layers_always_allowed_lcd_text; inputs.can_adjust_raster_scales = true; - render_surface_layer_list_count_ = - inputs.current_render_surface_layer_list_id; - LayerTreeHostCommon::CalculateDrawProperties(&inputs); } @@ -217,16 +210,11 @@ render_surface_layer_list_impl_.reset(new LayerImplList); DCHECK(!root_layer->bounds().IsEmpty()); - root_layer->layer_tree_impl()->IncrementRenderSurfaceListIdForTesting(); LayerTreeHostCommon::CalcDrawPropsImplInputsForTesting inputs( - root_layer, device_viewport_size, render_surface_layer_list_impl_.get(), - root_layer->layer_tree_impl()->current_render_surface_list_id()); + root_layer, device_viewport_size, render_surface_layer_list_impl_.get()); inputs.can_adjust_raster_scales = true; inputs.can_render_to_separate_surface = false; - render_surface_layer_list_count_ = - inputs.current_render_surface_layer_list_id; - LayerTreeHostCommon::CalculateDrawProperties(&inputs); }
diff --git a/cc/test/layer_tree_host_common_test.h b/cc/test/layer_tree_host_common_test.h index a91dc9b..45a42b8 100644 --- a/cc/test/layer_tree_host_common_test.h +++ b/cc/test/layer_tree_host_common_test.h
@@ -134,16 +134,10 @@ const LayerList& update_layer_list() const { return update_layer_list_; } bool UpdateLayerListContains(int id) const; - int render_surface_layer_list_count() const { - return render_surface_layer_list_count_; - } - private: std::unique_ptr<std::vector<LayerImpl*>> render_surface_layer_list_impl_; LayerList update_layer_list_; std::unique_ptr<LayerImplList> update_layer_list_impl_; - - int render_surface_layer_list_count_; }; class LayerTreeHostCommonTest : public LayerTreeHostCommonTestBase,
diff --git a/cc/tiles/tile_manager_unittest.cc b/cc/tiles/tile_manager_unittest.cc index c22a974..a691b44 100644 --- a/cc/tiles/tile_manager_unittest.cc +++ b/cc/tiles/tile_manager_unittest.cc
@@ -1558,6 +1558,7 @@ std::unique_ptr<PictureLayerImpl> layer_impl = PictureLayerImpl::Create(host_impl_.active_tree(), 1, false); + layer_impl->set_is_drawn_render_surface_layer_list_member(true); PictureLayerTilingSet* tiling_set = layer_impl->picture_layer_tiling_set(); PictureLayerTiling* tiling = tiling_set->AddTiling(1.0f, raster_source); @@ -1788,6 +1789,7 @@ std::unique_ptr<PictureLayerImpl> layer = PictureLayerImpl::Create(host_impl_->active_tree(), 1, false); PictureLayerTilingSet* tiling_set = layer->picture_layer_tiling_set(); + layer->set_is_drawn_render_surface_layer_list_member(true); auto* tiling = tiling_set->AddTiling(1.0f, raster); tiling->set_resolution(resolutions[i]);
diff --git a/cc/trees/damage_tracker_unittest.cc b/cc/trees/damage_tracker_unittest.cc index 56d3daf..e8747e2 100644 --- a/cc/trees/damage_tracker_unittest.cc +++ b/cc/trees/damage_tracker_unittest.cc
@@ -34,10 +34,8 @@ ASSERT_FALSE(render_surface_layer_list->size()); FakeLayerTreeHostImpl::RecursiveUpdateNumChildren(root); - root->layer_tree_impl()->IncrementRenderSurfaceListIdForTesting(); LayerTreeHostCommon::CalcDrawPropsImplInputsForTesting inputs( - root, root->bounds(), render_surface_layer_list, - root->layer_tree_impl()->current_render_surface_list_id()); + root, root->bounds(), render_surface_layer_list); LayerTreeHostCommon::CalculateDrawProperties(&inputs); ASSERT_TRUE(root->render_surface()); }
diff --git a/cc/trees/layer_tree_host_common.cc b/cc/trees/layer_tree_host_common.cc index eb7c3dd..aef8d33 100644 --- a/cc/trees/layer_tree_host_common.cc +++ b/cc/trees/layer_tree_host_common.cc
@@ -83,7 +83,6 @@ bool can_render_to_separate_surface, bool can_adjust_raster_scales, LayerImplList* render_surface_layer_list, - int current_render_surface_layer_list_id, PropertyTrees* property_trees) : root_layer(root_layer), device_viewport_size(device_viewport_size), @@ -102,16 +101,13 @@ can_render_to_separate_surface(can_render_to_separate_surface), can_adjust_raster_scales(can_adjust_raster_scales), render_surface_layer_list(render_surface_layer_list), - current_render_surface_layer_list_id( - current_render_surface_layer_list_id), property_trees(property_trees) {} LayerTreeHostCommon::CalcDrawPropsImplInputsForTesting:: CalcDrawPropsImplInputsForTesting(LayerImpl* root_layer, const gfx::Size& device_viewport_size, const gfx::Transform& device_transform, - LayerImplList* render_surface_layer_list, - int current_render_surface_layer_list_id) + LayerImplList* render_surface_layer_list) : CalcDrawPropsImplInputs(root_layer, device_viewport_size, device_transform, @@ -128,7 +124,6 @@ true, false, render_surface_layer_list, - current_render_surface_layer_list_id, GetPropertyTrees(root_layer)) { DCHECK(root_layer); DCHECK(render_surface_layer_list); @@ -137,13 +132,11 @@ LayerTreeHostCommon::CalcDrawPropsImplInputsForTesting:: CalcDrawPropsImplInputsForTesting(LayerImpl* root_layer, const gfx::Size& device_viewport_size, - LayerImplList* render_surface_layer_list, - int current_render_surface_layer_list_id) + LayerImplList* render_surface_layer_list) : CalcDrawPropsImplInputsForTesting(root_layer, device_viewport_size, gfx::Transform(), - render_surface_layer_list, - current_render_surface_layer_list_id) {} + render_surface_layer_list) {} bool LayerTreeHostCommon::ScrollUpdateInfo::operator==( const LayerTreeHostCommon::ScrollUpdateInfo& other) const { @@ -209,41 +202,41 @@ layer->HasPotentiallyRunningTransformAnimation(); } -static inline void MarkLayerWithRenderSurfaceLayerListId( - LayerImpl* layer, - int current_render_surface_layer_list_id) { - layer->draw_properties().last_drawn_render_surface_layer_list_id = - current_render_surface_layer_list_id; -} - -static inline void MarkMasksWithRenderSurfaceLayerListId( - LayerImpl* layer, - int current_render_surface_layer_list_id) { - if (layer->mask_layer()) { - MarkLayerWithRenderSurfaceLayerListId(layer->mask_layer(), - current_render_surface_layer_list_id); - } +static inline void SetMaskLayersAreDrawnRenderSurfaceLayerListMembers( + LayerImpl* layer) { + if (layer->mask_layer()) + layer->mask_layer()->set_is_drawn_render_surface_layer_list_member(true); if (layer->replica_layer() && layer->replica_layer()->mask_layer()) { - MarkLayerWithRenderSurfaceLayerListId(layer->replica_layer()->mask_layer(), - current_render_surface_layer_list_id); + layer->replica_layer() + ->mask_layer() + ->set_is_drawn_render_surface_layer_list_member(true); } } -static inline void ClearRenderSurfaceLayerListId(LayerImplList* layer_list, - ScrollTree* scroll_tree) { - const int cleared_render_surface_layer_list_id = 0; +static inline void ClearLayerIsDrawnRenderSurfaceLayerListMember( + LayerImpl* layer) { + layer->set_is_drawn_render_surface_layer_list_member(false); + if (layer->mask_layer()) + layer->mask_layer()->set_is_drawn_render_surface_layer_list_member(false); + if (layer->replica_layer() && layer->replica_layer()->mask_layer()) { + layer->replica_layer() + ->mask_layer() + ->set_is_drawn_render_surface_layer_list_member(false); + } +} + +static inline void ClearIsDrawnRenderSurfaceLayerListMember( + LayerImplList* layer_list, + ScrollTree* scroll_tree) { for (LayerImpl* layer : *layer_list) { - if (layer->IsDrawnRenderSurfaceLayerListMember()) { + if (layer->is_drawn_render_surface_layer_list_member()) { DCHECK_GT(scroll_tree->Node(layer->scroll_tree_index()) ->data.num_drawn_descendants, 0); scroll_tree->Node(layer->scroll_tree_index()) ->data.num_drawn_descendants--; } - MarkLayerWithRenderSurfaceLayerListId(layer, - cleared_render_surface_layer_list_id); - MarkMasksWithRenderSurfaceLayerListId(layer, - cleared_render_surface_layer_list_id); + ClearLayerIsDrawnRenderSurfaceLayerListMember(layer); } } @@ -478,8 +471,7 @@ LayerTreeImpl* layer_tree_impl, PropertyTrees* property_trees, LayerImplList* render_surface_layer_list, - bool can_render_to_separate_surface, - int current_render_surface_layer_list_id) { + bool can_render_to_separate_surface) { ScrollTree* scroll_tree = &property_trees->scroll_tree; for (int i = 0; i < static_cast<int>(scroll_tree->size()); ++i) scroll_tree->Node(i)->data.num_drawn_descendants = 0; @@ -490,6 +482,7 @@ for (LayerImpl* layer : *layer_tree_impl) { if (layer->render_surface()) layer->ClearRenderSurfaceLayerList(); + ClearLayerIsDrawnRenderSurfaceLayerListMember(layer); bool layer_is_drawn = property_trees->effect_tree.Node(layer->effect_tree_index()) @@ -552,8 +545,7 @@ if (!layer_should_be_drawn) continue; - MarkLayerWithRenderSurfaceLayerListId(layer, - current_render_surface_layer_list_id); + layer->set_is_drawn_render_surface_layer_list_member(true); scroll_tree->Node(layer->scroll_tree_index())->data.num_drawn_descendants++; layer->render_target()->layer_list().push_back(layer); @@ -586,12 +578,10 @@ } } -static void ComputeListOfNonEmptySurfaces( - LayerTreeImpl* layer_tree_impl, - PropertyTrees* property_trees, - LayerImplList* initial_surface_list, - LayerImplList* final_surface_list, - int current_render_surface_layer_list_id) { +static void ComputeListOfNonEmptySurfaces(LayerTreeImpl* layer_tree_impl, + PropertyTrees* property_trees, + LayerImplList* initial_surface_list, + LayerImplList* final_surface_list) { // Walk the initial surface list forwards. The root surface and each // surface with a non-empty content rect go into the final render surface // layer list. Surfaces with empty content rects or whose target isn't in @@ -602,8 +592,8 @@ RenderSurfaceImpl* target_surface = surface->render_target(); if (!is_root && (surface->content_rect().IsEmpty() || target_surface->layer_list().empty())) { - ClearRenderSurfaceLayerListId(&surface->layer_list(), - &property_trees->scroll_tree); + ClearIsDrawnRenderSurfaceLayerListMember(&surface->layer_list(), + &property_trees->scroll_tree); surface->ClearLayerLists(); if (!is_root) { LayerImplList& target_list = target_surface->layer_list(); @@ -624,8 +614,7 @@ } continue; } - MarkMasksWithRenderSurfaceLayerListId(layer, - current_render_surface_layer_list_id); + SetMaskLayersAreDrawnRenderSurfaceLayerListMembers(layer); final_surface_list->push_back(layer); } } @@ -635,7 +624,6 @@ PropertyTrees* property_trees, LayerImplList* render_surface_layer_list, const bool can_render_to_separate_surface, - const int current_render_surface_layer_list_id, const int max_texture_size) { // This calculates top level Render Surface Layer List, and Layer List for all // Render Surfaces. @@ -646,14 +634,14 @@ // First compute an RSLL that might include surfaces that later turn out to // have an empty content rect. After surface content rects are computed, // produce a final RSLL that omits empty surfaces. - ComputeInitialRenderSurfaceLayerList( - layer_tree_impl, property_trees, &initial_render_surface_list, - can_render_to_separate_surface, current_render_surface_layer_list_id); + ComputeInitialRenderSurfaceLayerList(layer_tree_impl, property_trees, + &initial_render_surface_list, + can_render_to_separate_surface); ComputeSurfaceContentRects(layer_tree_impl, property_trees, &initial_render_surface_list, max_texture_size); - ComputeListOfNonEmptySurfaces( - layer_tree_impl, property_trees, &initial_render_surface_list, - render_surface_layer_list, current_render_surface_layer_list_id); + ComputeListOfNonEmptySurfaces(layer_tree_impl, property_trees, + &initial_render_surface_list, + render_surface_layer_list); ComputeLayerScrollsDrawnDescendants(layer_tree_impl, &property_trees->scroll_tree); @@ -767,13 +755,10 @@ ComputeMaskLayerDrawProperties(layer, replica_mask_layer); } - DCHECK_EQ( - inputs->current_render_surface_layer_list_id, - inputs->root_layer->layer_tree_impl()->current_render_surface_list_id()); CalculateRenderSurfaceLayerList( inputs->root_layer->layer_tree_impl(), inputs->property_trees, inputs->render_surface_layer_list, inputs->can_render_to_separate_surface, - inputs->current_render_surface_layer_list_id, inputs->max_texture_size); + inputs->max_texture_size); if (should_measure_property_tree_performance) { TRACE_EVENT_END0(TRACE_DISABLED_BY_DEFAULT("cc.debug.cdp-perf"),
diff --git a/cc/trees/layer_tree_host_common.h b/cc/trees/layer_tree_host_common.h index 5f2d720b..10c0a1a 100644 --- a/cc/trees/layer_tree_host_common.h +++ b/cc/trees/layer_tree_host_common.h
@@ -82,7 +82,6 @@ bool can_render_to_separate_surface, bool can_adjust_raster_scales, LayerImplList* render_surface_layer_list, - int current_render_surface_layer_list_id, PropertyTrees* property_trees); LayerImpl* root_layer; @@ -101,7 +100,6 @@ bool can_render_to_separate_surface; bool can_adjust_raster_scales; LayerImplList* render_surface_layer_list; - int current_render_surface_layer_list_id; PropertyTrees* property_trees; }; @@ -110,12 +108,10 @@ CalcDrawPropsImplInputsForTesting(LayerImpl* root_layer, const gfx::Size& device_viewport_size, const gfx::Transform& device_transform, - LayerImplList* render_surface_layer_list, - int current_render_surface_layer_list_id); + LayerImplList* render_surface_layer_list); CalcDrawPropsImplInputsForTesting(LayerImpl* root_layer, const gfx::Size& device_viewport_size, - LayerImplList* render_surface_layer_list, - int current_render_surface_layer_list_id); + LayerImplList* render_surface_layer_list); }; static int CalculateLayerJitter(LayerImpl* scrolling_layer);
diff --git a/cc/trees/layer_tree_host_common_perftest.cc b/cc/trees/layer_tree_host_common_perftest.cc index 260e5743..30b0cbc 100644 --- a/cc/trees/layer_tree_host_common_perftest.cc +++ b/cc/trees/layer_tree_host_common_perftest.cc
@@ -107,7 +107,6 @@ LayerTreeImpl* active_tree, LayerTreeHostImpl* host_impl) { LayerImplList update_list; - active_tree->IncrementRenderSurfaceListIdForTesting(); LayerTreeHostCommon::CalcDrawPropsImplInputs inputs( active_tree->root_layer(), active_tree->DrawViewportSize(), host_impl->DrawTransform(), active_tree->device_scale_factor(), @@ -121,8 +120,7 @@ host_impl->settings().layers_always_allowed_lcd_text, can_render_to_separate_surface, host_impl->settings().layer_transforms_should_scale_layer_contents, - &update_list, active_tree->current_render_surface_list_id(), - active_tree->property_trees()); + &update_list, active_tree->property_trees()); LayerTreeHostCommon::CalculateDrawProperties(&inputs); } };
diff --git a/cc/trees/layer_tree_host_common_unittest.cc b/cc/trees/layer_tree_host_common_unittest.cc index 660a7ffc..99dca32 100644 --- a/cc/trees/layer_tree_host_common_unittest.cc +++ b/cc/trees/layer_tree_host_common_unittest.cc
@@ -1108,10 +1108,8 @@ // render_surface will have a sublayer scale because of device scale factor. float device_scale_factor = 2.0f; LayerImplList render_surface_layer_list_impl; - root->layer_tree_impl()->IncrementRenderSurfaceListIdForTesting(); LayerTreeHostCommon::CalcDrawPropsImplInputsForTesting inputs( - root, root->bounds(), translate, &render_surface_layer_list_impl, - root->layer_tree_impl()->current_render_surface_list_id()); + root, root->bounds(), translate, &render_surface_layer_list_impl); inputs.device_scale_factor = device_scale_factor; inputs.property_trees->needs_rebuild = true; LayerTreeHostCommon::CalculateDrawProperties(&inputs); @@ -1145,10 +1143,8 @@ translate.Translate(50, 50); { LayerImplList render_surface_layer_list_impl; - root->layer_tree_impl()->IncrementRenderSurfaceListIdForTesting(); LayerTreeHostCommon::CalcDrawPropsImplInputsForTesting inputs( - root, root->bounds(), translate, &render_surface_layer_list_impl, - root->layer_tree_impl()->current_render_surface_list_id()); + root, root->bounds(), translate, &render_surface_layer_list_impl); inputs.property_trees->needs_rebuild = true; LayerTreeHostCommon::CalculateDrawProperties(&inputs); EXPECT_EQ(translate, root->draw_properties().target_space_transform); @@ -1160,10 +1156,8 @@ scale.Scale(2, 2); { LayerImplList render_surface_layer_list_impl; - root->layer_tree_impl()->IncrementRenderSurfaceListIdForTesting(); LayerTreeHostCommon::CalcDrawPropsImplInputsForTesting inputs( - root, root->bounds(), scale, &render_surface_layer_list_impl, - root->layer_tree_impl()->current_render_surface_list_id()); + root, root->bounds(), scale, &render_surface_layer_list_impl); inputs.property_trees->needs_rebuild = true; LayerTreeHostCommon::CalculateDrawProperties(&inputs); EXPECT_EQ(scale, root->draw_properties().target_space_transform); @@ -1175,10 +1169,8 @@ rotate.Rotate(2); { LayerImplList render_surface_layer_list_impl; - root->layer_tree_impl()->IncrementRenderSurfaceListIdForTesting(); LayerTreeHostCommon::CalcDrawPropsImplInputsForTesting inputs( - root, root->bounds(), rotate, &render_surface_layer_list_impl, - root->layer_tree_impl()->current_render_surface_list_id()); + root, root->bounds(), rotate, &render_surface_layer_list_impl); inputs.property_trees->needs_rebuild = true; LayerTreeHostCommon::CalculateDrawProperties(&inputs); EXPECT_EQ(rotate, root->draw_properties().target_space_transform); @@ -1192,10 +1184,8 @@ composite.ConcatTransform(rotate); { LayerImplList render_surface_layer_list_impl; - root->layer_tree_impl()->IncrementRenderSurfaceListIdForTesting(); LayerTreeHostCommon::CalcDrawPropsImplInputsForTesting inputs( - root, root->bounds(), composite, &render_surface_layer_list_impl, - root->layer_tree_impl()->current_render_surface_list_id()); + root, root->bounds(), composite, &render_surface_layer_list_impl); inputs.property_trees->needs_rebuild = true; LayerTreeHostCommon::CalculateDrawProperties(&inputs); EXPECT_EQ(composite, root->draw_properties().target_space_transform); @@ -1208,10 +1198,8 @@ { LayerImplList render_surface_layer_list_impl; - root->layer_tree_impl()->IncrementRenderSurfaceListIdForTesting(); LayerTreeHostCommon::CalcDrawPropsImplInputsForTesting inputs( - root, root->bounds(), translate, &render_surface_layer_list_impl, - root->layer_tree_impl()->current_render_surface_list_id()); + root, root->bounds(), translate, &render_surface_layer_list_impl); inputs.device_scale_factor = device_scale_factor; inputs.property_trees->needs_rebuild = true; LayerTreeHostCommon::CalculateDrawProperties(&inputs); @@ -1229,10 +1217,8 @@ { LayerImplList render_surface_layer_list_impl; - root->layer_tree_impl()->IncrementRenderSurfaceListIdForTesting(); LayerTreeHostCommon::CalcDrawPropsImplInputsForTesting inputs( - root, root->bounds(), translate, &render_surface_layer_list_impl, - root->layer_tree_impl()->current_render_surface_list_id()); + root, root->bounds(), translate, &render_surface_layer_list_impl); inputs.page_scale_factor = page_scale_factor; inputs.page_scale_layer = root; inputs.property_trees->needs_rebuild = true; @@ -1251,10 +1237,8 @@ { LayerImplList render_surface_layer_list_impl; - root->layer_tree_impl()->IncrementRenderSurfaceListIdForTesting(); LayerTreeHostCommon::CalcDrawPropsImplInputsForTesting inputs( - root, root->bounds(), composite, &render_surface_layer_list_impl, - root->layer_tree_impl()->current_render_surface_list_id()); + root, root->bounds(), composite, &render_surface_layer_list_impl); inputs.property_trees->needs_rebuild = true; LayerTreeHostCommon::CalculateDrawProperties(&inputs); gfx::Transform compositeSquared = composite; @@ -1313,10 +1297,8 @@ render_surface1->SetOpacity(0.f); LayerImplList render_surface_layer_list; - parent->layer_tree_impl()->IncrementRenderSurfaceListIdForTesting(); LayerTreeHostCommon::CalcDrawPropsImplInputsForTesting inputs( - parent, parent->bounds(), &render_surface_layer_list, - parent->layer_tree_impl()->current_render_surface_list_id()); + parent, parent->bounds(), &render_surface_layer_list); inputs.can_adjust_raster_scales = true; LayerTreeHostCommon::CalculateDrawProperties(&inputs); @@ -1356,10 +1338,8 @@ { LayerImplList render_surface_layer_list; - parent->layer_tree_impl()->IncrementRenderSurfaceListIdForTesting(); LayerTreeHostCommon::CalcDrawPropsImplInputsForTesting inputs( - parent, parent->bounds(), &render_surface_layer_list, - parent->layer_tree_impl()->current_render_surface_list_id()); + parent, parent->bounds(), &render_surface_layer_list); inputs.can_adjust_raster_scales = true; LayerTreeHostCommon::CalculateDrawProperties(&inputs); EXPECT_EQ(2U, render_surface_layer_list.size()); @@ -1381,10 +1361,8 @@ render_surface1->set_visible_layer_rect(gfx::Rect()); { LayerImplList render_surface_layer_list; - parent->layer_tree_impl()->IncrementRenderSurfaceListIdForTesting(); LayerTreeHostCommon::CalcDrawPropsImplInputsForTesting inputs( - parent, parent->bounds(), &render_surface_layer_list, - parent->layer_tree_impl()->current_render_surface_list_id()); + parent, parent->bounds(), &render_surface_layer_list); inputs.can_adjust_raster_scales = true; LayerTreeHostCommon::CalculateDrawProperties(&inputs); } @@ -1421,10 +1399,8 @@ parent->SetFilters(filters); LayerImplList render_surface_layer_list; - parent->layer_tree_impl()->IncrementRenderSurfaceListIdForTesting(); LayerTreeHostCommon::CalcDrawPropsImplInputsForTesting inputs( - root, root->bounds(), &render_surface_layer_list, - root->layer_tree_impl()->current_render_surface_list_id()); + root, root->bounds(), &render_surface_layer_list); inputs.can_adjust_raster_scales = true; LayerTreeHostCommon::CalculateDrawProperties(&inputs); @@ -3458,11 +3434,9 @@ true, false, false); LayerImplList render_surface_layer_list_impl; - root->layer_tree_impl()->IncrementRenderSurfaceListIdForTesting(); // Now set the root render surface an empty clip. LayerTreeHostCommon::CalcDrawPropsImplInputsForTesting inputs( - root, gfx::Size(), &render_surface_layer_list_impl, - root->layer_tree_impl()->current_render_surface_list_id()); + root, gfx::Size(), &render_surface_layer_list_impl); LayerTreeHostCommon::CalculateDrawProperties(&inputs); ASSERT_TRUE(root->render_surface()); @@ -5224,10 +5198,8 @@ host_impl.pending_tree()->SetRootLayer(std::move(root)); LayerImplList render_surface_layer_list; - root_layer->layer_tree_impl()->IncrementRenderSurfaceListIdForTesting(); LayerTreeHostCommon::CalcDrawPropsImplInputsForTesting inputs( - root_layer, root_layer->bounds(), &render_surface_layer_list, - root_layer->layer_tree_impl()->current_render_surface_list_id()); + root_layer, root_layer->bounds(), &render_surface_layer_list); inputs.can_adjust_raster_scales = true; LayerTreeHostCommon::CalculateDrawProperties(&inputs); @@ -5241,10 +5213,8 @@ root_layer->SetOpacity(0.0f); root_layer->layer_tree_impl()->property_trees()->needs_rebuild = true; LayerImplList render_surface_layer_list2; - root_layer->layer_tree_impl()->IncrementRenderSurfaceListIdForTesting(); LayerTreeHostCommon::CalcDrawPropsImplInputsForTesting inputs2( - root_layer, root_layer->bounds(), &render_surface_layer_list2, - root_layer->layer_tree_impl()->current_render_surface_list_id()); + root_layer, root_layer->bounds(), &render_surface_layer_list2); inputs2.can_adjust_raster_scales = true; LayerTreeHostCommon::CalculateDrawProperties(&inputs2); @@ -5260,10 +5230,8 @@ child_ptr->SetOpacity(0.0f); root_layer->layer_tree_impl()->property_trees()->needs_rebuild = true; LayerImplList render_surface_layer_list3; - root_layer->layer_tree_impl()->IncrementRenderSurfaceListIdForTesting(); LayerTreeHostCommon::CalcDrawPropsImplInputsForTesting inputs3( - root_layer, root_layer->bounds(), &render_surface_layer_list3, - root_layer->layer_tree_impl()->current_render_surface_list_id()); + root_layer, root_layer->bounds(), &render_surface_layer_list3); inputs3.can_adjust_raster_scales = true; LayerTreeHostCommon::CalculateDrawProperties(&inputs3); @@ -5560,10 +5528,8 @@ host_impl.pending_tree()->SetRootLayer(std::move(root)); LayerImplList render_surface_layer_list; - root_layer->layer_tree_impl()->IncrementRenderSurfaceListIdForTesting(); LayerTreeHostCommon::CalcDrawPropsImplInputsForTesting inputs( - root_layer, root_layer->bounds(), &render_surface_layer_list, - root_layer->layer_tree_impl()->current_render_surface_list_id()); + root_layer, root_layer->bounds(), &render_surface_layer_list); inputs.can_adjust_raster_scales = true; LayerTreeHostCommon::CalculateDrawProperties(&inputs); @@ -5612,10 +5578,8 @@ host_impl.pending_tree()->SetRootLayer(std::move(root)); LayerImplList render_surface_layer_list; - root_layer->layer_tree_impl()->IncrementRenderSurfaceListIdForTesting(); LayerTreeHostCommon::CalcDrawPropsImplInputsForTesting inputs( - root_layer, root_layer->bounds(), &render_surface_layer_list, - root_layer->layer_tree_impl()->current_render_surface_list_id()); + root_layer, root_layer->bounds(), &render_surface_layer_list); inputs.can_adjust_raster_scales = true; LayerTreeHostCommon::CalculateDrawProperties(&inputs); @@ -5727,10 +5691,8 @@ EXPECT_TRUE(copy_layer->HasCopyRequest()); LayerImplList render_surface_layer_list; - root_layer->layer_tree_impl()->IncrementRenderSurfaceListIdForTesting(); LayerTreeHostCommon::CalcDrawPropsImplInputsForTesting inputs( - root_layer, root_layer->bounds(), &render_surface_layer_list, - root_layer->layer_tree_impl()->current_render_surface_list_id()); + root_layer, root_layer->bounds(), &render_surface_layer_list); inputs.can_adjust_raster_scales = true; LayerTreeHostCommon::CalculateDrawProperties(&inputs); @@ -5840,12 +5802,10 @@ root->AddChild(std::move(copy_parent)); LayerImplList render_surface_layer_list; - root->layer_tree_impl()->IncrementRenderSurfaceListIdForTesting(); LayerImpl* root_layer = root.get(); root_layer->layer_tree_impl()->SetRootLayer(std::move(root)); LayerTreeHostCommon::CalcDrawPropsImplInputsForTesting inputs( - root_layer, root_layer->bounds(), &render_surface_layer_list, - root_layer->layer_tree_impl()->current_render_surface_list_id()); + root_layer, root_layer->bounds(), &render_surface_layer_list); inputs.can_adjust_raster_scales = true; LayerTreeHostCommon::CalculateDrawProperties(&inputs); @@ -6366,10 +6326,8 @@ { LayerImplList render_surface_layer_list; FakeLayerTreeHostImpl::RecursiveUpdateNumChildren(root_layer); - root_layer->layer_tree_impl()->IncrementRenderSurfaceListIdForTesting(); LayerTreeHostCommon::CalcDrawPropsImplInputsForTesting inputs( - root_layer, root_layer->bounds(), &render_surface_layer_list, - root_layer->layer_tree_impl()->current_render_surface_list_id()); + root_layer, root_layer->bounds(), &render_surface_layer_list); inputs.can_render_to_separate_surface = true; LayerTreeHostCommon::CalculateDrawProperties(&inputs); @@ -6399,10 +6357,8 @@ { LayerImplList render_surface_layer_list; - root_layer->layer_tree_impl()->IncrementRenderSurfaceListIdForTesting(); LayerTreeHostCommon::CalcDrawPropsImplInputsForTesting inputs( - root_layer, root_layer->bounds(), &render_surface_layer_list, - root_layer->layer_tree_impl()->current_render_surface_list_id()); + root_layer, root_layer->bounds(), &render_surface_layer_list); inputs.can_render_to_separate_surface = false; LayerTreeHostCommon::CalculateDrawProperties(&inputs); @@ -6690,10 +6646,9 @@ float device_scale_factor = 1.5f; LayerImplList render_surface_layer_list_impl; - root->layer_tree_impl()->IncrementRenderSurfaceListIdForTesting(); LayerTreeHostCommon::CalcDrawPropsImplInputsForTesting inputs( - root, root->bounds(), identity_transform, &render_surface_layer_list_impl, - root->layer_tree_impl()->current_render_surface_list_id()); + root, root->bounds(), identity_transform, + &render_surface_layer_list_impl); inputs.device_scale_factor = device_scale_factor; LayerTreeHostCommon::CalculateDrawProperties(&inputs); @@ -7125,10 +7080,8 @@ SetScrollOffsetDelta(scroll_layer, scroll_delta); LayerImplList render_surface_layer_list; - root->layer_tree_impl()->IncrementRenderSurfaceListIdForTesting(); LayerTreeHostCommon::CalcDrawPropsImplInputsForTesting inputs( - root, root->bounds(), &render_surface_layer_list, - root->layer_tree_impl()->current_render_surface_list_id()); + root, root->bounds(), &render_surface_layer_list); root->layer_tree_impl() ->property_trees() ->transform_tree.set_source_to_parent_updates_allowed(false); @@ -7155,10 +7108,8 @@ gfx::Vector2dF rounded_scroll_delta(4.f, 8.f); LayerImplList render_surface_layer_list; - root->layer_tree_impl()->IncrementRenderSurfaceListIdForTesting(); LayerTreeHostCommon::CalcDrawPropsImplInputsForTesting inputs( - root, root->bounds(), &render_surface_layer_list, - root->layer_tree_impl()->current_render_surface_list_id()); + root, root->bounds(), &render_surface_layer_list); LayerTreeHostCommon::CalculateDrawProperties(&inputs); EXPECT_TRANSFORMATION_MATRIX_EQ( @@ -7185,10 +7136,8 @@ SetScrollOffsetDelta(scroll_layer, scroll_delta); LayerImplList render_surface_layer_list; - root->layer_tree_impl()->IncrementRenderSurfaceListIdForTesting(); LayerTreeHostCommon::CalcDrawPropsImplInputsForTesting inputs( - root, root->bounds(), &render_surface_layer_list, - root->layer_tree_impl()->current_render_surface_list_id()); + root, root->bounds(), &render_surface_layer_list); LayerTreeHostCommon::CalculateDrawProperties(&inputs); EXPECT_TRANSFORMATION_MATRIX_EQ( @@ -7612,10 +7561,6 @@ grand_child_raw->draw_properties().starting_animation_contents_scale); } -static int membership_id(LayerImpl* layer) { - return layer->draw_properties().last_drawn_render_surface_layer_list_id; -} - static void GatherDrawnLayers(LayerImplList* rsll, std::set<LayerImpl*>* drawn_layers) { for (LayerIterator it = LayerIterator::Begin(rsll), @@ -7687,13 +7632,12 @@ // Start with nothing being drawn. ExecuteCalculateDrawProperties(grand_parent_raw); - int member_id = render_surface_layer_list_count(); - EXPECT_NE(member_id, membership_id(grand_parent_raw)); - EXPECT_NE(member_id, membership_id(parent_raw)); - EXPECT_NE(member_id, membership_id(child_raw)); - EXPECT_NE(member_id, membership_id(grand_child1_raw)); - EXPECT_NE(member_id, membership_id(grand_child2_raw)); + EXPECT_FALSE(grand_parent_raw->is_drawn_render_surface_layer_list_member()); + EXPECT_FALSE(parent_raw->is_drawn_render_surface_layer_list_member()); + EXPECT_FALSE(child_raw->is_drawn_render_surface_layer_list_member()); + EXPECT_FALSE(grand_child1_raw->is_drawn_render_surface_layer_list_member()); + EXPECT_FALSE(grand_child2_raw->is_drawn_render_surface_layer_list_member()); std::set<LayerImpl*> expected; std::set<LayerImpl*> actual; @@ -7706,13 +7650,12 @@ grand_child1_raw->layer_tree_impl()->property_trees()->needs_rebuild = true; ExecuteCalculateDrawProperties(grand_parent_raw); - member_id = render_surface_layer_list_count(); - EXPECT_NE(member_id, membership_id(grand_parent_raw)); - EXPECT_NE(member_id, membership_id(parent_raw)); - EXPECT_NE(member_id, membership_id(child_raw)); - EXPECT_NE(member_id, membership_id(grand_child1_raw)); - EXPECT_NE(member_id, membership_id(grand_child2_raw)); + EXPECT_FALSE(grand_parent_raw->is_drawn_render_surface_layer_list_member()); + EXPECT_FALSE(parent_raw->is_drawn_render_surface_layer_list_member()); + EXPECT_FALSE(child_raw->is_drawn_render_surface_layer_list_member()); + EXPECT_FALSE(grand_child1_raw->is_drawn_render_surface_layer_list_member()); + EXPECT_FALSE(grand_child2_raw->is_drawn_render_surface_layer_list_member()); expected.clear(); actual.clear(); @@ -7724,13 +7667,12 @@ grand_child1_raw->SetDrawsContent(true); ExecuteCalculateDrawProperties(grand_parent_raw); - member_id = render_surface_layer_list_count(); - EXPECT_NE(member_id, membership_id(grand_parent_raw)); - EXPECT_NE(member_id, membership_id(parent_raw)); - EXPECT_NE(member_id, membership_id(child_raw)); - EXPECT_EQ(member_id, membership_id(grand_child1_raw)); - EXPECT_NE(member_id, membership_id(grand_child2_raw)); + EXPECT_FALSE(grand_parent_raw->is_drawn_render_surface_layer_list_member()); + EXPECT_FALSE(parent_raw->is_drawn_render_surface_layer_list_member()); + EXPECT_FALSE(child_raw->is_drawn_render_surface_layer_list_member()); + EXPECT_TRUE(grand_child1_raw->is_drawn_render_surface_layer_list_member()); + EXPECT_FALSE(grand_child2_raw->is_drawn_render_surface_layer_list_member()); expected.clear(); expected.insert(grand_child1_raw); @@ -7748,13 +7690,12 @@ grand_child2_raw->SetDrawsContent(true); ExecuteCalculateDrawProperties(grand_parent_raw); - member_id = render_surface_layer_list_count(); - EXPECT_NE(member_id, membership_id(grand_parent_raw)); - EXPECT_NE(member_id, membership_id(parent_raw)); - EXPECT_NE(member_id, membership_id(child_raw)); - EXPECT_NE(member_id, membership_id(grand_child1_raw)); - EXPECT_EQ(member_id, membership_id(grand_child2_raw)); + EXPECT_FALSE(grand_parent_raw->is_drawn_render_surface_layer_list_member()); + EXPECT_FALSE(parent_raw->is_drawn_render_surface_layer_list_member()); + EXPECT_FALSE(child_raw->is_drawn_render_surface_layer_list_member()); + EXPECT_FALSE(grand_child1_raw->is_drawn_render_surface_layer_list_member()); + EXPECT_TRUE(grand_child2_raw->is_drawn_render_surface_layer_list_member()); expected.clear(); expected.insert(grand_child2_raw); @@ -7768,14 +7709,14 @@ child_raw->layer_tree_impl()->property_trees()->needs_rebuild = true; ExecuteCalculateDrawProperties(grand_parent_raw); - member_id = render_surface_layer_list_count(); - EXPECT_NE(member_id, membership_id(grand_parent_raw)); - EXPECT_NE(member_id, membership_id(parent_raw)); - EXPECT_NE(member_id, membership_id(child_raw)); - EXPECT_EQ(member_id, membership_id(child_raw->mask_layer())); - EXPECT_NE(member_id, membership_id(grand_child1_raw)); - EXPECT_EQ(member_id, membership_id(grand_child2_raw)); + EXPECT_FALSE(grand_parent_raw->is_drawn_render_surface_layer_list_member()); + EXPECT_FALSE(parent_raw->is_drawn_render_surface_layer_list_member()); + EXPECT_FALSE(child_raw->is_drawn_render_surface_layer_list_member()); + EXPECT_TRUE( + child_raw->mask_layer()->is_drawn_render_surface_layer_list_member()); + EXPECT_FALSE(grand_child1_raw->is_drawn_render_surface_layer_list_member()); + EXPECT_TRUE(grand_child2_raw->is_drawn_render_surface_layer_list_member()); expected.clear(); expected.insert(grand_child2_raw); @@ -7797,15 +7738,17 @@ child_raw->layer_tree_impl()->property_trees()->needs_rebuild = true; ExecuteCalculateDrawProperties(grand_parent_raw); - member_id = render_surface_layer_list_count(); - EXPECT_NE(member_id, membership_id(grand_parent_raw)); - EXPECT_NE(member_id, membership_id(parent_raw)); - EXPECT_NE(member_id, membership_id(child_raw)); - EXPECT_EQ(member_id, membership_id(child_raw->mask_layer())); - EXPECT_EQ(member_id, membership_id(child_raw->replica_layer()->mask_layer())); - EXPECT_NE(member_id, membership_id(grand_child1_raw)); - EXPECT_EQ(member_id, membership_id(grand_child2_raw)); + EXPECT_FALSE(grand_parent_raw->is_drawn_render_surface_layer_list_member()); + EXPECT_FALSE(parent_raw->is_drawn_render_surface_layer_list_member()); + EXPECT_FALSE(child_raw->is_drawn_render_surface_layer_list_member()); + EXPECT_TRUE( + child_raw->mask_layer()->is_drawn_render_surface_layer_list_member()); + EXPECT_TRUE(child_raw->replica_layer() + ->mask_layer() + ->is_drawn_render_surface_layer_list_member()); + EXPECT_FALSE(grand_child1_raw->is_drawn_render_surface_layer_list_member()); + EXPECT_TRUE(grand_child2_raw->is_drawn_render_surface_layer_list_member()); expected.clear(); expected.insert(grand_child2_raw); @@ -7822,14 +7765,14 @@ grand_child2_raw->SetDrawsContent(false); ExecuteCalculateDrawProperties(grand_parent_raw); - member_id = render_surface_layer_list_count(); - EXPECT_NE(member_id, membership_id(grand_parent_raw)); - EXPECT_NE(member_id, membership_id(parent_raw)); - EXPECT_NE(member_id, membership_id(child_raw)); - EXPECT_NE(member_id, membership_id(child_raw->mask_layer())); - EXPECT_NE(member_id, membership_id(grand_child1_raw)); - EXPECT_NE(member_id, membership_id(grand_child2_raw)); + EXPECT_FALSE(grand_parent_raw->is_drawn_render_surface_layer_list_member()); + EXPECT_FALSE(parent_raw->is_drawn_render_surface_layer_list_member()); + EXPECT_FALSE(child_raw->is_drawn_render_surface_layer_list_member()); + EXPECT_FALSE( + child_raw->mask_layer()->is_drawn_render_surface_layer_list_member()); + EXPECT_FALSE(grand_child1_raw->is_drawn_render_surface_layer_list_member()); + EXPECT_FALSE(grand_child2_raw->is_drawn_render_surface_layer_list_member()); expected.clear(); actual.clear(); @@ -7841,14 +7784,14 @@ child_raw->SetDrawsContent(true); ExecuteCalculateDrawProperties(grand_parent_raw); - member_id = render_surface_layer_list_count(); - EXPECT_NE(member_id, membership_id(grand_parent_raw)); - EXPECT_NE(member_id, membership_id(parent_raw)); - EXPECT_EQ(member_id, membership_id(child_raw)); - EXPECT_EQ(member_id, membership_id(child_raw->mask_layer())); - EXPECT_NE(member_id, membership_id(grand_child1_raw)); - EXPECT_NE(member_id, membership_id(grand_child2_raw)); + EXPECT_FALSE(grand_parent_raw->is_drawn_render_surface_layer_list_member()); + EXPECT_FALSE(parent_raw->is_drawn_render_surface_layer_list_member()); + EXPECT_TRUE(child_raw->is_drawn_render_surface_layer_list_member()); + EXPECT_TRUE( + child_raw->mask_layer()->is_drawn_render_surface_layer_list_member()); + EXPECT_FALSE(grand_child1_raw->is_drawn_render_surface_layer_list_member()); + EXPECT_FALSE(grand_child2_raw->is_drawn_render_surface_layer_list_member()); expected.clear(); expected.insert(child_raw); @@ -7868,13 +7811,12 @@ grand_child2_raw->SetDrawsContent(true); ExecuteCalculateDrawProperties(grand_parent_raw); - member_id = render_surface_layer_list_count(); - EXPECT_EQ(member_id, membership_id(grand_parent_raw)); - EXPECT_EQ(member_id, membership_id(parent_raw)); - EXPECT_EQ(member_id, membership_id(child_raw)); - EXPECT_EQ(member_id, membership_id(grand_child1_raw)); - EXPECT_EQ(member_id, membership_id(grand_child2_raw)); + EXPECT_TRUE(grand_parent_raw->is_drawn_render_surface_layer_list_member()); + EXPECT_TRUE(parent_raw->is_drawn_render_surface_layer_list_member()); + EXPECT_TRUE(child_raw->is_drawn_render_surface_layer_list_member()); + EXPECT_TRUE(grand_child1_raw->is_drawn_render_surface_layer_list_member()); + EXPECT_TRUE(grand_child2_raw->is_drawn_render_surface_layer_list_member()); expected.clear(); expected.insert(grand_parent_raw); @@ -7984,10 +7926,8 @@ gfx::Size device_viewport_size = gfx::Size(root_layer->bounds().width() * device_scale_factor, root_layer->bounds().height() * device_scale_factor); - root_layer->layer_tree_impl()->IncrementRenderSurfaceListIdForTesting(); LayerTreeHostCommon::CalcDrawPropsImplInputsForTesting inputs( - root_layer, device_viewport_size, &render_surface_layer_list, - root_layer->layer_tree_impl()->current_render_surface_list_id()); + root_layer, device_viewport_size, &render_surface_layer_list); inputs.page_scale_factor = page_scale_factor; inputs.can_adjust_raster_scales = true; @@ -8073,11 +8013,9 @@ gfx::Size device_viewport_size(768, 582); LayerImplList render_surface_layer_list_impl; - root->layer_tree_impl()->IncrementRenderSurfaceListIdForTesting(); LayerTreeHostCommon::CalcDrawPropsImplInputsForTesting inputs( root, device_viewport_size, identity_matrix, - &render_surface_layer_list_impl, - root->layer_tree_impl()->current_render_surface_list_id()); + &render_surface_layer_list_impl); inputs.device_scale_factor = 2.f; inputs.page_scale_factor = 1.f; inputs.page_scale_layer = NULL; @@ -8140,10 +8078,8 @@ sublayer->SetDrawsContent(true); LayerImplList layer_impl_list; - root->layer_tree_impl()->IncrementRenderSurfaceListIdForTesting(); LayerTreeHostCommon::CalcDrawPropsImplInputsForTesting inputs( - root, device_viewport_size, &layer_impl_list, - root->layer_tree_impl()->current_render_surface_list_id()); + root, device_viewport_size, &layer_impl_list); LayerTreeHostCommon::CalculateDrawProperties(&inputs); EXPECT_EQ(gfx::Rect(root_size), sublayer->visible_layer_rect());
diff --git a/cc/trees/layer_tree_host_impl_unittest.cc b/cc/trees/layer_tree_host_impl_unittest.cc index 25822a64..06f81fe 100644 --- a/cc/trees/layer_tree_host_impl_unittest.cc +++ b/cc/trees/layer_tree_host_impl_unittest.cc
@@ -1433,7 +1433,7 @@ // CommitComplete below. LayerImplList list; LayerTreeHostCommon::CalcDrawPropsImplInputsForTesting inputs( - root, gfx::Size(50, 50), &list, 0); + root, gfx::Size(50, 50), &list); LayerTreeHostCommon::CalculateDrawProperties(&inputs); EXPECT_FALSE(did_request_next_frame_);
diff --git a/cc/trees/layer_tree_host_unittest_animation.cc b/cc/trees/layer_tree_host_unittest_animation.cc index bc9f6b8d..22a3d55 100644 --- a/cc/trees/layer_tree_host_unittest_animation.cc +++ b/cc/trees/layer_tree_host_unittest_animation.cc
@@ -753,6 +753,63 @@ SINGLE_AND_MULTI_THREAD_TEST_F( LayerTreeHostAnimationTestScrollOffsetChangesArePropagated); +// Verifies that when a main thread scrolling reason gets added, the +// notification to takover the animation on the main thread gets sent. +class LayerTreeHostAnimationTestScrollOffsetAnimationTakeover + : public LayerTreeHostAnimationTest { + public: + LayerTreeHostAnimationTestScrollOffsetAnimationTakeover() {} + + void SetupTree() override { + LayerTreeHostAnimationTest::SetupTree(); + + scroll_layer_ = FakePictureLayer::Create(&client_); + scroll_layer_->SetBounds(gfx::Size(10000, 10000)); + client_.set_bounds(scroll_layer_->bounds()); + scroll_layer_->SetScrollOffset(gfx::ScrollOffset(10, 20)); + layer_tree_host()->root_layer()->AddChild(scroll_layer_); + + AttachPlayersToTimeline(); + player_child_->AttachElement(scroll_layer_->id()); + // Allows NotifyAnimationTakeover to get called. + player_child_->set_animation_delegate(this); + } + + void BeginTest() override { PostSetNeedsCommitToMainThread(); } + + void DidCommit() override { + // Add a main thread scrolling reason after the first commit to trigger + // the takeover path. + if (layer_tree_host()->source_frame_number() == 1) { + scroll_layer_->AddMainThreadScrollingReasons( + MainThreadScrollingReason::kHasNonLayerViewportConstrainedObjects); + } + } + + void WillCommitCompleteOnThread(LayerTreeHostImpl* host_impl) override { + if (host_impl->sync_tree()->source_frame_number() == 0) { + host_impl->animation_host()->ImplOnlyScrollAnimationCreate( + scroll_layer_->id(), gfx::ScrollOffset(650.f, 750.f), + gfx::ScrollOffset(10, 20)); + } + } + + void NotifyAnimationTakeover(base::TimeTicks monotonic_time, + TargetProperty::Type target_property, + double animation_start_time, + std::unique_ptr<AnimationCurve> curve) override { + EndTest(); + } + + void AfterTest() override {} + + private: + FakeContentLayerClient client_; + scoped_refptr<FakePictureLayer> scroll_layer_; +}; + +MULTI_THREAD_TEST_F(LayerTreeHostAnimationTestScrollOffsetAnimationTakeover); + // Verifies that when the main thread removes a scroll animation and sets a new // scroll position, the active tree takes on exactly this new scroll position // after activation, and the main thread doesn't receive a spurious scroll
diff --git a/cc/trees/layer_tree_host_unittest_occlusion.cc b/cc/trees/layer_tree_host_unittest_occlusion.cc index eed7a0b..1d3b3963 100644 --- a/cc/trees/layer_tree_host_unittest_occlusion.cc +++ b/cc/trees/layer_tree_host_unittest_occlusion.cc
@@ -52,8 +52,8 @@ LayerImpl* child = impl->active_tree()->LayerById(child_->id()); // Verify the draw properties are valid. - EXPECT_TRUE(root->IsDrawnRenderSurfaceLayerListMember()); - EXPECT_TRUE(child->IsDrawnRenderSurfaceLayerListMember()); + EXPECT_TRUE(root->is_drawn_render_surface_layer_list_member()); + EXPECT_TRUE(child->is_drawn_render_surface_layer_list_member()); EXPECT_OCCLUSION_EQ( Occlusion(child->DrawTransform(), SimpleEnclosedRegion(), @@ -109,8 +109,8 @@ RenderSurfaceImpl* surface = child->render_surface(); // Verify the draw properties are valid. - EXPECT_TRUE(root->IsDrawnRenderSurfaceLayerListMember()); - EXPECT_TRUE(child->IsDrawnRenderSurfaceLayerListMember()); + EXPECT_TRUE(root->is_drawn_render_surface_layer_list_member()); + EXPECT_TRUE(child->is_drawn_render_surface_layer_list_member()); EXPECT_TRUE(child->has_render_surface()); EXPECT_EQ(child->render_surface(), child->render_target()); @@ -177,8 +177,8 @@ LayerImpl* mask = child->mask_layer(); // Verify the draw properties are valid. - EXPECT_TRUE(root->IsDrawnRenderSurfaceLayerListMember()); - EXPECT_TRUE(child->IsDrawnRenderSurfaceLayerListMember()); + EXPECT_TRUE(root->is_drawn_render_surface_layer_list_member()); + EXPECT_TRUE(child->is_drawn_render_surface_layer_list_member()); EXPECT_TRUE(child->has_render_surface()); EXPECT_EQ(child->render_surface(), child->render_target()); @@ -318,8 +318,8 @@ LayerImpl* mask = child->mask_layer(); // Verify the draw properties are valid. - EXPECT_TRUE(root->IsDrawnRenderSurfaceLayerListMember()); - EXPECT_TRUE(child->IsDrawnRenderSurfaceLayerListMember()); + EXPECT_TRUE(root->is_drawn_render_surface_layer_list_member()); + EXPECT_TRUE(child->is_drawn_render_surface_layer_list_member()); EXPECT_TRUE(child->has_render_surface()); EXPECT_EQ(child->render_surface(), child->render_target());
diff --git a/cc/trees/layer_tree_impl.cc b/cc/trees/layer_tree_impl.cc index 9963c87..858506a 100644 --- a/cc/trees/layer_tree_impl.cc +++ b/cc/trees/layer_tree_impl.cc
@@ -78,7 +78,6 @@ needs_full_tree_sync_(true), next_activation_forces_redraw_(false), has_ever_been_drawn_(false), - render_surface_layer_list_id_(0), have_scroll_event_handlers_(false), event_listener_properties_(), top_controls_shrink_blink_size_(false), @@ -818,8 +817,6 @@ (layer_tree_host_impl_->GetDrawMode() != DRAW_MODE_RESOURCELESS_SOFTWARE); - ++render_surface_layer_list_id_; - LayerTreeHostCommon::CalcDrawPropsImplInputs inputs( root_layer(), DrawViewportSize(), layer_tree_host_impl_->DrawTransform(), device_scale_factor(), @@ -830,8 +827,7 @@ settings().can_use_lcd_text, settings().layers_always_allowed_lcd_text, can_render_to_separate_surface, settings().layer_transforms_should_scale_layer_contents, - &render_surface_layer_list_, render_surface_layer_list_id_, - &property_trees_); + &render_surface_layer_list_, &property_trees_); LayerTreeHostCommon::CalculateDrawProperties(&inputs); if (const char* client_name = GetClientNameForMetrics()) { UMA_HISTOGRAM_COUNTS( @@ -938,7 +934,7 @@ size_t layers_updated_count = 0; bool tile_priorities_updated = false; for (PictureLayerImpl* layer : picture_layers_) { - if (!layer->IsDrawnRenderSurfaceLayerListMember()) + if (!layer->is_drawn_render_surface_layer_list_member()) continue; ++layers_updated_count; tile_priorities_updated |= layer->UpdateTiles(); @@ -969,10 +965,6 @@ property_trees_.transform_tree.set_source_to_parent_updates_allowed(false); } -void LayerTreeImpl::IncrementRenderSurfaceListIdForTesting() { - render_surface_layer_list_id_++; -} - const LayerImplList& LayerTreeImpl::RenderSurfaceLayerList() const { // If this assert triggers, then the list is dirty. DCHECK(!needs_update_draw_properties_); @@ -1615,7 +1607,7 @@ const LayerImpl* layer, const TransformTree& transform_tree) { DCHECK(layer->render_surface()); - return layer->IsDrawnRenderSurfaceLayerListMember() + return layer->is_drawn_render_surface_layer_list_member() ? layer->render_surface()->screen_space_transform() : transform_tree.ToScreenSpaceTransformWithoutSublayerScale( layer->render_surface()->TransformTreeIndex()); @@ -1762,7 +1754,7 @@ LayerImpl* layer) { return layer->scrolls_drawn_descendant() || (layer->ToScrollbarLayer() && - layer->IsDrawnRenderSurfaceLayerListMember()); + layer->is_drawn_render_surface_layer_list_member()); } struct FindScrollingLayerOrScrollbarLayerFunctor { @@ -1784,7 +1776,7 @@ struct HitTestVisibleScrollableOrTouchableFunctor { bool operator()(LayerImpl* layer) const { - return layer->IsDrawnRenderSurfaceLayerListMember() || + return layer->is_drawn_render_surface_layer_list_member() || ScrollsOrScrollbarAnyDrawnRenderSurfaceLayerListMember(layer) || !layer->touch_event_handler_region().IsEmpty(); }
diff --git a/cc/trees/layer_tree_impl.h b/cc/trees/layer_tree_impl.h index f90bf0f2..15d0a40 100644 --- a/cc/trees/layer_tree_impl.h +++ b/cc/trees/layer_tree_impl.h
@@ -275,7 +275,6 @@ // text may cause invalidations, so should only be done after a commit. bool UpdateDrawProperties(bool update_lcd_text); void BuildPropertyTreesForTesting(); - void IncrementRenderSurfaceListIdForTesting(); void set_needs_update_draw_properties() { needs_update_draw_properties_ = true; @@ -402,10 +401,6 @@ return surface_layers_; } - int current_render_surface_list_id() const { - return render_surface_layer_list_id_; - } - LayerImpl* FindFirstScrollingLayerOrScrollbarLayerThatIsHitByPoint( const gfx::PointF& screen_space_point); @@ -578,8 +573,6 @@ UIResourceRequestQueue ui_resource_request_queue_; - int render_surface_layer_list_id_; - bool have_scroll_event_handlers_; EventListenerProperties event_listener_properties_[static_cast<size_t>( EventListenerClass::kNumClasses)];
diff --git a/cc/trees/layer_tree_impl_unittest.cc b/cc/trees/layer_tree_impl_unittest.cc index 44b1f1e..2a1547f 100644 --- a/cc/trees/layer_tree_impl_unittest.cc +++ b/cc/trees/layer_tree_impl_unittest.cc
@@ -2116,7 +2116,7 @@ host_impl().active_tree()->FindLayerThatIsHitByPointInTouchHandlerRegion( test_point); EXPECT_FALSE(result_layer); - EXPECT_FALSE(test_layer->IsDrawnRenderSurfaceLayerListMember()); + EXPECT_FALSE(test_layer->is_drawn_render_surface_layer_list_member()); EXPECT_TRANSFORMATION_MATRIX_EQ( expected_screen_space_transform, draw_property_utils::ScreenSpaceTransform( @@ -2138,7 +2138,7 @@ test_point); ASSERT_TRUE(result_layer); ASSERT_EQ(test_layer, result_layer); - EXPECT_FALSE(result_layer->IsDrawnRenderSurfaceLayerListMember()); + EXPECT_FALSE(result_layer->is_drawn_render_surface_layer_list_member()); EXPECT_TRANSFORMATION_MATRIX_EQ( expected_screen_space_transform, draw_property_utils::ScreenSpaceTransform(
diff --git a/cc/trees/occlusion_tracker_unittest.cc b/cc/trees/occlusion_tracker_unittest.cc index 9b0e7f9..8b54ce2 100644 --- a/cc/trees/occlusion_tracker_unittest.cc +++ b/cc/trees/occlusion_tracker_unittest.cc
@@ -229,10 +229,8 @@ FakeLayerTreeHostImpl::RecursiveUpdateNumChildren(root); - root->layer_tree_impl()->IncrementRenderSurfaceListIdForTesting(); LayerTreeHostCommon::CalcDrawPropsImplInputsForTesting inputs( - root, root->bounds(), &render_surface_layer_list_impl_, - root->layer_tree_impl()->current_render_surface_list_id()); + root, root->bounds(), &render_surface_layer_list_impl_); inputs.can_adjust_raster_scales = true; LayerTreeHostCommon::CalculateDrawProperties(&inputs);
diff --git a/cc/trees/property_tree_builder.cc b/cc/trees/property_tree_builder.cc index 081778c..a265b4e 100644 --- a/cc/trees/property_tree_builder.cc +++ b/cc/trees/property_tree_builder.cc
@@ -1040,6 +1040,27 @@ property_trees->scroll_tree.set_needs_update(false); } +#if DCHECK_IS_ON() +static void CheckScrollAndClipPointersForLayer(Layer* layer) { + if (!layer) + return; + + if (layer->scroll_children()) { + for (std::set<Layer*>::iterator it = layer->scroll_children()->begin(); + it != layer->scroll_children()->end(); ++it) { + DCHECK_EQ((*it)->scroll_parent(), layer); + } + } + + if (layer->clip_children()) { + for (std::set<Layer*>::iterator it = layer->clip_children()->begin(); + it != layer->clip_children()->end(); ++it) { + DCHECK_EQ((*it)->clip_parent(), layer); + } + } +} +#endif + void PropertyTreeBuilder::BuildPropertyTrees( Layer* root_layer, const Layer* page_scale_layer, @@ -1062,6 +1083,10 @@ outer_viewport_scroll_layer, overscroll_elasticity_layer, elastic_overscroll, page_scale_factor, device_scale_factor, viewport, device_transform, property_trees, color); +#if DCHECK_IS_ON() + for (auto* layer : *root_layer->layer_tree_host()) + CheckScrollAndClipPointersForLayer(layer); +#endif } void PropertyTreeBuilder::BuildPropertyTrees(
diff --git a/cc/trees/tree_synchronizer.cc b/cc/trees/tree_synchronizer.cc index d055f4c..c726f83 100644 --- a/cc/trees/tree_synchronizer.cc +++ b/cc/trees/tree_synchronizer.cc
@@ -124,32 +124,6 @@ SynchronizeTreesRecursiveInternal(old_layers, old_root, tree_impl)); } -#if DCHECK_IS_ON() -static void CheckScrollAndClipPointersForLayer(Layer* layer) { - if (!layer) - return; - - if (layer->scroll_children()) { - for (std::set<Layer*>::iterator it = layer->scroll_children()->begin(); - it != layer->scroll_children()->end(); ++it) { - DCHECK_EQ((*it)->scroll_parent(), layer); - } - } - - if (layer->clip_children()) { - for (std::set<Layer*>::iterator it = layer->clip_children()->begin(); - it != layer->clip_children()->end(); ++it) { - DCHECK_EQ((*it)->clip_parent(), layer); - } - } -} - -static void CheckScrollAndClipPointers(LayerTreeHost* host) { - for (auto* layer : *host) - CheckScrollAndClipPointersForLayer(layer); -} -#endif - template <typename LayerType> static void PushLayerPropertiesInternal( std::unordered_set<LayerType*> layers_that_should_push_properties, @@ -171,11 +145,6 @@ LayerTreeImpl* impl_tree) { PushLayerPropertiesInternal(host_tree->LayersThatShouldPushProperties(), impl_tree); - -#if DCHECK_IS_ON() - if (host_tree->root_layer()) - CheckScrollAndClipPointers(host_tree); -#endif } } // namespace cc
diff --git a/chrome/android/java/AndroidManifest.xml b/chrome/android/java/AndroidManifest.xml index 1bc8c3e..2aac3c79 100644 --- a/chrome/android/java/AndroidManifest.xml +++ b/chrome/android/java/AndroidManifest.xml
@@ -307,12 +307,10 @@ android:label="@string/fre_label" android:launchMode="singleTop" android:windowSoftInputMode="stateHidden|adjustPan" - android:screenOrientation="portrait" android:configChanges="orientation|keyboardHidden|keyboard|screenSize|mcc|mnc|screenLayout|smallestScreenSize"> </activity> <activity android:name="org.chromium.chrome.browser.signin.AccountSigninActivity" android:theme="@style/MainTheme" - android:screenOrientation="portrait" android:configChanges="orientation|keyboardHidden|keyboard|screenSize|mcc|mnc|screenLayout|smallestScreenSize"> </activity> <activity android:name="org.chromium.chrome.browser.preferences.Preferences" @@ -360,11 +358,6 @@ android:label="@string/bookmark_choose_folder" android:configChanges="orientation|keyboardHidden|keyboard|screenSize|mcc|mnc|screenLayout|smallestScreenSize"> </activity> - <activity android:name="org.chromium.chrome.browser.bookmarks.BookmarkSigninActivity" - android:theme="@style/BookmarkDialogWhite" - android:screenOrientation="portrait" - android:configChanges="orientation|keyboardHidden|keyboard|screenSize|mcc|mnc|screenLayout|smallestScreenSize"> - </activity> <!-- Activities for webapps.
diff --git a/chrome/android/java/res/drawable-hdpi/add_circle_blue.png b/chrome/android/java/res/drawable-hdpi/add_circle_blue.png index c98a6a0..2a5b8df 100644 --- a/chrome/android/java/res/drawable-hdpi/add_circle_blue.png +++ b/chrome/android/java/res/drawable-hdpi/add_circle_blue.png Binary files differ
diff --git a/chrome/android/java/res/drawable-mdpi/add_circle_blue.png b/chrome/android/java/res/drawable-mdpi/add_circle_blue.png index fe576c7..58c0b5d 100644 --- a/chrome/android/java/res/drawable-mdpi/add_circle_blue.png +++ b/chrome/android/java/res/drawable-mdpi/add_circle_blue.png Binary files differ
diff --git a/chrome/android/java/res/drawable-xhdpi/add_circle_blue.png b/chrome/android/java/res/drawable-xhdpi/add_circle_blue.png index cf0e8ab1..f997bf7 100644 --- a/chrome/android/java/res/drawable-xhdpi/add_circle_blue.png +++ b/chrome/android/java/res/drawable-xhdpi/add_circle_blue.png Binary files differ
diff --git a/chrome/android/java/res/drawable-xxhdpi/add_circle_blue.png b/chrome/android/java/res/drawable-xxhdpi/add_circle_blue.png index a8d2d27a6..ec1a265 100644 --- a/chrome/android/java/res/drawable-xxhdpi/add_circle_blue.png +++ b/chrome/android/java/res/drawable-xxhdpi/add_circle_blue.png Binary files differ
diff --git a/chrome/android/java/res/drawable-xxxhdpi/add_circle_blue.png b/chrome/android/java/res/drawable-xxxhdpi/add_circle_blue.png index b9a6aa8..1f01536 100644 --- a/chrome/android/java/res/drawable-xxxhdpi/add_circle_blue.png +++ b/chrome/android/java/res/drawable-xxxhdpi/add_circle_blue.png Binary files differ
diff --git a/chrome/android/java/res/layout/account_signin_choice_description_view.xml b/chrome/android/java/res/layout/account_signin_choice_description_view.xml deleted file mode 100644 index 5a10a94..0000000 --- a/chrome/android/java/res/layout/account_signin_choice_description_view.xml +++ /dev/null
@@ -1,14 +0,0 @@ -<?xml version="1.0" encoding="utf-8"?> -<!-- Copyright 2016 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. --> - -<TextView xmlns:android="http://schemas.android.com/apk/res/android" - android:id="@+id/signin_choice_description" - android:layout_width="wrap_content" - android:layout_height="wrap_content" - android:padding="16dp" - android:lineSpacingMultiplier="1.4" - android:text="@string/signin_account_choice_description" - android:textColor="@color/default_text_color" - android:textSize="@dimen/fre_normal_text_size"/> \ No newline at end of file
diff --git a/chrome/android/java/res/layout/account_signin_view.xml b/chrome/android/java/res/layout/account_signin_view.xml index b1467f7..d0934926 100644 --- a/chrome/android/java/res/layout/account_signin_view.xml +++ b/chrome/android/java/res/layout/account_signin_view.xml
@@ -17,42 +17,51 @@ android:layout_marginBottom="52dp"> <!-- The view that allows the user to choose the sign in account --> - <LinearLayout - android:id="@+id/signin_choose_account_view" + <org.chromium.chrome.browser.signin.AccountSigninChooseView + android:id="@+id/account_signin_choose_view" android:layout_width="match_parent" android:layout_height="match_parent" - android:orientation="vertical"> + android:scrollbars="none" + android:requiresFadingEdge="vertical" + android:fadingEdgeLength="48dp"> - <!-- The layout_width/layout_height is set to 16/9 dynamically in Java --> - <TextView - android:id="@+id/signin_title" + <LinearLayout + android:id="@+id/account_signin_choose_view_root_child_view" android:layout_width="match_parent" android:layout_height="wrap_content" - android:gravity="bottom" - android:paddingStart="16dp" - android:paddingEnd="16dp" - android:paddingBottom="16dp" - android:background="@color/signin_head_background" - android:textColor="@color/default_text_color" - android:textSize="@dimen/fre_title_text_size" - android:text="@string/sign_in_to_chrome"/> + android:orientation="vertical"> - <View - android:layout_width="match_parent" - android:layout_height="1dp" - android:background="@color/signin_border_line_color" - android:alpha="0.08"/> + <!-- The layout_width/layout_height is set to 16/9 dynamically in Java --> + <TextView + android:id="@+id/signin_title" + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:gravity="bottom" + android:paddingStart="@dimen/signin_chooser_padding" + android:paddingEnd="@dimen/signin_chooser_padding" + android:paddingBottom="@dimen/signin_chooser_padding" + android:background="@color/signin_head_background" + android:textColor="@color/default_text_color" + android:textSize="@dimen/fre_title_text_size" + android:text="@string/sign_in_to_chrome"/> - <org.chromium.chrome.browser.signin.AccountListView - android:id="@+id/signin_account_list" - android:layout_width="match_parent" - android:layout_height="wrap_content" - android:divider="@null" - android:dividerHeight="0dp" - android:scrollbars="none" - android:requiresFadingEdge="vertical" - android:fadingEdgeLength="48dp"/> - </LinearLayout> + <View + android:layout_width="match_parent" + android:layout_height="1dp" + android:background="@color/signin_border_line_color" + android:alpha="0.08"/> + + <TextView + android:id="@+id/signin_choice_description" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:padding="@dimen/signin_chooser_padding" + android:lineSpacingMultiplier="1.4" + android:text="@string/signin_account_choice_description" + android:textColor="@color/default_text_color" + android:textSize="@dimen/fre_normal_text_size"/> + </LinearLayout> + </org.chromium.chrome.browser.signin.AccountSigninChooseView> <!-- The view that allows the user to confirm signed in account, sync and service personalization --> <org.chromium.chrome.browser.signin.AccountSigninConfirmationView
diff --git a/chrome/android/java/res/layout/recent_tabs_sync_promo.xml b/chrome/android/java/res/layout/recent_tabs_sync_promo.xml deleted file mode 100644 index 8c226e5..0000000 --- a/chrome/android/java/res/layout/recent_tabs_sync_promo.xml +++ /dev/null
@@ -1,30 +0,0 @@ -<?xml version="1.0" encoding="utf-8"?> -<!-- 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. --> - -<LinearLayout - xmlns:android="http://schemas.android.com/apk/res/android" - xmlns:chrome="http://schemas.android.com/apk/res-auto" - android:layout_width="match_parent" - android:layout_height="wrap_content" - android:orientation="vertical" - android:paddingTop="10dp" - android:paddingBottom="28dp" > - - <TextView - android:id="@+id/text_view" - android:layout_width="match_parent" - android:layout_height="wrap_content" - android:textSize="14sp" /> - - <org.chromium.ui.widget.ButtonCompat - android:id="@+id/enable_sync_button" - android:layout_width="wrap_content" - android:layout_height="wrap_content" - android:layout_marginTop="24dp" - android:text="@string/ntp_recent_tabs_sync_enable_sync_button" - android:textColor="#fff" - chrome:buttonColor="@color/light_active_color" /> - -</LinearLayout>
diff --git a/chrome/android/java/res/layout/bookmark_promo_header.xml b/chrome/android/java/res/layout/signin_and_sync_view.xml similarity index 82% rename from chrome/android/java/res/layout/bookmark_promo_header.xml rename to chrome/android/java/res/layout/signin_and_sync_view.xml index 26cf503..07c2257 100644 --- a/chrome/android/java/res/layout/bookmark_promo_header.xml +++ b/chrome/android/java/res/layout/signin_and_sync_view.xml
@@ -1,10 +1,7 @@ <?xml version="1.0" encoding="utf-8"?> -<!-- - Copyright 2015 The Chromium Authors. All rights reserved. - +<!-- Copyright 2016 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. ---> + found in the LICENSE file. --> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:chrome="http://schemas.android.com/apk/res-auto" android:layout_width="match_parent" @@ -16,7 +13,7 @@ android:id="@+id/title" android:layout_width="wrap_content" android:layout_height="wrap_content" - android:text="@string/bookmark_sign_in_promo_title" + android:layout_marginBottom="8dp" android:textColor="@color/default_text_color" android:textSize="16sp" android:textStyle="bold" /> @@ -25,8 +22,6 @@ android:id="@+id/description" android:layout_width="wrap_content" android:layout_height="wrap_content" - android:layout_marginTop="8dp" - android:text="@string/bookmark_sign_in_promo_description" android:textColor="@color/default_text_color" android:textSize="14sp" /> @@ -43,7 +38,7 @@ style="@style/ButtonCompatBorderless" android:layout_width="wrap_content" android:layout_height="wrap_content" - android:text="@string/bookmark_sign_in_promo_no_thanks" + android:text="@string/no_thanks" android:textAllCaps="true" android:textColor="@color/light_active_color" android:textSize="15sp" /> @@ -52,7 +47,6 @@ android:id="@+id/sign_in" android:layout_width="wrap_content" android:layout_height="wrap_content" - android:text="@string/bookmark_sign_in_promo_sign_in" android:textAllCaps="true" android:textColor="@android:color/white" android:textSize="15sp"
diff --git a/chrome/android/java/res/values/dimens.xml b/chrome/android/java/res/values/dimens.xml index abf0881..0da9eea 100644 --- a/chrome/android/java/res/values/dimens.xml +++ b/chrome/android/java/res/values/dimens.xml
@@ -166,6 +166,8 @@ <!-- The Account Signin page appears in the First Run Experience (amongst other places), so uses a lot of the fre_* dimensions for consistency. --> <dimen name="signin_image_carousel_width">240dp</dimen> + <dimen name="signin_chooser_padding">16dp</dimen> + <dimen name="signin_screen_top_padding">50dp</dimen> <!-- Autofill card unmasking prompt dimensions --> <dimen name="autofill_card_unmask_tooltip_horizontal_padding">16dp</dimen> @@ -267,7 +269,6 @@ <!-- Recent tabs page --> <dimen name="recent_tabs_visible_separator_padding">8dp</dimen> - <dimen name="recent_tabs_promo_padding">16dp</dimen> <!-- Snackbars --> <dimen name="snackbar_min_height">48dp</dimen>
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/bookmarks/BookmarkPromoHeader.java b/chrome/android/java/src/org/chromium/chrome/browser/bookmarks/BookmarkPromoHeader.java index 1a0ced1..50ed7c3 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/bookmarks/BookmarkPromoHeader.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/bookmarks/BookmarkPromoHeader.java
@@ -5,18 +5,16 @@ package org.chromium.chrome.browser.bookmarks; import android.content.Context; -import android.content.Intent; import android.content.SharedPreferences; import android.preference.PreferenceManager; import android.support.v7.widget.RecyclerView; import android.support.v7.widget.RecyclerView.ViewHolder; -import android.view.LayoutInflater; import android.view.View; -import android.view.View.OnClickListener; import android.view.ViewGroup; import org.chromium.base.metrics.RecordUserAction; -import org.chromium.chrome.R; +import org.chromium.chrome.browser.signin.SigninAccessPoint; +import org.chromium.chrome.browser.signin.SigninAndSyncView; import org.chromium.chrome.browser.signin.SigninManager; import org.chromium.chrome.browser.signin.SigninManager.SignInStateObserver; import org.chromium.sync.AndroidSyncSettings; @@ -98,26 +96,17 @@ * {@link RecyclerView}. */ ViewHolder createHolder(ViewGroup parent) { - ViewGroup promoHeader = (ViewGroup) LayoutInflater.from(mContext) - .inflate(R.layout.bookmark_promo_header, parent, false); - - promoHeader.findViewById(R.id.no_thanks).setOnClickListener(new OnClickListener() { + SigninAndSyncView.Listener listener = new SigninAndSyncView.Listener() { @Override - public void onClick(View view) { + public void onViewDismissed() { RecordUserAction.record("Stars_SignInPromoHeader_Dismissed"); setSigninPromoDeclined(); updateShouldShow(true); } - }); + }; - promoHeader.findViewById(R.id.sign_in).setOnClickListener(new OnClickListener() { - @Override - public void onClick(View view) { - mContext.startActivity(new Intent(mContext, BookmarkSigninActivity.class)); - } - }); - - return new ViewHolder(promoHeader) {}; + View view = new SigninAndSyncView(mContext, listener, SigninAccessPoint.BOOKMARK_MANAGER); + return new ViewHolder(view) {}; } /**
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/bookmarks/BookmarkSigninActivity.java b/chrome/android/java/src/org/chromium/chrome/browser/bookmarks/BookmarkSigninActivity.java deleted file mode 100644 index e84fcd7..0000000 --- a/chrome/android/java/src/org/chromium/chrome/browser/bookmarks/BookmarkSigninActivity.java +++ /dev/null
@@ -1,149 +0,0 @@ -// 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.chrome.browser.bookmarks; - -import android.os.Bundle; - -import org.chromium.base.ObserverList; -import org.chromium.base.metrics.RecordUserAction; -import org.chromium.chrome.browser.firstrun.ProfileDataCache; -import org.chromium.chrome.browser.ntp.RecentTabsPromoView; -import org.chromium.chrome.browser.ntp.RecentTabsPromoView.SyncPromoModel; -import org.chromium.chrome.browser.ntp.RecentTabsPromoView.UserActionListener; -import org.chromium.chrome.browser.profiles.Profile; -import org.chromium.chrome.browser.signin.SigninAccessPoint; -import org.chromium.chrome.browser.signin.SigninManager; -import org.chromium.chrome.browser.signin.SigninManager.SignInStateObserver; -import org.chromium.chrome.browser.sync.ProfileSyncService; -import org.chromium.sync.AndroidSyncSettings; -import org.chromium.sync.AndroidSyncSettings.AndroidSyncSettingsObserver; -import org.chromium.sync.signin.ChromeSigninController; - -/** - * Sign in promotion activity that is triggered from bookmark UI. - */ -public class BookmarkSigninActivity extends BookmarkActivityBase implements - AndroidSyncSettingsObserver, SignInStateObserver, SyncPromoModel, UserActionListener { - private SigninManager mSignInManager; - private ProfileDataCache mProfileDataCache; - private final ObserverList<AndroidSyncSettingsObserver> mObservers = - new ObserverList<AndroidSyncSettingsObserver>(); - - @Override - public void onCreate(Bundle savedInstanceState) { - super.onCreate(savedInstanceState); - if (savedInstanceState == null) { - RecordUserAction.record("Stars_SignInPromoActivity_Launched"); - } - - setContentView(new RecentTabsPromoView(this, this, this)); - - AndroidSyncSettings.registerObserver(this, this); - - mSignInManager = SigninManager.get(this); - mSignInManager.addSignInStateObserver(this); - - // This signin activity shouldn't be created if user is signed in already, but for just in - // case it was signed in just before onCreate somehow. - if (isSignedIn()) finish(); - } - - @Override - public void onDestroy() { - super.onDestroy(); - AndroidSyncSettings.unregisterObserver(this, this); - - mSignInManager.removeSignInStateObserver(this); - mSignInManager = null; - - if (mProfileDataCache != null) { - mProfileDataCache.destroy(); - mProfileDataCache = null; - } - } - - // AndroidSyncSettingsObserver - - @Override - public void androidSyncSettingsChanged() { - for (AndroidSyncSettingsObserver observer : mObservers) { - observer.androidSyncSettingsChanged(); - } - } - - // SignInStateObserver - - @Override - public void onSignedIn() { - androidSyncSettingsChanged(); - finish(); - } - - @Override - public void onSignedOut() { - assert false : "onSignedOut() called on signin activity."; - } - - // SyncPromoModel - - @Override - public boolean isSyncEnabled() { - return AndroidSyncSettings.isSyncEnabled(this); - } - - @Override - public boolean isSignedIn() { - return ChromeSigninController.get(this).isSignedIn(); - } - - @Override - public void enableSync() { - ProfileSyncService syncService = ProfileSyncService.get(); - if (syncService != null) { - syncService.requestStart(); - } - } - - @Override - public void registerForSyncUpdates(AndroidSyncSettingsObserver changeListener) { - mObservers.addObserver(changeListener); - } - - @Override - public void unregisterForSyncUpdates(AndroidSyncSettingsObserver changeListener) { - mObservers.removeObserver(changeListener); - } - - // UserActionListener - - @Override - public void onAccountSelectionConfirmed() { - RecordUserAction.record("Stars_SignInPromoActivity_SignedIn"); - RecordUserAction.record("Signin_Signin_FromBookmarkManager"); - } - - @Override - public void onNewAccount() { - RecordUserAction.record("Stars_SignInPromoActivity_NewAccount"); - } - - @Override - public void onAccountSelectionCancelled() { - finish(); - }; - - @Override - public ProfileDataCache getProfileDataCache() { - if (mProfileDataCache == null) { - mProfileDataCache = new ProfileDataCache(this, Profile.getLastUsedProfile()); - } - return mProfileDataCache; - } - - @Override - public int getAccessPoint() { - return SigninAccessPoint.BOOKMARK_MANAGER; - } -}
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/firstrun/FirstRunView.java b/chrome/android/java/src/org/chromium/chrome/browser/firstrun/FirstRunView.java index d360389..74f8582 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/firstrun/FirstRunView.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/firstrun/FirstRunView.java
@@ -48,12 +48,13 @@ return true; } - protected boolean isDynamicPaddingEnabled() { - return true; - } - @Override protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { + // There was a requirement to have the titles and images of all of the first run experience + // pages to be vertically aligned so the transitions between pages look nice. + // The other requirement is for an alternate layout in horizontal mode for screens of a + // certain size. These are why the padding is set manually. + // This assumes that view's layout_width is set to match_parent. assert MeasureSpec.getMode(widthMeasureSpec) == MeasureSpec.EXACTLY; @@ -96,12 +97,10 @@ } // Add padding to get it roughly centered. - if (isDynamicPaddingEnabled()) { - int topPadding = Math.max(0, (height / 2) - halfContentHeight); + int topPadding = Math.max(0, (height / 2) - halfContentHeight); - mMainLayout.setPadding(mMainLayout.getPaddingLeft(), topPadding, - mMainLayout.getPaddingRight(), mMainLayout.getPaddingBottom()); - } + mMainLayout.setPadding(mMainLayout.getPaddingLeft(), topPadding, + mMainLayout.getPaddingRight(), mMainLayout.getPaddingBottom()); ApiCompatibilityUtils.setPaddingRelative(mImageAndContent, imageAndContentPaddingStart,
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/init/ChromeBrowserInitializer.java b/chrome/android/java/src/org/chromium/chrome/browser/init/ChromeBrowserInitializer.java index 6991058..d7fda1d5 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/init/ChromeBrowserInitializer.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/init/ChromeBrowserInitializer.java
@@ -23,6 +23,7 @@ import org.chromium.base.BaseSwitches; import org.chromium.base.CommandLine; import org.chromium.base.ContentUriUtils; +import org.chromium.base.ContextUtils; import org.chromium.base.Log; import org.chromium.base.PathUtils; import org.chromium.base.ResourceExtractor; @@ -184,6 +185,8 @@ ThreadUtils.assertOnUiThread(); if (mPreInflationStartupComplete) return; + ContextUtils.initApplicationContext(mApplication); + // Ensure critical files are available, so they aren't blocked on the file-system // behind long-running accesses in next phase. // Don't do any large file access here!
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/media/router/cast/CastSessionImpl.java b/chrome/android/java/src/org/chromium/chrome/browser/media/router/cast/CastSessionImpl.java index 01aff0f5..cef866a6 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/media/router/cast/CastSessionImpl.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/media/router/cast/CastSessionImpl.java
@@ -142,8 +142,10 @@ } Intent contentIntent = Tab.createBringTabToFrontIntent(tabId); - contentIntent.putExtra(MediaNotificationUma.INTENT_EXTRA_NAME, - MediaNotificationUma.SOURCE_PRESENTATION); + if (contentIntent != null) { + contentIntent.putExtra(MediaNotificationUma.INTENT_EXTRA_NAME, + MediaNotificationUma.SOURCE_PRESENTATION); + } mNotificationBuilder = new MediaNotificationInfo.Builder() .setPaused(false) .setOrigin(origin)
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/media/ui/MediaSessionTabHelper.java b/chrome/android/java/src/org/chromium/chrome/browser/media/ui/MediaSessionTabHelper.java index 0484774a..083d709 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/media/ui/MediaSessionTabHelper.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/media/ui/MediaSessionTabHelper.java
@@ -114,8 +114,10 @@ } Intent contentIntent = Tab.createBringTabToFrontIntent(mTab.getId()); - contentIntent.putExtra(MediaNotificationUma.INTENT_EXTRA_NAME, - MediaNotificationUma.SOURCE_MEDIA); + if (contentIntent != null) { + contentIntent.putExtra(MediaNotificationUma.INTENT_EXTRA_NAME, + MediaNotificationUma.SOURCE_MEDIA); + } mNotificationInfoBuilder = new MediaNotificationInfo.Builder()
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/ntp/NewTabPage.java b/chrome/android/java/src/org/chromium/chrome/browser/ntp/NewTabPage.java index aa250af..a0c2500d 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/ntp/NewTabPage.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/ntp/NewTabPage.java
@@ -80,6 +80,8 @@ import org.chromium.ui.base.DeviceFormFactor; import org.chromium.ui.base.PageTransition; +import java.util.HashSet; +import java.util.Set; import java.util.concurrent.TimeUnit; import jp.tomorrowkey.android.gifplayer.BaseGifImage; @@ -455,10 +457,32 @@ } @Override - public boolean isOfflineAvailable(String pageUrl) { - if (mIsDestroyed || !isNtpOfflinePagesEnabled()) return false; - if (isLocalUrl(pageUrl)) return true; - return OfflinePageBridge.getForProfile(mProfile).offlinePageExists(pageUrl); + public void getUrlsAvailableOffline( + Set<String> pageUrls, final Callback<Set<String>> callback) { + final Set<String> urlsAvailableOffline = new HashSet<>(); + if (mIsDestroyed || !isNtpOfflinePagesEnabled()) { + callback.onResult(urlsAvailableOffline); + return; + } + + HashSet<String> urlsToCheckForOfflinePage = new HashSet<>(); + + for (String pageUrl : pageUrls) { + if (isLocalUrl(pageUrl)) { + urlsAvailableOffline.add(pageUrl); + } else { + urlsToCheckForOfflinePage.add(pageUrl); + } + } + + OfflinePageBridge.getForProfile(mProfile).checkPagesExistOffline( + urlsToCheckForOfflinePage, new Callback<Set<String>>() { + @Override + public void onResult(Set<String> urlsWithOfflinePages) { + urlsAvailableOffline.addAll(urlsWithOfflinePages); + callback.onResult(urlsAvailableOffline); + } + }); } @Override
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/ntp/NewTabPageView.java b/chrome/android/java/src/org/chromium/chrome/browser/ntp/NewTabPageView.java index 978476c3..bb726325 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/ntp/NewTabPageView.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/ntp/NewTabPageView.java
@@ -32,6 +32,7 @@ import android.widget.ImageView; import android.widget.TextView; +import org.chromium.base.Callback; import org.chromium.base.Log; import org.chromium.base.VisibleForTesting; import org.chromium.base.metrics.RecordUserAction; @@ -54,6 +55,10 @@ import org.chromium.chrome.browser.widget.RoundedIconGenerator; import org.chromium.ui.base.DeviceFormFactor; +import java.util.Arrays; +import java.util.HashSet; +import java.util.Set; + import jp.tomorrowkey.android.gifplayer.BaseGifImage; /** @@ -198,10 +203,11 @@ IconAvailabilityCallback callback); /** - * Checks if the page with the given URL is available offline. - * @param pageUrl The URL of the site whose offline availability is requested. + * Checks if the pages with the given URLs are available offline. + * @param pageUrls The URLs of the sites whose offline availability is requested. + * @param callback Fired when the results are available. */ - boolean isOfflineAvailable(String pageUrl); + void getUrlsAvailableOffline(Set<String> pageUrls, Callback<Set<String>> callback); /** * Called when the user clicks on the logo. @@ -805,7 +811,22 @@ @Override public void onMostVisitedURLsAvailable( - String[] titles, String[] urls, String[] whitelistIconPaths) { + final String[] titles, final String[] urls, final String[] whitelistIconPaths) { + Set<String> urlSet = new HashSet<>(Arrays.asList(urls)); + + // TODO(https://crbug.com/607573): We should show offline-available content in a nonblocking + // way so that responsiveness of the NTP does not depend on ready availability of offline + // pages. + mManager.getUrlsAvailableOffline(urlSet, new Callback<Set<String>>() { + @Override + public void onResult(Set<String> offlineUrls) { + onOfflineUrlsAvailable(titles, urls, whitelistIconPaths, offlineUrls); + } + }); + } + + private void onOfflineUrlsAvailable(final String[] titles, final String[] urls, + final String[] whitelistIconPaths, final Set<String> offlineUrls) { mMostVisitedLayout.removeAllViews(); MostVisitedItem[] oldItems = mMostVisitedItems; @@ -820,7 +841,7 @@ final String url = urls[i]; final String title = titles[i]; final String whitelistIconPath = whitelistIconPaths[i]; - boolean offlineAvailable = mManager.isOfflineAvailable(url); + boolean offlineAvailable = offlineUrls.contains(url); // Look for an existing item to reuse. MostVisitedItem item = null;
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/ntp/RecentTabsManager.java b/chrome/android/java/src/org/chromium/chrome/browser/ntp/RecentTabsManager.java index c799319..981530e 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/ntp/RecentTabsManager.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/ntp/RecentTabsManager.java
@@ -9,25 +9,20 @@ import android.graphics.Bitmap; import android.preference.PreferenceManager; -import org.chromium.base.ObserverList; import org.chromium.base.ThreadUtils; import org.chromium.chrome.browser.UrlConstants; import org.chromium.chrome.browser.favicon.FaviconHelper; import org.chromium.chrome.browser.favicon.FaviconHelper.FaviconImageCallback; -import org.chromium.chrome.browser.firstrun.ProfileDataCache; import org.chromium.chrome.browser.invalidation.InvalidationController; import org.chromium.chrome.browser.metrics.StartupMetrics; import org.chromium.chrome.browser.ntp.ForeignSessionHelper.ForeignSession; import org.chromium.chrome.browser.ntp.ForeignSessionHelper.ForeignSessionCallback; import org.chromium.chrome.browser.ntp.ForeignSessionHelper.ForeignSessionTab; -import org.chromium.chrome.browser.ntp.RecentTabsPromoView.SyncPromoModel; import org.chromium.chrome.browser.ntp.RecentlyClosedBridge.RecentlyClosedCallback; import org.chromium.chrome.browser.ntp.RecentlyClosedBridge.RecentlyClosedTab; import org.chromium.chrome.browser.profiles.Profile; -import org.chromium.chrome.browser.signin.SigninAccessPoint; import org.chromium.chrome.browser.signin.SigninManager; import org.chromium.chrome.browser.signin.SigninManager.SignInStateObserver; -import org.chromium.chrome.browser.sync.ProfileSyncService; import org.chromium.chrome.browser.tab.Tab; import org.chromium.content_public.browser.LoadUrlParams; import org.chromium.sync.AndroidSyncSettings; @@ -40,8 +35,7 @@ /** * Provides the domain logic and data for RecentTabsPage and RecentTabsRowAdapter. */ -public class RecentTabsManager implements AndroidSyncSettingsObserver, SignInStateObserver, - SyncPromoModel { +public class RecentTabsManager implements AndroidSyncSettingsObserver, SignInStateObserver { /** * Implement this to receive updates when the page contents change. @@ -60,8 +54,6 @@ private final Profile mProfile; private final Tab mTab; private final Context mContext; - private final ObserverList<AndroidSyncSettingsObserver> mObservers = - new ObserverList<AndroidSyncSettingsObserver>(); private FaviconHelper mFaviconHelper; private ForeignSessionHelper mForeignSessionHelper; @@ -71,7 +63,6 @@ private RecentlyClosedBridge mRecentlyClosedBridge; private SigninManager mSignInManager; private UpdatedCallback mUpdatedCallback; - private ProfileDataCache mProfileDataCache; private boolean mIsDestroyed; /** @@ -124,11 +115,6 @@ mNewTabPagePrefs.destroy(); mNewTabPagePrefs = null; - if (mProfileDataCache != null) { - mProfileDataCache.destroy(); - mProfileDataCache = null; - } - InvalidationController.get(mContext).onRecentTabsPageClosed(); } @@ -461,52 +447,11 @@ if (mIsDestroyed) return; updateForeignSessions(); postUpdate(); - for (AndroidSyncSettingsObserver observer : mObservers) { - observer.androidSyncSettingsChanged(); - } } }); } - // SyncPromoModel - @Override - public boolean isSyncEnabled() { - return AndroidSyncSettings.isSyncEnabled(mContext); - } - - @Override public boolean isSignedIn() { return ChromeSigninController.get(mContext).isSignedIn(); } - - @Override - public void enableSync() { - ProfileSyncService syncService = ProfileSyncService.get(); - if (syncService != null) { - syncService.requestStart(); - } - } - - @Override - public void registerForSyncUpdates(AndroidSyncSettingsObserver changeListener) { - mObservers.addObserver(changeListener); - } - - @Override - public void unregisterForSyncUpdates(AndroidSyncSettingsObserver changeListener) { - mObservers.removeObserver(changeListener); - } - - @Override - public ProfileDataCache getProfileDataCache() { - if (mProfileDataCache == null) { - mProfileDataCache = new ProfileDataCache(mContext, Profile.getLastUsedProfile()); - } - return mProfileDataCache; - } - - @Override - public int getAccessPoint() { - return SigninAccessPoint.RECENT_TABS; - } }
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/ntp/RecentTabsPromoView.java b/chrome/android/java/src/org/chromium/chrome/browser/ntp/RecentTabsPromoView.java deleted file mode 100644 index 6e1c5a8..0000000 --- a/chrome/android/java/src/org/chromium/chrome/browser/ntp/RecentTabsPromoView.java +++ /dev/null
@@ -1,296 +0,0 @@ -// 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.chrome.browser.ntp; - -import android.animation.Animator; -import android.animation.AnimatorListenerAdapter; -import android.animation.ObjectAnimator; -import android.app.Activity; -import android.app.FragmentManager; -import android.graphics.Color; -import android.view.Gravity; -import android.view.LayoutInflater; -import android.view.View; -import android.widget.FrameLayout; -import android.widget.TextView; - -import org.chromium.chrome.R; -import org.chromium.chrome.browser.firstrun.ProfileDataCache; -import org.chromium.chrome.browser.signin.AccountAdder; -import org.chromium.chrome.browser.signin.AccountSigninView; -import org.chromium.chrome.browser.signin.SigninManager; -import org.chromium.sync.AndroidSyncSettings.AndroidSyncSettingsObserver; - -/** - * Promo view on the recent tabs page that encourages the user to sign in to Chrome or enable sync. - * This view handles three scenarios: - * - * 1. The user is not signed in: Shows the sign-in screen from first run. - * 2. The user is signed in but sync is disabled: Displays a message encouraging the user - * to enable sync with a corresponding button. - * 3. The user is signed in and sync is enabled: Displays a message instructing - * the user to sign in and open tabs on another device to use this awesome feature. - */ -public class RecentTabsPromoView extends FrameLayout implements AndroidSyncSettingsObserver { - - /** - * Interface definition for the model this view needs to interact with. - */ - public interface SyncPromoModel { - /** - * @return Whether sync is enabled. - */ - public boolean isSyncEnabled(); - - /** - * @return Whether the user is signed in. - */ - public boolean isSignedIn(); - - /** - * Enables sync for the current signed in account. - */ - public void enableSync(); - - /** - * Attaches a listener to sync state changes. - * - * @param changeListener The SyncStateChangedListener The object to register for sync - * updates. - */ - public void registerForSyncUpdates(AndroidSyncSettingsObserver changeListener); - - /** - * Removes a listener for sync state changes. - * - * @param changeListener The SyncStateChangedListener The object to unregister for sync - * updates. - */ - public void unregisterForSyncUpdates(AndroidSyncSettingsObserver changeListener); - - /** - * @return A ProfileDataCache to retrieve user account info. - */ - public ProfileDataCache getProfileDataCache(); - - /** - * @return the access point of creating this view. - */ - public int getAccessPoint(); - } - - /** - * Interface for listening user actions on this UI. - */ - public interface UserActionListener { - /** - * Called when user confirms an account to sign-in. - */ - void onAccountSelectionConfirmed(); - - /** - * Called when user attempts to create a new account. - */ - void onNewAccount(); - - /** - * Called when a user cancels the account sign in process. - */ - void onAccountSelectionCancelled(); - } - - private static final int PROMO_TYPE_SIGN_IN = 0; - private static final int PROMO_TYPE_SYNC_DISABLED = 1; - private static final int PROMO_TYPE_SYNC_ENABLED = 2; - - private static final int TEXT_COLOR_NORMAL = 0xff333333; - private static final int TEXT_COLOR_LIGHT = 0xffa0a0a0; - - private static final long FADE_DURATION_MS = 300L; - - private Activity mActivity; - private SyncPromoModel mModel; - private UserActionListener mUserActionListener; - - private View mPromo; - private int mPromoType = -1; - private Animator mFadeAnimation; - - /** - * Constructor for use from Java. - * - * @param activity The Activity this view will be presented in. - * @param model The SyncPromoModel used to determine the state of sync and sign-in. - */ - public RecentTabsPromoView(Activity activity, SyncPromoModel model, - UserActionListener userActionListener) { - super(activity); - mModel = model; - mActivity = activity; - mUserActionListener = userActionListener; - int sidePadding = getResources().getDimensionPixelOffset(R.dimen.recent_tabs_promo_padding); - setPadding(sidePadding, 0, sidePadding, 0); - } - - @Override - protected void onAttachedToWindow() { - super.onAttachedToWindow(); - mModel.registerForSyncUpdates(this); - configureForSyncState(false); - } - - @Override - protected void onDetachedFromWindow() { - super.onDetachedFromWindow(); - mModel.unregisterForSyncUpdates(this); - } - - @Override - public void onWindowVisibilityChanged(int visibility) { - super.onWindowVisibilityChanged(visibility); - if (visibility == View.VISIBLE) { - configureForSyncState(false); - } - } - - // AndroidSyncSettingsObserver - @Override - public void androidSyncSettingsChanged() { - configureForSyncState(true); - } - - private void configureForSyncState(boolean animate) { - int desiredPromoType = getDesiredPromoType(); - if (mPromo != null && mPromoType == desiredPromoType) { - return; - } - - // In the rare case that the promo type changes while an animation is already underway, - // cancel the existing animation and show the new promo without animation. This is a rare - // case, and it's not worth the complexity (and bug potential) of implementing a three-way - // cross fade. - if (mFadeAnimation != null) { - mFadeAnimation.end(); - animate = false; - } - - if (animate && mPromoType == PROMO_TYPE_SIGN_IN) { - ((AccountSigninView) mPromo).switchToSignedMode(); - } - - final View oldPromo = mPromo; - mPromoType = desiredPromoType; - mPromo = createPromoView(desiredPromoType); - - if (animate) { - // Fade in the new promo on top of the old one. Set the background color to white so - // the old promo effectively fades out as the new one fades in. - mPromo.setAlpha(0f); - mPromo.setBackgroundColor(Color.WHITE); - addView(mPromo); - - mFadeAnimation = ObjectAnimator.ofFloat(mPromo, View.ALPHA, 1f); - mFadeAnimation.setDuration(FADE_DURATION_MS); - mFadeAnimation.addListener(new AnimatorListenerAdapter() { - @Override - public void onAnimationEnd(Animator animation) { - mFadeAnimation = null; - mPromo.setBackgroundResource(0); - removeView(oldPromo); - } - }); - mFadeAnimation.start(); - } else { - removeView(oldPromo); - addView(mPromo); - } - } - - private int getDesiredPromoType() { - if (!mModel.isSignedIn()) { - return PROMO_TYPE_SIGN_IN; - } else { - return mModel.isSyncEnabled() ? PROMO_TYPE_SYNC_ENABLED : PROMO_TYPE_SYNC_DISABLED; - } - } - - private View createPromoView(int promoType) { - if (promoType == PROMO_TYPE_SIGN_IN) { - return createSignInPromoView(); - } else { - return createSyncPromoView(promoType == PROMO_TYPE_SYNC_ENABLED); - } - } - - private View createSyncPromoView(boolean isSyncEnabled) { - View syncPromoView = LayoutInflater.from(getContext()).inflate( - R.layout.recent_tabs_sync_promo, this, false); - - TextView textView = (TextView) syncPromoView.findViewById(R.id.text_view); - View enableSyncButton = syncPromoView.findViewById(R.id.enable_sync_button); - - if (isSyncEnabled) { - textView.setText(R.string.ntp_recent_tabs_sync_promo_instructions); - textView.setTextColor(TEXT_COLOR_LIGHT); - enableSyncButton.setVisibility(View.GONE); - } else { - textView.setText(R.string.ntp_recent_tabs_sync_enable_sync); - textView.setTextColor(TEXT_COLOR_NORMAL); - enableSyncButton.setOnClickListener(new OnClickListener() { - @Override - public void onClick(View v) { - mModel.enableSync(); - } - }); - } - - return syncPromoView; - } - - private View createSignInPromoView() { - AccountSigninView signInPromoView = (AccountSigninView) LayoutInflater.from(getContext()) - .inflate(R.layout.account_signin_view, this, false); - signInPromoView.init(mModel.getProfileDataCache()); - signInPromoView.getLayoutParams().height = LayoutParams.WRAP_CONTENT; - ((FrameLayout.LayoutParams) signInPromoView.getLayoutParams()).gravity = Gravity.CENTER; - signInPromoView.configureForRecentTabsOrBookmarksPage(); - signInPromoView.setListener(new AccountSigninView.Listener() { - @Override - public void onAccountSelectionCanceled() { - assert mUserActionListener != null; - mUserActionListener.onAccountSelectionCancelled(); - } - - @Override - public void onNewAccount() { - if (mUserActionListener != null) mUserActionListener.onNewAccount(); - - AccountAdder.getInstance().addAccount(mActivity, AccountAdder.ADD_ACCOUNT_RESULT); - } - - @Override - public void onAccountSelected(String accountName, boolean settingsClicked) { - assert !settingsClicked : "Settings should be hidden in RecentTabsPromoView."; - - if (mUserActionListener != null) mUserActionListener.onAccountSelectionConfirmed(); - SigninManager.get(mActivity).signIn(accountName, mActivity, null); - } - - @Override - public void onFailedToSetForcedAccount(String forcedAccountName) { - // TODO(bauerb): make sure we shouldn't see SignInPromoView. - assert false : "No forced accounts in SignInPromoView"; - } - }); - signInPromoView.setDelegate(new AccountSigninView.Delegate() { - @Override - public FragmentManager getFragmentManager() { - return mActivity.getFragmentManager(); - } - }); - SigninManager.logSigninStartAccessPoint(mModel.getAccessPoint()); - return signInPromoView; - } -}
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/ntp/RecentTabsRowAdapter.java b/chrome/android/java/src/org/chromium/chrome/browser/ntp/RecentTabsRowAdapter.java index a301e552..bad325df 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/ntp/RecentTabsRowAdapter.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/ntp/RecentTabsRowAdapter.java
@@ -27,8 +27,9 @@ import org.chromium.chrome.browser.ntp.ForeignSessionHelper.ForeignSession; import org.chromium.chrome.browser.ntp.ForeignSessionHelper.ForeignSessionTab; import org.chromium.chrome.browser.ntp.ForeignSessionHelper.ForeignSessionWindow; -import org.chromium.chrome.browser.ntp.RecentTabsPromoView.UserActionListener; import org.chromium.chrome.browser.ntp.RecentlyClosedBridge.RecentlyClosedTab; +import org.chromium.chrome.browser.signin.SigninAccessPoint; +import org.chromium.chrome.browser.signin.SigninAndSyncView; import org.chromium.ui.WindowOpenDisposition; import org.chromium.ui.base.DeviceFormFactor; @@ -593,20 +594,16 @@ View getChildView(int childPosition, boolean isLastChild, View convertView, ViewGroup parent) { if (convertView == null) { - convertView = new RecentTabsPromoView( - mActivity, mRecentTabsManager, new UserActionListener() { - @Override - public void onAccountSelectionConfirmed() { - RecordUserAction.record("Signin_Signin_FromRecentTabs"); - } - @Override - public void onNewAccount() {} - @Override - public void onAccountSelectionCancelled() { - mRecentTabsManager.setSigninPromoDeclined(); - notifyDataSetChanged(); - } - }); + SigninAndSyncView.Listener listener = new SigninAndSyncView.Listener() { + @Override + public void onViewDismissed() { + mRecentTabsManager.setSigninPromoDeclined(); + notifyDataSetChanged(); + } + }; + + convertView = + new SigninAndSyncView(mActivity, listener, SigninAccessPoint.RECENT_TABS); } if (!mRecentTabsManager.isSignedIn()) { RecordUserAction.record("Signin_Impression_FromRecentTabs");
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/offlinepages/OfflinePageBridge.java b/chrome/android/java/src/org/chromium/chrome/browser/offlinepages/OfflinePageBridge.java index 4da8bdc..061de45 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/offlinepages/OfflinePageBridge.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/offlinepages/OfflinePageBridge.java
@@ -6,6 +6,7 @@ import android.os.AsyncTask; +import org.chromium.base.Callback; import org.chromium.base.ObserverList; import org.chromium.base.ThreadUtils; import org.chromium.base.VisibleForTesting; @@ -18,6 +19,7 @@ import org.chromium.content_public.browser.WebContents; import java.util.ArrayList; +import java.util.Collections; import java.util.HashSet; import java.util.List; import java.util.Set; @@ -470,17 +472,32 @@ nativeCheckMetadataConsistency(mNativeOfflinePageBridge); } + private static class CheckPagesExistOfflineCallbackInternal { + private Callback<Set<String>> mCallback; + + CheckPagesExistOfflineCallbackInternal(Callback<Set<String>> callback) { + mCallback = callback; + } + + @CalledByNative("CheckPagesExistOfflineCallbackInternal") + public void onResult(String[] results) { + Set<String> resultSet = new HashSet<>(); + Collections.addAll(resultSet, results); + mCallback.onResult(resultSet); + } + } + /** - * Gets the offline URL of an offline page of that is saved for the online URL. - * This method is deprecated. Use OfflinePageBridge#getPagesByOnlineUrl. + * Returns via callback any urls in <code>urls</code> for which there exist offline pages. * - * @param onlineUrl Online URL, which might have offline copy. - * @return URL pointing to the offline copy or <code>null</code> if none exists. + * TODO(http://crbug.com/598006): Add metrics for preventing UI jank. */ - public boolean offlinePageExists(String onlineUrl) { - assert mIsNativeOfflinePageModelLoaded; - OfflinePageItem item = nativeGetPageByOnlineURL(mNativeOfflinePageBridge, onlineUrl); - return item != null; + public void checkPagesExistOffline(Set<String> urls, Callback<Set<String>> callback) { + String[] urlArray = urls.toArray(new String[urls.size()]); + + CheckPagesExistOfflineCallbackInternal callbackInternal = + new CheckPagesExistOfflineCallbackInternal(callback); + nativeCheckPagesExistOffline(mNativeOfflinePageBridge, urlArray, callbackInternal); } private DeletePageCallback wrapCallbackWithHistogramReporting( @@ -587,6 +604,8 @@ @VisibleForTesting native void nativeGetAllPages(long nativeOfflinePageBridge, List<OfflinePageItem> offlinePages, final MultipleOfflinePageItemCallback callback); + private native void nativeCheckPagesExistOffline(long nativeOfflinePageBridge, Object[] urls, + CheckPagesExistOfflineCallbackInternal callback); native void nativeHasPages( long nativeOfflinePageBridge, String nameSpace, final HasPagesCallback callback);
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/preferences/MainPreferences.java b/chrome/android/java/src/org/chromium/chrome/browser/preferences/MainPreferences.java index c582536..5514860 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/preferences/MainPreferences.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/preferences/MainPreferences.java
@@ -4,7 +4,6 @@ package org.chromium.chrome.browser.preferences; -import android.content.Intent; import android.os.Bundle; import android.os.Handler; import android.preference.Preference; @@ -140,8 +139,8 @@ } mSignInPreference.setEnabled(false); - SigninManager.logSigninStartAccessPoint(SigninAccessPoint.SETTINGS); - startActivity(new Intent(getActivity(), AccountSigninActivity.class)); + AccountSigninActivity + .startAccountSigninActivity(getActivity(), SigninAccessPoint.SETTINGS); return true; } });
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/signin/AccountListAdapter.java b/chrome/android/java/src/org/chromium/chrome/browser/signin/AccountListAdapter.java deleted file mode 100644 index bf8e5893..0000000 --- a/chrome/android/java/src/org/chromium/chrome/browser/signin/AccountListAdapter.java +++ /dev/null
@@ -1,73 +0,0 @@ -// Copyright 2016 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.chrome.browser.signin; - -import android.content.Context; -import android.view.LayoutInflater; -import android.view.View; -import android.view.ViewGroup; -import android.widget.ArrayAdapter; -import android.widget.ImageView; -import android.widget.TextView; - -import org.chromium.chrome.R; -import org.chromium.chrome.browser.firstrun.ProfileDataCache; - -/** -* Adapter for AccountListView. It associates an array of account names on the device and -* provides account views of these accounts. -*/ -public class AccountListAdapter extends ArrayAdapter<String> { - private final LayoutInflater mInflater; - private final ProfileDataCache mProfileData; - private int mSelectedAccountPosition = 0; - - public AccountListAdapter(Context context, ProfileDataCache profileData) { - super(context, 0); - mInflater = LayoutInflater.from(context); - mProfileData = profileData; - } - - @Override - public View getView(int position, View convertView, ViewGroup parent) { - View view = convertView; - if (view == null) { - view = mInflater.inflate(R.layout.account_signin_account_view, parent, false); - } - - // Sets account profile image, name and selection status. - String accountName = getItem(position); - ImageView accountImage = (ImageView) view.findViewById(R.id.account_image); - // The view at the last position is the "Add account" view. - if (position == getCount() - 1) { - accountImage.setImageResource(R.drawable.add_circle_blue); - } else { - accountImage.setImageBitmap(mProfileData.getImage(accountName)); - } - ((TextView) view.findViewById(R.id.account_name)).setText(accountName); - if (position == mSelectedAccountPosition) { - view.findViewById(R.id.account_selection_mark).setVisibility(View.VISIBLE); - } else { - view.findViewById(R.id.account_selection_mark).setVisibility(View.GONE); - } - - return view; - } - - /** - * Sets selected account position. - * @param position Position in the collection of the associated items. - */ - public void setSelectedAccountPosition(int position) { - mSelectedAccountPosition = position; - } - - /** - * Gets selected account position. - */ - public int getSelectedAccountPosition() { - return mSelectedAccountPosition; - } -}
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/signin/AccountListView.java b/chrome/android/java/src/org/chromium/chrome/browser/signin/AccountListView.java deleted file mode 100644 index 1740da5c..0000000 --- a/chrome/android/java/src/org/chromium/chrome/browser/signin/AccountListView.java +++ /dev/null
@@ -1,24 +0,0 @@ -// Copyright 2016 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.chrome.browser.signin; - -import android.content.Context; -import android.util.AttributeSet; -import android.widget.ListView; - -/** -* ListView to list accounts on device. -*/ -public class AccountListView extends ListView { - public AccountListView(Context context, AttributeSet attrs) { - super(context, attrs); - } - - @Override - protected float getTopFadingEdgeStrength() { - // Disable fading out effect at the top of this ListView. - return 0; - } -}
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/signin/AccountSigninActivity.java b/chrome/android/java/src/org/chromium/chrome/browser/signin/AccountSigninActivity.java index 7d44cb1..21acd8c 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/signin/AccountSigninActivity.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/signin/AccountSigninActivity.java
@@ -4,8 +4,10 @@ package org.chromium.chrome.browser.signin; +import android.content.Context; import android.content.Intent; import android.os.Bundle; +import android.support.annotation.IntDef; import android.support.v7.app.AppCompatActivity; import android.view.LayoutInflater; @@ -18,22 +20,40 @@ import org.chromium.chrome.browser.init.ChromeBrowserInitializer; import org.chromium.chrome.browser.preferences.PreferencesLauncher; import org.chromium.chrome.browser.profiles.Profile; +import org.chromium.chrome.browser.signin.SigninManager.SignInCallback; + +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; /** * An Activity displayed from the MainPreferences to allow the user to pick an account to * sign in to. The AccountSigninView.Delegate interface is fulfilled by the AppCompatActivity. */ public class AccountSigninActivity extends AppCompatActivity - implements AccountSigninView.Listener, AccountSigninView.Delegate, - SigninManager.SignInCallback{ - private static final String TAG = "SigninActivity"; - - private static final String CONFIRM_IMPORT_SYNC_DATA_DIALOG_TAG = - "signin_import_data_tag"; + implements AccountSigninView.Listener, AccountSigninView.Delegate { + private static final String TAG = "AccountSigninActivity"; + private static final String INTENT_SIGNIN_ACCESS_POINT = + "AccountSigninActivity.SigninAccessPoint"; private AccountSigninView mView; - private String mAccountName; - private boolean mShowSigninSettings = false; + private ProfileDataCache mProfileDataCache; + + @IntDef({SigninAccessPoint.SETTINGS, SigninAccessPoint.BOOKMARK_MANAGER, + SigninAccessPoint.RECENT_TABS}) + @Retention(RetentionPolicy.SOURCE) + public @interface AccessPoint {} + @AccessPoint private int mAccessPoint; + + /** + * A convenience method to create a AccountSigninActivity passing the access point as an + * intent. + * @param accessPoint - A SigninAccessPoint designating where the activity is created from. + */ + public static void startAccountSigninActivity(Context context, @AccessPoint int accessPoint) { + Intent intent = new Intent(context, AccountSigninActivity.class); + intent.putExtra(INTENT_SIGNIN_ACCESS_POINT, accessPoint); + context.startActivity(intent); + } @Override @SuppressFBWarnings("DM_EXIT") @@ -52,52 +72,101 @@ // We don't trust android to restore the saved state correctly, so pass null. super.onCreate(null); + mAccessPoint = getIntent().getIntExtra(INTENT_SIGNIN_ACCESS_POINT, -1); + assert mAccessPoint == SigninAccessPoint.BOOKMARK_MANAGER + || mAccessPoint == SigninAccessPoint.RECENT_TABS + || mAccessPoint == SigninAccessPoint.SETTINGS : "invalid access point"; + + if (savedInstanceState == null && getAccessPoint() == SigninAccessPoint.BOOKMARK_MANAGER) { + RecordUserAction.record("Stars_SignInPromoActivity_Launched"); + } + mView = (AccountSigninView) LayoutInflater.from(this).inflate( R.layout.account_signin_view, null); - mView.init(new ProfileDataCache(this, Profile.getLastUsedProfile())); + mView.init(getProfileDataCache()); mView.setListener(this); mView.setDelegate(this); + if (getAccessPoint() == SigninAccessPoint.BOOKMARK_MANAGER + || getAccessPoint() == SigninAccessPoint.RECENT_TABS) { + mView.configureForRecentTabsOrBookmarksPage(); + } + + SigninManager.logSigninStartAccessPoint(getAccessPoint()); + setContentView(mView); } @Override + public void onDestroy() { + super.onDestroy(); + + if (mProfileDataCache != null) { + mProfileDataCache.destroy(); + mProfileDataCache = null; + } + } + + private ProfileDataCache getProfileDataCache() { + if (mProfileDataCache == null) { + mProfileDataCache = new ProfileDataCache(this, Profile.getLastUsedProfile()); + } + return mProfileDataCache; + } + + @AccessPoint private int getAccessPoint() { + return mAccessPoint; + } + + @Override public void onAccountSelectionCanceled() { finish(); } @Override public void onNewAccount() { + if (getAccessPoint() == SigninAccessPoint.BOOKMARK_MANAGER) { + RecordUserAction.record("Stars_SignInPromoActivity_NewAccount"); + } + AccountAdder.getInstance().addAccount(this, AccountAdder.ADD_ACCOUNT_RESULT); } @Override - public void onAccountSelected(String accountName, boolean settingsClicked) { - mShowSigninSettings = settingsClicked; - mAccountName = accountName; - RecordUserAction.record("Signin_Signin_FromSettings"); - SigninManager.get(this).signIn(accountName, this, this); - } - - @Override - public void onFailedToSetForcedAccount(String forcedAccountName) { - assert false : "No forced accounts in account switching preferences."; - - } - - @Override - public void onSignInComplete() { - if (mShowSigninSettings) { - Intent intent = PreferencesLauncher.createIntentForSettingsPage( - this, AccountManagementFragment.class.getName()); - startActivity(intent); + public void onAccountSelected(final String accountName, final boolean settingsClicked) { + switch (getAccessPoint()) { + case SigninAccessPoint.BOOKMARK_MANAGER: + RecordUserAction.record("Stars_SignInPromoActivity_SignedIn"); + RecordUserAction.record("Signin_Signin_FromBookmarkManager"); + break; + case SigninAccessPoint.RECENT_TABS: + RecordUserAction.record("Signin_Signin_FromRecentTabs"); + break; + case SigninAccessPoint.SETTINGS: + RecordUserAction.record("Signin_Signin_FromSettings"); + break; + default: } - finish(); + final Context context = this; + SigninManager.get(this).signIn(accountName, this, new SignInCallback(){ + + @Override + public void onSignInComplete() { + if (settingsClicked) { + Intent intent = PreferencesLauncher.createIntentForSettingsPage( + context, AccountManagementFragment.class.getName()); + startActivity(intent); + } + + finish(); + } + + @Override + public void onSignInAborted() {} + }); } @Override - public void onSignInAborted() { - assert false : "Signin cannot be aborted when forced."; - } + public void onFailedToSetForcedAccount(String forcedAccountName) {} }
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/signin/AccountSigninChooseView.java b/chrome/android/java/src/org/chromium/chrome/browser/signin/AccountSigninChooseView.java new file mode 100644 index 0000000..dc6f53f --- /dev/null +++ b/chrome/android/java/src/org/chromium/chrome/browser/signin/AccountSigninChooseView.java
@@ -0,0 +1,181 @@ +// Copyright 2016 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.chrome.browser.signin; + +import android.content.Context; +import android.util.AttributeSet; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.widget.ImageView; +import android.widget.LinearLayout; +import android.widget.ScrollView; +import android.widget.TextView; + +import org.chromium.chrome.R; +import org.chromium.chrome.browser.firstrun.ProfileDataCache; + +import java.util.List; + +/** +* The view that allows the user to choose the sign in account. +*/ +public class AccountSigninChooseView extends ScrollView { + private final LayoutInflater mInflater; + private LinearLayout mRootChildView; + private int mAccountViewStartIndex; + private int mSelectedAccountPosition; + private Observer mObserver; + + /** + * Add new account observer. + */ + public interface Observer { + /** + * On add new account clicked. + */ + void onAddNewAccount(); + } + + public AccountSigninChooseView(Context context, AttributeSet attrs) { + super(context, attrs); + mInflater = LayoutInflater.from(context); + } + + @Override + protected void onFinishInflate() { + super.onFinishInflate(); + mRootChildView = + (LinearLayout) findViewById(R.id.account_signin_choose_view_root_child_view); + mAccountViewStartIndex = mRootChildView.getChildCount(); + } + + @Override + protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { + // This assumes that view's layout_width and layout_height are set to match_parent. + assert MeasureSpec.getMode(widthMeasureSpec) == MeasureSpec.EXACTLY; + assert MeasureSpec.getMode(heightMeasureSpec) == MeasureSpec.EXACTLY; + + int width = MeasureSpec.getSize(widthMeasureSpec); + int height = MeasureSpec.getSize(heightMeasureSpec); + + View title = findViewById(R.id.signin_title); + ViewGroup.LayoutParams params = title.getLayoutParams(); + if (height > width) { + // Sets the title aspect ratio to be 16:9. + params.height = width * 9 / 16; + title.setPadding( + title.getPaddingLeft(), 0, title.getPaddingRight(), title.getPaddingBottom()); + } else { + params.height = ViewGroup.LayoutParams.WRAP_CONTENT; + + // Adds top padding. + title.setPadding(title.getPaddingLeft(), + getResources().getDimensionPixelOffset(R.dimen.signin_screen_top_padding), + title.getPaddingRight(), title.getPaddingBottom()); + } + title.setLayoutParams(params); + + super.onMeasure(widthMeasureSpec, heightMeasureSpec); + } + + @Override + protected float getTopFadingEdgeStrength() { + // Disable fading out effect at the top of this ScrollView. + return 0; + } + + /** + * Updates candidate accounts to sign in. + * + * @param accounts The candidate accounts. + * @param accountToSelect The index of the default selected account to sign in. + * @param profileData The ProfileDataCache contains accounts' info. + */ + public void updateAccounts( + List<String> accounts, int accountToSelect, ProfileDataCache profileData) { + mRootChildView.removeViews( + mAccountViewStartIndex, mRootChildView.getChildCount() - mAccountViewStartIndex); + if (accounts.isEmpty()) return; + + // Add accounts view. + for (int i = 0; i < accounts.size(); i++) { + View view = + mInflater.inflate(R.layout.account_signin_account_view, mRootChildView, false); + + // Sets account profile image and name. + String accountName = accounts.get(i); + ((ImageView) view.findViewById(R.id.account_image)) + .setImageBitmap(profileData.getImage(accountName)); + ((TextView) view.findViewById(R.id.account_name)).setText(accountName); + + view.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + v.findViewById(R.id.account_selection_mark).setVisibility(View.VISIBLE); + mRootChildView.getChildAt(mSelectedAccountPosition + mAccountViewStartIndex) + .findViewById(R.id.account_selection_mark) + .setVisibility(View.GONE); + mSelectedAccountPosition = + mRootChildView.indexOfChild(v) - mAccountViewStartIndex; + } + }); + + mRootChildView.addView(view); + } + + // The view at the last position is the "Add account" view. + View view = mInflater.inflate(R.layout.account_signin_account_view, mRootChildView, false); + ((ImageView) view.findViewById(R.id.account_image)) + .setImageResource(R.drawable.add_circle_blue); + ((TextView) view.findViewById(R.id.account_name)) + .setText(getResources().getString(R.string.signin_add_account)); + view.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + if (mObserver != null) mObserver.onAddNewAccount(); + } + }); + mRootChildView.addView(view); + + // Sets the default selected account selection status. + mRootChildView.getChildAt(accountToSelect + mAccountViewStartIndex) + .findViewById(R.id.account_selection_mark) + .setVisibility(View.VISIBLE); + mSelectedAccountPosition = accountToSelect; + } + + /** + * Updates candidate accounts' profile image. + * + * @param profileData The ProfileDataCache contains accounts' profile image. + */ + public void updateAccountProfileImages(ProfileDataCache profileData) { + // Do not update the last "Add account" view. + for (int i = mAccountViewStartIndex; i < mRootChildView.getChildCount() - 1; i++) { + View view = mRootChildView.getChildAt(i); + String accountEmail = + ((TextView) view.findViewById(R.id.account_name)).getText().toString(); + ((ImageView) view.findViewById(R.id.account_image)) + .setImageBitmap(profileData.getImage(accountEmail)); + } + } + + /** + * Sets add new account observer. See {@link Observer} + * + * @param observer The observer. + */ + public void setAddNewAccountObserver(Observer observer) { + mObserver = observer; + } + + /** + * Gets selected account position. + */ + public int getSelectedAccountPosition() { + return mSelectedAccountPosition; + } +}
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/signin/AccountSigninConfirmationView.java b/chrome/android/java/src/org/chromium/chrome/browser/signin/AccountSigninConfirmationView.java index 8ad1a51..ea87232 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/signin/AccountSigninConfirmationView.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/signin/AccountSigninConfirmationView.java
@@ -6,6 +6,7 @@ import android.content.Context; import android.util.AttributeSet; +import android.view.View; import android.widget.LinearLayout; import android.widget.RelativeLayout; import android.widget.ScrollView; @@ -42,15 +43,25 @@ int width = MeasureSpec.getSize(widthMeasureSpec); int height = MeasureSpec.getSize(heightMeasureSpec); - // Sets aspect ratio of the head to 16:9. + View head = findViewById(R.id.signin_confirmation_head); + RelativeLayout.LayoutParams headLayoutParams = + (RelativeLayout.LayoutParams) head.getLayoutParams(); + View accountImage = findViewById(R.id.signin_account_image); + LinearLayout.LayoutParams accountImageLayoutParams = + (LinearLayout.LayoutParams) accountImage.getLayoutParams(); if (height > width) { - LinearLayout layout = (LinearLayout) findViewById(R.id.signin_confirmation_head); - RelativeLayout.LayoutParams params = - (RelativeLayout.LayoutParams) layout.getLayoutParams(); - params.height = width * 9 / 16; - params.width = LayoutParams.MATCH_PARENT; - layout.setLayoutParams(params); + // Sets aspect ratio of the head to 16:9. + headLayoutParams.height = width * 9 / 16; + accountImageLayoutParams.topMargin = 0; + } else { + headLayoutParams.height = LayoutParams.WRAP_CONTENT; + + // Adds top margin. + accountImageLayoutParams.topMargin = + getResources().getDimensionPixelOffset(R.dimen.signin_screen_top_padding); } + head.setLayoutParams(headLayoutParams); + accountImage.setLayoutParams(accountImageLayoutParams); super.onMeasure(widthMeasureSpec, heightMeasureSpec); }
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/signin/AccountSigninView.java b/chrome/android/java/src/org/chromium/chrome/browser/signin/AccountSigninView.java index d8f70472..8b5c902 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/signin/AccountSigninView.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/signin/AccountSigninView.java
@@ -10,14 +10,10 @@ import android.text.TextUtils; import android.text.method.LinkMovementMethod; import android.util.AttributeSet; -import android.view.LayoutInflater; -import android.view.MotionEvent; import android.view.View; -import android.widget.AdapterView; import android.widget.Button; import android.widget.FrameLayout; import android.widget.ImageView; -import android.widget.ListView; import android.widget.TextView; import org.chromium.base.ApiCompatibilityUtils; @@ -39,7 +35,6 @@ import java.util.List; -// TODO(gogerald): add landscape mode (http://crbug.com/599139). // TODO(gogerald): refactor common part into one place after redesign all sign in screens. /** @@ -49,8 +44,7 @@ * {@link AccountSigninView#setDelegate(Delegate)} after the view has been inflated. */ -public class AccountSigninView - extends FrameLayout implements AdapterView.OnItemClickListener, ProfileDownloader.Observer { +public class AccountSigninView extends FrameLayout implements ProfileDownloader.Observer { /** * Callbacks for various account selection events. */ @@ -99,12 +93,9 @@ private AccountManagerHelper mAccountManagerHelper; private List<String> mAccountNames; - private View mSigninView; - private AccountListAdapter mAccountListAdapter; - private ListView mAccountListView; + private AccountSigninChooseView mSigninChooseView; private ButtonCompat mPositiveButton; private Button mNegativeButton; - private TextView mTitle; private Listener mListener; private Delegate mDelegate; private String mForcedAccountName; @@ -112,7 +103,6 @@ private boolean mSignedIn; private int mCancelButtonTextId; private boolean mIsChildAccount; - private boolean mShowSettingsSpan = true; private AccountSigninConfirmationView mSigninConfirmationView; private ImageView mSigninAccountImage; @@ -132,8 +122,6 @@ public void init(ProfileDataCache profileData) { mProfileData = profileData; mProfileData.setObserver(this); - mAccountListAdapter = new AccountListAdapter(getContext(), profileData); - mAccountListView.setAdapter(mAccountListAdapter); showSigninPage(); } @@ -141,41 +129,12 @@ protected void onFinishInflate() { super.onFinishInflate(); - mSigninView = findViewById(R.id.signin_choose_account_view); - - mTitle = (TextView) findViewById(R.id.signin_title); - - mAccountListView = (ListView) findViewById(R.id.signin_account_list); - mAccountListView.setOnItemClickListener(this); - View signinChoiceDescription = - LayoutInflater.from(getContext()) - .inflate(R.layout.account_signin_choice_description_view, null, false); - signinChoiceDescription.setOnClickListener(null); - mAccountListView.addHeaderView(signinChoiceDescription); - - // Once the user has touched this ListView, prevent the parent view from handling touch - // events. This allows the ListView to behave reasonably when nested inside a ListView. - // TODO(gogerald): Remove this listener after https://crbug.com/583774 has been fixed. - mAccountListView.setOnTouchListener(new ListView.OnTouchListener() { + mSigninChooseView = (AccountSigninChooseView) findViewById(R.id.account_signin_choose_view); + mSigninChooseView.setAddNewAccountObserver(new AccountSigninChooseView.Observer() { @Override - public boolean onTouch(View view, MotionEvent event) { - int action = event.getAction(); - switch (action) { - case MotionEvent.ACTION_DOWN: - view.getParent().requestDisallowInterceptTouchEvent(true); - break; - - case MotionEvent.ACTION_UP: - view.performClick(); - view.getParent().requestDisallowInterceptTouchEvent(false); - break; - default: - // Ignore. - break; - } - - view.onTouchEvent(event); - return true; + public void onAddNewAccount() { + mListener.onNewAccount(); + RecordUserAction.record("Signin_AddAccountToDevice"); } }); @@ -210,23 +169,6 @@ } @Override - protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { - // This assumes that view's layout_width and layout_height are set to match_parent. - assert MeasureSpec.getMode(widthMeasureSpec) == MeasureSpec.EXACTLY; - assert MeasureSpec.getMode(heightMeasureSpec) == MeasureSpec.EXACTLY; - - int width = MeasureSpec.getSize(widthMeasureSpec); - int height = MeasureSpec.getSize(heightMeasureSpec); - - // Sets title aspect ratio to be 16:9. - if (height > width) { - mTitle.setHeight(width * 9 / 16); - } - - super.onMeasure(widthMeasureSpec, heightMeasureSpec); - } - - @Override protected void onAttachedToWindow() { super.onAttachedToWindow(); updateAccounts(); @@ -251,8 +193,6 @@ * This is currently used in the Recent Tabs Promo and the bookmarks page. */ public void configureForRecentTabsOrBookmarksPage() { - mShowSettingsSpan = false; - setBackgroundResource(R.color.ntp_bg); mCancelButtonTextId = R.string.cancel; setUpCancelButton(); @@ -303,24 +243,18 @@ return false; } } else { - accountToSelect = getIndexOfNewElement(oldAccountNames, mAccountNames, - mAccountListAdapter.getSelectedAccountPosition()); + accountToSelect = getIndexOfNewElement( + oldAccountNames, mAccountNames, mSigninChooseView.getSelectedAccountPosition()); } - mAccountListAdapter.clear(); + mSigninChooseView.updateAccounts(mAccountNames, accountToSelect, mProfileData); if (!mAccountNames.isEmpty()) { - mAccountListAdapter.addAll(mAccountNames); - mAccountListAdapter.add(getResources().getString(R.string.signin_add_account)); - setUpSigninButton(true); } else { setUpSigninButton(false); } mProfileData.update(); - updateProfileImages(); - - selectAccount(accountToSelect); return oldAccountNames != null && !(oldAccountNames.size() == mAccountNames.size() @@ -352,13 +286,7 @@ @Override public void onProfileDownloaded(String accountId, String fullName, String givenName, Bitmap bitmap) { - updateProfileImages(); - } - - private void updateProfileImages() { - if (mProfileData == null) return; - - mAccountListAdapter.notifyDataSetChanged(); + mSigninChooseView.updateAccountProfileImages(mProfileData); if (mSignedIn) updateSignedInAccountInfo(); } @@ -389,7 +317,7 @@ mSignedIn = false; mSigninConfirmationView.setVisibility(View.GONE); - mSigninView.setVisibility(View.VISIBLE); + mSigninChooseView.setVisibility(View.VISIBLE); setUpCancelButton(); updateAccounts(); @@ -400,7 +328,7 @@ updateSignedInAccountInfo(); - mSigninView.setVisibility(View.GONE); + mSigninChooseView.setVisibility(View.GONE); mSigninConfirmationView.setVisibility(View.VISIBLE); setButtonsEnabled(true); @@ -408,22 +336,15 @@ setPositiveButtonDisabled(); setUpUndoButton(); - if (mShowSettingsSpan) { - NoUnderlineClickableSpan settingsSpan = new NoUnderlineClickableSpan() { - @Override - public void onClick(View widget) { - mListener.onAccountSelected(getSelectedAccountName(), true); - } - }; - mSigninSettingsControl.setText( - SpanApplier.applySpans(getSettingsControlDescription(mIsChildAccount), - new SpanInfo(SETTINGS_LINK_OPEN, SETTINGS_LINK_CLOSE, settingsSpan))); - } else { - // If we aren't showing the span, get rid of the LINK1 annotations. - mSigninSettingsControl.setText(getSettingsControlDescription(mIsChildAccount) - .replace(SETTINGS_LINK_OPEN, "") - .replace(SETTINGS_LINK_CLOSE, "")); - } + NoUnderlineClickableSpan settingsSpan = new NoUnderlineClickableSpan() { + @Override + public void onClick(View widget) { + mListener.onAccountSelected(getSelectedAccountName(), true); + } + }; + mSigninSettingsControl.setText( + SpanApplier.applySpans(getSettingsControlDescription(mIsChildAccount), + new SpanInfo(SETTINGS_LINK_OPEN, SETTINGS_LINK_CLOSE, settingsSpan))); } private void showConfirmSigninPageAccountTrackerServiceCheck() { @@ -592,23 +513,6 @@ return mForcedAccountName != null; } - // Overrides AdapterView.OnItemClickListener. - @Override - public void onItemClick(AdapterView<?> adapter, View view, int position, long id) { - int positionInAccountListAdapter = position - mAccountListView.getHeaderViewsCount(); - if (positionInAccountListAdapter == mAccountListAdapter.getCount() - 1) { - mListener.onNewAccount(); - RecordUserAction.record("Signin_AddAccountToDevice"); - } else { - selectAccount(positionInAccountListAdapter); - } - } - - private void selectAccount(int position) { - mAccountListAdapter.setSelectedAccountPosition(position); - mAccountListAdapter.notifyDataSetChanged(); - } - private void setPositiveButtonEnabled() { mPositiveButton.setButtonColor( ApiCompatibilityUtils.getColor(getResources(), R.color.light_active_color)); @@ -628,6 +532,6 @@ } private String getSelectedAccountName() { - return mAccountNames.get(mAccountListAdapter.getSelectedAccountPosition()); + return mAccountNames.get(mSigninChooseView.getSelectedAccountPosition()); } }
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/signin/SigninAndSyncView.java b/chrome/android/java/src/org/chromium/chrome/browser/signin/SigninAndSyncView.java new file mode 100644 index 0000000..65cb6e9d --- /dev/null +++ b/chrome/android/java/src/org/chromium/chrome/browser/signin/SigninAndSyncView.java
@@ -0,0 +1,265 @@ +// Copyright 2016 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.chrome.browser.signin; + +import android.content.Context; +import android.content.Intent; +import android.provider.Settings; +import android.view.LayoutInflater; +import android.view.View; +import android.widget.Button; +import android.widget.FrameLayout; +import android.widget.TextView; + +import org.chromium.chrome.R; +import org.chromium.chrome.browser.preferences.PreferencesLauncher; +import org.chromium.chrome.browser.signin.AccountSigninActivity.AccessPoint; +import org.chromium.chrome.browser.signin.SigninManager.SignInStateObserver; +import org.chromium.chrome.browser.sync.ui.SyncCustomizationFragment; +import org.chromium.sync.AndroidSyncSettings; +import org.chromium.sync.AndroidSyncSettings.AndroidSyncSettingsObserver; +import org.chromium.sync.signin.ChromeSigninController; + +/** + * A View that shows the user the next step they must complete to start syncing their data (eg. + * Recent Tabs or Bookmarks). For example, if the user is not signed in, the View will prompt them + * to do so and link to the AccountSigninActivity. + */ +public class SigninAndSyncView extends FrameLayout + implements AndroidSyncSettingsObserver, SignInStateObserver { + private static final String TAG = "SigninAndSyncView"; + private final Listener mListener; + private final int mAccessPoint; + @AccessPoint private final SigninManager mSigninManager; + + private final TextView mTitle; + private final TextView mDescription; + private final Button mNegativeButton; + private final Button mPositiveButton; + + /** + * A listener for the container of the SigninAndSyncView to be informed of certain user + * interactions. + */ + public interface Listener { + /** + * The user has pressed 'no thanks' and expects the view to be removed from its parent. + */ + public void onViewDismissed(); + } + + /** + * Constructor for use from Java. + */ + public SigninAndSyncView(Context context, Listener listener, @AccessPoint int accessPoint) { + // TODO(peconn): Simplify BookmarkPromoHeader + super(context); + mListener = listener; + mAccessPoint = accessPoint; + + assert mAccessPoint == SigninAccessPoint.BOOKMARK_MANAGER + || mAccessPoint == SigninAccessPoint.RECENT_TABS + : "SigninAndSyncView only has strings for bookmark manager and recent tabs."; + + mSigninManager = SigninManager.get(getContext()); + + addView(LayoutInflater.from(getContext()) + .inflate(R.layout.signin_and_sync_view, this, false)); + + mTitle = (TextView) findViewById(R.id.title); + mDescription = (TextView) findViewById(R.id.description); + mNegativeButton = (Button) findViewById(R.id.no_thanks); + mPositiveButton = (Button) findViewById(R.id.sign_in); + + // The title stays the same no matter what action the user must take. + if (mAccessPoint == SigninAccessPoint.BOOKMARK_MANAGER) { + mTitle.setText(R.string.sync_your_bookmarks); + } else { + mTitle.setVisibility(View.GONE); + } + + // We don't need to call update() here as it will be called in onAttachedToWindow(). + } + + private void update() { + ViewState viewState; + if (!ChromeSigninController.get(getContext()).isSignedIn()) { + viewState = getStateForSignin(); + } else if (!AndroidSyncSettings.isMasterSyncEnabled(getContext())) { + viewState = getStateForEnableAndroidSync(); + } else if (!AndroidSyncSettings.isChromeSyncEnabled(getContext())) { + viewState = getStateForEnableChromeSync(); + } else { + viewState = getStateForStartUsing(); + } + viewState.apply(mDescription, mPositiveButton, mNegativeButton); + } + + /** + * The ViewState class represents all the UI elements that can change for each variation of + * this View. We use this to ensure each variation (created in the getStateFor* methods) + * explicitly touches each UI element. + */ + private static class ViewState { + private final int mDescriptionText; + private final ButtonState mPositiveButtonState; + private final ButtonState mNegativeButtonState; + + public ViewState(int mDescriptionText, + ButtonState mPositiveButtonState, ButtonState mNegativeButtonState) { + this.mDescriptionText = mDescriptionText; + this.mPositiveButtonState = mPositiveButtonState; + this.mNegativeButtonState = mNegativeButtonState; + } + + public void apply(TextView description, Button positiveButton, Button negativeButton) { + description.setText(mDescriptionText); + mNegativeButtonState.apply(negativeButton); + mPositiveButtonState.apply(positiveButton); + } + } + + /** + * Classes to represent the state of a button that we are interested in, used to keep ViewState + * tidy and provide some convenience methods. + */ + private abstract static class ButtonState { + public abstract void apply(Button button); + } + + private static class ButtonAbsent extends ButtonState { + @Override + public void apply(Button button) { + button.setVisibility(View.GONE); + } + } + + private static class ButtonPresent extends ButtonState { + private final int mTextResource; + private final OnClickListener mOnClickListener; + + public ButtonPresent(int textResource, OnClickListener onClickListener) { + mTextResource = textResource; + mOnClickListener = onClickListener; + } + + @Override + public void apply(Button button) { + button.setVisibility(View.VISIBLE); + button.setText(mTextResource); + button.setOnClickListener(mOnClickListener); + } + } + + private ViewState getStateForSignin() { + int descId = mAccessPoint == SigninAccessPoint.BOOKMARK_MANAGER + ? R.string.bookmark_sign_in_promo_description + : R.string.recent_tabs_sign_in_promo_description; + + ButtonState positiveButton = new ButtonPresent( + R.string.sign_in_button, + new OnClickListener() { + @Override + public void onClick(View view) { + AccountSigninActivity + .startAccountSigninActivity(getContext(), mAccessPoint); + } + }); + + ButtonState negativeButton; + if (mAccessPoint == SigninAccessPoint.RECENT_TABS) { + negativeButton = new ButtonAbsent(); + } else { + negativeButton = new ButtonPresent(R.string.no_thanks, new OnClickListener() { + @Override + public void onClick(View view) { + mListener.onViewDismissed(); + } + }); + } + + return new ViewState(descId, positiveButton, negativeButton); + } + + private ViewState getStateForEnableAndroidSync() { + assert mAccessPoint == SigninAccessPoint.RECENT_TABS + : "Enable Android Sync should not be showing from bookmarks"; + + int descId = R.string.recent_tabs_sync_promo_enable_android_sync; + + ButtonState positiveButton = new ButtonPresent( + R.string.open_settings_button, + new OnClickListener() { + @Override + public void onClick(View v) { + // TODO(crbug.com/557784): Like AccountManagementFragment, this would also + // benefit from going directly to an account. + Intent intent = new Intent(Settings.ACTION_SYNC_SETTINGS); + intent.putExtra(Settings.EXTRA_ACCOUNT_TYPES, new String[] {"com.google"}); + getContext().startActivity(intent); + } + }); + + return new ViewState(descId, positiveButton, new ButtonAbsent()); + } + + private ViewState getStateForEnableChromeSync() { + int descId = mAccessPoint == SigninAccessPoint.BOOKMARK_MANAGER + ? R.string.bookmarks_sync_promo_enable_sync + : R.string.recent_tabs_sync_promo_enable_chrome_sync; + + ButtonState positiveButton = new ButtonPresent( + R.string.enable_sync_button, + new OnClickListener() { + @Override + public void onClick(View v) { + PreferencesLauncher.launchSettingsPage(getContext(), + SyncCustomizationFragment.class.getName()); + } + }); + + return new ViewState(descId, positiveButton, new ButtonAbsent()); + } + + private ViewState getStateForStartUsing() { + assert mAccessPoint == SigninAccessPoint.RECENT_TABS + : "This should not be showing from bookmarks"; + + return new ViewState(R.string.ntp_recent_tabs_sync_promo_instructions, + new ButtonAbsent(), new ButtonAbsent()); + } + + @Override + protected void onAttachedToWindow() { + super.onAttachedToWindow(); + mSigninManager.addSignInStateObserver(this); + AndroidSyncSettings.registerObserver(getContext(), this); + update(); + } + + @Override + protected void onDetachedFromWindow() { + super.onDetachedFromWindow(); + mSigninManager.removeSignInStateObserver(this); + AndroidSyncSettings.unregisterObserver(getContext(), this); + } + + // SigninStateObserver + @Override + public void onSignedIn() { + update(); + } + + @Override + public void onSignedOut() { + update(); + } + + // AndroidSyncStateObserver + @Override + public void androidSyncSettingsChanged() { + update(); + } +} \ No newline at end of file
diff --git a/chrome/android/java/strings/android_chrome_strings.grd b/chrome/android/java/strings/android_chrome_strings.grd index d6020c75..0e08bc2 100644 --- a/chrome/android/java/strings/android_chrome_strings.grd +++ b/chrome/android/java/strings/android_chrome_strings.grd
@@ -988,8 +988,39 @@ <message name="IDS_SIGNOUT_DIALOG_POSITIVE_BUTTON" desc="Button to sign out of Chrome"> Sign out </message> + <message name="IDS_SIGN_IN_BUTTON" desc="Label for a button to sign in"> + Sign in + </message> <!-- Sync strings --> + <message name="IDS_SYNC_YOUR_BOOKMARKS" desc="Title for the prompt to signin and enable sync to sync their bookmarks"> + Sync your bookmarks + </message> + <message name="IDS_BOOKMARK_SIGN_IN_PROMO_DESCRIPTION" desc="Description for bookmark UI sign-in promotion."> + To get your bookmarks on all your devices, sign in to Chrome + </message> + <message name="IDS_RECENT_TABS_SIGN_IN_PROMO_DESCRIPTION" desc="Description for recent tabs UI sign-in promotion."> + To get your tabs from all your devices, sign in to Chrome + </message> + <message name="IDS_ENABLE_SYNC_BUTTON" desc="Text that displayed or button that allows the user to open Chrome settings to enable sync."> + Open settings + </message> + <message name="IDS_OPEN_SETTINGS_BUTTON" desc="Text that displayed or button that allows the open Android settings to enable sync."> + Open settings + </message> + <message name="IDS_BOOKMARKS_SYNC_PROMO_ENABLE_SYNC" desc="Text that displayed in a textview encouraging the user to enable sync."> + Bookmarks saved on your other devices will appear here + </message> + <message name="IDS_RECENT_TABS_SYNC_PROMO_ENABLE_CHROME_SYNC" desc="Text that displayed in a textview encouraging the user to enable sync."> + To get your tabs from all your devices, turn on sync + </message> + <message name="IDS_RECENT_TABS_SYNC_PROMO_ENABLE_ANDROID_SYNC" desc="Text that displayed in a textview encouraging the user to enable sync in the android settings."> + To get your tabs from all your devices, turn on "Auto-sync data" in Android account setting + </message> + <message name="IDS_NTP_RECENT_TABS_SYNC_PROMO_INSTRUCTIONS" desc="Information about sync displayed on the NTP when the user has signed in on mobile but not on desktop"> + Tabs that you've opened in Chrome on your other devices will appear here + </message> + <message name="IDS_SIGN_IN_SYNC" desc="Sync preference title in signed-in prefs and prefix for notification related to sync [CHAR-LIMIT=32]"> Sync </message> @@ -1790,17 +1821,6 @@ <message name="IDS_NTP_RECENT_TABS_SYNC_PROMO_TITLE" desc="Header for the promo explaining how users can see the list of tabs open on their other devices"> Other devices </message> - <message name="IDS_NTP_RECENT_TABS_SYNC_PROMO_INSTRUCTIONS" desc="Information about sync displayed on the NTP when the user has signed in on mobile but not on desktop"> - Access the tabs you have open on your computer, right here. - -Just open Chrome on your computer, go to the menu, and select “Sign in to Chrome…” - </message> - <message name="IDS_NTP_RECENT_TABS_SYNC_ENABLE_SYNC" desc="Text that displayed in a textview encouraging the user to enable sync."> - Tabs you have opened in Chrome on your other devices will appear here. - </message> - <message name="IDS_NTP_RECENT_TABS_SYNC_ENABLE_SYNC_BUTTON" desc="Text that displayed or button that allows the user to enable sync."> - Enable sync - </message> <message name="IDS_NTP_RECENT_TABS_LAST_SYNCED" desc="Label for the time since a device was last synced"> Last synced: <ph name="WHEN">%1$s<ex>4 hours ago</ex></ph> </message> @@ -1912,18 +1932,6 @@ <message name="IDS_BOOKMARKS_FOLDER_EMPTY" desc="Text explaining that the currently selected bookmarks folder is empty."> No bookmarks here </message> - <message name="IDS_BOOKMARK_SIGN_IN_PROMO_TITLE" desc="Promo title encouraging the user to sign in to Chrome to improve their bookmarks experience. It means that after signing-in, bookmarks will become synced across devices and possible to search."> - Sync your bookmarks - </message> - <message name="IDS_BOOKMARK_SIGN_IN_PROMO_DESCRIPTION" desc="Description for bookmark UI sign-in promotion."> - To get your bookmarks on all your devices, sign in to Chrome - </message> - <message name="IDS_BOOKMARK_SIGN_IN_PROMO_NO_THANKS" desc="Text for the decline button in the bookmark UI"> - No, thanks - </message> - <message name="IDS_BOOKMARK_SIGN_IN_PROMO_SIGN_IN" desc="Text for the sign-in button in promotion in the bookmark UI"> - Sign in - </message> <message name="IDS_BOOKMARK_PAGE_SAVED" desc="Message shown after user adds a new bookmark. [CHAR-LIMIT=32]"> Bookmarked </message>
diff --git a/chrome/android/java_sources.gni b/chrome/android/java_sources.gni index 5b6184ac..2b230931 100644 --- a/chrome/android/java_sources.gni +++ b/chrome/android/java_sources.gni
@@ -110,7 +110,6 @@ "java/src/org/chromium/chrome/browser/bookmarks/BookmarkRow.java", "java/src/org/chromium/chrome/browser/bookmarks/BookmarkSearchRow.java", "java/src/org/chromium/chrome/browser/bookmarks/BookmarkSearchView.java", - "java/src/org/chromium/chrome/browser/bookmarks/BookmarkSigninActivity.java", "java/src/org/chromium/chrome/browser/bookmarks/BookmarkUIObserver.java", "java/src/org/chromium/chrome/browser/bookmarks/BookmarkUIState.java", "java/src/org/chromium/chrome/browser/bookmarks/BookmarkUndoController.java", @@ -500,7 +499,6 @@ "java/src/org/chromium/chrome/browser/ntp/RecentTabsGroupView.java", "java/src/org/chromium/chrome/browser/ntp/RecentTabsManager.java", "java/src/org/chromium/chrome/browser/ntp/RecentTabsPage.java", - "java/src/org/chromium/chrome/browser/ntp/RecentTabsPromoView.java", "java/src/org/chromium/chrome/browser/ntp/RecentTabsRowAdapter.java", "java/src/org/chromium/chrome/browser/ntp/RecentlyClosedBridge.java", "java/src/org/chromium/chrome/browser/ntp/interests/InterestsItemView.java", @@ -727,9 +725,8 @@ "java/src/org/chromium/chrome/browser/signin/AccountIdProvider.java", "java/src/org/chromium/chrome/browser/signin/AccountManagementFragment.java", "java/src/org/chromium/chrome/browser/signin/AccountManagementScreenHelper.java", - "java/src/org/chromium/chrome/browser/signin/AccountListAdapter.java", - "java/src/org/chromium/chrome/browser/signin/AccountListView.java", "java/src/org/chromium/chrome/browser/signin/AccountSigninActivity.java", + "java/src/org/chromium/chrome/browser/signin/AccountSigninChooseView.java", "java/src/org/chromium/chrome/browser/signin/AccountSigninConfirmationView.java", "java/src/org/chromium/chrome/browser/signin/AccountSigninView.java", "java/src/org/chromium/chrome/browser/signin/AccountTrackerService.java", @@ -738,6 +735,7 @@ "java/src/org/chromium/chrome/browser/signin/GoogleActivityController.java", "java/src/org/chromium/chrome/browser/signin/OAuth2TokenService.java", "java/src/org/chromium/chrome/browser/signin/SignOutDialogFragment.java", + "java/src/org/chromium/chrome/browser/signin/SigninAndSyncView.java", "java/src/org/chromium/chrome/browser/signin/SigninHelper.java", "java/src/org/chromium/chrome/browser/signin/SigninInvestigator.java", "java/src/org/chromium/chrome/browser/signin/SigninManager.java",
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/feedback/ConnectivityTaskTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/feedback/ConnectivityTaskTest.java index e6252a17d..a922307 100644 --- a/chrome/android/javatests/src/org/chromium/chrome/browser/feedback/ConnectivityTaskTest.java +++ b/chrome/android/javatests/src/org/chromium/chrome/browser/feedback/ConnectivityTaskTest.java
@@ -113,7 +113,7 @@ @MediumTest @Feature({"Feedback"}) public void testCallbackTwoTimeouts() throws InterruptedException { - final int checkTimeoutMs = 100; + final int checkTimeoutMs = 1000; final Semaphore semaphore = new Semaphore(0); final AtomicReference<FeedbackData> feedbackRef = new AtomicReference<>(); final ConnectivityTask.ConnectivityResult callback =
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/offlinepages/OfflinePageBridgeTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/offlinepages/OfflinePageBridgeTest.java index 6a07108..22924a8 100644 --- a/chrome/android/javatests/src/org/chromium/chrome/browser/offlinepages/OfflinePageBridgeTest.java +++ b/chrome/android/javatests/src/org/chromium/chrome/browser/offlinepages/OfflinePageBridgeTest.java
@@ -8,6 +8,7 @@ import android.os.Environment; import android.test.suitebuilder.annotation.SmallTest; +import org.chromium.base.Callback; import org.chromium.base.ThreadUtils; import org.chromium.base.test.util.CommandLineFlags; import org.chromium.chrome.browser.ChromeActivity; @@ -23,7 +24,9 @@ import org.chromium.net.test.EmbeddedTestServer; import java.util.ArrayList; +import java.util.HashSet; import java.util.List; +import java.util.Set; import java.util.concurrent.Semaphore; import java.util.concurrent.TimeUnit; import java.util.concurrent.atomic.AtomicInteger; @@ -154,18 +157,6 @@ getPageByClientId(BOOKMARK_ID)); } - @SmallTest - public void testOfflinePageExists() throws Exception { - loadUrl(mTestPage); - assertFalse("We should not say a page exists for one we haven't saved.", - mOfflinePageBridge.offlinePageExists(mTestPage)); - savePage(SavePageResult.SUCCESS, mTestPage); - assertTrue("We should say a page exists for one we just saved.", - mOfflinePageBridge.offlinePageExists(mTestPage)); - assertFalse("We should not say a page exists for one we haven't saved.", - mOfflinePageBridge.offlinePageExists(mTestPage + "?foo=bar")); - } - @CommandLineFlags.Add("disable-features=OfflinePagesBackgroundLoading") @SmallTest public void testBackgroundLoadSwitch() throws Exception { @@ -178,6 +169,26 @@ }); } + @SmallTest + public void testCheckPagesExistOffline() throws Exception { + // If we save a page, then it should exist in the result. + loadUrl(mTestPage); + savePage(SavePageResult.SUCCESS, mTestPage); + Set<String> testCases = new HashSet<>(); + testCases.add(mTestPage); + + // Querying for a page that hasn't been saved should not affect the result. + testCases.add(mTestPage + "?foo=bar"); + + Set<String> pages = checkPagesExistOffline(testCases); + + assertEquals( + "We only saved one page and queried for it, so the result should be one string.", 1, + pages.size()); + assertTrue("The only page returned should be the page that was actually saved.", + pages.contains(mTestPage)); + } + private void savePage(final int expectedResult, final String expectedUrl) throws InterruptedException { final Semaphore semaphore = new Semaphore(0); @@ -185,7 +196,7 @@ @Override public void run() { assertNotNull("Tab is null", getActivity().getActivityTab()); - assertEquals("URL does not match requested.", mTestPage, + assertEquals("URL does not match requested.", expectedUrl, getActivity().getActivityTab().getUrl()); assertNotNull("WebContents is null", getActivity().getActivityTab().getWebContents()); @@ -276,4 +287,24 @@ assertTrue(semaphore.tryAcquire(TIMEOUT_MS, TimeUnit.MILLISECONDS)); return result[0]; } + + private Set<String> checkPagesExistOffline(final Set<String> query) + throws InterruptedException { + final Set<String> result = new HashSet<>(); + final Semaphore semaphore = new Semaphore(0); + ThreadUtils.runOnUiThread(new Runnable() { + @Override + public void run() { + mOfflinePageBridge.checkPagesExistOffline(query, new Callback<Set<String>>() { + @Override + public void onResult(Set<String> offlinedPages) { + result.addAll(offlinedPages); + semaphore.release(); + } + }); + } + }); + assertTrue(semaphore.tryAcquire(TIMEOUT_MS, TimeUnit.MILLISECONDS)); + return result; + } }
diff --git a/chrome/browser/android/ntp/most_visited_sites.cc b/chrome/browser/android/ntp/most_visited_sites.cc index 7b1de89..3f5e907 100644 --- a/chrome/browser/android/ntp/most_visited_sites.cc +++ b/chrome/browser/android/ntp/most_visited_sites.cc
@@ -19,6 +19,7 @@ #include "chrome/browser/history/top_sites_factory.h" #include "chrome/browser/profiles/profile.h" #include "chrome/browser/search/suggestions/suggestions_service_factory.h" +#include "chrome/browser/search_engines/template_url_service_factory.h" #include "chrome/browser/supervised_user/supervised_user_service.h" #include "chrome/browser/supervised_user/supervised_user_service_factory.h" #include "chrome/browser/supervised_user/supervised_user_url_filter.h" @@ -203,7 +204,9 @@ if (ShouldShowPopularSites() && NeedPopularSites(profile_->GetPrefs(), num_sites_)) { popular_sites_.reset(new PopularSites( - profile_, + profile_->GetPrefs(), + TemplateURLServiceFactory::GetForProfile(profile_), + profile_->GetRequestContext(), GetPopularSitesCountry(), GetPopularSitesVersion(), false,
diff --git a/chrome/browser/android/ntp/popular_sites.cc b/chrome/browser/android/ntp/popular_sites.cc index be7e3e4..13ee926 100644 --- a/chrome/browser/android/ntp/popular_sites.cc +++ b/chrome/browser/android/ntp/popular_sites.cc
@@ -18,8 +18,6 @@ #include "base/time/time.h" #include "base/values.h" #include "chrome/browser/browser_process.h" -#include "chrome/browser/profiles/profile.h" -#include "chrome/browser/search_engines/template_url_service_factory.h" #include "chrome/common/chrome_paths.h" #include "chrome/common/chrome_switches.h" #include "components/google/core/browser/google_util.h" @@ -48,17 +46,14 @@ // Extract the country from the default search engine if the default search // engine is Google. -std::string GetDefaultSearchEngineCountryCode(Profile* profile) { - DCHECK(profile); +std::string GetDefaultSearchEngineCountryCode( + const TemplateURLService* template_url_service) { + DCHECK(template_url_service); base::CommandLine* cmd_line = base::CommandLine::ForCurrentProcess(); if (!cmd_line->HasSwitch(switches::kEnableNTPSearchEngineCountryDetection)) return std::string(); - const TemplateURLService* template_url_service = - TemplateURLServiceFactory::GetForProfile(profile); - DCHECK(template_url_service); - const TemplateURL* default_provider = template_url_service->GetDefaultSearchProvider(); // It's possible to not have a default provider in the case that the default @@ -93,12 +88,13 @@ // Google is the default search engine set. If Google is not the default search // engine use the country provided by VariationsService. Fallback to a default // if we can't make an educated guess. -std::string GetCountryToUse(Profile* profile, +std::string GetCountryToUse(const TemplateURLService* template_url_service, const std::string& override_country) { if (!override_country.empty()) return override_country; - std::string country_code = GetDefaultSearchEngineCountryCode(profile); + std::string country_code = GetDefaultSearchEngineCountryCode( + template_url_service); if (country_code.empty()) country_code = GetVariationsServiceCountry(); @@ -179,32 +175,44 @@ PopularSites::Site::~Site() {} -PopularSites::PopularSites(Profile* profile, +PopularSites::PopularSites(PrefService* prefs, + const TemplateURLService* template_url_service, + net::URLRequestContextGetter* download_context, const std::string& override_country, const std::string& override_version, bool force_download, const FinishedCallback& callback) - : PopularSites(profile, - GetCountryToUse(profile, override_country), + : PopularSites(prefs, + template_url_service, + download_context, + GetCountryToUse(template_url_service, override_country), GetVersionToUse(override_version), GURL(), force_download, callback) {} -PopularSites::PopularSites(Profile* profile, +PopularSites::PopularSites(PrefService* prefs, + const TemplateURLService* template_url_service, + net::URLRequestContextGetter* download_context, const GURL& url, const FinishedCallback& callback) - : PopularSites(profile, std::string(), std::string(), url, true, callback) { -} + : PopularSites(prefs, + template_url_service, + download_context, + std::string(), + std::string(), + url, + true, + callback) {} PopularSites::~PopularSites() {} std::string PopularSites::GetCountry() const { - return profile_->GetPrefs()->GetString(kPopularSitesCountryPref); + return prefs_->GetString(kPopularSitesCountryPref); } std::string PopularSites::GetVersion() const { - return profile_->GetPrefs()->GetString(kPopularSitesVersionPref); + return prefs_->GetString(kPopularSitesVersionPref); } // static @@ -215,7 +223,9 @@ user_prefs->RegisterStringPref(kPopularSitesVersionPref, std::string()); } -PopularSites::PopularSites(Profile* profile, +PopularSites::PopularSites(PrefService* prefs, + const TemplateURLService* template_url_service, + net::URLRequestContextGetter* download_context, const std::string& country, const std::string& version, const GURL& override_url, @@ -225,10 +235,12 @@ pending_country_(country), pending_version_(version), local_path_(GetPopularSitesPath()), - profile_(profile), + prefs_(prefs), + template_url_service_(template_url_service), + download_context_(download_context), weak_ptr_factory_(this) { const base::Time last_download_time = base::Time::FromInternalValue( - profile_->GetPrefs()->GetInt64(kPopularSitesLastDownloadPref)); + prefs_->GetInt64(kPopularSitesLastDownloadPref)); const base::TimeDelta time_since_last_download = base::Time::Now() - last_download_time; const base::TimeDelta redownload_interval = @@ -256,7 +268,7 @@ bool force_download, bool is_fallback) { downloader_.reset(new FileDownloader( - url, local_path_, force_download, profile_->GetRequestContext(), + url, local_path_, force_download, download_context_, base::Bind(&PopularSites::OnDownloadDone, base::Unretained(this), is_fallback))); } @@ -264,13 +276,12 @@ void PopularSites::OnDownloadDone(bool is_fallback, FileDownloader::Result result) { downloader_.reset(); - PrefService* prefs = profile_->GetPrefs(); switch (result) { case FileDownloader::DOWNLOADED: - prefs->SetInt64(kPopularSitesLastDownloadPref, + prefs_->SetInt64(kPopularSitesLastDownloadPref, base::Time::Now().ToInternalValue()); - prefs->SetString(kPopularSitesCountryPref, pending_country_); - prefs->SetString(kPopularSitesVersionPref, pending_version_); + prefs_->SetString(kPopularSitesCountryPref, pending_country_); + prefs_->SetString(kPopularSitesVersionPref, pending_version_); ParseSiteList(local_path_); break; case FileDownloader::EXISTS:
diff --git a/chrome/browser/android/ntp/popular_sites.h b/chrome/browser/android/ntp/popular_sites.h index 7cc520e..41523c5b 100644 --- a/chrome/browser/android/ntp/popular_sites.h +++ b/chrome/browser/android/ntp/popular_sites.h
@@ -25,7 +25,8 @@ class PrefRegistrySyncable; } -class Profile; +class PrefService; +class TemplateURLService; // Downloads and provides a list of suggested popular sites, for display on // the NTP when there are not enough personalized suggestions. Caches the @@ -56,7 +57,9 @@ // override the baked-in default version. // Set |force_download| to enforce re-downloading the suggestions file, even // if it already exists on disk. - PopularSites(Profile* profile, + PopularSites(PrefService* prefs, + const TemplateURLService* template_url_service, + net::URLRequestContextGetter* download_context, const std::string& override_country, const std::string& override_version, bool force_download, @@ -64,7 +67,9 @@ // This fetches the popular sites from a given url and is only used for // debugging through the popular-sites-internals page. - PopularSites(Profile* profile, + PopularSites(PrefService* prefs, + const TemplateURLService* template_url_service, + net::URLRequestContextGetter* download_context, const GURL& url, const FinishedCallback& callback); @@ -83,7 +88,9 @@ user_prefs::PrefRegistrySyncable* user_prefs); private: - PopularSites(Profile* profile, + PopularSites(PrefService* prefs, + const TemplateURLService* template_url_service, + net::URLRequestContextGetter* download_context, const std::string& country, const std::string& version, const GURL& override_url, @@ -113,7 +120,9 @@ base::FilePath local_path_; - Profile* profile_; + PrefService* prefs_; + const TemplateURLService* template_url_service_; + net::URLRequestContextGetter* download_context_; base::WeakPtrFactory<PopularSites> weak_ptr_factory_;
diff --git a/chrome/browser/android/offline_pages/offline_page_bridge.cc b/chrome/browser/android/offline_pages/offline_page_bridge.cc index ea267e9..ded2d9c8 100644 --- a/chrome/browser/android/offline_pages/offline_page_bridge.cc +++ b/chrome/browser/android/offline_pages/offline_page_bridge.cc
@@ -51,6 +51,23 @@ } } +void CheckPagesExistOfflineCallback( + const ScopedJavaGlobalRef<jobject>& j_callback_obj, + const OfflinePageModel::CheckPagesExistOfflineResult& offline_pages) { + JNIEnv* env = base::android::AttachCurrentThread(); + + std::vector<std::string> offline_pages_vector; + for (const GURL& page : offline_pages) + offline_pages_vector.push_back(page.spec()); + + ScopedJavaLocalRef<jobjectArray> j_result_array = + base::android::ToJavaArrayOfStrings(env, offline_pages_vector); + DCHECK(j_result_array.obj()); + + Java_CheckPagesExistOfflineCallbackInternal_onResult( + env, j_callback_obj.obj(), j_result_array.obj()); +} + void GetAllPagesCallback(const ScopedJavaGlobalRef<jobject>& j_result_obj, const ScopedJavaGlobalRef<jobject>& j_callback_obj, const OfflinePageModel::GetAllPagesResult& result) { @@ -179,6 +196,27 @@ name_space, base::Bind(&HasPagesCallback, j_callback_ref)); } +void OfflinePageBridge::CheckPagesExistOffline( + JNIEnv* env, + const JavaParamRef<jobject>& obj, + const JavaParamRef<jobjectArray>& j_urls_array, + const JavaParamRef<jobject>& j_callback_obj) { + DCHECK(j_urls_array); + DCHECK(j_callback_obj); + + std::vector<std::string> urls; + base::android::AppendJavaStringArrayToStringVector(env, j_urls_array.obj(), + &urls); + + std::set<GURL> page_urls; + for (const std::string& url : urls) + page_urls.insert(GURL(url)); + + offline_page_model_->CheckPagesExistOffline( + page_urls, base::Bind(&CheckPagesExistOfflineCallback, + ScopedJavaGlobalRef<jobject>(env, j_callback_obj))); +} + void OfflinePageBridge::GetAllPages( JNIEnv* env, const JavaParamRef<jobject>& obj,
diff --git a/chrome/browser/android/offline_pages/offline_page_bridge.h b/chrome/browser/android/offline_pages/offline_page_bridge.h index d8a3040..73fe91d 100644 --- a/chrome/browser/android/offline_pages/offline_page_bridge.h +++ b/chrome/browser/android/offline_pages/offline_page_bridge.h
@@ -44,6 +44,12 @@ const base::android::JavaParamRef<jstring>& name_space, const base::android::JavaParamRef<jobject>& j_callback_obj); + void CheckPagesExistOffline( + JNIEnv* env, + const base::android::JavaParamRef<jobject>& obj, + const base::android::JavaParamRef<jobjectArray>& j_urls_array, + const base::android::JavaParamRef<jobject>& j_callback_obj); + void GetAllPages(JNIEnv* env, const base::android::JavaParamRef<jobject>& obj, const base::android::JavaParamRef<jobject>& j_result_obj,
diff --git a/chrome/browser/apps/guest_view/web_view_interactive_browsertest.cc b/chrome/browser/apps/guest_view/web_view_interactive_browsertest.cc index 9647723..c8a839c 100644 --- a/chrome/browser/apps/guest_view/web_view_interactive_browsertest.cc +++ b/chrome/browser/apps/guest_view/web_view_interactive_browsertest.cc
@@ -995,9 +995,9 @@ // make sure we keep rendering popups correct in webview. } -// Flaky on ChromeOS: http://crbug.com/526886 -// Causes problems on windows: http://crbug.com/544037 -#if defined(OS_CHROMEOS) || defined(OS_WIN) +// Flaky on ChromeOS and Linux: http://crbug.com/526886 +// Causes problems on windows: http://crbug.com/544998 +#if defined(OS_CHROMEOS) || defined(OS_WIN) || defined(OS_LINUX) #define MAYBE_PopupPositioningMoved DISABLED_PopupPositioningMoved #else #define MAYBE_PopupPositioningMoved PopupPositioningMoved
diff --git a/chrome/browser/chromeos/arc/arc_policy_bridge.cc b/chrome/browser/chromeos/arc/arc_policy_bridge.cc index 5ad15000..58d92fc 100644 --- a/chrome/browser/chromeos/arc/arc_policy_bridge.cc +++ b/chrome/browser/chromeos/arc/arc_policy_bridge.cc
@@ -115,6 +115,9 @@ policy_map, 2 /*BlockGeolocation*/, &filtered_policies); MapBoolToBool("unmuteMicrophoneDisabled", policy::key::kAudioCaptureAllowed, policy_map, true, &filtered_policies); + MapBoolToBool("usbFileTransferDisabled", + policy::key::kExternalStorageDisabled, policy_map, false, + &filtered_policies); // Add global app restrictions. AddGlobalAppRestriction("com.android.browser:URLBlacklist",
diff --git a/chrome/browser/chromeos/arc/arc_policy_bridge_unittest.cc b/chrome/browser/chromeos/arc/arc_policy_bridge_unittest.cc index 4b3f7f1..da58e3a 100644 --- a/chrome/browser/chromeos/arc/arc_policy_bridge_unittest.cc +++ b/chrome/browser/chromeos/arc/arc_policy_bridge_unittest.cc
@@ -164,6 +164,15 @@ PolicyStringCallback("{\"shareLocationDisabled\":false}")); } +TEST_F(ArcPolicyBridgeTest, ExternalStorageDisabledTest) { + policy_map().Set(policy::key::kExternalStorageDisabled, + policy::POLICY_LEVEL_MANDATORY, policy::POLICY_SCOPE_USER, + policy::POLICY_SOURCE_CLOUD, + new base::FundamentalValue(true), nullptr); + policy_bridge()->GetPolicies( + PolicyStringCallback("{\"usbFileTransferDisabled\":true}")); +} + TEST_F(ArcPolicyBridgeTest, URLBlacklistTest) { base::ListValue blacklist; blacklist.Append(new base::StringValue("www.blacklist1.com"));
diff --git a/chrome/browser/extensions/extension_install_prompt.h b/chrome/browser/extensions/extension_install_prompt.h index f71eb801..13ee5bf 100644 --- a/chrome/browser/extensions/extension_install_prompt.h +++ b/chrome/browser/extensions/extension_install_prompt.h
@@ -260,13 +260,6 @@ // The implementations of this function are platform-specific. static ShowDialogCallback GetDefaultShowDialogCallback(); - // Callback to show the Views extension install dialog. Don't use this; it is - // a temporary hack for MacViews. - // TODO(ellyjones): Remove this. -#if defined(OS_MACOSX) - static ShowDialogCallback GetViewsShowDialogCallback(); -#endif - // Returns the appropriate prompt type for the given |extension|. // TODO(devlin): This method is yucky - callers probably only care about one // prompt type. We just need to comb through and figure out what it is.
diff --git a/chrome/browser/password_manager/chrome_password_manager_client.cc b/chrome/browser/password_manager/chrome_password_manager_client.cc index 0c11394..97ceb0b 100644 --- a/chrome/browser/password_manager/chrome_password_manager_client.cc +++ b/chrome/browser/password_manager/chrome_password_manager_client.cc
@@ -222,6 +222,10 @@ return false; } + // Prevent the autofill password manager from prompting the second time. + if (type == password_manager::CredentialSourceType::CREDENTIAL_SOURCE_API) + password_manager_.DropFormManagers(); + if (IsTheHotNewBubbleUIEnabled()) { #if !BUILDFLAG(ANDROID_JAVA_UI) PasswordsClientUIDelegate* manage_passwords_ui_controller =
diff --git a/chrome/browser/password_manager/credential_manager_browsertest.cc b/chrome/browser/password_manager/credential_manager_browsertest.cc index c8889467..378d660 100644 --- a/chrome/browser/password_manager/credential_manager_browsertest.cc +++ b/chrome/browser/password_manager/credential_manager_browsertest.cc
@@ -122,4 +122,29 @@ EXPECT_FALSE(prompt_observer->IsShowingPrompt()); } +IN_PROC_BROWSER_TEST_F(CredentialManagerBrowserTest, SaveViaAPIAndAutofill) { + NavigateToFile("/password/password_form.html"); + std::string fill_password = + "document.getElementById('username_field').value = 'user';" + "document.getElementById('password_field').value = '12345';"; + ASSERT_TRUE(content::ExecuteScript(RenderViewHost(), fill_password)); + + // Call the API to save the form. + ASSERT_TRUE(content::ExecuteScript( + RenderViewHost(), + "var c = new PasswordCredential({ id: 'user', password: '12345' });" + "navigator.credentials.store(c);")); + std::unique_ptr<PromptObserver> prompt_observer( + PromptObserver::Create(WebContents())); + EXPECT_TRUE(prompt_observer->IsShowingPrompt()); + prompt_observer->Dismiss(); + + NavigationObserver form_submit_observer(WebContents()); + ASSERT_TRUE(content::ExecuteScript( + RenderViewHost(), + "document.getElementById('input_submit_button').click();")); + form_submit_observer.Wait(); + EXPECT_FALSE(prompt_observer->IsShowingPrompt()); +} + } // namespace
diff --git a/chrome/browser/password_manager/password_manager_test_base.cc b/chrome/browser/password_manager/password_manager_test_base.cc index bdd32c3..909c9f9 100644 --- a/chrome/browser/password_manager/password_manager_test_base.cc +++ b/chrome/browser/password_manager/password_manager_test_base.cc
@@ -14,7 +14,7 @@ #include "chrome/browser/password_manager/password_store_factory.h" #include "chrome/browser/profiles/profile.h" #include "chrome/browser/ui/browser.h" -#include "chrome/browser/ui/passwords/passwords_model_delegate.h" +#include "chrome/browser/ui/passwords/manage_passwords_ui_controller.h" #include "chrome/browser/ui/tabs/tab_strip_model.h" #include "chrome/test/base/ui_test_utils.h" #include "components/autofill/core/browser/autofill_test_utils.h" @@ -24,6 +24,7 @@ #include "components/password_manager/core/browser/password_manager_test_utils.h" #include "components/password_manager/core/browser/test_password_store.h" #include "components/password_manager/core/common/password_manager_features.h" +#include "content/public/browser/navigation_details.h" #include "content/public/browser/render_frame_host.h" #include "content/public/test/browser_test_utils.h" #include "content/public/test/test_utils.h" @@ -95,6 +96,10 @@ infobar_service_->RemoveObserver(this); } + void Dismiss() const override { + NOTIMPLEMENTED(); + } + private: // PromptObserver: bool IsShowingPrompt() const override { return infobar_is_being_shown_; } @@ -143,6 +148,17 @@ ~BubbleObserver() override {} + void Dismiss() const override { + passwords_model_delegate_->OnBubbleHidden(); + // Navigate away to reset the state to inactive. + static_cast<content::WebContentsObserver*>( + static_cast<ManagePasswordsUIController*>(passwords_model_delegate_)) + ->DidNavigateMainFrame(content::LoadCommittedDetails(), + content::FrameNavigateParams()); + ASSERT_EQ(password_manager::ui::INACTIVE_STATE, + passwords_model_delegate_->GetState()); + } + private: // PromptObserver: bool IsShowingPrompt() const override {
diff --git a/chrome/browser/password_manager/password_manager_test_base.h b/chrome/browser/password_manager/password_manager_test_base.h index 0ca5179..a0f411f8 100644 --- a/chrome/browser/password_manager/password_manager_test_base.h +++ b/chrome/browser/password_manager/password_manager_test_base.h
@@ -67,6 +67,10 @@ // Checks if the update prompt is being currently shown. virtual bool IsShowingUpdatePrompt() const; + // Dismisses the prompt currently open and moves the controller to the + // inactive state. + virtual void Dismiss() const = 0; + // Expecting that the prompt is shown, saves the password. Checks that the // prompt is no longer visible afterwards. void Accept() const;
diff --git a/chrome/browser/prerender/prerender_histograms.cc b/chrome/browser/prerender/prerender_histograms.cc index 6e46198..30d9f03 100644 --- a/chrome/browser/prerender/prerender_histograms.cc +++ b/chrome/browser/prerender/prerender_histograms.cc
@@ -47,7 +47,7 @@ case ORIGIN_LINK_REL_PRERENDER_CROSSDOMAIN: return ComposeHistogramName("webcross", name); case ORIGIN_EXTERNAL_REQUEST: - return ComposeHistogramName("externalrequest", name); + return ComposeHistogramName("externalrequest", name); case ORIGIN_INSTANT: return ComposeHistogramName("Instant", name); case ORIGIN_LINK_REL_NEXT: @@ -56,6 +56,8 @@ return ComposeHistogramName("gws", name); case ORIGIN_EXTERNAL_REQUEST_FORCED_CELLULAR: return ComposeHistogramName("externalrequestforced", name); + case ORIGIN_OFFLINE: + return ComposeHistogramName("offline", name); default: NOTREACHED(); break; @@ -91,6 +93,7 @@ } \ /* Do not rename. HISTOGRAM expects a local variable "name". */ \ std::string name = GetHistogramName(origin, wash, histogram_name); \ + /* Branching because HISTOGRAM is caching the histogram into a static. */ \ if (wash) { \ HISTOGRAM; \ } else if (origin == ORIGIN_OMNIBOX) { \ @@ -109,6 +112,8 @@ HISTOGRAM; \ } else if (origin == ORIGIN_EXTERNAL_REQUEST_FORCED_CELLULAR) { \ HISTOGRAM; \ + } else if (origin == ORIGIN_OFFLINE) { \ + HISTOGRAM; \ } else { \ HISTOGRAM; \ } \
diff --git a/chrome/browser/prerender/prerender_manager.cc b/chrome/browser/prerender/prerender_manager.cc index 17bb6d91..f3dedfe 100644 --- a/chrome/browser/prerender/prerender_manager.cc +++ b/chrome/browser/prerender/prerender_manager.cc
@@ -320,6 +320,14 @@ session_storage_namespace); } +PrerenderHandle* PrerenderManager::AddPrerenderForOffline( + const GURL& url, + content::SessionStorageNamespace* session_storage_namespace, + const gfx::Size& size) { + return AddPrerender(ORIGIN_OFFLINE, url, content::Referrer(), size, + session_storage_namespace); +} + void PrerenderManager::CancelAllPrerenders() { DCHECK(CalledOnValidThread()); while (!active_prerenders_.empty()) { @@ -951,7 +959,8 @@ // histogram tracking. histograms_->RecordPrerender(origin, url_arg); - if (profile_->GetPrefs()->GetBoolean(prefs::kBlockThirdPartyCookies)) { + if (profile_->GetPrefs()->GetBoolean(prefs::kBlockThirdPartyCookies) && + origin != ORIGIN_OFFLINE) { RecordFinalStatusWithoutCreatingPrerenderContents( url, origin, FINAL_STATUS_BLOCK_THIRD_PARTY_COOKIES); return nullptr; @@ -1147,8 +1156,12 @@ const SessionStorageNamespace* session_storage_namespace) { for (ScopedVector<PrerenderData>::iterator it = active_prerenders_.begin(); it != active_prerenders_.end(); ++it) { - if ((*it)->contents()->Matches(url, session_storage_namespace)) + PrerenderContents* contents = (*it)->contents(); + if (contents->Matches(url, session_storage_namespace)) { + if (contents->origin() == ORIGIN_OFFLINE) + return NULL; return *it; + } } return NULL; } @@ -1169,6 +1182,11 @@ base::TimeDelta elapsed_time = GetCurrentTimeTicks() - last_prerender_start_time_; histograms_->RecordTimeBetweenPrerenderRequests(origin, elapsed_time); + // TODO(gabadie,pasko): Re-implement missing tests for + // FINAL_STATUS_RATE_LIMIT_EXCEEDED that where removed by: + // http://crrev.com/a2439eeab37f7cb7a118493fb55ec0cb07f93b49. + if (origin == ORIGIN_OFFLINE) + return true; if (!config_.rate_limit_enabled) return true; return elapsed_time >= @@ -1311,10 +1329,18 @@ Origin origin) const { DCHECK(CalledOnValidThread()); - // LINK rel=prerender origins ignore the network state and the privacy - // settings. + // <link rel=prerender> origins ignore the network state and the privacy + // settings. Web developers should be able prefetch with all possible privacy + // settings and with all possible network types. This would avoid web devs + // coming up with creative ways to prefetch in cases they are not allowed to + // do so. + // + // Offline originated prerenders also ignore the network state and privacy + // settings because they are controlled by the offliner logic via + // PrerenderHandle. if (origin == ORIGIN_LINK_REL_PRERENDER_SAMEDOMAIN || - origin == ORIGIN_LINK_REL_PRERENDER_CROSSDOMAIN) { + origin == ORIGIN_LINK_REL_PRERENDER_CROSSDOMAIN || + origin == ORIGIN_OFFLINE) { return NetworkPredictionStatus::ENABLED; }
diff --git a/chrome/browser/prerender/prerender_manager.h b/chrome/browser/prerender/prerender_manager.h index 692d971..d64fc202f 100644 --- a/chrome/browser/prerender/prerender_manager.h +++ b/chrome/browser/prerender/prerender_manager.h
@@ -151,6 +151,22 @@ content::SessionStorageNamespace* session_storage_namespace, const gfx::Size& size); + // Adds a prerender for the background loader. Returns a caller-owned + // PrerenderHandle* if the URL was added, NULL if it was not. + // + // The caller may set an observer on the handle to receive load events. When + // the caller is done using the WebContents, it should call OnCancel() on the + // handle to free the resources associated with the prerender. + // + // The caller must provide two guarantees: + // 1. It must never ask for a swap-in; + // 2. The SessionStorageNamespace must not be shared with any tab / page load + // to avoid swapping in from there. + PrerenderHandle* AddPrerenderForOffline( + const GURL& url, + content::SessionStorageNamespace* session_storage_namespace, + const gfx::Size& size); + // Cancels all active prerenders. void CancelAllPrerenders();
diff --git a/chrome/browser/prerender/prerender_origin.cc b/chrome/browser/prerender/prerender_origin.cc index 3c9b7b69..b674d62 100644 --- a/chrome/browser/prerender/prerender_origin.cc +++ b/chrome/browser/prerender/prerender_origin.cc
@@ -27,6 +27,7 @@ "Instant", "Link Rel Next", "External Request Forced Cellular", + "Offline", "Max", }; static_assert(arraysize(kOriginNames) == ORIGIN_MAX + 1,
diff --git a/chrome/browser/prerender/prerender_origin.h b/chrome/browser/prerender/prerender_origin.h index 60e3e0b..cb82294 100644 --- a/chrome/browser/prerender/prerender_origin.h +++ b/chrome/browser/prerender/prerender_origin.h
@@ -24,6 +24,7 @@ ORIGIN_INSTANT = 11, ORIGIN_LINK_REL_NEXT = 12, ORIGIN_EXTERNAL_REQUEST_FORCED_CELLULAR = 13, + ORIGIN_OFFLINE = 14, ORIGIN_MAX, };
diff --git a/chrome/browser/prerender/prerender_unittest.cc b/chrome/browser/prerender/prerender_unittest.cc index 0db797f2..ee3254a1 100644 --- a/chrome/browser/prerender/prerender_unittest.cc +++ b/chrome/browser/prerender/prerender_unittest.cc
@@ -427,6 +427,24 @@ EXPECT_FALSE(AddSimplePrerender(url)); } +TEST_F(PrerenderTest, OfflinePrerenderIgnoresThirdPartyCookiesPref) { + GURL url("http://www.google.com/"); + RestorePrerenderMode restore_prerender_mode; + ASSERT_TRUE(PrerenderManager::IsPrerenderingPossible()); + + profile()->GetPrefs()->SetBoolean(prefs::kBlockThirdPartyCookies, true); + DummyPrerenderContents* prerender_contents = + prerender_manager()->CreateNextPrerenderContents( + url, ORIGIN_OFFLINE, FINAL_STATUS_MANAGER_SHUTDOWN); + std::unique_ptr<PrerenderHandle> prerender_handle( + prerender_manager()->AddPrerenderForOffline(url, nullptr, kSize)); + EXPECT_TRUE(prerender_handle); + EXPECT_TRUE(prerender_handle->IsPrerendering()); + EXPECT_TRUE(prerender_contents->prerendering_has_started()); + EXPECT_EQ(prerender_contents, prerender_handle->contents()); + EXPECT_EQ(ORIGIN_OFFLINE, prerender_handle->contents()->origin()); +} + TEST_F(PrerenderTest, FoundTest) { GURL url("http://www.google.com/"); DummyPrerenderContents* prerender_contents = @@ -438,6 +456,19 @@ ASSERT_EQ(prerender_contents, prerender_manager()->FindAndUseEntry(url)); } +TEST_F(PrerenderTest, UnfindableOfflinePrerenderTest) { + GURL url("http://www.google.com/"); + DummyPrerenderContents* prerender_contents = + prerender_manager()->CreateNextPrerenderContents( + url, ORIGIN_OFFLINE, FINAL_STATUS_MANAGER_SHUTDOWN); + std::unique_ptr<PrerenderHandle> prerender_handle( + prerender_manager()->AddPrerenderForOffline(url, nullptr, kSize)); + EXPECT_TRUE(prerender_handle); + EXPECT_TRUE(prerender_handle->IsPrerendering()); + EXPECT_TRUE(prerender_contents->prerendering_has_started()); + ASSERT_EQ(nullptr, prerender_manager()->FindAndUseEntry(url)); +} + // Make sure that if queue a request, and a second prerender request for the // same URL comes in, that the second request attaches to the first prerender, // and we don't use the second prerender contents. @@ -1111,28 +1142,41 @@ EXPECT_FALSE(prerender_contents->prerendering_has_started()); } -TEST_F(PrerenderTest,PrerenderAllowedOnCellularWithForcedOrigin) { +TEST_F(PrerenderTest, PrerenderAllowedForOfflineAndForcedCellular) { + const Origin origins[] = { + ORIGIN_EXTERNAL_REQUEST_FORCED_CELLULAR, + ORIGIN_OFFLINE, + }; + EnablePrerender(); std::unique_ptr<net::NetworkChangeNotifier> mock( new MockNetworkChangeNotifier4G); EXPECT_TRUE(net::NetworkChangeNotifier::IsConnectionCellular( net::NetworkChangeNotifier::GetConnectionType())); GURL url("http://www.google.com/"); - DummyPrerenderContents* prerender_contents = - prerender_manager()->CreateNextPrerenderContents( - url, - ORIGIN_EXTERNAL_REQUEST_FORCED_CELLULAR, - FINAL_STATUS_USED); - std::unique_ptr<PrerenderHandle> prerender_handle( - prerender_manager()->AddPrerenderOnCellularFromExternalRequest( - url, content::Referrer(), nullptr, kSize)); - EXPECT_TRUE(prerender_handle); - EXPECT_TRUE(prerender_handle->IsPrerendering()); - EXPECT_TRUE(prerender_contents->prerendering_has_started()); - EXPECT_EQ(prerender_contents, prerender_handle->contents()); - EXPECT_EQ(ORIGIN_EXTERNAL_REQUEST_FORCED_CELLULAR, - prerender_handle->contents()->origin()); - ASSERT_EQ(prerender_contents, prerender_manager()->FindAndUseEntry(url)); + for (Origin origin: origins) { + DummyPrerenderContents* prerender_contents = nullptr; + std::unique_ptr<PrerenderHandle> prerender_handle; + if (origin == ORIGIN_OFFLINE) { + prerender_contents = prerender_manager()->CreateNextPrerenderContents( + url, origin, FINAL_STATUS_MANAGER_SHUTDOWN); + prerender_handle.reset(prerender_manager()->AddPrerenderForOffline( + url, nullptr, kSize)); + } else { + prerender_contents = prerender_manager()->CreateNextPrerenderContents( + url, origin, FINAL_STATUS_USED); + prerender_handle.reset( + prerender_manager()->AddPrerenderOnCellularFromExternalRequest( + url, content::Referrer(), nullptr, kSize)); + } + EXPECT_TRUE(prerender_handle); + EXPECT_TRUE(prerender_handle->IsPrerendering()); + EXPECT_TRUE(prerender_contents->prerendering_has_started()); + EXPECT_EQ(prerender_contents, prerender_handle->contents()); + EXPECT_EQ(origin, prerender_handle->contents()->origin()); + if (origin != ORIGIN_OFFLINE) + ASSERT_EQ(prerender_contents, prerender_manager()->FindAndUseEntry(url)); + } } TEST_F(PrerenderTest, LinkManagerCancel) {
diff --git a/chrome/browser/profiles/off_the_record_profile_io_data.cc b/chrome/browser/profiles/off_the_record_profile_io_data.cc index 8ac61f1..13e8f7f 100644 --- a/chrome/browser/profiles/off_the_record_profile_io_data.cc +++ b/chrome/browser/profiles/off_the_record_profile_io_data.cc
@@ -332,11 +332,23 @@ // extensions API, but we need to update it to understand isolated apps first. context->SetCookieStore( content::CreateCookieStore(content::CookieStoreConfig())); + std::unique_ptr<net::ChannelIDService> channel_id_service( + new net::ChannelIDService(new net::DefaultChannelIDStore(nullptr), + base::WorkerPool::GetTaskRunner(true))); + + // Build a new HttpNetworkSession that uses the new ChannelIDService. + net::HttpNetworkSession::Params network_params = + http_network_session_->params(); + network_params.channel_id_service = channel_id_service.get(); + std::unique_ptr<net::HttpNetworkSession> http_network_session( + new net::HttpNetworkSession(network_params)); // Use a separate in-memory cache for the app. std::unique_ptr<net::HttpCache> app_http_cache = CreateHttpFactory( - http_network_session_.get(), net::HttpCache::DefaultBackend::InMemory(0)); + http_network_session.get(), net::HttpCache::DefaultBackend::InMemory(0)); + context->SetChannelIDService(std::move(channel_id_service)); + context->SetHttpNetworkSession(std::move(http_network_session)); context->SetHttpTransactionFactory(std::move(app_http_cache)); std::unique_ptr<net::URLRequestJobFactoryImpl> job_factory(
diff --git a/chrome/browser/profiles/profile_browsertest.cc b/chrome/browser/profiles/profile_browsertest.cc index 2dc8064..cc98501 100644 --- a/chrome/browser/profiles/profile_browsertest.cc +++ b/chrome/browser/profiles/profile_browsertest.cc
@@ -38,6 +38,10 @@ #include "content/public/browser/browser_thread.h" #include "content/public/browser/storage_partition.h" #include "content/public/test/test_utils.h" +#include "extensions/browser/extension_registry.h" +#include "extensions/common/extension.h" +#include "extensions/common/extension_builder.h" +#include "extensions/common/value_builder.h" #include "net/base/net_errors.h" #include "net/test/url_request/url_request_failed_job.h" #include "net/url_request/url_fetcher.h" @@ -421,6 +425,133 @@ FlushIoTaskRunnerAndSpinThreads(); } +namespace { + +scoped_refptr<const extensions::Extension> BuildTestApp(Profile* profile) { + scoped_refptr<const extensions::Extension> app; + app = + extensions::ExtensionBuilder() + .SetManifest( + extensions::DictionaryBuilder() + .Set("name", "test app") + .Set("version", "1") + .Set("app", + extensions::DictionaryBuilder() + .Set("background", + extensions::DictionaryBuilder() + .Set("scripts", extensions::ListBuilder() + .Append("background.js") + .Build()) + .Build()) + .Build()) + .Build()) + .Build(); + extensions::ExtensionRegistry* registry = + extensions::ExtensionRegistry::Get(profile); + EXPECT_TRUE(registry->AddEnabled(app)); + return app; +} + +void CompareURLRequestContexts( + net::URLRequestContextGetter* extension_context_getter, + net::URLRequestContextGetter* main_context_getter) { + net::URLRequestContext* extension_context = + extension_context_getter->GetURLRequestContext(); + net::URLRequestContext* main_context = + main_context_getter->GetURLRequestContext(); + + // Check that the URLRequestContexts are different and that their + // ChannelIDServices and CookieStores are different. + EXPECT_NE(extension_context, main_context); + EXPECT_NE(extension_context->channel_id_service(), + main_context->channel_id_service()); + EXPECT_NE(extension_context->cookie_store(), main_context->cookie_store()); + + // Check that the ChannelIDService in the HttpNetworkSession is the same as + // the one directly on the URLRequestContext. + EXPECT_EQ(extension_context->http_transaction_factory() + ->GetSession() + ->params() + .channel_id_service, + extension_context->channel_id_service()); + EXPECT_EQ(main_context->http_transaction_factory() + ->GetSession() + ->params() + .channel_id_service, + main_context->channel_id_service()); +} + +} // namespace + +IN_PROC_BROWSER_TEST_F(ProfileBrowserTest, URLRequestContextIsolation) { + base::ScopedTempDir temp_dir; + ASSERT_TRUE(temp_dir.CreateUniqueTempDir()); + + MockProfileDelegate delegate; + EXPECT_CALL(delegate, OnProfileCreated(testing::NotNull(), true, true)); + + { + std::unique_ptr<Profile> profile(CreateProfile( + temp_dir.path(), &delegate, Profile::CREATE_MODE_SYNCHRONOUS)); + + scoped_refptr<const extensions::Extension> app = + BuildTestApp(profile.get()); + content::StoragePartition* extension_partition = + content::BrowserContext::GetStoragePartitionForSite( + profile.get(), + extensions::Extension::GetBaseURLFromExtensionId(app->id())); + net::URLRequestContextGetter* extension_context_getter = + extension_partition->GetURLRequestContext(); + net::URLRequestContextGetter* main_context_getter = + profile->GetRequestContext(); + + base::RunLoop run_loop; + content::BrowserThread::PostTaskAndReply( + content::BrowserThread::IO, FROM_HERE, + base::Bind(&CompareURLRequestContexts, extension_context_getter, + main_context_getter), + run_loop.QuitClosure()); + run_loop.Run(); + } + + FlushIoTaskRunnerAndSpinThreads(); +} + +IN_PROC_BROWSER_TEST_F(ProfileBrowserTest, + OffTheRecordURLRequestContextIsolation) { + base::ScopedTempDir temp_dir; + ASSERT_TRUE(temp_dir.CreateUniqueTempDir()); + + MockProfileDelegate delegate; + EXPECT_CALL(delegate, OnProfileCreated(testing::NotNull(), true, true)); + + { + std::unique_ptr<Profile> profile(CreateProfile( + temp_dir.path(), &delegate, Profile::CREATE_MODE_SYNCHRONOUS)); + Profile* otr_profile = profile->GetOffTheRecordProfile(); + + scoped_refptr<const extensions::Extension> app = BuildTestApp(otr_profile); + content::StoragePartition* extension_partition = + content::BrowserContext::GetStoragePartitionForSite( + otr_profile, + extensions::Extension::GetBaseURLFromExtensionId(app->id())); + net::URLRequestContextGetter* extension_context_getter = + extension_partition->GetURLRequestContext(); + net::URLRequestContextGetter* main_context_getter = + otr_profile->GetRequestContext(); + + base::RunLoop run_loop; + content::BrowserThread::PostTaskAndReply( + content::BrowserThread::IO, FROM_HERE, + base::Bind(&CompareURLRequestContexts, extension_context_getter, + main_context_getter), + run_loop.QuitClosure()); + run_loop.Run(); + } + + FlushIoTaskRunnerAndSpinThreads(); +} + // The EndSession IO synchronization is only critical on Windows, but also // happens under the USE_X11 define. See BrowserProcessImpl::EndSession. #if defined(USE_X11) || defined(OS_WIN) || defined(USE_OZONE)
diff --git a/chrome/browser/profiles/profile_impl_io_data.cc b/chrome/browser/profiles/profile_impl_io_data.cc index 59860504..93c99e4 100644 --- a/chrome/browser/profiles/profile_impl_io_data.cc +++ b/chrome/browser/profiles/profile_impl_io_data.cc
@@ -623,6 +623,8 @@ base::FilePath cookie_path = partition_descriptor.path.Append( chrome::kCookieFilename); + base::FilePath channel_id_path = + partition_descriptor.path.Append(chrome::kChannelIDFilename); base::FilePath cache_path = partition_descriptor.path.Append(chrome::kCacheDirname); @@ -638,10 +640,9 @@ app_cache_max_size_, BrowserThread::GetMessageLoopProxyForThread(BrowserThread::CACHE))); } - std::unique_ptr<net::HttpCache> app_http_cache = - CreateHttpFactory(http_network_session_.get(), std::move(app_backend)); std::unique_ptr<net::CookieStore> cookie_store; + scoped_refptr<net::SQLiteChannelIDStore> channel_id_db; if (partition_descriptor.in_memory) { cookie_store = content::CreateCookieStore(content::CookieStoreConfig()); } else { @@ -656,7 +657,29 @@ nullptr, nullptr); cookie_config.crypto_delegate = cookie_config::GetCookieCryptoDelegate(); cookie_store = content::CreateCookieStore(cookie_config); + channel_id_db = new net::SQLiteChannelIDStore( + channel_id_path, + BrowserThread::GetBlockingPool()->GetSequencedTaskRunner( + base::SequencedWorkerPool::GetSequenceToken())); } + std::unique_ptr<net::ChannelIDService> channel_id_service( + new net::ChannelIDService( + new net::DefaultChannelIDStore(channel_id_db.get()), + base::WorkerPool::GetTaskRunner(true))); + + // Build a new HttpNetworkSession that uses the new ChannelIDService. + net::HttpNetworkSession::Params network_params = + http_network_session_->params(); + network_params.channel_id_service = channel_id_service.get(); + std::unique_ptr<net::HttpNetworkSession> http_network_session( + new net::HttpNetworkSession(network_params)); + std::unique_ptr<net::HttpCache> app_http_cache = + CreateHttpFactory(http_network_session.get(), std::move(app_backend)); + + // Transfer ownership of the ChannelIDStore and the HttpNetworkSession to the + // AppRequestContext. + context->SetChannelIDService(std::move(channel_id_service)); + context->SetHttpNetworkSession(std::move(http_network_session)); // Transfer ownership of the cookies and cache to AppRequestContext. context->SetCookieStore(std::move(cookie_store));
diff --git a/chrome/browser/profiles/profile_io_data.cc b/chrome/browser/profiles/profile_io_data.cc index 39ec762..5a82008 100644 --- a/chrome/browser/profiles/profile_io_data.cc +++ b/chrome/browser/profiles/profile_io_data.cc
@@ -573,6 +573,17 @@ set_cookie_store(cookie_store_.get()); } +void ProfileIOData::AppRequestContext::SetChannelIDService( + std::unique_ptr<net::ChannelIDService> channel_id_service) { + channel_id_service_ = std::move(channel_id_service); + set_channel_id_service(channel_id_service_.get()); +} + +void ProfileIOData::AppRequestContext::SetHttpNetworkSession( + std::unique_ptr<net::HttpNetworkSession> http_network_session) { + http_network_session_ = std::move(http_network_session); +} + void ProfileIOData::AppRequestContext::SetHttpTransactionFactory( std::unique_ptr<net::HttpTransactionFactory> http_factory) { http_factory_ = std::move(http_factory);
diff --git a/chrome/browser/profiles/profile_io_data.h b/chrome/browser/profiles/profile_io_data.h index de32c6e..46f218b5 100644 --- a/chrome/browser/profiles/profile_io_data.h +++ b/chrome/browser/profiles/profile_io_data.h
@@ -267,6 +267,10 @@ AppRequestContext(); void SetCookieStore(std::unique_ptr<net::CookieStore> cookie_store); + void SetChannelIDService( + std::unique_ptr<net::ChannelIDService> channel_id_service); + void SetHttpNetworkSession( + std::unique_ptr<net::HttpNetworkSession> http_network_session); void SetHttpTransactionFactory( std::unique_ptr<net::HttpTransactionFactory> http_factory); void SetJobFactory(std::unique_ptr<net::URLRequestJobFactory> job_factory); @@ -275,6 +279,8 @@ ~AppRequestContext() override; std::unique_ptr<net::CookieStore> cookie_store_; + std::unique_ptr<net::ChannelIDService> channel_id_service_; + std::unique_ptr<net::HttpNetworkSession> http_network_session_; std::unique_ptr<net::HttpTransactionFactory> http_factory_; std::unique_ptr<net::URLRequestJobFactory> job_factory_; };
diff --git a/chrome/browser/safe_browsing/safe_browsing_service.cc b/chrome/browser/safe_browsing/safe_browsing_service.cc index a9e5bfc1..4cc6b1a 100644 --- a/chrome/browser/safe_browsing/safe_browsing_service.cc +++ b/chrome/browser/safe_browsing/safe_browsing_service.cc
@@ -20,6 +20,7 @@ #include "base/strings/string_util.h" #include "base/threading/thread.h" #include "base/threading/thread_restrictions.h" +#include "base/threading/worker_pool.h" #include "base/trace_event/trace_event.h" #include "build/build_config.h" #include "chrome/browser/browser_process.h" @@ -46,6 +47,11 @@ #include "google_apis/google_api_keys.h" #include "net/cookies/cookie_store.h" #include "net/extras/sqlite/cookie_crypto_delegate.h" +#include "net/extras/sqlite/sqlite_channel_id_store.h" +#include "net/http/http_network_layer.h" +#include "net/http/http_transaction_factory.h" +#include "net/ssl/channel_id_service.h" +#include "net/ssl/default_channel_id_store.h" #include "net/url_request/url_request_context.h" #include "net/url_request/url_request_context_getter.h" @@ -80,6 +86,8 @@ // Filename suffix for the cookie database. const base::FilePath::CharType kCookiesFile[] = FILE_PATH_LITERAL(" Cookies"); +const base::FilePath::CharType kChannelIDFile[] = + FILE_PATH_LITERAL(" Channel IDs"); // The default URL prefix where browser fetches chunk updates, hashes, // and reports safe browsing hits and malware details. @@ -105,6 +113,11 @@ SafeBrowsingService::GetBaseFilename().value() + kCookiesFile); } +base::FilePath ChannelIDFilePath() { + return base::FilePath(SafeBrowsingService::GetBaseFilename().value() + + kChannelIDFile); +} + } // namespace class SafeBrowsingURLRequestContextGetter @@ -135,6 +148,10 @@ std::unique_ptr<net::URLRequestContext> safe_browsing_request_context_; scoped_refptr<base::SingleThreadTaskRunner> network_task_runner_; + + std::unique_ptr<net::ChannelIDService> channel_id_service_; + std::unique_ptr<net::HttpNetworkSession> http_network_session_; + std::unique_ptr<net::HttpTransactionFactory> http_transaction_factory_; }; SafeBrowsingURLRequestContextGetter::SafeBrowsingURLRequestContextGetter( @@ -166,17 +183,36 @@ nullptr)); safe_browsing_request_context_->set_cookie_store( safe_browsing_cookie_store_.get()); - // The above cookie store will persist cookies, but the ChannelIDService in - // the system request context is ephemeral, which could lead to losing the - // keys that cookies are bound to. Since this is only used for safe - // browsing, any cookie bindings don't matter. - // - // For crbug.com/548423, the channel ID store and cookie store used for a - // request are being tracked to see if an ephemeral channel ID store is used - // with a persistent cookie store (which apart from here would be a bug). - // The following line tells that tracking to ignore the mismatch from this - // URLRequestContext. - safe_browsing_request_context_->set_has_known_mismatched_cookie_store(); + + // Set up the ChannelIDService + scoped_refptr<net::SQLiteChannelIDStore> channel_id_db = + new net::SQLiteChannelIDStore( + ChannelIDFilePath(), + BrowserThread::GetBlockingPool()->GetSequencedTaskRunner( + base::SequencedWorkerPool::GetSequenceToken())); + channel_id_service_.reset(new net::ChannelIDService( + new net::DefaultChannelIDStore(channel_id_db.get()), + base::WorkerPool::GetTaskRunner(true))); + safe_browsing_request_context_->set_channel_id_service( + channel_id_service_.get()); + + // Rebuild the HttpNetworkSession and the HttpTransactionFactory to use the + // new ChannelIDService. + if (safe_browsing_request_context_->http_transaction_factory() && + safe_browsing_request_context_->http_transaction_factory() + ->GetSession()) { + net::HttpNetworkSession::Params safe_browsing_params = + safe_browsing_request_context_->http_transaction_factory() + ->GetSession() + ->params(); + safe_browsing_params.channel_id_service = channel_id_service_.get(); + http_network_session_.reset( + new net::HttpNetworkSession(safe_browsing_params)); + http_transaction_factory_.reset( + new net::HttpNetworkLayer(http_network_session_.get())); + safe_browsing_request_context_->set_http_transaction_factory( + http_transaction_factory_.get()); + } } return safe_browsing_request_context_.get();
diff --git a/chrome/browser/ui/BUILD.gn b/chrome/browser/ui/BUILD.gn index 5e94bece..32cb2a36 100644 --- a/chrome/browser/ui/BUILD.gn +++ b/chrome/browser/ui/BUILD.gn
@@ -282,10 +282,6 @@ if (enable_extensions) { deps += [ "//extensions/components/native_app_window" ] - sources += - rebase_path(gypi_values.chrome_browser_ui_views_extensions_sources, - ".", - "//chrome") } if (!is_chromeos && (!is_mac || mac_views_browser)) {
diff --git a/chrome/browser/ui/ash/launcher/arc_app_window_launcher_controller.cc b/chrome/browser/ui/ash/launcher/arc_app_window_launcher_controller.cc index 1f78d40..89dc626 100644 --- a/chrome/browser/ui/ash/launcher/arc_app_window_launcher_controller.cc +++ b/chrome/browser/ui/ash/launcher/arc_app_window_launcher_controller.cc
@@ -280,6 +280,11 @@ TaskIdToAppWindow::iterator new_active_app_it = task_id_to_app_window_.find(active_task_id_); if (new_active_app_it != task_id_to_app_window_.end()) { + // Activate root Arc widget if active task has been changed. This can be + // due creating of the new Arc app or bringing an existing app to the front. + if (new_active_app_it != previous_active_app_it && root_widget_) + root_widget_->Activate(); + owner()->SetItemStatus(new_active_app_it->second->shelf_id(), root_widget_ && root_widget_->IsActive() ? ash::STATUS_ACTIVE
diff --git a/chrome/browser/ui/cocoa/extensions/extension_install_dialog_controller.mm b/chrome/browser/ui/cocoa/extensions/extension_install_dialog_controller.mm index 48bfd54..e36188d 100644 --- a/chrome/browser/ui/cocoa/extensions/extension_install_dialog_controller.mm +++ b/chrome/browser/ui/cocoa/extensions/extension_install_dialog_controller.mm
@@ -14,7 +14,6 @@ #include "chrome/browser/extensions/api/experience_sampling_private/experience_sampling.h" #include "chrome/browser/extensions/extension_install_prompt_show_params.h" #include "chrome/browser/ui/browser.h" -#include "chrome/browser/ui/browser_dialogs.h" #include "chrome/browser/ui/browser_finder.h" #import "chrome/browser/ui/cocoa/constrained_window/constrained_window_custom_sheet.h" #include "chrome/browser/ui/cocoa/constrained_window/constrained_window_custom_window.h" @@ -113,7 +112,5 @@ // static ExtensionInstallPrompt::ShowDialogCallback ExtensionInstallPrompt::GetDefaultShowDialogCallback() { - if (chrome::ToolkitViewsWebUIDialogsEnabled()) - return ExtensionInstallPrompt::GetViewsShowDialogCallback(); return base::Bind(&ShowExtensionInstallDialogImpl); }
diff --git a/chrome/browser/ui/views/bookmarks/bookmark_bar_view.cc b/chrome/browser/ui/views/bookmarks/bookmark_bar_view.cc index 23adb22..b8abfecd 100644 --- a/chrome/browser/ui/views/bookmarks/bookmark_bar_view.cc +++ b/chrome/browser/ui/views/bookmarks/bookmark_bar_view.cc
@@ -88,6 +88,7 @@ #include "ui/gfx/canvas.h" #include "ui/gfx/color_utils.h" #include "ui/gfx/favicon_size.h" +#include "ui/gfx/geometry/rect.h" #include "ui/gfx/paint_vector_icon.h" #include "ui/gfx/scoped_canvas.h" #include "ui/gfx/text_constants.h" @@ -189,10 +190,10 @@ return kHorizontalMargin[ui::MaterialDesignController::GetMode()]; } -gfx::Size CalculateInkDropSize(const gfx::Size& button_size) { - gfx::Size ink_drop_size(button_size); - ink_drop_size.Enlarge(0, -2); - return ink_drop_size; +gfx::Rect CalculateInkDropBounds(const gfx::Size& size) { + gfx::Rect ink_drop_bounds(size); + ink_drop_bounds.Inset(0, 1); + return ink_drop_bounds; } // BookmarkButtonBase ----------------------------------------------- @@ -240,16 +241,17 @@ std::unique_ptr<views::InkDropAnimation> CreateInkDropAnimation() const override { return base::WrapUnique(new views::FloodFillInkDropAnimation( - CalculateInkDropSize(size()), GetInkDropCenter(), + CalculateInkDropBounds(size()), GetInkDropCenter(), GetInkDropBaseColor())); } std::unique_ptr<views::InkDropHover> CreateInkDropHover() const override { if (!ShouldShowInkDropHover()) return nullptr; - return base::WrapUnique( - new views::InkDropHover(CalculateInkDropSize(size()), 0, - GetInkDropCenter(), GetInkDropBaseColor())); + + const gfx::Rect bounds = CalculateInkDropBounds(size()); + return base::WrapUnique(new views::InkDropHover( + bounds.size(), 0, bounds.CenterPoint(), GetInkDropBaseColor())); } SkColor GetInkDropBaseColor() const override { @@ -341,16 +343,17 @@ std::unique_ptr<views::InkDropAnimation> CreateInkDropAnimation() const override { return base::WrapUnique(new views::FloodFillInkDropAnimation( - CalculateInkDropSize(size()), GetInkDropCenter(), + CalculateInkDropBounds(size()), GetInkDropCenter(), GetInkDropBaseColor())); } std::unique_ptr<views::InkDropHover> CreateInkDropHover() const override { if (!ShouldShowInkDropHover()) return nullptr; - return base::WrapUnique( - new views::InkDropHover(CalculateInkDropSize(size()), 0, - GetInkDropCenter(), GetInkDropBaseColor())); + + const gfx::Rect bounds = CalculateInkDropBounds(size()); + return base::WrapUnique(new views::InkDropHover( + bounds.size(), 0, bounds.CenterPoint(), GetInkDropBaseColor())); } SkColor GetInkDropBaseColor() const override {
diff --git a/chrome/browser/ui/views/download/download_item_view_md.cc b/chrome/browser/ui/views/download/download_item_view_md.cc index 66d4394..f2c6bbf 100644 --- a/chrome/browser/ui/views/download/download_item_view_md.cc +++ b/chrome/browser/ui/views/download/download_item_view_md.cc
@@ -476,7 +476,7 @@ std::unique_ptr<views::InkDropAnimation> DownloadItemViewMd::CreateInkDropAnimation() const { return base::WrapUnique(new views::FloodFillInkDropAnimation( - size(), ink_drop_delegate_.last_ink_drop_location(), + GetLocalBounds(), ink_drop_delegate_.last_ink_drop_location(), color_utils::DeriveDefaultIconColor(GetTextColor()))); } @@ -835,6 +835,10 @@ if (complete_animation_.get() && complete_animation_->is_animating()) complete_animation_->End(); + // Don't show the ripple for right clicks. + if (!active_event) + return; + ink_drop_delegate_.set_last_ink_drop_location(event.location()); ink_drop_delegate_.OnAction(views::InkDropState::ACTION_PENDING); }
diff --git a/chrome/browser/ui/views/extensions/extension_install_dialog_view.cc b/chrome/browser/ui/views/extensions/extension_install_dialog_view.cc index e72f60e..59e8e5c 100644 --- a/chrome/browser/ui/views/extensions/extension_install_dialog_view.cc +++ b/chrome/browser/ui/views/extensions/extension_install_dialog_view.cc
@@ -771,19 +771,8 @@ arrow_toggle_->SetImage(views::Button::STATE_NORMAL, &icon); } -// On Mac, GetViewsShowDialogCallback is defined in Cocoa code. -#if !defined(OS_MACOSX) // static ExtensionInstallPrompt::ShowDialogCallback ExtensionInstallPrompt::GetDefaultShowDialogCallback() { return base::Bind(&ShowExtensionInstallDialogImpl); } -#endif - -#if defined(OS_MACOSX) -// static -ExtensionInstallPrompt::ShowDialogCallback -ExtensionInstallPrompt::GetViewsShowDialogCallback() { - return base::Bind(&ShowExtensionInstallDialogImpl); -} -#endif
diff --git a/chrome/browser/ui/webui/popular_sites_internals_message_handler.cc b/chrome/browser/ui/webui/popular_sites_internals_message_handler.cc index d6a1c3bce..9534044 100644 --- a/chrome/browser/ui/webui/popular_sites_internals_message_handler.cc +++ b/chrome/browser/ui/webui/popular_sites_internals_message_handler.cc
@@ -14,6 +14,7 @@ #include "base/values.h" #include "chrome/browser/android/ntp/popular_sites.h" #include "chrome/browser/profiles/profile.h" +#include "chrome/browser/search_engines/template_url_service_factory.h" #include "components/url_formatter/url_fixer.h" #include "content/public/browser/browser_thread.h" #include "content/public/browser/web_ui.h" @@ -55,8 +56,12 @@ std::string country; std::string version; + Profile* profile = Profile::FromWebUI(web_ui()); popular_sites_.reset(new PopularSites( - Profile::FromWebUI(web_ui()), country, version, false, + profile->GetPrefs(), + TemplateURLServiceFactory::GetForProfile(profile), + profile->GetRequestContext(), + country, version, false, base::Bind(&PopularSitesInternalsMessageHandler::OnPopularSitesAvailable, base::Unretained(this), false))); } @@ -64,6 +69,7 @@ void PopularSitesInternalsMessageHandler::HandleDownload( const base::ListValue* args) { DCHECK_EQ(3u, args->GetSize()); + Profile* profile = Profile::FromWebUI(web_ui()); auto callback = base::Bind(&PopularSitesInternalsMessageHandler::OnPopularSitesAvailable, base::Unretained(this), true); @@ -72,7 +78,9 @@ args->GetString(0, &url); if (!url.empty()) { popular_sites_.reset(new PopularSites( - Profile::FromWebUI(web_ui()), + profile->GetPrefs(), + TemplateURLServiceFactory::GetForProfile(profile), + profile->GetRequestContext(), url_formatter::FixupURL(url, std::string()), callback)); return; } @@ -80,8 +88,11 @@ args->GetString(1, &country); std::string version; args->GetString(2, &version); - popular_sites_.reset(new PopularSites(Profile::FromWebUI(web_ui()), country, - version, true, callback)); + popular_sites_.reset(new PopularSites( + profile->GetPrefs(), + TemplateURLServiceFactory::GetForProfile(profile), + profile->GetRequestContext(), + country, version, true, callback)); } void PopularSitesInternalsMessageHandler::HandleViewJson(
diff --git a/chrome/chrome_browser_ui.gypi b/chrome/chrome_browser_ui.gypi index 4bb431c..670959c 100644 --- a/chrome/chrome_browser_ui.gypi +++ b/chrome/chrome_browser_ui.gypi
@@ -2531,9 +2531,6 @@ 'browser/ui/views/website_settings/permissions_bubble_view.cc', 'browser/ui/views/website_settings/permissions_bubble_view.h', ], - 'chrome_browser_ui_views_extensions_sources': [ - 'browser/ui/views/extensions/extension_install_dialog_view.cc', - ], 'chrome_browser_ui_views_extensions_non_mac_sources': [ 'browser/ui/views/extensions/bookmark_app_confirmation_view.cc', 'browser/ui/views/extensions/bookmark_app_confirmation_view.h', @@ -2547,6 +2544,7 @@ 'browser/ui/views/extensions/extension_dialog.h', 'browser/ui/views/extensions/extension_dialog_observer.cc', 'browser/ui/views/extensions/extension_dialog_observer.h', + 'browser/ui/views/extensions/extension_install_dialog_view.cc', 'browser/ui/views/extensions/extension_installed_bubble_view.cc', 'browser/ui/views/extensions/extension_popup.cc', 'browser/ui/views/extensions/extension_popup.h', @@ -3089,7 +3087,6 @@ 'dependencies': [ '<(DEPTH)/extensions/components/extensions_components.gyp:native_app_window', ], - 'sources': [ '<@(chrome_browser_ui_views_extensions_sources)' ] }], ], }],
diff --git a/components/cronet/android/java/src/org/chromium/net/CronetLibraryLoader.java b/components/cronet/android/java/src/org/chromium/net/CronetLibraryLoader.java index 0ce0b5430..3522c6b 100644 --- a/components/cronet/android/java/src/org/chromium/net/CronetLibraryLoader.java +++ b/components/cronet/android/java/src/org/chromium/net/CronetLibraryLoader.java
@@ -34,7 +34,9 @@ if (sInitTaskPosted) { return; } + ContextUtils.initApplicationContext(context.getApplicationContext()); builder.loadLibrary(); + ContextUtils.initApplicationContextForNative(); if (!Version.CRONET_VERSION.equals(nativeGetCronetVersion())) { throw new RuntimeException(String.format( "Expected Cronet version number %s, " @@ -44,9 +46,9 @@ } Log.i(TAG, "Cronet version: %s, arch: %s", Version.CRONET_VERSION, System.getProperty("os.arch")); - ContextUtils.initApplicationContext(context.getApplicationContext()); // Init native Chromium CronetEngine on Main UI thread. Runnable task = new Runnable() { + @Override public void run() { initOnMainThread(context); }
diff --git a/components/cronet/android/test/javatests/src/org/chromium/net/CronetUrlRequestContextTest.java b/components/cronet/android/test/javatests/src/org/chromium/net/CronetUrlRequestContextTest.java index 5353b8a..6807d80 100644 --- a/components/cronet/android/test/javatests/src/org/chromium/net/CronetUrlRequestContextTest.java +++ b/components/cronet/android/test/javatests/src/org/chromium/net/CronetUrlRequestContextTest.java
@@ -1112,6 +1112,7 @@ @SmallTest @Feature({"Cronet"}) + @OnlyRunNativeCronet public void testSkipLibraryLoading() throws Exception { CronetEngine.Builder builder = new CronetEngine.Builder(getContext()); TestBadLibraryLoader loader = new TestBadLibraryLoader();
diff --git a/components/offline_pages/offline_page_model.cc b/components/offline_pages/offline_page_model.cc index f7260a6c..66d8c9ec 100644 --- a/components/offline_pages/offline_page_model.cc +++ b/components/offline_pages/offline_page_model.cc
@@ -294,6 +294,27 @@ callback.Run(has_pages); } +void OfflinePageModel::CheckPagesExistOffline( + const std::set<GURL>& urls, + const CheckPagesExistOfflineCallback& callback) { + RunWhenLoaded( + base::Bind(&OfflinePageModel::CheckPagesExistOfflineAfterLoadDone, + weak_ptr_factory_.GetWeakPtr(), urls, callback)); +} + +void OfflinePageModel::CheckPagesExistOfflineAfterLoadDone( + const std::set<GURL>& urls, + const CheckPagesExistOfflineCallback& callback) { + DCHECK(is_loaded_); + CheckPagesExistOfflineResult result; + for (const auto& id_page_pair : offline_pages_) { + auto iter = urls.find(id_page_pair.second.url); + if (iter != urls.end()) + result.insert(*iter); + } + callback.Run(result); +} + void OfflinePageModel::GetAllPages(const GetAllPagesCallback& callback) { if (!is_loaded_) { delayed_tasks_.push_back(
diff --git a/components/offline_pages/offline_page_model.h b/components/offline_pages/offline_page_model.h index 3579791..35084369 100644 --- a/components/offline_pages/offline_page_model.h +++ b/components/offline_pages/offline_page_model.h
@@ -9,6 +9,7 @@ #include <map> #include <memory> +#include <set> #include <vector> #include "base/callback.h" @@ -123,10 +124,13 @@ }; typedef std::vector<OfflinePageItem> GetAllPagesResult; + typedef std::set<GURL> CheckPagesExistOfflineResult; typedef base::Callback<void(SavePageResult, int64_t)> SavePageCallback; typedef base::Callback<void(DeletePageResult)> DeletePageCallback; typedef base::Callback<void(const GetAllPagesResult&)> GetAllPagesCallback; + typedef base::Callback<void(const CheckPagesExistOfflineResult&)> + CheckPagesExistOfflineCallback; typedef base::Callback<void(bool)> HasPagesCallback; // Generates a new offline id @@ -179,6 +183,11 @@ void HasPages(const std::string& name_space, const HasPagesCallback& callback); + // Returns via callback all GURLs in |urls| that are equal to the online URL + // of any offline page. + void CheckPagesExistOffline(const std::set<GURL>& urls, + const CheckPagesExistOfflineCallback& callback); + // Gets all available offline pages. Requires that the model is loaded. void GetAllPages(const GetAllPagesCallback& callback); @@ -237,6 +246,9 @@ void OnEnsureArchivesDirCreatedDone(); void GetAllPagesAfterLoadDone(const GetAllPagesCallback& callback); + void CheckPagesExistOfflineAfterLoadDone( + const std::set<GURL>& urls, + const CheckPagesExistOfflineCallback& callback); // Callback for checking whether we have offline pages. void HasPagesAfterLoadDone(const std::string& name_space,
diff --git a/components/offline_pages/offline_page_model_unittest.cc b/components/offline_pages/offline_page_model_unittest.cc index b8d7e2f..d6a8435 100644 --- a/components/offline_pages/offline_page_model_unittest.cc +++ b/components/offline_pages/offline_page_model_unittest.cc
@@ -30,6 +30,8 @@ using SavePageResult = offline_pages::OfflinePageModel::SavePageResult; using DeletePageResult = offline_pages::OfflinePageModel::DeletePageResult; using GetAllPagesResult = offline_pages::OfflinePageModel::GetAllPagesResult; +using CheckPagesExistOfflineResult = + offline_pages::OfflinePageModel::CheckPagesExistOfflineResult; namespace offline_pages { @@ -77,6 +79,7 @@ void OnSavePageDone(SavePageResult result, int64_t offline_id); void OnDeletePageDone(DeletePageResult result); void OnHasPagesDone(bool result); + void OnCheckPagesExistOfflineDone(const CheckPagesExistOfflineResult& result); void OnClearAllDone(); // OfflinePageMetadataStore callbacks. @@ -115,6 +118,7 @@ } bool HasPages(std::string name_space); + CheckPagesExistOfflineResult CheckPagesExistOffline(std::set<GURL>); OfflinePageModel* model() { return model_.get(); } @@ -148,6 +152,7 @@ int64_t last_deleted_offline_id_; ClientId last_deleted_client_id_; bool last_has_pages_result_; + CheckPagesExistOfflineResult last_pages_exist_result_; }; OfflinePageModelTest::OfflinePageModelTest() @@ -213,6 +218,11 @@ last_has_pages_result_ = result; } +void OfflinePageModelTest::OnCheckPagesExistOfflineDone( + const CheckPagesExistOfflineResult& result) { + last_pages_exist_result_ = result; +} + void OfflinePageModelTest::OnClearAllDone() { PumpLoop(); } @@ -260,6 +270,7 @@ last_save_result_ = SavePageResult::CANCELLED; last_delete_result_ = DeletePageResult::CANCELLED; last_archiver_path_.clear(); + last_pages_exist_result_.clear(); } OfflinePageTestStore* OfflinePageModelTest::GetStore() { @@ -290,6 +301,15 @@ return all_pages_; } +CheckPagesExistOfflineResult OfflinePageModelTest::CheckPagesExistOffline( + std::set<GURL> pages) { + model()->CheckPagesExistOffline( + pages, base::Bind(&OfflinePageModelTest::OnCheckPagesExistOfflineDone, + AsWeakPtr())); + PumpLoop(); + return last_pages_exist_result_; +} + bool OfflinePageModelTest::HasPages(std::string name_space) { model()->HasPages( name_space, @@ -750,6 +770,22 @@ EXPECT_FALSE(page); } +TEST_F(OfflinePageModelTest, CheckPagesExistOffline) { + SavePage(kTestUrl, kTestClientId1); + SavePage(kTestUrl2, kTestClientId2); + + std::set<GURL> input; + input.insert(kTestUrl); + input.insert(kTestUrl2); + input.insert(kTestUrl3); + + CheckPagesExistOfflineResult existing_pages = CheckPagesExistOffline(input); + EXPECT_EQ(2U, existing_pages.size()); + EXPECT_NE(existing_pages.end(), existing_pages.find(kTestUrl)); + EXPECT_NE(existing_pages.end(), existing_pages.find(kTestUrl2)); + EXPECT_EQ(existing_pages.end(), existing_pages.find(kTestUrl3)); +} + // Test that model returns pages that are older than 30 days as candidates for // clean up, hence the numbers in time delta. TEST_F(OfflinePageModelTest, GetPagesToCleanUp) {
diff --git a/components/page_load_metrics/renderer/metrics_render_frame_observer.cc b/components/page_load_metrics/renderer/metrics_render_frame_observer.cc index aa14692..ee1cc6c 100644 --- a/components/page_load_metrics/renderer/metrics_render_frame_observer.cc +++ b/components/page_load_metrics/renderer/metrics_render_frame_observer.cc
@@ -65,8 +65,10 @@ // non-null, we will send metrics for the current page at some later time, as // those metrics become available. if (ShouldSendMetrics()) { + PageLoadTiming timing(GetTiming()); + DCHECK(!timing.navigation_start.is_null()); page_timing_metrics_sender_.reset( - new PageTimingMetricsSender(this, routing_id(), CreateTimer())); + new PageTimingMetricsSender(this, routing_id(), CreateTimer(), timing)); } }
diff --git a/components/page_load_metrics/renderer/metrics_render_frame_observer_unittest.cc b/components/page_load_metrics/renderer/metrics_render_frame_observer_unittest.cc index e01ac94..f007571 100644 --- a/components/page_load_metrics/renderer/metrics_render_frame_observer_unittest.cc +++ b/components/page_load_metrics/renderer/metrics_render_frame_observer_unittest.cc
@@ -81,9 +81,9 @@ NiceMock<MockMetricsRenderFrameObserver> observer; base::MockTimer* mock_timer = new base::MockTimer(false, false); observer.set_mock_timer(base::WrapUnique(mock_timer)); - observer.DidCommitProvisionalLoad(true, false); EXPECT_CALL(observer, GetTiming()).WillRepeatedly(Return(PageLoadTiming())); + observer.DidChangePerformanceTiming(); ASSERT_FALSE(mock_timer->IsRunning()); } @@ -95,10 +95,15 @@ NiceMock<MockMetricsRenderFrameObserver> observer; base::MockTimer* mock_timer = new base::MockTimer(false, false); observer.set_mock_timer(base::WrapUnique(mock_timer)); - observer.DidCommitProvisionalLoad(true, false); PageLoadTiming timing; timing.navigation_start = nav_start; + EXPECT_CALL(observer, GetTiming()).WillRepeatedly(Return(timing)); + observer.DidCommitProvisionalLoad(true, false); + EXPECT_CALL(*observer.ipc_interceptor(), + OnTimingUpdated(timing, PageLoadMetadata())); + mock_timer->Fire(); + timing.first_layout = first_layout; EXPECT_CALL(observer, GetTiming()).WillRepeatedly(Return(timing)); @@ -118,10 +123,15 @@ NiceMock<MockMetricsRenderFrameObserver> observer; base::MockTimer* mock_timer = new base::MockTimer(false, false); observer.set_mock_timer(base::WrapUnique(mock_timer)); - observer.DidCommitProvisionalLoad(true, false); PageLoadTiming timing; timing.navigation_start = nav_start; + EXPECT_CALL(observer, GetTiming()).WillRepeatedly(Return(timing)); + observer.DidCommitProvisionalLoad(true, false); + EXPECT_CALL(*observer.ipc_interceptor(), + OnTimingUpdated(timing, PageLoadMetadata())); + mock_timer->Fire(); + timing.first_layout = first_layout; timing.dom_content_loaded_event_start = dom_event; EXPECT_CALL(observer, GetTiming()).WillRepeatedly(Return(timing)); @@ -165,10 +175,15 @@ NiceMock<MockMetricsRenderFrameObserver> observer; base::MockTimer* mock_timer = new base::MockTimer(false, false); observer.set_mock_timer(base::WrapUnique(mock_timer)); - observer.DidCommitProvisionalLoad(true, false); PageLoadTiming timing; timing.navigation_start = nav_start; + EXPECT_CALL(observer, GetTiming()).WillRepeatedly(Return(timing)); + observer.DidCommitProvisionalLoad(true, false); + EXPECT_CALL(*observer.ipc_interceptor(), + OnTimingUpdated(timing, PageLoadMetadata())); + mock_timer->Fire(); + timing.first_layout = first_layout; timing.dom_content_loaded_event_start = dom_event; timing.load_event_start = load_event; @@ -189,15 +204,23 @@ base::TimeDelta load_event_2 = base::TimeDelta::FromMillisecondsD(20); PageLoadTiming timing_2; timing_2.navigation_start = nav_start_2; - timing_2.first_layout = first_layout_2; - timing_2.dom_content_loaded_event_start = dom_event_2; - timing_2.load_event_start = load_event_2; base::MockTimer* mock_timer2 = new base::MockTimer(false, false); observer.set_mock_timer(base::WrapUnique(mock_timer2)); + + EXPECT_CALL(observer, GetTiming()).WillRepeatedly(Return(timing_2)); observer.DidCommitProvisionalLoad(true, false); EXPECT_CALL(*observer.ipc_interceptor(), - OnTimingUpdated(timing, PageLoadMetadata())); + OnTimingUpdated(timing_2, PageLoadMetadata())); + mock_timer2->Fire(); + + timing_2.first_layout = first_layout_2; + timing_2.dom_content_loaded_event_start = dom_event_2; + timing_2.load_event_start = load_event_2; + EXPECT_CALL(observer, GetTiming()).WillRepeatedly(Return(timing_2)); + + EXPECT_CALL(*observer.ipc_interceptor(), + OnTimingUpdated(timing_2, PageLoadMetadata())); observer.DidChangePerformanceTiming(); mock_timer2->Fire(); }
diff --git a/components/page_load_metrics/renderer/page_timing_metrics_sender.cc b/components/page_load_metrics/renderer/page_timing_metrics_sender.cc index 2a649191..5572461 100644 --- a/components/page_load_metrics/renderer/page_timing_metrics_sender.cc +++ b/components/page_load_metrics/renderer/page_timing_metrics_sender.cc
@@ -15,17 +15,23 @@ namespace page_load_metrics { namespace { +const int kInitialTimerDelayMillis = 50; const int kTimerDelayMillis = 1000; } // namespace PageTimingMetricsSender::PageTimingMetricsSender( IPC::Sender* ipc_sender, int routing_id, - std::unique_ptr<base::Timer> timer) + std::unique_ptr<base::Timer> timer, + const PageLoadTiming& initial_timing) : ipc_sender_(ipc_sender), routing_id_(routing_id), timer_(std::move(timer)), - metadata_(PageLoadMetadata()) {} + last_timing_(initial_timing), + metadata_(PageLoadMetadata()) { + // Send an initial IPC relatively early to help track aborts. + EnsureSendTimer(kInitialTimerDelayMillis); +} // On destruction, we want to send any data we have if we have a timer // currently running (and thus are talking to a browser process) @@ -41,7 +47,7 @@ if (behavior & metadata_.behavior_flags) return; metadata_.behavior_flags |= behavior; - EnsureSendTimer(); + EnsureSendTimer(kTimerDelayMillis); } void PageTimingMetricsSender::Send(const PageLoadTiming& timing) { @@ -57,13 +63,13 @@ } last_timing_ = timing; - EnsureSendTimer(); + EnsureSendTimer(kTimerDelayMillis); } -void PageTimingMetricsSender::EnsureSendTimer() { +void PageTimingMetricsSender::EnsureSendTimer(int delay) { if (!timer_->IsRunning()) timer_->Start( - FROM_HERE, base::TimeDelta::FromMilliseconds(kTimerDelayMillis), + FROM_HERE, base::TimeDelta::FromMilliseconds(delay), base::Bind(&PageTimingMetricsSender::SendNow, base::Unretained(this))); }
diff --git a/components/page_load_metrics/renderer/page_timing_metrics_sender.h b/components/page_load_metrics/renderer/page_timing_metrics_sender.h index 37d16fbc..1cdfb73 100644 --- a/components/page_load_metrics/renderer/page_timing_metrics_sender.h +++ b/components/page_load_metrics/renderer/page_timing_metrics_sender.h
@@ -28,7 +28,8 @@ public: PageTimingMetricsSender(IPC::Sender* ipc_sender, int routing_id, - std::unique_ptr<base::Timer> timer); + std::unique_ptr<base::Timer> timer, + const PageLoadTiming& initial_timing); ~PageTimingMetricsSender(); void DidObserveLoadingBehavior(blink::WebLoadingBehaviorFlag behavior); @@ -38,7 +39,7 @@ base::Timer* timer() const { return timer_.get(); } private: - void EnsureSendTimer(); + void EnsureSendTimer(int delay); void SendNow(); IPC::Sender* const ipc_sender_;
diff --git a/components/page_load_metrics/renderer/page_timing_metrics_sender_unittest.cc b/components/page_load_metrics/renderer/page_timing_metrics_sender_unittest.cc index 6a3f9b25..83993d6 100644 --- a/components/page_load_metrics/renderer/page_timing_metrics_sender_unittest.cc +++ b/components/page_load_metrics/renderer/page_timing_metrics_sender_unittest.cc
@@ -35,11 +35,13 @@ // MockTimer instance. class TestPageTimingMetricsSender : public PageTimingMetricsSender { public: - explicit TestPageTimingMetricsSender(IPC::Sender* ipc_sender) + explicit TestPageTimingMetricsSender(IPC::Sender* ipc_sender, + const PageLoadTiming& initial_timing) : PageTimingMetricsSender( ipc_sender, MSG_ROUTING_NONE, - std::unique_ptr<base::Timer>(new base::MockTimer(false, false))) {} + std::unique_ptr<base::Timer>(new base::MockTimer(false, false)), + initial_timing) {} base::MockTimer* mock_timer() const { return reinterpret_cast<base::MockTimer*>(timer()); @@ -48,7 +50,8 @@ class PageTimingMetricsSenderTest : public testing::Test { public: - PageTimingMetricsSenderTest() : metrics_sender_(&mock_ipc_sender_) {} + PageTimingMetricsSenderTest() + : metrics_sender_(&mock_ipc_sender_, PageLoadTiming()) {} protected: testing::StrictMock<MockIPCSender> mock_ipc_sender_; @@ -133,16 +136,14 @@ TEST_F(PageTimingMetricsSenderTest, SendIPCOnDestructor) { PageLoadTiming timing; timing.navigation_start = base::Time::FromDoubleT(10); - { - // This test wants to verify behavior in the PageTimingMetricsSender - // destructor, so we create our own instance to make it go out of scope - // before the end of the test body. - TestPageTimingMetricsSender sender(&mock_ipc_sender_); + timing.first_layout = base::TimeDelta::FromMilliseconds(10); - sender.Send(timing); - EXPECT_CALL(mock_ipc_sender_, OnTimingUpdated(timing, PageLoadMetadata())); - ASSERT_TRUE(sender.mock_timer()->IsRunning()); - } + // This test wants to verify behavior in the PageTimingMetricsSender + // destructor, the EXPECT_CALL will be verified when the test tears down and + // |metrics_sender_| goes out of scope. + metrics_sender_.Send(timing); + EXPECT_CALL(mock_ipc_sender_, OnTimingUpdated(timing, PageLoadMetadata())); + ASSERT_TRUE(metrics_sender_.mock_timer()->IsRunning()); } } // namespace page_load_metrics
diff --git a/components/resource_provider/android/android_hooks.cc b/components/resource_provider/android/android_hooks.cc index 4cf2687..b312e1af 100644 --- a/components/resource_provider/android/android_hooks.cc +++ b/components/resource_provider/android/android_hooks.cc
@@ -46,7 +46,6 @@ extern "C" JNI_EXPORT void InitApplicationContext( const base::android::JavaRef<jobject>& context) { JNIEnv* env = base::android::AttachCurrentThread(); - base::android::InitApplicationContext(env, context); resource_provider::Java_Main_init( env, base::android::GetApplicationContext()); }
diff --git a/components/resource_provider/android/java/org/chromium/resource_provider/Main.java b/components/resource_provider/android/java/org/chromium/resource_provider/Main.java index 6395262..a65e6917 100644 --- a/components/resource_provider/android/java/org/chromium/resource_provider/Main.java +++ b/components/resource_provider/android/java/org/chromium/resource_provider/Main.java
@@ -6,6 +6,7 @@ import android.content.Context; +import org.chromium.base.ContextUtils; import org.chromium.base.PathUtils; import org.chromium.base.annotations.CalledByNative; import org.chromium.base.annotations.JNINamespace; @@ -22,6 +23,7 @@ @SuppressWarnings("unused") @CalledByNative private static void init(Context context) { + ContextUtils.initApplicationContext(context.getApplicationContext()); PathUtils.setPrivateDataDirectorySuffix(PRIVATE_DATA_DIRECTORY_SUFFIX, context); } }
diff --git a/components/test_runner/layout_test_runtime_flags.cc b/components/test_runner/layout_test_runtime_flags.cc index 63e3310..c9d530f 100644 --- a/components/test_runner/layout_test_runtime_flags.cc +++ b/components/test_runner/layout_test_runtime_flags.cc
@@ -58,6 +58,8 @@ set_stay_on_page_after_handling_before_unload(false); + set_have_top_loading_frame(false); + // No need to report the initial state - only the future delta is important. tracked_dictionary().ResetChangeTracking(); }
diff --git a/components/test_runner/layout_test_runtime_flags.h b/components/test_runner/layout_test_runtime_flags.h index 0a4355b..78c8cbf 100644 --- a/components/test_runner/layout_test_runtime_flags.h +++ b/components/test_runner/layout_test_runtime_flags.h
@@ -158,6 +158,12 @@ DEFINE_BOOL_LAYOUT_TEST_RUNTIME_FLAG( stay_on_page_after_handling_before_unload) + // Indicates if the test already tracks a top loading frame (in any of the + // renderer processes). This flag is trying to prevent different renderer + // processes from tracking different top loading frames (i.e. main frame in + // one renderer and an OOPIF in another renderer). + DEFINE_BOOL_LAYOUT_TEST_RUNTIME_FLAG(have_top_loading_frame) + #undef DEFINE_BOOL_LAYOUT_TEST_RUNTIME_FLAG #undef DEFINE_STRING_LAYOUT_TEST_RUNTIME_FLAG
diff --git a/components/test_runner/test_runner.cc b/components/test_runner/test_runner.cc index b668843..2d0597ab 100644 --- a/components/test_runner/test_runner.cc +++ b/components/test_runner/test_runner.cc
@@ -1832,9 +1832,9 @@ void TestRunner::ReplicateLayoutTestRuntimeFlagsChanges( const base::DictionaryValue& changed_values) { - DCHECK(test_is_running_); - layout_test_runtime_flags_.tracked_dictionary().ApplyUntrackedChanges( - changed_values); + if (test_is_running_) + layout_test_runtime_flags_.tracked_dictionary().ApplyUntrackedChanges( + changed_values); } bool TestRunner::HasCustomTextDump(std::string* custom_text_dump) const { @@ -1944,10 +1944,12 @@ if (!IsFramePartOfMainTestWindow(frame)) return false; - if (top_loading_frame_) + if (top_loading_frame_ || layout_test_runtime_flags_.have_top_loading_frame()) return false; top_loading_frame_ = frame; + layout_test_runtime_flags_.set_have_top_loading_frame(true); + OnLayoutTestRuntimeFlagsChanged(); return true; } @@ -1959,6 +1961,10 @@ return false; top_loading_frame_ = nullptr; + DCHECK(layout_test_runtime_flags_.have_top_loading_frame()); + layout_test_runtime_flags_.set_have_top_loading_frame(false); + OnLayoutTestRuntimeFlagsChanged(); + LocationChangeDone(); return true; } @@ -3127,6 +3133,8 @@ void TestRunner::OnLayoutTestRuntimeFlagsChanged() { if (layout_test_runtime_flags_.tracked_dictionary().changed_values().empty()) return; + if (!test_is_running_) + return; delegate_->OnLayoutTestRuntimeFlagsChanged( layout_test_runtime_flags_.tracked_dictionary().changed_values());
diff --git a/components/web_restrictions/browser/junit/src/org/chromium/components/webrestrictions/WebRestrictionsClientTest.java b/components/web_restrictions/browser/junit/src/org/chromium/components/webrestrictions/WebRestrictionsClientTest.java index 662fbf40..0fd8756 100644 --- a/components/web_restrictions/browser/junit/src/org/chromium/components/webrestrictions/WebRestrictionsClientTest.java +++ b/components/web_restrictions/browser/junit/src/org/chromium/components/webrestrictions/WebRestrictionsClientTest.java
@@ -41,7 +41,7 @@ @Before public void setUp() { - ContextUtils.initApplicationContextForJUnitTests(Robolectric.application); + ContextUtils.initApplicationContextForTests(Robolectric.application); mTestClient = Mockito.spy(new WebRestrictionsClient()); Mockito.doNothing().when(mTestClient).nativeNotifyWebRestrictionsChanged(anyLong()); mProvider = Mockito.mock(ContentProvider.class);
diff --git a/content/browser/gamepad/gamepad_platform_data_fetcher_mac.h b/content/browser/gamepad/gamepad_platform_data_fetcher_mac.h index d373fee3..1fe50c0c 100644 --- a/content/browser/gamepad/gamepad_platform_data_fetcher_mac.h +++ b/content/browser/gamepad/gamepad_platform_data_fetcher_mac.h
@@ -60,6 +60,7 @@ size_t GetSlotForXboxDevice(XboxController* device); void DeviceAdd(IOHIDDeviceRef device); + bool CheckCollection(IOHIDElementRef element); bool AddButtonsAndAxes(NSArray* elements, size_t slot); void DeviceRemove(IOHIDDeviceRef device); void ValueChanged(IOHIDValueRef value);
diff --git a/content/browser/gamepad/gamepad_platform_data_fetcher_mac.mm b/content/browser/gamepad/gamepad_platform_data_fetcher_mac.mm index 4d55c55..fe77f536 100644 --- a/content/browser/gamepad/gamepad_platform_data_fetcher_mac.mm +++ b/content/browser/gamepad/gamepad_platform_data_fetcher_mac.mm
@@ -156,6 +156,23 @@ InstanceFromContext(context)->ValueChanged(ref); } +bool GamepadPlatformDataFetcherMac::CheckCollection(IOHIDElementRef element) { + // Check that a parent collection of this element matches one of the usage + // numbers that we are looking for. + while ((element = IOHIDElementGetParent(element)) != NULL) { + uint32_t usage_page = IOHIDElementGetUsagePage(element); + uint32_t usage = IOHIDElementGetUsage(element); + if (usage_page == kGenericDesktopUsagePage) { + if (usage == kJoystickUsageNumber || + usage == kGameUsageNumber || + usage == kMultiAxisUsageNumber) { + return true; + } + } + } + return false; +} + bool GamepadPlatformDataFetcherMac::AddButtonsAndAxes(NSArray* elements, size_t slot) { WebGamepad& pad = pad_state_[slot].data; @@ -172,6 +189,9 @@ for (id elem in elements) { IOHIDElementRef element = reinterpret_cast<IOHIDElementRef>(elem); + if (!CheckCollection(element)) + continue; + uint32_t usage_page = IOHIDElementGetUsagePage(element); uint32_t usage = IOHIDElementGetUsage(element); if (IOHIDElementGetType(element) == kIOHIDElementTypeInput_Button && @@ -202,6 +222,9 @@ uint32_t next_index = 0; for (id elem in elements) { IOHIDElementRef element = reinterpret_cast<IOHIDElementRef>(elem); + if (!CheckCollection(element)) + continue; + uint32_t usage_page = IOHIDElementGetUsagePage(element); uint32_t usage = IOHIDElementGetUsage(element); if (IOHIDElementGetType(element) == kIOHIDElementTypeInput_Misc &&
diff --git a/content/browser/media/capture/aura_window_capture_machine.cc b/content/browser/media/capture/aura_window_capture_machine.cc index 51e8d128..6aff1cbc 100644 --- a/content/browser/media/capture/aura_window_capture_machine.cc +++ b/content/browser/media/capture/aura_window_capture_machine.cc
@@ -31,7 +31,6 @@ #include "ui/compositor/compositor.h" #include "ui/compositor/dip_util.h" #include "ui/compositor/layer.h" -#include "ui/gfx/screen.h" #include "ui/wm/public/activation_client.h" namespace content {
diff --git a/content/browser/media/capture/web_contents_video_capture_device_unittest.cc b/content/browser/media/capture/web_contents_video_capture_device_unittest.cc index 32e4209..13367a3 100644 --- a/content/browser/media/capture/web_contents_video_capture_device_unittest.cc +++ b/content/browser/media/capture/web_contents_video_capture_device_unittest.cc
@@ -42,10 +42,10 @@ #include "testing/gtest/include/gtest/gtest.h" #include "third_party/skia/include/core/SkColor.h" #include "ui/base/layout.h" -#include "ui/gfx/display.h" +#include "ui/display/display.h" +#include "ui/display/screen.h" #include "ui/gfx/geometry/dip_util.h" #include "ui/gfx/geometry/size_conversions.h" -#include "ui/gfx/screen.h" #include "ui/gfx/test/test_screen.h" namespace content { @@ -600,8 +600,8 @@ test_screen_.display()->set_bounds(gfx::Rect(0, 0, 2560, 1440)); test_screen_.display()->set_device_scale_factor(kTestDeviceScaleFactor); - gfx::Screen::SetScreenInstance(&test_screen_); - ASSERT_EQ(&test_screen_, gfx::Screen::GetScreen()); + display::Screen::SetScreenInstance(&test_screen_); + ASSERT_EQ(&test_screen_, display::Screen::GetScreen()); // TODO(nick): Sadness and woe! Much "mock-the-world" boilerplate could be // eliminated here, if only we could use RenderViewHostTestHarness. The @@ -659,7 +659,7 @@ render_view_host_factory_.reset(); render_process_host_factory_.reset(); - gfx::Screen::SetScreenInstance(nullptr); + display::Screen::SetScreenInstance(nullptr); } // Accessors.
diff --git a/content/browser/renderer_host/dip_util.cc b/content/browser/renderer_host/dip_util.cc index 225d17b..3d20622 100644 --- a/content/browser/renderer_host/dip_util.cc +++ b/content/browser/renderer_host/dip_util.cc
@@ -6,7 +6,6 @@ #include "content/public/browser/render_widget_host_view.h" #include "ui/base/layout.h" -#include "ui/gfx/display.h" #include "ui/gfx/geometry/dip_util.h" #include "ui/gfx/geometry/point.h" #include "ui/gfx/geometry/point_conversions.h" @@ -14,7 +13,6 @@ #include "ui/gfx/geometry/rect_conversions.h" #include "ui/gfx/geometry/size.h" #include "ui/gfx/geometry/size_conversions.h" -#include "ui/gfx/screen.h" namespace content {
diff --git a/content/browser/renderer_host/input/web_input_event_unittest.cc b/content/browser/renderer_host/input/web_input_event_unittest.cc index b05608fa..2abe1e1 100644 --- a/content/browser/renderer_host/input/web_input_event_unittest.cc +++ b/content/browser/renderer_host/input/web_input_event_unittest.cc
@@ -6,8 +6,8 @@ #include "build/build_config.h" #include "testing/gtest/include/gtest/gtest.h" #include "third_party/WebKit/public/web/WebInputEvent.h" +#include "ui/display/display.h" #include "ui/events/event_constants.h" -#include "ui/gfx/display.h" #include "ui/gfx/switches.h" #if defined(OS_WIN) @@ -27,7 +27,7 @@ if (base::win::GetVersion() < base::win::VERSION_WIN7) return; - gfx::Display::ResetForceDeviceScaleFactorForTesting(); + display::Display::ResetForceDeviceScaleFactorForTesting(); base::CommandLine* command_line = base::CommandLine::ForCurrentProcess(); command_line->AppendSwitchASCII(switches::kForceDeviceScaleFactor, "2"); @@ -52,7 +52,7 @@ EXPECT_EQ(100, mouse_move.globalY); command_line->AppendSwitchASCII(switches::kForceDeviceScaleFactor, "1"); - gfx::Display::ResetForceDeviceScaleFactorForTesting(); + display::Display::ResetForceDeviceScaleFactorForTesting(); } #endif
diff --git a/content/browser/renderer_host/render_widget_host_unittest.cc b/content/browser/renderer_host/render_widget_host_unittest.cc index 77515873..f3556cb 100644 --- a/content/browser/renderer_host/render_widget_host_unittest.cc +++ b/content/browser/renderer_host/render_widget_host_unittest.cc
@@ -29,9 +29,9 @@ #include "content/public/test/test_browser_context.h" #include "content/test/test_render_view_host.h" #include "testing/gtest/include/gtest/gtest.h" +#include "ui/display/screen.h" #include "ui/events/keycodes/keyboard_codes.h" #include "ui/gfx/canvas.h" -#include "ui/gfx/screen.h" #if defined(OS_ANDROID) #include "content/browser/renderer_host/render_widget_host_view_android.h" @@ -464,7 +464,7 @@ #endif #if defined(USE_AURA) screen_.reset(aura::TestScreen::Create(gfx::Size())); - gfx::Screen::SetScreenInstance(screen_.get()); + display::Screen::SetScreenInstance(screen_.get()); #endif host_.reset(new MockRenderWidgetHost(delegate_.get(), process_, process_->GetNextRoutingID())); @@ -484,7 +484,7 @@ browser_context_.reset(); #if defined(USE_AURA) - gfx::Screen::SetScreenInstance(nullptr); + display::Screen::SetScreenInstance(nullptr); screen_.reset(); #endif #if defined(USE_AURA) || defined(OS_MACOSX) @@ -629,7 +629,7 @@ std::unique_ptr<MockRenderWidgetHostDelegate> delegate_; std::unique_ptr<MockRenderWidgetHost> host_; std::unique_ptr<TestView> view_; - std::unique_ptr<gfx::Screen> screen_; + std::unique_ptr<display::Screen> screen_; bool handle_key_press_event_; bool handle_mouse_event_; double last_simulated_event_time_seconds_;
diff --git a/content/browser/renderer_host/render_widget_host_view_android.cc b/content/browser/renderer_host/render_widget_host_view_android.cc index dbca7b5..5e05335 100644 --- a/content/browser/renderer_host/render_widget_host_view_android.cc +++ b/content/browser/renderer_host/render_widget_host_view_android.cc
@@ -80,16 +80,16 @@ #include "third_party/skia/include/core/SkCanvas.h" #include "ui/android/window_android.h" #include "ui/android/window_android_compositor.h" +#include "ui/display/display.h" +#include "ui/display/screen.h" #include "ui/events/blink/blink_event_util.h" #include "ui/events/gesture_detection/gesture_provider_config_helper.h" #include "ui/events/gesture_detection/motion_event.h" #include "ui/gfx/android/device_display_info.h" #include "ui/gfx/android/java_bitmap.h" #include "ui/gfx/android/view_configuration.h" -#include "ui/gfx/display.h" #include "ui/gfx/geometry/dip_util.h" #include "ui/gfx/geometry/size_conversions.h" -#include "ui/gfx/screen.h" #include "ui/touch_selection/touch_selection_controller.h" namespace content { @@ -421,7 +421,8 @@ src_subrect = gfx::Rect(bounds); DCHECK_LE(src_subrect.width() + src_subrect.x(), bounds.width()); DCHECK_LE(src_subrect.height() + src_subrect.y(), bounds.height()); - const gfx::Display& display = gfx::Screen::GetScreen()->GetPrimaryDisplay(); + const display::Display& display = + display::Screen::GetScreen()->GetPrimaryDisplay(); float device_scale_factor = display.device_scale_factor(); DCHECK_GT(device_scale_factor, 0); gfx::Size dst_size( @@ -876,7 +877,8 @@ callback.Run(SkBitmap(), READBACK_SURFACE_UNAVAILABLE); return; } - const gfx::Display& display = gfx::Screen::GetScreen()->GetPrimaryDisplay(); + const display::Display& display = + display::Screen::GetScreen()->GetPrimaryDisplay(); float device_scale_factor = display.device_scale_factor(); gfx::Size dst_size_in_pixel = gfx::ConvertRectToPixel(device_scale_factor, gfx::Rect(dst_size)).size(); @@ -2007,7 +2009,8 @@ // static void RenderWidgetHostViewBase::GetDefaultScreenInfo( blink::WebScreenInfo* results) { - const gfx::Display& display = gfx::Screen::GetScreen()->GetPrimaryDisplay(); + const display::Display& display = + display::Screen::GetScreen()->GetPrimaryDisplay(); results->rect = display.bounds(); // TODO(husky): Remove any system controls from availableRect. results->availableRect = display.work_area();
diff --git a/content/browser/renderer_host/render_widget_host_view_aura.cc b/content/browser/renderer_host/render_widget_host_view_aura.cc index bdc85b1..e2815c2 100644 --- a/content/browser/renderer_host/render_widget_host_view_aura.cc +++ b/content/browser/renderer_host/render_widget_host_view_aura.cc
@@ -76,6 +76,8 @@ #include "ui/base/ui_base_types.h" #include "ui/compositor/compositor_vsync_manager.h" #include "ui/compositor/dip_util.h" +#include "ui/display/display.h" +#include "ui/display/screen.h" #include "ui/events/blink/blink_event_util.h" #include "ui/events/event.h" #include "ui/events/event_utils.h" @@ -83,11 +85,9 @@ #include "ui/events/gestures/gesture_recognizer.h" #include "ui/gfx/canvas.h" #include "ui/gfx/color_profile.h" -#include "ui/gfx/display.h" #include "ui/gfx/geometry/dip_util.h" #include "ui/gfx/geometry/rect_conversions.h" #include "ui/gfx/geometry/size_conversions.h" -#include "ui/gfx/screen.h" #include "ui/gfx/skia_util.h" #include "ui/touch_selection/touch_selection_controller.h" #include "ui/wm/public/activation_client.h" @@ -169,9 +169,10 @@ } void GetScreenInfoForWindow(WebScreenInfo* results, aura::Window* window) { - gfx::Screen* screen = gfx::Screen::GetScreen(); - const gfx::Display display = window ? screen->GetDisplayNearestWindow(window) - : screen->GetPrimaryDisplay(); + display::Screen* screen = display::Screen::GetScreen(); + const display::Display display = window + ? screen->GetDisplayNearestWindow(window) + : screen->GetPrimaryDisplay(); results->rect = display.bounds(); results->availableRect = display.work_area(); // TODO(derat|oshima): Don't hardcode this. Get this from display object. @@ -433,8 +434,8 @@ if (parent_view) parent_view->AddChild(GetNativeView()); - const gfx::Display display = - gfx::Screen::GetScreen()->GetDisplayNearestWindow(window_); + const display::Display display = + display::Screen::GetScreen()->GetDisplayNearestWindow(window_); device_scale_factor_ = display.device_scale_factor(); } @@ -486,8 +487,8 @@ event_filter_for_popup_exit_.reset(new EventFilterForPopupExit(this)); - const gfx::Display display = - gfx::Screen::GetScreen()->GetDisplayNearestWindow(window_); + const display::Display display = + display::Screen::GetScreen()->GetDisplayNearestWindow(window_); device_scale_factor_ = display.device_scale_factor(); } @@ -510,8 +511,8 @@ host_tracker_.reset(new aura::WindowTracker); host_tracker_->Add(reference_window); } - gfx::Display display = - gfx::Screen::GetScreen()->GetDisplayNearestWindow(reference_window); + display::Display display = + display::Screen::GetScreen()->GetDisplayNearestWindow(reference_window); parent = reference_window->GetRootWindow(); bounds = display.bounds(); } @@ -519,8 +520,8 @@ Show(); Focus(); - const gfx::Display display = - gfx::Screen::GetScreen()->GetDisplayNearestWindow(window_); + const display::Display display = + display::Screen::GetScreen()->GetDisplayNearestWindow(window_); device_scale_factor_ = display.device_scale_factor(); } @@ -862,8 +863,8 @@ void RenderWidgetHostViewAura::UpdateCursor(const WebCursor& cursor) { current_cursor_ = cursor; - const gfx::Display display = - gfx::Screen::GetScreen()->GetDisplayNearestWindow(window_); + const display::Display display = + display::Screen::GetScreen()->GetDisplayNearestWindow(window_); current_cursor_.SetDisplayInfo(display); UpdateCursorIfOverSelf(); } @@ -1040,8 +1041,9 @@ void RenderWidgetHostViewAura::UpdateMouseLockRegion() { RECT window_rect = - gfx::Screen::GetScreen()->DIPToScreenRectInWindow( - window_, window_->GetBoundsInScreen()).ToRECT(); + display::Screen::GetScreen() + ->DIPToScreenRectInWindow(window_, window_->GetBoundsInScreen()) + .ToRECT(); ::ClipCursor(&window_rect); } @@ -1135,7 +1137,8 @@ } } - bounds = gfx::Screen::GetScreen()->ScreenToDIPRectInWindow(top_level, bounds); + bounds = + display::Screen::GetScreen()->ScreenToDIPRectInWindow(top_level, bounds); #endif return bounds; @@ -1688,20 +1691,19 @@ } //////////////////////////////////////////////////////////////////////////////// -// RenderWidgetHostViewAura, gfx::DisplayObserver implementation: +// RenderWidgetHostViewAura, display::DisplayObserver implementation: void RenderWidgetHostViewAura::OnDisplayAdded( - const gfx::Display& new_display) { -} + const display::Display& new_display) {} void RenderWidgetHostViewAura::OnDisplayRemoved( - const gfx::Display& old_display) { -} + const display::Display& old_display) {} void RenderWidgetHostViewAura::OnDisplayMetricsChanged( - const gfx::Display& display, uint32_t metrics) { + const display::Display& display, + uint32_t metrics) { // The screen info should be updated regardless of the metric change. - gfx::Screen* screen = gfx::Screen::GetScreen(); + display::Screen* screen = display::Screen::GetScreen(); if (display.id() == screen->GetDisplayNearestWindow(window_).id()) { UpdateScreenInfo(window_); current_cursor_.SetDisplayInfo(display); @@ -1772,8 +1774,8 @@ UpdateScreenInfo(window_); device_scale_factor_ = device_scale_factor; - const gfx::Display display = gfx::Screen::GetScreen()-> - GetDisplayNearestWindow(window_); + const display::Display display = + display::Screen::GetScreen()->GetDisplayNearestWindow(window_); DCHECK_EQ(device_scale_factor, display.device_scale_factor()); current_cursor_.SetDisplayInfo(display); SnapToPhysicalPixelBoundary(); @@ -2302,7 +2304,7 @@ // If we lose the focus while fullscreen, close the window; Pepper Flash // won't do it for us (unlike NPAPI Flash). However, we do not close the // window if we lose the focus to a window on another display. - gfx::Screen* screen = gfx::Screen::GetScreen(); + display::Screen* screen = display::Screen::GetScreen(); bool focusing_other_display = gained_focus && screen->GetNumDisplays() > 1 && (screen->GetDisplayNearestWindow(window_).id() != @@ -2360,7 +2362,7 @@ window_->GetHost()->RemoveObserver(this); UnlockMouse(); aura::client::SetTooltipText(window_, NULL); - gfx::Screen::GetScreen()->RemoveObserver(this); + display::Screen::GetScreen()->RemoveObserver(this); // This call is usually no-op since |this| object is already removed from // the Aura root window and we don't have a way to get an input method @@ -2396,7 +2398,7 @@ aura::client::SetActivationDelegate(window_, this); aura::client::SetFocusChangeObserver(window_, this); window_->set_layer_owner_delegate(delegated_frame_host_.get()); - gfx::Screen::GetScreen()->AddObserver(this); + display::Screen::GetScreen()->AddObserver(this); } void RenderWidgetHostViewAura::UpdateCursorIfOverSelf() { @@ -2407,7 +2409,7 @@ if (!root_window) return; - gfx::Screen* screen = gfx::Screen::GetScreen(); + display::Screen* screen = display::Screen::GetScreen(); DCHECK(screen); gfx::Point cursor_screen_point = screen->GetCursorScreenPoint();
diff --git a/content/browser/renderer_host/render_widget_host_view_aura.h b/content/browser/renderer_host/render_widget_host_view_aura.h index 494d269..bccb444 100644 --- a/content/browser/renderer_host/render_widget_host_view_aura.h +++ b/content/browser/renderer_host/render_widget_host_view_aura.h
@@ -38,8 +38,8 @@ #include "ui/aura/window_tree_host_observer.h" #include "ui/base/ime/text_input_client.h" #include "ui/base/touch/selection_bound.h" +#include "ui/display/display_observer.h" #include "ui/events/gestures/motion_event_aura.h" -#include "ui/gfx/display_observer.h" #include "ui/gfx/geometry/insets.h" #include "ui/gfx/geometry/rect.h" #include "ui/wm/public/activation_delegate.h" @@ -92,7 +92,7 @@ : public RenderWidgetHostViewBase, public DelegatedFrameHostClient, public ui::TextInputClient, - public gfx::DisplayObserver, + public display::DisplayObserver, public aura::WindowTreeHostObserver, public aura::WindowDelegate, public aura::client::ActivationDelegate, @@ -235,10 +235,10 @@ bool IsEditCommandEnabled(int command_id) override; void SetEditCommandForNextKeyEvent(int command_id) override; - // Overridden from gfx::DisplayObserver: - void OnDisplayAdded(const gfx::Display& new_display) override; - void OnDisplayRemoved(const gfx::Display& old_display) override; - void OnDisplayMetricsChanged(const gfx::Display& display, + // Overridden from display::DisplayObserver: + void OnDisplayAdded(const display::Display& new_display) override; + void OnDisplayRemoved(const display::Display& old_display) override; + void OnDisplayMetricsChanged(const display::Display& display, uint32_t metrics) override; // Overridden from aura::WindowDelegate:
diff --git a/content/browser/renderer_host/render_widget_host_view_base.cc b/content/browser/renderer_host/render_widget_host_view_base.cc index cf28db2d..dd88fae 100644 --- a/content/browser/renderer_host/render_widget_host_view_base.cc +++ b/content/browser/renderer_host/render_widget_host_view_base.cc
@@ -15,11 +15,11 @@ #include "content/browser/renderer_host/render_widget_host_view_base_observer.h" #include "content/common/content_switches_internal.h" #include "content/public/browser/render_widget_host_view_frame_subscriber.h" -#include "ui/gfx/display.h" +#include "ui/display/display.h" +#include "ui/display/screen.h" #include "ui/gfx/geometry/point_conversions.h" #include "ui/gfx/geometry/size_conversions.h" #include "ui/gfx/geometry/size_f.h" -#include "ui/gfx/screen.h" namespace content { @@ -38,7 +38,7 @@ selection_text_offset_(0), selection_range_(gfx::Range::InvalidRange()), current_device_scale_factor_(0), - current_display_rotation_(gfx::Display::ROTATE_0), + current_display_rotation_(display::Display::ROTATE_0), pinch_zoom_enabled_(content::IsPinchToZoomEnabled()), renderer_frame_number_(0), weak_factory_(this) {} @@ -82,8 +82,8 @@ } gfx::Size RenderWidgetHostViewBase::GetPhysicalBackingSize() const { - gfx::Display display = - gfx::Screen::GetScreen()->GetDisplayNearestWindow(GetNativeView()); + display::Display display = + display::Screen::GetScreen()->GetDisplayNearestWindow(GetNativeView()); return gfx::ScaleToCeiledSize(GetRequestedRendererSize(), display.device_scale_factor()); } @@ -214,8 +214,8 @@ } bool RenderWidgetHostViewBase::HasDisplayPropertyChanged(gfx::NativeView view) { - gfx::Display display = - gfx::Screen::GetScreen()->GetDisplayNearestWindow(view); + display::Display display = + display::Screen::GetScreen()->GetDisplayNearestWindow(view); if (current_display_area_ == display.work_area() && current_device_scale_factor_ == display.device_scale_factor() && current_display_rotation_ == display.rotation()) { @@ -291,7 +291,7 @@ // static blink::WebScreenOrientationType RenderWidgetHostViewBase::GetOrientationTypeForMobile( - const gfx::Display& display) { + const display::Display& display) { int angle = display.RotationAsDegree(); const gfx::Rect& bounds = display.bounds(); @@ -324,7 +324,7 @@ // static blink::WebScreenOrientationType RenderWidgetHostViewBase::GetOrientationTypeForDesktop( - const gfx::Display& display) { + const display::Display& display) { static int primary_landscape_angle = -1; static int primary_portrait_angle = -1;
diff --git a/content/browser/renderer_host/render_widget_host_view_base.h b/content/browser/renderer_host/render_widget_host_view_base.h index b71919b..8eb96897e 100644 --- a/content/browser/renderer_host/render_widget_host_view_base.h +++ b/content/browser/renderer_host/render_widget_host_view_base.h
@@ -31,7 +31,7 @@ #include "third_party/WebKit/public/web/WebTextDirection.h" #include "ui/base/ime/text_input_mode.h" #include "ui/base/ime/text_input_type.h" -#include "ui/gfx/display.h" +#include "ui/display/display.h" #include "ui/gfx/geometry/rect.h" #include "ui/gfx/native_widget_types.h" #include "ui/gfx/range/range.h" @@ -333,11 +333,11 @@ // Compute the orientation type of the display assuming it is a mobile device. static blink::WebScreenOrientationType GetOrientationTypeForMobile( - const gfx::Display& display); + const display::Display& display); // Compute the orientation type of the display assuming it is a desktop. static blink::WebScreenOrientationType GetOrientationTypeForDesktop( - const gfx::Display& display); + const display::Display& display); virtual void GetScreenInfo(blink::WebScreenInfo* results) = 0; virtual bool GetScreenColorProfile(std::vector<char>* color_profile) = 0; @@ -417,7 +417,7 @@ float current_device_scale_factor_; // The orientation of the display the renderer is currently on. - gfx::Display::Rotation current_display_rotation_; + display::Display::Rotation current_display_rotation_; // Whether pinch-to-zoom should be enabled and pinch events forwarded to the // renderer.
diff --git a/content/browser/renderer_host/render_widget_host_view_base_unittest.cc b/content/browser/renderer_host/render_widget_host_view_base_unittest.cc index 8277d1f6..acce950 100644 --- a/content/browser/renderer_host/render_widget_host_view_base_unittest.cc +++ b/content/browser/renderer_host/render_widget_host_view_base_unittest.cc
@@ -6,14 +6,14 @@ #include "testing/gtest/include/gtest/gtest.h" #include "third_party/WebKit/public/platform/modules/screen_orientation/WebScreenOrientationType.h" -#include "ui/gfx/display.h" +#include "ui/display/display.h" namespace content { namespace { -gfx::Display CreateDisplay(int width, int height, int angle) { - gfx::Display display; +display::Display CreateDisplay(int width, int height, int angle) { + display::Display display; display.SetRotationAsDegree(angle); display.set_bounds(gfx::Rect(width, height)); @@ -25,7 +25,7 @@ TEST(RenderWidgetHostViewBaseTest, OrientationTypeForMobile) { // Square display (width == height). { - gfx::Display display = CreateDisplay(100, 100, 0); + display::Display display = CreateDisplay(100, 100, 0); EXPECT_EQ(blink::WebScreenOrientationPortraitPrimary, RenderWidgetHostViewBase::GetOrientationTypeForMobile(display)); @@ -44,7 +44,7 @@ // natural width > natural height. { - gfx::Display display = CreateDisplay(1, 0, 0); + display::Display display = CreateDisplay(1, 0, 0); EXPECT_EQ(blink::WebScreenOrientationLandscapePrimary, RenderWidgetHostViewBase::GetOrientationTypeForMobile(display)); @@ -63,7 +63,7 @@ // natural width < natural height. { - gfx::Display display = CreateDisplay(0, 1, 0); + display::Display display = CreateDisplay(0, 1, 0); EXPECT_EQ(blink::WebScreenOrientationPortraitPrimary, RenderWidgetHostViewBase::GetOrientationTypeForMobile(display)); @@ -90,7 +90,7 @@ // natural width > natural height. { - gfx::Display display = CreateDisplay(1, 0, 0); + display::Display display = CreateDisplay(1, 0, 0); blink::WebScreenOrientationType landscape_1 = RenderWidgetHostViewBase::GetOrientationTypeForDesktop(display); EXPECT_TRUE(landscape_1 == blink::WebScreenOrientationLandscapePrimary ||
diff --git a/content/browser/renderer_host/render_widget_host_view_mac.h b/content/browser/renderer_host/render_widget_host_view_mac.h index add3fbe..fd4e494 100644 --- a/content/browser/renderer_host/render_widget_host_view_mac.h +++ b/content/browser/renderer_host/render_widget_host_view_mac.h
@@ -38,7 +38,7 @@ #import "ui/base/cocoa/command_dispatcher.h" #include "ui/base/cocoa/remote_layer_api.h" #import "ui/base/cocoa/tool_tip_base_view.h" -#include "ui/gfx/display_observer.h" +#include "ui/display/display_observer.h" namespace content { class RenderWidgetHostImpl; @@ -229,7 +229,7 @@ public DelegatedFrameHostClient, public ui::AcceleratedWidgetMacNSView, public IPC::Sender, - public gfx::DisplayObserver, + public display::DisplayObserver, public cc::BeginFrameObserverBase { public: // The view will associate itself with the given widget. The native view must @@ -355,10 +355,10 @@ // IPC::Sender implementation. bool Send(IPC::Message* message) override; - // gfx::DisplayObserver implementation. - void OnDisplayAdded(const gfx::Display& new_display) override; - void OnDisplayRemoved(const gfx::Display& old_display) override; - void OnDisplayMetricsChanged(const gfx::Display& display, + // display::DisplayObserver implementation. + void OnDisplayAdded(const display::Display& new_display) override; + void OnDisplayRemoved(const display::Display& old_display) override; + void OnDisplayMetricsChanged(const display::Display& display, uint32_t metrics) override; // Forwards the mouse event to the renderer.
diff --git a/content/browser/web_contents/web_contents_impl.cc b/content/browser/web_contents/web_contents_impl.cc index d593431..c37835e 100644 --- a/content/browser/web_contents/web_contents_impl.cc +++ b/content/browser/web_contents/web_contents_impl.cc
@@ -124,8 +124,6 @@ #include "third_party/skia/include/core/SkBitmap.h" #include "ui/accessibility/ax_tree_combiner.h" #include "ui/base/layout.h" -#include "ui/gfx/display.h" -#include "ui/gfx/screen.h" #include "ui/gl/gl_switches.h" #if defined(OS_ANDROID)
diff --git a/content/browser/web_contents/web_contents_view_aura.cc b/content/browser/web_contents/web_contents_view_aura.cc index c710eaf6..2df2944 100644 --- a/content/browser/web_contents/web_contents_view_aura.cc +++ b/content/browser/web_contents/web_contents_view_aura.cc
@@ -62,13 +62,13 @@ #include "ui/base/dragdrop/os_exchange_data.h" #include "ui/base/hit_test.h" #include "ui/compositor/layer.h" +#include "ui/display/screen.h" #include "ui/events/event.h" #include "ui/events/event_utils.h" #include "ui/gfx/canvas.h" #include "ui/gfx/image/image.h" #include "ui/gfx/image/image_png_rep.h" #include "ui/gfx/image/image_skia.h" -#include "ui/gfx/screen.h" #include "ui/touch_selection/touch_selection_controller.h" #include "ui/wm/public/drag_drop_client.h" #include "ui/wm/public/drag_drop_delegate.h" @@ -538,7 +538,7 @@ return; aura::Window* window = GetContentNativeView(); - gfx::Point screen_loc = gfx::Screen::GetScreen()->GetCursorScreenPoint(); + gfx::Point screen_loc = display::Screen::GetScreen()->GetCursorScreenPoint(); gfx::Point client_loc = screen_loc; aura::client::ScreenPositionClient* screen_position_client = aura::client::GetScreenPositionClient(window->GetRootWindow()); @@ -1046,7 +1046,7 @@ web_contents_->GetDelegate()->ActivateContents(web_contents_); web_contents_->GetDelegate()->ContentsMouseEvent( - web_contents_, gfx::Screen::GetScreen()->GetCursorScreenPoint(), + web_contents_, display::Screen::GetScreen()->GetCursorScreenPoint(), type == ui::ET_MOUSE_MOVED, type == ui::ET_MOUSE_EXITED); } @@ -1071,7 +1071,7 @@ if (drag_dest_delegate_) drag_dest_delegate_->DragInitialize(web_contents_); - gfx::Point screen_pt = gfx::Screen::GetScreen()->GetCursorScreenPoint(); + gfx::Point screen_pt = display::Screen::GetScreen()->GetCursorScreenPoint(); web_contents_->GetRenderViewHost()->DragTargetDragEnter( *current_drop_data_.get(), event.location(), screen_pt, op, ConvertAuraEventFlagsToWebInputEventModifiers(event.flags())); @@ -1091,7 +1091,7 @@ return ui::DragDropTypes::DRAG_NONE; blink::WebDragOperationsMask op = ConvertToWeb(event.source_operations()); - gfx::Point screen_pt = gfx::Screen::GetScreen()->GetCursorScreenPoint(); + gfx::Point screen_pt = display::Screen::GetScreen()->GetCursorScreenPoint(); web_contents_->GetRenderViewHost()->DragTargetDragOver( event.location(), screen_pt, op, ConvertAuraEventFlagsToWebInputEventModifiers(event.flags())); @@ -1126,7 +1126,7 @@ return ui::DragDropTypes::DRAG_NONE; web_contents_->GetRenderViewHost()->DragTargetDrop( - event.location(), gfx::Screen::GetScreen()->GetCursorScreenPoint(), + event.location(), display::Screen::GetScreen()->GetCursorScreenPoint(), ConvertAuraEventFlagsToWebInputEventModifiers(event.flags())); if (drag_dest_delegate_) drag_dest_delegate_->OnDrop();
diff --git a/content/common/cursors/webcursor.h b/content/common/cursors/webcursor.h index c306baf..9bbdd1e 100644 --- a/content/common/cursors/webcursor.h +++ b/content/common/cursors/webcursor.h
@@ -11,7 +11,7 @@ #include "build/build_config.h" #include "content/common/content_export.h" #include "third_party/WebKit/public/platform/WebCursorInfo.h" -#include "ui/gfx/display.h" +#include "ui/display/display.h" #include "ui/gfx/geometry/point.h" #include "ui/gfx/geometry/size.h" #include "ui/gfx/native_widget_types.h" @@ -109,7 +109,7 @@ ui::PlatformCursor GetPlatformCursor(); // Updates |device_scale_factor_| and |rotation_| based on |display|. - void SetDisplayInfo(const gfx::Display& display); + void SetDisplayInfo(const display::Display& display); float GetCursorScaleFactor(); @@ -197,7 +197,7 @@ #endif #if defined(USE_OZONE) - gfx::Display::Rotation rotation_; + display::Display::Rotation rotation_; gfx::Size maximum_cursor_size_; #endif };
diff --git a/content/common/cursors/webcursor_android.cc b/content/common/cursors/webcursor_android.cc index a932b27..d1d720e 100644 --- a/content/common/cursors/webcursor_android.cc +++ b/content/common/cursors/webcursor_android.cc
@@ -17,7 +17,7 @@ // In the future when we want to support cursors of various kinds in Aura on // Android, we should switch to using webcursor_aura rather than add an // implementation here. -void WebCursor::SetDisplayInfo(const gfx::Display& display) { +void WebCursor::SetDisplayInfo(const display::Display& display) { } #endif
diff --git a/content/common/cursors/webcursor_aura.cc b/content/common/cursors/webcursor_aura.cc index 7cd04b1..6aad277c 100644 --- a/content/common/cursors/webcursor_aura.cc +++ b/content/common/cursors/webcursor_aura.cc
@@ -125,12 +125,12 @@ ImageFromCustomData(bitmap); *hotspot = hotspot_; ui::ScaleAndRotateCursorBitmapAndHotpoint( - GetCursorScaleFactor(), gfx::Display::ROTATE_0, bitmap, hotspot); + GetCursorScaleFactor(), display::Display::ROTATE_0, bitmap, hotspot); } // ozone has its own SetDisplayInfo that takes rotation into account #if !defined(USE_OZONE) -void WebCursor::SetDisplayInfo(const gfx::Display& display) { +void WebCursor::SetDisplayInfo(const display::Display& display) { if (device_scale_factor_ == display.device_scale_factor()) return;
diff --git a/content/common/cursors/webcursor_ozone.cc b/content/common/cursors/webcursor_ozone.cc index e668460..6095da9f 100644 --- a/content/common/cursors/webcursor_ozone.cc +++ b/content/common/cursors/webcursor_ozone.cc
@@ -40,7 +40,7 @@ return platform_cursor_; } -void WebCursor::SetDisplayInfo(const gfx::Display& display) { +void WebCursor::SetDisplayInfo(const display::Display& display) { if (rotation_ == display.rotation() && device_scale_factor_ == display.device_scale_factor() && maximum_cursor_size_ == display.maximum_cursor_size()) @@ -64,7 +64,7 @@ void WebCursor::InitPlatformData() { platform_cursor_ = NULL; device_scale_factor_ = 1.f; - rotation_ = gfx::Display::ROTATE_0; + rotation_ = display::Display::ROTATE_0; maximum_cursor_size_ = gfx::Size(kDefaultMaxCursorWidth, kDefaultMaxCursorHeight); }
diff --git a/content/common/cursors/webcursor_unittest.cc b/content/common/cursors/webcursor_unittest.cc index dc9bdd6..37a20004 100644 --- a/content/common/cursors/webcursor_unittest.cc +++ b/content/common/cursors/webcursor_unittest.cc
@@ -267,7 +267,7 @@ #if defined(USE_AURA) TEST(WebCursorTest, CursorScaleFactor) { - gfx::Display display; + display::Display display; display.set_device_scale_factor(80.2f); WebCursor::CursorInfo info; @@ -309,7 +309,7 @@ #if defined(OS_WIN) void ScaleCursor(float scaleFactor, int hotspotX, int hotspotY) { - gfx::Display display; + display::Display display; display.set_device_scale_factor(scaleFactor); WebCursor::CursorInfo info;
diff --git a/content/common/page_state_serialization.cc b/content/common/page_state_serialization.cc index b9670c2f2..7bbced3b 100644 --- a/content/common/page_state_serialization.cc +++ b/content/common/page_state_serialization.cc
@@ -14,7 +14,7 @@ #include "base/strings/string_util.h" #include "base/strings/utf_string_conversions.h" #include "build/build_config.h" -#include "ui/gfx/screen.h" +#include "ui/display/screen.h" namespace content { namespace { @@ -605,8 +605,9 @@ if (state->page_scale_factor) { float device_scale_factor = g_device_scale_factor_for_testing; if (!device_scale_factor) { - device_scale_factor = - gfx::Screen::GetScreen()->GetPrimaryDisplay().device_scale_factor(); + device_scale_factor = display::Screen::GetScreen() + ->GetPrimaryDisplay() + .device_scale_factor(); } state->scroll_offset = gfx::Point(state->scroll_offset.x() / state->page_scale_factor,
diff --git a/content/public/android/java/src/org/chromium/content/app/ChildProcessService.java b/content/public/android/java/src/org/chromium/content/app/ChildProcessService.java index 54dc6e62f..77f70e9f 100644 --- a/content/public/android/java/src/org/chromium/content/app/ChildProcessService.java +++ b/content/public/android/java/src/org/chromium/content/app/ChildProcessService.java
@@ -116,6 +116,8 @@ sContext.set(this); super.onCreate(); + ContextUtils.initApplicationContext(getApplicationContext()); + mMainThread = new Thread(new Runnable() { @Override @SuppressFBWarnings("DM_EXIT") @@ -187,7 +189,6 @@ mMainThread.wait(); } } - ContextUtils.initApplicationContext(sContext.get().getApplicationContext()); for (FileDescriptorInfo fdInfo : mFdInfos) { nativeRegisterGlobalFileDescriptor( fdInfo.mId, fdInfo.mFd.detachFd(), fdInfo.mOffset, fdInfo.mSize);
diff --git a/content/public/android/java/src/org/chromium/content/browser/BrowserStartupController.java b/content/public/android/java/src/org/chromium/content/browser/BrowserStartupController.java index 6c97f4c..d53701d 100644 --- a/content/public/android/java/src/org/chromium/content/browser/BrowserStartupController.java +++ b/content/public/android/java/src/org/chromium/content/browser/BrowserStartupController.java
@@ -7,7 +7,6 @@ import android.content.Context; import android.os.Handler; -import org.chromium.base.ContextUtils; import org.chromium.base.Log; import org.chromium.base.ResourceExtractor; import org.chromium.base.ThreadUtils; @@ -292,7 +291,6 @@ // TODO(yfriedman): Remove dependency on a command line flag for this. DeviceUtils.addDeviceSpecificUserAgentSwitch(mContext); - ContextUtils.initApplicationContext(mContext); nativeSetCommandLineFlags( singleProcess, nativeIsPluginEnabled() ? getPlugins() : null); mPostResourceExtractionTasksCompleted = true; @@ -319,8 +317,6 @@ ResourceExtractor resourceExtractor = ResourceExtractor.get(mContext); resourceExtractor.startExtractingResources(); resourceExtractor.waitForCompletion(); - - ContextUtils.initApplicationContext(mContext.getApplicationContext()); nativeSetCommandLineFlags(false, null); }
diff --git a/content/public/android/javatests/src/org/chromium/content/browser/ChildProcessLauncherTest.java b/content/public/android/javatests/src/org/chromium/content/browser/ChildProcessLauncherTest.java index 9f439139..77016cd 100644 --- a/content/public/android/javatests/src/org/chromium/content/browser/ChildProcessLauncherTest.java +++ b/content/public/android/javatests/src/org/chromium/content/browser/ChildProcessLauncherTest.java
@@ -247,6 +247,6 @@ protected void setUp() throws Exception { super.setUp(); LibraryLoader.get(LibraryProcessType.PROCESS_CHILD) - .ensureInitialized(getInstrumentation().getContext()); + .ensureInitialized(getInstrumentation().getTargetContext()); } }
diff --git a/content/renderer/media/user_media_client_impl.cc b/content/renderer/media/user_media_client_impl.cc index 6b7d219..a19028a 100644 --- a/content/renderer/media/user_media_client_impl.cc +++ b/content/renderer/media/user_media_client_impl.cc
@@ -740,16 +740,13 @@ if (request_id == request->audio_input_request_id) { request->has_audio_input_returned = true; - DCHECK(request->audio_input_devices.empty()); request->audio_input_devices = device_array; } else if (request_id == request->video_input_request_id) { request->has_video_input_returned = true; - DCHECK(request->video_input_devices.empty()); request->video_input_devices = device_array; } else { DCHECK_EQ(request->audio_output_request_id, request_id); request->has_audio_output_returned = true; - DCHECK(request->audio_output_devices.empty()); request->audio_output_devices = device_array; }
diff --git a/content/shell/browser/layout_test/blink_test_controller.cc b/content/shell/browser/layout_test/blink_test_controller.cc index 91f7c13..450bbdf 100644 --- a/content/shell/browser/layout_test/blink_test_controller.cc +++ b/content/shell/browser/layout_test/blink_test_controller.cc
@@ -381,10 +381,10 @@ } void BlinkTestController::OnTestFinishedInSecondaryRenderer() { - RenderViewHost* render_view_host = + RenderViewHost* main_render_view_host = main_window_->web_contents()->GetRenderViewHost(); - render_view_host->Send( - new ShellViewMsg_NotifyDone(render_view_host->GetRoutingID())); + main_render_view_host->Send(new ShellViewMsg_TestFinishedInSecondaryRenderer( + main_render_view_host->GetRoutingID())); } bool BlinkTestController::IsMainWindow(WebContents* web_contents) const {
diff --git a/content/shell/browser/layout_test/layout_test_message_filter.cc b/content/shell/browser/layout_test/layout_test_message_filter.cc index 082fc238..c5fb851 100644 --- a/content/shell/browser/layout_test/layout_test_message_filter.cc +++ b/content/shell/browser/layout_test/layout_test_message_filter.cc
@@ -56,6 +56,7 @@ case LayoutTestHostMsg_SetPermission::ID: case LayoutTestHostMsg_ResetPermissions::ID: case LayoutTestHostMsg_LayoutTestRuntimeFlagsChanged::ID: + case LayoutTestHostMsg_TestFinishedInSecondaryRenderer::ID: *thread = BrowserThread::UI; break; } @@ -80,6 +81,8 @@ IPC_MESSAGE_HANDLER(LayoutTestHostMsg_ResetPermissions, OnResetPermissions) IPC_MESSAGE_HANDLER(LayoutTestHostMsg_LayoutTestRuntimeFlagsChanged, OnLayoutTestRuntimeFlagsChanged) + IPC_MESSAGE_HANDLER(LayoutTestHostMsg_TestFinishedInSecondaryRenderer, + OnTestFinishedInSecondaryRenderer) IPC_MESSAGE_UNHANDLED(handled = false) IPC_END_MESSAGE_MAP() @@ -193,4 +196,8 @@ render_process_id_, changed_layout_test_runtime_flags); } +void LayoutTestMessageFilter::OnTestFinishedInSecondaryRenderer() { + BlinkTestController::Get()->OnTestFinishedInSecondaryRenderer(); +} + } // namespace content
diff --git a/content/shell/browser/layout_test/layout_test_message_filter.h b/content/shell/browser/layout_test/layout_test_message_filter.h index 2123acfe..afab2fb 100644 --- a/content/shell/browser/layout_test/layout_test_message_filter.h +++ b/content/shell/browser/layout_test/layout_test_message_filter.h
@@ -72,6 +72,7 @@ void OnResetPermissions(); void OnLayoutTestRuntimeFlagsChanged( const base::DictionaryValue& changed_layout_test_runtime_flags); + void OnTestFinishedInSecondaryRenderer(); int render_process_id_;
diff --git a/content/shell/browser/layout_test/secondary_test_window_observer.cc b/content/shell/browser/layout_test/secondary_test_window_observer.cc index 933ce0e..3c8794ad 100644 --- a/content/shell/browser/layout_test/secondary_test_window_observer.cc +++ b/content/shell/browser/layout_test/secondary_test_window_observer.cc
@@ -17,21 +17,6 @@ SecondaryTestWindowObserver::~SecondaryTestWindowObserver() {} -bool SecondaryTestWindowObserver::OnMessageReceived( - const IPC::Message& message) { - bool handled = true; - IPC_BEGIN_MESSAGE_MAP(SecondaryTestWindowObserver, message) - IPC_MESSAGE_HANDLER(ShellViewHostMsg_TestFinishedInSecondaryRenderer, - OnTestFinishedInSecondaryRenderer) - IPC_MESSAGE_UNHANDLED(handled = false) - IPC_END_MESSAGE_MAP() - return handled; -} - -void SecondaryTestWindowObserver::OnTestFinishedInSecondaryRenderer() { - BlinkTestController::Get()->OnTestFinishedInSecondaryRenderer(); -} - void SecondaryTestWindowObserver::RenderFrameCreated( RenderFrameHost* render_frame_host) { DCHECK(!BlinkTestController::Get()->IsMainWindow(
diff --git a/content/shell/browser/layout_test/secondary_test_window_observer.h b/content/shell/browser/layout_test/secondary_test_window_observer.h index b41a95b..5e7f758 100644 --- a/content/shell/browser/layout_test/secondary_test_window_observer.h +++ b/content/shell/browser/layout_test/secondary_test_window_observer.h
@@ -18,18 +18,14 @@ ~SecondaryTestWindowObserver() override; // WebContentsObserver implementation. - bool OnMessageReceived(const IPC::Message& message) override; void RenderFrameCreated(RenderFrameHost* render_frame_host) override; void RenderFrameHostChanged(RenderFrameHost* old_host, RenderFrameHost* new_host) override; private: friend class WebContentsUserData<SecondaryTestWindowObserver>; - explicit SecondaryTestWindowObserver(WebContents* web_contents); - void OnTestFinishedInSecondaryRenderer(); - DISALLOW_COPY_AND_ASSIGN(SecondaryTestWindowObserver); };
diff --git a/content/shell/browser/shell.h b/content/shell/browser/shell.h index 547f338..590ccfd 100644 --- a/content/shell/browser/shell.h +++ b/content/shell/browser/shell.h
@@ -25,6 +25,10 @@ namespace gfx { class Screen; } +namespace display { +using Screen = gfx::Screen; +} + namespace wm { class WMTestHelper; } @@ -249,7 +253,7 @@ #elif defined(USE_AURA) #if defined(OS_CHROMEOS) static wm::WMTestHelper* wm_test_helper_; - static gfx::Screen* test_screen_; + static display::Screen* test_screen_; #endif #if defined(TOOLKIT_VIEWS) static views::ViewsDelegate* views_delegate_;
diff --git a/content/shell/browser/shell_aura.cc b/content/shell/browser/shell_aura.cc index cf704b93..dff4c2a 100644 --- a/content/shell/browser/shell_aura.cc +++ b/content/shell/browser/shell_aura.cc
@@ -17,7 +17,7 @@ void Shell::PlatformInitialize(const gfx::Size& default_window_size) { CHECK(!platform_); aura::TestScreen* screen = aura::TestScreen::Create(gfx::Size()); - gfx::Screen::SetScreenInstance(screen); + display::Screen::SetScreenInstance(screen); platform_ = new ShellPlatformDataAura(default_window_size); }
diff --git a/content/shell/browser/shell_platform_data_aura.cc b/content/shell/browser/shell_platform_data_aura.cc index 293b566..af14bb7 100644 --- a/content/shell/browser/shell_platform_data_aura.cc +++ b/content/shell/browser/shell_platform_data_aura.cc
@@ -16,7 +16,6 @@ #include "ui/base/ime/input_method.h" #include "ui/base/ime/input_method_delegate.h" #include "ui/base/ime/input_method_factory.h" -#include "ui/gfx/screen.h" #include "ui/wm/core/default_activation_client.h" namespace content {
diff --git a/content/shell/browser/shell_views.cc b/content/shell/browser/shell_views.cc index f7f8f286..1ca8493 100644 --- a/content/shell/browser/shell_views.cc +++ b/content/shell/browser/shell_views.cc
@@ -22,8 +22,8 @@ #include "ui/base/clipboard/clipboard.h" #include "ui/base/models/simple_menu_model.h" #include "ui/base/resource/resource_bundle.h" +#include "ui/display/screen.h" #include "ui/events/event.h" -#include "ui/gfx/screen.h" #include "ui/views/background.h" #include "ui/views/controls/button/label_button.h" #include "ui/views/controls/button/menu_button.h" @@ -385,7 +385,7 @@ #if defined(OS_CHROMEOS) wm::WMTestHelper* Shell::wm_test_helper_ = NULL; -gfx::Screen* Shell::test_screen_ = NULL; +display::Screen* Shell::test_screen_ = NULL; #endif views::ViewsDelegate* Shell::views_delegate_ = NULL; @@ -397,11 +397,11 @@ #endif #if defined(OS_CHROMEOS) test_screen_ = aura::TestScreen::Create(gfx::Size()); - gfx::Screen::SetScreenInstance(test_screen_); + display::Screen::SetScreenInstance(test_screen_); wm_test_helper_ = new wm::WMTestHelper(default_window_size, GetContextFactory()); #else - gfx::Screen::SetScreenInstance(views::CreateDesktopScreen()); + display::Screen::SetScreenInstance(views::CreateDesktopScreen()); #endif views_delegate_ = new views::DesktopTestViewsDelegate(); }
diff --git a/content/shell/common/layout_test/layout_test_messages.h b/content/shell/common/layout_test/layout_test_messages.h index b9712e5..2946722b8 100644 --- a/content/shell/common/layout_test/layout_test_messages.h +++ b/content/shell/common/layout_test/layout_test_messages.h
@@ -52,3 +52,6 @@ IPC_MESSAGE_CONTROL1( LayoutTestMsg_ReplicateLayoutTestRuntimeFlagsChanges, base::DictionaryValue /* changed_layout_test_runtime_flags */) + +// Sent by secondary test window to notify the test has finished. +IPC_MESSAGE_CONTROL0(LayoutTestHostMsg_TestFinishedInSecondaryRenderer)
diff --git a/content/shell/common/shell_messages.h b/content/shell/common/shell_messages.h index 248ca20..ef45330 100644 --- a/content/shell/common/shell_messages.h +++ b/content/shell/common/shell_messages.h
@@ -50,9 +50,9 @@ // main test window) for a layout test. IPC_MESSAGE_ROUTED0(ShellViewMsg_SetupSecondaryRenderer) -// Tells the main window that a secondary renderer in a different process thinks -// the test is finished. -IPC_MESSAGE_ROUTED0(ShellViewMsg_NotifyDone) +// Tells the main window that a secondary renderer in a different process asked +// to finish the test. +IPC_MESSAGE_ROUTED0(ShellViewMsg_TestFinishedInSecondaryRenderer) // Pushes a snapshot of the current session history from the browser process. // This includes only information about those RenderViews that are in the @@ -100,8 +100,6 @@ IPC_MESSAGE_ROUTED0(ShellViewHostMsg_ResetDone) -IPC_MESSAGE_ROUTED0(ShellViewHostMsg_TestFinishedInSecondaryRenderer) - // WebTestDelegate related. IPC_MESSAGE_ROUTED1(ShellViewHostMsg_OverridePreferences, content::WebPreferences /* preferences */)
diff --git a/content/shell/renderer/layout_test/blink_test_runner.cc b/content/shell/renderer/layout_test/blink_test_runner.cc index e90df06..81a61a31 100644 --- a/content/shell/renderer/layout_test/blink_test_runner.cc +++ b/content/shell/renderer/layout_test/blink_test_runner.cc
@@ -534,7 +534,8 @@ void BlinkTestRunner::TestFinished() { if (!is_main_window_ || !render_view()->GetMainRenderFrame()) { - Send(new ShellViewHostMsg_TestFinishedInSecondaryRenderer(routing_id())); + RenderThread::Get()->Send( + new LayoutTestHostMsg_TestFinishedInSecondaryRenderer()); return; } test_runner::WebTestInterfaces* interfaces = @@ -716,7 +717,8 @@ IPC_BEGIN_MESSAGE_MAP(BlinkTestRunner, message) IPC_MESSAGE_HANDLER(ShellViewMsg_SessionHistory, OnSessionHistory) IPC_MESSAGE_HANDLER(ShellViewMsg_Reset, OnReset) - IPC_MESSAGE_HANDLER(ShellViewMsg_NotifyDone, OnNotifyDone) + IPC_MESSAGE_HANDLER(ShellViewMsg_TestFinishedInSecondaryRenderer, + OnTestFinishedInSecondaryRenderer) IPC_MESSAGE_HANDLER(ShellViewMsg_TryLeakDetection, OnTryLeakDetection) IPC_MESSAGE_HANDLER(ShellViewMsg_ReplyBluetoothManualChooserEvents, OnReplyBluetoothManualChooserEvents) @@ -938,9 +940,9 @@ Send(new ShellViewHostMsg_ResetDone(routing_id())); } -void BlinkTestRunner::OnNotifyDone() { - render_view()->GetWebView()->mainFrame()->executeScript( - WebScriptSource(WebString::fromUTF8("testRunner.notifyDone();"))); +void BlinkTestRunner::OnTestFinishedInSecondaryRenderer() { + DCHECK(is_main_window_ && render_view()->GetMainRenderFrame()); + TestFinished(); } void BlinkTestRunner::OnTryLeakDetection() {
diff --git a/content/shell/renderer/layout_test/blink_test_runner.h b/content/shell/renderer/layout_test/blink_test_runner.h index c5329e0..91d527a9 100644 --- a/content/shell/renderer/layout_test/blink_test_runner.h +++ b/content/shell/renderer/layout_test/blink_test_runner.h
@@ -176,7 +176,7 @@ const std::vector<std::vector<PageState> >& session_histories, const std::vector<unsigned>& current_entry_indexes); void OnReset(); - void OnNotifyDone(); + void OnTestFinishedInSecondaryRenderer(); void OnTryLeakDetection(); void OnReplyBluetoothManualChooserEvents( const std::vector<std::string>& events);
diff --git a/content/test/BUILD.gn b/content/test/BUILD.gn index b2dde28..cd17f0a 100644 --- a/content/test/BUILD.gn +++ b/content/test/BUILD.gn
@@ -687,6 +687,7 @@ "//ui/accessibility", "//ui/base:test_support", "//ui/compositor:test_support", + "//ui/display", "//ui/events/blink", "//ui/gfx:test_support", "//ui/gfx/geometry",
diff --git a/extensions/renderer/api/display_source/display_source_session.cc b/extensions/renderer/api/display_source/display_source_session.cc index 8759977..ae2b6754 100644 --- a/extensions/renderer/api/display_source/display_source_session.cc +++ b/extensions/renderer/api/display_source/display_source_session.cc
@@ -40,8 +40,9 @@ const DisplaySourceSessionParams& params) { #if defined(ENABLE_WIFI_DISPLAY) return std::unique_ptr<DisplaySourceSession>(new WiFiDisplaySession(params)); -#endif +#else return nullptr; +#endif } } // namespace extensions
diff --git a/extensions/renderer/api/display_source/wifi_display/wifi_display_media_packetizer_unittest.cc b/extensions/renderer/api/display_source/wifi_display/wifi_display_media_packetizer_unittest.cc index 8a5839b..eae5c27 100644 --- a/extensions/renderer/api/display_source/wifi_display/wifi_display_media_packetizer_unittest.cc +++ b/extensions/renderer/api/display_source/wifi_display/wifi_display_media_packetizer_unittest.cc
@@ -169,7 +169,8 @@ }; struct ProgramClockReference { - enum { kInvalidBase = ~static_cast<uint64_t>(0u) }; + static const uint64_t kInvalidBase = ~static_cast<uint64_t>(0u); + uint64_t base; uint16_t extension; }; @@ -560,14 +561,13 @@ ? WiFiDisplayElementaryStreamPacketizer::kFirstVideoStreamId : WiFiDisplayElementaryStreamPacketizer::kFirstAudioStreamId; - WiFiDisplayElementaryStreamPacketizer packetizer; uint8_t unit_header_data[kMaxUnitHeaderSize]; for (size_t unit_header_size = 0u; unit_header_size <= kMaxUnitHeaderSize; ++unit_header_size) { WiFiDisplayElementaryStreamPacket packet = - packetizer.EncodeElementaryStreamUnit(stream_id, unit_header_data, - unit_header_size, unit_.data(), - unit_.size(), pts_, dts_); + WiFiDisplayElementaryStreamPacketizer::EncodeElementaryStreamUnit( + stream_id, unit_header_data, unit_header_size, unit_.data(), + unit_.size(), pts_, dts_); CheckElementaryStreamPacketHeader(packet, stream_id); CheckElementaryStreamPacketUnitHeader(packet, unit_header_data, unit_header_size); @@ -672,7 +672,6 @@ stream_infos.emplace_back(WiFiDisplayElementaryStreamInfo::AUDIO_LPCM, std::move(lpcm_descriptors)); stream_infos.emplace_back(WiFiDisplayElementaryStreamInfo::AUDIO_AAC); - WiFiDisplayElementaryStreamPacketizer elementary_stream_packetizer; FakeTransportStreamPacketizer packetizer( base::TimeDelta::FromMilliseconds(200), stream_infos); @@ -696,7 +695,7 @@ auto normalized_dts = dts_; packetizer.NormalizeUnitTimeStamps(&normalized_pts, &normalized_dts); WiFiDisplayElementaryStreamPacket elementary_stream_packet = - elementary_stream_packetizer.EncodeElementaryStreamUnit( + WiFiDisplayElementaryStreamPacketizer::EncodeElementaryStreamUnit( kStreamIds[stream_index], unit_header_data, unit_header_size, unit_.data(), unit_.size(), normalized_pts, normalized_dts); @@ -783,7 +782,7 @@ // Check datagram packets. ProgramClockReference pcr = {ProgramClockReference::kInvalidBase, 0u}; - uint16_t sequence_number; + uint16_t sequence_number = 0u; uint32_t synchronization_source_identifier; auto transport_stream_packet_it = transport_stream_packets.cbegin(); for (const auto& packet : packets) {
diff --git a/extensions/renderer/api/display_source/wifi_display/wifi_display_transport_stream_packetizer.cc b/extensions/renderer/api/display_source/wifi_display/wifi_display_transport_stream_packetizer.cc index 6c1917e..22e1bcf 100644 --- a/extensions/renderer/api/display_source/wifi_display/wifi_display_transport_stream_packetizer.cc +++ b/extensions/renderer/api/display_source/wifi_display/wifi_display_transport_stream_packetizer.cc
@@ -460,9 +460,8 @@ UpdateDelayForUnitTimeStamps(pts, dts); NormalizeUnitTimeStamps(&pts, &dts); - WiFiDisplayElementaryStreamPacketizer elementary_stream_packetizer; WiFiDisplayElementaryStreamPacket elementary_stream_packet = - elementary_stream_packetizer.EncodeElementaryStreamUnit( + WiFiDisplayElementaryStreamPacketizer::EncodeElementaryStreamUnit( stream_state.stream_id, stream_state.unit_header.data, stream_state.unit_header.size, unit_data, unit_size, pts, dts); @@ -477,14 +476,10 @@ // (only for the first and/or the last packet): // - for the first packet to hold flags // - for the last packet to hold padding - // * PES packet header (only for the first packet): - // - PES packet header base - // - Optional PES header base - // - Optional PES header optional fields: - // - Presentation time stamp - // - Decoding time stamp + // * Elementary stream packet header (only for the first packet) + // * Elementary stream packet unit header (only for the first packet) bool adaptation_field_flag = false; - size_t header_min_size; + size_t header_min_size = 0u; const bool is_payload_unit_start_or_end = is_payload_unit_start || remaining_unit_size <= WiFiDisplayTransportStreamPacket::kPacketSize -
diff --git a/gpu/ipc/common/gpu_param_traits_macros.h b/gpu/ipc/common/gpu_param_traits_macros.h index d610357..8c65904 100644 --- a/gpu/ipc/common/gpu_param_traits_macros.h +++ b/gpu/ipc/common/gpu_param_traits_macros.h
@@ -11,7 +11,6 @@ #include "gpu/gpu_export.h" #include "gpu/ipc/common/gpu_stream_constants.h" #include "ipc/ipc_message_macros.h" -#include "ui/gfx/gpu_memory_buffer.h" #include "ui/gfx/ipc/geometry/gfx_param_traits.h" #include "ui/gfx/ipc/gfx_param_traits.h" #include "ui/gfx/swap_result.h" @@ -40,26 +39,6 @@ IPC_STRUCT_TRAITS_MEMBER(max_framerate_denominator) IPC_STRUCT_TRAITS_END() -IPC_ENUM_TRAITS_MAX_VALUE(gfx::GpuMemoryBufferType, - gfx::GPU_MEMORY_BUFFER_TYPE_LAST) - -IPC_STRUCT_TRAITS_BEGIN(gfx::GpuMemoryBufferHandle) - IPC_STRUCT_TRAITS_MEMBER(id) - IPC_STRUCT_TRAITS_MEMBER(type) - IPC_STRUCT_TRAITS_MEMBER(handle) - IPC_STRUCT_TRAITS_MEMBER(offset) - IPC_STRUCT_TRAITS_MEMBER(stride) -#if defined(USE_OZONE) - IPC_STRUCT_TRAITS_MEMBER(native_pixmap_handle) -#elif defined(OS_MACOSX) - IPC_STRUCT_TRAITS_MEMBER(mach_port) -#endif -IPC_STRUCT_TRAITS_END() - -IPC_STRUCT_TRAITS_BEGIN(gfx::GpuMemoryBufferId) - IPC_STRUCT_TRAITS_MEMBER(id) -IPC_STRUCT_TRAITS_END() - IPC_ENUM_TRAITS_MAX_VALUE(gfx::GpuPreference, gfx::GpuPreferenceLast) IPC_ENUM_TRAITS_MAX_VALUE(gpu::GpuStreamPriority, gpu::GpuStreamPriority::LAST) IPC_ENUM_TRAITS_MAX_VALUE(gfx::SwapResult, gfx::SwapResult::SWAP_RESULT_LAST)
diff --git a/ios/third_party/earl_grey/earl_grey.gyp b/ios/third_party/earl_grey/earl_grey.gyp index cdd6fcd..7cfd3cd 100644 --- a/ios/third_party/earl_grey/earl_grey.gyp +++ b/ios/third_party/earl_grey/earl_grey.gyp
@@ -272,6 +272,11 @@ 'CODE_SIGN_IDENTITY[sdk=iphoneos*]': 'iPhone Developer', 'BUNDLE_IDENTIFIER': 'com.google.earlgrey.EarlGrey', 'INFOPLIST_FILE': 'src/EarlGrey-Info.plist', + 'DYLIB_INSTALL_NAME_BASE': '@rpath', + 'OTHER_LDFLAGS': [ + '-Xlinker', '-rpath', '-Xlinker', '@executable_path/Frameworks', + '-Xlinker', '-rpath', '-Xlinker', '@loader_path/Frameworks' + ] }, 'link_settings': { 'libraries': [
diff --git a/ios/third_party/ochamcrest/ochamcrest.gyp b/ios/third_party/ochamcrest/ochamcrest.gyp index 9ca749b..bf1ec1b 100644 --- a/ios/third_party/ochamcrest/ochamcrest.gyp +++ b/ios/third_party/ochamcrest/ochamcrest.gyp
@@ -230,6 +230,11 @@ 'CODE_SIGN_IDENTITY[sdk=iphoneos*]': 'iPhone Developer', 'PRODUCT_BUNDLE_IDENTIFIER': 'org.hamcrest.OCHamcrest.OCHamcrest-iOS', 'INFOPLIST_FILE': 'src/Source/OCHamcrest-Info.plist', + 'DYLIB_INSTALL_NAME_BASE': '@rpath', + 'OTHER_LDFLAGS': [ + '-Xlinker', '-rpath', '-Xlinker', '@executable_path/Frameworks', + '-Xlinker', '-rpath', '-Xlinker', '@loader_path/Frameworks' + ] }, 'include_dirs': [ 'src',
diff --git a/ios/web/ios_web_shell_tests.gyp b/ios/web/ios_web_shell_tests.gyp index 4bc2817b..685b266 100644 --- a/ios/web/ios_web_shell_tests.gyp +++ b/ios/web/ios_web_shell_tests.gyp
@@ -51,6 +51,10 @@ }, 'xcode_settings': { 'INFOPLIST_FILE': 'shell/test/Host-Info.plist', + 'OTHER_LDFLAGS': [ + '-Xlinker', '-rpath', '-Xlinker', '@executable_path/Frameworks', + '-Xlinker', '-rpath', '-Xlinker', '@loader_path/Frameworks' + ] }, 'dependencies': [ 'ios_web_shell_test_support',
diff --git a/mojo/android/javatests/src/org/chromium/mojo/MojoTestCase.java b/mojo/android/javatests/src/org/chromium/mojo/MojoTestCase.java index 3e81b7a8..c7348caa 100644 --- a/mojo/android/javatests/src/org/chromium/mojo/MojoTestCase.java +++ b/mojo/android/javatests/src/org/chromium/mojo/MojoTestCase.java
@@ -4,6 +4,7 @@ package org.chromium.mojo; +import android.content.Context; import android.test.InstrumentationTestCase; import org.chromium.base.ContextUtils; @@ -25,9 +26,9 @@ @Override protected void setUp() throws Exception { super.setUp(); - LibraryLoader.get(LibraryProcessType.PROCESS_BROWSER) - .ensureInitialized(getInstrumentation().getTargetContext()); - ContextUtils.initApplicationContext(getInstrumentation().getTargetContext()); + Context appContext = getInstrumentation().getTargetContext().getApplicationContext(); + ContextUtils.initApplicationContext(appContext); + LibraryLoader.get(LibraryProcessType.PROCESS_BROWSER).ensureInitialized(appContext); nativeInit(); mTestEnvironmentPointer = nativeSetupTestEnvironment(); }
diff --git a/mojo/edk/system/message_pipe_perftest.cc b/mojo/edk/system/message_pipe_perftest.cc index 6e348c8..63ae6c57 100644 --- a/mojo/edk/system/message_pipe_perftest.cc +++ b/mojo/edk/system/message_pipe_perftest.cc
@@ -5,12 +5,16 @@ #include <stddef.h> #include <stdint.h> +#include <memory> #include <utility> #include "base/bind.h" +#include "base/bind_helpers.h" #include "base/logging.h" +#include "base/macros.h" #include "base/strings/stringprintf.h" #include "base/test/perf_time_logger.h" +#include "base/threading/thread.h" #include "mojo/edk/embedder/embedder.h" #include "mojo/edk/embedder/scoped_platform_handle.h" #include "mojo/edk/system/handle_signals_state.h" @@ -25,11 +29,9 @@ namespace edk { namespace { -class MultiprocessMessagePipePerfTest : public test::MojoTestBase { +class MessagePipePerfTest : public test::MojoTestBase { public: - MultiprocessMessagePipePerfTest() - : message_count_(0), - message_size_(0) {} + MessagePipePerfTest() : message_count_(0), message_size_(0) {} void SetUpMeasurement(int message_count, size_t message_size) { message_count_ = message_count; @@ -76,50 +78,82 @@ logger.Done(); } + protected: + void RunPingPongServer(MojoHandle mp) { + // This values are set to align with one at ipc_pertests.cc for comparison. + const size_t kMsgSize[5] = {12, 144, 1728, 20736, 248832}; + const int kMessageCount[5] = {50000, 50000, 50000, 12000, 1000}; + + for (size_t i = 0; i < 5; i++) { + SetUpMeasurement(kMessageCount[i], kMsgSize[i]); + Measure(mp); + } + + SendQuitMessage(mp); + } + + static int RunPingPongClient(MojoHandle mp) { + std::string buffer(1000000, '\0'); + int rv = 0; + while (true) { + // Wait for our end of the message pipe to be readable. + HandleSignalsState hss; + MojoResult result = + MojoWait(mp, MOJO_HANDLE_SIGNAL_READABLE, + MOJO_DEADLINE_INDEFINITE, &hss); + if (result != MOJO_RESULT_OK) { + rv = result; + break; + } + + uint32_t read_size = static_cast<uint32_t>(buffer.size()); + CHECK_EQ(MojoReadMessage(mp, &buffer[0], + &read_size, nullptr, + 0, MOJO_READ_MESSAGE_FLAG_NONE), + MOJO_RESULT_OK); + + // Empty message indicates quit. + if (read_size == 0) + break; + + CHECK_EQ(MojoWriteMessage(mp, &buffer[0], + read_size, + nullptr, 0, MOJO_WRITE_MESSAGE_FLAG_NONE), + MOJO_RESULT_OK); + } + + return rv; + } + private: int message_count_; size_t message_size_; std::string payload_; std::string read_buffer_; std::unique_ptr<base::PerfTimeLogger> perf_logger_; + + DISALLOW_COPY_AND_ASSIGN(MessagePipePerfTest); }; +TEST_F(MessagePipePerfTest, PingPong) { + MojoHandle server_handle, client_handle; + CreateMessagePipe(&server_handle, &client_handle); + + base::Thread client_thread("PingPongClient"); + client_thread.Start(); + client_thread.task_runner()->PostTask( + FROM_HERE, + base::Bind(base::IgnoreResult(&RunPingPongClient), client_handle)); + + RunPingPongServer(server_handle); +} + // For each message received, sends a reply message with the same contents // repeated twice, until the other end is closed or it receives "quitquitquit" // (which it doesn't reply to). It'll return the number of messages received, // not including any "quitquitquit" message, modulo 100. -DEFINE_TEST_CLIENT_WITH_PIPE(PingPongClient, MultiprocessMessagePipePerfTest, - h) { - std::string buffer(1000000, '\0'); - int rv = 0; - while (true) { - // Wait for our end of the message pipe to be readable. - HandleSignalsState hss; - MojoResult result = - MojoWait(h, MOJO_HANDLE_SIGNAL_READABLE, - MOJO_DEADLINE_INDEFINITE, &hss); - if (result != MOJO_RESULT_OK) { - rv = result; - break; - } - - uint32_t read_size = static_cast<uint32_t>(buffer.size()); - CHECK_EQ(MojoReadMessage(h, &buffer[0], - &read_size, nullptr, - 0, MOJO_READ_MESSAGE_FLAG_NONE), - MOJO_RESULT_OK); - - // Empty message indicates quit. - if (read_size == 0) - break; - - CHECK_EQ(MojoWriteMessage(h, &buffer[0], - read_size, - nullptr, 0, MOJO_WRITE_MESSAGE_FLAG_NONE), - MOJO_RESULT_OK); - } - - return rv; +DEFINE_TEST_CLIENT_WITH_PIPE(PingPongClient, MessagePipePerfTest, h) { + return RunPingPongClient(h); } // Repeatedly sends messages as previous one got replied by the child. @@ -127,22 +161,13 @@ // number of messages has been sent. #if defined(OS_ANDROID) // Android multi-process tests are not executing the new process. This is flaky. -#define MAYBE_PingPong DISABLED_PingPong +#define MAYBE_MultiprocessPingPong DISABLED_MultiprocessPingPong #else -#define MAYBE_PingPong PingPong +#define MAYBE_MultiprocessPingPong MultiprocessPingPong #endif // defined(OS_ANDROID) -TEST_F(MultiprocessMessagePipePerfTest, MAYBE_PingPong) { +TEST_F(MessagePipePerfTest, MAYBE_MultiprocessPingPong) { RUN_CHILD_ON_PIPE(PingPongClient, h) - // This values are set to align with one at ipc_pertests.cc for comparison. - const size_t kMsgSize[5] = {12, 144, 1728, 20736, 248832}; - const int kMessageCount[5] = {50000, 50000, 50000, 12000, 1000}; - - for (size_t i = 0; i < 5; i++) { - SetUpMeasurement(kMessageCount[i], kMsgSize[i]); - Measure(h); - } - - SendQuitMessage(h); + RunPingPongServer(h); END_CHILD() }
diff --git a/mojo/edk/system/ports/node.cc b/mojo/edk/system/ports/node.cc index 3324397..40b8325 100644 --- a/mojo/edk/system/ports/node.cc +++ b/mojo/edk/system/ports/node.cc
@@ -301,6 +301,7 @@ } Port* port = port_ref.port(); + NodeName peer_node_name; { // We must acquire |ports_lock_| before grabbing any port locks, because // WillSendMessage_Locked may need to lock multiple ports out of order. @@ -322,10 +323,12 @@ // do to recover. Assume that failure beyond this point must be treated as a // transport failure. - if (port->peer_node_name != name_) { - delegate_->ForwardMessage(port->peer_node_name, std::move(m)); - return OK; - } + peer_node_name = port->peer_node_name; + } + + if (peer_node_name != name_) { + delegate_->ForwardMessage(peer_node_name, std::move(m)); + return OK; } int rv = AcceptMessage(std::move(m)); @@ -367,6 +370,7 @@ const NodeName& destination_node_name, const PortName& destination_port_name) { Port* port = port_ref.port(); + MergePortEventData data; { // |ports_lock_| must be held for WillSendPort_Locked below. base::AutoLock ports_lock(ports_lock_); @@ -377,15 +381,14 @@ // Send the port-to-merge over to the destination node so it can be merged // into the port cycle atomically there. - MergePortEventData data; data.new_port_name = port_ref.name(); WillSendPort_Locked(port, destination_node_name, &data.new_port_name, &data.new_port_descriptor); - delegate_->ForwardMessage( - destination_node_name, - NewInternalMessage(destination_port_name, - EventType::kMergePort, data)); } + delegate_->ForwardMessage( + destination_node_name, + NewInternalMessage(destination_port_name, + EventType::kMergePort, data)); return OK; } @@ -691,6 +694,9 @@ // ObserveProxyAck. bool notify_delegate = false; + ObserveClosureEventData forwarded_data; + NodeName peer_node_name; + PortName peer_port_name; { // We must acquire |ports_lock_| before the port lock because it must be // held for MaybeRemoveProxy_Locked. @@ -710,8 +716,6 @@ // cares about it. This ensures that any dead-end proxies beyond that port // are notified to remove themselves. - ObserveClosureEventData forwarded_data; - if (port->state == Port::kReceiving) { notify_delegate = true; @@ -741,11 +745,14 @@ << " (last_sequence_num=" << forwarded_data.last_sequence_num << ")"; - delegate_->ForwardMessage( - port->peer_node_name, - NewInternalMessage(port->peer_port_name, - EventType::kObserveClosure, forwarded_data)); + peer_node_name = port->peer_node_name; + peer_port_name = port->peer_port_name; } + delegate_->ForwardMessage( + peer_node_name, + NewInternalMessage(peer_port_name, EventType::kObserveClosure, + forwarded_data)); + if (notify_delegate) { PortRef port_ref(port_name, port); delegate_->PortStatusChanged(port_ref);
diff --git a/net/android/junit/src/org/chromium/net/HttpNegotiateAuthenticatorTest.java b/net/android/junit/src/org/chromium/net/HttpNegotiateAuthenticatorTest.java index de211a1..09485e3 100644 --- a/net/android/junit/src/org/chromium/net/HttpNegotiateAuthenticatorTest.java +++ b/net/android/junit/src/org/chromium/net/HttpNegotiateAuthenticatorTest.java
@@ -98,7 +98,7 @@ @Before public void setUp() { MockitoAnnotations.initMocks(this); - ContextUtils.initApplicationContextForJUnitTests(Robolectric.application); + ContextUtils.initApplicationContextForTests(Robolectric.application); } @After
diff --git a/net/spdy/spdy_protocol.h b/net/spdy/spdy_protocol.h index d66cddd0..aefc341 100644 --- a/net/spdy/spdy_protocol.h +++ b/net/spdy/spdy_protocol.h
@@ -55,6 +55,10 @@ // the maximum control frame size we accept. const uint32_t kSpdyInitialFrameSizeLimit = 1 << 14; +// The initial value for the maximum size of the header list, "unlimited" (max +// unsigned 32-bit int) as per the spec. +const uint32_t kSpdyInitialHeaderListSizeLimit = 0xFFFFFFFF; + // Maximum window size for a Spdy stream or session. const int32_t kSpdyMaximumWindowSize = 0x7FFFFFFF; // Max signed 32bit int
diff --git a/remoting/android/host/src/org/chromium/chromoting/host/jni/Host.java b/remoting/android/host/src/org/chromium/chromoting/host/jni/Host.java index e5aff2375..04c3857e9 100644 --- a/remoting/android/host/src/org/chromium/chromoting/host/jni/Host.java +++ b/remoting/android/host/src/org/chromium/chromoting/host/jni/Host.java
@@ -30,8 +30,9 @@ * @param context The Application context. */ public static void loadLibrary(Context context) { + ContextUtils.initApplicationContext(context.getApplicationContext()); System.loadLibrary("remoting_host_jni"); - ContextUtils.initApplicationContext(context); + ContextUtils.initApplicationContextForNative(); } public Host() {
diff --git a/remoting/android/java/src/org/chromium/chromoting/jni/JniInterface.java b/remoting/android/java/src/org/chromium/chromoting/jni/JniInterface.java index 95b1671..47a8d2b 100644 --- a/remoting/android/java/src/org/chromium/chromoting/jni/JniInterface.java +++ b/remoting/android/java/src/org/chromium/chromoting/jni/JniInterface.java
@@ -25,9 +25,9 @@ * @param context The Application context. */ public static void loadLibrary(Context context) { + ContextUtils.initApplicationContext(context.getApplicationContext()); System.loadLibrary("remoting_client_jni"); - - ContextUtils.initApplicationContext(context); + ContextUtils.initApplicationContextForNative(); nativeLoadNative(); }
diff --git a/skia/ext/benchmarking_canvas.cc b/skia/ext/benchmarking_canvas.cc index 1160b18..cccedd0 100644 --- a/skia/ext/benchmarking_canvas.cc +++ b/skia/ext/benchmarking_canvas.cc
@@ -18,7 +18,6 @@ #include "third_party/skia/include/core/SkRRect.h" #include "third_party/skia/include/core/SkRegion.h" #include "third_party/skia/include/core/SkString.h" -#include "third_party/skia/include/core/SkTLazy.h" #include "third_party/skia/include/core/SkTextBlob.h" #include "third_party/skia/include/core/SkXfermode.h" @@ -453,14 +452,13 @@ class BenchmarkingCanvas::AutoOp { public: + // AutoOp objects are always scoped within draw call frames, + // so the paint is guaranteed to be valid for their lifetime. AutoOp(BenchmarkingCanvas* canvas, const char op_name[], const SkPaint* paint = nullptr) : canvas_(canvas) , op_record_(new base::DictionaryValue()) - , op_params_(new base::ListValue()) - // AutoOp objects are always scoped within draw call frames, - // so the paint is guaranteed to be valid for their lifetime. - , paint_(paint) { + , op_params_(new base::ListValue()) { DCHECK(canvas); DCHECK(op_name); @@ -468,15 +466,16 @@ op_record_->SetString("cmd_string", op_name); op_record_->Set("info", op_params_); - if (paint) + if (paint) { this->addParam("paint", AsValue(*paint)); + filtered_paint_ = *paint; + } if (canvas->flags_ & kOverdrawVisualization_Flag) { DCHECK(canvas->overdraw_xfermode_); - paint_ = paint ? filtered_paint_.set(*paint) : filtered_paint_.init(); - filtered_paint_.get()->setXfermode(canvas->overdraw_xfermode_); - filtered_paint_.get()->setAntiAlias(false); + filtered_paint_.setXfermode(canvas->overdraw_xfermode_); + filtered_paint_.setAntiAlias(false); } start_ticks_ = base::TimeTicks::Now(); @@ -496,7 +495,7 @@ op_params_->Append(param.release()); } - const SkPaint* paint() const { return paint_; } + const SkPaint* paint() const { return &filtered_paint_; } private: BenchmarkingCanvas* canvas_; @@ -504,8 +503,7 @@ base::ListValue* op_params_; base::TimeTicks start_ticks_; - const SkPaint* paint_; - SkTLazy<SkPaint> filtered_paint_; + SkPaint filtered_paint_; }; BenchmarkingCanvas::BenchmarkingCanvas(SkCanvas* canvas, unsigned flags)
diff --git a/testing/android/native_test/java/src/org/chromium/native_test/NativeUnitTestActivity.java b/testing/android/native_test/java/src/org/chromium/native_test/NativeUnitTestActivity.java index c708549..8411583 100644 --- a/testing/android/native_test/java/src/org/chromium/native_test/NativeUnitTestActivity.java +++ b/testing/android/native_test/java/src/org/chromium/native_test/NativeUnitTestActivity.java
@@ -6,6 +6,7 @@ import android.os.Bundle; +import org.chromium.base.ContextUtils; import org.chromium.base.Log; import org.chromium.base.PathUtils; import org.chromium.base.PowerMonitor; @@ -29,6 +30,7 @@ // Needed by system_monitor_unittest.cc PowerMonitor.createForTests(this); + ContextUtils.initApplicationContext(getApplicationContext()); loadLibraries(); } @@ -38,5 +40,6 @@ System.loadLibrary(library); Log.i(TAG, "loaded: %s", library); } + ContextUtils.initApplicationContextForNative(); } }
diff --git a/testing/android/native_test/native_test_launcher.cc b/testing/android/native_test/native_test_launcher.cc index eb652d99..0f880a74 100644 --- a/testing/android/native_test/native_test_launcher.cc +++ b/testing/android/native_test/native_test_launcher.cc
@@ -75,10 +75,6 @@ static const char* const kInitialArgv[] = { "ChromeTestActivity" }; base::CommandLine::Init(arraysize(kInitialArgv), kInitialArgv); - // Set the application context in base. - base::android::RegisterJni(env); - base::android::InitApplicationContext(env, app_context); - std::vector<std::string> args; const std::string command_line_file_path( @@ -133,6 +129,9 @@ } bool RegisterNativeTestJNI(JNIEnv* env) { + if (!base::android::RegisterJni(env)) { + return false; + } return RegisterNativesImpl(env); }
diff --git a/testing/libfuzzer/fuzzers/BUILD.gn b/testing/libfuzzer/fuzzers/BUILD.gn index 0ca391d..a302af47 100644 --- a/testing/libfuzzer/fuzzers/BUILD.gn +++ b/testing/libfuzzer/fuzzers/BUILD.gn
@@ -219,6 +219,7 @@ "//v8:parser_fuzzer", ] dict = "dicts/js.dict" + seed_corpus = "//v8/test/mjsunit/regress/" } fuzzer_test("v8_json_parser_fuzzer") {
diff --git a/testing/variations/fieldtrial_testing_config_win.json b/testing/variations/fieldtrial_testing_config_win.json index f1cb787..06e995291 100644 --- a/testing/variations/fieldtrial_testing_config_win.json +++ b/testing/variations/fieldtrial_testing_config_win.json
@@ -193,10 +193,16 @@ ], "PreRead": [ { - "group_name": "NoPrefetchArgument", + "group_name": "NoPrefetchArgument2", "params": { "NoPrefetchArgument": "true" } + }, + { + "group_name": "PreReadChromeChildInBrowser", + "params": { + "PreReadChromeChildInBrowser": "true" + } } ], "QUIC": [
diff --git a/third_party/WebKit/LayoutTests/FlagExpectations/site-per-process b/third_party/WebKit/LayoutTests/FlagExpectations/site-per-process index ab88eec..8e9ad9906 100644 --- a/third_party/WebKit/LayoutTests/FlagExpectations/site-per-process +++ b/third_party/WebKit/LayoutTests/FlagExpectations/site-per-process
@@ -20,8 +20,6 @@ # Uninvestigated timeouts (possibly variants of https://crbug.com/584984) http/tests/history/cross-origin-redirect-on-back.html [ Timeout Crash ] -http/tests/security/cross-frame-access-document-direct.html [ Crash Timeout ] -http/tests/security/referrer-policy-origin-when-crossorigin-is-crossorigin.html [ Crash Timeout ] # https://crbug.com/582201 - missing console message about blocked XSS. http/tests/security/javascriptURL/javascriptURL-execution-context-frame-src-getAttribute-value.html [ Failure ] @@ -86,9 +84,6 @@ http/tests/security/mixedContent/insecure-eventsource-in-main-frame.html [ Failure ] # Uninvestigated failures under http/tests/security: -http/tests/security/cookies/third-party-cookie-blocking.html [ Timeout ] -http/tests/security/cookies/third-party-cookie-blocking-user-action.html [ Timeout ] -http/tests/security/cross-frame-access-delete.html [ Timeout ] http/tests/security/cross-frame-access-enumeration.html [ Timeout ] http/tests/security/cross-frame-access-get-custom-property-cached.html [ Timeout ] http/tests/security/cross-frame-access-get.html [ Timeout ] @@ -96,34 +91,21 @@ http/tests/security/cross-frame-access-getOwnPropertyDescriptor.html [ Timeout ] http/tests/security/cross-frame-access-location-get.html [ Timeout ] http/tests/security/cross-frame-access-location-get-override.html [ Timeout ] -http/tests/security/cross-frame-access-location-put.html [ Timeout ] -http/tests/security/cross-frame-access-object-prototype.html [ Timeout ] http/tests/security/cross-origin-shared-worker-allowed.html [ Failure Timeout ] http/tests/security/cross-origin-worker-indexeddb-allowed.html [ Failure Timeout ] -http/tests/security/dataURL/xss-DENIED-from-data-url-in-foreign-domain-subframe.html [ Timeout ] -http/tests/security/drag-drop-different-origin.html [ Timeout ] http/tests/security/frameNavigation/not-opener.html [ Timeout ] http/tests/security/frameNavigation/xss-DENIED-targeted-link-navigation.html [ Timeout ] -http/tests/security/host-compare-case-insensitive.html [ Timeout ] -http/tests/security/mixedContent/insecure-css-image-with-reload.html [ Timeout ] -http/tests/security/mixedContent/insecure-xhr-in-main-frame.html [ Timeout ] http/tests/security/referrer-policy-redirect-link.html [ Timeout ] -http/tests/security/window-events-clear-domain.html [ Timeout ] -http/tests/security/xssAuditor/anchor-url-dom-write-location-javascript-URL.html [ Timeout ] -http/tests/security/xssAuditor/dom-write-location-javascript-URL.html [ Timeout ] -http/tests/security/xssAuditor/get-from-iframe.html [ Timeout ] -http/tests/security/xssAuditor/link-opens-new-window.html [ Timeout ] -http/tests/security/xssAuditor/post-from-iframe.html [ Timeout ] -http/tests/security/xssAuditor/script-tag-post-control-char.html [ Timeout ] -http/tests/security/xssAuditor/script-tag-post.html [ Timeout ] -http/tests/security/xssAuditor/script-tag-post-null-char.html [ Failure Timeout ] -http/tests/security/xssAuditor/script-tag-post-redirect.html [ Timeout ] +http/tests/security/xssAuditor/post-from-iframe.html [ Failure ] +http/tests/security/xssAuditor/script-tag-post-control-char.html [ Failure ] +http/tests/security/xssAuditor/script-tag-post.html [ Failure ] +http/tests/security/xssAuditor/script-tag-post-null-char.html [ Failure ] http/tests/security/xssAuditor/script-tag-with-callbacks.html [ Failure ] -http/tests/security/xssAuditor/xss-filter-bypass-long-string.html [ Timeout ] +http/tests/security/xssAuditor/xss-filter-bypass-long-string.html [ Failure ] # Uninvestigated failures under http/tests (but outside of http/tests/security): http/tests/appcache/remove-cache.html [ Failure ] -http/tests/inspector-protocol/access-inspected-object.html [ Timeout Failure ] +http/tests/inspector-protocol/access-inspected-object.html [ Failure ] http/tests/inspector/injected-script-for-origin.html [ Failure ] http/tests/local/serviceworker/fetch-request-body-file.html [ Failure Crash ] http/tests/inspector-protocol/request-mixed-content-status-blockable.html [ Timeout ] @@ -148,4 +130,3 @@ http/tests/w3c/webperf/submission/Intel/resource-timing/test_resource_timing_cross_origin_redirect_with_timing_allow_origin.html [ Timeout ] http/tests/w3c/webperf/submission/Intel/resource-timing/test_resource_timing_cross_origin_resource_request.html [ Timeout ] http/tests/w3c/webperf/submission/Intel/resource-timing/test_resource_timing_timing_allow_cross_origin_resource_request.html [ Timeout ] -http/tests/workers/shared-worker-secure-context.https.html [ Timeout ]
diff --git a/third_party/WebKit/LayoutTests/TestExpectations b/third_party/WebKit/LayoutTests/TestExpectations index c5d54c2..32893c0 100644 --- a/third_party/WebKit/LayoutTests/TestExpectations +++ b/third_party/WebKit/LayoutTests/TestExpectations
@@ -543,9 +543,6 @@ crbug.com/542660 fast/css/absolute-inline-alignment-2.html [ Failure ] -crbug.com/603997 compositing/overflow/clear-scroll-parent.html [ NeedsManualRebaseline ] -crbug.com/603997 virtual/prefer_compositing_to_lcd_text/compositing/overflow/clear-scroll-parent.html [ NeedsManualRebaseline ] - # Ref tests that needs investigation. crbug.com/404597 [ Mac ] fast/css3-text/css3-text-justify/text-justify-crash.html [ Failure ] crbug.com/404597 fast/forms/long-text-in-input.html [ Failure ] @@ -1049,11 +1046,6 @@ crbug.com/548695 fast/forms/datalist/update-range-with-datalist.html [ Failure ] -crbug.com/607259 [ Win ] css2.1/t1508-c527-font-08-b.html [ NeedsManualRebaseline ] -crbug.com/607259 [ Win ] css2.1/t1504-c523-font-style-00-b.html [ NeedsManualRebaseline ] -crbug.com/607259 [ Win ] css1/font_properties/font_style.html [ NeedsManualRebaseline ] -crbug.com/607259 [ Win ] svg/batik/text/textStyles.svg [ NeedsManualRebaseline ] - # Temporarily disabled after chromium change crbug.com/492511 [ Mac ] fast/text/atsui-negative-spacing-features.html [ Failure ] crbug.com/492511 [ Mac ] fast/text/international/arabic-justify.html [ Failure ]
diff --git a/third_party/WebKit/LayoutTests/compositing/overflow/clear-scroll-parent-expected.txt b/third_party/WebKit/LayoutTests/compositing/overflow/clear-scroll-parent-expected.txt index 82736418..a7e022e7 100644 --- a/third_party/WebKit/LayoutTests/compositing/overflow/clear-scroll-parent-expected.txt +++ b/third_party/WebKit/LayoutTests/compositing/overflow/clear-scroll-parent-expected.txt
@@ -47,13 +47,13 @@ "backgroundColor": "#008000" }, { - "position": [12, 12], + "position": [4, 4], "bounds": [80, 80], "shouldFlattenTransform": false, "hasScrollParent": true, "children": [ { - "position": [10, 10], + "position": [18, 18], "bounds": [100, 100], "contentsOpaque": true, "drawsContent": true,
diff --git a/third_party/WebKit/LayoutTests/fast/canvas/OffscreenCanvas-getContext2D-expected.txt b/third_party/WebKit/LayoutTests/fast/canvas/OffscreenCanvas-getContext-expected.txt similarity index 91% rename from third_party/WebKit/LayoutTests/fast/canvas/OffscreenCanvas-getContext2D-expected.txt rename to third_party/WebKit/LayoutTests/fast/canvas/OffscreenCanvas-getContext-expected.txt index 6894f5c0..e78be60 100644 --- a/third_party/WebKit/LayoutTests/fast/canvas/OffscreenCanvas-getContext2D-expected.txt +++ b/third_party/WebKit/LayoutTests/fast/canvas/OffscreenCanvas-getContext-expected.txt
@@ -13,7 +13,7 @@ PASS ctx2 is null PASS ctx3 is non-null. PASS ctx3 == ctx is true -PASS bogusCtx is null +PASS ctx4 is an instance of WebGLRenderingContext PASS successfullyParsed is true TEST COMPLETE
diff --git a/third_party/WebKit/LayoutTests/fast/canvas/OffscreenCanvas-getContext2D-in-worker-expected.txt b/third_party/WebKit/LayoutTests/fast/canvas/OffscreenCanvas-getContext-in-worker-expected.txt similarity index 100% rename from third_party/WebKit/LayoutTests/fast/canvas/OffscreenCanvas-getContext2D-in-worker-expected.txt rename to third_party/WebKit/LayoutTests/fast/canvas/OffscreenCanvas-getContext-in-worker-expected.txt
diff --git a/third_party/WebKit/LayoutTests/fast/canvas/OffscreenCanvas-getContext2D-in-worker.html b/third_party/WebKit/LayoutTests/fast/canvas/OffscreenCanvas-getContext-in-worker.html similarity index 72% rename from third_party/WebKit/LayoutTests/fast/canvas/OffscreenCanvas-getContext2D-in-worker.html rename to third_party/WebKit/LayoutTests/fast/canvas/OffscreenCanvas-getContext-in-worker.html index e555fa9..91a3fd0 100644 --- a/third_party/WebKit/LayoutTests/fast/canvas/OffscreenCanvas-getContext2D-in-worker.html +++ b/third_party/WebKit/LayoutTests/fast/canvas/OffscreenCanvas-getContext-in-worker.html
@@ -5,10 +5,15 @@ <script id="myWorker" type="text/worker"> self.onmessage = function(e) { var aCanvas = new OffscreenCanvas(50, 50); + var bCanvas = new OffscreenCanvas(50, 50); try { - var ctx = aCanvas.getContext('2d'); - if (toString.call(ctx) != '[object OffscreenCanvasRenderingContext2D]') { + var ctx1 = aCanvas.getContext('2d'); + //TODO(crbug.com/602391): implement get webgl context in worker + var ctx2 = bCanvas.getContext('webgl'); + if (toString.call(ctx1) != '[object OffscreenCanvasRenderingContext2D]') { self.postMessage("aCanvas.getContext('2d') does not return [object OffscreenCanvasRenderingContext2D]"); + } else if (toString.call(ctx2) != '[object Null]') { + self.postMessage("bCanvas.getContext('webgl') does not return [object Null]"); } else { self.postMessage("success"); }
diff --git a/third_party/WebKit/LayoutTests/fast/canvas/OffscreenCanvas-getContext2D.html b/third_party/WebKit/LayoutTests/fast/canvas/OffscreenCanvas-getContext.html similarity index 89% rename from third_party/WebKit/LayoutTests/fast/canvas/OffscreenCanvas-getContext2D.html rename to third_party/WebKit/LayoutTests/fast/canvas/OffscreenCanvas-getContext.html index be7fad2..786b1c8 100644 --- a/third_party/WebKit/LayoutTests/fast/canvas/OffscreenCanvas-getContext2D.html +++ b/third_party/WebKit/LayoutTests/fast/canvas/OffscreenCanvas-getContext.html
@@ -32,7 +32,7 @@ // TODO: change the below part of the test when webgl is supported. // Calling getContext on an unimplemented context type will return null -var bogusCanvas = new OffscreenCanvas(20, 20); -var bogusCtx = bogusCanvas.getContext("webgl"); -shouldBeNull("bogusCtx"); +var bCanvas = new OffscreenCanvas(20, 20); +var ctx4 = bCanvas.getContext("webgl"); +shouldBeType("ctx4", "WebGLRenderingContext"); </script>
diff --git a/third_party/WebKit/LayoutTests/fast/canvas/canvas-ImageBitmap-close-expected.txt b/third_party/WebKit/LayoutTests/fast/canvas/canvas-ImageBitmap-close-expected.txt index 26836ff4..736ae1b 100644 --- a/third_party/WebKit/LayoutTests/fast/canvas/canvas-ImageBitmap-close-expected.txt +++ b/third_party/WebKit/LayoutTests/fast/canvas/canvas-ImageBitmap-close-expected.txt
@@ -9,9 +9,9 @@ PASS bitmap.height is imgHeight PASS bitmap.width is 0 PASS bitmap.height is 0 -PASS ctx.drawImage(bitmap, 0, 0) threw exception InvalidStateError: Failed to execute 'drawImage' on 'CanvasRenderingContext2D': The image source is neutered. -PASS Apply structured clone to an already closed bitmap is rejected as expected: DataCloneError: Failed to execute 'postMessage' on 'Worker': An ImageBitmap is neutered and could not be cloned. -PASS Apply transfering to an already closed bitmap is rejected as expected: DataCloneError: Failed to execute 'postMessage' on 'Worker': An ImageBitmap is neutered and could not be cloned. +PASS ctx.drawImage(bitmap, 0, 0) threw exception InvalidStateError: Failed to execute 'drawImage' on 'CanvasRenderingContext2D': The image source is detached. +PASS Apply structured clone to an already closed bitmap is rejected as expected: DataCloneError: Failed to execute 'postMessage' on 'Worker': An ImageBitmap is detached and could not be cloned. +PASS Apply transfering to an already closed bitmap is rejected as expected: DataCloneError: Failed to execute 'postMessage' on 'Worker': An ImageBitmap is detached and could not be cloned. PASS createImageBitmap from a closed ImageBitmap was rejected. IndexSizeError: Failed to execute 'createImageBitmap' on 'Window': The source width provided is 0. PASS bitmap.width is 0 PASS bitmap.height is 0
diff --git a/third_party/WebKit/LayoutTests/fast/canvas/canvas-ImageBitmap-transferable-expected.txt b/third_party/WebKit/LayoutTests/fast/canvas/canvas-ImageBitmap-transferable-expected.txt index 699627a7..17a76da 100644 --- a/third_party/WebKit/LayoutTests/fast/canvas/canvas-ImageBitmap-transferable-expected.txt +++ b/third_party/WebKit/LayoutTests/fast/canvas/canvas-ImageBitmap-transferable-expected.txt
@@ -7,7 +7,7 @@ PASS bitmapHeight is imageHeight PASS bitmapWidth is 0 PASS bitmapHeight is 0 -PASS Apply structured cloning to a neutered ImageBitmap should throw an exception: DataCloneError: Failed to execute 'postMessage' on 'Worker': An ImageBitmap is neutered and could not be cloned. +PASS Apply structured cloning to a neutered ImageBitmap should throw an exception: DataCloneError: Failed to execute 'postMessage' on 'Worker': An ImageBitmap is detached and could not be cloned. PASS createImageBitmap from a neutered ImageBitmap was rejected PASS bitmapWidth is imageWidth PASS bitmapHeight is imageHeight
diff --git a/third_party/WebKit/LayoutTests/fast/dom/SelectorAPI/namespaced-elements-and-selectors-expected.txt b/third_party/WebKit/LayoutTests/fast/dom/SelectorAPI/namespaced-elements-and-selectors-expected.txt new file mode 100644 index 0000000..22a2eb7 --- /dev/null +++ b/third_party/WebKit/LayoutTests/fast/dom/SelectorAPI/namespaced-elements-and-selectors-expected.txt
@@ -0,0 +1,12 @@ +querySelectorAll and namespaces + +On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE". + + +PASS sandbox.querySelectorAll('span').length is 3 +PASS sandbox.querySelectorAll('*|span').length is 3 +PASS sandbox.querySelectorAll('|span').length is 1 +PASS successfullyParsed is true + +TEST COMPLETE +
diff --git a/third_party/WebKit/LayoutTests/fast/dom/SelectorAPI/namespaced-elements-and-selectors.html b/third_party/WebKit/LayoutTests/fast/dom/SelectorAPI/namespaced-elements-and-selectors.html new file mode 100644 index 0000000..2f5a54e --- /dev/null +++ b/third_party/WebKit/LayoutTests/fast/dom/SelectorAPI/namespaced-elements-and-selectors.html
@@ -0,0 +1,15 @@ +<!DOCTYPE html> +<script src="../../../resources/js-test.js"></script> +<div id="sandbox"> + <span></span> +</div> +<script> +description("querySelectorAll and namespaces"); + +sandbox.appendChild(document.createElementNS("http://dummynamespace", "span")); +sandbox.appendChild(document.createElementNS("", "span")); + +shouldBe("sandbox.querySelectorAll('span').length", "3"); +shouldBe("sandbox.querySelectorAll('*|span').length", "3"); +shouldBe("sandbox.querySelectorAll('|span').length", "1"); +</script>
diff --git a/third_party/WebKit/LayoutTests/http/tests/loading/redirect-methods.html b/third_party/WebKit/LayoutTests/http/tests/loading/redirect-methods.html index 55e2cdb..39abd27 100644 --- a/third_party/WebKit/LayoutTests/http/tests/loading/redirect-methods.html +++ b/third_party/WebKit/LayoutTests/http/tests/loading/redirect-methods.html
@@ -33,8 +33,14 @@ var iframe = document.getElementById(frameID); if (iframe.hasAttribute("submitted")) { if (++frameID == testCodes.length) { - if (window.testRunner) - testRunner.notifyDone(); + if (window.testRunner) { + // Before finishing the test, we have to allow the callstack to + // unwind - this enables dumping of pending WebFrameClient + // callbacks (i.e. didFinishLoad and/or didHandleOnloadEvents). + window.setTimeout(function() { + testRunner.notifyDone(); + }, 0); + } return; } createFrame(frameID);
diff --git a/third_party/WebKit/LayoutTests/http/tests/security/contentSecurityPolicy/1.1/scripthash-handler-allowed.html b/third_party/WebKit/LayoutTests/http/tests/security/contentSecurityPolicy/1.1/scripthash-handler-allowed.html index b73cc17..e37a963e 100644 --- a/third_party/WebKit/LayoutTests/http/tests/security/contentSecurityPolicy/1.1/scripthash-handler-allowed.html +++ b/third_party/WebKit/LayoutTests/http/tests/security/contentSecurityPolicy/1.1/scripthash-handler-allowed.html
@@ -24,7 +24,7 @@ }, 'Inline event handlers not whitelisted by the policy should generate error events.'); </script> - <meta http-equiv="Content-Security-Policy" content="script-src 'sha256-nhtYaXCssBJTThiDLYewspQYue9tisulEwJ3nTJKcMI='"> + <meta http-equiv="Content-Security-Policy" content="script-src 'sha256-nhtYaXCssBJTThiDLYewspQYue9tisulEwJ3nTJKcMI=' 'unsafe-hashed-attributes'"> </head> <body> <button id="pass" onclick="expectSuccess(this)"></button>
diff --git a/third_party/WebKit/LayoutTests/http/tests/security/contentSecurityPolicy/1.1/scripthash-handler-blocked.html b/third_party/WebKit/LayoutTests/http/tests/security/contentSecurityPolicy/1.1/scripthash-handler-blocked.html new file mode 100644 index 0000000..b5e21d1 --- /dev/null +++ b/third_party/WebKit/LayoutTests/http/tests/security/contentSecurityPolicy/1.1/scripthash-handler-blocked.html
@@ -0,0 +1,24 @@ +<!DOCTYPE html> +<html> + <head> + <script src="/resources/testharness.js"></script> + <script src="/resources/testharnessreport.js"></script> + <script> + async_test(function (t) { + window.expectSuccess = t.unreached_func("Handler should not execute."); + window.addEventListener('load', t.step_func(function () { + document.querySelector('#pass').click(); + })); + document.addEventListener('securitypolicyviolation', t.step_func_done(function (e) { + assert_equals(e.target, document); + })); + }, 'Inline event handlers whitelisted by the policy should not fire, as \'unsafe-hash-attributes\' is not present.'); + </script> + + <meta http-equiv="Content-Security-Policy" content="script-src 'sha256-nhtYaXCssBJTThiDLYewspQYue9tisulEwJ3nTJKcMI='"> + </head> + <body> + <button id="pass" onclick="expectFailure(this)"></button> + <button id="fail" onclick="expectFailure(this)"></button> + </body> +</html>
diff --git a/third_party/WebKit/LayoutTests/imported/web-platform-tests/dom/events/Event-propagation-expected.txt b/third_party/WebKit/LayoutTests/imported/web-platform-tests/dom/events/Event-propagation-expected.txt deleted file mode 100644 index 991c91f..0000000 --- a/third_party/WebKit/LayoutTests/imported/web-platform-tests/dom/events/Event-propagation-expected.txt +++ /dev/null
@@ -1,8 +0,0 @@ -This is a testharness.js-based test. -PASS Newly-created Event -PASS After stopPropagation() -FAIL Reinitialized after stopPropagation() assert_equals: Propagation flag expected true but got false -PASS After stopImmediatePropagation() -FAIL Reinitialized after stopImmediatePropagation() assert_equals: Propagation flag expected true but got false -Harness: the test ran to completion. -
diff --git a/third_party/WebKit/LayoutTests/platform/android/compositing/overflow/clear-scroll-parent-expected.txt b/third_party/WebKit/LayoutTests/platform/android/compositing/overflow/clear-scroll-parent-expected.txt new file mode 100644 index 0000000..82736418 --- /dev/null +++ b/third_party/WebKit/LayoutTests/platform/android/compositing/overflow/clear-scroll-parent-expected.txt
@@ -0,0 +1,86 @@ +{ + "bounds": [800, 600], + "children": [ + { + "bounds": [800, 600], + "contentsOpaque": true, + "drawsContent": true, + "children": [ + { + "position": [8, 8], + "bounds": [308, 208], + "shouldFlattenTransform": false, + "drawsContent": true, + "children": [ + { + "position": [4, 4], + "bounds": [285, 200], + "shouldFlattenTransform": false, + "children": [ + { + "bounds": [285, 530], + "drawsContent": true + } + ] + }, + { + "bounds": [308, 208], + "children": [ + { + "position": [289, 4], + "bounds": [15, 185] + }, + { + "position": [289, 189], + "bounds": [15, 15], + "drawsContent": true + } + ] + } + ] + }, + { + "position": [50, 200], + "bounds": [200, 200], + "contentsOpaque": true, + "drawsContent": true, + "backgroundColor": "#008000" + }, + { + "position": [12, 12], + "bounds": [80, 80], + "shouldFlattenTransform": false, + "hasScrollParent": true, + "children": [ + { + "position": [10, 10], + "bounds": [100, 100], + "contentsOpaque": true, + "drawsContent": true, + "backgroundColor": "#FF0000" + } + ] + }, + { + "shouldFlattenTransform": false, + "hasScrollParent": true, + "children": [ + { + "position": [22, 102], + "bounds": [100, 100], + "contentsOpaque": true, + "drawsContent": true, + "backgroundColor": "#0000FF" + }, + { + "position": [22, 212], + "bounds": [100, 320], + "drawsContent": true + } + ] + } + ] + } + ] +} +
diff --git a/third_party/WebKit/LayoutTests/platform/android/virtual/prefer_compositing_to_lcd_text/compositing/overflow/clear-scroll-parent-expected.txt b/third_party/WebKit/LayoutTests/platform/android/virtual/prefer_compositing_to_lcd_text/compositing/overflow/clear-scroll-parent-expected.txt new file mode 100644 index 0000000..82736418 --- /dev/null +++ b/third_party/WebKit/LayoutTests/platform/android/virtual/prefer_compositing_to_lcd_text/compositing/overflow/clear-scroll-parent-expected.txt
@@ -0,0 +1,86 @@ +{ + "bounds": [800, 600], + "children": [ + { + "bounds": [800, 600], + "contentsOpaque": true, + "drawsContent": true, + "children": [ + { + "position": [8, 8], + "bounds": [308, 208], + "shouldFlattenTransform": false, + "drawsContent": true, + "children": [ + { + "position": [4, 4], + "bounds": [285, 200], + "shouldFlattenTransform": false, + "children": [ + { + "bounds": [285, 530], + "drawsContent": true + } + ] + }, + { + "bounds": [308, 208], + "children": [ + { + "position": [289, 4], + "bounds": [15, 185] + }, + { + "position": [289, 189], + "bounds": [15, 15], + "drawsContent": true + } + ] + } + ] + }, + { + "position": [50, 200], + "bounds": [200, 200], + "contentsOpaque": true, + "drawsContent": true, + "backgroundColor": "#008000" + }, + { + "position": [12, 12], + "bounds": [80, 80], + "shouldFlattenTransform": false, + "hasScrollParent": true, + "children": [ + { + "position": [10, 10], + "bounds": [100, 100], + "contentsOpaque": true, + "drawsContent": true, + "backgroundColor": "#FF0000" + } + ] + }, + { + "shouldFlattenTransform": false, + "hasScrollParent": true, + "children": [ + { + "position": [22, 102], + "bounds": [100, 100], + "contentsOpaque": true, + "drawsContent": true, + "backgroundColor": "#0000FF" + }, + { + "position": [22, 212], + "bounds": [100, 320], + "drawsContent": true + } + ] + } + ] + } + ] +} +
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.10/fast/forms/suggestion-picker/month-suggestion-picker-appearance-with-scroll-bar-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mac10.10/fast/forms/suggestion-picker/month-suggestion-picker-appearance-with-scroll-bar-expected.png index 3d61b46..ca8d067 100644 --- a/third_party/WebKit/LayoutTests/platform/mac-mac10.10/fast/forms/suggestion-picker/month-suggestion-picker-appearance-with-scroll-bar-expected.png +++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.10/fast/forms/suggestion-picker/month-suggestion-picker-appearance-with-scroll-bar-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.10/fast/forms/suggestion-picker/time-suggestion-picker-appearance-rtl-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mac10.10/fast/forms/suggestion-picker/time-suggestion-picker-appearance-rtl-expected.png index 2e00afc..a5c0196 100644 --- a/third_party/WebKit/LayoutTests/platform/mac-mac10.10/fast/forms/suggestion-picker/time-suggestion-picker-appearance-rtl-expected.png +++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.10/fast/forms/suggestion-picker/time-suggestion-picker-appearance-rtl-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/css1/font_properties/font_style-expected.png b/third_party/WebKit/LayoutTests/platform/win/css1/font_properties/font_style-expected.png index bc4eb9a..73c037e 100644 --- a/third_party/WebKit/LayoutTests/platform/win/css1/font_properties/font_style-expected.png +++ b/third_party/WebKit/LayoutTests/platform/win/css1/font_properties/font_style-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/css2.1/t1504-c523-font-style-00-b-expected.png b/third_party/WebKit/LayoutTests/platform/win/css2.1/t1504-c523-font-style-00-b-expected.png index c4df9b8..5b787c1d 100644 --- a/third_party/WebKit/LayoutTests/platform/win/css2.1/t1504-c523-font-style-00-b-expected.png +++ b/third_party/WebKit/LayoutTests/platform/win/css2.1/t1504-c523-font-style-00-b-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/css2.1/t1508-c527-font-08-b-expected.png b/third_party/WebKit/LayoutTests/platform/win/css2.1/t1508-c527-font-08-b-expected.png index 93a5f79a5..c3dd5ff 100644 --- a/third_party/WebKit/LayoutTests/platform/win/css2.1/t1508-c527-font-08-b-expected.png +++ b/third_party/WebKit/LayoutTests/platform/win/css2.1/t1508-c527-font-08-b-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/svg/batik/text/textStyles-expected.png b/third_party/WebKit/LayoutTests/platform/win/svg/batik/text/textStyles-expected.png index cc6aec7a..7d89179 100644 --- a/third_party/WebKit/LayoutTests/platform/win/svg/batik/text/textStyles-expected.png +++ b/third_party/WebKit/LayoutTests/platform/win/svg/batik/text/textStyles-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/svg/batik/text/textStyles-expected.txt b/third_party/WebKit/LayoutTests/platform/win/svg/batik/text/textStyles-expected.txt index 8e3e8824..eba396f 100644 --- a/third_party/WebKit/LayoutTests/platform/win/svg/batik/text/textStyles-expected.txt +++ b/third_party/WebKit/LayoutTests/platform/win/svg/batik/text/textStyles-expected.txt
@@ -29,10 +29,10 @@ LayoutSVGText {text} at (-36,3) size 72x15 contains 1 chunk(s) LayoutSVGInlineText {#text} at (0,0) size 71x15 chunk 1 (middle anchor) text run 1 at (-35.50,15.00) startOffset 0 endOffset 15 width 71.00: "SansSerif, bold" - LayoutSVGContainer {g} at (307,83) size 88x45 [transform={m=((1.00,0.00)(0.00,1.00)) t=(350.00,110.00)}] - LayoutSVGContainer {use} at (307,83) size 88x34 - LayoutSVGText {text} at (-43,-27) size 88x34 contains 1 chunk(s) - LayoutSVGInlineText {#text} at (0,0) size 87x34 + LayoutSVGContainer {g} at (307,83) size 89x45 [transform={m=((1.00,0.00)(0.00,1.00)) t=(350.00,110.00)}] + LayoutSVGContainer {use} at (307,83) size 89x34 + LayoutSVGText {text} at (-43,-27) size 89x34 contains 1 chunk(s) + LayoutSVGInlineText {#text} at (0,0) size 88x34 chunk 1 (middle anchor) text run 1 at (-42.49,0.00) startOffset 0 endOffset 6 width 84.98: "sample" LayoutSVGText {text} at (-43,3) size 86x15 contains 1 chunk(s) LayoutSVGInlineText {#text} at (0,0) size 85x15 @@ -53,10 +53,10 @@ LayoutSVGText {text} at (-25,3) size 50x15 contains 1 chunk(s) LayoutSVGInlineText {#text} at (0,0) size 49x15 chunk 1 (middle anchor) text run 1 at (-24.50,15.00) startOffset 0 endOffset 11 width 49.00: "Serif, bold" - LayoutSVGContainer {g} at (307,133) size 88x45 [transform={m=((1.00,0.00)(0.00,1.00)) t=(350.00,160.00)}] - LayoutSVGContainer {use} at (307,133) size 88x34 - LayoutSVGText {text} at (-43,-27) size 88x34 contains 1 chunk(s) - LayoutSVGInlineText {#text} at (0,0) size 87x34 + LayoutSVGContainer {g} at (307,133) size 89x45 [transform={m=((1.00,0.00)(0.00,1.00)) t=(350.00,160.00)}] + LayoutSVGContainer {use} at (307,133) size 89x34 + LayoutSVGText {text} at (-43,-27) size 89x34 contains 1 chunk(s) + LayoutSVGInlineText {#text} at (0,0) size 88x34 chunk 1 (middle anchor) text run 1 at (-42.49,0.00) startOffset 0 endOffset 6 width 84.98: "sample" LayoutSVGText {text} at (-32,3) size 64x15 contains 1 chunk(s) LayoutSVGInlineText {#text} at (0,0) size 63x15 @@ -78,9 +78,9 @@ LayoutSVGInlineText {#text} at (0,0) size 90x15 chunk 1 (middle anchor) text run 1 at (-45.00,15.00) startOffset 0 endOffset 16 width 90.00: "Monospaced, bold" LayoutSVGContainer {g} at (298,183) size 104x45 [transform={m=((1.00,0.00)(0.00,1.00)) t=(350.00,210.00)}] - LayoutSVGContainer {use} at (307,183) size 88x34 - LayoutSVGText {text} at (-43,-27) size 88x34 contains 1 chunk(s) - LayoutSVGInlineText {#text} at (0,0) size 87x34 + LayoutSVGContainer {use} at (307,183) size 89x34 + LayoutSVGText {text} at (-43,-27) size 89x34 contains 1 chunk(s) + LayoutSVGInlineText {#text} at (0,0) size 88x34 chunk 1 (middle anchor) text run 1 at (-42.49,0.00) startOffset 0 endOffset 6 width 84.98: "sample" LayoutSVGText {text} at (-52,3) size 104x15 contains 1 chunk(s) LayoutSVGInlineText {#text} at (0,0) size 104x15 @@ -94,9 +94,9 @@ LayoutSVGInlineText {#text} at (0,0) size 41x15 chunk 1 (middle anchor) text run 1 at (-20.50,15.00) startOffset 0 endOffset 9 width 41.00: "(default)" LayoutSVGContainer {g} at (174,233) size 102x45 [transform={m=((1.00,0.00)(0.00,1.00)) t=(225.00,260.00)}] - LayoutSVGContainer {use} at (180,233) size 92x34 - LayoutSVGText {text} at (-45,-27) size 92x34 contains 1 chunk(s) - LayoutSVGInlineText {#text} at (0,0) size 92x34 + LayoutSVGContainer {use} at (180,233) size 93x34 + LayoutSVGText {text} at (-45,-27) size 93x34 contains 1 chunk(s) + LayoutSVGInlineText {#text} at (0,0) size 93x34 chunk 1 (middle anchor) text run 1 at (-45.00,0.00) startOffset 0 endOffset 6 width 90.00: "sample" LayoutSVGText {text} at (-51,3) size 102x15 contains 1 chunk(s) LayoutSVGInlineText {#text} at (0,0) size 101x15
diff --git a/third_party/WebKit/LayoutTests/virtual/prefer_compositing_to_lcd_text/compositing/overflow/clear-scroll-parent-expected.txt b/third_party/WebKit/LayoutTests/virtual/prefer_compositing_to_lcd_text/compositing/overflow/clear-scroll-parent-expected.txt index 82736418..a7e022e7 100644 --- a/third_party/WebKit/LayoutTests/virtual/prefer_compositing_to_lcd_text/compositing/overflow/clear-scroll-parent-expected.txt +++ b/third_party/WebKit/LayoutTests/virtual/prefer_compositing_to_lcd_text/compositing/overflow/clear-scroll-parent-expected.txt
@@ -47,13 +47,13 @@ "backgroundColor": "#008000" }, { - "position": [12, 12], + "position": [4, 4], "bounds": [80, 80], "shouldFlattenTransform": false, "hasScrollParent": true, "children": [ { - "position": [10, 10], + "position": [18, 18], "bounds": [100, 100], "contentsOpaque": true, "drawsContent": true,
diff --git a/third_party/WebKit/Source/bindings/core/v8/ScriptValueSerializer.cpp b/third_party/WebKit/Source/bindings/core/v8/ScriptValueSerializer.cpp index 94a19886..ce69fab 100644 --- a/third_party/WebKit/Source/bindings/core/v8/ScriptValueSerializer.cpp +++ b/third_party/WebKit/Source/bindings/core/v8/ScriptValueSerializer.cpp
@@ -1053,7 +1053,7 @@ if (!imageBitmap) return nullptr; if (imageBitmap->isNeutered()) - return handleError(DataCloneError, "An ImageBitmap is neutered and could not be cloned.", next); + return handleError(DataCloneError, "An ImageBitmap is detached and could not be cloned.", next); OwnPtr<uint8_t[]> pixelData = imageBitmap->copyBitmapData(PremultiplyAlpha); m_writer.writeImageBitmap(imageBitmap->width(), imageBitmap->height(), pixelData.get(), imageBitmap->width() * imageBitmap->height() * 4); return nullptr; @@ -1123,7 +1123,7 @@ if (!imageBitmap) return 0; if (imageBitmap->isNeutered()) - return handleError(DataCloneError, "An ImageBitmap is neutered and could not be cloned.", next); + return handleError(DataCloneError, "An ImageBitmap is detached and could not be cloned.", next); m_writer.writeTransferredImageBitmap(index); return 0; }
diff --git a/third_party/WebKit/Source/bindings/core/v8/SerializedScriptValue.cpp b/third_party/WebKit/Source/bindings/core/v8/SerializedScriptValue.cpp index 43cc0f8..0863f1e 100644 --- a/third_party/WebKit/Source/bindings/core/v8/SerializedScriptValue.cpp +++ b/third_party/WebKit/Source/bindings/core/v8/SerializedScriptValue.cpp
@@ -125,7 +125,7 @@ for (size_t i = 0; i < imageBitmaps.size(); ++i) { if (imageBitmaps[i]->isNeutered()) { - exceptionState.throwDOMException(DataCloneError, "ImageBitmap at index " + String::number(i) + " is already neutered."); + exceptionState.throwDOMException(DataCloneError, "ImageBitmap at index " + String::number(i) + " is already detached."); return; } } @@ -151,7 +151,7 @@ if (visited.contains(offscreenCanvases[i].get())) continue; if (offscreenCanvases[i]->isNeutered()) { - exceptionState.throwDOMException(DataCloneError, "OffscreenCanvas at index " + String::number(i) + " is already neutered."); + exceptionState.throwDOMException(DataCloneError, "OffscreenCanvas at index " + String::number(i) + " is already detached."); return; } if (offscreenCanvases[i]->renderingContext()) {
diff --git a/third_party/WebKit/Source/bindings/core/v8/ToV8.h b/third_party/WebKit/Source/bindings/core/v8/ToV8.h index 39ad5dd..3f4a9779 100644 --- a/third_party/WebKit/Source/bindings/core/v8/ToV8.h +++ b/third_party/WebKit/Source/bindings/core/v8/ToV8.h
@@ -198,11 +198,15 @@ template<typename Sequence> inline v8::Local<v8::Value> toV8SequenceInternal(const Sequence& sequence, v8::Local<v8::Object> creationContext, v8::Isolate* isolate) { - v8::Local<v8::Array> array = v8::Array::New(isolate, sequence.size()); + v8::Local<v8::Array> array; + { + v8::Context::Scope contextScope(creationContext->CreationContext()); + array = v8::Array::New(isolate, sequence.size()); + } uint32_t index = 0; typename Sequence::const_iterator end = sequence.end(); for (typename Sequence::const_iterator iter = sequence.begin(); iter != end; ++iter) { - v8::Local<v8::Value> value = toV8(*iter, creationContext, isolate); + v8::Local<v8::Value> value = toV8(*iter, array, isolate); if (value.IsEmpty()) value = v8::Undefined(isolate); if (!v8CallBoolean(array->Set(isolate->GetCurrentContext(), v8::Integer::New(isolate, index++), value))) @@ -226,9 +230,13 @@ template<typename T> inline v8::Local<v8::Value> toV8(const Vector<std::pair<String, T>>& value, v8::Local<v8::Object> creationContext, v8::Isolate* isolate) { - v8::Local<v8::Object> object = v8::Object::New(isolate); + v8::Local<v8::Object> object; + { + v8::Context::Scope contextScope(creationContext->CreationContext()); + object = v8::Object::New(isolate); + } for (unsigned i = 0; i < value.size(); ++i) { - v8::Local<v8::Value> v8Value = toV8(value[i].second, creationContext, isolate); + v8::Local<v8::Value> v8Value = toV8(value[i].second, object, isolate); if (v8Value.IsEmpty()) v8Value = v8::Undefined(isolate); if (!v8CallBoolean(object->Set(isolate->GetCurrentContext(), v8String(isolate, value[i].first), v8Value)))
diff --git a/third_party/WebKit/Source/bindings/core/v8/V8LazyEventListener.cpp b/third_party/WebKit/Source/bindings/core/v8/V8LazyEventListener.cpp index 58e0541..967857f 100644 --- a/third_party/WebKit/Source/bindings/core/v8/V8LazyEventListener.cpp +++ b/third_party/WebKit/Source/bindings/core/v8/V8LazyEventListener.cpp
@@ -126,7 +126,7 @@ if (!executionContext->isDocument()) return; - if (!toDocument(executionContext)->allowInlineEventHandlers(m_node, this, m_sourceURL, m_position.m_line)) { + if (!toDocument(executionContext)->allowInlineEventHandler(m_node, this, m_sourceURL, m_position.m_line)) { clearListenerObject(); return; }
diff --git a/third_party/WebKit/Source/core/core.gypi b/third_party/WebKit/Source/core/core.gypi index 4bcfb1b..85f5b12 100644 --- a/third_party/WebKit/Source/core/core.gypi +++ b/third_party/WebKit/Source/core/core.gypi
@@ -2694,7 +2694,6 @@ 'dom/shadow/SelectRuleFeatureSet.h', 'dom/shadow/ShadowRoot.cpp', 'dom/shadow/ShadowRoot.h', - 'dom/shadow/ShadowRootRareData.h', 'dom/shadow/ShadowRootRareDataV0.h', 'dom/shadow/SlotAssignment.cpp', 'dom/shadow/SlotAssignment.h',
diff --git a/third_party/WebKit/Source/core/css/resolver/StyleBuilderCustom.cpp b/third_party/WebKit/Source/core/css/resolver/StyleBuilderCustom.cpp index 583dfbe7..07dd462 100644 --- a/third_party/WebKit/Source/core/css/resolver/StyleBuilderCustom.cpp +++ b/third_party/WebKit/Source/core/css/resolver/StyleBuilderCustom.cpp
@@ -674,13 +674,8 @@ ContentData* prevContent = nullptr; for (auto& item : toCSSValueList(*value)) { ContentData* nextContent = nullptr; - // TODO(timloh): This should just call styleImage to handle all the different image types - if (item->isImageGeneratorValue()) { - nextContent = ContentData::create(StyleGeneratedImage::create(toCSSImageGeneratorValue(*item))); - } else if (item->isImageSetValue()) { - nextContent = ContentData::create(state.elementStyleResources().setOrPendingFromValue(CSSPropertyContent, toCSSImageSetValue(*item))); - } else if (item->isImageValue()) { - nextContent = ContentData::create(state.elementStyleResources().cachedOrPendingFromValue(CSSPropertyContent, toCSSImageValue(*item))); + if (item->isImageGeneratorValue() || item->isImageSetValue() || item->isImageValue()) { + nextContent = ContentData::create(state.styleImage(CSSPropertyContent, *item)); } else if (item->isCounterValue()) { CSSCounterValue* counterValue = toCSSCounterValue(item.get()); EListStyleType listStyleType = NoneListStyle;
diff --git a/third_party/WebKit/Source/core/dom/Document.cpp b/third_party/WebKit/Source/core/dom/Document.cpp index 8c475bbf..b4fde8e 100644 --- a/third_party/WebKit/Source/core/dom/Document.cpp +++ b/third_party/WebKit/Source/core/dom/Document.cpp
@@ -3409,11 +3409,11 @@ return true; } -StyleSheetList* Document::styleSheets() +StyleSheetList& Document::styleSheets() { if (!m_styleSheetList) m_styleSheetList = StyleSheetList::create(this); - return m_styleSheetList.get(); + return *m_styleSheetList; } String Document::preferredStylesheetSet() const @@ -5037,10 +5037,9 @@ return getSecurityOrigin()->canAccess(other.get()); } -bool Document::allowInlineEventHandlers(Node* node, EventListener* listener, const String& contextURL, const WTF::OrdinalNumber& contextLine) +bool Document::allowInlineEventHandler(Node* node, EventListener* listener, const String& contextURL, const WTF::OrdinalNumber& contextLine) { - bool allowedByHash = contentSecurityPolicy()->experimentalFeaturesEnabled() && contentSecurityPolicy()->allowScriptWithHash(listener->code()); - if (!ContentSecurityPolicy::shouldBypassMainWorld(this) && !allowedByHash && !contentSecurityPolicy()->allowInlineEventHandlers(contextURL, contextLine)) + if (!ContentSecurityPolicy::shouldBypassMainWorld(this) && !contentSecurityPolicy()->allowInlineEventHandler(listener->code(), contextURL, contextLine)) return false; // HTML says that inline script needs browsing context to create its execution environment. @@ -5052,7 +5051,7 @@ return false; if (!frame->script().canExecuteScripts(NotAboutToExecuteScript)) return false; - if (node && node->document() != this && !node->document().allowInlineEventHandlers(node, listener, contextURL, contextLine)) + if (node && node->document() != this && !node->document().allowInlineEventHandler(node, listener, contextURL, contextLine)) return false; return true;
diff --git a/third_party/WebKit/Source/core/dom/Document.h b/third_party/WebKit/Source/core/dom/Document.h index 4a5afa0..e102c0b0 100644 --- a/third_party/WebKit/Source/core/dom/Document.h +++ b/third_party/WebKit/Source/core/dom/Document.h
@@ -378,7 +378,7 @@ bool isScriptExecutionReady() const { return isRenderingReady(); } // This is a DOM function. - StyleSheetList* styleSheets(); + StyleSheetList& styleSheets(); StyleEngine& styleEngine() { DCHECK(m_styleEngine.get()); return *m_styleEngine.get(); } @@ -862,7 +862,7 @@ bool isSecureTransitionTo(const KURL&) const; - bool allowInlineEventHandlers(Node*, EventListener*, const String& contextURL, const WTF::OrdinalNumber& contextLine); + bool allowInlineEventHandler(Node*, EventListener*, const String& contextURL, const WTF::OrdinalNumber& contextLine); bool allowExecutingScripts(Node*); void enforceSandboxFlags(SandboxFlags mask) override;
diff --git a/third_party/WebKit/Source/core/dom/DocumentOrShadowRoot.h b/third_party/WebKit/Source/core/dom/DocumentOrShadowRoot.h index 1f4a04b..11fbf32 100644 --- a/third_party/WebKit/Source/core/dom/DocumentOrShadowRoot.h +++ b/third_party/WebKit/Source/core/dom/DocumentOrShadowRoot.h
@@ -24,12 +24,12 @@ static StyleSheetList* styleSheets(Document& document) { - return document.styleSheets(); + return &document.styleSheets(); } static StyleSheetList* styleSheets(ShadowRoot& shadowRoot) { - return shadowRoot.styleSheets(); + return &shadowRoot.styleSheets(); } static DOMSelection* getSelection(TreeScope& treeScope)
diff --git a/third_party/WebKit/Source/core/dom/ScriptLoader.cpp b/third_party/WebKit/Source/core/dom/ScriptLoader.cpp index ce1d001..2b19ef878 100644 --- a/third_party/WebKit/Source/core/dom/ScriptLoader.cpp +++ b/third_party/WebKit/Source/core/dom/ScriptLoader.cpp
@@ -375,7 +375,7 @@ const ContentSecurityPolicy* csp = elementDocument->contentSecurityPolicy(); bool shouldBypassMainWorldCSP = (frame && frame->script().shouldBypassMainWorldCSP()) || csp->allowScriptWithNonce(m_element->fastGetAttribute(HTMLNames::nonceAttr)) - || csp->allowScriptWithHash(sourceCode.source().toString()) + || csp->allowScriptWithHash(sourceCode.source().toString(), ContentSecurityPolicy::InlineType::Block) || (!isParserInserted() && csp->allowDynamic()); if (!m_isExternalScript && (!shouldBypassMainWorldCSP && !csp->allowInlineScript(elementDocument->url(), m_startLineNumber, sourceCode.source().toString()))) {
diff --git a/third_party/WebKit/Source/core/dom/SelectorQuery.cpp b/third_party/WebKit/Source/core/dom/SelectorQuery.cpp index 76151d5..5966fc9 100644 --- a/third_party/WebKit/Source/core/dom/SelectorQuery.cpp +++ b/third_party/WebKit/Source/core/dom/SelectorQuery.cpp
@@ -205,10 +205,8 @@ template <typename SelectorQueryTrait> void SelectorDataList::collectElementsByTagName(ContainerNode& rootNode, const QualifiedName& tagName, typename SelectorQueryTrait::OutputType& output) const { + DCHECK_EQ(tagName.namespaceURI(), starAtom); for (Element& element : ElementTraversal::descendantsOf(rootNode)) { - // querySelector*() doesn't allow namespaces and throws before it gets - // here so we can ignore them. - DCHECK_EQ(tagName.namespaceURI(), starAtom); if (matchesTagName(tagName, element)) { SelectorQueryTrait::appendElement(output, element); if (SelectorQueryTrait::shouldOnlyMatchFirstElement) @@ -510,8 +508,15 @@ collectElementsByClassName<SelectorQueryTrait>(rootNode, firstSelector.value(), output); return; case CSSSelector::Tag: - collectElementsByTagName<SelectorQueryTrait>(rootNode, firstSelector.tagQName(), output); - return; + if (firstSelector.tagQName().namespaceURI() == starAtom) { + collectElementsByTagName<SelectorQueryTrait>(rootNode, firstSelector.tagQName(), output); + return; + } + // querySelector*() doesn't allow namespace prefix resolution and + // throws before we get here, but we still may have selectors for + // elements without a namespace. + DCHECK_EQ(firstSelector.tagQName().namespaceURI(), nullAtom); + break; default: break; // If we need another fast path, add here. }
diff --git a/third_party/WebKit/Source/core/dom/StyleElement.cpp b/third_party/WebKit/Source/core/dom/StyleElement.cpp index b10eff3..247c28a97 100644 --- a/third_party/WebKit/Source/core/dom/StyleElement.cpp +++ b/third_party/WebKit/Source/core/dom/StyleElement.cpp
@@ -174,7 +174,7 @@ const ContentSecurityPolicy* csp = document.contentSecurityPolicy(); bool passesContentSecurityPolicyChecks = shouldBypassMainWorldCSP(e) - || csp->allowStyleWithHash(text) + || csp->allowStyleWithHash(text, ContentSecurityPolicy::InlineType::Block) || csp->allowStyleWithNonce(e->fastGetAttribute(HTMLNames::nonceAttr)) || csp->allowInlineStyle(e->document().url(), m_startPosition.m_line, text);
diff --git a/third_party/WebKit/Source/core/dom/shadow/ElementShadow.cpp b/third_party/WebKit/Source/core/dom/shadow/ElementShadow.cpp index 393a0ea..8823456 100644 --- a/third_party/WebKit/Source/core/dom/shadow/ElementShadow.cpp +++ b/third_party/WebKit/Source/core/dom/shadow/ElementShadow.cpp
@@ -234,14 +234,14 @@ if (!root || !otherRoot) return false; - StyleSheetList* list = root->styleSheets(); - StyleSheetList* otherList = otherRoot->styleSheets(); + StyleSheetList& list = root->styleSheets(); + StyleSheetList& otherList = otherRoot->styleSheets(); - if (list->length() != otherList->length()) + if (list.length() != otherList.length()) return false; - for (size_t i = 0; i < list->length(); i++) { - if (toCSSStyleSheet(list->item(i))->contents() != toCSSStyleSheet(otherList->item(i))->contents()) + for (size_t i = 0; i < list.length(); i++) { + if (toCSSStyleSheet(list.item(i))->contents() != toCSSStyleSheet(otherList.item(i))->contents()) return false; } root = root->olderShadowRoot();
diff --git a/third_party/WebKit/Source/core/dom/shadow/ShadowRoot.cpp b/third_party/WebKit/Source/core/dom/shadow/ShadowRoot.cpp index 078e1fa..c7d7c0d 100644 --- a/third_party/WebKit/Source/core/dom/shadow/ShadowRoot.cpp +++ b/third_party/WebKit/Source/core/dom/shadow/ShadowRoot.cpp
@@ -35,10 +35,11 @@ #include "core/dom/Text.h" #include "core/dom/shadow/ElementShadow.h" #include "core/dom/shadow/InsertionPoint.h" -#include "core/dom/shadow/ShadowRootRareData.h" #include "core/dom/shadow/ShadowRootRareDataV0.h" +#include "core/dom/shadow/SlotAssignment.h" #include "core/editing/serializers/Serialization.h" #include "core/html/HTMLShadowElement.h" +#include "core/html/HTMLSlotElement.h" #include "public/platform/Platform.h" namespace blink { @@ -55,6 +56,7 @@ : DocumentFragment(0, CreateShadowRoot) , TreeScope(*this, document) , m_numberOfStyles(0) + , m_childShadowRootCount(0) , m_type(static_cast<unsigned>(type)) , m_registeredWithParentShadowRoot(false) , m_descendantInsertionPointsIsValid(false) @@ -102,6 +104,19 @@ ensureShadowRootRareDataV0().setOlderShadowRoot(root); } +SlotAssignment& ShadowRoot::ensureSlotAssignment() +{ + if (!m_slotAssignment) + m_slotAssignment = SlotAssignment::create(); + return *m_slotAssignment; +} + +HTMLSlotElement* ShadowRoot::assignedSlotFor(const Node& node) const +{ + DCHECK(m_slotAssignment); + return m_slotAssignment->assignedSlotFor(node); +} + Node* ShadowRoot::cloneNode(bool, ExceptionState& exceptionState) { exceptionState.throwDOMException(NotSupportedError, "ShadowRoot nodes are not clonable."); @@ -209,15 +224,6 @@ --m_numberOfStyles; } -ShadowRootRareData& ShadowRoot::ensureShadowRootRareData() -{ - if (m_shadowRootRareData) - return *m_shadowRootRareData; - - m_shadowRootRareData = new ShadowRootRareData; - return *m_shadowRootRareData; -} - ShadowRootRareDataV0& ShadowRoot::ensureShadowRootRareDataV0() { if (m_shadowRootRareDataV0) @@ -237,11 +243,6 @@ return m_shadowRootRareDataV0 ? m_shadowRootRareDataV0->containsContentElements() : false; } -bool ShadowRoot::containsShadowRoots() const -{ - return m_shadowRootRareData ? m_shadowRootRareData->containsShadowRoots() : false; -} - unsigned ShadowRoot::descendantShadowElementCount() const { return m_shadowRootRareDataV0 ? m_shadowRootRareDataV0->descendantShadowElementCount() : 0; @@ -271,24 +272,6 @@ invalidateDescendantInsertionPoints(); } -void ShadowRoot::addChildShadowRoot() -{ - ensureShadowRootRareData().didAddChildShadowRoot(); -} - -void ShadowRoot::removeChildShadowRoot() -{ - // FIXME: Why isn't this an ASSERT? - if (!m_shadowRootRareData) - return; - m_shadowRootRareData->didRemoveChildShadowRoot(); -} - -unsigned ShadowRoot::childShadowRootCount() const -{ - return m_shadowRootRareData ? m_shadowRootRareData->childShadowRootCount() : 0; -} - void ShadowRoot::invalidateDescendantInsertionPoints() { m_descendantInsertionPointsIsValid = false; @@ -315,56 +298,56 @@ return m_shadowRootRareDataV0->descendantInsertionPoints(); } -StyleSheetList* ShadowRoot::styleSheets() +StyleSheetList& ShadowRoot::styleSheets() { - if (!ensureShadowRootRareData().styleSheets()) - m_shadowRootRareData->setStyleSheets(StyleSheetList::create(this)); - - return m_shadowRootRareData->styleSheets(); + if (!m_styleSheetList) + setStyleSheets(StyleSheetList::create(this)); + return *m_styleSheetList; } void ShadowRoot::didAddSlot() { - ensureShadowRootRareData().didAddSlot(); + ensureSlotAssignment().didAddSlot(); invalidateDescendantSlots(); } void ShadowRoot::didRemoveSlot() { - DCHECK(m_shadowRootRareData); - m_shadowRootRareData->didRemoveSlot(); + DCHECK(m_slotAssignment); + m_slotAssignment->didRemoveSlot(); invalidateDescendantSlots(); } void ShadowRoot::invalidateDescendantSlots() { + DCHECK(m_slotAssignment); m_descendantSlotsIsValid = false; - m_shadowRootRareData->clearDescendantSlots(); + m_slotAssignment->clearDescendantSlots(); } unsigned ShadowRoot::descendantSlotCount() const { - return m_shadowRootRareData ? m_shadowRootRareData->descendantSlotCount() : 0; + return m_slotAssignment ? m_slotAssignment->descendantSlotCount() : 0; } const HeapVector<Member<HTMLSlotElement>>& ShadowRoot::descendantSlots() { DEFINE_STATIC_LOCAL(HeapVector<Member<HTMLSlotElement>>, emptyList, (new HeapVector<Member<HTMLSlotElement>>)); if (m_descendantSlotsIsValid) { - DCHECK(m_shadowRootRareData); - return m_shadowRootRareData->descendantSlots(); + DCHECK(m_slotAssignment); + return m_slotAssignment->descendantSlots(); } if (descendantSlotCount() == 0) return emptyList; - DCHECK(m_shadowRootRareData); + DCHECK(m_slotAssignment); HeapVector<Member<HTMLSlotElement>> slots; slots.reserveCapacity(descendantSlotCount()); for (HTMLSlotElement& slot : Traversal<HTMLSlotElement>::descendantsOf(rootNode())) slots.append(&slot); - m_shadowRootRareData->setDescendantSlots(slots); + m_slotAssignment->setDescendantSlots(slots); m_descendantSlotsIsValid = true; - return m_shadowRootRareData->descendantSlots(); + return m_slotAssignment->descendantSlots(); } void ShadowRoot::assignV1() @@ -383,9 +366,9 @@ DEFINE_TRACE(ShadowRoot) { - visitor->trace(m_shadowRootRareData); visitor->trace(m_shadowRootRareDataV0); visitor->trace(m_slotAssignment); + visitor->trace(m_styleSheetList); TreeScope::trace(visitor); DocumentFragment::trace(visitor); }
diff --git a/third_party/WebKit/Source/core/dom/shadow/ShadowRoot.h b/third_party/WebKit/Source/core/dom/shadow/ShadowRoot.h index 8000de5..944a022 100644 --- a/third_party/WebKit/Source/core/dom/shadow/ShadowRoot.h +++ b/third_party/WebKit/Source/core/dom/shadow/ShadowRoot.h
@@ -32,7 +32,6 @@ #include "core/dom/DocumentFragment.h" #include "core/dom/Element.h" #include "core/dom/TreeScope.h" -#include "core/dom/shadow/SlotAssignment.h" namespace blink { @@ -40,9 +39,10 @@ class ElementShadow; class ExceptionState; class HTMLShadowElement; +class HTMLSlotElement; class InsertionPoint; -class ShadowRootRareData; class ShadowRootRareDataV0; +class SlotAssignment; class StyleSheetList; enum class ShadowRootType { @@ -64,60 +64,57 @@ return new ShadowRoot(document, type); } - void recalcStyle(StyleRecalcChange); - // Disambiguate between Node and TreeScope hierarchies; TreeScope's implementation is simpler. using TreeScope::document; using TreeScope::getElementById; + // Make protected methods from base class public here. + using TreeScope::setDocument; + using TreeScope::setParentTreeScope; + // TODO(kochi): crbug.com/507413 In non-Oilpan, host() may return null during queued // event handling (e.g. during execCommand()). Element* host() const { return toElement(parentOrShadowHostNode()); } ElementShadow* owner() const { return host() ? host()->shadow() : 0; } - - ShadowRoot* youngerShadowRoot() const; - ShadowRoot* olderShadowRoot() const; - ShadowRoot* olderShadowRootForBindings() const; - - void setYoungerShadowRoot(ShadowRoot&); - void setOlderShadowRoot(ShadowRoot&); - + ShadowRootType type() const { return static_cast<ShadowRootType>(m_type); } String mode() const { return (type() == ShadowRootType::V0 || type() == ShadowRootType::Open) ? "open" : "closed"; }; bool isOpenOrV0() const { return type() == ShadowRootType::V0 || type() == ShadowRootType::Open; } - bool isV1() const { return type() == ShadowRootType::Open || type() == ShadowRootType::Closed; } - bool isYoungest() const { return !youngerShadowRoot(); } - bool isOldest() const { return !olderShadowRoot(); } - void attach(const AttachContext& = AttachContext()) override; InsertionNotificationRequest insertedInto(ContainerNode*) override; void removedFrom(ContainerNode*) override; - void registerScopedHTMLStyleChild(); - void unregisterScopedHTMLStyleChild(); - + // For V0 + ShadowRoot* youngerShadowRoot() const; + ShadowRoot* olderShadowRoot() const; + ShadowRoot* olderShadowRootForBindings() const; + void setYoungerShadowRoot(ShadowRoot&); + void setOlderShadowRoot(ShadowRoot&); + bool isYoungest() const { return !youngerShadowRoot(); } + bool isOldest() const { return !olderShadowRoot(); } bool containsShadowElements() const; bool containsContentElements() const; bool containsInsertionPoints() const { return containsShadowElements() || containsContentElements(); } - bool containsShadowRoots() const; - unsigned descendantShadowElementCount() const; - - // For Internals, don't use this. - unsigned childShadowRootCount() const; - unsigned numberOfStyles() const { return m_numberOfStyles; } - HTMLShadowElement* shadowInsertionPointOfYoungerShadowRoot() const; void setShadowInsertionPointOfYoungerShadowRoot(HTMLShadowElement*); - void didAddInsertionPoint(InsertionPoint*); void didRemoveInsertionPoint(InsertionPoint*); const HeapVector<Member<InsertionPoint>>& descendantInsertionPoints(); - ShadowRootType type() const { return static_cast<ShadowRootType>(m_type); } + // For Internals, don't use this. + unsigned childShadowRootCount() const { return m_childShadowRootCount; } + unsigned numberOfStyles() const { return m_numberOfStyles; } + + void recalcStyle(StyleRecalcChange); + + void registerScopedHTMLStyleChild(); + void unregisterScopedHTMLStyleChild(); + + SlotAssignment& ensureSlotAssignment(); void didAddSlot(); void didRemoveSlot(); @@ -126,15 +123,7 @@ void assignV1(); void distributeV1(); - HTMLSlotElement* assignedSlotFor(const Node& node) const - { - DCHECK(m_slotAssignment); - return m_slotAssignment->assignedSlotFor(node); - } - - // Make protected methods from base class public here. - using TreeScope::setDocument; - using TreeScope::setParentTreeScope; + HTMLSlotElement* assignedSlotFor(const Node&) const; Element* activeElement() const; @@ -143,11 +132,14 @@ Node* cloneNode(bool, ExceptionState&); - StyleSheetList* styleSheets(); - void setDelegatesFocus(bool flag) { m_delegatesFocus = flag; } bool delegatesFocus() const { return m_delegatesFocus; } + bool containsShadowRoots() const { return m_childShadowRootCount; } + + StyleSheetList& styleSheets(); + void setStyleSheets(StyleSheetList* styleSheetList) { m_styleSheetList = styleSheetList; } + DECLARE_VIRTUAL_TRACE(); private: @@ -156,11 +148,10 @@ void childrenChanged(const ChildrenChange&) override; - ShadowRootRareData& ensureShadowRootRareData(); ShadowRootRareDataV0& ensureShadowRootRareDataV0(); - void addChildShadowRoot(); - void removeChildShadowRoot(); + void addChildShadowRoot() { ++m_childShadowRootCount; } + void removeChildShadowRoot() { DCHECK_GT(m_childShadowRootCount, 0u); --m_childShadowRootCount; } void invalidateDescendantInsertionPoints(); // ShadowRoots should never be cloned. @@ -172,10 +163,11 @@ void invalidateDescendantSlots(); unsigned descendantSlotCount() const; - Member<ShadowRootRareData> m_shadowRootRareData; Member<ShadowRootRareDataV0> m_shadowRootRareDataV0; + Member<StyleSheetList> m_styleSheetList; Member<SlotAssignment> m_slotAssignment; - unsigned m_numberOfStyles : 26; + unsigned m_numberOfStyles : 13; + unsigned m_childShadowRootCount : 13; unsigned m_type : 2; unsigned m_registeredWithParentShadowRoot : 1; unsigned m_descendantInsertionPointsIsValid : 1;
diff --git a/third_party/WebKit/Source/core/dom/shadow/ShadowRootRareData.h b/third_party/WebKit/Source/core/dom/shadow/ShadowRootRareData.h deleted file mode 100644 index 9c5d91b..0000000 --- a/third_party/WebKit/Source/core/dom/shadow/ShadowRootRareData.h +++ /dev/null
@@ -1,83 +0,0 @@ -/* - * Copyright (C) 2013 Google Inc. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are - * met: - * - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above - * copyright notice, this list of conditions and the following disclaimer - * in the documentation and/or other materials provided with the - * distribution. - * * Neither the name of Google Inc. nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#ifndef ShadowRootRareData_h -#define ShadowRootRareData_h - -#include "core/dom/shadow/InsertionPoint.h" -#include "core/html/HTMLSlotElement.h" -#include "wtf/Vector.h" - -namespace blink { - -class ShadowRootRareData : public GarbageCollected<ShadowRootRareData> { -public: - ShadowRootRareData() - : m_childShadowRootCount(0) - , m_descendantSlotCount(0) - { - } - - bool containsShadowRoots() const { return m_childShadowRootCount; } - - void didAddChildShadowRoot() { ++m_childShadowRootCount; } - void didRemoveChildShadowRoot() { DCHECK_GT(m_childShadowRootCount, 0u); --m_childShadowRootCount; } - - unsigned childShadowRootCount() const { return m_childShadowRootCount; } - - StyleSheetList* styleSheets() { return m_styleSheetList.get(); } - void setStyleSheets(StyleSheetList* styleSheetList) { m_styleSheetList = styleSheetList; } - - void didAddSlot() { ++m_descendantSlotCount; } - void didRemoveSlot() { DCHECK_GT(m_descendantSlotCount, 0u); --m_descendantSlotCount; } - - unsigned descendantSlotCount() const { return m_descendantSlotCount; } - - const HeapVector<Member<HTMLSlotElement>>& descendantSlots() const { return m_descendantSlots; } - - void setDescendantSlots(HeapVector<Member<HTMLSlotElement>>& slots) { m_descendantSlots.swap(slots); } - void clearDescendantSlots() { m_descendantSlots.clear(); } - - DEFINE_INLINE_TRACE() - { - visitor->trace(m_styleSheetList); - visitor->trace(m_descendantSlots); - } - -private: - unsigned m_childShadowRootCount; - Member<StyleSheetList> m_styleSheetList; - unsigned m_descendantSlotCount; - HeapVector<Member<HTMLSlotElement>> m_descendantSlots; -}; - -} // namespace blink - -#endif
diff --git a/third_party/WebKit/Source/core/dom/shadow/SlotAssignment.cpp b/third_party/WebKit/Source/core/dom/shadow/SlotAssignment.cpp index 44274a2..a13e9fb 100644 --- a/third_party/WebKit/Source/core/dom/shadow/SlotAssignment.cpp +++ b/third_party/WebKit/Source/core/dom/shadow/SlotAssignment.cpp
@@ -107,6 +107,7 @@ DEFINE_TRACE(SlotAssignment) { + visitor->trace(m_descendantSlots); visitor->trace(m_assignment); }
diff --git a/third_party/WebKit/Source/core/dom/shadow/SlotAssignment.h b/third_party/WebKit/Source/core/dom/shadow/SlotAssignment.h index 4ed964673..50c5b48 100644 --- a/third_party/WebKit/Source/core/dom/shadow/SlotAssignment.h +++ b/third_party/WebKit/Source/core/dom/shadow/SlotAssignment.h
@@ -24,13 +24,25 @@ void resolveAssignment(ShadowRoot&); void resolveDistribution(ShadowRoot&); + void didAddSlot() { ++m_descendantSlotCount; } + void didRemoveSlot() { DCHECK_GT(m_descendantSlotCount, 0u); --m_descendantSlotCount; } + unsigned descendantSlotCount() const { return m_descendantSlotCount; } + + const HeapVector<Member<HTMLSlotElement>>& descendantSlots() const { return m_descendantSlots; } + + void setDescendantSlots(HeapVector<Member<HTMLSlotElement>>& slots) { m_descendantSlots.swap(slots); } + void clearDescendantSlots() { m_descendantSlots.clear(); } + DECLARE_TRACE(); private: - SlotAssignment() { } + SlotAssignment() { }; void assign(Node&, HTMLSlotElement&); void distribute(Node&, HTMLSlotElement&); + + unsigned m_descendantSlotCount = 0; + HeapVector<Member<HTMLSlotElement>> m_descendantSlots; HeapHashMap<Member<Node>, Member<HTMLSlotElement>> m_assignment; };
diff --git a/third_party/WebKit/Source/core/editing/VisibleUnits.cpp b/third_party/WebKit/Source/core/editing/VisibleUnits.cpp index 9adde60..239873a 100644 --- a/third_party/WebKit/Source/core/editing/VisibleUnits.cpp +++ b/third_party/WebKit/Source/core/editing/VisibleUnits.cpp
@@ -671,23 +671,20 @@ const PositionTemplate<Strategy> end = pos.parentAnchoredEquivalent(); ForwardsTextBuffer suffixString; - unsigned suffixLength = 0; - if (requiresContextForWordBoundary(characterBefore(c))) { TextIteratorAlgorithm<Strategy> forwardsIterator(end, PositionTemplate<Strategy>::afterNode(boundary)); while (!forwardsIterator.atEnd()) { - // TODO(xiaochengh): Eliminate this intermediate buffer. - ForwardsTextBuffer characters; - forwardsIterator.copyTextTo(&characters); - int i = endOfFirstWordBoundaryContext(characters.data(), characters.size()); - suffixString.pushRange(characters.data(), i); - suffixLength += i; - if (static_cast<unsigned>(i) < characters.size()) + forwardsIterator.copyTextTo(&suffixString); + int contextEndIndex = endOfFirstWordBoundaryContext(suffixString.data() + suffixString.size() - forwardsIterator.length(), forwardsIterator.length()); + if (contextEndIndex < forwardsIterator.length()) { + suffixString.shrink(forwardsIterator.length() - contextEndIndex); break; + } forwardsIterator.advance(); } } + unsigned suffixLength = suffixString.size(); BackwardsTextBuffer string; string.pushRange(suffixString.data(), suffixString.size()); @@ -759,24 +756,20 @@ const PositionTemplate<Strategy> start(pos.parentAnchoredEquivalent()); BackwardsTextBuffer prefixString; - unsigned prefixLength = 0; - if (requiresContextForWordBoundary(characterAfter(c))) { SimplifiedBackwardsTextIteratorAlgorithm<Strategy> backwardsIterator(PositionTemplate<Strategy>::firstPositionInNode(&d), start); while (!backwardsIterator.atEnd()) { - // TODO(xiaochengh): Eliminate this intermediate buffer. - BackwardsTextBuffer characters; - backwardsIterator.copyTextTo(&characters); - int length = characters.size(); - int i = startOfLastWordBoundaryContext(characters.data(), length); - prefixString.pushRange(characters.data() + i, length - i); - prefixLength += length - i; - if (i > 0) + backwardsIterator.copyTextTo(&prefixString); + int contextStartIndex = startOfLastWordBoundaryContext(prefixString.data(), backwardsIterator.length()); + if (contextStartIndex > 0) { + prefixString.shrink(contextStartIndex); break; + } backwardsIterator.advance(); } } + unsigned prefixLength = prefixString.size(); ForwardsTextBuffer string; string.pushRange(prefixString.data(), prefixString.size());
diff --git a/third_party/WebKit/Source/core/editing/iterators/TextBufferBase.h b/third_party/WebKit/Source/core/editing/iterators/TextBufferBase.h index 95a0624..b7a5b839 100644 --- a/third_party/WebKit/Source/core/editing/iterators/TextBufferBase.h +++ b/third_party/WebKit/Source/core/editing/iterators/TextBufferBase.h
@@ -32,6 +32,8 @@ std::copy(other, other + length, ensureDestination(length)); } + void shrink(size_t delta) { DCHECK_LE(delta, m_size); m_size -= delta; } + protected: TextBufferBase(); UChar* ensureDestination(size_t length);
diff --git a/third_party/WebKit/Source/core/events/CompositionEvent.cpp b/third_party/WebKit/Source/core/events/CompositionEvent.cpp index 9544626..d5ca38b 100644 --- a/third_party/WebKit/Source/core/events/CompositionEvent.cpp +++ b/third_party/WebKit/Source/core/events/CompositionEvent.cpp
@@ -51,7 +51,7 @@ void CompositionEvent::initCompositionEvent(const AtomicString& type, bool canBubble, bool cancelable, AbstractView* view, const String& data) { - if (dispatched()) + if (isBeingDispatched()) return; initUIEvent(type, canBubble, cancelable, view, 0);
diff --git a/third_party/WebKit/Source/core/events/CustomEvent.cpp b/third_party/WebKit/Source/core/events/CustomEvent.cpp index 4c66fd2..ed23900 100644 --- a/third_party/WebKit/Source/core/events/CustomEvent.cpp +++ b/third_party/WebKit/Source/core/events/CustomEvent.cpp
@@ -50,7 +50,7 @@ void CustomEvent::initCustomEvent(const AtomicString& type, bool canBubble, bool cancelable, PassRefPtr<SerializedScriptValue> serializedDetail) { - if (dispatched()) + if (isBeingDispatched()) return; initEvent(type, canBubble, cancelable);
diff --git a/third_party/WebKit/Source/core/events/Event.cpp b/third_party/WebKit/Source/core/events/Event.cpp index fcbe35e..0971daa 100644 --- a/third_party/WebKit/Source/core/events/Event.cpp +++ b/third_party/WebKit/Source/core/events/Event.cpp
@@ -114,7 +114,7 @@ void Event::initEvent(const AtomicString& eventTypeArg, bool canBubbleArg, bool cancelableArg, EventTarget* relatedTarget) { - if (dispatched()) + if (isBeingDispatched()) return; m_propagationStopped = false;
diff --git a/third_party/WebKit/Source/core/events/Event.h b/third_party/WebKit/Source/core/events/Event.h index 505c055..4d436246 100644 --- a/third_party/WebKit/Source/core/events/Event.h +++ b/third_party/WebKit/Source/core/events/Event.h
@@ -216,7 +216,6 @@ Event(const AtomicString& type, const EventInit&); virtual void receivedTarget(); - bool dispatched() const { return m_target; } void setCanBubble(bool bubble) { m_canBubble = bubble; }
diff --git a/third_party/WebKit/Source/core/events/KeyboardEvent.cpp b/third_party/WebKit/Source/core/events/KeyboardEvent.cpp index 185341f..146800f 100644 --- a/third_party/WebKit/Source/core/events/KeyboardEvent.cpp +++ b/third_party/WebKit/Source/core/events/KeyboardEvent.cpp
@@ -113,7 +113,7 @@ void KeyboardEvent::initKeyboardEvent(ScriptState* scriptState, const AtomicString& type, bool canBubble, bool cancelable, AbstractView* view, const String& keyIdentifier, unsigned location, bool ctrlKey, bool altKey, bool shiftKey, bool metaKey) { - if (dispatched()) + if (isBeingDispatched()) return; if (scriptState->world().isIsolatedWorld())
diff --git a/third_party/WebKit/Source/core/events/MessageEvent.cpp b/third_party/WebKit/Source/core/events/MessageEvent.cpp index 6c676b67..33bb457 100644 --- a/third_party/WebKit/Source/core/events/MessageEvent.cpp +++ b/third_party/WebKit/Source/core/events/MessageEvent.cpp
@@ -140,7 +140,7 @@ void MessageEvent::initMessageEvent(const AtomicString& type, bool canBubble, bool cancelable, ScriptValue data, const String& origin, const String& lastEventId, DOMWindow* source, MessagePortArray* ports) { - if (dispatched()) + if (isBeingDispatched()) return; initEvent(type, canBubble, cancelable); @@ -156,7 +156,7 @@ void MessageEvent::initMessageEvent(const AtomicString& type, bool canBubble, bool cancelable, PassRefPtr<SerializedScriptValue> data, const String& origin, const String& lastEventId, DOMWindow* source, MessagePortArray* ports) { - if (dispatched()) + if (isBeingDispatched()) return; initEvent(type, canBubble, cancelable);
diff --git a/third_party/WebKit/Source/core/events/MouseEvent.cpp b/third_party/WebKit/Source/core/events/MouseEvent.cpp index f4dfdc6..ecd784f3 100644 --- a/third_party/WebKit/Source/core/events/MouseEvent.cpp +++ b/third_party/WebKit/Source/core/events/MouseEvent.cpp
@@ -181,7 +181,7 @@ bool ctrlKey, bool altKey, bool shiftKey, bool metaKey, short button, EventTarget* relatedTarget, unsigned short buttons) { - if (dispatched()) + if (isBeingDispatched()) return; if (scriptState && scriptState->world().isIsolatedWorld())
diff --git a/third_party/WebKit/Source/core/events/MutationEvent.cpp b/third_party/WebKit/Source/core/events/MutationEvent.cpp index 1a9b917..065e9c0 100644 --- a/third_party/WebKit/Source/core/events/MutationEvent.cpp +++ b/third_party/WebKit/Source/core/events/MutationEvent.cpp
@@ -49,7 +49,7 @@ const String& prevValue, const String& newValue, const String& attrName, unsigned short attrChange) { - if (dispatched()) + if (isBeingDispatched()) return; initEvent(type, canBubble, cancelable);
diff --git a/third_party/WebKit/Source/core/events/TextEvent.cpp b/third_party/WebKit/Source/core/events/TextEvent.cpp index 0cca759d..65ff7dc 100644 --- a/third_party/WebKit/Source/core/events/TextEvent.cpp +++ b/third_party/WebKit/Source/core/events/TextEvent.cpp
@@ -89,7 +89,7 @@ void TextEvent::initTextEvent(const AtomicString& type, bool canBubble, bool cancelable, AbstractView* view, const String& data) { - if (dispatched()) + if (isBeingDispatched()) return; initUIEvent(type, canBubble, cancelable, view, 0);
diff --git a/third_party/WebKit/Source/core/events/TouchEvent.cpp b/third_party/WebKit/Source/core/events/TouchEvent.cpp index 085c275c..721ec81 100644 --- a/third_party/WebKit/Source/core/events/TouchEvent.cpp +++ b/third_party/WebKit/Source/core/events/TouchEvent.cpp
@@ -68,7 +68,7 @@ int, int, int, int, bool ctrlKey, bool altKey, bool shiftKey, bool metaKey) { - if (dispatched()) + if (isBeingDispatched()) return; if (scriptState->world().isIsolatedWorld())
diff --git a/third_party/WebKit/Source/core/events/UIEvent.cpp b/third_party/WebKit/Source/core/events/UIEvent.cpp index 5194710..317cf06 100644 --- a/third_party/WebKit/Source/core/events/UIEvent.cpp +++ b/third_party/WebKit/Source/core/events/UIEvent.cpp
@@ -83,7 +83,7 @@ void UIEvent::initUIEventInternal(const AtomicString& typeArg, bool canBubbleArg, bool cancelableArg, EventTarget* relatedTarget, AbstractView* viewArg, int detailArg, InputDeviceCapabilities* sourceCapabilitiesArg) { - if (dispatched()) + if (isBeingDispatched()) return; initEvent(typeArg, canBubbleArg, cancelableArg, relatedTarget);
diff --git a/third_party/WebKit/Source/core/frame/csp/CSPDirectiveList.cpp b/third_party/WebKit/Source/core/frame/csp/CSPDirectiveList.cpp index 8f74b66..fe57589 100644 --- a/third_party/WebKit/Source/core/frame/csp/CSPDirectiveList.cpp +++ b/third_party/WebKit/Source/core/frame/csp/CSPDirectiveList.cpp
@@ -130,6 +130,11 @@ return !directive || directive->allowHash(hashValue); } +bool CSPDirectiveList::checkHashedAttributes(SourceListDirective* directive) const +{ + return !directive || directive->allowHashedAttributes(); +} + bool CSPDirectiveList::checkDynamic(SourceListDirective* directive) const { return !directive || directive->allowDynamic(); @@ -423,13 +428,21 @@ return checkNonce(operativeDirective(m_styleSrc.get()), nonce); } -bool CSPDirectiveList::allowScriptHash(const CSPHashValue& hashValue) const +bool CSPDirectiveList::allowScriptHash(const CSPHashValue& hashValue, ContentSecurityPolicy::InlineType type) const { + if (type == ContentSecurityPolicy::InlineType::Attribute) { + if (!m_policy->experimentalFeaturesEnabled()) + return false; + if (!checkHashedAttributes(operativeDirective(m_scriptSrc.get()))) + return false; + } return checkHash(operativeDirective(m_scriptSrc.get()), hashValue); } -bool CSPDirectiveList::allowStyleHash(const CSPHashValue& hashValue) const +bool CSPDirectiveList::allowStyleHash(const CSPHashValue& hashValue, ContentSecurityPolicy::InlineType type) const { + if (type != ContentSecurityPolicy::InlineType::Block) + return false; return checkHash(operativeDirective(m_styleSrc.get()), hashValue); }
diff --git a/third_party/WebKit/Source/core/frame/csp/CSPDirectiveList.h b/third_party/WebKit/Source/core/frame/csp/CSPDirectiveList.h index 066c622..0f1ded5 100644 --- a/third_party/WebKit/Source/core/frame/csp/CSPDirectiveList.h +++ b/third_party/WebKit/Source/core/frame/csp/CSPDirectiveList.h
@@ -61,8 +61,8 @@ bool allowAncestors(LocalFrame*, const KURL&, ContentSecurityPolicy::ReportingStatus) const; bool allowScriptNonce(const String&) const; bool allowStyleNonce(const String&) const; - bool allowScriptHash(const CSPHashValue&) const; - bool allowStyleHash(const CSPHashValue&) const; + bool allowScriptHash(const CSPHashValue&, ContentSecurityPolicy::InlineType) const; + bool allowStyleHash(const CSPHashValue&, ContentSecurityPolicy::InlineType) const; bool allowDynamic() const; const String& evalDisabledErrorMessage() const { return m_evalDisabledErrorMessage; } @@ -111,6 +111,7 @@ bool checkDynamic(SourceListDirective*) const; bool checkNonce(SourceListDirective*, const String&) const; bool checkHash(SourceListDirective*, const CSPHashValue&) const; + bool checkHashedAttributes(SourceListDirective*) const; bool checkSource(SourceListDirective*, const KURL&, ContentSecurityPolicy::RedirectStatus) const; bool checkMediaType(MediaListDirective*, const String& type, const String& typeAttribute) const; bool checkAncestors(SourceListDirective*, LocalFrame*) const;
diff --git a/third_party/WebKit/Source/core/frame/csp/CSPSourceList.cpp b/third_party/WebKit/Source/core/frame/csp/CSPSourceList.cpp index 42d4c08..f9915535 100644 --- a/third_party/WebKit/Source/core/frame/csp/CSPSourceList.cpp +++ b/third_party/WebKit/Source/core/frame/csp/CSPSourceList.cpp
@@ -39,6 +39,7 @@ , m_allowInline(false) , m_allowEval(false) , m_allowDynamic(false) + , m_allowHashedAttributes(false) , m_hashAlgorithmsUsed(0) { } @@ -89,6 +90,11 @@ return m_hashes.contains(hashValue); } +bool CSPSourceList::allowHashedAttributes() const +{ + return m_allowHashedAttributes; +} + uint8_t CSPSourceList::hashAlgorithmsUsed() const { return m_hashAlgorithmsUsed; @@ -175,6 +181,11 @@ return true; } + if (equalIgnoringCase("'unsafe-hashed-attributes'", begin, end - begin)) { + addSourceUnsafeHashedAttributes(); + return true; + } + String nonce; if (!parseNonce(begin, end, nonce)) return false; @@ -497,6 +508,11 @@ m_allowDynamic = true; } +void CSPSourceList::addSourceUnsafeHashedAttributes() +{ + m_allowHashedAttributes = true; +} + void CSPSourceList::addSourceNonce(const String& nonce) { m_nonces.add(nonce);
diff --git a/third_party/WebKit/Source/core/frame/csp/CSPSourceList.h b/third_party/WebKit/Source/core/frame/csp/CSPSourceList.h index 4850102..9dd3117 100644 --- a/third_party/WebKit/Source/core/frame/csp/CSPSourceList.h +++ b/third_party/WebKit/Source/core/frame/csp/CSPSourceList.h
@@ -33,6 +33,7 @@ bool allowDynamic() const; bool allowNonce(const String&) const; bool allowHash(const CSPHashValue&) const; + bool allowHashedAttributes() const; uint8_t hashAlgorithmsUsed() const; bool isHashOrNoncePresent() const; @@ -51,6 +52,7 @@ void addSourceUnsafeInline(); void addSourceUnsafeEval(); void addSourceUnsafeDynamic(); + void addSourceUnsafeHashedAttributes(); void addSourceNonce(const String& nonce); void addSourceHash(const ContentSecurityPolicyHashAlgorithm&, const DigestValue& hash); @@ -64,6 +66,7 @@ bool m_allowInline; bool m_allowEval; bool m_allowDynamic; + bool m_allowHashedAttributes; HashSet<String> m_nonces; HashSet<CSPHashValue> m_hashes; uint8_t m_hashAlgorithmsUsed;
diff --git a/third_party/WebKit/Source/core/frame/csp/CSPSourceListTest.cpp b/third_party/WebKit/Source/core/frame/csp/CSPSourceListTest.cpp index 91405a7..df588a0 100644 --- a/third_party/WebKit/Source/core/frame/csp/CSPSourceListTest.cpp +++ b/third_party/WebKit/Source/core/frame/csp/CSPSourceListTest.cpp
@@ -62,6 +62,16 @@ EXPECT_TRUE(sourceList.allowDynamic()); } +TEST_F(CSPSourceListTest, BasicMatchingUnsafeHashedAttributes) +{ + String sources = "'unsafe-hashed-attributes'"; + CSPSourceList sourceList(csp.get(), "script-src"); + parseSourceList(sourceList, sources); + + EXPECT_TRUE(sourceList.allowHashedAttributes()); +} + + TEST_F(CSPSourceListTest, BasicMatchingStar) { KURL base;
diff --git a/third_party/WebKit/Source/core/frame/csp/ContentSecurityPolicy.cpp b/third_party/WebKit/Source/core/frame/csp/ContentSecurityPolicy.cpp index f3d35c4..950512fc 100644 --- a/third_party/WebKit/Source/core/frame/csp/ContentSecurityPolicy.cpp +++ b/third_party/WebKit/Source/core/frame/csp/ContentSecurityPolicy.cpp
@@ -372,11 +372,11 @@ return true; } -template<bool (CSPDirectiveList::*allowed)(const CSPHashValue&) const> -bool isAllowedByAllWithHash(const CSPDirectiveListVector& policies, const CSPHashValue& hashValue) +template<bool (CSPDirectiveList::*allowed)(const CSPHashValue&, ContentSecurityPolicy::InlineType) const> +bool isAllowedByAllWithHash(const CSPDirectiveListVector& policies, const CSPHashValue& hashValue, ContentSecurityPolicy::InlineType type) { for (const auto& policy : policies) { - if (!(policy.get()->*allowed)(hashValue)) + if (!(policy.get()->*allowed)(hashValue, type)) return false; } return true; @@ -405,8 +405,8 @@ return true; } -template<bool (CSPDirectiveList::*allowed)(const CSPHashValue&) const> -bool checkDigest(const String& source, uint8_t hashAlgorithmsUsed, const CSPDirectiveListVector& policies) +template<bool (CSPDirectiveList::*allowed)(const CSPHashValue&, ContentSecurityPolicy::InlineType) const> +bool checkDigest(const String& source, ContentSecurityPolicy::InlineType type, uint8_t hashAlgorithmsUsed, const CSPDirectiveListVector& policies) { // Any additions or subtractions from this struct should also modify the // respective entries in the kSupportedPrefixes array in @@ -431,7 +431,7 @@ DigestValue digest; if (algorithmMap.cspHashAlgorithm & hashAlgorithmsUsed) { bool digestSuccess = computeDigest(algorithmMap.algorithm, utf8Source.data(), utf8Source.length(), digest); - if (digestSuccess && isAllowedByAllWithHash<allowed>(policies, CSPHashValue(algorithmMap.cspHashAlgorithm, digest))) + if (digestSuccess && isAllowedByAllWithHash<allowed>(policies, CSPHashValue(algorithmMap.cspHashAlgorithm, digest), type)) return true; } } @@ -444,8 +444,12 @@ return isAllowedByAllWithContext<&CSPDirectiveList::allowJavaScriptURLs>(m_policies, contextURL, contextLine, reportingStatus); } -bool ContentSecurityPolicy::allowInlineEventHandlers(const String& contextURL, const WTF::OrdinalNumber& contextLine, ContentSecurityPolicy::ReportingStatus reportingStatus) const +bool ContentSecurityPolicy::allowInlineEventHandler(const String& source, const String& contextURL, const WTF::OrdinalNumber& contextLine, ContentSecurityPolicy::ReportingStatus reportingStatus) const { + // Inline event handlers may be whitelisted by hash, if 'unsafe-hash-attributes' is present in a policy. Check + // against the digest of the |source| first before proceeding on to checking whether inline script is allowed. + if (checkDigest<&CSPDirectiveList::allowScriptHash>(source, InlineType::Attribute, m_scriptHashAlgorithmsUsed, m_policies)) + return true; return isAllowedByAllWithContext<&CSPDirectiveList::allowInlineEventHandlers>(m_policies, contextURL, contextLine, reportingStatus); } @@ -528,14 +532,14 @@ return isAllowedByAllWithNonce<&CSPDirectiveList::allowStyleNonce>(m_policies, nonce); } -bool ContentSecurityPolicy::allowScriptWithHash(const String& source) const +bool ContentSecurityPolicy::allowScriptWithHash(const String& source, InlineType type) const { - return checkDigest<&CSPDirectiveList::allowScriptHash>(source, m_scriptHashAlgorithmsUsed, m_policies); + return checkDigest<&CSPDirectiveList::allowScriptHash>(source, type, m_scriptHashAlgorithmsUsed, m_policies); } -bool ContentSecurityPolicy::allowStyleWithHash(const String& source) const +bool ContentSecurityPolicy::allowStyleWithHash(const String& source, InlineType type) const { - return checkDigest<&CSPDirectiveList::allowStyleHash>(source, m_styleHashAlgorithmsUsed, m_policies); + return checkDigest<&CSPDirectiveList::allowStyleHash>(source, type, m_styleHashAlgorithmsUsed, m_policies); } bool ContentSecurityPolicy::allowRequest(WebURLRequest::RequestContext context, const KURL& url, RedirectStatus redirectStatus, ReportingStatus reportingStatus) const
diff --git a/third_party/WebKit/Source/core/frame/csp/ContentSecurityPolicy.h b/third_party/WebKit/Source/core/frame/csp/ContentSecurityPolicy.h index 2e410f6..f9e2466 100644 --- a/third_party/WebKit/Source/core/frame/csp/ContentSecurityPolicy.h +++ b/third_party/WebKit/Source/core/frame/csp/ContentSecurityPolicy.h
@@ -129,6 +129,11 @@ URLViolation }; + enum class InlineType { + Block, + Attribute + }; + static ContentSecurityPolicy* create() { return new ContentSecurityPolicy(); @@ -146,7 +151,7 @@ PassOwnPtr<Vector<CSPHeaderAndType>> headers() const; bool allowJavaScriptURLs(const String& contextURL, const WTF::OrdinalNumber& contextLine, ReportingStatus = SendReport) const; - bool allowInlineEventHandlers(const String& contextURL, const WTF::OrdinalNumber& contextLine, ReportingStatus = SendReport) const; + bool allowInlineEventHandler(const String& source, const String& contextURL, const WTF::OrdinalNumber& contextLine, ReportingStatus = SendReport) const; bool allowInlineScript(const String& contextURL, const WTF::OrdinalNumber& contextLine, const String& scriptContent, ReportingStatus = SendReport) const; bool allowInlineStyle(const String& contextURL, const WTF::OrdinalNumber& contextLine, const String& styleContent, ReportingStatus = SendReport) const; // When the reporting status is |SendReport|, the |ExceptionStatus| @@ -193,8 +198,8 @@ // issue a load and be safe disabling any further CSP checks. bool allowScriptWithNonce(const String& nonce) const; bool allowStyleWithNonce(const String& nonce) const; - bool allowScriptWithHash(const String& source) const; - bool allowStyleWithHash(const String& source) const; + bool allowScriptWithHash(const String& source, InlineType) const; + bool allowStyleWithHash(const String& source, InlineType) const; bool allowRequest(WebURLRequest::RequestContext, const KURL&, RedirectStatus = DidNotRedirect, ReportingStatus = SendReport) const;
diff --git a/third_party/WebKit/Source/core/frame/csp/SourceListDirective.cpp b/third_party/WebKit/Source/core/frame/csp/SourceListDirective.cpp index b1d3412..78b3323 100644 --- a/third_party/WebKit/Source/core/frame/csp/SourceListDirective.cpp +++ b/third_party/WebKit/Source/core/frame/csp/SourceListDirective.cpp
@@ -52,6 +52,11 @@ return m_sourceList.allowHash(hashValue); } +bool SourceListDirective::allowHashedAttributes() const +{ + return m_sourceList.allowHashedAttributes(); +} + bool SourceListDirective::isHashOrNoncePresent() const { return m_sourceList.isHashOrNoncePresent();
diff --git a/third_party/WebKit/Source/core/frame/csp/SourceListDirective.h b/third_party/WebKit/Source/core/frame/csp/SourceListDirective.h index 97adb21..d00ee36 100644 --- a/third_party/WebKit/Source/core/frame/csp/SourceListDirective.h +++ b/third_party/WebKit/Source/core/frame/csp/SourceListDirective.h
@@ -29,6 +29,7 @@ bool allowDynamic() const; bool allowNonce(const String& nonce) const; bool allowHash(const CSPHashValue&) const; + bool allowHashedAttributes() const; bool isHashOrNoncePresent() const; uint8_t hashAlgorithmsUsed() const;
diff --git a/third_party/WebKit/Source/core/html/canvas/CanvasRenderingContext.cpp b/third_party/WebKit/Source/core/html/canvas/CanvasRenderingContext.cpp index 9d89f0c9..17c1e81 100644 --- a/third_party/WebKit/Source/core/html/canvas/CanvasRenderingContext.cpp +++ b/third_party/WebKit/Source/core/html/canvas/CanvasRenderingContext.cpp
@@ -31,13 +31,9 @@ namespace blink { -CanvasRenderingContext::CanvasRenderingContext(HTMLCanvasElement* canvas) +CanvasRenderingContext::CanvasRenderingContext(HTMLCanvasElement* canvas, OffscreenCanvas* offscreenCanvas) : m_canvas(canvas) -{ -} - -CanvasRenderingContext::CanvasRenderingContext(OffscreenCanvas* canvas) - : m_offscreenCanvas(canvas) + , m_offscreenCanvas(offscreenCanvas) { }
diff --git a/third_party/WebKit/Source/core/html/canvas/CanvasRenderingContext.h b/third_party/WebKit/Source/core/html/canvas/CanvasRenderingContext.h index 88d3e53..315aebe 100644 --- a/third_party/WebKit/Source/core/html/canvas/CanvasRenderingContext.h +++ b/third_party/WebKit/Source/core/html/canvas/CanvasRenderingContext.h
@@ -73,7 +73,8 @@ virtual bool hasAlpha() const { return true; } virtual void setIsHidden(bool) = 0; virtual bool isContextLost() const { return true; } - virtual void setCanvasGetContextResult(RenderingContext&) = 0; + virtual void setCanvasGetContextResult(RenderingContext&) { ASSERT_NOT_REACHED(); }; + virtual void setOffscreenCanvasGetContextResult(OffscreenRenderingContext&) { ASSERT_NOT_REACHED(); } // Return true if the content is updated. virtual bool paintRenderingResultsToCanvas(SourceDrawingBuffer) { return false; } @@ -126,8 +127,7 @@ virtual ImageBitmap* transferToImageBitmap(ExceptionState&) { return nullptr; } protected: - CanvasRenderingContext(HTMLCanvasElement*); - CanvasRenderingContext(OffscreenCanvas*); + CanvasRenderingContext(HTMLCanvasElement* = nullptr, OffscreenCanvas* = nullptr); DECLARE_VIRTUAL_TRACE(); virtual void stop() = 0;
diff --git a/third_party/WebKit/Source/core/html/canvas/CanvasRenderingContextFactory.h b/third_party/WebKit/Source/core/html/canvas/CanvasRenderingContextFactory.h index a1d94d3b..a8d3f9a 100644 --- a/third_party/WebKit/Source/core/html/canvas/CanvasRenderingContextFactory.h +++ b/third_party/WebKit/Source/core/html/canvas/CanvasRenderingContextFactory.h
@@ -25,7 +25,7 @@ virtual ~CanvasRenderingContextFactory() { } virtual CanvasRenderingContext* create(HTMLCanvasElement*, const CanvasContextCreationAttributes&, Document&) { return nullptr; } - virtual CanvasRenderingContext* create(OffscreenCanvas*, const CanvasContextCreationAttributes&) { return nullptr; } + virtual CanvasRenderingContext* create(ScriptState*, OffscreenCanvas*, const CanvasContextCreationAttributes&) { return nullptr; } virtual CanvasRenderingContext::ContextType getContextType() const = 0; virtual void onError(HTMLCanvasElement*, const String& error) {}; virtual void onError(OffscreenCanvas*, const String& error) {};
diff --git a/third_party/WebKit/Source/core/html/imports/HTMLImportChild.cpp b/third_party/WebKit/Source/core/html/imports/HTMLImportChild.cpp index 33bca1d..e40a404 100644 --- a/third_party/WebKit/Source/core/html/imports/HTMLImportChild.cpp +++ b/third_party/WebKit/Source/core/html/imports/HTMLImportChild.cpp
@@ -83,7 +83,7 @@ void HTMLImportChild::didFinishLoading() { stateWillChange(); - if (document() && document()->styleSheets()->length() > 0) + if (document() && document()->styleSheets().length() > 0) UseCounter::count(root()->document(), UseCounter::HTMLImportsHasStyleSheets); V0CustomElement::didFinishLoadingImport(*(root()->document())); }
diff --git a/third_party/WebKit/Source/core/offscreencanvas/OffscreenCanvas.cpp b/third_party/WebKit/Source/core/offscreencanvas/OffscreenCanvas.cpp index 7712195..b29be4d 100644 --- a/third_party/WebKit/Source/core/offscreencanvas/OffscreenCanvas.cpp +++ b/third_party/WebKit/Source/core/offscreencanvas/OffscreenCanvas.cpp
@@ -58,7 +58,7 @@ return image; } -CanvasRenderingContext* OffscreenCanvas::getCanvasRenderingContext(const String& id, const CanvasContextCreationAttributes& attributes) +CanvasRenderingContext* OffscreenCanvas::getCanvasRenderingContext(ScriptState* scriptState, const String& id, const CanvasContextCreationAttributes& attributes) { CanvasRenderingContext::ContextType contextType = CanvasRenderingContext::contextTypeFromId(id); @@ -76,7 +76,7 @@ return nullptr; } } else { - m_context = factory->create(this, attributes); + m_context = factory->create(scriptState, this, attributes); } return m_context.get();
diff --git a/third_party/WebKit/Source/core/offscreencanvas/OffscreenCanvas.h b/third_party/WebKit/Source/core/offscreencanvas/OffscreenCanvas.h index 69051b8..f97398d3 100644 --- a/third_party/WebKit/Source/core/offscreencanvas/OffscreenCanvas.h +++ b/third_party/WebKit/Source/core/offscreencanvas/OffscreenCanvas.h
@@ -16,6 +16,8 @@ class CanvasContextCreationAttributes; class ImageBitmap; +class OffscreenCanvasRenderingContext2DOrWebGLRenderingContextOrWebGL2RenderingContext; +typedef OffscreenCanvasRenderingContext2DOrWebGLRenderingContextOrWebGL2RenderingContext OffscreenRenderingContext; class CORE_EXPORT OffscreenCanvas final : public GarbageCollected<OffscreenCanvas>, public ScriptWrappable { DEFINE_WRAPPERTYPEINFO(); @@ -36,7 +38,7 @@ int getAssociatedCanvasId() const { return m_canvasId; } bool isNeutered() const { return m_isNeutered; } void setNeutered(); - CanvasRenderingContext* getCanvasRenderingContext(const String&, const CanvasContextCreationAttributes&); + CanvasRenderingContext* getCanvasRenderingContext(ScriptState*, const String&, const CanvasContextCreationAttributes&); CanvasRenderingContext* renderingContext() { return m_context; } static void registerRenderingContextFactory(PassOwnPtr<CanvasRenderingContextFactory>);
diff --git a/third_party/WebKit/Source/devtools/front_end/emulation/DeviceModeModel.js b/third_party/WebKit/Source/devtools/front_end/emulation/DeviceModeModel.js index 662a0588..946ee71 100644 --- a/third_party/WebKit/Source/devtools/front_end/emulation/DeviceModeModel.js +++ b/third_party/WebKit/Source/devtools/front_end/emulation/DeviceModeModel.js
@@ -434,7 +434,9 @@ if (this._type === WebInspector.DeviceModeModel.Type.Device) { var orientation = this._device.orientationByName(this._mode.orientation); - var outline = (this._deviceOutlineSetting.get() && Runtime.experiments.isEnabled("deviceFrames")) ? orientation.outlineInsets : new Insets(0,0,0,0); + var outline = new Insets(0, 0, 0, 0); + if (Runtime.experiments.isEnabled("deviceFrames") && this._deviceOutlineSetting.get()) + outline = orientation.outlineInsets || outline; this._fitScale = this._calculateFitScale(orientation.width, orientation.height); if (this._device.mobile()) this._appliedUserAgentType = this._device.touch() ? WebInspector.DeviceModeModel.UA.Mobile : WebInspector.DeviceModeModel.UA.MobileNoTouch; @@ -501,7 +503,7 @@ /** * @param {!Size} screenSize * @param {!Insets} insets - * @param {!Insets|null} outline + * @param {!Insets} outline * @param {number} scale * @param {number} deviceScaleFactor * @param {boolean} mobile
diff --git a/third_party/WebKit/Source/modules/ModulesInitializer.cpp b/third_party/WebKit/Source/modules/ModulesInitializer.cpp index 4024c17c..6c69430 100644 --- a/third_party/WebKit/Source/modules/ModulesInitializer.cpp +++ b/third_party/WebKit/Source/modules/ModulesInitializer.cpp
@@ -55,6 +55,7 @@ // OffscreenCanvas context types must be registered with the OffscreenCanvas. OffscreenCanvas::registerRenderingContextFactory(adoptPtr(new OffscreenCanvasRenderingContext2D::Factory())); + OffscreenCanvas::registerRenderingContextFactory(adoptPtr(new WebGLRenderingContext::Factory())); ASSERT(isInitialized()); }
diff --git a/third_party/WebKit/Source/modules/canvas2d/BaseRenderingContext2D.cpp b/third_party/WebKit/Source/modules/canvas2d/BaseRenderingContext2D.cpp index 5397f3b..1f6d8b4 100644 --- a/third_party/WebKit/Source/modules/canvas2d/BaseRenderingContext2D.cpp +++ b/third_party/WebKit/Source/modules/canvas2d/BaseRenderingContext2D.cpp
@@ -849,7 +849,7 @@ return value.getAsHTMLCanvasElement(); if (value.isImageBitmap()) { if (static_cast<ImageBitmap*>(value.getAsImageBitmap())->isNeutered()) { - exceptionState.throwDOMException(InvalidStateError, String::format("The image source is neutered")); + exceptionState.throwDOMException(InvalidStateError, String::format("The image source is detached")); return nullptr; } return value.getAsImageBitmap();
diff --git a/third_party/WebKit/Source/modules/device_orientation/DeviceMotionEvent.cpp b/third_party/WebKit/Source/modules/device_orientation/DeviceMotionEvent.cpp index 1c2112d..1d2c5897 100644 --- a/third_party/WebKit/Source/modules/device_orientation/DeviceMotionEvent.cpp +++ b/third_party/WebKit/Source/modules/device_orientation/DeviceMotionEvent.cpp
@@ -48,7 +48,7 @@ void DeviceMotionEvent::initDeviceMotionEvent(const AtomicString& type, bool bubbles, bool cancelable, DeviceMotionData* deviceMotionData) { - if (dispatched()) + if (isBeingDispatched()) return; initEvent(type, bubbles, cancelable);
diff --git a/third_party/WebKit/Source/modules/device_orientation/DeviceOrientationEvent.cpp b/third_party/WebKit/Source/modules/device_orientation/DeviceOrientationEvent.cpp index 4bd0770..7552b71 100644 --- a/third_party/WebKit/Source/modules/device_orientation/DeviceOrientationEvent.cpp +++ b/third_party/WebKit/Source/modules/device_orientation/DeviceOrientationEvent.cpp
@@ -46,7 +46,7 @@ void DeviceOrientationEvent::initDeviceOrientationEvent(const AtomicString& type, bool bubbles, bool cancelable, const Nullable<double>& alpha, const Nullable<double>& beta, const Nullable<double>& gamma, bool absolute) { - if (dispatched()) + if (isBeingDispatched()) return; initEvent(type, bubbles, cancelable);
diff --git a/third_party/WebKit/Source/modules/offscreencanvas/OffscreenCanvasModules.cpp b/third_party/WebKit/Source/modules/offscreencanvas/OffscreenCanvasModules.cpp index 4dd5050..0585db0 100644 --- a/third_party/WebKit/Source/modules/offscreencanvas/OffscreenCanvasModules.cpp +++ b/third_party/WebKit/Source/modules/offscreencanvas/OffscreenCanvasModules.cpp
@@ -10,18 +10,16 @@ namespace blink { -OffscreenCanvasRenderingContext2D* OffscreenCanvasModules::getContext(OffscreenCanvas& offscreenCanvas, const String& id, const CanvasContextCreationAttributes& attributes, ExceptionState& exceptionState) +void OffscreenCanvasModules::getContext(ScriptState* scriptState, OffscreenCanvas& offscreenCanvas, const String& id, const CanvasContextCreationAttributes& attributes, ExceptionState& exceptionState, OffscreenRenderingContext& result) { if (offscreenCanvas.isNeutered()) { exceptionState.throwDOMException(InvalidStateError, "OffscreenCanvas object is detached"); - return nullptr; + return; } - CanvasRenderingContext* context = offscreenCanvas.getCanvasRenderingContext(id, attributes); - if (!context) - return nullptr; - - return static_cast<OffscreenCanvasRenderingContext2D*>(context); + CanvasRenderingContext* context = offscreenCanvas.getCanvasRenderingContext(scriptState, id, attributes); + if (context) + context->setOffscreenCanvasGetContextResult(result); } } // namespace blink
diff --git a/third_party/WebKit/Source/modules/offscreencanvas/OffscreenCanvasModules.h b/third_party/WebKit/Source/modules/offscreencanvas/OffscreenCanvasModules.h index 1353356..ed43b21 100644 --- a/third_party/WebKit/Source/modules/offscreencanvas/OffscreenCanvasModules.h +++ b/third_party/WebKit/Source/modules/offscreencanvas/OffscreenCanvasModules.h
@@ -6,6 +6,7 @@ #define OffscreenCanvasModules_h #include "bindings/core/v8/ExceptionState.h" +#include "core/offscreencanvas/OffscreenCanvas.h" #include "modules/ModulesExport.h" #include "wtf/Allocator.h" #include "wtf/text/WTFString.h" @@ -19,7 +20,7 @@ class MODULES_EXPORT OffscreenCanvasModules { STATIC_ONLY(OffscreenCanvasModules) public: - static OffscreenCanvasRenderingContext2D* getContext(OffscreenCanvas&, const String&, const CanvasContextCreationAttributes&, ExceptionState&); + static void getContext(ScriptState*, OffscreenCanvas&, const String&, const CanvasContextCreationAttributes&, ExceptionState&, OffscreenRenderingContext&); }; } // namespace blink
diff --git a/third_party/WebKit/Source/modules/offscreencanvas/OffscreenCanvasModules.idl b/third_party/WebKit/Source/modules/offscreencanvas/OffscreenCanvasModules.idl index 17c5b73e..42dccec506 100644 --- a/third_party/WebKit/Source/modules/offscreencanvas/OffscreenCanvasModules.idl +++ b/third_party/WebKit/Source/modules/offscreencanvas/OffscreenCanvasModules.idl
@@ -2,8 +2,10 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -typedef OffscreenCanvasRenderingContext2D OffscreenRenderingContext; +typedef (OffscreenCanvasRenderingContext2D or + WebGLRenderingContext or + WebGL2RenderingContext) OffscreenRenderingContext; partial interface OffscreenCanvas { - [RaisesException, RuntimeEnabled=ExperimentalCanvasFeatures] OffscreenRenderingContext? getContext(DOMString contextId, optional CanvasContextCreationAttributes attributes); + [CallWith=ScriptState, RaisesException, RuntimeEnabled=ExperimentalCanvasFeatures] OffscreenRenderingContext? getContext(DOMString contextId, optional CanvasContextCreationAttributes attributes); };
diff --git a/third_party/WebKit/Source/modules/offscreencanvas2d/OffscreenCanvasRenderingContext2D.cpp b/third_party/WebKit/Source/modules/offscreencanvas2d/OffscreenCanvasRenderingContext2D.cpp index 4a60e82c..758318b 100644 --- a/third_party/WebKit/Source/modules/offscreencanvas2d/OffscreenCanvasRenderingContext2D.cpp +++ b/third_party/WebKit/Source/modules/offscreencanvas2d/OffscreenCanvasRenderingContext2D.cpp
@@ -19,7 +19,7 @@ } OffscreenCanvasRenderingContext2D::OffscreenCanvasRenderingContext2D(OffscreenCanvas* canvas, const CanvasContextCreationAttributes& attrs) - : CanvasRenderingContext(canvas) + : CanvasRenderingContext(nullptr, canvas) , m_hasAlpha(attrs.alpha()) { } @@ -95,6 +95,11 @@ return ImageBitmap::create(image.release()); } +void OffscreenCanvasRenderingContext2D::setOffscreenCanvasGetContextResult(OffscreenRenderingContext& result) +{ + result.setOffscreenCanvasRenderingContext2D(this); +} + bool OffscreenCanvasRenderingContext2D::parseColorOrCurrentColor(Color& color, const String& colorString) const { return ::blink::parseColorOrCurrentColor(color, colorString, nullptr);
diff --git a/third_party/WebKit/Source/modules/offscreencanvas2d/OffscreenCanvasRenderingContext2D.h b/third_party/WebKit/Source/modules/offscreencanvas2d/OffscreenCanvasRenderingContext2D.h index f217cdf..1db409c7 100644 --- a/third_party/WebKit/Source/modules/offscreencanvas2d/OffscreenCanvasRenderingContext2D.h +++ b/third_party/WebKit/Source/modules/offscreencanvas2d/OffscreenCanvasRenderingContext2D.h
@@ -12,8 +12,6 @@ namespace blink { -class HTMLCanvasElement; - class MODULES_EXPORT OffscreenCanvasRenderingContext2D final : public CanvasRenderingContext, public BaseRenderingContext2D { DEFINE_WRAPPERTYPEINFO(); USING_GARBAGE_COLLECTED_MIXIN(OffscreenCanvasRenderingContext2D); @@ -23,7 +21,7 @@ Factory() {} ~Factory() override {} - CanvasRenderingContext* create(OffscreenCanvas* canvas, const CanvasContextCreationAttributes& attrs) override + CanvasRenderingContext* create(ScriptState* scriptState, OffscreenCanvas* canvas, const CanvasContextCreationAttributes& attrs) override { return new OffscreenCanvasRenderingContext2D(canvas, attrs); } @@ -38,6 +36,7 @@ ~OffscreenCanvasRenderingContext2D() override; ContextType getContextType() const override { return Context2d; } bool is2d() const override { return true; } + void setOffscreenCanvasGetContextResult(OffscreenRenderingContext&) final; void setIsHidden(bool) final { ASSERT_NOT_REACHED(); } void stop() final { ASSERT_NOT_REACHED(); } void setCanvasGetContextResult(RenderingContext&) final {}
diff --git a/third_party/WebKit/Source/modules/storage/StorageEvent.cpp b/third_party/WebKit/Source/modules/storage/StorageEvent.cpp index b18c5032..7a91673 100644 --- a/third_party/WebKit/Source/modules/storage/StorageEvent.cpp +++ b/third_party/WebKit/Source/modules/storage/StorageEvent.cpp
@@ -81,7 +81,7 @@ void StorageEvent::initStorageEvent(const AtomicString& type, bool canBubble, bool cancelable, const String& key, const String& oldValue, const String& newValue, const String& url, Storage* storageArea) { - if (dispatched()) + if (isBeingDispatched()) return; initEvent(type, canBubble, cancelable);
diff --git a/third_party/WebKit/Source/modules/webgl/WebGL2RenderingContext.cpp b/third_party/WebKit/Source/modules/webgl/WebGL2RenderingContext.cpp index 671319c..1da246a 100644 --- a/third_party/WebKit/Source/modules/webgl/WebGL2RenderingContext.cpp +++ b/third_party/WebKit/Source/modules/webgl/WebGL2RenderingContext.cpp
@@ -83,6 +83,17 @@ result.setWebGL2RenderingContext(this); } +void WebGL2RenderingContext::setOffscreenCanvasGetContextResult(OffscreenRenderingContext& result) +{ + result.setWebGL2RenderingContext(this); +} + +ImageBitmap* WebGL2RenderingContext::transferToImageBitmap(ExceptionState& exceptionState) +{ + NOTIMPLEMENTED(); + return nullptr; +} + void WebGL2RenderingContext::registerContextExtensions() { // Register extensions.
diff --git a/third_party/WebKit/Source/modules/webgl/WebGL2RenderingContext.h b/third_party/WebKit/Source/modules/webgl/WebGL2RenderingContext.h index 61ad255..899faac 100644 --- a/third_party/WebKit/Source/modules/webgl/WebGL2RenderingContext.h +++ b/third_party/WebKit/Source/modules/webgl/WebGL2RenderingContext.h
@@ -30,10 +30,12 @@ ~WebGL2RenderingContext() override; CanvasRenderingContext::ContextType getContextType() const override { return CanvasRenderingContext::ContextWebgl2; } + ImageBitmap* transferToImageBitmap(ExceptionState&) final; unsigned version() const override { return 2; } String contextName() const override { return "WebGL2RenderingContext"; } void registerContextExtensions() override; void setCanvasGetContextResult(RenderingContext&) final; + void setOffscreenCanvasGetContextResult(OffscreenRenderingContext&) final; DECLARE_VIRTUAL_TRACE();
diff --git a/third_party/WebKit/Source/modules/webgl/WebGLRenderingContext.cpp b/third_party/WebKit/Source/modules/webgl/WebGLRenderingContext.cpp index abd64cd..cc46e80 100644 --- a/third_party/WebKit/Source/modules/webgl/WebGLRenderingContext.cpp +++ b/third_party/WebKit/Source/modules/webgl/WebGLRenderingContext.cpp
@@ -65,28 +65,51 @@ namespace blink { +// An helper function for the two create() methods. The return value is an +// indicate of whether the create() should return nullptr or not. +static bool shouldCreateContext(WebGraphicsContext3DProvider* contextProvider) +{ + if (!contextProvider) + return false; + gpu::gles2::GLES2Interface* gl = contextProvider->contextGL(); + OwnPtr<Extensions3DUtil> extensionsUtil = Extensions3DUtil::create(gl); + if (!extensionsUtil) + return false; + if (extensionsUtil->supportsExtension("GL_EXT_debug_marker")) { + String contextLabel(String::format("WebGLRenderingContext-%p", contextProvider)); + gl->PushGroupMarkerEXT(0, contextLabel.ascii().data()); + } + return true; +} + +CanvasRenderingContext* WebGLRenderingContext::Factory::create(ScriptState* scriptState, OffscreenCanvas* offscreenCanvas, const CanvasContextCreationAttributes& attrs) +{ + WebGLContextAttributes attributes = toWebGLContextAttributes(attrs); + OwnPtr<WebGraphicsContext3DProvider> contextProvider(createWebGraphicsContext3DProvider(scriptState, attributes, 1)); + if (!shouldCreateContext(contextProvider.get())) + return nullptr; + + WebGLRenderingContext* renderingContext = new WebGLRenderingContext(offscreenCanvas, contextProvider.release(), attributes); + if (!renderingContext->drawingBuffer()) + return nullptr; + renderingContext->initializeNewContext(); + renderingContext->registerContextExtensions(); + + return renderingContext; +} + CanvasRenderingContext* WebGLRenderingContext::Factory::create(HTMLCanvasElement* canvas, const CanvasContextCreationAttributes& attrs, Document&) { WebGLContextAttributes attributes = toWebGLContextAttributes(attrs); OwnPtr<WebGraphicsContext3DProvider> contextProvider(createWebGraphicsContext3DProvider(canvas, attributes, 1)); - if (!contextProvider) + if (!shouldCreateContext(contextProvider.get())) return nullptr; - gpu::gles2::GLES2Interface* gl = contextProvider->contextGL(); - OwnPtr<Extensions3DUtil> extensionsUtil = Extensions3DUtil::create(gl); - if (!extensionsUtil) - return nullptr; - if (extensionsUtil->supportsExtension("GL_EXT_debug_marker")) { - String contextLabel(String::format("WebGLRenderingContext-%p", contextProvider.get())); - gl->PushGroupMarkerEXT(0, contextLabel.ascii().data()); - } WebGLRenderingContext* renderingContext = new WebGLRenderingContext(canvas, contextProvider.release(), attributes); - if (!renderingContext->drawingBuffer()) { canvas->dispatchEvent(WebGLContextEvent::create(EventTypeNames::webglcontextcreationerror, false, true, "Could not create a WebGL context.")); return nullptr; } - renderingContext->initializeNewContext(); renderingContext->registerContextExtensions(); @@ -103,6 +126,11 @@ { } +WebGLRenderingContext::WebGLRenderingContext(OffscreenCanvas* passedOffscreenCanvas, PassOwnPtr<WebGraphicsContext3DProvider> contextProvider, const WebGLContextAttributes& requestedAttributes) + : WebGLRenderingContextBase(passedOffscreenCanvas, std::move(contextProvider), requestedAttributes) +{ +} + WebGLRenderingContext::~WebGLRenderingContext() { } @@ -112,6 +140,17 @@ result.setWebGLRenderingContext(this); } +void WebGLRenderingContext::setOffscreenCanvasGetContextResult(OffscreenRenderingContext& result) +{ + result.setWebGLRenderingContext(this); +} + +ImageBitmap* WebGLRenderingContext::transferToImageBitmap(ExceptionState& exceptionState) +{ + NOTIMPLEMENTED(); + return nullptr; +} + void WebGLRenderingContext::registerContextExtensions() { // Register extensions.
diff --git a/third_party/WebKit/Source/modules/webgl/WebGLRenderingContext.h b/third_party/WebKit/Source/modules/webgl/WebGLRenderingContext.h index e0f6a0b3..b2f6548 100644 --- a/third_party/WebKit/Source/modules/webgl/WebGLRenderingContext.h +++ b/third_party/WebKit/Source/modules/webgl/WebGLRenderingContext.h
@@ -43,6 +43,7 @@ ~Factory() override {} CanvasRenderingContext* create(HTMLCanvasElement*, const CanvasContextCreationAttributes&, Document&) override; + CanvasRenderingContext* create(ScriptState*, OffscreenCanvas*, const CanvasContextCreationAttributes&) override; CanvasRenderingContext::ContextType getContextType() const override { return CanvasRenderingContext::ContextWebgl; } void onError(HTMLCanvasElement*, const String& error) override; }; @@ -50,16 +51,19 @@ ~WebGLRenderingContext() override; CanvasRenderingContext::ContextType getContextType() const override { return CanvasRenderingContext::ContextWebgl; } + ImageBitmap* transferToImageBitmap(ExceptionState&) final; unsigned version() const override { return 1; } String contextName() const override { return "WebGLRenderingContext"; } void registerContextExtensions() override; void setCanvasGetContextResult(RenderingContext&) final; + void setOffscreenCanvasGetContextResult(OffscreenRenderingContext&) final; EAGERLY_FINALIZE(); DECLARE_VIRTUAL_TRACE(); private: WebGLRenderingContext(HTMLCanvasElement*, PassOwnPtr<WebGraphicsContext3DProvider>, const WebGLContextAttributes&); + WebGLRenderingContext(OffscreenCanvas*, PassOwnPtr<WebGraphicsContext3DProvider>, const WebGLContextAttributes&); // Enabled extension objects. Member<ANGLEInstancedArrays> m_angleInstancedArrays;
diff --git a/third_party/WebKit/Source/modules/webgl/WebGLRenderingContextBase.cpp b/third_party/WebKit/Source/modules/webgl/WebGLRenderingContextBase.cpp index 999af82..828b8752 100644 --- a/third_party/WebKit/Source/modules/webgl/WebGLRenderingContextBase.cpp +++ b/third_party/WebKit/Source/modules/webgl/WebGLRenderingContextBase.cpp
@@ -503,6 +503,34 @@ return statusMessage; } +static PassOwnPtr<WebGraphicsContext3DProvider> createWebGraphicsContext3DProviderInternal(HTMLCanvasElement* canvas, ScriptState* scriptState, WebGLContextAttributes attributes, unsigned webGLVersion) +{ + Platform::ContextAttributes contextAttributes = toPlatformContextAttributes(attributes, webGLVersion); + Platform::GraphicsInfo glInfo; + OwnPtr<WebGraphicsContext3DProvider> contextProvider; + if (canvas) { + contextProvider = adoptPtr(Platform::current()->createOffscreenGraphicsContext3DProvider( + contextAttributes, canvas->document().topDocument().url(), 0, &glInfo)); + } else { + contextProvider = adoptPtr(Platform::current()->createOffscreenGraphicsContext3DProvider( + contextAttributes, scriptState->getExecutionContext()->url(), 0, &glInfo)); + } + if (!contextProvider || shouldFailContextCreationForTesting) { + shouldFailContextCreationForTesting = false; + if (canvas) + canvas->dispatchEvent(WebGLContextEvent::create(EventTypeNames::webglcontextcreationerror, false, true, extractWebGLContextCreationError(glInfo))); + return nullptr; + } + gpu::gles2::GLES2Interface* gl = contextProvider->contextGL(); + if (!String(gl->GetString(GL_EXTENSIONS)).contains("GL_OES_packed_depth_stencil")) { + if (canvas) + canvas->dispatchEvent(WebGLContextEvent::create(EventTypeNames::webglcontextcreationerror, false, true, "OES_packed_depth_stencil support is required.")); + return nullptr; + } + + return contextProvider.release(); +} + PassOwnPtr<WebGraphicsContext3DProvider> WebGLRenderingContextBase::createWebGraphicsContext3DProvider(HTMLCanvasElement* canvas, WebGLContextAttributes attributes, unsigned webGLVersion) { Document& document = canvas->document(); @@ -520,22 +548,12 @@ return nullptr; } - Platform::ContextAttributes contextAttributes = toPlatformContextAttributes(attributes, webGLVersion); - Platform::GraphicsInfo glInfo; - OwnPtr<WebGraphicsContext3DProvider> contextProvider = adoptPtr(Platform::current()->createOffscreenGraphicsContext3DProvider( - contextAttributes, document.topDocument().url(), 0, &glInfo)); - if (!contextProvider || shouldFailContextCreationForTesting) { - shouldFailContextCreationForTesting = false; - canvas->dispatchEvent(WebGLContextEvent::create(EventTypeNames::webglcontextcreationerror, false, true, extractWebGLContextCreationError(glInfo))); - return nullptr; - } - gpu::gles2::GLES2Interface* gl = contextProvider->contextGL(); - if (!String(gl->GetString(GL_EXTENSIONS)).contains("GL_OES_packed_depth_stencil")) { - canvas->dispatchEvent(WebGLContextEvent::create(EventTypeNames::webglcontextcreationerror, false, true, "OES_packed_depth_stencil support is required.")); - return nullptr; - } + return createWebGraphicsContext3DProviderInternal(canvas, nullptr, attributes, webGLVersion); +} - return contextProvider.release(); +PassOwnPtr<WebGraphicsContext3DProvider> WebGLRenderingContextBase::createWebGraphicsContext3DProvider(ScriptState* scriptState, WebGLContextAttributes attributes, unsigned webGLVersion) +{ + return createWebGraphicsContext3DProviderInternal(nullptr, scriptState, attributes, webGLVersion); } void WebGLRenderingContextBase::forceNextWebGLContextCreationToFail() @@ -780,8 +798,16 @@ } // namespace +WebGLRenderingContextBase::WebGLRenderingContextBase(OffscreenCanvas* passedOffscreenCanvas, PassOwnPtr<WebGraphicsContext3DProvider> contextProvider, const WebGLContextAttributes& requestedAttributes) + : WebGLRenderingContextBase(nullptr, passedOffscreenCanvas, std::move(contextProvider), requestedAttributes) +{ } + WebGLRenderingContextBase::WebGLRenderingContextBase(HTMLCanvasElement* passedCanvas, PassOwnPtr<WebGraphicsContext3DProvider> contextProvider, const WebGLContextAttributes& requestedAttributes) - : CanvasRenderingContext(passedCanvas) + : WebGLRenderingContextBase(passedCanvas, nullptr, std::move(contextProvider), requestedAttributes) +{ } + +WebGLRenderingContextBase::WebGLRenderingContextBase(HTMLCanvasElement* passedCanvas, OffscreenCanvas* passedOffscreenCanvas, PassOwnPtr<WebGraphicsContext3DProvider> contextProvider, const WebGLContextAttributes& requestedAttributes) + : CanvasRenderingContext(passedCanvas, passedOffscreenCanvas) , m_isHidden(false) , m_contextLostMode(NotLostContext) , m_autoRecoveryMethod(Manual) @@ -976,8 +1002,10 @@ void WebGLRenderingContextBase::setupFlags() { ASSERT(drawingBuffer()); - if (Page* p = canvas()->document().page()) { - m_synthesizedErrorsToConsole = p->settings().webGLErrorsToConsoleEnabled(); + if (canvas()) { + if (Page* p = canvas()->document().page()) { + m_synthesizedErrorsToConsole = p->settings().webGLErrorsToConsoleEnabled(); + } } m_isDepthStencilSupported = extensionsUtil()->isExtensionEnabled("GL_OES_packed_depth_stencil"); @@ -5790,7 +5818,7 @@ bool WebGLRenderingContextBase::validateImageBitmap(const char* functionName, ImageBitmap* bitmap, ExceptionState& exceptionState) { if (bitmap->isNeutered()) { - synthesizeGLError(GL_INVALID_VALUE, functionName, "The source data has been neutered."); + synthesizeGLError(GL_INVALID_VALUE, functionName, "The source data has been detached."); return false; } if (!bitmap->originClean()) { @@ -6044,8 +6072,16 @@ IntSize WebGLRenderingContextBase::clampedCanvasSize() { - return IntSize(clamp(canvas()->width(), 1, m_maxViewportDims[0]), - clamp(canvas()->height(), 1, m_maxViewportDims[1])); + int width, height; + if (canvas()) { + width = canvas()->width(); + height = canvas()->height(); + } else { + width = getOffscreenCanvas()->width(); + height = getOffscreenCanvas()->height(); + } + return IntSize(clamp(width, 1, m_maxViewportDims[0]), + clamp(height, 1, m_maxViewportDims[1])); } GLint WebGLRenderingContextBase::maxDrawBuffers()
diff --git a/third_party/WebKit/Source/modules/webgl/WebGLRenderingContextBase.h b/third_party/WebKit/Source/modules/webgl/WebGLRenderingContextBase.h index 488589a..97edb87 100644 --- a/third_party/WebKit/Source/modules/webgl/WebGLRenderingContextBase.h +++ b/third_party/WebKit/Source/modules/webgl/WebGLRenderingContextBase.h
@@ -152,6 +152,7 @@ static unsigned getWebGLVersion(const CanvasRenderingContext*); static PassOwnPtr<WebGraphicsContext3DProvider> createWebGraphicsContext3DProvider(HTMLCanvasElement*, WebGLContextAttributes, unsigned webGLVersion); + static PassOwnPtr<WebGraphicsContext3DProvider> createWebGraphicsContext3DProvider(ScriptState*, WebGLContextAttributes, unsigned webGLVersion); static void forceNextWebGLContextCreationToFail(); int drawingBufferWidth() const; @@ -443,6 +444,7 @@ friend class ScopedFramebufferRestorer; WebGLRenderingContextBase(HTMLCanvasElement*, PassOwnPtr<WebGraphicsContext3DProvider>, const WebGLContextAttributes&); + WebGLRenderingContextBase(OffscreenCanvas*, PassOwnPtr<WebGraphicsContext3DProvider>, const WebGLContextAttributes&); PassRefPtr<DrawingBuffer> createDrawingBuffer(PassOwnPtr<WebGraphicsContext3DProvider>); void setupFlags(); @@ -1074,6 +1076,9 @@ static WebGLRenderingContextBase* oldestEvictedContext(); CrossThreadWeakPersistentThisPointer<WebGLRenderingContextBase> createWeakThisPointer() { return CrossThreadWeakPersistentThisPointer<WebGLRenderingContextBase>(this); } + +private: + WebGLRenderingContextBase(HTMLCanvasElement*, OffscreenCanvas*, PassOwnPtr<WebGraphicsContext3DProvider>, const WebGLContextAttributes&); }; DEFINE_TYPE_CASTS(WebGLRenderingContextBase, CanvasRenderingContext, context, context->is3d(), context.is3d());
diff --git a/third_party/WebKit/Source/platform/CrossThreadCopier.h b/third_party/WebKit/Source/platform/CrossThreadCopier.h index de30baa0..e29e8411 100644 --- a/third_party/WebKit/Source/platform/CrossThreadCopier.h +++ b/third_party/WebKit/Source/platform/CrossThreadCopier.h
@@ -158,16 +158,6 @@ }; template <typename T> -struct CrossThreadCopier<WeakMember<T>*> { - STATIC_ONLY(CrossThreadCopier); - typedef WeakMember<T>* Type; - static Type copy(Type ptr) - { - return ptr; - } -}; - -template <typename T> struct CrossThreadCopier<WTF::PassedWrapper<T>> { STATIC_ONLY(CrossThreadCopier); using Type = WTF::PassedWrapper<typename CrossThreadCopier<T>::Type>; @@ -225,25 +215,20 @@ } }; -template <typename T> -struct CrossThreadCopier<WeakMember<T>> { - STATIC_ONLY(CrossThreadCopier); - static_assert(IsGarbageCollectedType<T>::value, "T must be a garbage-collected type."); - typedef T* Type; - static Type copy(const WeakMember<T>& ptr) - { - return ptr; - } -}; - // |T| is |C*| or |const WeakPtr<C>&|. template <typename T> struct AllowCrossThreadAccessWrapper { STACK_ALLOCATED(); public: - explicit AllowCrossThreadAccessWrapper(T value) : m_value(value) { } T value() const { return m_value; } private: + // Only constructible from AllowCrossThreadAccess(). + explicit AllowCrossThreadAccessWrapper(T value) : m_value(value) { } + template <typename U> + friend AllowCrossThreadAccessWrapper<U*> AllowCrossThreadAccess(U*); + template <typename U> + friend AllowCrossThreadAccessWrapper<const WeakPtr<U>&> AllowCrossThreadAccess(const WeakPtr<U>&); + // This raw pointer is safe since AllowCrossThreadAccessWrapper is // always stack-allocated. Ideally this should be Member<T> if T is // garbage-collected and T* otherwise, but we don't want to introduce
diff --git a/third_party/WebKit/Source/platform/fonts/FontDataForRangeSet.h b/third_party/WebKit/Source/platform/fonts/FontDataForRangeSet.h index 42091042..a31bb4727 100644 --- a/third_party/WebKit/Source/platform/fonts/FontDataForRangeSet.h +++ b/third_party/WebKit/Source/platform/fonts/FontDataForRangeSet.h
@@ -38,17 +38,8 @@ class FontDataForRangeSet final { DISALLOW_NEW_EXCEPT_PLACEMENT_NEW(); - explicit FontDataForRangeSet(PassRefPtr<SimpleFontData> fontData) - : m_fontData(fontData) - { - } - FontDataForRangeSet() - : m_fontData(nullptr) - { - } - - explicit FontDataForRangeSet(PassRefPtr<SimpleFontData> fontData, PassRefPtr<UnicodeRangeSet> rangeSet) + explicit FontDataForRangeSet(PassRefPtr<SimpleFontData> fontData = nullptr, PassRefPtr<UnicodeRangeSet> rangeSet = nullptr) : m_fontData(fontData) , m_rangeSet(rangeSet) { @@ -67,9 +58,9 @@ bool contains(UChar32 testChar) const { return m_rangeSet->contains(testChar); } bool isEntireRange() const { return m_rangeSet->isEntireRange(); } - PassRefPtr<UnicodeRangeSet> ranges() const { return m_rangeSet; } - bool hasFontData() const { return fontData(); } - PassRefPtr<SimpleFontData> fontData() const { return m_fontData; } + UnicodeRangeSet* ranges() const { return m_rangeSet.get(); } + bool hasFontData() const { return m_fontData.get(); } + const SimpleFontData* fontData() const { return m_fontData.get(); } private: RefPtr<SimpleFontData> m_fontData;
diff --git a/third_party/WebKit/Source/platform/fonts/FontFallbackIterator.cpp b/third_party/WebKit/Source/platform/fonts/FontFallbackIterator.cpp index 7467c93..c1c0ca9 100644 --- a/third_party/WebKit/Source/platform/fonts/FontFallbackIterator.cpp +++ b/third_party/WebKit/Source/platform/fonts/FontFallbackIterator.cpp
@@ -154,9 +154,10 @@ } if (rangeSetContributesForHint(hintList, currentSegmentedFace)) { - if (currentSegmentedFace.fontData()->customFontData()) - currentSegmentedFace.fontData()->customFontData()->beginLoadIfNeeded(); - if (!currentSegmentedFace.fontData()->isLoading()) + const SimpleFontData* fontData = currentSegmentedFace.fontData(); + if (const CustomFontData* customFontData = fontData->customFontData()) + customFontData->beginLoadIfNeeded(); + if (!fontData->isLoading()) return currentSegmentedFace; m_trackedLoadingRangeSets.append(currentSegmentedFace); }
diff --git a/third_party/WebKit/Source/platform/fonts/FontFallbackList.cpp b/third_party/WebKit/Source/platform/fonts/FontFallbackList.cpp index 713ed39..71d1851 100644 --- a/third_party/WebKit/Source/platform/fonts/FontFallbackList.cpp +++ b/third_party/WebKit/Source/platform/fonts/FontFallbackList.cpp
@@ -134,7 +134,7 @@ if (fontData->isSegmented()) { const SegmentedFontData* segmented = toSegmentedFontData(fontData); for (unsigned i = 0; i < segmented->numFaces(); i++) { - const SimpleFontData* rangeFontData = segmented->faceAt(i).fontData().get(); + const SimpleFontData* rangeFontData = segmented->faceAt(i).fontData(); if (!rangeFontData->isLoadingFallback()) return rangeFontData; }
diff --git a/third_party/WebKit/Source/platform/fonts/GlyphPageTreeNode.cpp b/third_party/WebKit/Source/platform/fonts/GlyphPageTreeNode.cpp index 9bd9479..d0b99cf 100644 --- a/third_party/WebKit/Source/platform/fonts/GlyphPageTreeNode.cpp +++ b/third_party/WebKit/Source/platform/fonts/GlyphPageTreeNode.cpp
@@ -278,7 +278,7 @@ continue; } - haveGlyphs |= fill(m_page.get(), from, to - from, buffer + from * (start < 0x10000 ? 1 : 2), (to - from) * (start < 0x10000 ? 1 : 2), fontDataForRangeSet.fontData().get()); + haveGlyphs |= fill(m_page.get(), from, to - from, buffer + from * (start < 0x10000 ? 1 : 2), (to - from) * (start < 0x10000 ? 1 : 2), fontDataForRangeSet.fontData()); } } }
diff --git a/third_party/WebKit/Source/platform/fonts/SegmentedFontData.cpp b/third_party/WebKit/Source/platform/fonts/SegmentedFontData.cpp index e2f00607..05fe81f 100644 --- a/third_party/WebKit/Source/platform/fonts/SegmentedFontData.cpp +++ b/third_party/WebKit/Source/platform/fonts/SegmentedFontData.cpp
@@ -41,9 +41,9 @@ Vector<FontDataForRangeSet>::const_iterator end = m_faces.end(); for (Vector<FontDataForRangeSet>::const_iterator it = m_faces.begin(); it != end; ++it) { if (it->contains(c)) - return it->fontData().get(); + return it->fontData(); } - return m_faces[0].fontData().get(); + return m_faces[0].fontData(); } bool SegmentedFontData::containsCharacter(UChar32 c) const
diff --git a/third_party/WebKit/Source/platform/fonts/SimpleFontData.h b/third_party/WebKit/Source/platform/fonts/SimpleFontData.h index eed56b4..03a087c 100644 --- a/third_party/WebKit/Source/platform/fonts/SimpleFontData.h +++ b/third_party/WebKit/Source/platform/fonts/SimpleFontData.h
@@ -122,7 +122,7 @@ bool canRenderCombiningCharacterSequence(const UChar*, size_t) const; - PassRefPtr<CustomFontData> customFontData() const { return m_customFontData; } + CustomFontData* customFontData() const { return m_customFontData.get(); } // Implemented by the platform. virtual bool fillGlyphPage(GlyphPage* pageToFill, unsigned offset, unsigned length, UChar* buffer, unsigned bufferLength) const;
diff --git a/third_party/WebKit/Source/platform/fonts/shaping/HarfBuzzShaper.cpp b/third_party/WebKit/Source/platform/fonts/shaping/HarfBuzzShaper.cpp index d2e90d4..204da72b 100644 --- a/third_party/WebKit/Source/platform/fonts/shaping/HarfBuzzShaper.cpp +++ b/third_party/WebKit/Source/platform/fonts/shaping/HarfBuzzShaper.cpp
@@ -80,11 +80,6 @@ DestroyFunction m_destroy; }; -static inline float harfBuzzPositionToFloat(hb_position_t value) -{ - return static_cast<float>(value) / (1 << 16); -} - static void normalizeCharacters(const TextRun& run, unsigned length, UChar* destination, unsigned* destinationLength) { unsigned position = 0; @@ -436,14 +431,16 @@ // When we're getting here with the last resort font, we have no other // choice than adding boxes to the ShapeResult. if ((currentClusterResult == NotDef && numCharacters) || isLastResort) { + hb_direction_t direction = TextDirectionToHBDirection( + m_textRun.direction(), + m_font->getFontDescription().orientation(), currentFont); // Here we need to specify glyph positions. - OwnPtr<ShapeResult::RunInfo> run = adoptPtr(new ShapeResult::RunInfo(currentFont, - TextDirectionToHBDirection(m_textRun.direction(), - m_font->getFontDescription().orientation(), currentFont), - ICUScriptToHBScript(currentRunScript), - startIndex, - numGlyphsToInsert, numCharacters)); - insertRunIntoShapeResult(shapeResult, run.release(), lastChangePosition, numGlyphsToInsert, harfBuzzBuffer); + ShapeResult::RunInfo* run = new ShapeResult::RunInfo(currentFont, + direction, ICUScriptToHBScript(currentRunScript), + startIndex, numGlyphsToInsert, numCharacters); + shapeResult->insertRun(adoptPtr(run), lastChangePosition, + numGlyphsToInsert, + harfBuzzBuffer); } lastChangePosition = glyphIndex; } @@ -588,7 +585,7 @@ } FontDataForRangeSet nextFontDataForRangeSet = fallbackIterator->next(fallbackCharsHint); - currentFont = nextFontDataForRangeSet.fontData().get(); + currentFont = nextFontDataForRangeSet.fontData(); currentFontRangeSet = nextFontDataForRangeSet.ranges(); if (!currentFont) { @@ -661,81 +658,6 @@ return result.release(); } -// TODO crbug.com/542701: This should be a method on ShapeResult. -void HarfBuzzShaper::insertRunIntoShapeResult(ShapeResult* result, - PassOwnPtr<ShapeResult::RunInfo> runToInsert, unsigned startGlyph, unsigned numGlyphs, - hb_buffer_t* harfBuzzBuffer) -{ - ASSERT(numGlyphs > 0); - OwnPtr<ShapeResult::RunInfo> run(std::move(runToInsert)); - ASSERT(numGlyphs == run->m_glyphData.size()); - - const SimpleFontData* currentFontData = run->m_fontData.get(); - const hb_glyph_info_t* glyphInfos = hb_buffer_get_glyph_infos(harfBuzzBuffer, 0); - const hb_glyph_position_t* glyphPositions = hb_buffer_get_glyph_positions(harfBuzzBuffer, 0); - const unsigned startCluster = HB_DIRECTION_IS_FORWARD(hb_buffer_get_direction(harfBuzzBuffer)) - ? glyphInfos[startGlyph].cluster : glyphInfos[startGlyph + numGlyphs - 1].cluster; - - float totalAdvance = 0.0f; - FloatPoint glyphOrigin; - bool hasVerticalOffsets = !HB_DIRECTION_IS_HORIZONTAL(run->m_direction); - - // HarfBuzz returns result in visual order, no need to flip for RTL. - for (unsigned i = 0; i < numGlyphs; ++i) { - uint16_t glyph = glyphInfos[startGlyph + i].codepoint; - float offsetX = harfBuzzPositionToFloat(glyphPositions[startGlyph + i].x_offset); - float offsetY = -harfBuzzPositionToFloat(glyphPositions[startGlyph + i].y_offset); - - // One out of x_advance and y_advance is zero, depending on - // whether the buffer direction is horizontal or vertical. - float advance = harfBuzzPositionToFloat(glyphPositions[startGlyph + i].x_advance - glyphPositions[startGlyph + i].y_advance); - RELEASE_ASSERT(m_normalizedBufferLength > glyphInfos[startGlyph + i].cluster); - - // The characterIndex of one ShapeResult run is normalized to the run's - // startIndex and length. TODO crbug.com/542703: Consider changing that - // and instead pass the whole run to hb_buffer_t each time. - run->m_glyphData[i].characterIndex = glyphInfos[startGlyph + i].cluster - startCluster; - - run->setGlyphAndPositions(i, glyph, advance, offsetX, offsetY); - totalAdvance += advance; - hasVerticalOffsets |= (offsetY != 0); - - FloatRect glyphBounds = currentFontData->boundsForGlyph(glyph); - glyphBounds.move(glyphOrigin.x(), glyphOrigin.y()); - result->m_glyphBoundingBox.unite(glyphBounds); - glyphOrigin += FloatSize(advance + offsetX, offsetY); - } - run->m_width = std::max(0.0f, totalAdvance); - result->m_width += run->m_width; - result->m_numGlyphs += numGlyphs; - ASSERT(result->m_numGlyphs >= numGlyphs); // no overflow - result->m_hasVerticalOffsets |= hasVerticalOffsets; - - // The runs are stored in result->m_runs in visual order. For LTR, we place - // the run to be inserted before the next run with a bigger character - // start index. For RTL, we place the run before the next run with a lower - // character index. Otherwise, for both directions, at the end. - if (HB_DIRECTION_IS_FORWARD(run->m_direction)) { - for (size_t pos = 0; pos < result->m_runs.size(); ++pos) { - if (result->m_runs.at(pos)->m_startIndex > run->m_startIndex) { - result->m_runs.insert(pos, run.release()); - break; - } - } - } else { - for (size_t pos = 0; pos < result->m_runs.size(); ++pos) { - if (result->m_runs.at(pos)->m_startIndex < run->m_startIndex) { - result->m_runs.insert(pos, run.release()); - break; - } - } - } - // If we didn't find an existing slot to place it, append. - if (run) { - result->m_runs.append(run.release()); - } -} - PassRefPtr<ShapeResult> ShapeResult::createForTabulationCharacters(const Font* font, const TextRun& textRun, float positionOffset, unsigned count) {
diff --git a/third_party/WebKit/Source/platform/fonts/shaping/ShapeResult.cpp b/third_party/WebKit/Source/platform/fonts/shaping/ShapeResult.cpp index ada9db22..476057b 100644 --- a/third_party/WebKit/Source/platform/fonts/shaping/ShapeResult.cpp +++ b/third_party/WebKit/Source/platform/fonts/shaping/ShapeResult.cpp
@@ -34,6 +34,7 @@ #include "platform/fonts/Font.h" #include "platform/fonts/shaping/ShapeResultInlineHeaders.h" #include "platform/fonts/shaping/ShapeResultSpacing.h" +#include <hb.h> namespace blink { @@ -271,4 +272,88 @@ return result.release(); } +static inline float harfBuzzPositionToFloat(hb_position_t value) +{ + return static_cast<float>(value) / (1 << 16); +} + +void ShapeResult::insertRun(PassOwnPtr<ShapeResult::RunInfo> runToInsert, + unsigned startGlyph, unsigned numGlyphs, hb_buffer_t* harfBuzzBuffer) +{ + ASSERT(numGlyphs > 0); + OwnPtr<ShapeResult::RunInfo> run(std::move(runToInsert)); + ASSERT(numGlyphs == run->m_glyphData.size()); + + const SimpleFontData* currentFontData = run->m_fontData.get(); + const hb_glyph_info_t* glyphInfos = + hb_buffer_get_glyph_infos(harfBuzzBuffer, 0); + const hb_glyph_position_t* glyphPositions = + hb_buffer_get_glyph_positions(harfBuzzBuffer, 0); + const unsigned startCluster = + HB_DIRECTION_IS_FORWARD(hb_buffer_get_direction(harfBuzzBuffer)) + ? glyphInfos[startGlyph].cluster + : glyphInfos[startGlyph + numGlyphs - 1].cluster; + + float totalAdvance = 0.0f; + FloatPoint glyphOrigin; + bool hasVerticalOffsets = !HB_DIRECTION_IS_HORIZONTAL(run->m_direction); + + // HarfBuzz returns result in visual order, no need to flip for RTL. + for (unsigned i = 0; i < numGlyphs; ++i) { + uint16_t glyph = glyphInfos[startGlyph + i].codepoint; + hb_glyph_position_t pos = glyphPositions[startGlyph + i]; + + float offsetX = harfBuzzPositionToFloat(pos.x_offset); + float offsetY = -harfBuzzPositionToFloat(pos.y_offset); + + // One out of x_advance and y_advance is zero, depending on + // whether the buffer direction is horizontal or vertical. + float advance = harfBuzzPositionToFloat(pos.x_advance - pos.y_advance); + + // The characterIndex of one ShapeResult run is normalized to the run's + // startIndex and length. TODO crbug.com/542703: Consider changing that + // and instead pass the whole run to hb_buffer_t each time. + run->m_glyphData[i].characterIndex = + glyphInfos[startGlyph + i].cluster - startCluster; + + run->setGlyphAndPositions(i, glyph, advance, offsetX, offsetY); + totalAdvance += advance; + hasVerticalOffsets |= (offsetY != 0); + + FloatRect glyphBounds = currentFontData->boundsForGlyph(glyph); + glyphBounds.move(glyphOrigin.x(), glyphOrigin.y()); + m_glyphBoundingBox.unite(glyphBounds); + glyphOrigin += FloatSize(advance + offsetX, offsetY); + } + + run->m_width = std::max(0.0f, totalAdvance); + m_width += run->m_width; + m_numGlyphs += numGlyphs; + ASSERT(m_numGlyphs >= numGlyphs); + m_hasVerticalOffsets |= hasVerticalOffsets; + + // The runs are stored in result->m_runs in visual order. For LTR, we place + // the run to be inserted before the next run with a bigger character + // start index. For RTL, we place the run before the next run with a lower + // character index. Otherwise, for both directions, at the end. + if (HB_DIRECTION_IS_FORWARD(run->m_direction)) { + for (size_t pos = 0; pos < m_runs.size(); ++pos) { + if (m_runs.at(pos)->m_startIndex > run->m_startIndex) { + m_runs.insert(pos, run.release()); + break; + } + } + } else { + for (size_t pos = 0; pos < m_runs.size(); ++pos) { + if (m_runs.at(pos)->m_startIndex < run->m_startIndex) { + m_runs.insert(pos, run.release()); + break; + } + } + } + // If we didn't find an existing slot to place it, append. + if (run) + m_runs.append(run.release()); +} + } // namespace blink
diff --git a/third_party/WebKit/Source/platform/fonts/shaping/ShapeResult.h b/third_party/WebKit/Source/platform/fonts/shaping/ShapeResult.h index 8501b8e..bb00c3e 100644 --- a/third_party/WebKit/Source/platform/fonts/shaping/ShapeResult.h +++ b/third_party/WebKit/Source/platform/fonts/shaping/ShapeResult.h
@@ -40,6 +40,8 @@ #include "wtf/RefCounted.h" #include "wtf/Vector.h" +struct hb_buffer_t; + namespace blink { class Font; @@ -89,6 +91,8 @@ } void applySpacing(ShapeResultSpacing&, const TextRun&); + void insertRun(PassOwnPtr<ShapeResult::RunInfo>, unsigned startGlyph, + unsigned numGlyphs, hb_buffer_t*); float m_width; FloatRect m_glyphBoundingBox;
diff --git a/third_party/WebKit/Source/platform/heap/HeapTest.cpp b/third_party/WebKit/Source/platform/heap/HeapTest.cpp index adacd00..9b6cca4 100644 --- a/third_party/WebKit/Source/platform/heap/HeapTest.cpp +++ b/third_party/WebKit/Source/platform/heap/HeapTest.cpp
@@ -6405,7 +6405,7 @@ MutexLocker mainThreadMutexLocker(mainThreadMutex()); OwnPtr<WebThread> workerThread = adoptPtr(Platform::current()->createThread("Test Worker Thread")); DestructorLockingObject* object = nullptr; - workerThread->getWebTaskRunner()->postTask(BLINK_FROM_HERE, threadSafeBind(workerThreadMainForCrossThreadWeakPersistentTest, AllowCrossThreadAccessWrapper<DestructorLockingObject**>(&object))); + workerThread->getWebTaskRunner()->postTask(BLINK_FROM_HERE, threadSafeBind(workerThreadMainForCrossThreadWeakPersistentTest, AllowCrossThreadAccess(&object))); parkMainThread(); // Step 3: Set up a CrossThreadWeakPersistent.
diff --git a/third_party/WebKit/Tools/Scripts/webkitpy/common/system/executive.py b/third_party/WebKit/Tools/Scripts/webkitpy/common/system/executive.py index 81d9c12..fa82dd9 100644 --- a/third_party/WebKit/Tools/Scripts/webkitpy/common/system/executive.py +++ b/third_party/WebKit/Tools/Scripts/webkitpy/common/system/executive.py
@@ -391,7 +391,7 @@ # run_command automatically decodes to unicode() unless explicitly told not to. if decode_output: - output = output.decode(self._child_process_encoding()) + output = output.decode(self._child_process_encoding(), errors="replace") # wait() is not threadsafe and can throw OSError due to: # http://bugs.python.org/issue1731717
diff --git a/third_party/WebKit/Tools/Scripts/webkitpy/layout_tests/port/android.py b/third_party/WebKit/Tools/Scripts/webkitpy/layout_tests/port/android.py index 9f5565f5..9b00de40 100644 --- a/third_party/WebKit/Tools/Scripts/webkitpy/layout_tests/port/android.py +++ b/third_party/WebKit/Tools/Scripts/webkitpy/layout_tests/port/android.py
@@ -257,12 +257,10 @@ error_handler = None result = self._executive.run_command(self.adb_command() + command, - error_handler=error_handler, - decode_output=False, - debug_logging=self._debug_logging) + error_handler=error_handler, debug_logging=self._debug_logging) # We limit the length to avoid outputting too verbose commands, such as "adb logcat". - self._log_debug('Run adb result: ' + result[:80].decode('ascii', errors='replace')) + self._log_debug('Run adb result: ' + result[:80]) return result def get_serial(self): @@ -315,14 +313,12 @@ def _determine_adb_version(adb_command_path, executive, debug_logging): re_version = re.compile('^.*version ([\d\.]+)') try: - output = executive.run_command([adb_command_path, 'version'], - error_handler=executive.ignore_error, - decode_output=False, + output = executive.run_command([adb_command_path, 'version'], error_handler=executive.ignore_error, debug_logging=debug_logging) except OSError: return None - result = re_version.match(output.decode('ascii', errors='replace')) + result = re_version.match(output) if not output or not result: return None @@ -359,10 +355,8 @@ re_device = re.compile('^([a-zA-Z0-9_:.-]+)\tdevice$', re.MULTILINE) result = executive.run_command([AndroidCommands.adb_command_path(executive, debug_logging=self._debug_logging), 'devices'], - error_handler=executive.ignore_error, - decode_output=False, - debug_logging=self._debug_logging) - devices = re_device.findall(result.decode('ascii', errors='replace')) + error_handler=executive.ignore_error, debug_logging=self._debug_logging) + devices = re_device.findall(result) if not devices: return [] @@ -514,16 +508,14 @@ pids = self._executive.running_pids(lambda name: 'adb' in name) if not pids: # Apparently adb is not running, which is unusual. Running any adb command should start it. - self._executive.run_command(['adb', 'devices'], - decode_output=False) + self._executive.run_command(['adb', 'devices']) pids = self._executive.running_pids(lambda name: 'adb' in name) if not pids: _log.error("The adb daemon does not appear to be running.") return False for pid in pids: - self._executive.run_command(['taskset', '-p', '-c', '0', str(pid)], - decode_output=False) + self._executive.run_command(['taskset', '-p', '-c', '0', str(pid)]) if not result: _log.error('For complete Android build requirements, please see:') @@ -742,8 +734,7 @@ def _perf_version_string(self, perf_path): try: - return self._host.executive.run_command([perf_path, '--version'], - decode_output=False) + return self._host.executive.run_command([perf_path, '--version']) except: return None @@ -784,10 +775,9 @@ ] if perfhost_path: perfhost_args = [perfhost_path] + perfhost_report_command + ['--call-graph', 'none'] - perf_output = self._host.executive.run_command(perfhost_args, - decode_output=False) + perf_output = self._host.executive.run_command(perfhost_args) # We could save off the full -g report to a file if users found that useful. - _log.debug(self._first_ten_lines_of_profile(perf_output).decode('ascii', errors='replace')) + _log.debug(self._first_ten_lines_of_profile(perf_output)) else: _log.debug(""" Failed to find perfhost_linux binary, can't process samples from the device.
diff --git a/third_party/libjingle/BUILD.gn b/third_party/libjingle/BUILD.gn index b189c70..5b9bbe1 100644 --- a/third_party/libjingle/BUILD.gn +++ b/third_party/libjingle/BUILD.gn
@@ -415,7 +415,6 @@ "//third_party/webrtc", "//third_party/webrtc/modules/media_file", "//third_party/webrtc/modules/video_capture", - "//third_party/webrtc/modules/video_render", "//third_party/webrtc/system_wrappers", "//third_party/webrtc/voice_engine", ]
diff --git a/third_party/libjingle/README.chromium b/third_party/libjingle/README.chromium index b2e6977..a7accdf 100644 --- a/third_party/libjingle/README.chromium +++ b/third_party/libjingle/README.chromium
@@ -1,7 +1,7 @@ Name: libjingle URL: http://www.webrtc.org Version: unknown -Revision: 12501 +Revision: 12534 License: BSD License File: source/talk/COPYING Security Critical: yes
diff --git a/third_party/libjingle/libjingle.gyp b/third_party/libjingle/libjingle.gyp index d146e71..20403df 100644 --- a/third_party/libjingle/libjingle.gyp +++ b/third_party/libjingle/libjingle.gyp
@@ -365,7 +365,6 @@ '<(DEPTH)/third_party/usrsctp/usrsctp.gyp:usrsctplib', '<(DEPTH)/third_party/webrtc/modules/modules.gyp:media_file', '<(DEPTH)/third_party/webrtc/modules/modules.gyp:video_capture', - '<(DEPTH)/third_party/webrtc/modules/modules.gyp:video_render', '<(DEPTH)/third_party/webrtc/voice_engine/voice_engine.gyp:voice_engine', '<(DEPTH)/third_party/webrtc/webrtc.gyp:webrtc', 'libjingle',
diff --git a/third_party/libjingle/libjingle_nacl.gyp b/third_party/libjingle/libjingle_nacl.gyp index 46129c8..99dd667 100644 --- a/third_party/libjingle/libjingle_nacl.gyp +++ b/third_party/libjingle/libjingle_nacl.gyp
@@ -138,6 +138,7 @@ '<(webrtc_base)/network.h', '<(webrtc_base)/networkmonitor.cc', '<(webrtc_base)/networkmonitor.h', + '<(webrtc_base)/nullsocketserver.cc', '<(webrtc_base)/nullsocketserver.h', '<(webrtc_base)/openssladapter.cc', '<(webrtc_base)/openssldigest.cc',
diff --git a/third_party/qcms/README.chromium b/third_party/qcms/README.chromium index 98653d6..a62e37d 100644 --- a/third_party/qcms/README.chromium +++ b/third_party/qcms/README.chromium
@@ -151,6 +151,8 @@ - https://code.google.com/p/chromium/issues/detail?id=580917 - Fix build_output_lut to return correct data for parametric curves - https://bugs.chromium.org/p/chromium/issues/detail?id=600338 + - Make build_output_lut output 4096 points for parametric curves + - https://bugs.chromium.org/p/chromium/issues/detail?id=600338 For the Chromium changes, since the import, in a patch format run: git diff b8456f38 src
diff --git a/third_party/qcms/src/tests/qcms_test_output_trc.c b/third_party/qcms/src/tests/qcms_test_output_trc.c index 9f95a3b..771033f7 100644 --- a/third_party/qcms/src/tests/qcms_test_output_trc.c +++ b/third_party/qcms/src/tests/qcms_test_output_trc.c
@@ -40,7 +40,7 @@ } *size = qcms_transform_get_output_trc_rgba(transform, target, QCMS_TRC_USHORT, NULL); - assert(*size == 256); + assert(*size >= 256); *table = malloc(*size * sizeof(uint16_t) * 4); qcms_transform_get_output_trc_rgba(transform, target, QCMS_TRC_USHORT, *table); @@ -75,7 +75,7 @@ } *size = qcms_transform_get_input_trc_rgba(transform, source, QCMS_TRC_USHORT, NULL); - assert(*size == 256); + assert(*size >= 256); *table = calloc(*size, sizeof(uint16_t) * 4); qcms_transform_get_input_trc_rgba(transform, source, QCMS_TRC_USHORT, *table); @@ -96,7 +96,7 @@ { qcms_profile *profile; uint16_t *gamma_table_out; - size_t gamma_table_size; + size_t output_size; size_t i; printf("Test qcms output gamma curve table integrity.\n"); @@ -109,13 +109,13 @@ // Create profiles and transforms, get table and then free resources to make sure none // of the internal tables are initialized by previous calls. gamma_table_out = NULL; - gamma_table_size = 0; - if (get_output_gamma_table(in_path, &gamma_table_out, &gamma_table_size) != 0) { + output_size = 0; + if (get_output_gamma_table(in_path, &gamma_table_out, &output_size) != 0) { fprintf(stderr, "Unable to extract output gamma table\n"); return EXIT_FAILURE; } - printf("LUT size = %zu\n", gamma_table_size); + printf("Output gamma LUT size = %zu\n", output_size); profile = qcms_profile_from_path(in_path); if (!profile) { @@ -127,16 +127,17 @@ // Check only for red curve for now. if (profile->redTRC->type == PARAMETRIC_CURVE_TYPE) { int type = - (int)(profile->redTRC->count + 1); - FILE *gamma_file; uint16_t *gamma_table_in = NULL; - uint16_t *p_table_out, *p_table_in; - char file_name[256] = {0,}; size_t input_size = 0; + float scale_factor; + FILE *output_file; + char output_file_name[1024]; + long int time_stamp = (long int)time(NULL); printf("Detected parametric curve type = %d\n", profile->redTRC->count); - sprintf(file_name, "qcms-test-%ld-parametric-gamma-%s.csv", (long int)time(NULL), profile->description); - printf("Writing input and output gamma tables to %s\n", file_name); + sprintf(output_file_name, "qcms-test-%ld-parametric-gamma-output-%s.csv", time_stamp, profile->description); + printf("Writing output gamma tables to %s\n", output_file_name); printf("gamma = %.6f, a = %.6f, b = %.6f, c = %.6f, d = %.6f, e = %.6f, f = %.6f\n", profile->redTRC->parameter[0], profile->redTRC->parameter[1], profile->redTRC->parameter[2], @@ -144,44 +145,44 @@ profile->redTRC->parameter[6]); // Write output to stdout and tables into a csv file. - gamma_file = fopen(file_name, "w"); - fprintf(gamma_file, "Parametric gamma values for %s\n", profile->description); - fprintf(gamma_file, "gamma, a, b, c, d, e, f\n"); - fprintf(gamma_file, "%.6f, %.6f, %.6f, %.6f, %.6f, %.6f, %.6f\n", + output_file = fopen(output_file_name, "w"); + fprintf(output_file, "Parametric gamma values for %s\n", profile->description); + fprintf(output_file, "gamma, a, b, c, d, e, f\n"); + fprintf(output_file, "%.6f, %.6f, %.6f, %.6f, %.6f, %.6f, %.6f\n", profile->redTRC->parameter[0], profile->redTRC->parameter[1], profile->redTRC->parameter[2], profile->redTRC->parameter[3], profile->redTRC->parameter[4], profile->redTRC->parameter[5], profile->redTRC->parameter[6]); get_input_gamma_table(in_path, &gamma_table_in, &input_size); - assert(input_size == gamma_table_size); if (!gamma_table_in) { fprintf(stderr, "Unable to compute input trc. Aborting\n"); - fclose(gamma_file); + fclose(output_file); qcms_profile_release(profile); free(gamma_table_out); return EXIT_FAILURE; } - fprintf(gamma_file, "\n\nInput gamma, Output gamma, LCMS Output gamma, Output gamma error\n"); + scale_factor = (float)(output_size - 1) / (input_size - 1); - p_table_out = gamma_table_out; - p_table_in = gamma_table_in; + fprintf(output_file, "\nInput curve size: %zu\nOutput curve size: %zu\n", input_size, output_size); + fprintf(output_file, "\n\nInput gamma, Output gamma, LCMS Output gamma, Output gamma error\n"); - for (i = 0; i < gamma_table_size; ++i) { - float p = i / (gamma_table_size * 1.0); - float reference_out = clamp_float(evaluate_parametric_curve(type, profile->redTRC->parameter, p)); - float actual_out = *p_table_out * inverse65535; - float error_out = fabs(actual_out - reference_out); - float input = *p_table_in * inverse65535; + for (i = 0; i < input_size; ++i) { + float input = gamma_table_in[i * 4] * inverse65535; + size_t out_index = (size_t)floor(i * scale_factor + 0.5); + float p = out_index / (float)(output_size - 1); + float reference = clamp_float(evaluate_parametric_curve(type, profile->redTRC->parameter, p)); + float actual = gamma_table_out[out_index * 4] * inverse65535; + float difference = fabs(actual - reference); - fprintf(gamma_file, "%.6f, %.6f, %6f, %6f\n",input, actual_out, reference_out, error_out); - - p_table_out += 4; // Skip other channels. - p_table_in += 4; // Skip other channels. + fprintf(output_file, "%.6f, %.6f, %6f, %6f\n", input, actual, reference, difference); } + fprintf(output_file, "\nNote: the output curves we down sampled by a factor of %zu / %zu\n", + output_size, input_size); + + fclose(output_file); free(gamma_table_in); - fclose(gamma_file); } qcms_profile_release(profile);
diff --git a/third_party/qcms/src/transform_util.c b/third_party/qcms/src/transform_util.c index 3d84716e..3b2dcef7 100644 --- a/third_party/qcms/src/transform_util.c +++ b/third_party/qcms/src/transform_util.c
@@ -601,7 +601,7 @@ uint16_t i; uint16_t *output = malloc(sizeof(uint16_t)*256); uint16_t *inverted; - int inverted_size = 256; + int inverted_size = 4096; if (!output) { *output_gamma_lut = NULL; @@ -618,9 +618,6 @@ // measurement or data, however it is what lcms uses. // the maximum number we would need is 65535 because that's the // accuracy used for computing the pre cache table - if (inverted_size < 256) - inverted_size = 256; - inverted = invert_lut(output, 256, inverted_size); if (!inverted) return;
diff --git a/tools/android/loading/cloud/frontend/clovis_frontend.py b/tools/android/loading/cloud/frontend/clovis_frontend.py index ffef8be..42b7b09 100644 --- a/tools/android/loading/cloud/frontend/clovis_frontend.py +++ b/tools/android/loading/cloud/frontend/clovis_frontend.py
@@ -14,6 +14,7 @@ from common.clovis_task import ClovisTask import common.google_instance_helper +import email_helper from memory_logs import MemoryLogs @@ -33,7 +34,7 @@ 'log.html', body=message, log=memory_logs.Flush().split('\n')) -def PollWorkers(tag, start_time, timeout_hours): +def PollWorkers(tag, start_time, timeout_hours, email_address, task_url): """Checks if there are workers associated with tag, by polling the instance group. When all workers are finished, the instance group and the instance template are destroyed. @@ -46,10 +47,12 @@ start_time (float): Time when the polling started, as returned by time.time(). timeout_hours (int): Timeout after which workers are terminated. + email_address (str): Email address to notify when the task is complete. + task_url (str): URL where the results of the task can be found. """ if (time.time() - start_time) > (3600 * timeout_hours): clovis_logger.error('Worker timeout for tag %s, shuting down.' % tag) - deferred.defer(DeleteInstanceGroup, tag) + Finalize(tag, email_address, 'TIMEOUT', task_url) return clovis_logger.info('Polling workers for tag: ' + tag) @@ -60,10 +63,26 @@ if live_instance_count > 0 or live_instance_count == -1: clovis_logger.info('Retry later, instances still alive for tag: ' + tag) poll_interval_minutes = 10 - deferred.defer(PollWorkers, tag, start_time, + deferred.defer(PollWorkers, tag, start_time, email_address, task_url, _countdown=(60 * poll_interval_minutes)) return + Finalize(tag, email_address, 'SUCCESS', task_url) + + +def Finalize(tag, email_address, status, task_url): + """Cleans up the remaining ComputeEngine resources and notifies the user. + + Args: + tag (str): Tag of the task to finalize. + email_address (str): Email address of the user to be notified. + status (str): Status of the task, indicating the success or the cause of + failure. + task_url (str): URL where the results of the task can be found. + """ + email_helper.SendEmailTaskComplete( + to_address=email_address, tag=tag, status=status, task_url=task_url, + logger=clovis_logger) clovis_logger.info('Scheduling instance group destruction for tag: ' + tag) deferred.defer(DeleteInstanceGroup, tag) @@ -142,7 +161,11 @@ # Split the task in smaller tasks. sub_tasks = [] + task_url = None if task.Action() == 'trace': + bucket = task.BackendParams().get('storage_bucket') + if bucket: + task_url = 'https://console.cloud.google.com/storage/' + bucket sub_tasks = SplitTraceTask(task) else: error_string = 'Unsupported action: %s.' % task.Action() @@ -160,10 +183,14 @@ clovis_logger.info('Creating worker polling task.') first_poll_delay_minutes = 10 timeout_hours = task.BackendParams().get('timeout_hours', 5) - deferred.defer(PollWorkers, task_tag, time.time(), timeout_hours, - _countdown=(60 * first_poll_delay_minutes)) + user_email = email_helper.GetUserEmail() + deferred.defer(PollWorkers, task_tag, time.time(), timeout_hours, user_email, + task_url, _countdown=(60 * first_poll_delay_minutes)) - return Render('Success', memory_logs) + return Render(flask.Markup( + 'Success!<br>Your task %s has started.<br>' + 'You will be notified at %s when completed.') % (task_tag, user_email), + memory_logs) def SplitTraceTask(task):
diff --git a/tools/android/loading/cloud/frontend/email_helper.py b/tools/android/loading/cloud/frontend/email_helper.py new file mode 100644 index 0000000..dd82ee7 --- /dev/null +++ b/tools/android/loading/cloud/frontend/email_helper.py
@@ -0,0 +1,42 @@ +# Copyright 2016 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. + +from google.appengine.api import (mail, users) + + +def GetUserEmail(): + """Returns the email address of the user currently making the request or None. + """ + user = users.get_current_user() + if user: + return user.email() + return None + + +def SendEmailTaskComplete(to_address, tag, status, task_url, logger): + """Sends an email to to_address notifying that the task identified by tag is + complete. + + Args: + to_address (str): The email address to notify. + tag (str): The tag of the task. + status (str): Status of the task. + task_url (str): URL where the results of the task can be found. + logger (logging.logger): Used for logging. + """ + if not to_address: + logger.error('No email address to notify for task ' + tag) + return + + logger.info('Notify task %s complete to %s.' % (tag, to_address)) + # The sender address must be in the "Email API authorized senders", configured + # in the Application Settings of AppEngine. + sender_address = 'clovis-noreply@google.com' + subject = 'Task %s complete' % tag + body = 'Your Clovis task %s is now complete with status: %s.' % (tag, status) + if task_url: + body += '\nCheck the results at ' + task_url + mail.send_mail(sender=sender_address, to=to_address, subject=subject, + body=body) +
diff --git a/tools/android/loading/controller.py b/tools/android/loading/controller.py index d8c20e01..8a2d4a6 100644 --- a/tools/android/loading/controller.py +++ b/tools/android/loading/controller.py
@@ -324,6 +324,8 @@ child processes used to run Chrome and XVFB.""" chrome_cmd = [OPTIONS.local_binary] chrome_cmd.extend(self._GetChromeArguments()) + # Force use of simple cache. + chrome_cmd.append('--use-simple-cache-backend=on') chrome_cmd.append('--user-data-dir=%s' % self._profile_dir) chrome_cmd.extend(['--enable-logging=stderr', '--v=1']) # Navigates to about:blank for couples of reasons:
diff --git a/tools/android/loading/prefetch_view.py b/tools/android/loading/prefetch_view.py index 0df9025b..cbd882a 100644 --- a/tools/android/loading/prefetch_view.py +++ b/tools/android/loading/prefetch_view.py
@@ -52,7 +52,7 @@ if trace is None: return requests = trace.request_track.GetEvents() - critical_requests_ids = user_lens.CriticalRequests() + critical_requests_ids = user_lens.CriticalRequestIds() self.postload_msec = user_lens.PostloadTimeMsec() self.graph = dependency_graph.RequestDependencyGraph( requests, dependencies_lens, node_class=RequestNode)
diff --git a/tools/android/loading/request_track.py b/tools/android/loading/request_track.py index b4e3a15..8bd62da 100644 --- a/tools/android/loading/request_track.py +++ b/tools/android/loading/request_track.py
@@ -12,6 +12,7 @@ import copy import datetime import email.utils +import hashlib import json import logging import re @@ -213,6 +214,12 @@ return None return self.start_msec + self.timing.LargestOffset() + @property + def fingerprint(self): + h = hashlib.sha256() + h.update(self.url) + return h.hexdigest()[:10] + def _TimestampOffsetFromStartMs(self, timestamp): assert self.timing.request_time != -1 request_time = self.timing.request_time
diff --git a/tools/android/loading/sandwich.py b/tools/android/loading/sandwich.py index 6dda5d0..d7ec1a1a 100755 --- a/tools/android/loading/sandwich.py +++ b/tools/android/loading/sandwich.py
@@ -44,6 +44,9 @@ # Use options layer to access constants. OPTIONS = options.OPTIONS +_SPEED_INDEX_MEASUREMENT = 'speed-index' +_MEMORY_MEASUREMENT = 'memory' + def _ArgumentParser(): """Build a command line argument's parser.""" @@ -179,6 +182,9 @@ parents=[common_job_parser, task_parser], help='Run all steps using the task manager ' 'infrastructure.') + run_all.add_argument('-m', '--measure', default=[], dest='optional_measures', + choices=[_SPEED_INDEX_MEASUREMENT, _MEMORY_MEASUREMENT], + nargs='+', help='Enable optional measurements.') run_all.add_argument('-g', '--gen-full', action='store_true', help='Generate the full graph with all possible' 'benchmarks.') @@ -281,31 +287,37 @@ builder = sandwich_task_builder.SandwichTaskBuilder( output_directory=args.output, android_device=android_device, - job_path=args.job, - url_repeat=args.url_repeat) + job_path=args.job) if args.wpr_archive_path: builder.OverridePathToWprArchive(args.wpr_archive_path) else: builder.PopulateWprRecordingTask() builder.PopulateCommonPipelines() - runner_transformer_name = 'no-network-emulation' - runner_transformer = lambda arg: None + def MainTransformer(runner): + runner.record_video = _SPEED_INDEX_MEASUREMENT in args.optional_measures + runner.record_memory_dumps = _MEMORY_MEASUREMENT in args.optional_measures + runner.job_repeat = args.url_repeat + + transformer_list_name = 'no-network-emulation' builder.PopulateLoadBenchmark(sandwich_misc.EMPTY_CACHE_DISCOVERER, - runner_transformer_name, runner_transformer) + transformer_list_name, + transformer_list=[MainTransformer]) builder.PopulateLoadBenchmark(sandwich_misc.FULL_CACHE_DISCOVERER, - runner_transformer_name, runner_transformer) + transformer_list_name, + transformer_list=[MainTransformer]) if args.gen_full: - for subresource_discoverer in sandwich_misc.SUBRESOURCE_DISCOVERERS: - if subresource_discoverer == sandwich_misc.FULL_CACHE_DISCOVERER: - continue - for network_condition in ['Regular4G', 'Regular3G', 'Regular2G']: - runner_transformer_name = network_condition.lower() - runner_transformer = sandwich_task_builder.NetworkSimulationTransformer( - network_condition) - builder.PopulateLoadBenchmark( - subresource_discoverer, runner_transformer_name, runner_transformer) + for network_condition in ['Regular4G', 'Regular3G', 'Regular2G']: + transformer_list_name = network_condition.lower() + network_transformer = \ + sandwich_task_builder.NetworkSimulationTransformer(network_condition) + transformer_list = [MainTransformer, network_transformer] + for subresource_discoverer in sandwich_misc.SUBRESOURCE_DISCOVERERS: + if subresource_discoverer == sandwich_misc.FULL_CACHE_DISCOVERER: + continue + builder.PopulateLoadBenchmark(subresource_discoverer, + transformer_list_name, transformer_list) return task_manager.ExecuteWithCommandLine( args, builder.tasks.values(), builder.default_final_tasks)
diff --git a/tools/android/loading/sandwich_metrics.py b/tools/android/loading/sandwich_metrics.py index 1324b75..339cf72 100644 --- a/tools/android/loading/sandwich_metrics.py +++ b/tools/android/loading/sandwich_metrics.py
@@ -43,6 +43,8 @@ 'net_emul.upload', 'net_emul.latency'] +_UNAVAILABLE_CSV_VALUE = 'unavailable' + _TRACKED_EVENT_NAMES = set(['requestStart', 'loadEventStart', 'loadEventEnd']) # Points of a completeness record. @@ -81,6 +83,7 @@ Returns: List of memory dump events. """ + assert sandwich_runner.MEMORY_DUMP_CATEGORY in tracing_track.Categories() browser_pid = _GetBrowserPID(tracing_track) browser_dumps_events = [] for event in tracing_track.GetEvents(): @@ -130,8 +133,8 @@ return tracked_events -def _ExtractMetricsFromLoadingTrace(loading_trace): - """Pulls all the metrics from a given trace. +def _ExtractDefaultMetrics(loading_trace): + """Extracts all the default metrics from a given trace. Args: loading_trace: loading_trace_module.LoadingTrace. @@ -139,15 +142,32 @@ Returns: Dictionary with all trace extracted fields set. """ - assert all( - cat in loading_trace.tracing_track.Categories() - for cat in sandwich_runner.ADDITIONAL_CATEGORIES), ( - 'This trace was not generated with the required set of categories ' - 'to be processed by this script.') - browser_dump_events = _GetBrowserDumpEvents(loading_trace.tracing_track) web_page_tracked_events = _GetWebPageTrackedEvents( loading_trace.tracing_track) + return { + 'total_load': (web_page_tracked_events['loadEventEnd'].start_msec - + web_page_tracked_events['requestStart'].start_msec), + 'js_onload_event': (web_page_tracked_events['loadEventEnd'].start_msec - + web_page_tracked_events['loadEventStart'].start_msec) + } + +def _ExtractMemoryMetrics(loading_trace): + """Extracts all the memory metrics from a given trace. + + Args: + loading_trace: loading_trace_module.LoadingTrace. + + Returns: + Dictionary with all trace extracted fields set. + """ + if (sandwich_runner.MEMORY_DUMP_CATEGORY not in + loading_trace.tracing_track.Categories()): + return { + 'browser_malloc_avg': _UNAVAILABLE_CSV_VALUE, + 'browser_malloc_max': _UNAVAILABLE_CSV_VALUE + } + browser_dump_events = _GetBrowserDumpEvents(loading_trace.tracing_track) browser_malloc_sum = 0 browser_malloc_max = 0 for dump_event in browser_dump_events: @@ -156,12 +176,7 @@ size = int(attr['value'], 16) browser_malloc_sum += size browser_malloc_max = max(browser_malloc_max, size) - return { - 'total_load': (web_page_tracked_events['loadEventEnd'].start_msec - - web_page_tracked_events['requestStart'].start_msec), - 'js_onload_event': (web_page_tracked_events['loadEventEnd'].start_msec - - web_page_tracked_events['loadEventStart'].start_msec), 'browser_malloc_avg': browser_malloc_sum / float(len(browser_dump_events)), 'browser_malloc_max': browser_malloc_max } @@ -239,14 +254,15 @@ logging.info('processing trace \'%s\'' % trace_path) loading_trace = loading_trace_module.LoadingTrace.FromJsonFile(trace_path) run_metrics = {'url': loading_trace.url} - run_metrics.update(_ExtractMetricsFromLoadingTrace(loading_trace)) + run_metrics.update(_ExtractDefaultMetrics(loading_trace)) + run_metrics.update(_ExtractMemoryMetrics(loading_trace)) video_path = os.path.join(run_directory_path, 'video.mp4') if os.path.isfile(video_path): logging.info('processing speed-index video \'%s\'' % video_path) completeness_record = _ExtractCompletenessRecordFromVideo(video_path) run_metrics['speed_index'] = ComputeSpeedIndex(completeness_record) else: - run_metrics['speed_index'] = 'disabled' + run_metrics['speed_index'] = _UNAVAILABLE_CSV_VALUE for key, value in loading_trace.metadata['network_emulation'].iteritems(): run_metrics['net_emul.' + key] = value return run_metrics
diff --git a/tools/android/loading/sandwich_metrics_unittest.py b/tools/android/loading/sandwich_metrics_unittest.py index 73c8f3e..e7553bc3 100644 --- a/tools/android/loading/sandwich_metrics_unittest.py +++ b/tools/android/loading/sandwich_metrics_unittest.py
@@ -19,7 +19,7 @@ _BLINK_CAT = 'blink.user_timing' -_MEM_CAT = 'disabled-by-default-memory-infra' +_MEM_CAT = sandwich_runner.MEMORY_DUMP_CATEGORY _START='requestStart' _LOADS='loadEventStart' _LOADE='loadEventEnd' @@ -48,7 +48,7 @@ return tracing.TracingTrack.FromJsonDict({ 'events': events, 'categories': (tracing.INITIAL_CATEGORIES + - sandwich_runner.ADDITIONAL_CATEGORIES)}) + (sandwich_runner.MEMORY_DUMP_CATEGORY,))}) def LoadingTrace(events): @@ -107,8 +107,6 @@ {'pid': 354, 'ts': 11000, 'cat': 'whatever0', 'ph': 'R'}, {'pid': 672, 'ts': 12000, 'cat': _MEM_CAT, 'ph': 'v', 'name': NAME}] - self.assertTrue(_MEM_CAT in sandwich_runner.ADDITIONAL_CATEGORIES) - bump_events = RunHelper(TRACE_EVENTS, 123) self.assertEquals(2, len(bump_events)) self.assertEquals(5, bump_events[0].start_msec) @@ -187,12 +185,17 @@ self.assertEquals(17, trace_events['loadEventStart'].start_msec) self.assertEquals(19, trace_events['loadEventEnd'].start_msec) - def testPullMetricsFromLoadingTrace(self): - metrics = puller._ExtractMetricsFromLoadingTrace(LoadingTrace( + def testExtractDefaultMetrics(self): + metrics = puller._ExtractDefaultMetrics(LoadingTrace( _MINIMALIST_TRACE_EVENTS)) - self.assertEquals(4, len(metrics)) + self.assertEquals(2, len(metrics)) self.assertEquals(20, metrics['total_load']) self.assertEquals(5, metrics['js_onload_event']) + + def testExtractMemoryMetrics(self): + metrics = puller._ExtractMemoryMetrics(LoadingTrace( + _MINIMALIST_TRACE_EVENTS)) + self.assertEquals(2, len(metrics)) self.assertEquals(30971, metrics['browser_malloc_avg']) self.assertEquals(55044, metrics['browser_malloc_max'])
diff --git a/tools/android/loading/sandwich_runner.py b/tools/android/loading/sandwich_runner.py index 3a56b59..3dc0415 100644 --- a/tools/android/loading/sandwich_runner.py +++ b/tools/android/loading/sandwich_runner.py
@@ -26,9 +26,8 @@ TRACE_FILENAME = 'trace.json' VIDEO_FILENAME = 'video.mp4' -# List of selected trace event categories when running chrome. -ADDITIONAL_CATEGORIES = ( - 'disabled-by-default-memory-infra',) # Used by _GetBrowserDumpEvents() +# Memory dump category used to get memory metrics. +MEMORY_DUMP_CATEGORY = 'disabled-by-default-memory-infra' _JOB_SEARCH_PATH = 'sandwich_jobs' @@ -124,6 +123,9 @@ # Configures whether to record speed-index video. self.record_video = False + # Configures whether to record memory dumps. + self.record_memory_dumps = False + # Path to the WPR archive to load or save. Is str or None. self.wpr_archive_path = None @@ -189,13 +191,17 @@ os.makedirs(run_path) self._chrome_ctl.SetNetworkEmulation( self._GetEmulatorNetworkCondition('browser')) + additional_categories = [] + if self.record_memory_dumps: + additional_categories = [MEMORY_DUMP_CATEGORY] # TODO(gabadie): add a way to avoid recording a trace. with self._chrome_ctl.Open() as connection: if clear_cache: connection.ClearCache() if run_path is not None and self.record_video: device = self._chrome_ctl.GetDevice() - assert device, 'Can only record video on a remote device.' + if device is None: + raise RuntimeError('Can only record video on a remote device.') video_recording_path = os.path.join(run_path, VIDEO_FILENAME) with device_setup.RemoteSpeedIndexRecorder(device, connection, video_recording_path): @@ -203,14 +209,14 @@ url=url, connection=connection, chrome_metadata=self._chrome_ctl.ChromeMetadata(), - additional_categories=ADDITIONAL_CATEGORIES, + additional_categories=additional_categories, timeout_seconds=_DEVTOOLS_TIMEOUT) else: trace = loading_trace.LoadingTrace.RecordUrlNavigation( url=url, connection=connection, chrome_metadata=self._chrome_ctl.ChromeMetadata(), - additional_categories=ADDITIONAL_CATEGORIES, + additional_categories=additional_categories, timeout_seconds=_DEVTOOLS_TIMEOUT) if run_path is not None: trace_path = os.path.join(run_path, TRACE_FILENAME)
diff --git a/tools/android/loading/sandwich_task_builder.py b/tools/android/loading/sandwich_task_builder.py index 954c67e..ea763ecb 100644 --- a/tools/android/loading/sandwich_task_builder.py +++ b/tools/android/loading/sandwich_task_builder.py
@@ -37,7 +37,7 @@ """A builder for a graph of tasks, each prepares or invokes a SandwichRunner. """ - def __init__(self, output_directory, android_device, job_path, url_repeat): + def __init__(self, output_directory, android_device, job_path): """Constructor. Args: @@ -45,13 +45,10 @@ android_device: The android DeviceUtils to run sandwich on or None to run it locally. job_path: Path of the sandwich's job. - url_repeat: Non null integer controlling how many times the URLs should be - repeated in the benchmarks. """ task_manager.Builder.__init__(self, output_directory) self._android_device = android_device self._job_path = job_path - self._url_repeat = url_repeat self._default_final_tasks = [] self._original_wpr_task = None @@ -159,20 +156,20 @@ return ValidateReferenceCache def PopulateLoadBenchmark(self, subresource_discoverer, - runner_transformer_name, runner_transformer): + transformer_list_name, transformer_list): """Populate benchmarking tasks from its setup tasks. Args: subresource_discoverer: Name of a subresources discoverer. - runner_transformer: A function that takes an instance of SandwichRunner as - parameter, would be applied immediately before SandwichRunner.Run(). - runner_transformer_name: Name of the runner transformer used to generate - task names. - benchmark_name: The benchmark's name for that runner modifier. + transformer_list_name: A string describing the transformers, will be used + in Task names (prefer names without spaces and special characters). + transformer_list: An ordered list of function that takes an instance of + SandwichRunner as parameter, would be applied immediately before + SandwichRunner.Run() in the given order. Here is the full dependency of the added tree for the returned task: - <runner_transformer_name>/<subresource_discoverer>-metrics.csv - depends on: <runner_transformer_name>/<subresource_discoverer>-run/ + <transformer_list_name>/<subresource_discoverer>-metrics.csv + depends on: <transformer_list_name>/<subresource_discoverer>-run/ depends on: common/<subresource_discoverer>-cache.zip depends on: some tasks saved by PopulateCommonPipelines() depends on: common/<subresource_discoverer>-setup.json @@ -180,12 +177,12 @@ Returns: task_manager.Task for - <runner_transformer_name>/<subresource_discoverer>-metrics.csv + <transformer_list_name>/<subresource_discoverer>-metrics.csv """ assert subresource_discoverer in sandwich_misc.SUBRESOURCE_DISCOVERERS assert 'common' not in sandwich_misc.SUBRESOURCE_DISCOVERERS shared_task_prefix = os.path.join('common', subresource_discoverer) - task_prefix = os.path.join(runner_transformer_name, subresource_discoverer) + task_prefix = os.path.join(transformer_list_name, subresource_discoverer) @self.RegisterTask(shared_task_prefix + '-setup.json', merge=True, dependencies=[self._subresources_for_urls_task]) @@ -221,9 +218,8 @@ dependencies=[BuildBenchmarkCacheArchive]) def RunBenchmark(): runner = self._CreateSandwichRunner() - # runner.record_video = True - runner.job_repeat = self._url_repeat - runner_transformer(runner) + for transformer in transformer_list: + transformer(runner) runner.wpr_archive_path = self._patched_wpr_task.path runner.wpr_out_log_path = os.path.join(RunBenchmark.path, 'wpr.log') runner.cache_archive_path = BuildBenchmarkCacheArchive.path
diff --git a/tools/android/loading/test_utils.py b/tools/android/loading/test_utils.py index 8f61969..10385b5 100644 --- a/tools/android/loading/test_utils.py +++ b/tools/android/loading/test_utils.py
@@ -221,7 +221,7 @@ return response -class MockUserSatisfiedLens(user_satisfied_lens._UserSatisfiedLens): +class MockUserSatisfiedLens(user_satisfied_lens._FirstEventLens): def _CalculateTimes(self, _): self._satisfied_msec = float('inf') self._event_msec = float('inf')
diff --git a/tools/android/loading/tracing.py b/tools/android/loading/tracing.py index 068c5b6b..55009a63 100644 --- a/tools/android/loading/tracing.py +++ b/tools/android/loading/tracing.py
@@ -92,10 +92,26 @@ def GetMatchingMainFrameEvents(self, category, name): """Gets events matching |category| and |name| that occur in the main frame. - Assumes that the events in question have a 'frame' key in their |args|.""" + + Events without a 'frame' key in their |args| are discarded. + """ matching_events = self.GetMatchingEvents(category, name) return [e for e in matching_events - if e.args['frame'] == self._GetMainFrameID()] + if 'frame' in e.args and e.args['frame'] == self.GetMainFrameID()] + + def GetMainFrameID(self): + """Returns the main frame ID.""" + if not self._main_frame_id: + navigation_start_events = [e for e in self.GetEvents() + if e.Matches('blink.user_timing', 'navigationStart')] + first_event = min(navigation_start_events, key=lambda e: e.start_msec) + self._main_frame_id = first_event.args['frame'] + + return self._main_frame_id + + def SetMainFrameID(self, frame_id): + """Set the main frame ID. Normally this is used only for testing.""" + self._main_frame_id = frame_id def EventsAt(self, msec): """Gets events active at a timestamp. @@ -197,16 +213,6 @@ return event return None - def _GetMainFrameID(self): - """Returns the main frame ID.""" - if not self._main_frame_id: - navigation_start_events = [e for e in self.GetEvents() - if e.Matches('blink.user_timing', 'navigationStart')] - first_event = min(navigation_start_events, key=lambda e: e.start_msec) - self._main_frame_id = first_event.args['frame'] - - return self._main_frame_id - def _IndexEvents(self, strict=False): if self._interval_tree: return
diff --git a/tools/android/loading/tracing_unittest.py b/tools/android/loading/tracing_unittest.py index cce5809..95acef8 100644 --- a/tools/android/loading/tracing_unittest.py +++ b/tools/android/loading/tracing_unittest.py
@@ -309,7 +309,7 @@ 'args': {'frame': _MAIN_FRAME_ID}}, ] self._HandleEvents(events) - self.assertEquals(_MAIN_FRAME_ID, self.track._GetMainFrameID()) + self.assertEquals(_MAIN_FRAME_ID, self.track.GetMainFrameID()) def testGetMatchingEvents(self): _MAIN_FRAME_ID = 0xffff
diff --git a/tools/android/loading/user_satisfied_lens.py b/tools/android/loading/user_satisfied_lens.py index dd99d79..523a240e 100644 --- a/tools/android/loading/user_satisfied_lens.py +++ b/tools/android/loading/user_satisfied_lens.py
@@ -6,6 +6,9 @@ Several lenses are defined, for example FirstTextPaintLens and FirstSignificantPaintLens. + +When run from the command line, takes a lens name and a trace, and prints the +fingerprints of the critical resources to stdout. """ import logging import operator @@ -24,6 +27,53 @@ _ATTRS = ['_satisfied_msec', '_event_msec', '_postload_msec', '_critical_request_ids'] + def CriticalRequests(self): + """Critical requests. + + Returns: + A sequence of request_track.Request objects representing an estimate of + all requests that are necessary for the user satisfaction defined by this + class. + """ + raise NotImplementedError + + def CriticalRequestIds(self): + """Ids of critical requests.""" + return set(rq.request_id for rq in self.CriticalRequests()) + + def CriticalFingerprints(self): + """Fingerprints of critical requests.""" + return set(rq.fingerprint for rq in self.CriticalRequests()) + + def PostloadTimeMsec(self): + """Return postload time. + + The postload time is an estimate of the amount of time needed by chrome to + transform the critical results into the satisfying event. + + Returns: + Postload time in milliseconds. + """ + return 0 + + +class RequestFingerprintLens(_UserSatisfiedLens): + """A lens built using requests in a trace that match a set of fingerprints.""" + def __init__(self, trace, fingerprints): + fingerprints = set(fingerprints) + self._critical_requests = [rq for rq in trace.request_track.GetEvents() + if rq.fingerprint in fingerprints] + + def CriticalRequests(self): + """Ids of critical requests.""" + return set(self._critical_requests) + + +class _FirstEventLens(_UserSatisfiedLens): + """Helper abstract subclass that defines users first event manipulations.""" + # pylint can't handle abstract subclasses. + # pylint: disable=abstract-method + def __init__(self, trace): """Initialize the lens. @@ -36,34 +86,23 @@ self._critical_request_ids = None if trace is None: return - self._CalculateTimes(trace.tracing_track) - critical_requests = self._RequestsBefore( + self._CalculateTimes(trace) + self._critical_requests = self._RequestsBefore( trace.request_track, self._satisfied_msec) - self._critical_request_ids = set(rq.request_id for rq in critical_requests) - if critical_requests: - last_load = max(rq.end_msec for rq in critical_requests) + self._critical_request_ids = set(rq.request_id + for rq in self._critical_requests) + if self._critical_requests: + last_load = max(rq.end_msec for rq in self._critical_requests) else: last_load = float('inf') self._postload_msec = self._event_msec - last_load def CriticalRequests(self): - """Request ids of critical requests. - - Returns: - A set of request ids (as strings) of an estimate of all requests that are - necessary for the user satisfaction defined by this class. - """ - return self._critical_request_ids + """Override.""" + return self._critical_requests def PostloadTimeMsec(self): - """Return postload time. - - The postload time is an estimate of the amount of time needed by chrome to - transform the critical results into the satisfying event. - - Returns: - Postload time in milliseconds. - """ + """Override.""" return self._postload_msec def ToJsonDict(self): @@ -75,7 +114,7 @@ return common_util.DeserializeAttributesFromJsonDict( json_dict, result, cls._ATTRS) - def _CalculateTimes(self, tracing_track): + def _CalculateTimes(self, trace): """Subclasses should implement to set _satisfied_msec and _event_msec.""" raise NotImplementedError @@ -84,26 +123,19 @@ return [rq for rq in request_track.GetEvents() if rq.end_msec <= time_ms] - -class _FirstEventLens(_UserSatisfiedLens): - """Helper abstract subclass that defines users first event manipulations.""" - # pylint can't handle abstract subclasses. - # pylint: disable=abstract-method - @classmethod def _CheckCategory(cls, tracing_track, category): assert category in tracing_track.Categories(), ( 'The "%s" category must be enabled.' % category) @classmethod - def _ExtractFirstTiming(cls, times): + def _ExtractBestTiming(cls, times): if not times: return float('inf') - if len(times) != 1: - # TODO(mattcary): in some cases a trace has two first paint events. Why? - logging.error('%d %s with spread of %s', len(times), - str(cls), max(times) - min(times)) - return float(min(times)) + assert len(times) == 1, \ + 'Unexpected duplicate {}: {} with spread of {}'.format( + str(cls), len(times), max(times) - min(times)) + return float(max(times)) class FirstTextPaintLens(_FirstEventLens): @@ -112,12 +144,13 @@ This event is taken directly from a trace. """ _EVENT_CATEGORY = 'blink.user_timing' - def _CalculateTimes(self, tracing_track): - self._CheckCategory(tracing_track, self._EVENT_CATEGORY) - first_paints = [e.start_msec for e in tracing_track.GetEvents() - if e.Matches(self._EVENT_CATEGORY, 'firstPaint')] + def _CalculateTimes(self, trace): + self._CheckCategory(trace.tracing_track, self._EVENT_CATEGORY) + first_paints = [ + e.start_msec for e in trace.tracing_track.GetMatchingMainFrameEvents( + 'blink.user_timing', 'firstPaint')] self._satisfied_msec = self._event_msec = \ - self._ExtractFirstTiming(first_paints) + self._ExtractBestTiming(first_paints) class FirstContentfulPaintLens(_FirstEventLens): @@ -127,12 +160,13 @@ by filtering out things like background paint from firstPaint. """ _EVENT_CATEGORY = 'blink.user_timing' - def _CalculateTimes(self, tracing_track): - self._CheckCategory(tracing_track, self._EVENT_CATEGORY) - first_paints = [e.start_msec for e in tracing_track.GetEvents() - if e.Matches(self._EVENT_CATEGORY, 'firstContentfulPaint')] + def _CalculateTimes(self, trace): + self._CheckCategory(trace.tracing_track, self._EVENT_CATEGORY) + first_paints = [ + e.start_msec for e in trace.tracing_track.GetMatchingMainFrameEvents( + 'blink.user_timing', 'firstContentfulPaint')] self._satisfied_msec = self._event_msec = \ - self._ExtractFirstTiming(first_paints) + self._ExtractBestTiming(first_paints) class FirstSignificantPaintLens(_FirstEventLens): @@ -143,12 +177,18 @@ that is the observable event. """ _FIRST_LAYOUT_COUNTER = 'LayoutObjectsThatHadNeverHadLayout' - _EVENT_CATEGORY = 'disabled-by-default-blink.debug.layout' - def _CalculateTimes(self, tracing_track): - self._CheckCategory(tracing_track, self._EVENT_CATEGORY) + _EVENT_CATEGORIES = ['blink', 'disabled-by-default-blink.debug.layout'] + def _CalculateTimes(self, trace): + for cat in self._EVENT_CATEGORIES: + self._CheckCategory(trace.tracing_track, cat) sync_paint_times = [] layouts = [] # (layout item count, msec). - for e in tracing_track.GetEvents(): + for e in trace.tracing_track.GetEvents(): + if ('frame' in e.args and + e.args['frame'] != trace.tracing_track.GetMainFrameID()): + continue + # If we don't know have a frame id, we assume it applies to all events. + # TODO(mattcary): is this the right paint event? Check if synchronized # paints appear at the same time as the first*Paint events, above. if e.Matches('blink', 'FrameView::synchronizedPaint'): @@ -158,7 +198,25 @@ layouts.append((e.args['counters'][self._FIRST_LAYOUT_COUNTER], e.start_msec)) assert layouts, 'No layout events' + assert sync_paint_times,'No sync paint times' layouts.sort(key=operator.itemgetter(0), reverse=True) self._satisfied_msec = layouts[0][1] - self._event_msec = self._ExtractFirstTiming([ - min(t for t in sync_paint_times if t > self._satisfied_msec)]) + self._event_msec = min(t for t in sync_paint_times + if t > self._satisfied_msec) + + +def main(lens_name, trace_file): + assert (lens_name in globals() and + not lens_name.startswith('_') and + lens_name.endswith('Lens')), 'Bad lens %s' % lens_name + lens_cls = globals()[lens_name] + trace = loading_trace.LoadingTrace.FromJsonFile(trace_file) + lens = lens_cls(trace) + for fp in sorted(lens.CriticalFingerprints()): + print fp + + +if __name__ == '__main__': + import sys + import loading_trace + main(sys.argv[1], sys.argv[2])
diff --git a/tools/android/loading/user_satisfied_lens_unittest.py b/tools/android/loading/user_satisfied_lens_unittest.py index c7cdb102..c603bbe5 100644 --- a/tools/android/loading/user_satisfied_lens_unittest.py +++ b/tools/android/loading/user_satisfied_lens_unittest.py
@@ -32,51 +32,65 @@ return rq def testFirstContentfulPaintLens(self): + MAINFRAME = 1 + SUBFRAME = 2 loading_trace = test_utils.LoadingTraceFromEvents( [self._RequestAt(1), self._RequestAt(10), self._RequestAt(20)], trace_events=[{'ts': 0, 'ph': 'I', 'cat': 'blink.some_other_user_timing', 'name': 'firstContentfulPaint'}, - {'ts': 9 * self.MILLI_TO_MICRO, 'ph': 'I', + {'ts': 30 * self.MILLI_TO_MICRO, 'ph': 'I', 'cat': 'blink.user_timing', 'name': 'firstDiscontentPaint'}, + {'ts': 5 * self.MILLI_TO_MICRO, 'ph': 'I', + 'cat': 'blink.user_timing', + 'name': 'firstContentfulPaint', + 'args': {'frame': SUBFRAME} }, {'ts': 12 * self.MILLI_TO_MICRO, 'ph': 'I', 'cat': 'blink.user_timing', - 'name': 'firstContentfulPaint'}, - {'ts': 22 * self.MILLI_TO_MICRO, 'ph': 'I', - 'cat': 'blink.user_timing', - 'name': 'firstContentfulPaint'}]) + 'name': 'firstContentfulPaint', + 'args': {'frame': MAINFRAME}}]) + loading_trace.tracing_track.SetMainFrameID(MAINFRAME) lens = user_satisfied_lens.FirstContentfulPaintLens(loading_trace) - self.assertEqual(set(['0.1', '0.2']), lens.CriticalRequests()) + self.assertEqual(set(['0.1', '0.2']), lens.CriticalRequestIds()) self.assertEqual(1, lens.PostloadTimeMsec()) def testCantGetNoSatisfaction(self): + MAINFRAME = 1 loading_trace = test_utils.LoadingTraceFromEvents( [self._RequestAt(1), self._RequestAt(10), self._RequestAt(20)], trace_events=[{'ts': 0, 'ph': 'I', 'cat': 'not_my_cat', - 'name': 'someEvent'}]) + 'name': 'someEvent', + 'args': {'frame': MAINFRAME}}]) + loading_trace.tracing_track.SetMainFrameID(MAINFRAME) lens = user_satisfied_lens.FirstContentfulPaintLens(loading_trace) - self.assertEqual(set(['0.1', '0.2', '0.3']), lens.CriticalRequests()) + self.assertEqual(set(['0.1', '0.2', '0.3']), lens.CriticalRequestIds()) self.assertEqual(float('inf'), lens.PostloadTimeMsec()) def testFirstTextPaintLens(self): + MAINFRAME = 1 + SUBFRAME = 2 loading_trace = test_utils.LoadingTraceFromEvents( [self._RequestAt(1), self._RequestAt(10), self._RequestAt(20)], trace_events=[{'ts': 0, 'ph': 'I', 'cat': 'blink.some_other_user_timing', 'name': 'firstPaint'}, - {'ts': 9 * self.MILLI_TO_MICRO, 'ph': 'I', + {'ts': 30 * self.MILLI_TO_MICRO, 'ph': 'I', 'cat': 'blink.user_timing', - 'name': 'firstishPaint'}, + 'name': 'firstishPaint', + 'args': {'frame': MAINFRAME}}, + {'ts': 3 * self.MILLI_TO_MICRO, 'ph': 'I', + 'cat': 'blink.user_timing', + 'name': 'firstPaint', + 'args': {'frame': SUBFRAME}}, {'ts': 12 * self.MILLI_TO_MICRO, 'ph': 'I', 'cat': 'blink.user_timing', - 'name': 'firstPaint'}, - {'ts': 22 * self.MILLI_TO_MICRO, 'ph': 'I', - 'cat': 'blink.user_timing', - 'name': 'firstPaint'}]) + 'name': 'firstPaint', + 'args': {'frame': MAINFRAME}}]) + loading_trace.tracing_track.SetMainFrameID(MAINFRAME) lens = user_satisfied_lens.FirstTextPaintLens(loading_trace) - self.assertEqual(set(['0.1', '0.2']), lens.CriticalRequests()) + self.assertEqual(set(['0.1', '0.2']), lens.CriticalRequestIds()) self.assertEqual(1, lens.PostloadTimeMsec()) def testFirstSignificantPaintLens(self): @@ -112,9 +126,37 @@ 'LayoutObjectsThatHadNeverHadLayout': 10 } } } ]) lens = user_satisfied_lens.FirstSignificantPaintLens(loading_trace) - self.assertEqual(set(['0.1', '0.2']), lens.CriticalRequests()) + self.assertEqual(set(['0.1', '0.2']), lens.CriticalRequestIds()) self.assertEqual(7, lens.PostloadTimeMsec()) + def testRequestFingerprintLens(self): + MAINFRAME = 1 + SUBFRAME = 2 + loading_trace = test_utils.LoadingTraceFromEvents( + [self._RequestAt(1), self._RequestAt(10), self._RequestAt(20)], + trace_events=[{'ts': 0, 'ph': 'I', + 'cat': 'blink.some_other_user_timing', + 'name': 'firstContentfulPaint'}, + {'ts': 30 * self.MILLI_TO_MICRO, 'ph': 'I', + 'cat': 'blink.user_timing', + 'name': 'firstDiscontentPaint'}, + {'ts': 5 * self.MILLI_TO_MICRO, 'ph': 'I', + 'cat': 'blink.user_timing', + 'name': 'firstContentfulPaint', + 'args': {'frame': SUBFRAME} }, + {'ts': 12 * self.MILLI_TO_MICRO, 'ph': 'I', + 'cat': 'blink.user_timing', + 'name': 'firstContentfulPaint', + 'args': {'frame': MAINFRAME}}]) + loading_trace.tracing_track.SetMainFrameID(MAINFRAME) + lens = user_satisfied_lens.FirstContentfulPaintLens(loading_trace) + self.assertEqual(set(['0.1', '0.2']), lens.CriticalRequestIds()) + self.assertEqual(1, lens.PostloadTimeMsec()) + request_lens = user_satisfied_lens.RequestFingerprintLens( + loading_trace, lens.CriticalFingerprints()) + self.assertEqual(set(['0.1', '0.2']), request_lens.CriticalRequestIds()) + self.assertEqual(0, request_lens.PostloadTimeMsec()) + if __name__ == '__main__': unittest.main()
diff --git a/tools/clang/blink_gc_plugin/BlinkGCPluginConsumer.cpp b/tools/clang/blink_gc_plugin/BlinkGCPluginConsumer.cpp index 21ef6e3..1a32def 100644 --- a/tools/clang/blink_gc_plugin/BlinkGCPluginConsumer.cpp +++ b/tools/clang/blink_gc_plugin/BlinkGCPluginConsumer.cpp
@@ -8,6 +8,9 @@ #include <set> #include "CheckDispatchVisitor.h" +#include "CheckFieldsVisitor.h" +#include "CheckFinalizerVisitor.h" +#include "CheckGCRootsVisitor.h" #include "CheckTraceVisitor.h" #include "CollectVisitor.h" #include "JsonWriter.h" @@ -19,136 +22,6 @@ namespace { -const char kClassMustLeftMostlyDeriveGC[] = - "[blink-gc] Class %0 must derive its GC base in the left-most position."; - -const char kClassRequiresTraceMethod[] = - "[blink-gc] Class %0 requires a trace method."; - -const char kBaseRequiresTracing[] = - "[blink-gc] Base class %0 of derived class %1 requires tracing."; - -const char kBaseRequiresTracingNote[] = - "[blink-gc] Untraced base class %0 declared here:"; - -const char kFieldsRequireTracing[] = - "[blink-gc] Class %0 has untraced fields that require tracing."; - -const char kFieldRequiresTracingNote[] = - "[blink-gc] Untraced field %0 declared here:"; - -const char kClassContainsInvalidFields[] = - "[blink-gc] Class %0 contains invalid fields."; - -const char kClassContainsGCRoot[] = - "[blink-gc] Class %0 contains GC root in field %1."; - -const char kClassRequiresFinalization[] = - "[blink-gc] Class %0 requires finalization."; - -const char kClassDoesNotRequireFinalization[] = - "[blink-gc] Class %0 may not require finalization."; - -const char kFinalizerAccessesFinalizedField[] = - "[blink-gc] Finalizer %0 accesses potentially finalized field %1."; - -const char kFinalizerAccessesEagerlyFinalizedField[] = - "[blink-gc] Finalizer %0 accesses eagerly finalized field %1."; - -const char kRawPtrToGCManagedClassNote[] = - "[blink-gc] Raw pointer field %0 to a GC managed class declared here:"; - -const char kRefPtrToGCManagedClassNote[] = - "[blink-gc] RefPtr field %0 to a GC managed class declared here:"; - -const char kReferencePtrToGCManagedClassNote[] = - "[blink-gc] Reference pointer field %0 to a GC managed class" - " declared here:"; - -const char kOwnPtrToGCManagedClassNote[] = - "[blink-gc] OwnPtr field %0 to a GC managed class declared here:"; - -const char kMemberToGCUnmanagedClassNote[] = - "[blink-gc] Member field %0 to non-GC managed class declared here:"; - -const char kStackAllocatedFieldNote[] = - "[blink-gc] Stack-allocated field %0 declared here:"; - -const char kMemberInUnmanagedClassNote[] = - "[blink-gc] Member field %0 in unmanaged class declared here:"; - -const char kPartObjectToGCDerivedClassNote[] = - "[blink-gc] Part-object field %0 to a GC derived class declared here:"; - -const char kPartObjectContainsGCRootNote[] = - "[blink-gc] Field %0 with embedded GC root in %1 declared here:"; - -const char kFieldContainsGCRootNote[] = - "[blink-gc] Field %0 defining a GC root declared here:"; - -const char kOverriddenNonVirtualTrace[] = - "[blink-gc] Class %0 overrides non-virtual trace of base class %1."; - -const char kOverriddenNonVirtualTraceNote[] = - "[blink-gc] Non-virtual trace method declared here:"; - -const char kMissingTraceDispatchMethod[] = - "[blink-gc] Class %0 is missing manual trace dispatch."; - -const char kMissingFinalizeDispatchMethod[] = - "[blink-gc] Class %0 is missing manual finalize dispatch."; - -const char kVirtualAndManualDispatch[] = - "[blink-gc] Class %0 contains or inherits virtual methods" - " but implements manual dispatching."; - -const char kMissingTraceDispatch[] = - "[blink-gc] Missing dispatch to class %0 in manual trace dispatch."; - -const char kMissingFinalizeDispatch[] = - "[blink-gc] Missing dispatch to class %0 in manual finalize dispatch."; - -const char kFinalizedFieldNote[] = - "[blink-gc] Potentially finalized field %0 declared here:"; - -const char kEagerlyFinalizedFieldNote[] = - "[blink-gc] Field %0 having eagerly finalized value, declared here:"; - -const char kUserDeclaredDestructorNote[] = - "[blink-gc] User-declared destructor declared here:"; - -const char kUserDeclaredFinalizerNote[] = - "[blink-gc] User-declared finalizer declared here:"; - -const char kBaseRequiresFinalizationNote[] = - "[blink-gc] Base class %0 requiring finalization declared here:"; - -const char kFieldRequiresFinalizationNote[] = - "[blink-gc] Field %0 requiring finalization declared here:"; - -const char kManualDispatchMethodNote[] = - "[blink-gc] Manual dispatch %0 declared here:"; - -const char kDerivesNonStackAllocated[] = - "[blink-gc] Stack-allocated class %0 derives class %1" - " which is not stack allocated."; - -const char kClassOverridesNew[] = - "[blink-gc] Garbage collected class %0" - " is not permitted to override its new operator."; - -const char kClassDeclaresPureVirtualTrace[] = - "[blink-gc] Garbage collected class %0" - " is not permitted to declare a pure-virtual trace method."; - -const char kLeftMostBaseMustBePolymorphic[] = - "[blink-gc] Left-most base class %0 of derived class %1" - " must be polymorphic."; - -const char kBaseClassMustDeclareVirtualTrace[] = - "[blink-gc] Left-most base class %0 of derived class %1" - " must define a virtual trace method."; - // Use a local RAV implementation to simply collect all FunctionDecls marked for // late template parsing. This happens with the flag -fdelayed-template-parsing, // which is on by default in MSVC-compatible mode. @@ -193,7 +66,7 @@ clang::CompilerInstance& instance, const BlinkGCPluginOptions& options) : instance_(instance), - diagnostic_(instance.getDiagnostics()), + reporter_(instance), options_(options), json_(0) { // Only check structures in the blink and WebKit namespaces. @@ -201,97 +74,11 @@ // Ignore GC implementation files. options_.ignored_directories.push_back("/heap/"); - - // Register warning/error messages. - diag_class_must_left_mostly_derive_gc_ = diagnostic_.getCustomDiagID( - getErrorLevel(), kClassMustLeftMostlyDeriveGC); - diag_class_requires_trace_method_ = - diagnostic_.getCustomDiagID(getErrorLevel(), kClassRequiresTraceMethod); - diag_base_requires_tracing_ = - diagnostic_.getCustomDiagID(getErrorLevel(), kBaseRequiresTracing); - diag_fields_require_tracing_ = - diagnostic_.getCustomDiagID(getErrorLevel(), kFieldsRequireTracing); - diag_class_contains_invalid_fields_ = diagnostic_.getCustomDiagID( - getErrorLevel(), kClassContainsInvalidFields); - diag_class_contains_gc_root_ = - diagnostic_.getCustomDiagID(getErrorLevel(), kClassContainsGCRoot); - diag_class_requires_finalization_ = diagnostic_.getCustomDiagID( - getErrorLevel(), kClassRequiresFinalization); - diag_class_does_not_require_finalization_ = diagnostic_.getCustomDiagID( - DiagnosticsEngine::Warning, kClassDoesNotRequireFinalization); - diag_finalizer_accesses_finalized_field_ = diagnostic_.getCustomDiagID( - getErrorLevel(), kFinalizerAccessesFinalizedField); - diag_finalizer_eagerly_finalized_field_ = diagnostic_.getCustomDiagID( - getErrorLevel(), kFinalizerAccessesEagerlyFinalizedField); - diag_overridden_non_virtual_trace_ = diagnostic_.getCustomDiagID( - getErrorLevel(), kOverriddenNonVirtualTrace); - diag_missing_trace_dispatch_method_ = diagnostic_.getCustomDiagID( - getErrorLevel(), kMissingTraceDispatchMethod); - diag_missing_finalize_dispatch_method_ = diagnostic_.getCustomDiagID( - getErrorLevel(), kMissingFinalizeDispatchMethod); - diag_virtual_and_manual_dispatch_ = - diagnostic_.getCustomDiagID(getErrorLevel(), kVirtualAndManualDispatch); - diag_missing_trace_dispatch_ = - diagnostic_.getCustomDiagID(getErrorLevel(), kMissingTraceDispatch); - diag_missing_finalize_dispatch_ = - diagnostic_.getCustomDiagID(getErrorLevel(), kMissingFinalizeDispatch); - diag_derives_non_stack_allocated_ = - diagnostic_.getCustomDiagID(getErrorLevel(), kDerivesNonStackAllocated); - diag_class_overrides_new_ = - diagnostic_.getCustomDiagID(getErrorLevel(), kClassOverridesNew); - diag_class_declares_pure_virtual_trace_ = diagnostic_.getCustomDiagID( - getErrorLevel(), kClassDeclaresPureVirtualTrace); - diag_left_most_base_must_be_polymorphic_ = diagnostic_.getCustomDiagID( - getErrorLevel(), kLeftMostBaseMustBePolymorphic); - diag_base_class_must_declare_virtual_trace_ = diagnostic_.getCustomDiagID( - getErrorLevel(), kBaseClassMustDeclareVirtualTrace); - - // Register note messages. - diag_base_requires_tracing_note_ = diagnostic_.getCustomDiagID( - DiagnosticsEngine::Note, kBaseRequiresTracingNote); - diag_field_requires_tracing_note_ = diagnostic_.getCustomDiagID( - DiagnosticsEngine::Note, kFieldRequiresTracingNote); - diag_raw_ptr_to_gc_managed_class_note_ = diagnostic_.getCustomDiagID( - DiagnosticsEngine::Note, kRawPtrToGCManagedClassNote); - diag_ref_ptr_to_gc_managed_class_note_ = diagnostic_.getCustomDiagID( - DiagnosticsEngine::Note, kRefPtrToGCManagedClassNote); - diag_reference_ptr_to_gc_managed_class_note_ = diagnostic_.getCustomDiagID( - DiagnosticsEngine::Note, kReferencePtrToGCManagedClassNote); - diag_own_ptr_to_gc_managed_class_note_ = diagnostic_.getCustomDiagID( - DiagnosticsEngine::Note, kOwnPtrToGCManagedClassNote); - diag_member_to_gc_unmanaged_class_note_ = diagnostic_.getCustomDiagID( - DiagnosticsEngine::Note, kMemberToGCUnmanagedClassNote); - diag_stack_allocated_field_note_ = diagnostic_.getCustomDiagID( - DiagnosticsEngine::Note, kStackAllocatedFieldNote); - diag_member_in_unmanaged_class_note_ = diagnostic_.getCustomDiagID( - DiagnosticsEngine::Note, kMemberInUnmanagedClassNote); - diag_part_object_to_gc_derived_class_note_ = diagnostic_.getCustomDiagID( - DiagnosticsEngine::Note, kPartObjectToGCDerivedClassNote); - diag_part_object_contains_gc_root_note_ = diagnostic_.getCustomDiagID( - DiagnosticsEngine::Note, kPartObjectContainsGCRootNote); - diag_field_contains_gc_root_note_ = diagnostic_.getCustomDiagID( - DiagnosticsEngine::Note, kFieldContainsGCRootNote); - diag_finalized_field_note_ = diagnostic_.getCustomDiagID( - DiagnosticsEngine::Note, kFinalizedFieldNote); - diag_eagerly_finalized_field_note_ = diagnostic_.getCustomDiagID( - DiagnosticsEngine::Note, kEagerlyFinalizedFieldNote); - diag_user_declared_destructor_note_ = diagnostic_.getCustomDiagID( - DiagnosticsEngine::Note, kUserDeclaredDestructorNote); - diag_user_declared_finalizer_note_ = diagnostic_.getCustomDiagID( - DiagnosticsEngine::Note, kUserDeclaredFinalizerNote); - diag_base_requires_finalization_note_ = diagnostic_.getCustomDiagID( - DiagnosticsEngine::Note, kBaseRequiresFinalizationNote); - diag_field_requires_finalization_note_ = diagnostic_.getCustomDiagID( - DiagnosticsEngine::Note, kFieldRequiresFinalizationNote); - diag_overridden_non_virtual_trace_note_ = diagnostic_.getCustomDiagID( - DiagnosticsEngine::Note, kOverriddenNonVirtualTraceNote); - diag_manual_dispatch_method_note_ = diagnostic_.getCustomDiagID( - DiagnosticsEngine::Note, kManualDispatchMethodNote); } void BlinkGCPluginConsumer::HandleTranslationUnit(ASTContext& context) { // Don't run the plugin if the compilation unit is already invalid. - if (diagnostic_.hasErrorOccurred()) + if (reporter_.hasErrorOccurred()) return; ParseFunctionTemplates(context.getTranslationUnitDecl()); @@ -393,14 +180,14 @@ if (info->IsStackAllocated()) { for (auto& base : info->GetBases()) if (!base.second.info()->IsStackAllocated()) - ReportDerivesNonStackAllocated(info, &base.second); + reporter_.DerivesNonStackAllocated(info, &base.second); } if (CXXMethodDecl* trace = info->GetTraceMethod()) { if (trace->isPure()) - ReportClassDeclaresPureVirtualTrace(info, trace); + reporter_.ClassDeclaresPureVirtualTrace(info, trace); } else if (info->RequiresTraceMethod()) { - ReportClassRequiresTraceMethod(info); + reporter_.ClassRequiresTraceMethod(info); } // Check polymorphic classes that are GC-derived or have a trace method. @@ -412,9 +199,9 @@ } { - CheckFieldsVisitor visitor(options_); + CheckFieldsVisitor visitor; if (visitor.ContainsInvalidFields(info)) - ReportClassContainsInvalidFields(info, visitor.invalid_fields()); + reporter_.ClassContainsInvalidFields(info, visitor.invalid_fields()); } if (info->IsGCDerived()) { @@ -423,13 +210,13 @@ CheckDispatch(info); if (CXXMethodDecl* newop = info->DeclaresNewOperator()) if (!Config::IsIgnoreAnnotated(newop)) - ReportClassOverridesNew(info, newop); + reporter_.ClassOverridesNew(info, newop); } { CheckGCRootsVisitor visitor; if (visitor.ContainsGCRoots(info)) - ReportClassContainsGCRoots(info, visitor.gc_roots()); + reporter_.ClassContainsGCRoots(info, visitor.gc_roots()); } if (info->NeedsFinalization()) @@ -513,7 +300,7 @@ if (trace->isVirtual()) return; } - ReportBaseClassMustDeclareVirtualTrace(info, left_most); + reporter_.BaseClassMustDeclareVirtualTrace(info, left_most); return; } @@ -529,13 +316,13 @@ if (CXXRecordDecl* next_left_most = GetLeftMostBase(next_base)) { if (DeclaresVirtualMethods(next_left_most)) return; - ReportLeftMostBaseMustBePolymorphic(info, next_left_most); + reporter_.LeftMostBaseMustBePolymorphic(info, next_left_most); return; } } } } - ReportLeftMostBaseMustBePolymorphic(info, left_most); + reporter_.LeftMostBaseMustBePolymorphic(info, left_most); } } @@ -567,7 +354,7 @@ if (!left_most) return; if (!Config::IsGCBase(left_most->getName())) - ReportClassMustLeftMostlyDeriveGC(info); + reporter_.ClassMustLeftMostlyDeriveGC(info); } void BlinkGCPluginConsumer::CheckDispatch(RecordInfo* info) { @@ -583,18 +370,18 @@ // Check that dispatch methods are defined at the base. if (base == info->record()) { if (!trace_dispatch) - ReportMissingTraceDispatchMethod(info); + reporter_.MissingTraceDispatchMethod(info); if (finalized && !finalize_dispatch) - ReportMissingFinalizeDispatchMethod(info); + reporter_.MissingFinalizeDispatchMethod(info); if (!finalized && finalize_dispatch) { - ReportClassRequiresFinalization(info); - NoteUserDeclaredFinalizer(finalize_dispatch); + reporter_.ClassRequiresFinalization(info); + reporter_.NoteUserDeclaredFinalizer(finalize_dispatch); } } // Check that classes implementing manual dispatch do not have vtables. if (info->record()->isPolymorphic()) { - ReportVirtualAndManualDispatch( + reporter_.VirtualAndManualDispatch( info, trace_dispatch ? trace_dispatch : finalize_dispatch); } @@ -610,14 +397,14 @@ CheckDispatchVisitor visitor(info); visitor.TraverseStmt(defn->getBody()); if (!visitor.dispatched_to_receiver()) - ReportMissingTraceDispatch(defn, info); + reporter_.MissingTraceDispatch(defn, info); } if (finalized && finalize_dispatch && finalize_dispatch->isDefined(defn)) { CheckDispatchVisitor visitor(info); visitor.TraverseStmt(defn->getBody()); if (!visitor.dispatched_to_receiver()) - ReportMissingFinalizeDispatch(defn, info); + reporter_.MissingFinalizeDispatch(defn, info); } } @@ -631,7 +418,7 @@ CheckFinalizerVisitor visitor(&cache_, info->IsEagerlyFinalized()); visitor.TraverseCXXMethodDecl(dtor); if (!visitor.finalized_fields().empty()) { - ReportFinalizerAccessesFinalizedFields( + reporter_.FinalizerAccessesFinalizedFields( dtor, visitor.finalized_fields()); } } @@ -644,23 +431,23 @@ // Report the finalization error, and proceed to print possible causes for // the finalization requirement. - ReportClassRequiresFinalization(info); + reporter_.ClassRequiresFinalization(info); if (dtor && dtor->isUserProvided()) - NoteUserDeclaredDestructor(dtor); + reporter_.NoteUserDeclaredDestructor(dtor); for (auto& base : info->GetBases()) if (base.second.info()->NeedsFinalization()) - NoteBaseRequiresFinalization(&base.second); + reporter_.NoteBaseRequiresFinalization(&base.second); for (auto& field : info->GetFields()) if (field.second.edge()->NeedsFinalization()) - NoteField(&field.second, diag_field_requires_finalization_note_); + reporter_.NoteFieldRequiresFinalization(&field.second); } void BlinkGCPluginConsumer::CheckUnneededFinalization(RecordInfo* info) { if (!HasNonEmptyFinalizer(info)) - ReportClassDoesNotRequireFinalization(info); + reporter_.ClassDoesNotRequireFinalization(info); } bool BlinkGCPluginConsumer::HasNonEmptyFinalizer(RecordInfo* info) { @@ -748,7 +535,7 @@ if (trace_type == Config::TRACE_METHOD) { for (auto& base : parent->GetBases()) if (CXXMethodDecl* other = base.second.info()->InheritsNonVirtualTrace()) - ReportOverriddenNonVirtualTrace(parent, trace, other); + reporter_.OverriddenNonVirtualTrace(parent, trace, other); } CheckTraceVisitor visitor(trace, parent, &cache_); @@ -762,12 +549,12 @@ for (auto& base : parent->GetBases()) if (!base.second.IsProperlyTraced()) - ReportBaseRequiresTracing(parent, trace, base.first); + reporter_.BaseRequiresTracing(parent, trace, base.first); for (auto& field : parent->GetFields()) { if (!field.second.IsProperlyTraced()) { // Discontinue once an untraced-field error is found. - ReportFieldsRequireTracing(parent, trace); + reporter_.FieldsRequireTracing(parent, trace); break; } } @@ -858,11 +645,6 @@ GetLocString(field.second.field()->getLocStart())); } -DiagnosticsEngine::Level BlinkGCPluginConsumer::getErrorLevel() { - return diagnostic_.getWarningsAsErrors() ? DiagnosticsEngine::Error - : DiagnosticsEngine::Warning; -} - std::string BlinkGCPluginConsumer::GetLocString(SourceLocation loc) { const SourceManager& source_manager = instance_.getSourceManager(); PresumedLoc ploc = source_manager.getPresumedLoc(loc); @@ -937,283 +719,3 @@ *filename = ploc.getFilename(); return true; } - -DiagnosticBuilder BlinkGCPluginConsumer::ReportDiagnostic( - SourceLocation location, - unsigned diag_id) { - SourceManager& manager = instance_.getSourceManager(); - FullSourceLoc full_loc(location, manager); - return diagnostic_.Report(full_loc, diag_id); -} - -void BlinkGCPluginConsumer::ReportClassMustLeftMostlyDeriveGC( - RecordInfo* info) { - ReportDiagnostic(info->record()->getInnerLocStart(), - diag_class_must_left_mostly_derive_gc_) - << info->record(); -} - -void BlinkGCPluginConsumer::ReportClassRequiresTraceMethod(RecordInfo* info) { - ReportDiagnostic(info->record()->getInnerLocStart(), - diag_class_requires_trace_method_) - << info->record(); - - for (auto& base : info->GetBases()) - if (base.second.NeedsTracing().IsNeeded()) - NoteBaseRequiresTracing(&base.second); - - for (auto& field : info->GetFields()) - if (!field.second.IsProperlyTraced()) - NoteFieldRequiresTracing(info, field.first); -} - -void BlinkGCPluginConsumer::ReportBaseRequiresTracing( - RecordInfo* derived, - CXXMethodDecl* trace, - CXXRecordDecl* base) { - ReportDiagnostic(trace->getLocStart(), diag_base_requires_tracing_) - << base << derived->record(); -} - -void BlinkGCPluginConsumer::ReportFieldsRequireTracing( - RecordInfo* info, - CXXMethodDecl* trace) { - ReportDiagnostic(trace->getLocStart(), diag_fields_require_tracing_) - << info->record(); - for (auto& field : info->GetFields()) - if (!field.second.IsProperlyTraced()) - NoteFieldRequiresTracing(info, field.first); -} - -void BlinkGCPluginConsumer::ReportClassContainsInvalidFields( - RecordInfo* info, - const CheckFieldsVisitor::Errors& errors) { - - ReportDiagnostic(info->record()->getLocStart(), - diag_class_contains_invalid_fields_) - << info->record(); - - for (auto& error : errors) { - unsigned note; - if (error.second == CheckFieldsVisitor::kRawPtrToGCManaged) { - note = diag_raw_ptr_to_gc_managed_class_note_; - } else if (error.second == CheckFieldsVisitor::kRefPtrToGCManaged) { - note = diag_ref_ptr_to_gc_managed_class_note_; - } else if (error.second == CheckFieldsVisitor::kReferencePtrToGCManaged) { - note = diag_reference_ptr_to_gc_managed_class_note_; - } else if (error.second == CheckFieldsVisitor::kOwnPtrToGCManaged) { - note = diag_own_ptr_to_gc_managed_class_note_; - } else if (error.second == CheckFieldsVisitor::kMemberToGCUnmanaged) { - note = diag_member_to_gc_unmanaged_class_note_; - } else if (error.second == CheckFieldsVisitor::kMemberInUnmanaged) { - note = diag_member_in_unmanaged_class_note_; - } else if (error.second == CheckFieldsVisitor::kPtrFromHeapToStack) { - note = diag_stack_allocated_field_note_; - } else if (error.second == CheckFieldsVisitor::kGCDerivedPartObject) { - note = diag_part_object_to_gc_derived_class_note_; - } else { - assert(false && "Unknown field error"); - } - NoteField(error.first, note); - } -} - -void BlinkGCPluginConsumer::ReportClassContainsGCRoots( - RecordInfo* info, - const CheckGCRootsVisitor::Errors& errors) { - for (auto& error : errors) { - FieldPoint* point = nullptr; - for (FieldPoint* path : error) { - if (!point) { - point = path; - ReportDiagnostic(info->record()->getLocStart(), - diag_class_contains_gc_root_) - << info->record() << point->field(); - continue; - } - NotePartObjectContainsGCRoot(point); - point = path; - } - NoteFieldContainsGCRoot(point); - } -} - -void BlinkGCPluginConsumer::ReportFinalizerAccessesFinalizedFields( - CXXMethodDecl* dtor, - const CheckFinalizerVisitor::Errors& errors) { - for (auto& error : errors) { - bool as_eagerly_finalized = error.as_eagerly_finalized; - unsigned diag_error = as_eagerly_finalized ? - diag_finalizer_eagerly_finalized_field_ : - diag_finalizer_accesses_finalized_field_; - unsigned diag_note = as_eagerly_finalized ? - diag_eagerly_finalized_field_note_ : - diag_finalized_field_note_; - ReportDiagnostic(error.member->getLocStart(), diag_error) - << dtor << error.field->field(); - NoteField(error.field, diag_note); - } -} - -void BlinkGCPluginConsumer::ReportClassRequiresFinalization(RecordInfo* info) { - ReportDiagnostic(info->record()->getInnerLocStart(), - diag_class_requires_finalization_) - << info->record(); -} - -void BlinkGCPluginConsumer::ReportClassDoesNotRequireFinalization( - RecordInfo* info) { - ReportDiagnostic(info->record()->getInnerLocStart(), - diag_class_does_not_require_finalization_) - << info->record(); -} - -void BlinkGCPluginConsumer::ReportOverriddenNonVirtualTrace( - RecordInfo* info, - CXXMethodDecl* trace, - CXXMethodDecl* overridden) { - ReportDiagnostic(trace->getLocStart(), diag_overridden_non_virtual_trace_) - << info->record() << overridden->getParent(); - NoteOverriddenNonVirtualTrace(overridden); -} - -void BlinkGCPluginConsumer::ReportMissingTraceDispatchMethod(RecordInfo* info) { - ReportMissingDispatchMethod(info, diag_missing_trace_dispatch_method_); -} - -void BlinkGCPluginConsumer::ReportMissingFinalizeDispatchMethod( - RecordInfo* info) { - ReportMissingDispatchMethod(info, diag_missing_finalize_dispatch_method_); -} - -void BlinkGCPluginConsumer::ReportMissingDispatchMethod( - RecordInfo* info, - unsigned error) { - ReportDiagnostic(info->record()->getInnerLocStart(), error) - << info->record(); -} - -void BlinkGCPluginConsumer::ReportVirtualAndManualDispatch( - RecordInfo* info, - CXXMethodDecl* dispatch) { - ReportDiagnostic(info->record()->getInnerLocStart(), - diag_virtual_and_manual_dispatch_) - << info->record(); - NoteManualDispatchMethod(dispatch); -} - -void BlinkGCPluginConsumer::ReportMissingTraceDispatch( - const FunctionDecl* dispatch, - RecordInfo* receiver) { - ReportMissingDispatch(dispatch, receiver, diag_missing_trace_dispatch_); -} - -void BlinkGCPluginConsumer::ReportMissingFinalizeDispatch( - const FunctionDecl* dispatch, - RecordInfo* receiver) { - ReportMissingDispatch(dispatch, receiver, diag_missing_finalize_dispatch_); -} - -void BlinkGCPluginConsumer::ReportMissingDispatch( - const FunctionDecl* dispatch, - RecordInfo* receiver, - unsigned error) { - ReportDiagnostic(dispatch->getLocStart(), error) << receiver->record(); -} - -void BlinkGCPluginConsumer::ReportDerivesNonStackAllocated( - RecordInfo* info, - BasePoint* base) { - ReportDiagnostic(base->spec().getLocStart(), - diag_derives_non_stack_allocated_) - << info->record() << base->info()->record(); -} - -void BlinkGCPluginConsumer::ReportClassOverridesNew( - RecordInfo* info, - CXXMethodDecl* newop) { - ReportDiagnostic(newop->getLocStart(), diag_class_overrides_new_) - << info->record(); -} - -void BlinkGCPluginConsumer::ReportClassDeclaresPureVirtualTrace( - RecordInfo* info, - CXXMethodDecl* trace) { - ReportDiagnostic(trace->getLocStart(), - diag_class_declares_pure_virtual_trace_) - << info->record(); -} - -void BlinkGCPluginConsumer::ReportLeftMostBaseMustBePolymorphic( - RecordInfo* derived, - CXXRecordDecl* base) { - ReportDiagnostic(base->getLocStart(), - diag_left_most_base_must_be_polymorphic_) - << base << derived->record(); -} - -void BlinkGCPluginConsumer::ReportBaseClassMustDeclareVirtualTrace( - RecordInfo* derived, - CXXRecordDecl* base) { - ReportDiagnostic(base->getLocStart(), - diag_base_class_must_declare_virtual_trace_) - << base << derived->record(); -} - -void BlinkGCPluginConsumer::NoteManualDispatchMethod(CXXMethodDecl* dispatch) { - ReportDiagnostic(dispatch->getLocStart(), - diag_manual_dispatch_method_note_) - << dispatch; -} - -void BlinkGCPluginConsumer::NoteBaseRequiresTracing(BasePoint* base) { - ReportDiagnostic(base->spec().getLocStart(), - diag_base_requires_tracing_note_) - << base->info()->record(); -} - -void BlinkGCPluginConsumer::NoteFieldRequiresTracing( - RecordInfo* holder, - FieldDecl* field) { - NoteField(field, diag_field_requires_tracing_note_); -} - -void BlinkGCPluginConsumer::NotePartObjectContainsGCRoot(FieldPoint* point) { - FieldDecl* field = point->field(); - ReportDiagnostic(field->getLocStart(), - diag_part_object_contains_gc_root_note_) - << field << field->getParent(); -} - -void BlinkGCPluginConsumer::NoteFieldContainsGCRoot(FieldPoint* point) { - NoteField(point, diag_field_contains_gc_root_note_); -} - -void BlinkGCPluginConsumer::NoteUserDeclaredDestructor(CXXMethodDecl* dtor) { - ReportDiagnostic(dtor->getLocStart(), diag_user_declared_destructor_note_); -} - -void BlinkGCPluginConsumer::NoteUserDeclaredFinalizer(CXXMethodDecl* dtor) { - ReportDiagnostic(dtor->getLocStart(), diag_user_declared_finalizer_note_); -} - -void BlinkGCPluginConsumer::NoteBaseRequiresFinalization(BasePoint* base) { - ReportDiagnostic(base->spec().getLocStart(), - diag_base_requires_finalization_note_) - << base->info()->record(); -} - -void BlinkGCPluginConsumer::NoteField(FieldPoint* point, unsigned note) { - NoteField(point->field(), note); -} - -void BlinkGCPluginConsumer::NoteField(FieldDecl* field, unsigned note) { - ReportDiagnostic(field->getLocStart(), note) << field; -} - -void BlinkGCPluginConsumer::NoteOverriddenNonVirtualTrace( - CXXMethodDecl* overridden) { - ReportDiagnostic(overridden->getLocStart(), - diag_overridden_non_virtual_trace_note_) - << overridden; -}
diff --git a/tools/clang/blink_gc_plugin/BlinkGCPluginConsumer.h b/tools/clang/blink_gc_plugin/BlinkGCPluginConsumer.h index e05bd82..bcfb3af 100644 --- a/tools/clang/blink_gc_plugin/BlinkGCPluginConsumer.h +++ b/tools/clang/blink_gc_plugin/BlinkGCPluginConsumer.h
@@ -8,10 +8,8 @@ #include <string> #include "BlinkGCPluginOptions.h" -#include "CheckFieldsVisitor.h" -#include "CheckFinalizerVisitor.h" -#include "CheckGCRootsVisitor.h" #include "Config.h" +#include "DiagnosticsReporter.h" #include "clang/AST/AST.h" #include "clang/AST/ASTConsumer.h" #include "clang/Basic/Diagnostic.h" @@ -75,7 +73,7 @@ std::string GetLocString(clang::SourceLocation loc); - bool IsIgnored(RecordInfo* record); + bool IsIgnored(RecordInfo* info); bool IsIgnoredClass(RecordInfo* info); @@ -85,112 +83,11 @@ bool GetFilename(clang::SourceLocation loc, std::string* filename); - clang::DiagnosticBuilder ReportDiagnostic( - clang::SourceLocation location, - unsigned diag_id); - - void ReportClassMustLeftMostlyDeriveGC(RecordInfo* info); - void ReportClassRequiresTraceMethod(RecordInfo* info); - void ReportBaseRequiresTracing(RecordInfo* derived, - clang::CXXMethodDecl* trace, - clang::CXXRecordDecl* base); - void ReportFieldsRequireTracing(RecordInfo* info, - clang::CXXMethodDecl* trace); - void ReportClassContainsInvalidFields( - RecordInfo* info, - const CheckFieldsVisitor::Errors& errors); - void ReportClassContainsGCRoots(RecordInfo* info, - const CheckGCRootsVisitor::Errors& errors); - void ReportFinalizerAccessesFinalizedFields( - clang::CXXMethodDecl* dtor, - const CheckFinalizerVisitor::Errors& errors); - void ReportClassRequiresFinalization(RecordInfo* info); - void ReportClassDoesNotRequireFinalization(RecordInfo* info); - void ReportClassMustDeclareGCMixinTraceMethod(RecordInfo* info); - void ReportOverriddenNonVirtualTrace(RecordInfo* info, - clang::CXXMethodDecl* trace, - clang::CXXMethodDecl* overridden); - void ReportMissingTraceDispatchMethod(RecordInfo* info); - void ReportMissingFinalizeDispatchMethod(RecordInfo* info); - void ReportMissingDispatchMethod(RecordInfo* info, unsigned error); - void ReportVirtualAndManualDispatch(RecordInfo* info, - clang::CXXMethodDecl* dispatch); - void ReportMissingTraceDispatch(const clang::FunctionDecl* dispatch, - RecordInfo* receiver); - void ReportMissingFinalizeDispatch(const clang::FunctionDecl* dispatch, - RecordInfo* receiver); - void ReportMissingDispatch(const clang::FunctionDecl* dispatch, - RecordInfo* receiver, - unsigned error); - void ReportDerivesNonStackAllocated(RecordInfo* info, BasePoint* base); - void ReportClassOverridesNew(RecordInfo* info, clang::CXXMethodDecl* newop); - void ReportClassDeclaresPureVirtualTrace(RecordInfo* info, - clang::CXXMethodDecl* trace); - void ReportLeftMostBaseMustBePolymorphic(RecordInfo* derived, - clang::CXXRecordDecl* base); - void ReportBaseClassMustDeclareVirtualTrace(RecordInfo* derived, - clang::CXXRecordDecl* base); - void NoteManualDispatchMethod(clang::CXXMethodDecl* dispatch); - void NoteBaseRequiresTracing(BasePoint* base); - void NoteFieldRequiresTracing(RecordInfo* holder, clang::FieldDecl* field); - void NotePartObjectContainsGCRoot(FieldPoint* point); - void NoteFieldContainsGCRoot(FieldPoint* point); - void NoteUserDeclaredDestructor(clang::CXXMethodDecl* dtor); - void NoteUserDeclaredFinalizer(clang::CXXMethodDecl* dtor); - void NoteBaseRequiresFinalization(BasePoint* base); - void NoteField(FieldPoint* point, unsigned note); - void NoteField(clang::FieldDecl* field, unsigned note); - void NoteOverriddenNonVirtualTrace(clang::CXXMethodDecl* overridden); - - unsigned diag_class_must_left_mostly_derive_gc_; - unsigned diag_class_requires_trace_method_; - unsigned diag_base_requires_tracing_; - unsigned diag_fields_require_tracing_; - unsigned diag_class_contains_invalid_fields_; - unsigned diag_class_contains_gc_root_; - unsigned diag_class_requires_finalization_; - unsigned diag_class_does_not_require_finalization_; - unsigned diag_finalizer_accesses_finalized_field_; - unsigned diag_finalizer_eagerly_finalized_field_; - unsigned diag_overridden_non_virtual_trace_; - unsigned diag_missing_trace_dispatch_method_; - unsigned diag_missing_finalize_dispatch_method_; - unsigned diag_virtual_and_manual_dispatch_; - unsigned diag_missing_trace_dispatch_; - unsigned diag_missing_finalize_dispatch_; - unsigned diag_derives_non_stack_allocated_; - unsigned diag_class_overrides_new_; - unsigned diag_class_declares_pure_virtual_trace_; - unsigned diag_left_most_base_must_be_polymorphic_; - unsigned diag_base_class_must_declare_virtual_trace_; - - unsigned diag_base_requires_tracing_note_; - unsigned diag_field_requires_tracing_note_; - unsigned diag_raw_ptr_to_gc_managed_class_note_; - unsigned diag_ref_ptr_to_gc_managed_class_note_; - unsigned diag_reference_ptr_to_gc_managed_class_note_; - unsigned diag_own_ptr_to_gc_managed_class_note_; - unsigned diag_member_to_gc_unmanaged_class_note_; - unsigned diag_stack_allocated_field_note_; - unsigned diag_member_in_unmanaged_class_note_; - unsigned diag_part_object_to_gc_derived_class_note_; - unsigned diag_part_object_contains_gc_root_note_; - unsigned diag_field_contains_gc_root_note_; - unsigned diag_finalized_field_note_; - unsigned diag_eagerly_finalized_field_note_; - unsigned diag_user_declared_destructor_note_; - unsigned diag_user_declared_finalizer_note_; - unsigned diag_base_requires_finalization_note_; - unsigned diag_field_requires_finalization_note_; - unsigned diag_overridden_non_virtual_trace_note_; - unsigned diag_manual_dispatch_method_note_; - clang::CompilerInstance& instance_; - clang::DiagnosticsEngine& diagnostic_; + DiagnosticsReporter reporter_; BlinkGCPluginOptions options_; RecordCache cache_; JsonWriter* json_; }; - #endif // TOOLS_BLINK_GC_PLUGIN_BLINK_GC_PLUGIN_CONSUMER_H_
diff --git a/tools/clang/blink_gc_plugin/CMakeLists.txt b/tools/clang/blink_gc_plugin/CMakeLists.txt index 60ad1e52..009807b 100644 --- a/tools/clang/blink_gc_plugin/CMakeLists.txt +++ b/tools/clang/blink_gc_plugin/CMakeLists.txt
@@ -10,6 +10,7 @@ CheckTraceVisitor.cpp CollectVisitor.cpp Config.cpp + DiagnosticsReporter.cpp Edge.cpp RecordInfo.cpp)
diff --git a/tools/clang/blink_gc_plugin/CheckFieldsVisitor.cpp b/tools/clang/blink_gc_plugin/CheckFieldsVisitor.cpp index f08710f8..e609a9706 100644 --- a/tools/clang/blink_gc_plugin/CheckFieldsVisitor.cpp +++ b/tools/clang/blink_gc_plugin/CheckFieldsVisitor.cpp
@@ -9,9 +9,8 @@ #include "BlinkGCPluginOptions.h" #include "RecordInfo.h" -CheckFieldsVisitor::CheckFieldsVisitor(const BlinkGCPluginOptions& options) - : options_(options), - current_(0), +CheckFieldsVisitor::CheckFieldsVisitor() + : current_(0), stack_allocated_host_(false) { }
diff --git a/tools/clang/blink_gc_plugin/CheckFieldsVisitor.h b/tools/clang/blink_gc_plugin/CheckFieldsVisitor.h index d700be2..4fddede3 100644 --- a/tools/clang/blink_gc_plugin/CheckFieldsVisitor.h +++ b/tools/clang/blink_gc_plugin/CheckFieldsVisitor.h
@@ -31,9 +31,9 @@ kGCDerivedPartObject }; - typedef std::vector<std::pair<FieldPoint*, Error> > Errors; + using Errors = std::vector<std::pair<FieldPoint*, Error>>; - explicit CheckFieldsVisitor(const BlinkGCPluginOptions& options); + CheckFieldsVisitor(); Errors& invalid_fields(); @@ -46,7 +46,6 @@ private: Error InvalidSmartPtr(Edge* ptr); - const BlinkGCPluginOptions& options_; FieldPoint* current_; bool stack_allocated_host_; bool managed_host_;
diff --git a/tools/clang/blink_gc_plugin/DiagnosticsReporter.cpp b/tools/clang/blink_gc_plugin/DiagnosticsReporter.cpp new file mode 100644 index 0000000..0057d80d --- /dev/null +++ b/tools/clang/blink_gc_plugin/DiagnosticsReporter.cpp
@@ -0,0 +1,527 @@ +// Copyright 2016 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "DiagnosticsReporter.h" + +using namespace clang; + +namespace { + +const char kClassMustLeftMostlyDeriveGC[] = + "[blink-gc] Class %0 must derive its GC base in the left-most position."; + +const char kClassRequiresTraceMethod[] = + "[blink-gc] Class %0 requires a trace method."; + +const char kBaseRequiresTracing[] = + "[blink-gc] Base class %0 of derived class %1 requires tracing."; + +const char kBaseRequiresTracingNote[] = + "[blink-gc] Untraced base class %0 declared here:"; + +const char kFieldsRequireTracing[] = + "[blink-gc] Class %0 has untraced fields that require tracing."; + +const char kFieldRequiresTracingNote[] = + "[blink-gc] Untraced field %0 declared here:"; + +const char kClassContainsInvalidFields[] = + "[blink-gc] Class %0 contains invalid fields."; + +const char kClassContainsGCRoot[] = + "[blink-gc] Class %0 contains GC root in field %1."; + +const char kClassRequiresFinalization[] = + "[blink-gc] Class %0 requires finalization."; + +const char kClassDoesNotRequireFinalization[] = + "[blink-gc] Class %0 may not require finalization."; + +const char kFinalizerAccessesFinalizedField[] = + "[blink-gc] Finalizer %0 accesses potentially finalized field %1."; + +const char kFinalizerAccessesEagerlyFinalizedField[] = + "[blink-gc] Finalizer %0 accesses eagerly finalized field %1."; + +const char kRawPtrToGCManagedClassNote[] = + "[blink-gc] Raw pointer field %0 to a GC managed class declared here:"; + +const char kRefPtrToGCManagedClassNote[] = + "[blink-gc] RefPtr field %0 to a GC managed class declared here:"; + +const char kReferencePtrToGCManagedClassNote[] = + "[blink-gc] Reference pointer field %0 to a GC managed class" + " declared here:"; + +const char kOwnPtrToGCManagedClassNote[] = + "[blink-gc] OwnPtr field %0 to a GC managed class declared here:"; + +const char kMemberToGCUnmanagedClassNote[] = + "[blink-gc] Member field %0 to non-GC managed class declared here:"; + +const char kStackAllocatedFieldNote[] = + "[blink-gc] Stack-allocated field %0 declared here:"; + +const char kMemberInUnmanagedClassNote[] = + "[blink-gc] Member field %0 in unmanaged class declared here:"; + +const char kPartObjectToGCDerivedClassNote[] = + "[blink-gc] Part-object field %0 to a GC derived class declared here:"; + +const char kPartObjectContainsGCRootNote[] = + "[blink-gc] Field %0 with embedded GC root in %1 declared here:"; + +const char kFieldContainsGCRootNote[] = + "[blink-gc] Field %0 defining a GC root declared here:"; + +const char kOverriddenNonVirtualTrace[] = + "[blink-gc] Class %0 overrides non-virtual trace of base class %1."; + +const char kOverriddenNonVirtualTraceNote[] = + "[blink-gc] Non-virtual trace method declared here:"; + +const char kMissingTraceDispatchMethod[] = + "[blink-gc] Class %0 is missing manual trace dispatch."; + +const char kMissingFinalizeDispatchMethod[] = + "[blink-gc] Class %0 is missing manual finalize dispatch."; + +const char kVirtualAndManualDispatch[] = + "[blink-gc] Class %0 contains or inherits virtual methods" + " but implements manual dispatching."; + +const char kMissingTraceDispatch[] = + "[blink-gc] Missing dispatch to class %0 in manual trace dispatch."; + +const char kMissingFinalizeDispatch[] = + "[blink-gc] Missing dispatch to class %0 in manual finalize dispatch."; + +const char kFinalizedFieldNote[] = + "[blink-gc] Potentially finalized field %0 declared here:"; + +const char kEagerlyFinalizedFieldNote[] = + "[blink-gc] Field %0 having eagerly finalized value, declared here:"; + +const char kUserDeclaredDestructorNote[] = + "[blink-gc] User-declared destructor declared here:"; + +const char kUserDeclaredFinalizerNote[] = + "[blink-gc] User-declared finalizer declared here:"; + +const char kBaseRequiresFinalizationNote[] = + "[blink-gc] Base class %0 requiring finalization declared here:"; + +const char kFieldRequiresFinalizationNote[] = + "[blink-gc] Field %0 requiring finalization declared here:"; + +const char kManualDispatchMethodNote[] = + "[blink-gc] Manual dispatch %0 declared here:"; + +const char kDerivesNonStackAllocated[] = + "[blink-gc] Stack-allocated class %0 derives class %1" + " which is not stack allocated."; + +const char kClassOverridesNew[] = + "[blink-gc] Garbage collected class %0" + " is not permitted to override its new operator."; + +const char kClassDeclaresPureVirtualTrace[] = + "[blink-gc] Garbage collected class %0" + " is not permitted to declare a pure-virtual trace method."; + +const char kLeftMostBaseMustBePolymorphic[] = + "[blink-gc] Left-most base class %0 of derived class %1" + " must be polymorphic."; + +const char kBaseClassMustDeclareVirtualTrace[] = + "[blink-gc] Left-most base class %0 of derived class %1" + " must define a virtual trace method."; + +} // namespace + +DiagnosticBuilder DiagnosticsReporter::ReportDiagnostic( + SourceLocation location, + unsigned diag_id) { + SourceManager& manager = instance_.getSourceManager(); + FullSourceLoc full_loc(location, manager); + return diagnostic_.Report(full_loc, diag_id); +} + +DiagnosticsReporter::DiagnosticsReporter( + clang::CompilerInstance& instance) + : instance_(instance), + diagnostic_(instance.getDiagnostics()) +{ + // Register warning/error messages. + diag_class_must_left_mostly_derive_gc_ = diagnostic_.getCustomDiagID( + getErrorLevel(), kClassMustLeftMostlyDeriveGC); + diag_class_requires_trace_method_ = + diagnostic_.getCustomDiagID(getErrorLevel(), kClassRequiresTraceMethod); + diag_base_requires_tracing_ = + diagnostic_.getCustomDiagID(getErrorLevel(), kBaseRequiresTracing); + diag_fields_require_tracing_ = + diagnostic_.getCustomDiagID(getErrorLevel(), kFieldsRequireTracing); + diag_class_contains_invalid_fields_ = diagnostic_.getCustomDiagID( + getErrorLevel(), kClassContainsInvalidFields); + diag_class_contains_gc_root_ = + diagnostic_.getCustomDiagID(getErrorLevel(), kClassContainsGCRoot); + diag_class_requires_finalization_ = diagnostic_.getCustomDiagID( + getErrorLevel(), kClassRequiresFinalization); + diag_class_does_not_require_finalization_ = diagnostic_.getCustomDiagID( + DiagnosticsEngine::Warning, kClassDoesNotRequireFinalization); + diag_finalizer_accesses_finalized_field_ = diagnostic_.getCustomDiagID( + getErrorLevel(), kFinalizerAccessesFinalizedField); + diag_finalizer_eagerly_finalized_field_ = diagnostic_.getCustomDiagID( + getErrorLevel(), kFinalizerAccessesEagerlyFinalizedField); + diag_overridden_non_virtual_trace_ = diagnostic_.getCustomDiagID( + getErrorLevel(), kOverriddenNonVirtualTrace); + diag_missing_trace_dispatch_method_ = diagnostic_.getCustomDiagID( + getErrorLevel(), kMissingTraceDispatchMethod); + diag_missing_finalize_dispatch_method_ = diagnostic_.getCustomDiagID( + getErrorLevel(), kMissingFinalizeDispatchMethod); + diag_virtual_and_manual_dispatch_ = + diagnostic_.getCustomDiagID(getErrorLevel(), kVirtualAndManualDispatch); + diag_missing_trace_dispatch_ = + diagnostic_.getCustomDiagID(getErrorLevel(), kMissingTraceDispatch); + diag_missing_finalize_dispatch_ = + diagnostic_.getCustomDiagID(getErrorLevel(), kMissingFinalizeDispatch); + diag_derives_non_stack_allocated_ = + diagnostic_.getCustomDiagID(getErrorLevel(), kDerivesNonStackAllocated); + diag_class_overrides_new_ = + diagnostic_.getCustomDiagID(getErrorLevel(), kClassOverridesNew); + diag_class_declares_pure_virtual_trace_ = diagnostic_.getCustomDiagID( + getErrorLevel(), kClassDeclaresPureVirtualTrace); + diag_left_most_base_must_be_polymorphic_ = diagnostic_.getCustomDiagID( + getErrorLevel(), kLeftMostBaseMustBePolymorphic); + diag_base_class_must_declare_virtual_trace_ = diagnostic_.getCustomDiagID( + getErrorLevel(), kBaseClassMustDeclareVirtualTrace); + + // Register note messages. + diag_base_requires_tracing_note_ = diagnostic_.getCustomDiagID( + DiagnosticsEngine::Note, kBaseRequiresTracingNote); + diag_field_requires_tracing_note_ = diagnostic_.getCustomDiagID( + DiagnosticsEngine::Note, kFieldRequiresTracingNote); + diag_raw_ptr_to_gc_managed_class_note_ = diagnostic_.getCustomDiagID( + DiagnosticsEngine::Note, kRawPtrToGCManagedClassNote); + diag_ref_ptr_to_gc_managed_class_note_ = diagnostic_.getCustomDiagID( + DiagnosticsEngine::Note, kRefPtrToGCManagedClassNote); + diag_reference_ptr_to_gc_managed_class_note_ = diagnostic_.getCustomDiagID( + DiagnosticsEngine::Note, kReferencePtrToGCManagedClassNote); + diag_own_ptr_to_gc_managed_class_note_ = diagnostic_.getCustomDiagID( + DiagnosticsEngine::Note, kOwnPtrToGCManagedClassNote); + diag_member_to_gc_unmanaged_class_note_ = diagnostic_.getCustomDiagID( + DiagnosticsEngine::Note, kMemberToGCUnmanagedClassNote); + diag_stack_allocated_field_note_ = diagnostic_.getCustomDiagID( + DiagnosticsEngine::Note, kStackAllocatedFieldNote); + diag_member_in_unmanaged_class_note_ = diagnostic_.getCustomDiagID( + DiagnosticsEngine::Note, kMemberInUnmanagedClassNote); + diag_part_object_to_gc_derived_class_note_ = diagnostic_.getCustomDiagID( + DiagnosticsEngine::Note, kPartObjectToGCDerivedClassNote); + diag_part_object_contains_gc_root_note_ = diagnostic_.getCustomDiagID( + DiagnosticsEngine::Note, kPartObjectContainsGCRootNote); + diag_field_contains_gc_root_note_ = diagnostic_.getCustomDiagID( + DiagnosticsEngine::Note, kFieldContainsGCRootNote); + diag_finalized_field_note_ = diagnostic_.getCustomDiagID( + DiagnosticsEngine::Note, kFinalizedFieldNote); + diag_eagerly_finalized_field_note_ = diagnostic_.getCustomDiagID( + DiagnosticsEngine::Note, kEagerlyFinalizedFieldNote); + diag_user_declared_destructor_note_ = diagnostic_.getCustomDiagID( + DiagnosticsEngine::Note, kUserDeclaredDestructorNote); + diag_user_declared_finalizer_note_ = diagnostic_.getCustomDiagID( + DiagnosticsEngine::Note, kUserDeclaredFinalizerNote); + diag_base_requires_finalization_note_ = diagnostic_.getCustomDiagID( + DiagnosticsEngine::Note, kBaseRequiresFinalizationNote); + diag_field_requires_finalization_note_ = diagnostic_.getCustomDiagID( + DiagnosticsEngine::Note, kFieldRequiresFinalizationNote); + diag_overridden_non_virtual_trace_note_ = diagnostic_.getCustomDiagID( + DiagnosticsEngine::Note, kOverriddenNonVirtualTraceNote); + diag_manual_dispatch_method_note_ = diagnostic_.getCustomDiagID( + DiagnosticsEngine::Note, kManualDispatchMethodNote); +} + +bool DiagnosticsReporter::hasErrorOccurred() const +{ + return diagnostic_.hasErrorOccurred(); +} + +DiagnosticsEngine::Level DiagnosticsReporter::getErrorLevel() const { + return diagnostic_.getWarningsAsErrors() ? DiagnosticsEngine::Error + : DiagnosticsEngine::Warning; +} + +void DiagnosticsReporter::ClassMustLeftMostlyDeriveGC( + RecordInfo* info) { + ReportDiagnostic(info->record()->getInnerLocStart(), + diag_class_must_left_mostly_derive_gc_) + << info->record(); +} + +void DiagnosticsReporter::ClassRequiresTraceMethod(RecordInfo* info) { + ReportDiagnostic(info->record()->getInnerLocStart(), + diag_class_requires_trace_method_) + << info->record(); + + for (auto& base : info->GetBases()) + if (base.second.NeedsTracing().IsNeeded()) + NoteBaseRequiresTracing(&base.second); + + for (auto& field : info->GetFields()) + if (!field.second.IsProperlyTraced()) + NoteFieldRequiresTracing(info, field.first); +} + +void DiagnosticsReporter::BaseRequiresTracing( + RecordInfo* derived, + CXXMethodDecl* trace, + CXXRecordDecl* base) { + ReportDiagnostic(trace->getLocStart(), diag_base_requires_tracing_) + << base << derived->record(); +} + +void DiagnosticsReporter::FieldsRequireTracing( + RecordInfo* info, + CXXMethodDecl* trace) { + ReportDiagnostic(trace->getLocStart(), diag_fields_require_tracing_) + << info->record(); + for (auto& field : info->GetFields()) + if (!field.second.IsProperlyTraced()) + NoteFieldRequiresTracing(info, field.first); +} + +void DiagnosticsReporter::ClassContainsInvalidFields( + RecordInfo* info, + const CheckFieldsVisitor::Errors& errors) { + + ReportDiagnostic(info->record()->getLocStart(), + diag_class_contains_invalid_fields_) + << info->record(); + + for (auto& error : errors) { + unsigned note; + if (error.second == CheckFieldsVisitor::kRawPtrToGCManaged) { + note = diag_raw_ptr_to_gc_managed_class_note_; + } else if (error.second == CheckFieldsVisitor::kRefPtrToGCManaged) { + note = diag_ref_ptr_to_gc_managed_class_note_; + } else if (error.second == CheckFieldsVisitor::kReferencePtrToGCManaged) { + note = diag_reference_ptr_to_gc_managed_class_note_; + } else if (error.second == CheckFieldsVisitor::kOwnPtrToGCManaged) { + note = diag_own_ptr_to_gc_managed_class_note_; + } else if (error.second == CheckFieldsVisitor::kMemberToGCUnmanaged) { + note = diag_member_to_gc_unmanaged_class_note_; + } else if (error.second == CheckFieldsVisitor::kMemberInUnmanaged) { + note = diag_member_in_unmanaged_class_note_; + } else if (error.second == CheckFieldsVisitor::kPtrFromHeapToStack) { + note = diag_stack_allocated_field_note_; + } else if (error.second == CheckFieldsVisitor::kGCDerivedPartObject) { + note = diag_part_object_to_gc_derived_class_note_; + } else { + assert(false && "Unknown field error"); + } + NoteField(error.first, note); + } +} + +void DiagnosticsReporter::ClassContainsGCRoots( + RecordInfo* info, + const CheckGCRootsVisitor::Errors& errors) { + for (auto& error : errors) { + FieldPoint* point = nullptr; + for (FieldPoint* path : error) { + if (!point) { + point = path; + ReportDiagnostic(info->record()->getLocStart(), + diag_class_contains_gc_root_) + << info->record() << point->field(); + continue; + } + NotePartObjectContainsGCRoot(point); + point = path; + } + NoteFieldContainsGCRoot(point); + } +} + +void DiagnosticsReporter::FinalizerAccessesFinalizedFields( + CXXMethodDecl* dtor, + const CheckFinalizerVisitor::Errors& errors) { + for (auto& error : errors) { + bool as_eagerly_finalized = error.as_eagerly_finalized; + unsigned diag_error = as_eagerly_finalized ? + diag_finalizer_eagerly_finalized_field_ : + diag_finalizer_accesses_finalized_field_; + unsigned diag_note = as_eagerly_finalized ? + diag_eagerly_finalized_field_note_ : + diag_finalized_field_note_; + ReportDiagnostic(error.member->getLocStart(), diag_error) + << dtor << error.field->field(); + NoteField(error.field, diag_note); + } +} + +void DiagnosticsReporter::ClassRequiresFinalization(RecordInfo* info) { + ReportDiagnostic(info->record()->getInnerLocStart(), + diag_class_requires_finalization_) + << info->record(); +} + +void DiagnosticsReporter::ClassDoesNotRequireFinalization( + RecordInfo* info) { + ReportDiagnostic(info->record()->getInnerLocStart(), + diag_class_does_not_require_finalization_) + << info->record(); +} + +void DiagnosticsReporter::OverriddenNonVirtualTrace( + RecordInfo* info, + CXXMethodDecl* trace, + CXXMethodDecl* overridden) { + ReportDiagnostic(trace->getLocStart(), diag_overridden_non_virtual_trace_) + << info->record() << overridden->getParent(); + NoteOverriddenNonVirtualTrace(overridden); +} + +void DiagnosticsReporter::MissingTraceDispatchMethod(RecordInfo* info) { + ReportMissingDispatchMethod(info, diag_missing_trace_dispatch_method_); +} + +void DiagnosticsReporter::MissingFinalizeDispatchMethod( + RecordInfo* info) { + ReportMissingDispatchMethod(info, diag_missing_finalize_dispatch_method_); +} + +void DiagnosticsReporter::ReportMissingDispatchMethod( + RecordInfo* info, + unsigned error) { + ReportDiagnostic(info->record()->getInnerLocStart(), error) + << info->record(); +} + +void DiagnosticsReporter::VirtualAndManualDispatch( + RecordInfo* info, + CXXMethodDecl* dispatch) { + ReportDiagnostic(info->record()->getInnerLocStart(), + diag_virtual_and_manual_dispatch_) + << info->record(); + NoteManualDispatchMethod(dispatch); +} + +void DiagnosticsReporter::MissingTraceDispatch( + const FunctionDecl* dispatch, + RecordInfo* receiver) { + ReportMissingDispatch(dispatch, receiver, diag_missing_trace_dispatch_); +} + +void DiagnosticsReporter::MissingFinalizeDispatch( + const FunctionDecl* dispatch, + RecordInfo* receiver) { + ReportMissingDispatch(dispatch, receiver, diag_missing_finalize_dispatch_); +} + +void DiagnosticsReporter::ReportMissingDispatch( + const FunctionDecl* dispatch, + RecordInfo* receiver, + unsigned error) { + ReportDiagnostic(dispatch->getLocStart(), error) << receiver->record(); +} + +void DiagnosticsReporter::DerivesNonStackAllocated( + RecordInfo* info, + BasePoint* base) { + ReportDiagnostic(base->spec().getLocStart(), + diag_derives_non_stack_allocated_) + << info->record() << base->info()->record(); +} + +void DiagnosticsReporter::ClassOverridesNew( + RecordInfo* info, + CXXMethodDecl* newop) { + ReportDiagnostic(newop->getLocStart(), diag_class_overrides_new_) + << info->record(); +} + +void DiagnosticsReporter::ClassDeclaresPureVirtualTrace( + RecordInfo* info, + CXXMethodDecl* trace) { + ReportDiagnostic(trace->getLocStart(), + diag_class_declares_pure_virtual_trace_) + << info->record(); +} + +void DiagnosticsReporter::LeftMostBaseMustBePolymorphic( + RecordInfo* derived, + CXXRecordDecl* base) { + ReportDiagnostic(base->getLocStart(), + diag_left_most_base_must_be_polymorphic_) + << base << derived->record(); +} + +void DiagnosticsReporter::BaseClassMustDeclareVirtualTrace( + RecordInfo* derived, + CXXRecordDecl* base) { + ReportDiagnostic(base->getLocStart(), + diag_base_class_must_declare_virtual_trace_) + << base << derived->record(); +} + +void DiagnosticsReporter::NoteManualDispatchMethod(CXXMethodDecl* dispatch) { + ReportDiagnostic(dispatch->getLocStart(), + diag_manual_dispatch_method_note_) + << dispatch; +} + +void DiagnosticsReporter::NoteBaseRequiresTracing(BasePoint* base) { + ReportDiagnostic(base->spec().getLocStart(), + diag_base_requires_tracing_note_) + << base->info()->record(); +} + +void DiagnosticsReporter::NoteFieldRequiresTracing( + RecordInfo* holder, + FieldDecl* field) { + NoteField(field, diag_field_requires_tracing_note_); +} + +void DiagnosticsReporter::NotePartObjectContainsGCRoot(FieldPoint* point) { + FieldDecl* field = point->field(); + ReportDiagnostic(field->getLocStart(), + diag_part_object_contains_gc_root_note_) + << field << field->getParent(); +} + +void DiagnosticsReporter::NoteFieldContainsGCRoot(FieldPoint* point) { + NoteField(point, diag_field_contains_gc_root_note_); +} + +void DiagnosticsReporter::NoteUserDeclaredDestructor(CXXMethodDecl* dtor) { + ReportDiagnostic(dtor->getLocStart(), diag_user_declared_destructor_note_); +} + +void DiagnosticsReporter::NoteUserDeclaredFinalizer(CXXMethodDecl* dtor) { + ReportDiagnostic(dtor->getLocStart(), diag_user_declared_finalizer_note_); +} + +void DiagnosticsReporter::NoteBaseRequiresFinalization(BasePoint* base) { + ReportDiagnostic(base->spec().getLocStart(), + diag_base_requires_finalization_note_) + << base->info()->record(); +} + +void DiagnosticsReporter::NoteFieldRequiresFinalization(FieldPoint* point) { + NoteField(point, diag_field_requires_finalization_note_); +} + +void DiagnosticsReporter::NoteField(FieldPoint* point, unsigned note) { + NoteField(point->field(), note); +} + +void DiagnosticsReporter::NoteField(FieldDecl* field, unsigned note) { + ReportDiagnostic(field->getLocStart(), note) << field; +} + +void DiagnosticsReporter::NoteOverriddenNonVirtualTrace( + CXXMethodDecl* overridden) { + ReportDiagnostic(overridden->getLocStart(), + diag_overridden_non_virtual_trace_note_) + << overridden; +}
diff --git a/tools/clang/blink_gc_plugin/DiagnosticsReporter.h b/tools/clang/blink_gc_plugin/DiagnosticsReporter.h new file mode 100644 index 0000000..2f9076ec --- /dev/null +++ b/tools/clang/blink_gc_plugin/DiagnosticsReporter.h
@@ -0,0 +1,137 @@ +// Copyright 2016 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef TOOLS_BLINK_GC_PLUGIN_DIAGNOSTICS_REPORTER_H_ +#define TOOLS_BLINK_GC_PLUGIN_DIAGNOSTICS_REPORTER_H_ + +#include "CheckFieldsVisitor.h" +#include "CheckFinalizerVisitor.h" +#include "CheckGCRootsVisitor.h" +#include "Config.h" +#include "clang/AST/AST.h" +#include "clang/AST/ASTConsumer.h" +#include "clang/Basic/Diagnostic.h" +#include "clang/Frontend/CompilerInstance.h" + +class RecordInfo; + +// All error/warning reporting methods under one roof. +// +class DiagnosticsReporter { + public: + explicit DiagnosticsReporter(clang::CompilerInstance&); + + bool hasErrorOccurred() const; + clang::DiagnosticsEngine::Level getErrorLevel() const; + + void ClassMustLeftMostlyDeriveGC(RecordInfo* info); + void ClassRequiresTraceMethod(RecordInfo* info); + void BaseRequiresTracing(RecordInfo* derived, + clang::CXXMethodDecl* trace, + clang::CXXRecordDecl* base); + void FieldsRequireTracing(RecordInfo* info, + clang::CXXMethodDecl* trace); + void ClassContainsInvalidFields( + RecordInfo* info, + const CheckFieldsVisitor::Errors& errors); + void ClassContainsGCRoots(RecordInfo* info, + const CheckGCRootsVisitor::Errors& errors); + void FinalizerAccessesFinalizedFields( + clang::CXXMethodDecl* dtor, + const CheckFinalizerVisitor::Errors& errors); + void ClassRequiresFinalization(RecordInfo* info); + void ClassDoesNotRequireFinalization(RecordInfo* info); + void ClassMustDeclareGCMixinTraceMethod(RecordInfo* info); + void OverriddenNonVirtualTrace(RecordInfo* info, + clang::CXXMethodDecl* trace, + clang::CXXMethodDecl* overridden); + void MissingTraceDispatchMethod(RecordInfo* info); + void MissingFinalizeDispatchMethod(RecordInfo* info); + void VirtualAndManualDispatch(RecordInfo* info, + clang::CXXMethodDecl* dispatch); + void MissingTraceDispatch(const clang::FunctionDecl* dispatch, + RecordInfo* receiver); + void MissingFinalizeDispatch(const clang::FunctionDecl* dispatch, + RecordInfo* receiver); + void DerivesNonStackAllocated(RecordInfo* info, BasePoint* base); + void ClassOverridesNew(RecordInfo* info, clang::CXXMethodDecl* newop); + void ClassDeclaresPureVirtualTrace(RecordInfo* info, + clang::CXXMethodDecl* trace); + void LeftMostBaseMustBePolymorphic(RecordInfo* derived, + clang::CXXRecordDecl* base); + void BaseClassMustDeclareVirtualTrace(RecordInfo* derived, + clang::CXXRecordDecl* base); + + void NoteManualDispatchMethod(clang::CXXMethodDecl* dispatch); + void NoteBaseRequiresTracing(BasePoint* base); + void NoteFieldRequiresTracing(RecordInfo* holder, clang::FieldDecl* field); + void NotePartObjectContainsGCRoot(FieldPoint* point); + void NoteFieldContainsGCRoot(FieldPoint* point); + void NoteUserDeclaredDestructor(clang::CXXMethodDecl* dtor); + void NoteUserDeclaredFinalizer(clang::CXXMethodDecl* dtor); + void NoteBaseRequiresFinalization(BasePoint* base); + void NoteFieldRequiresFinalization(FieldPoint* field); + void NoteField(FieldPoint* point, unsigned note); + void NoteField(clang::FieldDecl* field, unsigned note); + void NoteOverriddenNonVirtualTrace(clang::CXXMethodDecl* overridden); + + private: + clang::DiagnosticBuilder ReportDiagnostic( + clang::SourceLocation location, + unsigned diag_id); + + void ReportMissingDispatchMethod(RecordInfo* info, unsigned error); + void ReportMissingDispatch(const clang::FunctionDecl* dispatch, + RecordInfo* receiver, + unsigned error); + + clang::CompilerInstance& instance_; + clang::DiagnosticsEngine& diagnostic_; + + unsigned diag_class_must_left_mostly_derive_gc_; + unsigned diag_class_requires_trace_method_; + unsigned diag_base_requires_tracing_; + unsigned diag_fields_require_tracing_; + unsigned diag_class_contains_invalid_fields_; + unsigned diag_class_contains_gc_root_; + unsigned diag_class_requires_finalization_; + unsigned diag_class_does_not_require_finalization_; + unsigned diag_finalizer_accesses_finalized_field_; + unsigned diag_finalizer_eagerly_finalized_field_; + unsigned diag_overridden_non_virtual_trace_; + unsigned diag_missing_trace_dispatch_method_; + unsigned diag_missing_finalize_dispatch_method_; + unsigned diag_virtual_and_manual_dispatch_; + unsigned diag_missing_trace_dispatch_; + unsigned diag_missing_finalize_dispatch_; + unsigned diag_derives_non_stack_allocated_; + unsigned diag_class_overrides_new_; + unsigned diag_class_declares_pure_virtual_trace_; + unsigned diag_left_most_base_must_be_polymorphic_; + unsigned diag_base_class_must_declare_virtual_trace_; + + unsigned diag_base_requires_tracing_note_; + unsigned diag_field_requires_tracing_note_; + unsigned diag_raw_ptr_to_gc_managed_class_note_; + unsigned diag_ref_ptr_to_gc_managed_class_note_; + unsigned diag_reference_ptr_to_gc_managed_class_note_; + unsigned diag_own_ptr_to_gc_managed_class_note_; + unsigned diag_member_to_gc_unmanaged_class_note_; + unsigned diag_stack_allocated_field_note_; + unsigned diag_member_in_unmanaged_class_note_; + unsigned diag_part_object_to_gc_derived_class_note_; + unsigned diag_part_object_contains_gc_root_note_; + unsigned diag_field_contains_gc_root_note_; + unsigned diag_finalized_field_note_; + unsigned diag_eagerly_finalized_field_note_; + unsigned diag_user_declared_destructor_note_; + unsigned diag_user_declared_finalizer_note_; + unsigned diag_base_requires_finalization_note_; + unsigned diag_field_requires_finalization_note_; + unsigned diag_overridden_non_virtual_trace_note_; + unsigned diag_manual_dispatch_method_note_; + +}; + +#endif // TOOLS_BLINK_GC_PLUGIN_DIAGNOSTICS_REPORTER_H_
diff --git a/tools/metrics/histograms/histograms.xml b/tools/metrics/histograms/histograms.xml index 07be7876..7155726 100644 --- a/tools/metrics/histograms/histograms.xml +++ b/tools/metrics/histograms/histograms.xml
@@ -92427,6 +92427,8 @@ <suffix name="websame" label="Link triggered prerender, rel=prerender, same domain."/> <suffix name="webnext" label="Link triggered prerender, rel=next."/> + <suffix name="offline" + label="Prerender triggered for saving a page for offline use."/> <affected-histogram name="Prerender.AbandonTimeUntilUsed"/> <affected-histogram name="Prerender.CookieSendType"/> <affected-histogram name="Prerender.CookieStatus"/>
diff --git a/ui/gfx/ipc/gfx_param_traits_macros.h b/ui/gfx/ipc/gfx_param_traits_macros.h index cf8dec7b..f717960e 100644 --- a/ui/gfx/ipc/gfx_param_traits_macros.h +++ b/ui/gfx/ipc/gfx_param_traits_macros.h
@@ -9,6 +9,7 @@ #define UI_GFX_IPC_GFX_PARAM_TRAITS_MACROS_H_ #include "ui/gfx/buffer_types.h" +#include "ui/gfx/gpu_memory_buffer.h" #include "ui/gfx/ipc/gfx_ipc_export.h" #include "ipc/ipc_message_macros.h" @@ -23,6 +24,26 @@ IPC_ENUM_TRAITS_MAX_VALUE(gfx::BufferUsage, gfx::BufferUsage::LAST) +IPC_ENUM_TRAITS_MAX_VALUE(gfx::GpuMemoryBufferType, + gfx::GPU_MEMORY_BUFFER_TYPE_LAST) + +IPC_STRUCT_TRAITS_BEGIN(gfx::GpuMemoryBufferHandle) + IPC_STRUCT_TRAITS_MEMBER(id) + IPC_STRUCT_TRAITS_MEMBER(type) + IPC_STRUCT_TRAITS_MEMBER(handle) + IPC_STRUCT_TRAITS_MEMBER(offset) + IPC_STRUCT_TRAITS_MEMBER(stride) +#if defined(USE_OZONE) + IPC_STRUCT_TRAITS_MEMBER(native_pixmap_handle) +#elif defined(OS_MACOSX) + IPC_STRUCT_TRAITS_MEMBER(mach_port) +#endif +IPC_STRUCT_TRAITS_END() + +IPC_STRUCT_TRAITS_BEGIN(gfx::GpuMemoryBufferId) + IPC_STRUCT_TRAITS_MEMBER(id) +IPC_STRUCT_TRAITS_END() + #if defined(USE_OZONE) IPC_STRUCT_TRAITS_BEGIN(gfx::NativePixmapHandle) IPC_STRUCT_TRAITS_MEMBER(fd)
diff --git a/ui/gl/generate_bindings.py b/ui/gl/generate_bindings.py index be41ea46..1b28d2a 100755 --- a/ui/gl/generate_bindings.py +++ b/ui/gl/generate_bindings.py
@@ -116,6 +116,10 @@ 'versions': [{ 'name': 'glBindTransformFeedback' }], 'arguments': 'GLenum target, GLuint id', }, { 'return_type': 'void', + 'versions': [{ 'name': 'glBindUniformLocationCHROMIUM', + 'extensions': ['GL_CHROMIUM_bind_uniform_location'] }], + 'arguments': 'GLuint program, GLint location, const char* name' }, +{ 'return_type': 'void', 'known_as': 'glBindVertexArrayOES', 'versions': [{ 'name': 'glBindVertexArray', 'extensions': ['GL_ARB_vertex_array_object'], },
diff --git a/ui/gl/gl_bindings_api_autogen_gl.h b/ui/gl/gl_bindings_api_autogen_gl.h index a513ed20..ed809dd 100644 --- a/ui/gl/gl_bindings_api_autogen_gl.h +++ b/ui/gl/gl_bindings_api_autogen_gl.h
@@ -42,6 +42,9 @@ void glBindSamplerFn(GLuint unit, GLuint sampler) override; void glBindTextureFn(GLenum target, GLuint texture) override; void glBindTransformFeedbackFn(GLenum target, GLuint id) override; +void glBindUniformLocationCHROMIUMFn(GLuint program, + GLint location, + const char* name) override; void glBindVertexArrayOESFn(GLuint array) override; void glBlendBarrierKHRFn(void) override; void glBlendColorFn(GLclampf red,
diff --git a/ui/gl/gl_bindings_autogen_gl.cc b/ui/gl/gl_bindings_autogen_gl.cc index e0a78b0..42b0e27 100644 --- a/ui/gl/gl_bindings_autogen_gl.cc +++ b/ui/gl/gl_bindings_autogen_gl.cc
@@ -46,6 +46,7 @@ fn.glBindTextureFn = reinterpret_cast<glBindTextureProc>(GetGLProcAddress("glBindTexture")); fn.glBindTransformFeedbackFn = 0; + fn.glBindUniformLocationCHROMIUMFn = 0; fn.glBindVertexArrayOESFn = 0; fn.glBlendBarrierKHRFn = 0; fn.glBlendColorFn = @@ -513,6 +514,9 @@ extensions.find("GL_ARB_timer_query ") != std::string::npos; ext.b_GL_ARB_vertex_array_object = extensions.find("GL_ARB_vertex_array_object ") != std::string::npos; + ext.b_GL_CHROMIUM_bind_uniform_location = + extensions.find("GL_CHROMIUM_bind_uniform_location ") != + std::string::npos; ext.b_GL_CHROMIUM_gles_depth_binding_hack = extensions.find("GL_CHROMIUM_gles_depth_binding_hack ") != std::string::npos; @@ -680,6 +684,13 @@ GetGLProcAddress("glBindTransformFeedback")); } + debug_fn.glBindUniformLocationCHROMIUMFn = 0; + if (ext.b_GL_CHROMIUM_bind_uniform_location) { + fn.glBindUniformLocationCHROMIUMFn = + reinterpret_cast<glBindUniformLocationCHROMIUMProc>( + GetGLProcAddress("glBindUniformLocationCHROMIUM")); + } + debug_fn.glBindVertexArrayOESFn = 0; if (ver->IsAtLeastGL(3u, 0u) || ver->IsAtLeastGLES(3u, 0u) || ext.b_GL_ARB_vertex_array_object) { @@ -2200,6 +2211,16 @@ g_driver_gl.debug_fn.glBindTransformFeedbackFn(target, id); } +static void GL_BINDING_CALL +Debug_glBindUniformLocationCHROMIUM(GLuint program, + GLint location, + const char* name) { + GL_SERVICE_LOG("glBindUniformLocationCHROMIUM" + << "(" << program << ", " << location << ", " << name << ")"); + DCHECK(g_driver_gl.debug_fn.glBindUniformLocationCHROMIUMFn != nullptr); + g_driver_gl.debug_fn.glBindUniformLocationCHROMIUMFn(program, location, name); +} + static void GL_BINDING_CALL Debug_glBindVertexArrayOES(GLuint array) { GL_SERVICE_LOG("glBindVertexArrayOES" << "(" << array << ")"); @@ -5580,6 +5601,11 @@ debug_fn.glBindTransformFeedbackFn = fn.glBindTransformFeedbackFn; fn.glBindTransformFeedbackFn = Debug_glBindTransformFeedback; } + if (!debug_fn.glBindUniformLocationCHROMIUMFn) { + debug_fn.glBindUniformLocationCHROMIUMFn = + fn.glBindUniformLocationCHROMIUMFn; + fn.glBindUniformLocationCHROMIUMFn = Debug_glBindUniformLocationCHROMIUM; + } if (!debug_fn.glBindVertexArrayOESFn) { debug_fn.glBindVertexArrayOESFn = fn.glBindVertexArrayOESFn; fn.glBindVertexArrayOESFn = Debug_glBindVertexArrayOES; @@ -6899,6 +6925,12 @@ driver_->fn.glBindTransformFeedbackFn(target, id); } +void GLApiBase::glBindUniformLocationCHROMIUMFn(GLuint program, + GLint location, + const char* name) { + driver_->fn.glBindUniformLocationCHROMIUMFn(program, location, name); +} + void GLApiBase::glBindVertexArrayOESFn(GLuint array) { driver_->fn.glBindVertexArrayOESFn(array); } @@ -8807,6 +8839,14 @@ gl_api_->glBindTransformFeedbackFn(target, id); } +void TraceGLApi::glBindUniformLocationCHROMIUMFn(GLuint program, + GLint location, + const char* name) { + TRACE_EVENT_BINARY_EFFICIENT0("gpu", + "TraceGLAPI::glBindUniformLocationCHROMIUM") + gl_api_->glBindUniformLocationCHROMIUMFn(program, location, name); +} + void TraceGLApi::glBindVertexArrayOESFn(GLuint array) { TRACE_EVENT_BINARY_EFFICIENT0("gpu", "TraceGLAPI::glBindVertexArrayOES") gl_api_->glBindVertexArrayOESFn(array); @@ -11060,6 +11100,15 @@ << "Trying to call glBindTransformFeedback() without current GL context"; } +void NoContextGLApi::glBindUniformLocationCHROMIUMFn(GLuint program, + GLint location, + const char* name) { + NOTREACHED() << "Trying to call glBindUniformLocationCHROMIUM() without " + "current GL context"; + LOG(ERROR) << "Trying to call glBindUniformLocationCHROMIUM() without " + "current GL context"; +} + void NoContextGLApi::glBindVertexArrayOESFn(GLuint array) { NOTREACHED() << "Trying to call glBindVertexArrayOES() without current GL context";
diff --git a/ui/gl/gl_bindings_autogen_gl.h b/ui/gl/gl_bindings_autogen_gl.h index 28393dca..7019e7d 100644 --- a/ui/gl/gl_bindings_autogen_gl.h +++ b/ui/gl/gl_bindings_autogen_gl.h
@@ -57,6 +57,10 @@ typedef void(GL_BINDING_CALL* glBindTextureProc)(GLenum target, GLuint texture); typedef void(GL_BINDING_CALL* glBindTransformFeedbackProc)(GLenum target, GLuint id); +typedef void(GL_BINDING_CALL* glBindUniformLocationCHROMIUMProc)( + GLuint program, + GLint location, + const char* name); typedef void(GL_BINDING_CALL* glBindVertexArrayOESProc)(GLuint array); typedef void(GL_BINDING_CALL* glBlendBarrierKHRProc)(void); typedef void(GL_BINDING_CALL* glBlendColorProc)(GLclampf red, @@ -1057,6 +1061,7 @@ bool b_GL_ARB_texture_storage; bool b_GL_ARB_timer_query; bool b_GL_ARB_vertex_array_object; + bool b_GL_CHROMIUM_bind_uniform_location; bool b_GL_CHROMIUM_gles_depth_binding_hack; bool b_GL_CHROMIUM_glgetstringi_hack; bool b_GL_EXT_blend_func_extended; @@ -1110,6 +1115,7 @@ glBindSamplerProc glBindSamplerFn; glBindTextureProc glBindTextureFn; glBindTransformFeedbackProc glBindTransformFeedbackFn; + glBindUniformLocationCHROMIUMProc glBindUniformLocationCHROMIUMFn; glBindVertexArrayOESProc glBindVertexArrayOESFn; glBlendBarrierKHRProc glBlendBarrierKHRFn; glBlendColorProc glBlendColorFn; @@ -1459,6 +1465,9 @@ virtual void glBindSamplerFn(GLuint unit, GLuint sampler) = 0; virtual void glBindTextureFn(GLenum target, GLuint texture) = 0; virtual void glBindTransformFeedbackFn(GLenum target, GLuint id) = 0; + virtual void glBindUniformLocationCHROMIUMFn(GLuint program, + GLint location, + const char* name) = 0; virtual void glBindVertexArrayOESFn(GLuint array) = 0; virtual void glBlendBarrierKHRFn(void) = 0; virtual void glBlendColorFn(GLclampf red, @@ -2352,6 +2361,8 @@ #define glBindTexture ::gfx::g_current_gl_context->glBindTextureFn #define glBindTransformFeedback \ ::gfx::g_current_gl_context->glBindTransformFeedbackFn +#define glBindUniformLocationCHROMIUM \ + ::gfx::g_current_gl_context->glBindUniformLocationCHROMIUMFn #define glBindVertexArrayOES ::gfx::g_current_gl_context->glBindVertexArrayOESFn #define glBlendBarrierKHR ::gfx::g_current_gl_context->glBlendBarrierKHRFn #define glBlendColor ::gfx::g_current_gl_context->glBlendColorFn
diff --git a/ui/gl/gl_bindings_autogen_mock.cc b/ui/gl/gl_bindings_autogen_mock.cc index d813760..6098236 100644 --- a/ui/gl/gl_bindings_autogen_mock.cc +++ b/ui/gl/gl_bindings_autogen_mock.cc
@@ -194,6 +194,14 @@ interface_->BindTransformFeedback(target, id); } +void GL_BINDING_CALL +MockGLInterface::Mock_glBindUniformLocationCHROMIUM(GLuint program, + GLint location, + const char* name) { + MakeFunctionUnique("glBindUniformLocationCHROMIUM"); + interface_->BindUniformLocationCHROMIUM(program, location, name); +} + void GL_BINDING_CALL MockGLInterface::Mock_glBindVertexArray(GLuint array) { MakeFunctionUnique("glBindVertexArray"); interface_->BindVertexArrayOES(array); @@ -2959,6 +2967,8 @@ return reinterpret_cast<void*>(Mock_glBindTexture); if (strcmp(name, "glBindTransformFeedback") == 0) return reinterpret_cast<void*>(Mock_glBindTransformFeedback); + if (strcmp(name, "glBindUniformLocationCHROMIUM") == 0) + return reinterpret_cast<void*>(Mock_glBindUniformLocationCHROMIUM); if (strcmp(name, "glBindVertexArray") == 0) return reinterpret_cast<void*>(Mock_glBindVertexArray); if (strcmp(name, "glBindVertexArrayAPPLE") == 0)
diff --git a/ui/gl/gl_bindings_autogen_mock.h b/ui/gl/gl_bindings_autogen_mock.h index 88a06fef..2a05128f 100644 --- a/ui/gl/gl_bindings_autogen_mock.h +++ b/ui/gl/gl_bindings_autogen_mock.h
@@ -69,6 +69,10 @@ static void GL_BINDING_CALL Mock_glBindTexture(GLenum target, GLuint texture); static void GL_BINDING_CALL Mock_glBindTransformFeedback(GLenum target, GLuint id); +static void GL_BINDING_CALL +Mock_glBindUniformLocationCHROMIUM(GLuint program, + GLint location, + const char* name); static void GL_BINDING_CALL Mock_glBindVertexArray(GLuint array); static void GL_BINDING_CALL Mock_glBindVertexArrayAPPLE(GLuint array); static void GL_BINDING_CALL Mock_glBindVertexArrayOES(GLuint array);
diff --git a/ui/gl/gl_mock_autogen_gl.h b/ui/gl/gl_mock_autogen_gl.h index 2a5a445..5490842 100644 --- a/ui/gl/gl_mock_autogen_gl.h +++ b/ui/gl/gl_mock_autogen_gl.h
@@ -41,6 +41,8 @@ MOCK_METHOD2(BindSampler, void(GLuint unit, GLuint sampler)); MOCK_METHOD2(BindTexture, void(GLenum target, GLuint texture)); MOCK_METHOD2(BindTransformFeedback, void(GLenum target, GLuint id)); +MOCK_METHOD3(BindUniformLocationCHROMIUM, + void(GLuint program, GLint location, const char* name)); MOCK_METHOD1(BindVertexArrayOES, void(GLuint array)); MOCK_METHOD0(BlendBarrierKHR, void()); MOCK_METHOD4(BlendColor,
diff --git a/ui/views/animation/flood_fill_ink_drop_animation.cc b/ui/views/animation/flood_fill_ink_drop_animation.cc index 4520fb4..6e177aaf 100644 --- a/ui/views/animation/flood_fill_ink_drop_animation.cc +++ b/ui/views/animation/flood_fill_ink_drop_animation.cc
@@ -107,26 +107,22 @@ namespace views { FloodFillInkDropAnimation::FloodFillInkDropAnimation( - const gfx::Size& size, + const gfx::Rect& clip_bounds, const gfx::Point& center_point, SkColor color) - : size_(size), + : clip_bounds_(clip_bounds), center_point_(center_point), root_layer_(ui::LAYER_NOT_DRAWN), - circle_layer_delegate_(color, - std::max(size_.width(), size_.height()) / 2.f), + circle_layer_delegate_( + color, + std::max(clip_bounds_.width(), clip_bounds_.height()) / 2.f), ink_drop_state_(InkDropState::HIDDEN) { root_layer_.set_name("FloodFillInkDropAnimation:ROOT_LAYER"); root_layer_.SetMasksToBounds(true); - root_layer_.SetBounds(gfx::Rect(size_)); + root_layer_.SetBounds(clip_bounds); - const gfx::Vector2dF translate_vector = - center_point_ - root_layer_.bounds().CenterPoint(); - gfx::Transform transfrom; - transfrom.Translate(translate_vector.x(), translate_vector.y()); - root_layer_.SetTransform(transfrom); - - const int painted_size_length = 2 * std::max(size_.width(), size_.height()); + const int painted_size_length = + 2 * std::max(clip_bounds_.width(), clip_bounds_.height()); painted_layer_.SetBounds(gfx::Rect(painted_size_length, painted_size_length)); painted_layer_.SetFillsBoundsOpaquely(false); @@ -313,10 +309,10 @@ ToRoundedPoint(circle_layer_delegate_.GetCenterPoint()); gfx::Transform transform = gfx::Transform(); - transform.Translate(root_layer_.bounds().CenterPoint().x(), - root_layer_.bounds().CenterPoint().y()); + transform.Translate(center_point_.x(), center_point_.y()); transform.Scale(target_scale, target_scale); - transform.Translate(-drawn_center_point.x(), -drawn_center_point.y()); + transform.Translate(-drawn_center_point.x() - root_layer_.bounds().x(), + -drawn_center_point.y() - root_layer_.bounds().y()); return transform; } @@ -325,7 +321,7 @@ // TODO(estade): get rid of this 2, but make the fade out start before the // active/action transform is done. return CalculateTransform( - gfx::Vector2dF(size_.width(), size_.height()).Length() / 2); + gfx::Vector2dF(clip_bounds_.width(), clip_bounds_.height()).Length() / 2); } } // namespace views
diff --git a/ui/views/animation/flood_fill_ink_drop_animation.h b/ui/views/animation/flood_fill_ink_drop_animation.h index 97a4cd08..303f295 100644 --- a/ui/views/animation/flood_fill_ink_drop_animation.h +++ b/ui/views/animation/flood_fill_ink_drop_animation.h
@@ -48,7 +48,7 @@ // class VIEWS_EXPORT FloodFillInkDropAnimation : public InkDropAnimation { public: - FloodFillInkDropAnimation(const gfx::Size& size, + FloodFillInkDropAnimation(const gfx::Rect& clip_bounds, const gfx::Point& center_point, SkColor color); ~FloodFillInkDropAnimation() override; @@ -101,8 +101,8 @@ // Returns the target Transform for when the ink drop is fully shown. gfx::Transform GetMaxSizeTargetTransform() const; - // The clip Size. - const gfx::Size size_; + // The clip bounds. + const gfx::Rect clip_bounds_; // The point where the Center of the ink drop's circle should be drawn. gfx::Point center_point_;
diff --git a/ui/views/animation/ink_drop_animation.cc b/ui/views/animation/ink_drop_animation.cc index 717b905..214716da 100644 --- a/ui/views/animation/ink_drop_animation.cc +++ b/ui/views/animation/ink_drop_animation.cc
@@ -91,6 +91,10 @@ target_ink_drop_state_ = InkDropState::HIDDEN; } +test::InkDropAnimationTestApi* InkDropAnimation::GetTestApi() { + return nullptr; +} + void InkDropAnimation::AnimationStartedCallback( InkDropState ink_drop_state, const ui::CallbackLayerAnimationObserver& observer) {
diff --git a/ui/views/animation/ink_drop_animation.h b/ui/views/animation/ink_drop_animation.h index 3d4c62fc..b00be7d 100644 --- a/ui/views/animation/ink_drop_animation.h +++ b/ui/views/animation/ink_drop_animation.h
@@ -19,6 +19,10 @@ namespace views { +namespace test { +class InkDropAnimationTestApi; +} // namespace test + // Simple base class for animations that provide visual feedback for View state. // Manages the attached InkDropAnimationObservers. // @@ -81,6 +85,11 @@ // animates to the target HIDDEN state. virtual bool IsVisible() const = 0; + // Returns a test api to access internals of this. Default implmentations + // should return nullptr and test specific subclasses can override to return + // an instance. + virtual test::InkDropAnimationTestApi* GetTestApi(); + protected: // Animates the ripple from the |old_ink_drop_state| to the // |new_ink_drop_state|. |observer| is added to all LayerAnimationSequence's
diff --git a/ui/views/animation/ink_drop_animation_controller_impl.h b/ui/views/animation/ink_drop_animation_controller_impl.h index 41bd3f2..e075975 100644 --- a/ui/views/animation/ink_drop_animation_controller_impl.h +++ b/ui/views/animation/ink_drop_animation_controller_impl.h
@@ -19,6 +19,10 @@ } // namespace base namespace views { +namespace test { +class InkDropAnimationControllerImplTestApi; +} // namespace test + class InkDropAnimation; class InkDropHost; class InkDropHover; @@ -42,8 +46,7 @@ void SetHovered(bool is_hovered) override; private: - friend class InkDropAnimationControllerFactoryTest; - friend class InkDropAnimationControllerImplTest; + friend class test::InkDropAnimationControllerImplTestApi; // Destroys |ink_drop_animation_| if it's targeted to the HIDDEN state. void DestroyHiddenTargetedAnimations();
diff --git a/ui/views/animation/ink_drop_animation_controller_impl_unittest.cc b/ui/views/animation/ink_drop_animation_controller_impl_unittest.cc index 923315b..8ceab47 100644 --- a/ui/views/animation/ink_drop_animation_controller_impl_unittest.cc +++ b/ui/views/animation/ink_drop_animation_controller_impl_unittest.cc
@@ -8,7 +8,8 @@ #include "base/test/test_simple_task_runner.h" #include "base/thread_task_runner_handle.h" #include "testing/gtest/include/gtest/gtest.h" -#include "ui/compositor/scoped_animation_duration_scale_mode.h" +#include "ui/views/animation/ink_drop_animation.h" +#include "ui/views/animation/test/ink_drop_animation_controller_impl_test_api.h" #include "ui/views/animation/test/test_ink_drop_host.h" namespace views { @@ -23,17 +24,12 @@ protected: TestInkDropHost ink_drop_host_; - bool is_hover_fading_in_or_visible() { - return ink_drop_animation_controller_.IsHoverFadingInOrVisible(); - } - - const InkDropHover* hover() const { - return ink_drop_animation_controller_.hover_.get(); - } - // The test target. InkDropAnimationControllerImpl ink_drop_animation_controller_; + // Allows privileged access to the the |ink_drop_hover_|. + test::InkDropAnimationControllerImplTestApi test_api_; + // Used to control the tasks scheduled by the InkDropAnimationControllerImpl's // Timer. scoped_refptr<base::TestSimpleTaskRunner> task_runner_; @@ -42,19 +38,16 @@ std::unique_ptr<base::ThreadTaskRunnerHandle> thread_task_runner_handle_; private: - // Ensures all animations complete immediately. - std::unique_ptr<ui::ScopedAnimationDurationScaleMode> zero_duration_mode_; - DISALLOW_COPY_AND_ASSIGN(InkDropAnimationControllerImplTest); }; InkDropAnimationControllerImplTest::InkDropAnimationControllerImplTest() : ink_drop_animation_controller_(&ink_drop_host_), + test_api_(&ink_drop_animation_controller_), task_runner_(new base::TestSimpleTaskRunner), thread_task_runner_handle_( new base::ThreadTaskRunnerHandle(task_runner_)) { - zero_duration_mode_.reset(new ui::ScopedAnimationDurationScaleMode( - ui::ScopedAnimationDurationScaleMode::ZERO_DURATION)); + ink_drop_host_.set_disable_timers_for_test(true); } InkDropAnimationControllerImplTest::~InkDropAnimationControllerImplTest() {} @@ -63,10 +56,12 @@ ink_drop_host_.set_should_show_hover(true); ink_drop_animation_controller_.SetHovered(true); - EXPECT_TRUE(is_hover_fading_in_or_visible()); + EXPECT_TRUE(test_api_.IsHoverFadingInOrVisible()); + + test_api_.CompleteAnimations(); ink_drop_animation_controller_.SetHovered(false); - EXPECT_FALSE(is_hover_fading_in_or_visible()); + EXPECT_FALSE(test_api_.IsHoverFadingInOrVisible()); } TEST_F(InkDropAnimationControllerImplTest, @@ -74,9 +69,10 @@ ink_drop_host_.set_should_show_hover(true); ink_drop_animation_controller_.SetHovered(false); ink_drop_animation_controller_.AnimateToState(InkDropState::ACTION_TRIGGERED); + test_api_.CompleteAnimations(); EXPECT_FALSE(task_runner_->HasPendingTask()); - EXPECT_FALSE(is_hover_fading_in_or_visible()); + EXPECT_FALSE(test_api_.IsHoverFadingInOrVisible()); } TEST_F(InkDropAnimationControllerImplTest, @@ -84,12 +80,13 @@ ink_drop_host_.set_should_show_hover(true); ink_drop_animation_controller_.SetHovered(true); ink_drop_animation_controller_.AnimateToState(InkDropState::ACTION_TRIGGERED); + test_api_.CompleteAnimations(); EXPECT_TRUE(task_runner_->HasPendingTask()); task_runner_->RunPendingTasks(); - EXPECT_TRUE(is_hover_fading_in_or_visible()); + EXPECT_TRUE(test_api_.IsHoverFadingInOrVisible()); } TEST_F(InkDropAnimationControllerImplTest, @@ -97,12 +94,13 @@ ink_drop_host_.set_should_show_hover(false); ink_drop_animation_controller_.SetHovered(true); ink_drop_animation_controller_.AnimateToState(InkDropState::ACTION_TRIGGERED); + test_api_.CompleteAnimations(); EXPECT_TRUE(task_runner_->HasPendingTask()); task_runner_->RunPendingTasks(); - EXPECT_FALSE(is_hover_fading_in_or_visible()); + EXPECT_FALSE(test_api_.IsHoverFadingInOrVisible()); } TEST_F(InkDropAnimationControllerImplTest, @@ -110,10 +108,11 @@ ink_drop_host_.set_should_show_hover(true); ink_drop_animation_controller_.SetHovered(true); - EXPECT_TRUE(is_hover_fading_in_or_visible()); + test_api_.CompleteAnimations(); + EXPECT_TRUE(test_api_.IsHoverFadingInOrVisible()); ink_drop_animation_controller_.AnimateToState(InkDropState::ACTION_TRIGGERED); - EXPECT_FALSE(is_hover_fading_in_or_visible()); + EXPECT_FALSE(test_api_.IsHoverFadingInOrVisible()); } // Verifies that there is not a crash when setting hovered state and the host @@ -122,20 +121,21 @@ SetHoveredFalseWorksWhenNoInkDropHoverExists) { ink_drop_host_.set_should_show_hover(false); ink_drop_animation_controller_.SetHovered(true); - EXPECT_FALSE(hover()); + EXPECT_FALSE(test_api_.hover()); ink_drop_animation_controller_.SetHovered(false); - EXPECT_FALSE(hover()); + EXPECT_FALSE(test_api_.hover()); } TEST_F(InkDropAnimationControllerImplTest, HoverFadesOutOnSnapToActivated) { ink_drop_host_.set_should_show_hover(true); ink_drop_animation_controller_.SetHovered(true); + test_api_.CompleteAnimations(); - EXPECT_TRUE(is_hover_fading_in_or_visible()); + EXPECT_TRUE(test_api_.IsHoverFadingInOrVisible()); ink_drop_animation_controller_.SnapToActivated(); - EXPECT_FALSE(is_hover_fading_in_or_visible()); + EXPECT_FALSE(test_api_.IsHoverFadingInOrVisible()); } } // namespace views
diff --git a/ui/views/animation/ink_drop_animation_unittest.cc b/ui/views/animation/ink_drop_animation_unittest.cc index d07b1c3..85434b5 100644 --- a/ui/views/animation/ink_drop_animation_unittest.cc +++ b/ui/views/animation/ink_drop_animation_unittest.cc
@@ -69,7 +69,7 @@ } case FLOOD_FILL_INK_DROP_ANIMATION: { FloodFillInkDropAnimation* flood_fill_ink_drop_animation = - new FloodFillInkDropAnimation(gfx::Size(10, 10), gfx::Point(), + new FloodFillInkDropAnimation(gfx::Rect(0, 0, 10, 10), gfx::Point(), SK_ColorBLACK); ink_drop_animation_.reset(flood_fill_ink_drop_animation); test_api_.reset(
diff --git a/ui/views/animation/ink_drop_hover.cc b/ui/views/animation/ink_drop_hover.cc index 9bb7b02..f53a95a0 100644 --- a/ui/views/animation/ink_drop_hover.cc +++ b/ui/views/animation/ink_drop_hover.cc
@@ -59,6 +59,10 @@ AnimateFade(FADE_OUT, duration, size_, explode ? explode_size_ : size_); } +test::InkDropHoverTestApi* InkDropHover::GetTestApi() { + return nullptr; +} + void InkDropHover::AnimateFade(HoverAnimationType animation_type, const base::TimeDelta& duration, const gfx::Size& initial_size,
diff --git a/ui/views/animation/ink_drop_hover.h b/ui/views/animation/ink_drop_hover.h index b65f28a..cda2424 100644 --- a/ui/views/animation/ink_drop_hover.h +++ b/ui/views/animation/ink_drop_hover.h
@@ -22,6 +22,10 @@ } // namespace ui namespace views { +namespace test { +class InkDropHoverTestApi; +} // namespace test + class RoundedRectangleLayerDelegate; // Manages fade in/out animations for a painted Layer that is used to provide @@ -32,7 +36,7 @@ int corner_radius, const gfx::Point& center_point, SkColor color); - ~InkDropHover(); + virtual ~InkDropHover(); void set_explode_size(const gfx::Size& size) { explode_size_ = size; } @@ -50,7 +54,14 @@ // The root Layer that can be added in to a Layer tree. ui::Layer* layer() { return layer_.get(); } + // Returns a test api to access internals of this. Default implmentations + // should return nullptr and test specific subclasses can override to return + // an instance. + virtual test::InkDropHoverTestApi* GetTestApi(); + private: + friend class test::InkDropHoverTestApi; + enum HoverAnimationType { FADE_IN, FADE_OUT }; // Animates a fade in/out as specified by |animation_type| combined with a
diff --git a/ui/views/animation/test/ink_drop_animation_controller_impl_test_api.cc b/ui/views/animation/test/ink_drop_animation_controller_impl_test_api.cc new file mode 100644 index 0000000..a41d67c --- /dev/null +++ b/ui/views/animation/test/ink_drop_animation_controller_impl_test_api.cc
@@ -0,0 +1,58 @@ +// Copyright 2016 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "ui/views/animation/test/ink_drop_animation_controller_impl_test_api.h" + +#include "ui/views/animation/ink_drop_animation.h" +#include "ui/views/animation/ink_drop_animation_controller_impl.h" +#include "ui/views/animation/ink_drop_hover.h" +#include "ui/views/animation/test/ink_drop_animation_test_api.h" +#include "ui/views/animation/test/ink_drop_hover_test_api.h" + +namespace views { +namespace test { + +InkDropAnimationControllerImplTestApi::InkDropAnimationControllerImplTestApi( + InkDropAnimationControllerImpl* ink_drop_controller) + : ui::test::MultiLayerAnimatorTestController(this), + ink_drop_controller_(ink_drop_controller) {} + +InkDropAnimationControllerImplTestApi:: + ~InkDropAnimationControllerImplTestApi() {} + +const InkDropHover* InkDropAnimationControllerImplTestApi::hover() const { + return ink_drop_controller_->hover_.get(); +} + +bool InkDropAnimationControllerImplTestApi::IsHoverFadingInOrVisible() const { + return ink_drop_controller_->IsHoverFadingInOrVisible(); +} + +std::vector<ui::LayerAnimator*> +InkDropAnimationControllerImplTestApi::GetLayerAnimators() { + std::vector<ui::LayerAnimator*> animators; + + if (ink_drop_controller_->hover_) { + InkDropHoverTestApi* ink_drop_hover_test_api = + ink_drop_controller_->hover_->GetTestApi(); + std::vector<ui::LayerAnimator*> ink_drop_hover_animators = + ink_drop_hover_test_api->GetLayerAnimators(); + animators.insert(animators.end(), ink_drop_hover_animators.begin(), + ink_drop_hover_animators.end()); + } + + if (ink_drop_controller_->ink_drop_animation_) { + InkDropAnimationTestApi* ink_drop_animation_test_api = + ink_drop_controller_->ink_drop_animation_->GetTestApi(); + std::vector<ui::LayerAnimator*> ink_drop_animation_animators = + ink_drop_animation_test_api->GetLayerAnimators(); + animators.insert(animators.end(), ink_drop_animation_animators.begin(), + ink_drop_animation_animators.end()); + } + + return animators; +} + +} // namespace test +} // namespace views
diff --git a/ui/views/animation/test/ink_drop_animation_controller_impl_test_api.h b/ui/views/animation/test/ink_drop_animation_controller_impl_test_api.h new file mode 100644 index 0000000..54b80c6 --- /dev/null +++ b/ui/views/animation/test/ink_drop_animation_controller_impl_test_api.h
@@ -0,0 +1,54 @@ +// Copyright 2016 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef UI_VIEWS_ANIMATION_TEST_INK_DROP_ANIMATION_CONTROLLER_IMPL_TEST_API_H_ +#define UI_VIEWS_ANIMATION_TEST_INK_DROP_ANIMATION_CONTROLLER_IMPL_TEST_API_H_ + +#include <vector> + +#include "base/macros.h" +#include "ui/compositor/test/multi_layer_animator_test_controller.h" +#include "ui/compositor/test/multi_layer_animator_test_controller_delegate.h" + +namespace ui { +class LayerAnimator; +} // namespace ui + +namespace views { +class InkDropAnimationControllerImpl; +class InkDropHover; + +namespace test { + +// Test API to provide internal access to an InkDropAnimationControllerImpl +// instance. This can also be used to control the InkDropAnimation and +// InkDropHover animations via the ui::test::MultiLayerAnimatorTestController +// API. +class InkDropAnimationControllerImplTestApi + : public ui::test::MultiLayerAnimatorTestController, + public ui::test::MultiLayerAnimatorTestControllerDelegate { + public: + explicit InkDropAnimationControllerImplTestApi( + InkDropAnimationControllerImpl* ink_drop_controller_); + ~InkDropAnimationControllerImplTestApi() override; + + // Wrappers to InkDropAnimationControllerImpl internals: + const InkDropHover* hover() const; + bool IsHoverFadingInOrVisible() const; + + protected: + // MultiLayerAnimatorTestControllerDelegate: + std::vector<ui::LayerAnimator*> GetLayerAnimators() override; + + private: + // The InkDropedAnimation to provide internal access to. + InkDropAnimationControllerImpl* ink_drop_controller_; + + DISALLOW_COPY_AND_ASSIGN(InkDropAnimationControllerImplTestApi); +}; + +} // namespace test +} // namespace views + +#endif // UI_VIEWS_ANIMATION_TEST_INK_DROP_ANIMATION_CONTROLLER_IMPL_TEST_API_H_
diff --git a/ui/views/animation/test/ink_drop_animation_test_api.h b/ui/views/animation/test/ink_drop_animation_test_api.h index b8d44e4..611f3d7 100644 --- a/ui/views/animation/test/ink_drop_animation_test_api.h +++ b/ui/views/animation/test/ink_drop_animation_test_api.h
@@ -21,8 +21,9 @@ namespace test { -// Base Test API used by test fixtures to validate all concrete implementations -// of the InkDropAnimation class. +// Test API to provide internal access to an InkDropAnimation instance. This can +// also be used to control the animations via the +// ui::test::MultiLayerAnimatorTestController API. class InkDropAnimationTestApi : public ui::test::MultiLayerAnimatorTestController, public ui::test::MultiLayerAnimatorTestControllerDelegate { @@ -33,6 +34,9 @@ // Gets the opacity of the ink drop. virtual float GetCurrentOpacity() const = 0; + // MultiLayerAnimatorTestControllerDelegate: + std::vector<ui::LayerAnimator*> GetLayerAnimators() override; + protected: InkDropAnimation* ink_drop_animation() { return static_cast<const InkDropAnimationTestApi*>(this) @@ -41,9 +45,6 @@ InkDropAnimation* ink_drop_animation() const { return ink_drop_animation_; } - // MultiLayerAnimatorTestControllerDelegate: - std::vector<ui::LayerAnimator*> GetLayerAnimators() override; - private: // The InkDropedAnimation to provide internal access to. InkDropAnimation* ink_drop_animation_;
diff --git a/ui/views/animation/test/ink_drop_hover_test_api.cc b/ui/views/animation/test/ink_drop_hover_test_api.cc new file mode 100644 index 0000000..b7c1b45 --- /dev/null +++ b/ui/views/animation/test/ink_drop_hover_test_api.cc
@@ -0,0 +1,29 @@ +// Copyright 2016 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "ui/views/animation/test/ink_drop_hover_test_api.h" + +#include "base/time/time.h" +#include "ui/compositor/layer.h" +#include "ui/compositor/layer_animator.h" +#include "ui/compositor/test/layer_animator_test_controller.h" +#include "ui/views/animation/ink_drop_hover.h" + +namespace views { +namespace test { + +InkDropHoverTestApi::InkDropHoverTestApi(InkDropHover* ink_drop_hover) + : ui::test::MultiLayerAnimatorTestController(this), + ink_drop_hover_(ink_drop_hover) {} + +InkDropHoverTestApi::~InkDropHoverTestApi() {} + +std::vector<ui::LayerAnimator*> InkDropHoverTestApi::GetLayerAnimators() { + std::vector<ui::LayerAnimator*> animators; + animators.push_back(ink_drop_hover()->layer_->GetAnimator()); + return animators; +} + +} // namespace test +} // namespace views
diff --git a/ui/views/animation/test/ink_drop_hover_test_api.h b/ui/views/animation/test/ink_drop_hover_test_api.h new file mode 100644 index 0000000..07f24b5 --- /dev/null +++ b/ui/views/animation/test/ink_drop_hover_test_api.h
@@ -0,0 +1,53 @@ +// Copyright 2016 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef UI_VIEWS_ANIMATION_TEST_INK_DROP_HOVER_TEST_API_H_ +#define UI_VIEWS_ANIMATION_TEST_INK_DROP_HOVER_TEST_API_H_ + +#include <vector> + +#include "base/macros.h" +#include "ui/compositor/test/multi_layer_animator_test_controller.h" +#include "ui/compositor/test/multi_layer_animator_test_controller_delegate.h" + +namespace ui { +class LayerAnimator; +} // namespace ui + +namespace views { +class InkDropHover; + +namespace test { + +// Test API to provide internal access to an InkDropHover instance. This can +// also be used to control the animations via the +// ui::test::MultiLayerAnimatorTestController API. +class InkDropHoverTestApi + : public ui::test::MultiLayerAnimatorTestController, + public ui::test::MultiLayerAnimatorTestControllerDelegate { + public: + explicit InkDropHoverTestApi(InkDropHover* ink_drop_hover); + ~InkDropHoverTestApi() override; + + // MultiLayerAnimatorTestControllerDelegate: + std::vector<ui::LayerAnimator*> GetLayerAnimators() override; + + protected: + InkDropHover* ink_drop_hover() { + return static_cast<const InkDropHoverTestApi*>(this)->ink_drop_hover(); + } + + InkDropHover* ink_drop_hover() const { return ink_drop_hover_; } + + private: + // The InkDropedAnimation to provide internal access to. + InkDropHover* ink_drop_hover_; + + DISALLOW_COPY_AND_ASSIGN(InkDropHoverTestApi); +}; + +} // namespace test +} // namespace views + +#endif // UI_VIEWS_ANIMATION_TEST_INK_DROP_HOVER_TEST_API_H_
diff --git a/ui/views/animation/test/test_ink_drop_host.cc b/ui/views/animation/test/test_ink_drop_host.cc index c919b68..f264e25c 100644 --- a/ui/views/animation/test/test_ink_drop_host.cc +++ b/ui/views/animation/test/test_ink_drop_host.cc
@@ -8,11 +8,74 @@ #include "ui/gfx/geometry/size.h" #include "ui/views/animation/ink_drop_hover.h" #include "ui/views/animation/square_ink_drop_animation.h" +#include "ui/views/animation/test/ink_drop_hover_test_api.h" +#include "ui/views/animation/test/square_ink_drop_animation_test_api.h" namespace views { +namespace { + +// Test specific subclass of InkDropAnimation that returns a test api from +// GetTestApi(). +class TestInkDropAnimation : public SquareInkDropAnimation { + public: + TestInkDropAnimation(const gfx::Size& large_size, + int large_corner_radius, + const gfx::Size& small_size, + int small_corner_radius, + const gfx::Point& center_point, + SkColor color) + : SquareInkDropAnimation(large_size, + large_corner_radius, + small_size, + small_corner_radius, + center_point, + color) {} + + ~TestInkDropAnimation() override {} + + test::InkDropAnimationTestApi* GetTestApi() override { + if (!test_api_) + test_api_.reset(new test::SquareInkDropAnimationTestApi(this)); + return test_api_.get(); + } + + private: + std::unique_ptr<test::InkDropAnimationTestApi> test_api_; + + DISALLOW_COPY_AND_ASSIGN(TestInkDropAnimation); +}; + +// Test specific subclass of InkDropHover that returns a test api from +// GetTestApi(). +class TestInkDropHover : public InkDropHover { + public: + TestInkDropHover(const gfx::Size& size, + int corner_radius, + const gfx::Point& center_point, + SkColor color) + : InkDropHover(size, corner_radius, center_point, color) {} + + ~TestInkDropHover() override {} + + test::InkDropHoverTestApi* GetTestApi() override { + if (!test_api_) + test_api_.reset(new test::InkDropHoverTestApi(this)); + return test_api_.get(); + } + + private: + std::unique_ptr<test::InkDropHoverTestApi> test_api_; + + DISALLOW_COPY_AND_ASSIGN(TestInkDropHover); +}; + +} // namespace + TestInkDropHost::TestInkDropHost() - : num_ink_drop_layers_(0), should_show_hover_(false) {} + : num_ink_drop_layers_(0), + should_show_hover_(false), + disable_timers_for_test_(false) {} TestInkDropHost::~TestInkDropHost() {} @@ -27,15 +90,22 @@ std::unique_ptr<InkDropAnimation> TestInkDropHost::CreateInkDropAnimation() const { gfx::Size size(10, 10); - return base::WrapUnique(new SquareInkDropAnimation( - size, 5, size, 5, gfx::Point(), SK_ColorBLACK)); + std::unique_ptr<InkDropAnimation> animation( + new TestInkDropAnimation(size, 5, size, 5, gfx::Point(), SK_ColorBLACK)); + if (disable_timers_for_test_) + animation->GetTestApi()->SetDisableAnimationTimers(true); + return animation; } std::unique_ptr<InkDropHover> TestInkDropHost::CreateInkDropHover() const { - return should_show_hover_ - ? base::WrapUnique(new InkDropHover(gfx::Size(10, 10), 4, - gfx::Point(), SK_ColorBLACK)) - : nullptr; + std::unique_ptr<InkDropHover> hover; + if (should_show_hover_) { + hover.reset(new TestInkDropHover(gfx::Size(10, 10), 4, gfx::Point(), + SK_ColorBLACK)); + if (disable_timers_for_test_) + hover->GetTestApi()->SetDisableAnimationTimers(true); + } + return hover; } } // namespace views
diff --git a/ui/views/animation/test/test_ink_drop_host.h b/ui/views/animation/test/test_ink_drop_host.h index 5bf8650e..7bb18e1a 100644 --- a/ui/views/animation/test/test_ink_drop_host.h +++ b/ui/views/animation/test/test_ink_drop_host.h
@@ -23,6 +23,10 @@ should_show_hover_ = should_show_hover; } + void set_disable_timers_for_test(bool disable_timers_for_test) { + disable_timers_for_test_ = disable_timers_for_test; + } + // TestInkDropHost: void AddInkDropLayer(ui::Layer* ink_drop_layer) override; void RemoveInkDropLayer(ui::Layer* ink_drop_layer) override; @@ -34,6 +38,10 @@ bool should_show_hover_; + // When true, the InkDropAnimation/InkDropHover instances will have their + // timers disabled after creation. + bool disable_timers_for_test_; + DISALLOW_COPY_AND_ASSIGN(TestInkDropHost); };
diff --git a/ui/views/controls/button/label_button.cc b/ui/views/controls/button/label_button.cc index 19dbb5be..f2371ea 100644 --- a/ui/views/controls/button/label_button.cc +++ b/ui/views/controls/button/label_button.cc
@@ -424,7 +424,8 @@ return GetText().empty() ? CustomButton::CreateInkDropAnimation() : base::WrapUnique(new views::FloodFillInkDropAnimation( - size(), GetInkDropCenter(), GetInkDropBaseColor())); + GetLocalBounds(), GetInkDropCenter(), + GetInkDropBaseColor())); } std::unique_ptr<views::InkDropHover> LabelButton::CreateInkDropHover() const {
diff --git a/ui/views/views.gyp b/ui/views/views.gyp index 1703707..d158ba5 100644 --- a/ui/views/views.gyp +++ b/ui/views/views.gyp
@@ -494,6 +494,10 @@ 'animation/test/flood_fill_ink_drop_animation_test_api.h', 'animation/test/ink_drop_animation_test_api.cc', 'animation/test/ink_drop_animation_test_api.h', + 'animation/test/ink_drop_animation_controller_impl_test_api.cc', + 'animation/test/ink_drop_animation_controller_impl_test_api.h', + 'animation/test/ink_drop_hover_test_api.cc', + 'animation/test/ink_drop_hover_test_api.h', 'animation/test/square_ink_drop_animation_test_api.cc', 'animation/test/square_ink_drop_animation_test_api.h', 'animation/test/test_ink_drop_animation_observer.cc',