diff --git a/.gn b/.gn index b0f1756..f86b832a 100644 --- a/.gn +++ b/.gn
@@ -43,8 +43,7 @@ "//crypto/*", "//data/*", "//dbus/*", - - #"//device/*", # Ran into http://crbug.com/500761 adding dbus dependency + "//device/*", #"//extensions/*", # Lots of errors. #"//gin/*", # Easy. @@ -107,6 +106,7 @@ "//build/config/linux/pkg_config.gni", "//build/config/mac/mac_sdk.gni", "//build/config/posix/BUILD.gn", + "//build/config/sysroot.gni", "//build/config/win/BUILD.gn", "//build/config/win/visual_studio_version.gni", "//build/gn_helpers.py",
diff --git a/DEPS b/DEPS index ffe59f4..d4d41eb 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': '222b30d3a84b29b72b32e639751db4e6542d5e48', + 'skia_revision': '262a71b7f95ce98ff3dd8dba845afbd724470903', # 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': 'baf869df700a81846de2a0fc9e06ee7d4d1f23e0', + 'v8_revision': '62edb0c29bcea560a375c89bd775c3ae572ad256', # 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. @@ -51,11 +51,11 @@ # Three lines of non-changing comments so that # the commit queue can handle CLs rolling ANGLE # and whatever else without interference from each other. - 'angle_revision': 'dd5c5b79333fdde7858a77d39e91cc3d30b74c9e', + 'angle_revision': 'fc1a44a1fe23f100a3164baf90a1b1693748450b', # Three lines of non-changing comments so that # the commit queue can handle CLs rolling build tools # and whatever else without interference from each other. - 'buildtools_revision': '818123dac34899ec230840936fc15b8b2b5556f9', + 'buildtools_revision': 'b747a9e091cb8212a62343258406eaf53a6c032e', # Three lines of non-changing comments so that # the commit queue can handle CLs rolling PDFium # and whatever else without interference from each other. @@ -67,7 +67,7 @@ # Three lines of non-changing comments so that # the commit queue can handle CLs rolling BoringSSL # and whatever else without interference from each other. - 'boringssl_revision': 'fde89b43c347155798dee8b1210c2c5faabe25f8', + 'boringssl_revision': '6d9e5a74482bb832a6b4d9ae3d20d8f10f250bbd', # Three lines of non-changing comments so that # the commit queue can handle CLs rolling nss # and whatever else without interference from each other. @@ -187,7 +187,7 @@ Var('chromium_git') + '/webm/libvpx.git' + '@' + '23831545a0a148a066b905c0f1e011375c97d790', 'src/third_party/ffmpeg': - Var('chromium_git') + '/chromium/third_party/ffmpeg.git' + '@' + 'ddfb37c83df5385cb1ef0bcdb94449d69b96b9d5', + Var('chromium_git') + '/chromium/third_party/ffmpeg.git' + '@' + 'b5b1d0e988d68b2bba2eb2deeacf77079f70ddfa', 'src/third_party/libjingle/source/talk': Var('chromium_git') + '/external/webrtc/trunk/talk.git' + '@' + 'b92be1202589b4530e348aca9cf2a0dcd1263c6a', # commit position 10864
diff --git a/android_webview/javatests/src/org/chromium/android_webview/test/AwContentsClientFullScreenTest.java b/android_webview/javatests/src/org/chromium/android_webview/test/AwContentsClientFullScreenTest.java index dda45ff..e15f7f8 100644 --- a/android_webview/javatests/src/org/chromium/android_webview/test/AwContentsClientFullScreenTest.java +++ b/android_webview/javatests/src/org/chromium/android_webview/test/AwContentsClientFullScreenTest.java
@@ -191,7 +191,7 @@ assertTrue(DOMUtils.isMediaPaused(getWebContentsOnUiThread(), VIDEO_ID)); tapPlayButton(); - assertTrue(DOMUtils.waitForMediaPlay(getWebContentsOnUiThread(), VIDEO_ID)); + DOMUtils.waitForMediaPlay(getWebContentsOnUiThread(), VIDEO_ID); } @MediumTest @@ -206,7 +206,7 @@ // Play and verify that a surface view for hole punching is not created. // Note that VIDEO_TEST_URL contains clear video. tapPlayButton(); - assertTrue(DOMUtils.waitForMediaPlay(getWebContentsOnUiThread(), VIDEO_ID)); + DOMUtils.waitForMediaPlay(getWebContentsOnUiThread(), VIDEO_ID); // Wait to ensure that the surface view is not added asynchronously. VideoSurfaceViewUtils.waitAndAssertContainsZeroVideoHoleSurfaceViews(this, mTestContainerView); @@ -228,7 +228,7 @@ // Play and verify that there is a surface view for hole punching. tapPlayButton(); - assertTrue(DOMUtils.waitForMediaPlay(getWebContentsOnUiThread(), VIDEO_ID)); + DOMUtils.waitForMediaPlay(getWebContentsOnUiThread(), VIDEO_ID); VideoSurfaceViewUtils.pollAndAssertContainsOneVideoHoleSurfaceView(this, mTestContainerView); @@ -262,7 +262,7 @@ // Play and verify that there is a surface view for hole punching. tapPlayButton(); - assertTrue(DOMUtils.waitForMediaPlay(getWebContentsOnUiThread(), VIDEO_ID)); + DOMUtils.waitForMediaPlay(getWebContentsOnUiThread(), VIDEO_ID); VideoSurfaceViewUtils.pollAndAssertContainsOneVideoHoleSurfaceView(this, mTestContainerView); @@ -438,7 +438,7 @@ throws InterruptedException { // We need to poll because it takes time to synchronize the state between the android // views and Javascript. - assertTrue(CriteriaHelper.pollForCriteria(new Criteria() { + CriteriaHelper.pollForCriteria(new Criteria() { @Override public boolean isSatisfied() { try { @@ -450,7 +450,7 @@ return false; } } - })); + }); } private void assertKeepScreenOnActive(final View view, final boolean expected) @@ -475,7 +475,7 @@ private void assertWaitForIsFullscreen() throws InterruptedException { // We need to poll because the Javascript state is updated asynchronously - assertTrue(CriteriaHelper.pollForCriteria(new Criteria() { + CriteriaHelper.pollForCriteria(new Criteria() { @Override public boolean isSatisfied() { try { @@ -485,12 +485,12 @@ return false; } } - })); + }); } private void assertWaitForIsEmbedded() throws InterruptedException { // We need to poll because the Javascript state is updated asynchronously - assertTrue(CriteriaHelper.pollForCriteria(new Criteria() { + CriteriaHelper.pollForCriteria(new Criteria() { @Override public boolean isSatisfied() { try { @@ -500,7 +500,7 @@ return false; } } - })); + }); // TODO: Test that inline video is actually displayed. }
diff --git a/android_webview/javatests/src/org/chromium/android_webview/test/AwContentsClientOnScaleChangedTest.java b/android_webview/javatests/src/org/chromium/android_webview/test/AwContentsClientOnScaleChangedTest.java index 338216a1..a98fedf65 100644 --- a/android_webview/javatests/src/org/chromium/android_webview/test/AwContentsClientOnScaleChangedTest.java +++ b/android_webview/javatests/src/org/chromium/android_webview/test/AwContentsClientOnScaleChangedTest.java
@@ -37,12 +37,12 @@ + " minimum-scale=0.5, maximum-scale=2, user-scalable=yes\" />", "testScaleUp test page body"), "text/html", false); - assertTrue(CriteriaHelper.pollForCriteria(new Criteria() { + CriteriaHelper.pollForCriteria(new Criteria() { @Override public boolean isSatisfied() { return mAwContents.canZoomIn(); } - })); + }); int callCount = mContentsClient.getOnScaleChangedHelper().getCallCount(); ThreadUtils.runOnUiThread(new Runnable() { @Override
diff --git a/android_webview/javatests/src/org/chromium/android_webview/test/AwContentsGarbageCollectionTest.java b/android_webview/javatests/src/org/chromium/android_webview/test/AwContentsGarbageCollectionTest.java index 6825dc3..501ce01 100644 --- a/android_webview/javatests/src/org/chromium/android_webview/test/AwContentsGarbageCollectionTest.java +++ b/android_webview/javatests/src/org/chromium/android_webview/test/AwContentsGarbageCollectionTest.java
@@ -206,9 +206,10 @@ // catch this case. final long timeoutBetweenGcMs = scaleTimeout(1000); for (int i = 0; i < 15; ++i) { - if (CriteriaHelper.pollForCriteria(criteria, timeoutBetweenGcMs, CHECK_INTERVAL)) { + try { + CriteriaHelper.pollForCriteria(criteria, timeoutBetweenGcMs, CHECK_INTERVAL); break; - } else { + } catch (AssertionError e) { Runtime.getRuntime().gc(); } }
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 4cc375d..2f9ad91 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
@@ -495,7 +495,7 @@ * treats timeouts and exceptions as test failures automatically. */ public static void poll(final Callable<Boolean> callable) throws Exception { - assertTrue(CriteriaHelper.pollForCriteria(new Criteria() { + CriteriaHelper.pollForCriteria(new Criteria() { @Override public boolean isSatisfied() { try { @@ -505,7 +505,7 @@ return false; } } - }, WAIT_TIMEOUT_MS, CHECK_INTERVAL)); + }, WAIT_TIMEOUT_MS, CHECK_INTERVAL); } /**
diff --git a/android_webview/javatests/src/org/chromium/android_webview/test/MultipleVideosTest.java b/android_webview/javatests/src/org/chromium/android_webview/test/MultipleVideosTest.java index c5f8d7f..368aa092 100644 --- a/android_webview/javatests/src/org/chromium/android_webview/test/MultipleVideosTest.java +++ b/android_webview/javatests/src/org/chromium/android_webview/test/MultipleVideosTest.java
@@ -57,7 +57,7 @@ // Play the first video. tapFirstPlayButton(); - assertTrue(DOMUtils.waitForMediaPlay(getWebContentsOnUiThread(), FIRST_VIDEO_ID)); + DOMUtils.waitForMediaPlay(getWebContentsOnUiThread(), FIRST_VIDEO_ID); // Verify that there is one video hole surface. VideoSurfaceViewUtils.pollAndAssertContainsOneVideoHoleSurfaceView(this, @@ -65,7 +65,7 @@ // Start the second video. tapSecondPlayButton(); - assertTrue(DOMUtils.waitForMediaPlay(getWebContentsOnUiThread(), SECOND_VIDEO_ID)); + DOMUtils.waitForMediaPlay(getWebContentsOnUiThread(), SECOND_VIDEO_ID); // Verify that the first video pauses once the second video starts. assertFalse(DOMUtils.isMediaPaused(getWebContentsOnUiThread(), SECOND_VIDEO_ID));
diff --git a/android_webview/javatests/src/org/chromium/android_webview/test/PopupWindowTest.java b/android_webview/javatests/src/org/chromium/android_webview/test/PopupWindowTest.java index 80ebe074..288ed3b8 100644 --- a/android_webview/javatests/src/org/chromium/android_webview/test/PopupWindowTest.java +++ b/android_webview/javatests/src/org/chromium/android_webview/test/PopupWindowTest.java
@@ -134,12 +134,12 @@ // Copied from imeTest.java. private void assertWaitForSelectActionBarStatus(final boolean show, final ContentViewCore cvc) throws InterruptedException { - assertTrue(CriteriaHelper.pollForUIThreadCriteria(new Criteria() { + CriteriaHelper.pollForUIThreadCriteria(new Criteria() { @Override public boolean isSatisfied() { return show == cvc.isSelectActionBarShowing(); } - })); + }); } private void hideSelectActionMode(final ContentViewCore cvc) {
diff --git a/android_webview/javatests/src/org/chromium/android_webview/test/PostMessageTest.java b/android_webview/javatests/src/org/chromium/android_webview/test/PostMessageTest.java index c9615cc3..ec62fdb 100644 --- a/android_webview/javatests/src/org/chromium/android_webview/test/PostMessageTest.java +++ b/android_webview/javatests/src/org/chromium/android_webview/test/PostMessageTest.java
@@ -157,13 +157,14 @@ // Call on non-UI thread. private void expectTitle(final String title) throws Throwable { - assertTrue("Received title " + mAwContents.getTitle() + " while expecting " + title, - CriteriaHelper.pollForUIThreadCriteria(new Criteria() { - @Override - public boolean isSatisfied() { - return mAwContents.getTitle().equals(title); - } - })); + CriteriaHelper.pollForUIThreadCriteria(new Criteria() { + @Override + public boolean isSatisfied() { + updateFailureReason( + "Received title " + mAwContents.getTitle() + " while expecting " + title); + return mAwContents.getTitle().equals(title); + } + }); } private void loadPage(String page) throws Throwable {
diff --git a/android_webview/javatests/src/org/chromium/android_webview/test/util/JSUtils.java b/android_webview/javatests/src/org/chromium/android_webview/test/util/JSUtils.java index c522fa80..488b318 100644 --- a/android_webview/javatests/src/org/chromium/android_webview/test/util/JSUtils.java +++ b/android_webview/javatests/src/org/chromium/android_webview/test/util/JSUtils.java
@@ -28,7 +28,7 @@ final OnEvaluateJavaScriptResultHelper onEvaluateJavaScriptResultHelper, final String linkId) throws Exception { - Assert.assertTrue(CriteriaHelper.pollForCriteria(new Criteria() { + CriteriaHelper.pollForCriteria(new Criteria() { @Override public boolean isSatisfied() { try { @@ -42,7 +42,7 @@ return false; } } - }, WAIT_TIMEOUT_MS, CHECK_INTERVAL)); + }, WAIT_TIMEOUT_MS, CHECK_INTERVAL); testCase.getInstrumentation().runOnMainSync(new Runnable() { @Override
diff --git a/android_webview/javatests/src/org/chromium/android_webview/test/util/VideoSurfaceViewUtils.java b/android_webview/javatests/src/org/chromium/android_webview/test/util/VideoSurfaceViewUtils.java index 2eb11c0..cd63272 100644 --- a/android_webview/javatests/src/org/chromium/android_webview/test/util/VideoSurfaceViewUtils.java +++ b/android_webview/javatests/src/org/chromium/android_webview/test/util/VideoSurfaceViewUtils.java
@@ -91,7 +91,7 @@ */ public static void pollAndAssertContainsOneVideoHoleSurfaceView(final AwTestBase test, final View view) throws InterruptedException { - AwTestBase.assertTrue(CriteriaHelper.pollForCriteria(new Criteria() { + CriteriaHelper.pollForCriteria(new Criteria() { @Override public boolean isSatisfied() { try { @@ -102,7 +102,7 @@ } } }, MAX_WAIT_FOR_HOLE_PUNCHING_SURFACE_ATTACHED, - MAX_WAIT_FOR_HOLE_PUNCHING_SURFACE_ATTACHED / 10)); + MAX_WAIT_FOR_HOLE_PUNCHING_SURFACE_ATTACHED / 10); } private static int containsNumChildrenOfType(final AwTestBase test,
diff --git a/android_webview/native/aw_autofill_client.cc b/android_webview/native/aw_autofill_client.cc index 2b2c2667..911571a 100644 --- a/android_webview/native/aw_autofill_client.cc +++ b/android_webview/native/aw_autofill_client.cc
@@ -194,7 +194,7 @@ } void AwAutofillClient::SuggestionSelected(JNIEnv* env, - jobject object, + const JavaParamRef<jobject>& object, jint position) { if (delegate_) { delegate_->DidAcceptSuggestion(suggestions_[position].value,
diff --git a/android_webview/native/aw_autofill_client.h b/android_webview/native/aw_autofill_client.h index c869ddb..b4278ed 100644 --- a/android_webview/native/aw_autofill_client.h +++ b/android_webview/native/aw_autofill_client.h
@@ -96,7 +96,9 @@ void OnFirstUserGestureObserved() override; bool IsContextSecure(const GURL& form_origin) override; - void SuggestionSelected(JNIEnv* env, jobject obj, jint position); + void SuggestionSelected(JNIEnv* env, + const base::android::JavaParamRef<jobject>& obj, + jint position); private: AwAutofillClient(content::WebContents* web_contents);
diff --git a/android_webview/native/aw_contents.cc b/android_webview/native/aw_contents.cc index 8ec6260..a3bcf2f 100644 --- a/android_webview/native/aw_contents.cc +++ b/android_webview/native/aw_contents.cc
@@ -213,13 +213,14 @@ AwContentsLifecycleNotifier::OnWebViewCreated(); } -void AwContents::SetJavaPeers(JNIEnv* env, - jobject obj, - jobject aw_contents, - jobject web_contents_delegate, - jobject contents_client_bridge, - jobject io_thread_client, - jobject intercept_navigation_delegate) { +void AwContents::SetJavaPeers( + JNIEnv* env, + const JavaParamRef<jobject>& obj, + const JavaParamRef<jobject>& aw_contents, + const JavaParamRef<jobject>& web_contents_delegate, + const JavaParamRef<jobject>& contents_client_bridge, + const JavaParamRef<jobject>& io_thread_client, + const JavaParamRef<jobject>& intercept_navigation_delegate) { DCHECK_CURRENTLY_ON(BrowserThread::UI); // The |aw_content| param is technically spurious as it duplicates |obj| but // is passed over anyway to make the binding more explicit. @@ -234,8 +235,8 @@ AwContentsClientBridgeBase::Associate(web_contents_.get(), contents_client_bridge_.get()); - AwContentsIoThreadClientImpl::Associate( - web_contents_.get(), ScopedJavaLocalRef<jobject>(env, io_thread_client)); + AwContentsIoThreadClientImpl::Associate(web_contents_.get(), + io_thread_client); InterceptNavigationDelegate::Associate( web_contents_.get(), @@ -303,8 +304,9 @@ AwContentsLifecycleNotifier::OnWebViewDestroyed(); } -base::android::ScopedJavaLocalRef<jobject> -AwContents::GetWebContents(JNIEnv* env, jobject obj) { +base::android::ScopedJavaLocalRef<jobject> AwContents::GetWebContents( + JNIEnv* env, + const JavaParamRef<jobject>& obj) { DCHECK_CURRENTLY_ON(BrowserThread::UI); DCHECK(web_contents_); if (!web_contents_) @@ -313,7 +315,7 @@ return web_contents_->GetJavaWebContents(); } -void AwContents::Destroy(JNIEnv* env, jobject obj) { +void AwContents::Destroy(JNIEnv* env, const JavaParamRef<jobject>& obj) { java_ref_.reset(); delete this; } @@ -357,7 +359,8 @@ return base::subtle::NoBarrier_Load(&g_instance_count); } -jlong AwContents::GetAwDrawGLViewContext(JNIEnv* env, jobject obj) { +jlong AwContents::GetAwDrawGLViewContext(JNIEnv* env, + const JavaParamRef<jobject>& obj) { DCHECK_CURRENTLY_ON(BrowserThread::UI); return reinterpret_cast<intptr_t>( browser_view_renderer_.GetAwDrawGLViewContext()); @@ -372,7 +375,9 @@ } } // namespace -void AwContents::DocumentHasImages(JNIEnv* env, jobject obj, jobject message) { +void AwContents::DocumentHasImages(JNIEnv* env, + const JavaParamRef<jobject>& obj, + const JavaParamRef<jobject>& message) { DCHECK_CURRENTLY_ON(BrowserThread::UI); ScopedJavaGlobalRef<jobject> j_message; j_message.Reset(env, message); @@ -392,8 +397,10 @@ } } // namespace -void AwContents::GenerateMHTML(JNIEnv* env, jobject obj, - jstring jpath, jobject callback) { +void AwContents::GenerateMHTML(JNIEnv* env, + const JavaParamRef<jobject>& obj, + const JavaParamRef<jstring>& jpath, + const JavaParamRef<jobject>& callback) { DCHECK_CURRENTLY_ON(BrowserThread::UI); ScopedJavaGlobalRef<jobject>* j_callback = new ScopedJavaGlobalRef<jobject>(); j_callback->Reset(env, callback); @@ -404,8 +411,8 @@ } void AwContents::CreatePdfExporter(JNIEnv* env, - jobject obj, - jobject pdfExporter) { + const JavaParamRef<jobject>& obj, + const JavaParamRef<jobject>& pdfExporter) { pdf_exporter_.reset( new AwPdfExporter(env, pdfExporter, @@ -435,9 +442,10 @@ browser_view_renderer_.SetOffscreenPreRaster(enabled); } -void AwContents::AddVisitedLinks(JNIEnv* env, - jobject obj, - jobjectArray jvisited_links) { +void AwContents::AddVisitedLinks( + JNIEnv* env, + const JavaParamRef<jobject>& obj, + const JavaParamRef<jobjectArray>& jvisited_links) { DCHECK_CURRENTLY_ON(BrowserThread::UI); std::vector<base::string16> visited_link_strings; base::android::AppendJavaStringArrayToStringVector( @@ -503,10 +511,11 @@ } // Invoked from Java -void AwContents::InvokeGeolocationCallback(JNIEnv* env, - jobject obj, - jboolean value, - jstring origin) { +void AwContents::InvokeGeolocationCallback( + JNIEnv* env, + const JavaParamRef<jobject>& obj, + jboolean value, + const JavaParamRef<jstring>& origin) { DCHECK_CURRENTLY_ON(BrowserThread::UI); if (pending_geolocation_prompts_.empty()) return; @@ -581,11 +590,10 @@ env, j_ref.obj(), j_request.obj()); } -void AwContents::PreauthorizePermission( - JNIEnv* env, - jobject obj, - jstring origin, - jlong resources) { +void AwContents::PreauthorizePermission(JNIEnv* env, + const JavaParamRef<jobject>& obj, + const JavaParamRef<jstring>& origin, + jlong resources) { permission_request_handler_->PreauthorizePermission( GURL(base::android::ConvertJavaStringToUTF8(env, origin)), resources); } @@ -648,25 +656,28 @@ origin, AwPermissionRequest::AwPermissionRequest::MIDISysex); } -void AwContents::FindAllAsync(JNIEnv* env, jobject obj, jstring search_string) { +void AwContents::FindAllAsync(JNIEnv* env, + const JavaParamRef<jobject>& obj, + const JavaParamRef<jstring>& search_string) { DCHECK_CURRENTLY_ON(BrowserThread::UI); GetFindHelper()->FindAllAsync(ConvertJavaStringToUTF16(env, search_string)); } -void AwContents::FindNext(JNIEnv* env, jobject obj, jboolean forward) { +void AwContents::FindNext(JNIEnv* env, + const JavaParamRef<jobject>& obj, + jboolean forward) { DCHECK_CURRENTLY_ON(BrowserThread::UI); GetFindHelper()->FindNext(forward); } -void AwContents::ClearMatches(JNIEnv* env, jobject obj) { +void AwContents::ClearMatches(JNIEnv* env, const JavaParamRef<jobject>& obj) { DCHECK_CURRENTLY_ON(BrowserThread::UI); GetFindHelper()->ClearMatches(); } -void AwContents::ClearCache( - JNIEnv* env, - jobject obj, - jboolean include_disk_files) { +void AwContents::ClearCache(JNIEnv* env, + const JavaParamRef<jobject>& obj, + jboolean include_disk_files) { DCHECK_CURRENTLY_ON(BrowserThread::UI); render_view_host_ext_->ClearCache(); @@ -764,7 +775,7 @@ base::android::ScopedJavaLocalRef<jbyteArray> AwContents::GetCertificate( JNIEnv* env, - jobject obj) { + const JavaParamRef<jobject>& obj) { DCHECK_CURRENTLY_ON(BrowserThread::UI); content::NavigationEntry* entry = web_contents_->GetController().GetLastCommittedEntry(); @@ -785,7 +796,7 @@ } void AwContents::RequestNewHitTestDataAt(JNIEnv* env, - jobject obj, + const JavaParamRef<jobject>& obj, jfloat x, jfloat y, jfloat touch_major) { @@ -795,7 +806,8 @@ render_view_host_ext_->RequestNewHitTestDataAt(touch_center, touch_area); } -void AwContents::UpdateLastHitTestData(JNIEnv* env, jobject obj) { +void AwContents::UpdateLastHitTestData(JNIEnv* env, + const JavaParamRef<jobject>& obj) { DCHECK_CURRENTLY_ON(BrowserThread::UI); if (!render_view_host_ext_->HasNewHitTestData()) return; @@ -829,23 +841,33 @@ img_src.obj()); } -void AwContents::OnSizeChanged(JNIEnv* env, jobject obj, - int w, int h, int ow, int oh) { +void AwContents::OnSizeChanged(JNIEnv* env, + const JavaParamRef<jobject>& obj, + int w, + int h, + int ow, + int oh) { DCHECK_CURRENTLY_ON(BrowserThread::UI); browser_view_renderer_.OnSizeChanged(w, h); } -void AwContents::SetViewVisibility(JNIEnv* env, jobject obj, bool visible) { +void AwContents::SetViewVisibility(JNIEnv* env, + const JavaParamRef<jobject>& obj, + bool visible) { DCHECK_CURRENTLY_ON(BrowserThread::UI); browser_view_renderer_.SetViewVisibility(visible); } -void AwContents::SetWindowVisibility(JNIEnv* env, jobject obj, bool visible) { +void AwContents::SetWindowVisibility(JNIEnv* env, + const JavaParamRef<jobject>& obj, + bool visible) { DCHECK_CURRENTLY_ON(BrowserThread::UI); browser_view_renderer_.SetWindowVisibility(visible); } -void AwContents::SetIsPaused(JNIEnv* env, jobject obj, bool paused) { +void AwContents::SetIsPaused(JNIEnv* env, + const JavaParamRef<jobject>& obj, + bool paused) { DCHECK_CURRENTLY_ON(BrowserThread::UI); browser_view_renderer_.SetIsPaused(paused); ContentViewCore* cvc = @@ -855,17 +877,21 @@ } } -void AwContents::OnAttachedToWindow(JNIEnv* env, jobject obj, int w, int h) { +void AwContents::OnAttachedToWindow(JNIEnv* env, + const JavaParamRef<jobject>& obj, + int w, + int h) { DCHECK_CURRENTLY_ON(BrowserThread::UI); browser_view_renderer_.OnAttachedToWindow(w, h); } -void AwContents::OnDetachedFromWindow(JNIEnv* env, jobject obj) { +void AwContents::OnDetachedFromWindow(JNIEnv* env, + const JavaParamRef<jobject>& obj) { DCHECK_CURRENTLY_ON(BrowserThread::UI); browser_view_renderer_.OnDetachedFromWindow(); } -bool AwContents::IsVisible(JNIEnv* env, jobject obj) { +bool AwContents::IsVisible(JNIEnv* env, const JavaParamRef<jobject>& obj) { return browser_view_renderer_.IsClientVisible(); } @@ -876,8 +902,9 @@ Java_AwContents_detachFunctorFromView(env, obj.obj()); } -base::android::ScopedJavaLocalRef<jbyteArray> -AwContents::GetOpaqueState(JNIEnv* env, jobject obj) { +base::android::ScopedJavaLocalRef<jbyteArray> AwContents::GetOpaqueState( + JNIEnv* env, + const JavaParamRef<jobject>& obj) { DCHECK_CURRENTLY_ON(BrowserThread::UI); // Required optimization in WebViewClassic to not save any state if // there has been no navigations. @@ -894,7 +921,9 @@ } jboolean AwContents::RestoreFromOpaqueState( - JNIEnv* env, jobject obj, jbyteArray state) { + JNIEnv* env, + const JavaParamRef<jobject>& obj, + const JavaParamRef<jbyteArray>& state) { DCHECK_CURRENTLY_ON(BrowserThread::UI); // TODO(boliu): This copy can be optimized out if this is a performance // problem. @@ -909,8 +938,8 @@ } bool AwContents::OnDraw(JNIEnv* env, - jobject obj, - jobject canvas, + const JavaParamRef<jobject>& obj, + const JavaParamRef<jobject>& canvas, jboolean is_hardware_accelerated, jint scroll_x, jint scroll_y, @@ -966,18 +995,20 @@ pending_contents_->SetDipScaleInternal(browser_view_renderer_.dip_scale()); } -void AwContents::FocusFirstNode(JNIEnv* env, jobject obj) { +void AwContents::FocusFirstNode(JNIEnv* env, const JavaParamRef<jobject>& obj) { DCHECK_CURRENTLY_ON(BrowserThread::UI); web_contents_->FocusThroughTabTraversal(false); } -void AwContents::SetBackgroundColor(JNIEnv* env, jobject obj, jint color) { +void AwContents::SetBackgroundColor(JNIEnv* env, + const JavaParamRef<jobject>& obj, + jint color) { DCHECK_CURRENTLY_ON(BrowserThread::UI); render_view_host_ext_->SetBackgroundColor(color); } void AwContents::OnComputeScroll(JNIEnv* env, - jobject obj, + const JavaParamRef<jobject>& obj, jlong animation_time_millis) { DCHECK_CURRENTLY_ON(BrowserThread::UI); browser_view_renderer_.OnComputeScroll( @@ -985,7 +1016,8 @@ base::TimeDelta::FromMilliseconds(animation_time_millis)); } -jlong AwContents::ReleasePopupAwContents(JNIEnv* env, jobject obj) { +jlong AwContents::ReleasePopupAwContents(JNIEnv* env, + const JavaParamRef<jobject>& obj) { DCHECK_CURRENTLY_ON(BrowserThread::UI); return reinterpret_cast<intptr_t>(pending_contents_.release()); } @@ -1047,7 +1079,9 @@ overscroll_velocity.y()); } -void AwContents::SetDipScale(JNIEnv* env, jobject obj, jfloat dip_scale) { +void AwContents::SetDipScale(JNIEnv* env, + const JavaParamRef<jobject>& obj, + jfloat dip_scale) { DCHECK_CURRENTLY_ON(BrowserThread::UI); SetDipScaleInternal(dip_scale); } @@ -1056,13 +1090,16 @@ browser_view_renderer_.SetDipScale(dip_scale); } -void AwContents::ScrollTo(JNIEnv* env, jobject obj, jint x, jint y) { +void AwContents::ScrollTo(JNIEnv* env, + const JavaParamRef<jobject>& obj, + jint x, + jint y) { DCHECK_CURRENTLY_ON(BrowserThread::UI); browser_view_renderer_.ScrollTo(gfx::Vector2d(x, y)); } void AwContents::SmoothScroll(JNIEnv* env, - jobject obj, + const JavaParamRef<jobject>& obj, jint target_x, jint target_y, jlong duration_ms) { @@ -1096,7 +1133,7 @@ } jlong AwContents::CapturePicture(JNIEnv* env, - jobject obj, + const JavaParamRef<jobject>& obj, int width, int height) { DCHECK_CURRENTLY_ON(BrowserThread::UI); @@ -1105,7 +1142,7 @@ } void AwContents::EnableOnNewPicture(JNIEnv* env, - jobject obj, + const JavaParamRef<jobject>& obj, jboolean enabled) { DCHECK_CURRENTLY_ON(BrowserThread::UI); browser_view_renderer_.EnableOnNewPicture(enabled); @@ -1126,7 +1163,10 @@ } // namespace void AwContents::InsertVisualStateCallback( - JNIEnv* env, jobject obj, jlong request_id, jobject callback) { + JNIEnv* env, + const JavaParamRef<jobject>& obj, + jlong request_id, + const JavaParamRef<jobject>& callback) { DCHECK_CURRENTLY_ON(BrowserThread::UI); ScopedJavaGlobalRef<jobject>* j_callback = new ScopedJavaGlobalRef<jobject>(); j_callback->Reset(env, callback); @@ -1135,13 +1175,16 @@ base::Owned(j_callback))); } -void AwContents::ClearView(JNIEnv* env, jobject obj) { +void AwContents::ClearView(JNIEnv* env, const JavaParamRef<jobject>& obj) { DCHECK_CURRENTLY_ON(BrowserThread::UI); browser_view_renderer_.ClearView(); } -void AwContents::SetExtraHeadersForUrl(JNIEnv* env, jobject obj, - jstring url, jstring jextra_headers) { +void AwContents::SetExtraHeadersForUrl( + JNIEnv* env, + const JavaParamRef<jobject>& obj, + const JavaParamRef<jstring>& url, + const JavaParamRef<jstring>& jextra_headers) { std::string extra_headers; if (jextra_headers) extra_headers = ConvertJavaStringToUTF8(env, jextra_headers); @@ -1153,14 +1196,14 @@ } void AwContents::SetJsOnlineProperty(JNIEnv* env, - jobject obj, + const JavaParamRef<jobject>& obj, jboolean network_up) { DCHECK_CURRENTLY_ON(BrowserThread::UI); render_view_host_ext_->SetJsOnlineProperty(network_up); } void AwContents::TrimMemory(JNIEnv* env, - jobject obj, + const JavaParamRef<jobject>& obj, jint level, jboolean visible) { DCHECK_CURRENTLY_ON(BrowserThread::UI); @@ -1169,10 +1212,12 @@ // TODO(sgurun) add support for posting a frame whose name is known (only // main frame is supported at this time, see crbug.com/389721) -void AwContents::PostMessageToFrame(JNIEnv* env, jobject obj, - jstring frame_name, jstring message, jstring target_origin, - jintArray sent_ports) { - +void AwContents::PostMessageToFrame(JNIEnv* env, + const JavaParamRef<jobject>& obj, + const JavaParamRef<jstring>& frame_name, + const JavaParamRef<jstring>& message, + const JavaParamRef<jstring>& target_origin, + const JavaParamRef<jintArray>& sent_ports) { // Use an empty source origin for android webview. base::string16 source_origin; base::string16 j_target_origin(ConvertJavaStringToUTF16(env, target_origin)); @@ -1211,20 +1256,23 @@ return message_port_message_filter_; } -void AwContents::CreateMessageChannel(JNIEnv* env, jobject obj, - jobjectArray ports) { - +void AwContents::CreateMessageChannel(JNIEnv* env, + const JavaParamRef<jobject>& obj, + const JavaParamRef<jobjectArray>& ports) { AwMessagePortServiceImpl::GetInstance()->CreateMessageChannel(env, ports, GetMessagePortMessageFilter()); } -void AwContents::GrantFileSchemeAccesstoChildProcess(JNIEnv* env, jobject obj) { +void AwContents::GrantFileSchemeAccesstoChildProcess( + JNIEnv* env, + const JavaParamRef<jobject>& obj) { content::ChildProcessSecurityPolicy::GetInstance()->GrantScheme( web_contents_->GetRenderProcessHost()->GetID(), url::kFileScheme); } -void AwContents::ResumeLoadingCreatedPopupWebContents(JNIEnv* env, - jobject obj) { +void AwContents::ResumeLoadingCreatedPopupWebContents( + JNIEnv* env, + const JavaParamRef<jobject>& obj) { web_contents_->ResumeLoadingCreatedWebContents(); }
diff --git a/android_webview/native/aw_contents.h b/android_webview/native/aw_contents.h index af9e8819d..22fe1b18 100644 --- a/android_webview/native/aw_contents.h +++ b/android_webview/native/aw_contents.h
@@ -86,45 +86,85 @@ void SetOffscreenPreRaster(bool enabled); // Methods called from Java. - void SetJavaPeers(JNIEnv* env, - jobject obj, - jobject aw_contents, - jobject web_contents_delegate, - jobject contents_client_bridge, - jobject io_thread_client, - jobject intercept_navigation_delegate); - base::android::ScopedJavaLocalRef<jobject> GetWebContents(JNIEnv* env, - jobject obj); + void SetJavaPeers( + JNIEnv* env, + const base::android::JavaParamRef<jobject>& obj, + const base::android::JavaParamRef<jobject>& aw_contents, + const base::android::JavaParamRef<jobject>& web_contents_delegate, + const base::android::JavaParamRef<jobject>& contents_client_bridge, + const base::android::JavaParamRef<jobject>& io_thread_client, + const base::android::JavaParamRef<jobject>& + intercept_navigation_delegate); + base::android::ScopedJavaLocalRef<jobject> GetWebContents( + JNIEnv* env, + const base::android::JavaParamRef<jobject>& obj); - void Destroy(JNIEnv* env, jobject obj); - void DocumentHasImages(JNIEnv* env, jobject obj, jobject message); - void GenerateMHTML(JNIEnv* env, jobject obj, jstring jpath, jobject callback); - void CreatePdfExporter(JNIEnv* env, jobject obj, jobject pdfExporter); - void AddVisitedLinks(JNIEnv* env, jobject obj, jobjectArray jvisited_links); + void Destroy(JNIEnv* env, const base::android::JavaParamRef<jobject>& obj); + void DocumentHasImages(JNIEnv* env, + const base::android::JavaParamRef<jobject>& obj, + const base::android::JavaParamRef<jobject>& message); + void GenerateMHTML(JNIEnv* env, + const base::android::JavaParamRef<jobject>& obj, + const base::android::JavaParamRef<jstring>& jpath, + const base::android::JavaParamRef<jobject>& callback); + void CreatePdfExporter( + JNIEnv* env, + const base::android::JavaParamRef<jobject>& obj, + const base::android::JavaParamRef<jobject>& pdfExporter); + void AddVisitedLinks( + JNIEnv* env, + const base::android::JavaParamRef<jobject>& obj, + const base::android::JavaParamRef<jobjectArray>& jvisited_links); base::android::ScopedJavaLocalRef<jbyteArray> GetCertificate( - JNIEnv* env, jobject obj); + JNIEnv* env, + const base::android::JavaParamRef<jobject>& obj); void RequestNewHitTestDataAt(JNIEnv* env, - jobject obj, + const base::android::JavaParamRef<jobject>& obj, jfloat x, jfloat y, jfloat touch_major); - void UpdateLastHitTestData(JNIEnv* env, jobject obj); - void OnSizeChanged(JNIEnv* env, jobject obj, int w, int h, int ow, int oh); - void SetViewVisibility(JNIEnv* env, jobject obj, bool visible); - void SetWindowVisibility(JNIEnv* env, jobject obj, bool visible); - void SetIsPaused(JNIEnv* env, jobject obj, bool paused); - void OnAttachedToWindow(JNIEnv* env, jobject obj, int w, int h); - void OnDetachedFromWindow(JNIEnv* env, jobject obj); - bool IsVisible(JNIEnv* env, jobject obj); + void UpdateLastHitTestData(JNIEnv* env, + const base::android::JavaParamRef<jobject>& obj); + void OnSizeChanged(JNIEnv* env, + const base::android::JavaParamRef<jobject>& obj, + int w, + int h, + int ow, + int oh); + void SetViewVisibility(JNIEnv* env, + const base::android::JavaParamRef<jobject>& obj, + bool visible); + void SetWindowVisibility(JNIEnv* env, + const base::android::JavaParamRef<jobject>& obj, + bool visible); + void SetIsPaused(JNIEnv* env, + const base::android::JavaParamRef<jobject>& obj, + bool paused); + void OnAttachedToWindow(JNIEnv* env, + const base::android::JavaParamRef<jobject>& obj, + int w, + int h); + void OnDetachedFromWindow(JNIEnv* env, + const base::android::JavaParamRef<jobject>& obj); + bool IsVisible(JNIEnv* env, const base::android::JavaParamRef<jobject>& obj); base::android::ScopedJavaLocalRef<jbyteArray> GetOpaqueState( - JNIEnv* env, jobject obj); - jboolean RestoreFromOpaqueState(JNIEnv* env, jobject obj, jbyteArray state); - void FocusFirstNode(JNIEnv* env, jobject obj); - void SetBackgroundColor(JNIEnv* env, jobject obj, jint color); - void OnComputeScroll(JNIEnv* env, jobject obj, jlong animation_time_millis); + JNIEnv* env, + const base::android::JavaParamRef<jobject>& obj); + jboolean RestoreFromOpaqueState( + JNIEnv* env, + const base::android::JavaParamRef<jobject>& obj, + const base::android::JavaParamRef<jbyteArray>& state); + void FocusFirstNode(JNIEnv* env, + const base::android::JavaParamRef<jobject>& obj); + void SetBackgroundColor(JNIEnv* env, + const base::android::JavaParamRef<jobject>& obj, + jint color); + void OnComputeScroll(JNIEnv* env, + const base::android::JavaParamRef<jobject>& obj, + jlong animation_time_millis); bool OnDraw(JNIEnv* env, - jobject obj, - jobject canvas, + const base::android::JavaParamRef<jobject>& obj, + const base::android::JavaParamRef<jobject>& canvas, jboolean is_hardware_accelerated, jint scroll_x, jint scroll_y, @@ -132,21 +172,32 @@ jint visible_top, jint visible_right, jint visible_bottom); - jlong GetAwDrawGLViewContext(JNIEnv* env, jobject obj); - jlong CapturePicture(JNIEnv* env, jobject obj, int width, int height); - void EnableOnNewPicture(JNIEnv* env, jobject obj, jboolean enabled); - void InsertVisualStateCallback(JNIEnv* env, - jobject obj, - jlong request_id, - jobject callback); - void ClearView(JNIEnv* env, jobject obj); - void SetExtraHeadersForUrl(JNIEnv* env, jobject obj, - jstring url, jstring extra_headers); + jlong GetAwDrawGLViewContext(JNIEnv* env, + const base::android::JavaParamRef<jobject>& obj); + jlong CapturePicture(JNIEnv* env, + const base::android::JavaParamRef<jobject>& obj, + int width, + int height); + void EnableOnNewPicture(JNIEnv* env, + const base::android::JavaParamRef<jobject>& obj, + jboolean enabled); + void InsertVisualStateCallback( + JNIEnv* env, + const base::android::JavaParamRef<jobject>& obj, + jlong request_id, + const base::android::JavaParamRef<jobject>& callback); + void ClearView(JNIEnv* env, const base::android::JavaParamRef<jobject>& obj); + void SetExtraHeadersForUrl( + JNIEnv* env, + const base::android::JavaParamRef<jobject>& obj, + const base::android::JavaParamRef<jstring>& url, + const base::android::JavaParamRef<jstring>& extra_headers); - void InvokeGeolocationCallback(JNIEnv* env, - jobject obj, - jboolean value, - jstring origin); + void InvokeGeolocationCallback( + JNIEnv* env, + const base::android::JavaParamRef<jobject>& obj, + jboolean value, + const base::android::JavaParamRef<jstring>& origin); // PermissionRequestHandlerClient implementation. void OnPermissionRequest(base::android::ScopedJavaLocalRef<jobject> j_request, @@ -157,10 +208,11 @@ return permission_request_handler_.get(); } - void PreauthorizePermission(JNIEnv* env, - jobject obj, - jstring origin, - jlong resources); + void PreauthorizePermission( + JNIEnv* env, + const base::android::JavaParamRef<jobject>& obj, + const base::android::JavaParamRef<jstring>& origin, + jlong resources); // AwBrowserPermissionRequestDelegate implementation. void RequestProtectedMediaIdentifierPermission( @@ -178,9 +230,14 @@ void CancelMIDISysexPermissionRequests(const GURL& origin) override; // Find-in-page API and related methods. - void FindAllAsync(JNIEnv* env, jobject obj, jstring search_string); - void FindNext(JNIEnv* env, jobject obj, jboolean forward); - void ClearMatches(JNIEnv* env, jobject obj); + void FindAllAsync(JNIEnv* env, + const base::android::JavaParamRef<jobject>& obj, + const base::android::JavaParamRef<jstring>& search_string); + void FindNext(JNIEnv* env, + const base::android::JavaParamRef<jobject>& obj, + jboolean forward); + void ClearMatches(JNIEnv* env, + const base::android::JavaParamRef<jobject>& obj); FindHelper* GetFindHelper(); // Per WebView Cookie Policy @@ -218,33 +275,58 @@ void ParentDrawConstraintsUpdated( const ParentCompositorDrawConstraints& draw_constraints) override {} - void ClearCache(JNIEnv* env, jobject obj, jboolean include_disk_files); + void ClearCache(JNIEnv* env, + const base::android::JavaParamRef<jobject>& obj, + jboolean include_disk_files); void SetPendingWebContentsForPopup(scoped_ptr<content::WebContents> pending); - jlong ReleasePopupAwContents(JNIEnv* env, jobject obj); + jlong ReleasePopupAwContents(JNIEnv* env, + const base::android::JavaParamRef<jobject>& obj); - void ScrollTo(JNIEnv* env, jobject obj, jint x, jint y); + void ScrollTo(JNIEnv* env, + const base::android::JavaParamRef<jobject>& obj, + jint x, + jint y); void SmoothScroll(JNIEnv* env, - jobject obj, + const base::android::JavaParamRef<jobject>& obj, jint target_x, jint target_y, jlong duration_ms); - void SetDipScale(JNIEnv* env, jobject obj, jfloat dip_scale); + void SetDipScale(JNIEnv* env, + const base::android::JavaParamRef<jobject>& obj, + jfloat dip_scale); void SetSaveFormData(bool enabled); // Sets the java client void SetAwAutofillClient(jobject client); - void SetJsOnlineProperty(JNIEnv* env, jobject obj, jboolean network_up); - void TrimMemory(JNIEnv* env, jobject obj, jint level, jboolean visible); + void SetJsOnlineProperty(JNIEnv* env, + const base::android::JavaParamRef<jobject>& obj, + jboolean network_up); + void TrimMemory(JNIEnv* env, + const base::android::JavaParamRef<jobject>& obj, + jint level, + jboolean visible); scoped_refptr<AwMessagePortMessageFilter> GetMessagePortMessageFilter(); - void PostMessageToFrame(JNIEnv* env, jobject obj, jstring frame_id, - jstring message, jstring target_origin, jintArray sent_ports); - void CreateMessageChannel(JNIEnv* env, jobject obj, jobjectArray ports); + void PostMessageToFrame( + JNIEnv* env, + const base::android::JavaParamRef<jobject>& obj, + const base::android::JavaParamRef<jstring>& frame_id, + const base::android::JavaParamRef<jstring>& message, + const base::android::JavaParamRef<jstring>& target_origin, + const base::android::JavaParamRef<jintArray>& sent_ports); + void CreateMessageChannel( + JNIEnv* env, + const base::android::JavaParamRef<jobject>& obj, + const base::android::JavaParamRef<jobjectArray>& ports); - void GrantFileSchemeAccesstoChildProcess(JNIEnv* env, jobject obj); + void GrantFileSchemeAccesstoChildProcess( + JNIEnv* env, + const base::android::JavaParamRef<jobject>& obj); - void ResumeLoadingCreatedPopupWebContents(JNIEnv* env, jobject obj); + void ResumeLoadingCreatedPopupWebContents( + JNIEnv* env, + const base::android::JavaParamRef<jobject>& obj); private: void InitAutofillIfNecessary(bool enabled);
diff --git a/android_webview/native/aw_contents_client_bridge.cc b/android_webview/native/aw_contents_client_bridge.cc index 9e570af6..2dae8f5 100644 --- a/android_webview/native/aw_contents_client_bridge.cc +++ b/android_webview/native/aw_contents_client_bridge.cc
@@ -108,8 +108,10 @@ } } -void AwContentsClientBridge::ProceedSslError(JNIEnv* env, jobject obj, - jboolean proceed, jint id) { +void AwContentsClientBridge::ProceedSslError(JNIEnv* env, + const JavaRef<jobject>& obj, + jboolean proceed, + jint id) { DCHECK_CURRENTLY_ON(BrowserThread::UI); CertErrorCallback* callback = pending_cert_error_callbacks_.Lookup(id); if (!callback || callback->is_null()) { @@ -196,17 +198,17 @@ // chrome/browser/ui/android/ssl_client_certificate_request.cc void AwContentsClientBridge::ProvideClientCertificateResponse( JNIEnv* env, - jobject obj, + const JavaRef<jobject>& obj, int request_id, - jobjectArray encoded_chain_ref, - jobject private_key_ref) { + const JavaRef<jobjectArray>& encoded_chain_ref, + const JavaRef<jobject>& private_key_ref) { DCHECK_CURRENTLY_ON(BrowserThread::UI); content::ClientCertificateDelegate* delegate = pending_client_cert_request_delegates_.Lookup(request_id); DCHECK(delegate); - if (encoded_chain_ref == NULL || private_key_ref == NULL) { + if (encoded_chain_ref.is_null() || private_key_ref.is_null()) { LOG(ERROR) << "No client certificate selected"; pending_client_cert_request_delegates_.Remove(request_id); delegate->ContinueWithCertificate(nullptr); @@ -222,9 +224,9 @@ // Convert the encoded chain to a vector of strings. std::vector<std::string> encoded_chain_strings; - if (encoded_chain_ref) { + if (!encoded_chain_ref.is_null()) { base::android::JavaArrayOfByteArrayToStringVector( - env, encoded_chain_ref, &encoded_chain_strings); + env, encoded_chain_ref.obj(), &encoded_chain_strings); } std::vector<base::StringPiece> encoded_chain; @@ -241,7 +243,7 @@ // Create an EVP_PKEY wrapper for the private key JNI reference. crypto::ScopedEVP_PKEY private_key( - net::android::GetOpenSSLPrivateKeyWrapper(private_key_ref)); + net::android::GetOpenSSLPrivateKeyWrapper(private_key_ref.obj())); if (!private_key.get()) { LOG(ERROR) << "Could not create OpenSSL wrapper for private key"; return; @@ -341,9 +343,9 @@ } void AwContentsClientBridge::ConfirmJsResult(JNIEnv* env, - jobject, + const JavaRef<jobject>&, int id, - jstring prompt) { + const JavaRef<jstring>& prompt) { DCHECK_CURRENTLY_ON(BrowserThread::UI); content::JavaScriptDialogManager::DialogClosedCallback* callback = pending_js_dialog_callbacks_.Lookup(id); @@ -352,14 +354,16 @@ return; } base::string16 prompt_text; - if (prompt) { + if (!prompt.is_null()) { prompt_text = ConvertJavaStringToUTF16(env, prompt); } callback->Run(true, prompt_text); pending_js_dialog_callbacks_.Remove(id); } -void AwContentsClientBridge::CancelJsResult(JNIEnv*, jobject, int id) { +void AwContentsClientBridge::CancelJsResult(JNIEnv*, + const JavaRef<jobject>&, + int id) { DCHECK_CURRENTLY_ON(BrowserThread::UI); content::JavaScriptDialogManager::DialogClosedCallback* callback = pending_js_dialog_callbacks_.Lookup(id);
diff --git a/android_webview/native/aw_contents_client_bridge.h b/android_webview/native/aw_contents_client_bridge.h index 74f13e0..5372fb0 100644 --- a/android_webview/native/aw_contents_client_bridge.h +++ b/android_webview/native/aw_contents_client_bridge.h
@@ -56,12 +56,21 @@ override; // Methods called from Java. - void ProceedSslError(JNIEnv* env, jobject obj, jboolean proceed, jint id); - void ProvideClientCertificateResponse(JNIEnv* env, jobject object, - jint request_id, jobjectArray encoded_chain_ref, - jobject private_key_ref); - void ConfirmJsResult(JNIEnv*, jobject, int id, jstring prompt); - void CancelJsResult(JNIEnv*, jobject, int id); + void ProceedSslError(JNIEnv* env, + const base::android::JavaRef<jobject>& obj, + jboolean proceed, + jint id); + void ProvideClientCertificateResponse( + JNIEnv* env, + const base::android::JavaRef<jobject>& object, + jint request_id, + const base::android::JavaRef<jobjectArray>& encoded_chain_ref, + const base::android::JavaRef<jobject>& private_key_ref); + void ConfirmJsResult(JNIEnv*, + const base::android::JavaRef<jobject>&, + int id, + const base::android::JavaRef<jstring>& prompt); + void CancelJsResult(JNIEnv*, const base::android::JavaRef<jobject>&, int id); private: void HandleErrorInClientCertificateResponse(int id);
diff --git a/android_webview/native/aw_contents_client_bridge_unittest.cc b/android_webview/native/aw_contents_client_bridge_unittest.cc index 5f19a52..e685d0b 100644 --- a/android_webview/native/aw_contents_client_bridge_unittest.cc +++ b/android_webview/native/aw_contents_client_bridge_unittest.cc
@@ -129,10 +129,10 @@ bridge_->SelectClientCertificate( cert_request_info_.get(), make_scoped_ptr(new TestClientCertificateDelegate(this))); - bridge_->ProvideClientCertificateResponse(env_, jbridge_.obj(), + bridge_->ProvideClientCertificateResponse( + env_, jbridge_, Java_MockAwContentsClientBridge_getRequestId(env_, jbridge_.obj()), - Java_MockAwContentsClientBridge_createTestCertChain( - env_, jbridge_.obj()).obj(), + Java_MockAwContentsClientBridge_createTestCertChain(env_, jbridge_.obj()), nullptr); base::RunLoop().RunUntilIdle(); EXPECT_EQ(nullptr, selected_cert_); @@ -150,8 +150,8 @@ make_scoped_ptr(new TestClientCertificateDelegate(this))); int requestId = Java_MockAwContentsClientBridge_getRequestId(env_, jbridge_.obj()); - bridge_->ProvideClientCertificateResponse( - env_, jbridge_.obj(), requestId, nullptr, nullptr); + bridge_->ProvideClientCertificateResponse(env_, jbridge_, requestId, nullptr, + nullptr); base::RunLoop().RunUntilIdle(); EXPECT_EQ(nullptr, selected_cert_); EXPECT_EQ(1, cert_selected_callbacks_);
diff --git a/android_webview/native/aw_http_auth_handler.cc b/android_webview/native/aw_http_auth_handler.cc index 700270a..8f4293b 100644 --- a/android_webview/native/aw_http_auth_handler.cc +++ b/android_webview/native/aw_http_auth_handler.cc
@@ -38,9 +38,9 @@ } void AwHttpAuthHandler::Proceed(JNIEnv* env, - jobject obj, - jstring user, - jstring password) { + const JavaParamRef<jobject>& obj, + const JavaParamRef<jstring>& user, + const JavaParamRef<jstring>& password) { DCHECK_CURRENTLY_ON(BrowserThread::UI); if (login_delegate_.get()) { login_delegate_->Proceed(ConvertJavaStringToUTF16(env, user), @@ -49,7 +49,7 @@ } } -void AwHttpAuthHandler::Cancel(JNIEnv* env, jobject obj) { +void AwHttpAuthHandler::Cancel(JNIEnv* env, const JavaParamRef<jobject>& obj) { DCHECK_CURRENTLY_ON(BrowserThread::UI); if (login_delegate_.get()) { login_delegate_->Cancel();
diff --git a/android_webview/native/aw_http_auth_handler.h b/android_webview/native/aw_http_auth_handler.h index 79b7406e..09f6ed12 100644 --- a/android_webview/native/aw_http_auth_handler.h +++ b/android_webview/native/aw_http_auth_handler.h
@@ -37,8 +37,11 @@ // from AwHttpAuthHandler bool HandleOnUIThread(content::WebContents* web_contents) override; - void Proceed(JNIEnv* env, jobject obj, jstring username, jstring password); - void Cancel(JNIEnv* env, jobject obj); + void Proceed(JNIEnv* env, + const base::android::JavaParamRef<jobject>& obj, + const base::android::JavaParamRef<jstring>& username, + const base::android::JavaParamRef<jstring>& password); + void Cancel(JNIEnv* env, const base::android::JavaParamRef<jobject>& obj); private: scoped_refptr<AwLoginDelegate> login_delegate_;
diff --git a/android_webview/native/aw_message_port_service_impl.cc b/android_webview/native/aw_message_port_service_impl.cc index cbbe282..65f7bb0 100644 --- a/android_webview/native/aw_message_port_service_impl.cc +++ b/android_webview/native/aw_message_port_service_impl.cc
@@ -122,8 +122,12 @@ } } -void AwMessagePortServiceImpl::PostAppToWebMessage(JNIEnv* env, jobject obj, - int sender_id, jstring message, jintArray sent_ports) { +void AwMessagePortServiceImpl::PostAppToWebMessage( + JNIEnv* env, + const JavaParamRef<jobject>& obj, + int sender_id, + const JavaParamRef<jstring>& message, + const JavaParamRef<jintArray>& sent_ports) { DCHECK_CURRENTLY_ON(BrowserThread::UI); base::string16* j_message = new base::string16; ConvertJavaStringToUTF16(env, message, j_message); @@ -145,8 +149,9 @@ // it is possible that messages are still queued in the renderer process // waiting for a conversion. Instead, it sends a special message with // a flag which indicates that this message port should be closed. -void AwMessagePortServiceImpl::ClosePort(JNIEnv* env, jobject obj, - int message_port_id) { +void AwMessagePortServiceImpl::ClosePort(JNIEnv* env, + const JavaParamRef<jobject>& obj, + int message_port_id) { DCHECK_CURRENTLY_ON(BrowserThread::UI); BrowserThread::PostTask( BrowserThread::IO, @@ -156,8 +161,9 @@ message_port_id)); } -void AwMessagePortServiceImpl::ReleaseMessages(JNIEnv* env, jobject obj, - int message_port_id) { +void AwMessagePortServiceImpl::ReleaseMessages(JNIEnv* env, + const JavaParamRef<jobject>& obj, + int message_port_id) { DCHECK_CURRENTLY_ON(BrowserThread::UI); BrowserThread::PostTask( BrowserThread::IO,
diff --git a/android_webview/native/aw_message_port_service_impl.h b/android_webview/native/aw_message_port_service_impl.h index 7f42421..2ee31b46 100644 --- a/android_webview/native/aw_message_port_service_impl.h +++ b/android_webview/native/aw_message_port_service_impl.h
@@ -42,10 +42,18 @@ void CleanupPort(int message_port_id) override; // Methods called from Java. - void PostAppToWebMessage(JNIEnv* env, jobject object, int sender_id, - jstring message, jintArray sent_ports); - void ClosePort(JNIEnv* env, jobject object, int message_port_id); - void ReleaseMessages(JNIEnv* env, jobject object, int message_port_id); + void PostAppToWebMessage( + JNIEnv* env, + const base::android::JavaParamRef<jobject>& object, + int sender_id, + const base::android::JavaParamRef<jstring>& message, + const base::android::JavaParamRef<jintArray>& sent_ports); + void ClosePort(JNIEnv* env, + const base::android::JavaParamRef<jobject>& object, + int message_port_id); + void ReleaseMessages(JNIEnv* env, + const base::android::JavaParamRef<jobject>& object, + int message_port_id); void RemoveSentPorts(const std::vector<int>& sent_ports);
diff --git a/android_webview/native/aw_pdf_exporter.cc b/android_webview/native/aw_pdf_exporter.cc index 48fa9f9..af08f1ff 100644 --- a/android_webview/native/aw_pdf_exporter.cc +++ b/android_webview/native/aw_pdf_exporter.cc
@@ -33,9 +33,9 @@ } void AwPdfExporter::ExportToPdf(JNIEnv* env, - jobject obj, + const JavaParamRef<jobject>& obj, int fd, - jobject cancel_signal) { + const JavaParamRef<jobject>& cancel_signal) { DCHECK_CURRENTLY_ON(content::BrowserThread::UI); printing::PrintSettings print_settings; InitPdfSettings(env, obj, print_settings);
diff --git a/android_webview/native/aw_pdf_exporter.h b/android_webview/native/aw_pdf_exporter.h index f2513f8..2b44a85 100644 --- a/android_webview/native/aw_pdf_exporter.h +++ b/android_webview/native/aw_pdf_exporter.h
@@ -31,9 +31,9 @@ ~AwPdfExporter(); void ExportToPdf(JNIEnv* env, - jobject obj, + const base::android::JavaParamRef<jobject>& obj, int fd, - jobject cancel_signal); + const base::android::JavaParamRef<jobject>& cancel_signal); private: void InitPdfSettings(JNIEnv* env,
diff --git a/android_webview/native/aw_picture.cc b/android_webview/native/aw_picture.cc index a46be2ca..6c98d3db 100644 --- a/android_webview/native/aw_picture.cc +++ b/android_webview/native/aw_picture.cc
@@ -18,19 +18,21 @@ AwPicture::~AwPicture() {} -void AwPicture::Destroy(JNIEnv* env, jobject obj) { +void AwPicture::Destroy(JNIEnv* env, const JavaParamRef<jobject>& obj) { delete this; } -jint AwPicture::GetWidth(JNIEnv* env, jobject obj) { +jint AwPicture::GetWidth(JNIEnv* env, const JavaParamRef<jobject>& obj) { return picture_->cullRect().roundOut().width(); } -jint AwPicture::GetHeight(JNIEnv* env, jobject obj) { +jint AwPicture::GetHeight(JNIEnv* env, const JavaParamRef<jobject>& obj) { return picture_->cullRect().roundOut().height(); } -void AwPicture::Draw(JNIEnv* env, jobject obj, jobject canvas) { +void AwPicture::Draw(JNIEnv* env, + const JavaParamRef<jobject>& obj, + const JavaParamRef<jobject>& canvas) { const SkIRect bounds = picture_->cullRect().roundOut(); scoped_ptr<SoftwareCanvasHolder> canvas_holder = SoftwareCanvasHolder::Create( canvas, gfx::Vector2d(), gfx::Size(bounds.width(), bounds.height()),
diff --git a/android_webview/native/aw_picture.h b/android_webview/native/aw_picture.h index fc4d1ec..bc129e5 100644 --- a/android_webview/native/aw_picture.h +++ b/android_webview/native/aw_picture.h
@@ -23,10 +23,12 @@ ~AwPicture(); // Methods called from Java. - void Destroy(JNIEnv* env, jobject obj); - jint GetWidth(JNIEnv* env, jobject obj); - jint GetHeight(JNIEnv* env, jobject obj); - void Draw(JNIEnv* env, jobject obj, jobject canvas); + void Destroy(JNIEnv* env, const base::android::JavaParamRef<jobject>& obj); + jint GetWidth(JNIEnv* env, const base::android::JavaParamRef<jobject>& obj); + jint GetHeight(JNIEnv* env, const base::android::JavaParamRef<jobject>& obj); + void Draw(JNIEnv* env, + const base::android::JavaParamRef<jobject>& obj, + const base::android::JavaParamRef<jobject>& canvas); private: skia::RefPtr<SkPicture> picture_;
diff --git a/android_webview/native/aw_quota_manager_bridge_impl.cc b/android_webview/native/aw_quota_manager_bridge_impl.cc index abf791e..d4ae0cd 100644 --- a/android_webview/native/aw_quota_manager_bridge_impl.cc +++ b/android_webview/native/aw_quota_manager_bridge_impl.cc
@@ -180,7 +180,8 @@ AwQuotaManagerBridgeImpl::~AwQuotaManagerBridgeImpl() {} -void AwQuotaManagerBridgeImpl::Init(JNIEnv* env, jobject object) { +void AwQuotaManagerBridgeImpl::Init(JNIEnv* env, + const JavaParamRef<jobject>& object) { java_ref_ = JavaObjectWeakGlobalRef(env, object); } @@ -202,7 +203,9 @@ return quota_manager; } -void AwQuotaManagerBridgeImpl::DeleteAllData(JNIEnv* env, jobject object) { +void AwQuotaManagerBridgeImpl::DeleteAllData( + JNIEnv* env, + const JavaParamRef<jobject>& object) { RunOnUIThread(base::Bind(&AwQuotaManagerBridgeImpl::DeleteAllDataOnUiThread, this)); } @@ -222,7 +225,9 @@ } void AwQuotaManagerBridgeImpl::DeleteOrigin( - JNIEnv* env, jobject object, jstring origin) { + JNIEnv* env, + const JavaParamRef<jobject>& object, + const JavaParamRef<jstring>& origin) { base::string16 origin_string( base::android::ConvertJavaStringToUTF16(env, origin)); RunOnUIThread(base::Bind(&AwQuotaManagerBridgeImpl::DeleteOriginOnUiThread, @@ -246,8 +251,9 @@ base::Bind(&base::DoNothing)); } -void AwQuotaManagerBridgeImpl::GetOrigins( - JNIEnv* env, jobject object, jint callback_id) { +void AwQuotaManagerBridgeImpl::GetOrigins(JNIEnv* env, + const JavaParamRef<jobject>& object, + jint callback_id) { RunOnUIThread(base::Bind(&AwQuotaManagerBridgeImpl::GetOriginsOnUiThread, this, callback_id)); @@ -305,8 +311,9 @@ } // namespace void AwQuotaManagerBridgeImpl::GetUsageAndQuotaForOrigin( - JNIEnv* env, jobject object, - jstring origin, + JNIEnv* env, + const JavaParamRef<jobject>& object, + const JavaParamRef<jstring>& origin, jint callback_id, bool is_quota) { base::string16 origin_string(
diff --git a/android_webview/native/aw_quota_manager_bridge_impl.h b/android_webview/native/aw_quota_manager_bridge_impl.h index dc7f20f3..530705d 100644 --- a/android_webview/native/aw_quota_manager_bridge_impl.h +++ b/android_webview/native/aw_quota_manager_bridge_impl.h
@@ -37,15 +37,21 @@ AwBrowserContext* browser_context); // Called by Java. - void Init(JNIEnv* env, jobject object); - void DeleteAllData(JNIEnv* env, jobject object); - void DeleteOrigin(JNIEnv* env, jobject object, jstring origin); - void GetOrigins(JNIEnv* env, jobject object, jint callback_id); - void GetUsageAndQuotaForOrigin(JNIEnv* env, - jobject object, - jstring origin, - jint callback_id, - bool is_quota); + void Init(JNIEnv* env, const base::android::JavaParamRef<jobject>& object); + void DeleteAllData(JNIEnv* env, + const base::android::JavaParamRef<jobject>& object); + void DeleteOrigin(JNIEnv* env, + const base::android::JavaParamRef<jobject>& object, + const base::android::JavaParamRef<jstring>& origin); + void GetOrigins(JNIEnv* env, + const base::android::JavaParamRef<jobject>& object, + jint callback_id); + void GetUsageAndQuotaForOrigin( + JNIEnv* env, + const base::android::JavaParamRef<jobject>& object, + const base::android::JavaParamRef<jstring>& origin, + jint callback_id, + bool is_quota); typedef base::Callback< void(const std::vector<std::string>& /* origin */,
diff --git a/android_webview/native/aw_settings.cc b/android_webview/native/aw_settings.cc index 753a9e1..8817abc 100644 --- a/android_webview/native/aw_settings.cc +++ b/android_webview/native/aw_settings.cc
@@ -93,7 +93,7 @@ reinterpret_cast<intptr_t>(this)); } -void AwSettings::Destroy(JNIEnv* env, jobject obj) { +void AwSettings::Destroy(JNIEnv* env, const JavaParamRef<jobject>& obj) { delete this; } @@ -108,7 +108,8 @@ return contents->render_view_host_ext(); } -void AwSettings::ResetScrollAndScaleState(JNIEnv* env, jobject obj) { +void AwSettings::ResetScrollAndScaleState(JNIEnv* env, + const JavaParamRef<jobject>& obj) { AwRenderViewHostExt* rvhe = GetAwRenderViewHostExt(); if (!rvhe) return; rvhe->ResetScrollAndScaleState(); @@ -124,7 +125,8 @@ Java_AwSettings_updateEverything(env, obj); } -void AwSettings::UpdateEverythingLocked(JNIEnv* env, jobject obj) { +void AwSettings::UpdateEverythingLocked(JNIEnv* env, + const JavaParamRef<jobject>& obj) { UpdateInitialPageScaleLocked(env, obj); UpdateWebkitPreferencesLocked(env, obj); UpdateUserAgentLocked(env, obj); @@ -134,7 +136,8 @@ UpdateOffscreenPreRasterLocked(env, obj); } -void AwSettings::UpdateUserAgentLocked(JNIEnv* env, jobject obj) { +void AwSettings::UpdateUserAgentLocked(JNIEnv* env, + const JavaParamRef<jobject>& obj) { if (!web_contents()) return; ScopedJavaLocalRef<jstring> str = @@ -152,7 +155,9 @@ controller.GetEntryAtIndex(i)->SetIsOverridingUserAgent(ua_overidden); } -void AwSettings::UpdateWebkitPreferencesLocked(JNIEnv* env, jobject obj) { +void AwSettings::UpdateWebkitPreferencesLocked( + JNIEnv* env, + const JavaParamRef<jobject>& obj) { if (!web_contents()) return; AwRenderViewHostExt* render_view_host_ext = GetAwRenderViewHostExt(); if (!render_view_host_ext) return; @@ -163,7 +168,9 @@ render_view_host->OnWebkitPreferencesChanged(); } -void AwSettings::UpdateInitialPageScaleLocked(JNIEnv* env, jobject obj) { +void AwSettings::UpdateInitialPageScaleLocked( + JNIEnv* env, + const JavaParamRef<jobject>& obj) { AwRenderViewHostExt* rvhe = GetAwRenderViewHostExt(); if (!rvhe) return; @@ -178,7 +185,9 @@ } } -void AwSettings::UpdateFormDataPreferencesLocked(JNIEnv* env, jobject obj) { +void AwSettings::UpdateFormDataPreferencesLocked( + JNIEnv* env, + const JavaParamRef<jobject>& obj) { if (!web_contents()) return; AwContents* contents = AwContents::FromWebContents(web_contents()); if (!contents) return; @@ -186,7 +195,9 @@ contents->SetSaveFormData(Java_AwSettings_getSaveFormDataLocked(env, obj)); } -void AwSettings::UpdateRendererPreferencesLocked(JNIEnv* env, jobject obj) { +void AwSettings::UpdateRendererPreferencesLocked( + JNIEnv* env, + const JavaParamRef<jobject>& obj) { if (!web_contents()) return; bool update_prefs = false; @@ -215,7 +226,9 @@ host->SyncRendererPrefs(); } -void AwSettings::UpdateOffscreenPreRasterLocked(JNIEnv* env, jobject obj) { +void AwSettings::UpdateOffscreenPreRasterLocked( + JNIEnv* env, + const JavaParamRef<jobject>& obj) { AwContents* contents = AwContents::FromWebContents(web_contents()); if (contents) { contents->SetOffscreenPreRaster( @@ -253,8 +266,9 @@ env, obj, reinterpret_cast<jlong>(web_prefs)); } -void AwSettings::PopulateWebPreferencesLocked( - JNIEnv* env, jobject obj, jlong web_prefs_ptr) { +void AwSettings::PopulateWebPreferencesLocked(JNIEnv* env, + const JavaParamRef<jobject>& obj, + jlong web_prefs_ptr) { AwRenderViewHostExt* render_view_host_ext = GetAwRenderViewHostExt(); if (!render_view_host_ext) return;
diff --git a/android_webview/native/aw_settings.h b/android_webview/native/aw_settings.h index 56b09ad..79d4f758 100644 --- a/android_webview/native/aw_settings.h +++ b/android_webview/native/aw_settings.h
@@ -29,16 +29,33 @@ // Called from Java. Methods with "Locked" suffix require that the settings // access lock is held during their execution. - void Destroy(JNIEnv* env, jobject obj); - void PopulateWebPreferencesLocked(JNIEnv* env, jobject obj, jlong web_prefs); - void ResetScrollAndScaleState(JNIEnv* env, jobject obj); - void UpdateEverythingLocked(JNIEnv* env, jobject obj); - void UpdateInitialPageScaleLocked(JNIEnv* env, jobject obj); - void UpdateUserAgentLocked(JNIEnv* env, jobject obj); - void UpdateWebkitPreferencesLocked(JNIEnv* env, jobject obj); - void UpdateFormDataPreferencesLocked(JNIEnv* env, jobject obj); - void UpdateRendererPreferencesLocked(JNIEnv* env, jobject obj); - void UpdateOffscreenPreRasterLocked(JNIEnv* env, jobject obj); + void Destroy(JNIEnv* env, const base::android::JavaParamRef<jobject>& obj); + void PopulateWebPreferencesLocked( + JNIEnv* env, + const base::android::JavaParamRef<jobject>& obj, + jlong web_prefs); + void ResetScrollAndScaleState( + JNIEnv* env, + const base::android::JavaParamRef<jobject>& obj); + void UpdateEverythingLocked(JNIEnv* env, + const base::android::JavaParamRef<jobject>& obj); + void UpdateInitialPageScaleLocked( + JNIEnv* env, + const base::android::JavaParamRef<jobject>& obj); + void UpdateUserAgentLocked(JNIEnv* env, + const base::android::JavaParamRef<jobject>& obj); + void UpdateWebkitPreferencesLocked( + JNIEnv* env, + const base::android::JavaParamRef<jobject>& obj); + void UpdateFormDataPreferencesLocked( + JNIEnv* env, + const base::android::JavaParamRef<jobject>& obj); + void UpdateRendererPreferencesLocked( + JNIEnv* env, + const base::android::JavaParamRef<jobject>& obj); + void UpdateOffscreenPreRasterLocked( + JNIEnv* env, + const base::android::JavaParamRef<jobject>& obj); void PopulateWebPreferences(content::WebPreferences* web_prefs);
diff --git a/android_webview/native/aw_web_contents_view_delegate.cc b/android_webview/native/aw_web_contents_view_delegate.cc index 94f582aa..bc160599 100644 --- a/android_webview/native/aw_web_contents_view_delegate.cc +++ b/android_webview/native/aw_web_contents_view_delegate.cc
@@ -43,11 +43,13 @@ if (params.is_editable && params.selection_text.empty()) { content::ContentViewCore* content_view_core = content::ContentViewCore::FromWebContents(web_contents_); - if (content_view_core) { - content_view_core->ShowPastePopup(params.selection_start.x(), - params.selection_start.y()); + if (content_view_core && + content_view_core->ShowPastePopup(params.selection_start.x(), + params.selection_start.y())) { + return; } } + web_contents_->NotifyContextMenuClosed(content::CustomContextMenuContext()); } } // namespace android_webview
diff --git a/android_webview/native/permission/aw_permission_request.cc b/android_webview/native/permission/aw_permission_request.cc index f25db3e0..27f0b5b6 100644 --- a/android_webview/native/permission/aw_permission_request.cc +++ b/android_webview/native/permission/aw_permission_request.cc
@@ -46,7 +46,7 @@ } void AwPermissionRequest::OnAccept(JNIEnv* env, - jobject jcaller, + const JavaParamRef<jobject>& jcaller, jboolean accept) { OnAcceptInternal(accept); } @@ -66,7 +66,8 @@ j_request.obj()); } -void AwPermissionRequest::Destroy(JNIEnv* env, jobject obj) { +void AwPermissionRequest::Destroy(JNIEnv* env, + const JavaParamRef<jobject>& obj) { delete this; }
diff --git a/android_webview/native/permission/aw_permission_request.h b/android_webview/native/permission/aw_permission_request.h index d146538..f016799 100644 --- a/android_webview/native/permission/aw_permission_request.h +++ b/android_webview/native/permission/aw_permission_request.h
@@ -41,8 +41,10 @@ // Invoked by Java peer when request is processed, |granted| indicates the // request was granted or not. - void OnAccept(JNIEnv* env, jobject jcaller, jboolean granted); - void Destroy(JNIEnv* env, jobject obj); + void OnAccept(JNIEnv* env, + const base::android::JavaParamRef<jobject>& jcaller, + jboolean granted); + void Destroy(JNIEnv* env, const base::android::JavaParamRef<jobject>& obj); // Return the origin which initiated the request. const GURL& GetOrigin();
diff --git a/ash/root_window_controller_unittest.cc b/ash/root_window_controller_unittest.cc index e0f9ecc..cd8bcc4 100644 --- a/ash/root_window_controller_unittest.cc +++ b/ash/root_window_controller_unittest.cc
@@ -214,13 +214,12 @@ EXPECT_EQ("0,0 600x597", maximized->GetNativeView()->GetBoundsInRootWindow().ToString()); - // Set fullscreen to true. In that case the 3px inset becomes invisible so - // the maximized window can also use the area fully. + // Set fullscreen to true, but maximized window's size won't change because + // it's not visible. see crbug.com/504299. fullscreen->SetFullscreen(true); EXPECT_EQ(root_windows[0], maximized->GetNativeView()->GetRootWindow()); - EXPECT_EQ("0,0 600x600", - maximized->GetWindowBoundsInScreen().ToString()); - EXPECT_EQ("0,0 600x600", + EXPECT_EQ("0,0 600x597", maximized->GetWindowBoundsInScreen().ToString()); + EXPECT_EQ("0,0 600x597", maximized->GetNativeView()->GetBoundsInRootWindow().ToString()); EXPECT_EQ(root_windows[0], minimized->GetNativeView()->GetRootWindow());
diff --git a/ash/shell/toplevel_window.cc b/ash/shell/toplevel_window.cc index ab9cdc4..ef28e5d 100644 --- a/ash/shell/toplevel_window.cc +++ b/ash/shell/toplevel_window.cc
@@ -29,9 +29,7 @@ } // namespace ToplevelWindow::CreateParams::CreateParams() - : can_resize(false), - can_maximize(false) { -} + : can_resize(false), can_maximize(false), use_saved_placement(true) {} // static views::Widget* ToplevelWindow::CreateToplevelWindow( @@ -78,7 +76,7 @@ gfx::Rect* bounds, ui::WindowShowState* show_state) const { bool is_saved_bounds = !!saved_state; - if (saved_state) { + if (saved_state && params_.use_saved_placement) { *bounds = saved_state->bounds; *show_state = saved_state->show_state; } else {
diff --git a/ash/shell/toplevel_window.h b/ash/shell/toplevel_window.h index 693bad5..19104516 100644 --- a/ash/shell/toplevel_window.h +++ b/ash/shell/toplevel_window.h
@@ -17,6 +17,7 @@ bool can_resize; bool can_maximize; + bool use_saved_placement; }; static views::Widget* CreateToplevelWindow( const CreateParams& params);
diff --git a/ash/wm/default_state.cc b/ash/wm/default_state.cc index bacf0356..ff2ac4e 100644 --- a/ash/wm/default_state.cc +++ b/ash/wm/default_state.cc
@@ -5,6 +5,7 @@ #include "ash/wm/default_state.h" #include "ash/display/window_tree_host_manager.h" +#include "ash/root_window_controller.h" #include "ash/screen_util.h" #include "ash/shell.h" #include "ash/shell_window_ids.h" @@ -17,6 +18,7 @@ #include "ash/wm/window_util.h" #include "ash/wm/wm_event.h" #include "ash/wm/workspace/workspace_window_resizer.h" +#include "ash/wm/workspace_controller.h" #include "ui/aura/client/aura_constants.h" #include "ui/aura/window.h" #include "ui/aura/window_delegate.h" @@ -461,6 +463,15 @@ return true; } case WM_EVENT_WORKAREA_BOUNDS_CHANGED: { + // Don't resize the maximized window when the desktop is covered + // by fullscreen window. crbug.com/504299. + bool in_fullscreen = + RootWindowController::ForWindow(window_state->window()) + ->workspace_controller() + ->GetWindowState() == WORKSPACE_WINDOW_STATE_FULL_SCREEN; + if (in_fullscreen && window_state->IsMaximized()) + return true; + if (window_state->is_dragged() || SetMaximizedOrFullscreenBounds(window_state)) { return true;
diff --git a/ash/wm/window_positioner.cc b/ash/wm/window_positioner.cc index eed15a0..4a1d02e 100644 --- a/ash/wm/window_positioner.cc +++ b/ash/wm/window_positioner.cc
@@ -60,17 +60,18 @@ return !window_state->is_dragged() && window_state->window_position_managed(); } -// Check if a given |window| can be managed. This includes that it's state is -// not minimized/maximized/the user has changed it's size by hand already. -// It furthermore checks for the WindowIsManaged status. +// Check if a given |window| can be managed. This includes that its +// state is not minimized/maximized/fullscreen/the user has changed +// its size by hand already. It furthermore checks for the +// WindowIsManaged status. bool WindowPositionCanBeManaged(const aura::Window* window) { if (disable_auto_positioning) return false; const wm::WindowState* window_state = wm::GetWindowState(window); return window_state->window_position_managed() && - !window_state->IsMinimized() && - !window_state->IsMaximized() && - !window_state->bounds_changed_by_user(); + !window_state->IsMinimized() && !window_state->IsMaximized() && + !window_state->IsFullscreen() && + !window_state->bounds_changed_by_user(); } // Get the work area for a given |window| in parent coordinates. @@ -291,12 +292,13 @@ ui::SHOW_STATE_DEFAULT; } - if (maximized) { + if (maximized || top_window_state->IsFullscreen()) { bool has_restore_bounds = top_window_state->HasRestoreBounds(); if (has_restore_bounds) { - // For a maximized window ignore the real bounds of the top level window - // and use its restore bounds instead. Offset the bounds to prevent the - // windows from overlapping exactly when restored. + // For a maximized/fullscreen window ignore the real bounds of + // the top level window and use its restore bounds + // instead. Offset the bounds to prevent the windows from + // overlapping exactly when restored. *bounds_in_out = top_window_state->GetRestoreBoundsInScreen() + gfx::Vector2d(kMinimumWindowOffset, kMinimumWindowOffset); }
diff --git a/ash/wm/window_positioner_unittest.cc b/ash/wm/window_positioner_unittest.cc index a9445eb..05067538 100644 --- a/ash/wm/window_positioner_unittest.cc +++ b/ash/wm/window_positioner_unittest.cc
@@ -195,4 +195,39 @@ EXPECT_EQ(show_state_out, ui::SHOW_STATE_MAXIMIZED); } -} // namespace +TEST_F(WindowPositionerTest, IgnoreFullscreenInAutoRearrange) { + if (!SupportsHostWindowResize()) + return; + // Set bigger than 1366 so that the new window is opened in normal state. + UpdateDisplay("1400x800"); + + // 1st window mimics fullscreen browser window behavior. + shell::ToplevelWindow::CreateParams params; + params.can_resize = true; + params.can_maximize = true; + views::Widget* widget1 = shell::ToplevelWindow::CreateToplevelWindow(params); + wm::WindowState* managed_state = + wm::GetWindowState(widget1->GetNativeWindow()); + EXPECT_TRUE(managed_state->window_position_managed()); + EXPECT_EQ("300x300", widget1->GetWindowBoundsInScreen().size().ToString()); + widget1->SetFullscreen(true); + ASSERT_EQ("1400x800", widget1->GetWindowBoundsInScreen().size().ToString()); + + // 2nd window mimics windowed v1 app. + params.use_saved_placement = false; + views::Widget* widget2 = shell::ToplevelWindow::CreateToplevelWindow(params); + wm::WindowState* state_2 = wm::GetWindowState(widget2->GetNativeWindow()); + EXPECT_TRUE(state_2->window_position_managed()); + EXPECT_EQ("300x300", widget2->GetWindowBoundsInScreen().size().ToString()); + + // Restores to the original size. + widget1->SetFullscreen(false); + ASSERT_EQ("300x300", widget1->GetWindowBoundsInScreen().size().ToString()); + + // Closing 2nd widget triggers the rearrange logic but the 1st + // widget should stay in the current size. + widget2->CloseNow(); + ASSERT_EQ("300x300", widget1->GetWindowBoundsInScreen().size().ToString()); +} + +} // namespace ash
diff --git a/ash/wm/window_state_unittest.cc b/ash/wm/window_state_unittest.cc index d816cf7..ecfbc6a 100644 --- a/ash/wm/window_state_unittest.cc +++ b/ash/wm/window_state_unittest.cc
@@ -334,6 +334,35 @@ EXPECT_TRUE(work_area.Contains(window->bounds())); } +TEST_F(WindowStateTest, DoNotResizeMaximizedWindowInFullscreen) { + if (!SupportsHostWindowResize()) + return; + + scoped_ptr<aura::Window> maximized(CreateTestWindowInShellWithId(0)); + scoped_ptr<aura::Window> fullscreen(CreateTestWindowInShellWithId(1)); + WindowState* maximized_state = GetWindowState(maximized.get()); + maximized_state->Maximize(); + ASSERT_TRUE(maximized_state->IsMaximized()); + EXPECT_EQ("0,0 800x553", maximized->GetBoundsInScreen().ToString()); + + // Entering fullscreen mode will not update the maximized window's size + // under fullscreen. + WMEvent fullscreen_event(WM_EVENT_FULLSCREEN); + WindowState* fullscreen_state = GetWindowState(fullscreen.get()); + fullscreen_state->OnWMEvent(&fullscreen_event); + ASSERT_TRUE(fullscreen_state->IsFullscreen()); + ASSERT_TRUE(maximized_state->IsMaximized()); + EXPECT_EQ("0,0 800x553", maximized->GetBoundsInScreen().ToString()); + + // Updating display size will update the maximum window size. + UpdateDisplay("900x700"); + EXPECT_EQ("0,0 900x700", maximized->GetBoundsInScreen().ToString()); + fullscreen.reset(); + + // Exitting fullscreen will update the maximized widnow to the work area. + EXPECT_EQ("0,0 900x653", maximized->GetBoundsInScreen().ToString()); +} + // TODO(skuhne): Add more unit test to verify the correctness for the restore // operation.
diff --git a/base/BUILD.gn b/base/BUILD.gn index e5f3c196..6bc61d41 100644 --- a/base/BUILD.gn +++ b/base/BUILD.gn
@@ -1005,6 +1005,8 @@ output_name = "base_i18n" sources = [ "i18n/base_i18n_export.h", + "i18n/base_i18n_switches.cc", + "i18n/base_i18n_switches.h", "i18n/bidi_line_iterator.cc", "i18n/bidi_line_iterator.h", "i18n/break_iterator.cc", @@ -1257,6 +1259,7 @@ test("base_unittests") { sources = [ + "allocator/tcmalloc_unittest.cc", "android/application_status_listener_unittest.cc", "android/content_uri_utils_unittest.cc", "android/jni_android_unittest.cc",
diff --git a/base/allocator/BUILD.gn b/base/allocator/BUILD.gn index ad781f8..7c94b5d 100644 --- a/base/allocator/BUILD.gn +++ b/base/allocator/BUILD.gn
@@ -3,6 +3,7 @@ # found in the LICENSE file. import("//build/config/allocator.gni") +import("//build/config/compiler/compiler.gni") declare_args() { # Provide a way to force disable debugallocation in Debug builds, @@ -147,8 +148,6 @@ "$tcmalloc_dir/src/base/synchronization_profiling.h", "$tcmalloc_dir/src/base/sysinfo.cc", "$tcmalloc_dir/src/base/sysinfo.h", - "$tcmalloc_dir/src/base/thread_lister.c", - "$tcmalloc_dir/src/base/thread_lister.h", "$tcmalloc_dir/src/base/vdso_support.cc", "$tcmalloc_dir/src/base/vdso_support.h", "$tcmalloc_dir/src/central_freelist.cc", @@ -175,11 +174,6 @@ "$tcmalloc_dir/src/memory_region_map.h", "$tcmalloc_dir/src/page_heap.cc", "$tcmalloc_dir/src/page_heap.h", - "$tcmalloc_dir/src/profile-handler.cc", - "$tcmalloc_dir/src/profile-handler.h", - "$tcmalloc_dir/src/profiledata.cc", - "$tcmalloc_dir/src/profiledata.h", - "$tcmalloc_dir/src/profiler.cc", "$tcmalloc_dir/src/raw_printer.cc", "$tcmalloc_dir/src/raw_printer.h", "$tcmalloc_dir/src/sampler.cc", @@ -239,16 +233,8 @@ "$tcmalloc_dir/src/symbolize.h", "$tcmalloc_dir/src/system-alloc.cc", "$tcmalloc_dir/src/system-alloc.h", - - # cpuprofiler - "$tcmalloc_dir/src/base/thread_lister.c", - "$tcmalloc_dir/src/base/thread_lister.h", - "$tcmalloc_dir/src/profile-handler.cc", - "$tcmalloc_dir/src/profile-handler.h", - "$tcmalloc_dir/src/profiledata.cc", - "$tcmalloc_dir/src/profiledata.h", - "$tcmalloc_dir/src/profiler.cc", ] + defines += [ "PERFTOOLS_DLL_DECL=" ] configs -= [ @@ -262,6 +248,19 @@ deps += [ ":prep_libc" ] } + if (enable_profiling) { + sources += [ + "$tcmalloc_dir/src/base/thread_lister.c", + "$tcmalloc_dir/src/base/thread_lister.h", + "$tcmalloc_dir/src/profile-handler.cc", + "$tcmalloc_dir/src/profile-handler.h", + "$tcmalloc_dir/src/profiledata.cc", + "$tcmalloc_dir/src/profiledata.h", + "$tcmalloc_dir/src/profiler.cc", + ] + defines += [ "ENABLE_PROFILING=1" ] + } + if (is_linux || is_android) { sources -= [ "$tcmalloc_dir/src/system-alloc.h",
diff --git a/base/allocator/allocator.gyp b/base/allocator/allocator.gyp index ae93e9e0..a49c2680 100644 --- a/base/allocator/allocator.gyp +++ b/base/allocator/allocator.gyp
@@ -16,6 +16,10 @@ 'variables': { 'tcmalloc_dir': '../../third_party/tcmalloc/chromium', 'use_vtable_verify%': 0, + # Provide a way to force disable debugallocation in Debug builds + # e.g. for profiling (it's more rare to profile Debug builds, + # but people sometimes need to do that). + 'disable_debugallocation%': 0, }, 'targets': [ # Only executables and not libraries should depend on the @@ -23,70 +27,82 @@ # knows what allocator makes sense. { 'target_name': 'allocator', + # TODO(primiano): This should be type: none for the noop cases (an empty + # static lib can confuse some gyp generators). Fix it once the refactoring + # (crbug.com/564618) bring this file to a saner state (fewer conditions). 'type': 'static_library', - 'direct_dependent_settings': { - 'configurations': { - 'Common_Base': { - 'msvs_settings': { - 'VCLinkerTool': { - 'IgnoreDefaultLibraryNames': ['libcmtd.lib', 'libcmt.lib'], - 'AdditionalDependencies': [ - '<(SHARED_INTERMEDIATE_DIR)/allocator/libcmt.lib' - ], - }, + 'conditions': [ + # TODO(primiano): in next CL this should check win_use_allocator_shim. + # Right now that would produce a non-zero ninja diff for asan=1. + ['OS=="win" and component!="shared_library"', { + 'msvs_settings': { + # TODO(sgk): merge this with build/common.gypi settings + 'VCLibrarianTool': { + 'AdditionalOptions': ['/ignore:4006,4221'], + }, + 'VCLinkerTool': { + 'AdditionalOptions': ['/ignore:4006'], }, }, - }, - 'conditions': [ - ['OS=="win"', { + 'dependencies': [ + 'libcmt', + + # TODO(primiano): remove in next CL, not really needed. + '../third_party/dynamic_annotations/dynamic_annotations.gyp:dynamic_annotations', + ], + 'include_dirs': [ + '.', # TODO(primiano): remove in next CL, not really needed. + '../..', + ], + 'sources': [ + 'allocator_shim_win.cc', + ], + 'configurations': { + 'Debug_Base': { + 'msvs_settings': { + 'VCCLCompilerTool': { + 'RuntimeLibrary': '0', + }, + }, + # TODO(primiano): remove this 'conditions' section soon. This is + # only for tc-malloc, which is not supported on windows. The only + # reason os it is to make the initial refactoring easier and + # a zero-diff ninja w.r.t. the current situation. + 'conditions': [ + ['disable_debugallocation==0', { + 'defines': [ 'TCMALLOC_FOR_DEBUGALLOCATION' ], + }], + ], + }, + }, + 'direct_dependent_settings': { + 'configurations': { + 'Common_Base': { + 'msvs_settings': { + 'VCLinkerTool': { + 'IgnoreDefaultLibraryNames': ['libcmtd.lib', 'libcmt.lib'], + 'AdditionalDependencies': [ + '<(SHARED_INTERMEDIATE_DIR)/allocator/libcmt.lib' + ], + }, + }, + }, + }, 'defines': [ 'PERFTOOLS_DLL_DECL=', ], - }], - ], - }, - 'dependencies': [ - '../third_party/dynamic_annotations/dynamic_annotations.gyp:dynamic_annotations', - ], - 'msvs_settings': { - # TODO(sgk): merge this with build/common.gypi settings - 'VCLibrarianTool': { - 'AdditionalOptions': ['/ignore:4006,4221'], - }, - 'VCLinkerTool': { - 'AdditionalOptions': ['/ignore:4006'], - }, - }, - 'configurations': { - 'Debug_Base': { - 'msvs_settings': { - 'VCCLCompilerTool': { - 'RuntimeLibrary': '0', - }, }, - 'variables': { - # Provide a way to force disable debugallocation in Debug builds, - # e.g. for profiling (it's more rare to profile Debug builds, - # but people sometimes need to do that). - 'disable_debugallocation%': 0, - }, - 'conditions': [ - ['disable_debugallocation==0', { - 'defines': [ - # Use debugallocation for Debug builds to catch problems early - # and cleanly, http://crbug.com/30715 . - 'TCMALLOC_FOR_DEBUGALLOCATION', - ], - }], - ], - }, - }, - 'conditions': [ + }], # OS=="win" ['use_allocator=="tcmalloc"', { # Disable the heap checker in tcmalloc. 'defines': [ 'NO_HEAP_CHECK', ], + 'dependencies': [ + '../third_party/dynamic_annotations/dynamic_annotations.gyp:dynamic_annotations', + ], + # The order of this include_dirs matters, as tc-malloc has its own + # base/ mini-fork. Do not factor these out of this conditions section. 'include_dirs': [ '.', '<(tcmalloc_dir)/src/base', @@ -287,59 +303,66 @@ # Included by debugallocation_shim.cc. '<(tcmalloc_dir)/src/debugallocation.cc', '<(tcmalloc_dir)/src/tcmalloc.cc', - ] - },{ - 'include_dirs': [ - '.', - '../..', ], - }], - ['OS=="win" and component!="shared_library"', { - 'dependencies': [ - 'libcmt', + 'conditions': [ + ['OS=="linux" or OS=="freebsd" or OS=="solaris" or OS=="android"', { + 'sources!': [ + '<(tcmalloc_dir)/src/system-alloc.h', + ], + # We enable all warnings by default, but upstream disables a few. + # Keep "-Wno-*" flags in sync with upstream by comparing against: + # http://code.google.com/p/google-perftools/source/browse/trunk/Makefile.am + 'cflags': [ + '-Wno-sign-compare', + '-Wno-unused-result', + ], + 'cflags!': [ + '-fvisibility=hidden', + ], + 'link_settings': { + 'ldflags': [ + # Don't let linker rip this symbol out, otherwise the heap&cpu + # profilers will not initialize properly on startup. + '-Wl,-uIsHeapProfilerRunning,-uProfilerStart', + # Do the same for heap leak checker. + '-Wl,-u_Z21InitialMallocHook_NewPKvj,-u_Z22InitialMallocHook_MMapPKvS0_jiiix,-u_Z22InitialMallocHook_SbrkPKvi', + '-Wl,-u_Z21InitialMallocHook_NewPKvm,-u_Z22InitialMallocHook_MMapPKvS0_miiil,-u_Z22InitialMallocHook_SbrkPKvl', + '-Wl,-u_ZN15HeapLeakChecker12IgnoreObjectEPKv,-u_ZN15HeapLeakChecker14UnIgnoreObjectEPKv', + ], + }, + }], + ['profiling!=1', { + 'sources!': [ + # cpuprofiler + '<(tcmalloc_dir)/src/base/thread_lister.c', + '<(tcmalloc_dir)/src/base/thread_lister.h', + '<(tcmalloc_dir)/src/profile-handler.cc', + '<(tcmalloc_dir)/src/profile-handler.h', + '<(tcmalloc_dir)/src/profiledata.cc', + '<(tcmalloc_dir)/src/profiledata.h', + '<(tcmalloc_dir)/src/profiler.cc', + ], + }], ], - 'sources': [ - 'allocator_shim_win.cc', - ], - }], - ['profiling!=1', { - 'sources!': [ - # cpuprofiler - '<(tcmalloc_dir)/src/base/thread_lister.c', - '<(tcmalloc_dir)/src/base/thread_lister.h', - '<(tcmalloc_dir)/src/profile-handler.cc', - '<(tcmalloc_dir)/src/profile-handler.h', - '<(tcmalloc_dir)/src/profiledata.cc', - '<(tcmalloc_dir)/src/profiledata.h', - '<(tcmalloc_dir)/src/profiler.cc', - ], - }], - ['OS=="linux" or OS=="freebsd" or OS=="solaris" or OS=="android"', { - 'sources!': [ - '<(tcmalloc_dir)/src/system-alloc.h', - ], - # We enable all warnings by default, but upstream disables a few. - # Keep "-Wno-*" flags in sync with upstream by comparing against: - # http://code.google.com/p/google-perftools/source/browse/trunk/Makefile.am - 'cflags': [ - '-Wno-sign-compare', - '-Wno-unused-result', - ], - 'cflags!': [ - '-fvisibility=hidden', - ], - 'link_settings': { - 'ldflags': [ - # Don't let linker rip this symbol out, otherwise the heap&cpu - # profilers will not initialize properly on startup. - '-Wl,-uIsHeapProfilerRunning,-uProfilerStart', - # Do the same for heap leak checker. - '-Wl,-u_Z21InitialMallocHook_NewPKvj,-u_Z22InitialMallocHook_MMapPKvS0_jiiix,-u_Z22InitialMallocHook_SbrkPKvi', - '-Wl,-u_Z21InitialMallocHook_NewPKvm,-u_Z22InitialMallocHook_MMapPKvS0_miiil,-u_Z22InitialMallocHook_SbrkPKvl', - '-Wl,-u_ZN15HeapLeakChecker12IgnoreObjectEPKv,-u_ZN15HeapLeakChecker14UnIgnoreObjectEPKv', - ]}, - }], - [ 'use_vtable_verify==1', { + 'configurations': { + 'Debug_Base': { + 'conditions': [ + ['disable_debugallocation==0', { + 'defines': [ + # Use debugallocation for Debug builds to catch problems + # early and cleanly, http://crbug.com/30715 . + 'TCMALLOC_FOR_DEBUGALLOCATION', + ], + }], + ], + }, + }, + }], # use_allocator=="tcmalloc + # For CrOS builds with vtable verification. According to the author of + # crrev.com/10854031 this is used in conjuction with some other CrOS + # build flag, to enable verification of any allocator that uses virtual + # function calls. + ['use_vtable_verify==1', { 'cflags': [ '-fvtable-verify=preinit', ], @@ -351,12 +374,9 @@ }], ], }], - ], - }, + ], # conditions of 'allocator' target. + }, # 'allocator' target. { - # This library is linked in to src/base.gypi:base and allocator_unittests - # It can't depend on either and nothing else should depend on it - all - # other code should use the interfaced provided by base. 'target_name': 'allocator_extension_thunks', 'type': 'static_library', 'sources': [ @@ -394,24 +414,6 @@ }, ], }, - { - 'target_name': 'allocator_unittests', - 'type': 'executable', - 'dependencies': [ - 'allocator', - 'allocator_extension_thunks', - '../../testing/gtest.gyp:gtest', - ], - 'include_dirs': [ - '.', - '../..', - ], - 'sources': [ - '../profiler/alternate_timer.cc', - '../profiler/alternate_timer.h', - 'allocator_unittest.cc', - ], - }, ], }], ['OS=="win" and target_arch=="ia32"', { @@ -435,24 +437,5 @@ }, ], }], - ['use_allocator=="tcmalloc"', { - 'targets': [ - { - 'target_name': 'tcmalloc_unittest', - 'type': 'executable', - 'sources': [ - 'tcmalloc_unittest.cc', - ], - 'include_dirs': [ - '<(tcmalloc_dir)/src', - '../..', - ], - 'dependencies': [ - '../../testing/gtest.gyp:gtest', - 'allocator', - ], - }, - ], - }], ], }
diff --git a/base/allocator/allocator_unittest.cc b/base/allocator/allocator_unittest.cc deleted file mode 100644 index a1d1ef0..0000000 --- a/base/allocator/allocator_unittest.cc +++ /dev/null
@@ -1,245 +0,0 @@ -// Copyright 2014 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include <stdio.h> -#include <stdlib.h> -#include <algorithm> // for min() - -#include "base/macros.h" -#include "testing/gtest/include/gtest/gtest.h" - -// Number of bits in a size_t. -static const int kSizeBits = 8 * sizeof(size_t); -// The maximum size of a size_t. -static const size_t kMaxSize = ~static_cast<size_t>(0); -// Maximum positive size of a size_t if it were signed. -static const size_t kMaxSignedSize = ((size_t(1) << (kSizeBits-1)) - 1); - -namespace { - -using std::min; - -// Fill a buffer of the specified size with a predetermined pattern -static void Fill(unsigned char* buffer, int n) { - for (int i = 0; i < n; i++) { - buffer[i] = (i & 0xff); - } -} - -// Check that the specified buffer has the predetermined pattern -// generated by Fill() -static bool Valid(unsigned char* buffer, int n) { - for (int i = 0; i < n; i++) { - if (buffer[i] != (i & 0xff)) { - return false; - } - } - return true; -} - -// Check that a buffer is completely zeroed. -static bool IsZeroed(unsigned char* buffer, int n) { - for (int i = 0; i < n; i++) { - if (buffer[i] != 0) { - return false; - } - } - return true; -} - -// Check alignment -static void CheckAlignment(void* p, int align) { - EXPECT_EQ(0, reinterpret_cast<uintptr_t>(p) & (align-1)); -} - -// Return the next interesting size/delta to check. Returns -1 if no more. -static int NextSize(int size) { - if (size < 100) - return size+1; - - if (size < 100000) { - // Find next power of two - int power = 1; - while (power < size) - power <<= 1; - - // Yield (power-1, power, power+1) - if (size < power-1) - return power-1; - - if (size == power-1) - return power; - - assert(size == power); - return power+1; - } else { - return -1; - } -} - -static void TestCalloc(size_t n, size_t s, bool ok) { - char* p = reinterpret_cast<char*>(calloc(n, s)); - if (!ok) { - EXPECT_EQ(NULL, p) << "calloc(n, s) should not succeed"; - } else { - EXPECT_NE(reinterpret_cast<void*>(NULL), p) << - "calloc(n, s) should succeed"; - for (size_t i = 0; i < n*s; i++) { - EXPECT_EQ('\0', p[i]); - } - free(p); - } -} - -} // namespace - -//----------------------------------------------------------------------------- - - -TEST(Allocators, Malloc) { - // Try allocating data with a bunch of alignments and sizes - for (int size = 1; size < 1048576; size *= 2) { - unsigned char* ptr = reinterpret_cast<unsigned char*>(malloc(size)); - CheckAlignment(ptr, 2); // Should be 2 byte aligned - Fill(ptr, size); - EXPECT_TRUE(Valid(ptr, size)); - free(ptr); - } -} - -TEST(Allocators, Calloc) { - TestCalloc(0, 0, true); - TestCalloc(0, 1, true); - TestCalloc(1, 1, true); - TestCalloc(1<<10, 0, true); - TestCalloc(1<<20, 0, true); - TestCalloc(0, 1<<10, true); - TestCalloc(0, 1<<20, true); - TestCalloc(1<<20, 2, true); - TestCalloc(2, 1<<20, true); - TestCalloc(1000, 1000, true); - - TestCalloc(kMaxSize, 2, false); - TestCalloc(2, kMaxSize, false); - TestCalloc(kMaxSize, kMaxSize, false); - - TestCalloc(kMaxSignedSize, 3, false); - TestCalloc(3, kMaxSignedSize, false); - TestCalloc(kMaxSignedSize, kMaxSignedSize, false); -} - -// This makes sure that reallocing a small number of bytes in either -// direction doesn't cause us to allocate new memory. -TEST(Allocators, Realloc1) { - int start_sizes[] = { 100, 1000, 10000, 100000 }; - int deltas[] = { 1, -2, 4, -8, 16, -32, 64, -128 }; - - for (int s = 0; s < sizeof(start_sizes)/sizeof(*start_sizes); ++s) { - void* p = malloc(start_sizes[s]); - ASSERT_TRUE(p); - // The larger the start-size, the larger the non-reallocing delta. - for (int d = 0; d < s*2; ++d) { - void* new_p = realloc(p, start_sizes[s] + deltas[d]); - ASSERT_EQ(p, new_p); // realloc should not allocate new memory - } - // Test again, but this time reallocing smaller first. - for (int d = 0; d < s*2; ++d) { - void* new_p = realloc(p, start_sizes[s] - deltas[d]); - ASSERT_EQ(p, new_p); // realloc should not allocate new memory - } - free(p); - } -} - -TEST(Allocators, Realloc2) { - for (int src_size = 0; src_size >= 0; src_size = NextSize(src_size)) { - for (int dst_size = 0; dst_size >= 0; dst_size = NextSize(dst_size)) { - unsigned char* src = reinterpret_cast<unsigned char*>(malloc(src_size)); - Fill(src, src_size); - unsigned char* dst = - reinterpret_cast<unsigned char*>(realloc(src, dst_size)); - EXPECT_TRUE(Valid(dst, min(src_size, dst_size))); - Fill(dst, dst_size); - EXPECT_TRUE(Valid(dst, dst_size)); - if (dst != NULL) free(dst); - } - } - - // Now make sure realloc works correctly even when we overflow the - // packed cache, so some entries are evicted from the cache. - // The cache has 2^12 entries, keyed by page number. - const int kNumEntries = 1 << 14; - int** p = reinterpret_cast<int**>(malloc(sizeof(*p) * kNumEntries)); - int sum = 0; - for (int i = 0; i < kNumEntries; i++) { - // no page size is likely to be bigger than 8192? - p[i] = reinterpret_cast<int*>(malloc(8192)); - p[i][1000] = i; // use memory deep in the heart of p - } - for (int i = 0; i < kNumEntries; i++) { - p[i] = reinterpret_cast<int*>(realloc(p[i], 9000)); - } - for (int i = 0; i < kNumEntries; i++) { - sum += p[i][1000]; - free(p[i]); - } - EXPECT_EQ(kNumEntries/2 * (kNumEntries - 1), sum); // assume kNE is even - free(p); -} - -// Test recalloc -TEST(Allocators, Recalloc) { - for (int src_size = 0; src_size >= 0; src_size = NextSize(src_size)) { - for (int dst_size = 0; dst_size >= 0; dst_size = NextSize(dst_size)) { - unsigned char* src = - reinterpret_cast<unsigned char*>(_recalloc(NULL, 1, src_size)); - EXPECT_TRUE(IsZeroed(src, src_size)); - Fill(src, src_size); - unsigned char* dst = - reinterpret_cast<unsigned char*>(_recalloc(src, 1, dst_size)); - EXPECT_TRUE(Valid(dst, min(src_size, dst_size))); - Fill(dst, dst_size); - EXPECT_TRUE(Valid(dst, dst_size)); - if (dst != NULL) - free(dst); - } - } -} - -// Test windows specific _aligned_malloc() and _aligned_free() methods. -TEST(Allocators, AlignedMalloc) { - // Try allocating data with a bunch of alignments and sizes - static const int kTestAlignments[] = {8, 16, 256, 4096, 8192, 16384}; - for (int size = 1; size > 0; size = NextSize(size)) { - for (int i = 0; i < arraysize(kTestAlignments); ++i) { - unsigned char* ptr = static_cast<unsigned char*>( - _aligned_malloc(size, kTestAlignments[i])); - CheckAlignment(ptr, kTestAlignments[i]); - Fill(ptr, size); - EXPECT_TRUE(Valid(ptr, size)); - - // Make a second allocation of the same size and alignment to prevent - // allocators from passing this test by accident. Per jar, tcmalloc - // provides allocations for new (never before seen) sizes out of a thread - // local heap of a given "size class." Each time the test requests a new - // size, it will usually get the first element of a span, which is a - // 4K aligned allocation. - unsigned char* ptr2 = static_cast<unsigned char*>( - _aligned_malloc(size, kTestAlignments[i])); - CheckAlignment(ptr2, kTestAlignments[i]); - Fill(ptr2, size); - EXPECT_TRUE(Valid(ptr2, size)); - - // Should never happen, but sanity check just in case. - ASSERT_NE(ptr, ptr2); - _aligned_free(ptr); - _aligned_free(ptr2); - } - } -} - -int main(int argc, char** argv) { - testing::InitGoogleTest(&argc, argv); - return RUN_ALL_TESTS(); -}
diff --git a/base/allocator/tcmalloc_unittest.cc b/base/allocator/tcmalloc_unittest.cc index 0f7082eb..04a1466 100644 --- a/base/allocator/tcmalloc_unittest.cc +++ b/base/allocator/tcmalloc_unittest.cc
@@ -1,96 +1,222 @@ // Copyright (c) 2012 The Chromium Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. + #include <stddef.h> #include <stdio.h> +#include "base/logging.h" +#include "base/process/process_metrics.h" +#include "build/build_config.h" #include "testing/gtest/include/gtest/gtest.h" -// TCMalloc header files. -#include "common.h" // For TCMalloc constants like page size, etc. - -// TCMalloc implementation. -#include "debugallocation_shim.cc" +#if defined(USE_TCMALLOC) +extern "C" { +void* tc_malloc(size_t size); +void tc_free(void*); +} namespace { +using std::min; + +#ifdef NDEBUG void* TCMallocDoMallocForTest(size_t size) { - return do_malloc(size); + return tc_malloc(size); } void TCMallocDoFreeForTest(void* ptr) { - do_free(ptr); + tc_free(ptr); +} +#endif + +// Fill a buffer of the specified size with a predetermined pattern +static void Fill(unsigned char* buffer, int n) { + for (int i = 0; i < n; i++) { + buffer[i] = (i & 0xff); + } } -size_t ExcludeSpaceForMarkForTest(size_t size) { - return ExcludeSpaceForMark(size); +// Check that the specified buffer has the predetermined pattern +// generated by Fill() +static bool Valid(unsigned char* buffer, int n) { + for (int i = 0; i < n; i++) { + if (buffer[i] != (i & 0xff)) { + return false; + } + } + return true; +} + +// Return the next interesting size/delta to check. Returns -1 if no more. +static int NextSize(int size) { + if (size < 100) + return size + 1; + + if (size < 100000) { + // Find next power of two + int power = 1; + while (power < size) + power <<= 1; + + // Yield (power-1, power, power+1) + if (size < power - 1) + return power - 1; + + if (size == power - 1) + return power; + + CHECK_EQ(size, power); + return power + 1; + } else { + return -1; + } +} + +static void TestCalloc(size_t n, size_t s, bool ok) { + char* p = reinterpret_cast<char*>(calloc(n, s)); + if (!ok) { + EXPECT_EQ(NULL, p) << "calloc(n, s) should not succeed"; + } else { + EXPECT_NE(reinterpret_cast<void*>(NULL), p) + << "calloc(n, s) should succeed"; + for (size_t i = 0; i < n * s; i++) { + EXPECT_EQ('\0', p[i]); + } + free(p); + } } } // namespace -TEST(TCMallocFreeCheck, BadPointerInFirstPageOfTheLargeObject) { - char* p = reinterpret_cast<char*>( - TCMallocDoMallocForTest(ExcludeSpaceForMarkForTest(kMaxSize + 1))); - for (int offset = 1; offset < kPageSize ; offset <<= 1) { +TEST(TCMallocTest, Malloc) { + // Try allocating data with a bunch of alignments and sizes + for (int size = 1; size < 1048576; size *= 2) { + unsigned char* ptr = reinterpret_cast<unsigned char*>(malloc(size)); + // Should be 2 byte aligned + EXPECT_EQ(0u, reinterpret_cast<uintptr_t>(ptr) & 1); + Fill(ptr, size); + EXPECT_TRUE(Valid(ptr, size)); + free(ptr); + } +} + +TEST(TCMallocTest, Calloc) { + TestCalloc(0, 0, true); + TestCalloc(0, 1, true); + TestCalloc(1, 1, true); + TestCalloc(1 << 10, 0, true); + TestCalloc(1 << 20, 0, true); + TestCalloc(0, 1 << 10, true); + TestCalloc(0, 1 << 20, true); + TestCalloc(1 << 20, 2, true); + TestCalloc(2, 1 << 20, true); + TestCalloc(1000, 1000, true); +} + +#ifdef NDEBUG +// This makes sure that reallocing a small number of bytes in either +// direction doesn't cause us to allocate new memory. Tcmalloc in debug mode +// does not follow this. +TEST(TCMallocTest, ReallocSmallDelta) { + int start_sizes[] = {100, 1000, 10000, 100000}; + int deltas[] = {1, -2, 4, -8, 16, -32, 64, -128}; + + for (unsigned s = 0; s < sizeof(start_sizes) / sizeof(*start_sizes); ++s) { + void* p = malloc(start_sizes[s]); + ASSERT_TRUE(p); + // The larger the start-size, the larger the non-reallocing delta. + for (unsigned d = 0; d < s * 2; ++d) { + void* new_p = realloc(p, start_sizes[s] + deltas[d]); + ASSERT_EQ(p, new_p); // realloc should not allocate new memory + } + // Test again, but this time reallocing smaller first. + for (unsigned d = 0; d < s * 2; ++d) { + void* new_p = realloc(p, start_sizes[s] - deltas[d]); + ASSERT_EQ(p, new_p); // realloc should not allocate new memory + } + free(p); + } +} +#endif + +TEST(TCMallocTest, Realloc) { + for (int src_size = 0; src_size >= 0; src_size = NextSize(src_size)) { + for (int dst_size = 0; dst_size >= 0; dst_size = NextSize(dst_size)) { + unsigned char* src = reinterpret_cast<unsigned char*>(malloc(src_size)); + Fill(src, src_size); + unsigned char* dst = + reinterpret_cast<unsigned char*>(realloc(src, dst_size)); + EXPECT_TRUE(Valid(dst, min(src_size, dst_size))); + Fill(dst, dst_size); + EXPECT_TRUE(Valid(dst, dst_size)); + if (dst != NULL) + free(dst); + } + } + + // Now make sure realloc works correctly even when we overflow the + // packed cache, so some entries are evicted from the cache. + // The cache has 2^12 entries, keyed by page number. + const int kNumEntries = 1 << 14; + int** p = reinterpret_cast<int**>(malloc(sizeof(*p) * kNumEntries)); + int sum = 0; + for (int i = 0; i < kNumEntries; i++) { + // no page size is likely to be bigger than 8192? + p[i] = reinterpret_cast<int*>(malloc(8192)); + p[i][1000] = i; // use memory deep in the heart of p + } + for (int i = 0; i < kNumEntries; i++) { + p[i] = reinterpret_cast<int*>(realloc(p[i], 9000)); + } + for (int i = 0; i < kNumEntries; i++) { + sum += p[i][1000]; + free(p[i]); + } + EXPECT_EQ(kNumEntries / 2 * (kNumEntries - 1), sum); // assume kNE is even + free(p); +} + +#ifdef NDEBUG +TEST(TCMallocFreeTest, BadPointerInFirstPageOfTheLargeObject) { + const size_t kPageSize = base::GetPageSize(); + char* p = + reinterpret_cast<char*>(TCMallocDoMallocForTest(10 * kPageSize + 1)); + for (unsigned offset = 1; offset < kPageSize; offset <<= 1) { ASSERT_DEATH(TCMallocDoFreeForTest(p + offset), "Pointer is not pointing to the start of a span"); } } -TEST(TCMallocFreeCheck, BadPageAlignedPointerInsideLargeObject) { - char* p = reinterpret_cast<char*>( - TCMallocDoMallocForTest(ExcludeSpaceForMarkForTest(kMaxSize + 1))); +TEST(TCMallocFreeTest, BadPageAlignedPointerInsideLargeObject) { + const size_t kPageSize = base::GetPageSize(); + const size_t kMaxSize = 10 * kPageSize; + char* p = reinterpret_cast<char*>(TCMallocDoMallocForTest(kMaxSize + 1)); - for (int offset = kPageSize; offset < kMaxSize; offset += kPageSize) { + for (unsigned offset = kPageSize; offset < kMaxSize; offset += kPageSize) { // Only the first and last page of a span are in heap map. So for others // tcmalloc will give a general error of invalid pointer. - ASSERT_DEATH(TCMallocDoFreeForTest(p + offset), - "Attempt to free invalid pointer"); + ASSERT_DEATH(TCMallocDoFreeForTest(p + offset), ""); } ASSERT_DEATH(TCMallocDoFreeForTest(p + kMaxSize), "Pointer is not pointing to the start of a span"); } -TEST(TCMallocFreeCheck, DoubleFreeLargeObject) { - char* p = reinterpret_cast<char*>( - TCMallocDoMallocForTest(ExcludeSpaceForMarkForTest(kMaxSize + 1))); +TEST(TCMallocFreeTest, DoubleFreeLargeObject) { + const size_t kMaxSize = 10 * base::GetPageSize(); + char* p = reinterpret_cast<char*>(TCMallocDoMallocForTest(kMaxSize + 1)); ASSERT_DEATH(TCMallocDoFreeForTest(p); TCMallocDoFreeForTest(p), "Object was not in-use"); } - -#ifdef NDEBUG -TEST(TCMallocFreeCheck, DoubleFreeSmallObject) { - for (size_t size = 1; - size <= ExcludeSpaceForMarkForTest(kMaxSize); - size <<= 1) { +TEST(TCMallocFreeTest, DoubleFreeSmallObject) { + const size_t kPageSize = base::GetPageSize(); + for (size_t size = 1; size <= kPageSize; size <<= 1) { char* p = reinterpret_cast<char*>(TCMallocDoMallocForTest(size)); ASSERT_DEATH(TCMallocDoFreeForTest(p); TCMallocDoFreeForTest(p), "Circular loop in list detected"); } } -#else -TEST(TCMallocFreeCheck, DoubleFreeSmallObject) { - size_t size = 1; +#endif // NDEBUG - // When the object is small, tcmalloc validation can not distinguish normal - // memory corruption or double free, because there's not enough space in - // freed objects to keep the mark. - for (; size <= ExcludeSpaceForMarkForTest(kMinClassSize); size <<= 1) { - char* p = reinterpret_cast<char*>(TCMallocDoMallocForTest(size)); - ASSERT_DEATH(TCMallocDoFreeForTest(p); TCMallocDoFreeForTest(p), - "Memory corrupted"); - } - - for (; size <= ExcludeSpaceForMarkForTest(kMaxSize); size <<= 1) { - char* p = reinterpret_cast<char*>(TCMallocDoMallocForTest(size)); - ASSERT_DEATH(TCMallocDoFreeForTest(p); TCMallocDoFreeForTest(p), - "Attempt to double free"); - } -} #endif - -int main(int argc, char **argv) { - testing::InitGoogleTest(&argc, argv); - return RUN_ALL_TESTS(); -}
diff --git a/base/base.gyp b/base/base.gyp index 6ab4b36..e067154bd 100644 --- a/base/base.gyp +++ b/base/base.gyp
@@ -21,6 +21,7 @@ 'optimize': 'max', }, 'dependencies': [ + 'base_debugging_flags', 'base_static', 'allocator/allocator.gyp:allocator_extension_thunks', '../testing/gtest.gyp:gtest_prod', @@ -426,6 +427,7 @@ 'target_name': 'base_unittests', 'type': '<(gtest_target_type)', 'sources': [ + 'allocator/tcmalloc_unittest.cc', 'android/application_status_listener_unittest.cc', 'android/content_uri_utils_unittest.cc', 'android/jni_android_unittest.cc', @@ -1076,6 +1078,18 @@ }], ], }, + { + # GN version: //base/debug:debugging_flags + 'target_name': 'base_debugging_flags', + 'toolsets': ['host', 'target'], + 'includes': [ '../build/buildflag_header.gypi' ], + 'variables': { + 'buildflag_header_path': 'base/debug/debugging_flags.h', + 'buildflag_flags': [ + 'ENABLE_PROFILING=<(profiling)', + ], + }, + }, ], 'conditions': [ ['OS=="ios" and "<(GENERATOR)"=="ninja"', { @@ -1131,6 +1145,7 @@ 'base_target': 1, }, 'dependencies': [ + 'base_debugging_flags', 'base_static_win64', 'allocator/allocator.gyp:allocator_extension_thunks_win64', '../third_party/modp_b64/modp_b64.gyp:modp_b64_win64',
diff --git a/base/base.gypi b/base/base.gypi index 35bd747..3ad9ccf 100644 --- a/base/base.gypi +++ b/base/base.gypi
@@ -1018,6 +1018,8 @@ ], 'sources': [ 'i18n/base_i18n_export.h', + 'i18n/base_i18n_switches.cc', + 'i18n/base_i18n_switches.h', 'i18n/bidi_line_iterator.cc', 'i18n/bidi_line_iterator.h', 'i18n/break_iterator.cc',
diff --git a/base/base_nacl.gyp b/base/base_nacl.gyp index b2b4b7f..7010256 100644 --- a/base/base_nacl.gyp +++ b/base/base_nacl.gyp
@@ -39,6 +39,9 @@ '-fno-strict-aliasing', ], }, + 'dependencies': [ + 'base.gyp:base_debugging_flags', + ], }, { 'target_name': 'base_i18n_nacl', @@ -115,6 +118,7 @@ ], 'dependencies': [ '../third_party/libevent/libevent_nacl_nonsfi.gyp:event_nacl_nonsfi', + 'base.gyp:base_debugging_flags', ], }, {
diff --git a/base/basictypes.h b/base/basictypes.h index c17cfbb..e39e29fb 100644 --- a/base/basictypes.h +++ b/base/basictypes.h
@@ -26,7 +26,6 @@ // DEPRECATED: Use std::numeric_limits (from <limits>) or // (U)INT{8,16,32,64}_{MIN,MAX} in case of globals (and include <stdint.h>). // http://crbug.com/138542 -const uint32 kuint32max = 0xFFFFFFFF; const uint64 kuint64max = 0xFFFFFFFFFFFFFFFFULL; const int32 kint32max = 0x7FFFFFFF; const int64 kint64max = 0x7FFFFFFFFFFFFFFFLL;
diff --git a/base/debug/BUILD.gn b/base/debug/BUILD.gn index be8084e..ec9298a7 100644 --- a/base/debug/BUILD.gn +++ b/base/debug/BUILD.gn
@@ -2,6 +2,9 @@ # Use of this source code is governed by a BSD-style license that can be # found in the LICENSE file. +import("//build/buildflag_header.gni") +import("//build/config/compiler/compiler.gni") + source_set("debug") { sources = [ "alias.cc", @@ -58,6 +61,7 @@ configs += [ "//base:base_implementation" ] deps = [ + ":debugging_flags", "//base:base_static", "//base/memory", "//base/process", @@ -75,3 +79,9 @@ visibility = [ "//base/*" ] } + +buildflag_header("debugging_flags") { + header = "debugging_flags.h" + + flags = [ "ENABLE_PROFILING=$enable_profiling" ] +}
diff --git a/base/debug/profiler.cc b/base/debug/profiler.cc index 924c769..b499c14 100644 --- a/base/debug/profiler.cc +++ b/base/debug/profiler.cc
@@ -6,6 +6,7 @@ #include <string> +#include "base/debug/debugging_flags.h" #include "base/process/process_handle.h" #include "base/strings/string_number_conversions.h" #include "base/strings/string_util.h" @@ -15,7 +16,7 @@ #endif // defined(OS_WIN) // TODO(peria): Enable profiling on Windows. -#if defined(ENABLE_PROFILING) && !defined(NO_TCMALLOC) && !defined(OS_WIN) +#if BUILDFLAG(ENABLE_PROFILING) && !defined(NO_TCMALLOC) && !defined(OS_WIN) #include "third_party/tcmalloc/chromium/src/gperftools/profiler.h" #endif @@ -23,7 +24,7 @@ namespace debug { // TODO(peria): Enable profiling on Windows. -#if defined(ENABLE_PROFILING) && !defined(NO_TCMALLOC) && !defined(OS_WIN) +#if BUILDFLAG(ENABLE_PROFILING) && !defined(NO_TCMALLOC) && !defined(OS_WIN) static int profile_count = 0;
diff --git a/base/i18n/base_i18n_switches.cc b/base/i18n/base_i18n_switches.cc new file mode 100644 index 0000000..44e8393 --- /dev/null +++ b/base/i18n/base_i18n_switches.cc
@@ -0,0 +1,16 @@ +// 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. + +#include "base/i18n/base_i18n_switches.h" + +namespace switches { + +// Force the UI to a specific direction. Valid values are "ltr" (left-to-right) +// and "rtl" (right-to-left). +const char kForceUIDirection[] = "force-ui-direction"; + +const char kForceUIDirectionLTR[] = "ltr"; +const char kForceUIDirectionRTL[] = "rtl"; + +} // namespace switches
diff --git a/base/i18n/base_i18n_switches.h b/base/i18n/base_i18n_switches.h new file mode 100644 index 0000000..f00cff3 --- /dev/null +++ b/base/i18n/base_i18n_switches.h
@@ -0,0 +1,20 @@ +// 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. + +#ifndef BASE_I18N_BASE_I18N_SWITCHES_H_ +#define BASE_I18N_BASE_I18N_SWITCHES_H_ + +#include "base/i18n/base_i18n_export.h" + +namespace switches { + +BASE_I18N_EXPORT extern const char kForceUIDirection[]; + +// kForceUIDirection choices. +BASE_I18N_EXPORT extern const char kForceUIDirectionLTR[]; +BASE_I18N_EXPORT extern const char kForceUIDirectionRTL[]; + +} // namespace switches + +#endif // BASE_I18N_BASE_I18N_SWITCHES_H_
diff --git a/base/i18n/rtl.cc b/base/i18n/rtl.cc index ac9589c..adcf6deb0 100644 --- a/base/i18n/rtl.cc +++ b/base/i18n/rtl.cc
@@ -6,7 +6,9 @@ #include <algorithm> +#include "base/command_line.h" #include "base/files/file_path.h" +#include "base/i18n/base_i18n_switches.h" #include "base/logging.h" #include "base/strings/string_split.h" #include "base/strings/string_util.h" @@ -64,6 +66,30 @@ return base::i18n::UNKNOWN_DIRECTION; } +// Gets the explicitly forced text direction for debugging. If no forcing is +// applied, returns UNKNOWN_DIRECTION. +base::i18n::TextDirection GetForcedTextDirection() { + // On iOS, check for RTL forcing. +#if defined(OS_IOS) + if (base::ios::IsInForcedRTL()) + return base::i18n::RIGHT_TO_LEFT; +#endif + + base::CommandLine* command_line = base::CommandLine::ForCurrentProcess(); + if (command_line->HasSwitch(switches::kForceUIDirection)) { + std::string force_flag = + command_line->GetSwitchValueASCII(switches::kForceUIDirection); + + if (force_flag == switches::kForceUIDirectionLTR) + return base::i18n::LEFT_TO_RIGHT; + + if (force_flag == switches::kForceUIDirectionRTL) + return base::i18n::RIGHT_TO_LEFT; + } + + return base::i18n::UNKNOWN_DIRECTION; +} + } // namespace namespace base { @@ -135,11 +161,10 @@ } TextDirection GetTextDirectionForLocaleInStartUp(const char* locale_name) { -// On iOS, check for RTL forcing. -#if defined(OS_IOS) - if (ios::IsInForcedRTL()) - return RIGHT_TO_LEFT; -#endif + // Check for direction forcing. + TextDirection forced_direction = GetForcedTextDirection(); + if (forced_direction != UNKNOWN_DIRECTION) + return forced_direction; // This list needs to be updated in alphabetical order if we add more RTL // locales. @@ -155,11 +180,10 @@ } TextDirection GetTextDirectionForLocale(const char* locale_name) { - // On iOS, check for RTL forcing. -#if defined(OS_IOS) - if (ios::IsInForcedRTL()) - return RIGHT_TO_LEFT; -#endif + // Check for direction forcing. + TextDirection forced_direction = GetForcedTextDirection(); + if (forced_direction != UNKNOWN_DIRECTION) + return forced_direction; UErrorCode status = U_ZERO_ERROR; ULayoutType layout_dir = uloc_getCharacterOrientation(locale_name, &status);
diff --git a/base/macros.h b/base/macros.h index 4adbbb07..5f8d9705d2d 100644 --- a/base/macros.h +++ b/base/macros.h
@@ -27,13 +27,6 @@ TypeName(const TypeName&); \ void operator=(const TypeName&) -// An older, deprecated, politically incorrect name for the above. -// NOTE: The usage of this macro was banned from our code base, but some -// third_party libraries are yet using it. -// TODO(tfarina): Figure out how to fix the usage of this macro in the -// third_party libraries and get rid of it. -#define DISALLOW_EVIL_CONSTRUCTORS(TypeName) DISALLOW_COPY_AND_ASSIGN(TypeName) - // A macro to disallow all the implicit constructors, namely the // default constructor, copy constructor and operator= functions. //
diff --git a/base/memory/discardable_shared_memory.cc b/base/memory/discardable_shared_memory.cc index 2b0cfd0..24bd3e3 100644 --- a/base/memory/discardable_shared_memory.cc +++ b/base/memory/discardable_shared_memory.cc
@@ -122,15 +122,8 @@ if (!checked_size.IsValid()) return false; -#if defined(OS_MACOSX) && !defined(OS_IOS) - // DiscardableSharedMemory does not yet support a Mach-implementation, so - // force the underlying primitive to be a POSIX fd. https://crbug.com/547239. - if (!shared_memory_.CreateAndMapAnonymousPosix(checked_size.ValueOrDie())) - return false; -#else if (!shared_memory_.CreateAndMapAnonymous(checked_size.ValueOrDie())) return false; -#endif // defined(OS_MACOSX) && !defined(OS_IOS) mapped_size_ = shared_memory_.mapped_size() - AlignToPageSize(sizeof(SharedState));
diff --git a/base/memory/ref_counted.h b/base/memory/ref_counted.h index 26c6551..85dd433 100644 --- a/base/memory/ref_counted.h +++ b/base/memory/ref_counted.h
@@ -14,7 +14,6 @@ #ifndef NDEBUG #include "base/logging.h" #endif -#include "base/move.h" #include "base/threading/thread_collision_warner.h" #include "build/build_config.h" @@ -265,7 +264,6 @@ // template <class T> class scoped_refptr { - TYPE_WITH_MOVE_CONSTRUCTOR_FOR_CPP_03(scoped_refptr) public: typedef T element_type; @@ -277,17 +275,24 @@ AddRef(ptr_); } + // Copy constructor. scoped_refptr(const scoped_refptr<T>& r) : ptr_(r.ptr_) { if (ptr_) AddRef(ptr_); } + // Copy conversion constructor. template <typename U> scoped_refptr(const scoped_refptr<U>& r) : ptr_(r.get()) { if (ptr_) AddRef(ptr_); } + // Move constructor. This is required in addition to the conversion + // constructor below in order for clang to warn about pessimizing moves. + scoped_refptr(scoped_refptr&& r) : ptr_(r.get()) { r.ptr_ = nullptr; } + + // Move conversion constructor. template <typename U> scoped_refptr(scoped_refptr<U>&& r) : ptr_(r.get()) { r.ptr_ = nullptr;
diff --git a/base/move.h b/base/move.h index fe0517e..6743eb7 100644 --- a/base/move.h +++ b/base/move.h
@@ -63,9 +63,4 @@ \ private: -#define TYPE_WITH_MOVE_CONSTRUCTOR_FOR_CPP_03(type) \ - public: \ - type&& Pass() WARN_UNUSED_RESULT { return std::move(*this); } \ - private: - #endif // BASE_MOVE_H_
diff --git a/base/path_service.cc b/base/path_service.cc index 97a0ce5..3b9b69e1 100644 --- a/base/path_service.cc +++ b/base/path_service.cc
@@ -126,19 +126,9 @@ providers = &base_provider_posix; #endif } - - ~PathData() { - Provider* p = providers; - while (p) { - Provider* next = p->next; - if (!p->is_static) - delete p; - p = next; - } - } }; -static LazyInstance<PathData> g_path_data = LAZY_INSTANCE_INITIALIZER; +static LazyInstance<PathData>::Leaky g_path_data = LAZY_INSTANCE_INITIALIZER; static PathData* GetPathData() { return g_path_data.Pointer();
diff --git a/base/pickle.cc b/base/pickle.cc index 489c7f8..6fcdece3 100644 --- a/base/pickle.cc +++ b/base/pickle.cc
@@ -30,7 +30,7 @@ const char* read_from = GetReadPointerAndAdvance<Type>(); if (!read_from) return false; - if (sizeof(Type) > sizeof(uint32)) + if (sizeof(Type) > sizeof(uint32_t)) memcpy(result, read_from, sizeof(*result)); else *result = *reinterpret_cast<const Type*>(read_from); @@ -72,9 +72,9 @@ int num_elements, size_t size_element) { // Check for int32 overflow. - int64 num_bytes = static_cast<int64>(num_elements) * size_element; + int64_t num_bytes = static_cast<int64_t>(num_elements) * size_element; int num_bytes32 = static_cast<int>(num_bytes); - if (num_bytes != static_cast<int64>(num_bytes32)) + if (num_bytes != static_cast<int64_t>(num_bytes32)) return NULL; return GetReadPointerAndAdvance(num_bytes32); } @@ -91,26 +91,26 @@ return ReadBuiltinType(result); } -bool PickleIterator::ReadUInt16(uint16* result) { +bool PickleIterator::ReadUInt16(uint16_t* result) { return ReadBuiltinType(result); } -bool PickleIterator::ReadUInt32(uint32* result) { +bool PickleIterator::ReadUInt32(uint32_t* result) { return ReadBuiltinType(result); } -bool PickleIterator::ReadInt64(int64* result) { +bool PickleIterator::ReadInt64(int64_t* result) { return ReadBuiltinType(result); } -bool PickleIterator::ReadUInt64(uint64* result) { +bool PickleIterator::ReadUInt64(uint64_t* result) { return ReadBuiltinType(result); } bool PickleIterator::ReadSizeT(size_t* result) { // Always read size_t as a 64-bit value to ensure compatibility between 32-bit // and 64-bit processes. - uint64 result_uint64 = 0; + uint64_t result_uint64 = 0; bool success = ReadBuiltinType(&result_uint64); *result = static_cast<size_t>(result_uint64); // Fail if the cast above truncates the value. @@ -207,7 +207,7 @@ return true; } -// Payload is uint32 aligned. +// Payload is uint32_t aligned. Pickle::Pickle() : header_(NULL), @@ -222,7 +222,7 @@ Pickle::Pickle(int header_size) : header_(NULL), - header_size_(bits::Align(header_size, sizeof(uint32))), + header_size_(bits::Align(header_size, sizeof(uint32_t))), capacity_after_header_(0), write_offset_(0) { DCHECK_GE(static_cast<size_t>(header_size), sizeof(Header)); @@ -242,7 +242,7 @@ if (header_size_ > static_cast<unsigned int>(data_len)) header_size_ = 0; - if (header_size_ != bits::Align(header_size_, sizeof(uint32))) + if (header_size_ != bits::Align(header_size_, sizeof(uint32_t))) header_size_ = 0; // If there is anything wrong with the data, we're not going to use it. @@ -310,12 +310,12 @@ } void Pickle::Reserve(size_t length) { - size_t data_len = bits::Align(length, sizeof(uint32)); + size_t data_len = bits::Align(length, sizeof(uint32_t)); DCHECK_GE(data_len, length); #ifdef ARCH_CPU_64_BITS - DCHECK_LE(data_len, kuint32max); + DCHECK_LE(data_len, std::numeric_limits<uint32_t>::max()); #endif - DCHECK_LE(write_offset_, kuint32max - data_len); + DCHECK_LE(write_offset_, std::numeric_limits<uint32_t>::max() - data_len); size_t new_size = write_offset_ + data_len; if (new_size > capacity_after_header_) Resize(capacity_after_header_ * 2 + new_size); @@ -354,7 +354,7 @@ const char* start, const char* end, size_t* pickle_size) { - DCHECK_EQ(header_size, bits::Align(header_size, sizeof(uint32))); + DCHECK_EQ(header_size, bits::Align(header_size, sizeof(uint32_t))); DCHECK_GE(header_size, sizeof(Header)); DCHECK_LE(header_size, static_cast<size_t>(kPayloadUnit)); @@ -388,12 +388,12 @@ DCHECK_NE(kCapacityReadOnly, capacity_after_header_) << "oops: pickle is readonly"; MSAN_CHECK_MEM_IS_INITIALIZED(data, length); - size_t data_len = bits::Align(length, sizeof(uint32)); + size_t data_len = bits::Align(length, sizeof(uint32_t)); DCHECK_GE(data_len, length); #ifdef ARCH_CPU_64_BITS - DCHECK_LE(data_len, kuint32max); + DCHECK_LE(data_len, std::numeric_limits<uint32_t>::max()); #endif - DCHECK_LE(write_offset_, kuint32max - data_len); + DCHECK_LE(write_offset_, std::numeric_limits<uint32_t>::max() - data_len); size_t new_size = write_offset_ + data_len; if (new_size > capacity_after_header_) { size_t new_capacity = capacity_after_header_ * 2; @@ -406,7 +406,7 @@ char* write = mutable_payload() + write_offset_; memcpy(write, data, length); memset(write + length, 0, data_len - length); - header_->payload_size = static_cast<uint32>(new_size); + header_->payload_size = static_cast<uint32_t>(new_size); write_offset_ = new_size; }
diff --git a/base/pickle.h b/base/pickle.h index 22b8055..72b33ddc 100644 --- a/base/pickle.h +++ b/base/pickle.h
@@ -5,10 +5,11 @@ #ifndef BASE_PICKLE_H_ #define BASE_PICKLE_H_ +#include <stdint.h> + #include <string> #include "base/base_export.h" -#include "base/basictypes.h" #include "base/compiler_specific.h" #include "base/gtest_prod_util.h" #include "base/logging.h" @@ -34,10 +35,10 @@ bool ReadBool(bool* result) WARN_UNUSED_RESULT; bool ReadInt(int* result) WARN_UNUSED_RESULT; bool ReadLong(long* result) WARN_UNUSED_RESULT; - bool ReadUInt16(uint16* result) WARN_UNUSED_RESULT; - bool ReadUInt32(uint32* result) WARN_UNUSED_RESULT; - bool ReadInt64(int64* result) WARN_UNUSED_RESULT; - bool ReadUInt64(uint64* result) WARN_UNUSED_RESULT; + bool ReadUInt16(uint16_t* result) WARN_UNUSED_RESULT; + bool ReadUInt32(uint32_t* result) WARN_UNUSED_RESULT; + bool ReadInt64(int64_t* result) WARN_UNUSED_RESULT; + bool ReadUInt64(uint64_t* result) WARN_UNUSED_RESULT; bool ReadSizeT(size_t* result) WARN_UNUSED_RESULT; bool ReadFloat(float* result) WARN_UNUSED_RESULT; bool ReadDouble(double* result) WARN_UNUSED_RESULT; @@ -179,22 +180,14 @@ bool WriteLongUsingDangerousNonPortableLessPersistableForm(long value) { return WritePOD(value); } - bool WriteUInt16(uint16 value) { - return WritePOD(value); - } - bool WriteUInt32(uint32 value) { - return WritePOD(value); - } - bool WriteInt64(int64 value) { - return WritePOD(value); - } - bool WriteUInt64(uint64 value) { - return WritePOD(value); - } + bool WriteUInt16(uint16_t value) { return WritePOD(value); } + bool WriteUInt32(uint32_t value) { return WritePOD(value); } + bool WriteInt64(int64_t value) { return WritePOD(value); } + bool WriteUInt64(uint64_t value) { return WritePOD(value); } bool WriteSizeT(size_t value) { // Always write size_t as a 64-bit value to ensure compatibility between // 32-bit and 64-bit processes. - return WritePOD(static_cast<uint64>(value)); + return WritePOD(static_cast<uint64_t>(value)); } bool WriteFloat(float value) { return WritePOD(value); @@ -219,7 +212,7 @@ // Payload follows after allocation of Header (header size is customizable). struct Header { - uint32 payload_size; // Specifies the size of the payload. + uint32_t payload_size; // Specifies the size of the payload. }; // Returns the header, cast to a user-specified type T. The type T must be a
diff --git a/base/profiler/native_stack_sampler_win.cc b/base/profiler/native_stack_sampler_win.cc index 7b41fee..87bb6ce 100644 --- a/base/profiler/native_stack_sampler_win.cc +++ b/base/profiler/native_stack_sampler_win.cc
@@ -138,21 +138,30 @@ } // Walks the stack represented by |context| from the current frame downwards, -// recording the instruction pointers for each frame in |instruction_pointers|. -int RecordStack(CONTEXT* context, int max_stack_size, - const void* instruction_pointers[], - ScopedModuleHandle modules[]) { +// recording the instruction pointers for each frame in |instruction_pointers| +// and associated modules in |modules|. +void RecordStack(CONTEXT* context, + std::vector<const void*>* instruction_pointers, + std::vector<ScopedModuleHandle>* modules) { #ifdef _WIN64 + DCHECK(instruction_pointers->empty()); + DCHECK(modules->empty()); + + // Reserve enough memory for most stacks, to avoid repeated + // allocations. Approximately 99.5% of recorded stacks are 64 frames or fewer. + instruction_pointers->reserve(64); + modules->reserve(64); + Win32StackFrameUnwinder frame_unwinder; - int i = 0; - for (; (i < max_stack_size) && context->Rip; ++i) { - instruction_pointers[i] = reinterpret_cast<const void*>(context->Rip); - if (!frame_unwinder.TryUnwind(context, &modules[i])) - return i; + while (context->Rip) { + const void* instruction_pointer = + reinterpret_cast<const void*>(context->Rip); + ScopedModuleHandle module; + if (!frame_unwinder.TryUnwind(context, &module)) + return; + instruction_pointers->push_back(instruction_pointer); + modules->push_back(std::move(module)); } - return i; -#else - return 0; #endif } @@ -259,22 +268,24 @@ } // Suspends the thread with |thread_handle|, copies its stack and resumes the -// thread, then records the stack into |instruction_pointers|. Returns the size -// of the stack. +// thread, then records the stack into |instruction_pointers| and associated +// modules into |modules|. // // IMPORTANT NOTE: No allocations from the default heap may occur in the // ScopedSuspendThread scope, including indirectly via use of DCHECK/CHECK or // other logging statements. Otherwise this code can deadlock on heap locks in -// the default heap acquired by the target thread before it was suspended. This -// is why we pass instruction pointers as preallocated arrays. -int SuspendThreadAndRecordStack(HANDLE thread_handle, - const void* base_address, - void* stack_copy_buffer, - size_t stack_copy_buffer_size, - int max_stack_size, - const void* instruction_pointers[], - ScopedModuleHandle modules[], - NativeStackSamplerTestDelegate* test_delegate) { +// the default heap acquired by the target thread before it was suspended. +void SuspendThreadAndRecordStack( + HANDLE thread_handle, + const void* base_address, + void* stack_copy_buffer, + size_t stack_copy_buffer_size, + std::vector<const void*>* instruction_pointers, + std::vector<ScopedModuleHandle>* modules, + NativeStackSamplerTestDelegate* test_delegate) { + DCHECK(instruction_pointers->empty()); + DCHECK(modules->empty()); + CONTEXT thread_context = {0}; thread_context.ContextFlags = CONTEXT_FULL; // The stack bounds are saved to uintptr_ts for use outside @@ -287,10 +298,10 @@ ScopedSuspendThread suspend_thread(thread_handle); if (!suspend_thread.was_successful()) - return 0; + return; if (!::GetThreadContext(thread_handle, &thread_context)) - return 0; + return; #if defined(_WIN64) bottom = thread_context.Rsp; #else @@ -298,7 +309,7 @@ #endif if ((top - bottom) > stack_copy_buffer_size) - return 0; + return; std::memcpy(stack_copy_buffer, reinterpret_cast<const void*>(bottom), top - bottom); @@ -309,8 +320,7 @@ RewritePointersToStackMemory(top, bottom, &thread_context, stack_copy_buffer); - return RecordStack(&thread_context, max_stack_size, instruction_pointers, - modules); + RecordStack(&thread_context, instruction_pointers, modules); } // NativeStackSamplerWin ------------------------------------------------------ @@ -351,9 +361,8 @@ // Copies the stack information represented by |instruction_pointers| into // |sample| and |modules|. - void CopyToSample(const void* const instruction_pointers[], - const ScopedModuleHandle module_handles[], - int stack_depth, + void CopyToSample(const std::vector<const void*>& instruction_pointers, + const std::vector<ScopedModuleHandle>& module_handles, StackSamplingProfiler::Sample* sample, std::vector<StackSamplingProfiler::Module>* modules); @@ -404,20 +413,12 @@ if (!stack_copy_buffer_) return; - const int max_stack_size = 64; - const void* instruction_pointers[max_stack_size] = {0}; - ScopedModuleHandle modules[max_stack_size]; - - int stack_depth = SuspendThreadAndRecordStack(thread_handle_.Get(), - thread_stack_base_address_, - stack_copy_buffer_.get(), - kStackCopyBufferSize, - max_stack_size, - instruction_pointers, - modules, - test_delegate_); - CopyToSample(instruction_pointers, modules, stack_depth, sample, - current_modules_); + std::vector<const void*> instruction_pointers; + std::vector<ScopedModuleHandle> modules; + SuspendThreadAndRecordStack(thread_handle_.Get(), thread_stack_base_address_, + stack_copy_buffer_.get(), kStackCopyBufferSize, + &instruction_pointers, &modules, test_delegate_); + CopyToSample(instruction_pointers, modules, sample, current_modules_); } void NativeStackSamplerWin::ProfileRecordingStopped() { @@ -465,15 +466,15 @@ } void NativeStackSamplerWin::CopyToSample( - const void* const instruction_pointers[], - const ScopedModuleHandle module_handles[], - int stack_depth, + const std::vector<const void*>& instruction_pointers, + const std::vector<ScopedModuleHandle>& module_handles, StackSamplingProfiler::Sample* sample, std::vector<StackSamplingProfiler::Module>* modules) { + DCHECK_EQ(instruction_pointers.size(), module_handles.size()); sample->clear(); - sample->reserve(stack_depth); + sample->reserve(instruction_pointers.size()); - for (int i = 0; i < stack_depth; ++i) { + for (size_t i = 0; i < instruction_pointers.size(); ++i) { sample->push_back(StackSamplingProfiler::Frame( reinterpret_cast<uintptr_t>(instruction_pointers[i]), GetModuleIndex(module_handles[i].Get(), modules)));
diff --git a/base/win/event_trace_provider.h b/base/win/event_trace_provider.h index 7907347..a87cb9c1 100644 --- a/base/win/event_trace_provider.h +++ b/base/win/event_trace_provider.h
@@ -10,9 +10,12 @@ #include <windows.h> #include <wmistr.h> #include <evntrace.h> +#include <stdint.h> + +#include <limits> #include "base/base_export.h" -#include "base/basictypes.h" +#include "base/macros.h" namespace base { namespace win { @@ -66,7 +69,7 @@ void SetField(int field, size_t size, const void *data) { // DCHECK(field < N); - if ((field < N) && (size <= kuint32max)) { + if ((field < N) && (size <= std::numeric_limits<uint32_t>::max())) { fields[field].DataPtr = reinterpret_cast<ULONG64>(data); fields[field].Length = static_cast<ULONG>(size); }
diff --git a/blimp/BUILD.gn b/blimp/BUILD.gn index 7dc92b8..d29270cc 100644 --- a/blimp/BUILD.gn +++ b/blimp/BUILD.gn
@@ -45,6 +45,7 @@ test("blimp_unittests") { deps = [ "//blimp/client:unit_tests", + "//blimp/common:unit_tests", "//blimp/net:unit_tests", ]
diff --git a/blimp/client/BUILD.gn b/blimp/client/BUILD.gn index edde7b61..48f647b 100644 --- a/blimp/client/BUILD.gn +++ b/blimp/client/BUILD.gn
@@ -57,6 +57,7 @@ "//base", "//base/test:run_all_unittests", "//base/test:test_support", + "//blimp/common:blimp_common", "//blimp/common/proto", "//blimp/net:blimp_net", "//blimp/net:test_support",
diff --git a/blimp/client/compositor/render_widget_message_processor.cc b/blimp/client/compositor/render_widget_message_processor.cc index 23ad1de..73699fc0 100644 --- a/blimp/client/compositor/render_widget_message_processor.cc +++ b/blimp/client/compositor/render_widget_message_processor.cc
@@ -5,6 +5,7 @@ #include "blimp/client/compositor/render_widget_message_processor.h" #include "base/numerics/safe_conversions.h" +#include "blimp/common/create_blimp_message.h" #include "blimp/common/proto/blimp_message.pb.h" #include "blimp/common/proto/compositor.pb.h" #include "blimp/common/proto/input.pb.h" @@ -48,10 +49,10 @@ void RenderWidgetMessageProcessor::SendCompositorMessage( const int tab_id, const cc::proto::CompositorMessage& message) { - scoped_ptr<BlimpMessage> blimp_message(new BlimpMessage); - blimp_message->set_target_tab_id(tab_id); + CompositorMessage* compositor_message; + scoped_ptr<BlimpMessage> blimp_message = + CreateBlimpMessage(&compositor_message, tab_id); - CompositorMessage* compositor_message = blimp_message->mutable_compositor(); uint32_t render_widget_id = GetRenderWidgetId(tab_id); DCHECK_LT(0U, render_widget_id); compositor_message->set_render_widget_id(render_widget_id);
diff --git a/blimp/client/compositor/render_widget_message_processor_unittest.cc b/blimp/client/compositor/render_widget_message_processor_unittest.cc index b2aa921..384c7314 100644 --- a/blimp/client/compositor/render_widget_message_processor_unittest.cc +++ b/blimp/client/compositor/render_widget_message_processor_unittest.cc
@@ -6,6 +6,7 @@ #include "base/logging.h" #include "base/memory/scoped_ptr.h" +#include "blimp/common/create_blimp_message.h" #include "blimp/common/proto/blimp_message.pb.h" #include "blimp/common/proto/compositor.pb.h" #include "blimp/common/proto/render_widget.pb.h" @@ -50,11 +51,8 @@ void SendRenderWidgetMessage(BlimpMessageProcessor* processor, int tab_id, uint32_t rw_id) { - scoped_ptr<BlimpMessage> message(new BlimpMessage); - message->set_type(BlimpMessage::RENDER_WIDGET); - message->set_target_tab_id(tab_id); - - RenderWidgetMessage* details = message->mutable_render_widget(); + RenderWidgetMessage* details; + scoped_ptr<BlimpMessage> message = CreateBlimpMessage(&details, tab_id); details->set_type(RenderWidgetMessage::INITIALIZE); details->set_render_widget_id(rw_id); processor->ProcessMessage(std::move(message), @@ -64,11 +62,8 @@ void SendCompositorMessage(BlimpMessageProcessor* processor, int tab_id, uint32_t rw_id) { - scoped_ptr<BlimpMessage> message(new BlimpMessage); - message->set_type(BlimpMessage::COMPOSITOR); - message->set_target_tab_id(tab_id); - - CompositorMessage* details = message->mutable_compositor(); + CompositorMessage* details; + scoped_ptr<BlimpMessage> message = CreateBlimpMessage(&details, tab_id); details->set_render_widget_id(rw_id); processor->ProcessMessage(std::move(message), net::CompletionCallback());
diff --git a/blimp/common/BUILD.gn b/blimp/common/BUILD.gn index 49afa02..72d23e1 100644 --- a/blimp/common/BUILD.gn +++ b/blimp/common/BUILD.gn
@@ -9,6 +9,8 @@ "blimp_common_export.h", "compositor/blimp_task_graph_runner.cc", "compositor/blimp_task_graph_runner.h", + "create_blimp_message.cc", + "create_blimp_message.h", ] defines = [ "BLIMP_COMMON_IMPLEMENTATION=1" ] @@ -22,3 +24,17 @@ "//ui/gl", ] } + +source_set("unit_tests") { + testonly = true + + sources = [ + "create_blimp_message_unittest.cc", + ] + + deps = [ + ":blimp_common", + "//blimp/common/proto", + "//testing/gtest", + ] +}
diff --git a/blimp/common/create_blimp_message.cc b/blimp/common/create_blimp_message.cc new file mode 100644 index 0000000..4d331ac --- /dev/null +++ b/blimp/common/create_blimp_message.cc
@@ -0,0 +1,46 @@ +// 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. + +#include "blimp/common/create_blimp_message.h" + +#include "base/logging.h" +#include "base/memory/scoped_ptr.h" +#include "blimp/common/proto/blimp_message.pb.h" +#include "blimp/common/proto/compositor.pb.h" +#include "blimp/common/proto/input.pb.h" +#include "blimp/common/proto/render_widget.pb.h" + +namespace blimp { + +scoped_ptr<BlimpMessage> CreateBlimpMessage( + CompositorMessage** compositor_message, + int target_tab_id) { + DCHECK(compositor_message); + scoped_ptr<BlimpMessage> output(new BlimpMessage); + output->set_type(BlimpMessage::COMPOSITOR); + output->set_target_tab_id(target_tab_id); + *compositor_message = output->mutable_compositor(); + return output; +} + +scoped_ptr<BlimpMessage> CreateBlimpMessage(InputMessage** input_message) { + DCHECK(input_message); + scoped_ptr<BlimpMessage> output(new BlimpMessage); + output->set_type(BlimpMessage::INPUT); + *input_message = output->mutable_input(); + return output; +} + +scoped_ptr<BlimpMessage> CreateBlimpMessage( + RenderWidgetMessage** render_widget_message, + int target_tab_id) { + DCHECK(render_widget_message); + scoped_ptr<BlimpMessage> output(new BlimpMessage); + output->set_type(BlimpMessage::RENDER_WIDGET); + output->set_target_tab_id(target_tab_id); + *render_widget_message = output->mutable_render_widget(); + return output; +} + +} // namespace blimp
diff --git a/blimp/common/create_blimp_message.h b/blimp/common/create_blimp_message.h new file mode 100644 index 0000000..1e638d5 --- /dev/null +++ b/blimp/common/create_blimp_message.h
@@ -0,0 +1,43 @@ +// 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. + +#ifndef BLIMP_COMMON_CREATE_BLIMP_MESSAGE_H_ +#define BLIMP_COMMON_CREATE_BLIMP_MESSAGE_H_ + +#include "base/memory/scoped_ptr.h" +#include "blimp/common/blimp_common_export.h" + +namespace blimp { + +class BlimpMessage; +class CompositorMessage; +class InputMessage; +class RenderWidgetMessage; + +// Suite of helper methods to simplify the repetitive task of creating +// new BlimpMessages, initializing them, and extracting type-specific +// inner messages. +// +// +// Every specialization of CreateBlimpMessage returns an initialized +// BlimpMessage object. In addition, a pointer to the type-specific inner +// message is returned via the initial double-pointer parameter. +// +// Additional initialization arguments may be taken depending on the +// message type. + +BLIMP_COMMON_EXPORT scoped_ptr<BlimpMessage> CreateBlimpMessage( + CompositorMessage** compositor_message, + int target_tab_id); + +BLIMP_COMMON_EXPORT scoped_ptr<BlimpMessage> CreateBlimpMessage( + InputMessage** input_message); + +BLIMP_COMMON_EXPORT scoped_ptr<BlimpMessage> CreateBlimpMessage( + RenderWidgetMessage** render_widget_message, + int target_tab_id); + +} // namespace blimp + +#endif // BLIMP_COMMON_CREATE_BLIMP_MESSAGE_H_
diff --git a/blimp/common/create_blimp_message_unittest.cc b/blimp/common/create_blimp_message_unittest.cc new file mode 100644 index 0000000..1db89566 --- /dev/null +++ b/blimp/common/create_blimp_message_unittest.cc
@@ -0,0 +1,44 @@ +// 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. + +#include "blimp/common/create_blimp_message.h" +#include "blimp/common/proto/blimp_message.pb.h" +#include "blimp/common/proto/compositor.pb.h" +#include "blimp/common/proto/input.pb.h" +#include "blimp/common/proto/render_widget.pb.h" +#include "testing/gtest/include/gtest/gtest.h" + +namespace blimp { +namespace { + +const int kTabId = 1234; + +TEST(CreateBlimpMessageTest, CompositorMessage) { + CompositorMessage* details = nullptr; + scoped_ptr<BlimpMessage> message = CreateBlimpMessage(&details, kTabId); + EXPECT_NE(nullptr, details); + EXPECT_NE(nullptr, message); + EXPECT_EQ(details, message->mutable_compositor()); + EXPECT_EQ(kTabId, message->target_tab_id()); +} + +TEST(CreateBlimpMessageTest, InputMessage) { + InputMessage* details = nullptr; + scoped_ptr<BlimpMessage> message = CreateBlimpMessage(&details); + EXPECT_NE(nullptr, details); + EXPECT_NE(nullptr, message); + EXPECT_EQ(details, message->mutable_input()); +} + +TEST(CreateBlimpMessageTest, RenderWidgetMessage) { + RenderWidgetMessage* details = nullptr; + scoped_ptr<BlimpMessage> message = CreateBlimpMessage(&details, kTabId); + EXPECT_NE(nullptr, details); + EXPECT_NE(nullptr, message); + EXPECT_EQ(details, message->mutable_render_widget()); + EXPECT_EQ(kTabId, message->target_tab_id()); +} + +} // namespace +} // namespace blimp
diff --git a/blimp/engine/browser/BUILD.gn b/blimp/engine/browser/BUILD.gn index 714f092d..0bd678c4 100644 --- a/blimp/engine/browser/BUILD.gn +++ b/blimp/engine/browser/BUILD.gn
@@ -24,6 +24,7 @@ deps = [ "//base", + "//blimp/common:blimp_common", "//blimp/common/proto", "//blimp/engine/ui", "//blimp/net:blimp_net", @@ -51,6 +52,7 @@ "//base", "//base/test:run_all_unittests", "//base/test:test_support", + "//blimp/common:blimp_common", "//blimp/common/proto", "//blimp/engine/common", "//blimp/net:blimp_net",
diff --git a/blimp/engine/browser/engine_render_widget_message_processor.cc b/blimp/engine/browser/engine_render_widget_message_processor.cc index 00975d1..6e377dc 100644 --- a/blimp/engine/browser/engine_render_widget_message_processor.cc +++ b/blimp/engine/browser/engine_render_widget_message_processor.cc
@@ -5,6 +5,7 @@ #include "blimp/engine/browser/engine_render_widget_message_processor.h" #include "base/numerics/safe_conversions.h" +#include "blimp/common/create_blimp_message.h" #include "blimp/common/proto/blimp_message.pb.h" #include "blimp/common/proto/compositor.pb.h" #include "blimp/common/proto/input.pb.h" @@ -32,12 +33,9 @@ const int tab_id) { render_widget_ids_[tab_id] = GetRenderWidgetId(tab_id) + 1; - scoped_ptr<BlimpMessage> blimp_message(new BlimpMessage); - blimp_message->set_target_tab_id(tab_id); - - RenderWidgetMessage* render_widget_message = - blimp_message->mutable_render_widget(); - + RenderWidgetMessage* render_widget_message; + scoped_ptr<BlimpMessage> blimp_message = + CreateBlimpMessage(&render_widget_message, tab_id); render_widget_message->set_type(RenderWidgetMessage::INITIALIZE); render_widget_message->set_render_widget_id(GetRenderWidgetId(tab_id)); @@ -48,10 +46,10 @@ void EngineRenderWidgetMessageProcessor::SendCompositorMessage( const int tab_id, const std::vector<uint8_t>& message) { - scoped_ptr<BlimpMessage> blimp_message(new BlimpMessage); - blimp_message->set_target_tab_id(tab_id); + CompositorMessage* compositor_message; + scoped_ptr<BlimpMessage> blimp_message = + CreateBlimpMessage(&compositor_message, tab_id); - CompositorMessage* compositor_message = blimp_message->mutable_compositor(); uint32_t render_widget_id = GetRenderWidgetId(tab_id); DCHECK_LT(0U, render_widget_id); compositor_message->set_render_widget_id(render_widget_id);
diff --git a/blimp/engine/browser/engine_render_widget_message_processor_unittest.cc b/blimp/engine/browser/engine_render_widget_message_processor_unittest.cc index 2d0da5e9..70d78fdc 100644 --- a/blimp/engine/browser/engine_render_widget_message_processor_unittest.cc +++ b/blimp/engine/browser/engine_render_widget_message_processor_unittest.cc
@@ -7,6 +7,7 @@ #include "base/logging.h" #include "base/memory/scoped_ptr.h" #include "base/numerics/safe_conversions.h" +#include "blimp/common/create_blimp_message.h" #include "blimp/common/proto/blimp_message.pb.h" #include "blimp/common/proto/compositor.pb.h" #include "blimp/common/proto/render_widget.pb.h" @@ -91,11 +92,8 @@ int tab_id, uint32_t rw_id, const std::vector<uint8_t>& payload) { - scoped_ptr<BlimpMessage> message(new BlimpMessage); - message->set_type(BlimpMessage::COMPOSITOR); - message->set_target_tab_id(tab_id); - - CompositorMessage* details = message->mutable_compositor(); + CompositorMessage* details; + scoped_ptr<BlimpMessage> message = CreateBlimpMessage(&details, tab_id); details->set_render_widget_id(rw_id); details->set_payload(payload.data(), base::checked_cast<int>(payload.size())); processor->ProcessMessage(std::move(message),
diff --git a/blimp/net/BUILD.gn b/blimp/net/BUILD.gn index f20c77c..bd73b7a 100644 --- a/blimp/net/BUILD.gn +++ b/blimp/net/BUILD.gn
@@ -51,6 +51,7 @@ deps = [ "//base", + "//blimp/common:blimp_common", "//blimp/common/proto", "//net", ] @@ -82,6 +83,7 @@ "blimp_message_multiplexer_unittest.cc", "blimp_message_output_buffer_unittest.cc", "blimp_message_pump_unittest.cc", + "client_connection_manager_unittest.cc", "engine_connection_manager_unittest.cc", "input_message_unittest.cc", "stream_packet_reader_unittest.cc",
diff --git a/blimp/net/blimp_message_output_buffer.cc b/blimp/net/blimp_message_output_buffer.cc index 62cc259..c599ffaf 100644 --- a/blimp/net/blimp_message_output_buffer.cc +++ b/blimp/net/blimp_message_output_buffer.cc
@@ -66,7 +66,7 @@ DCHECK_GE(max_buffer_size_bytes_, current_buffer_size_bytes_); write_buffer_.push_back( - make_scoped_ptr(new BufferEntry(message.Pass(), callback))); + make_scoped_ptr(new BufferEntry(std::move(message), callback))); // Write the message if (write_buffer_.size() == 1 && output_processor_) { @@ -115,7 +115,7 @@ BlimpMessageOutputBuffer::BufferEntry::BufferEntry( scoped_ptr<BlimpMessage> message, net::CompletionCallback callback) - : message(message.Pass()), callback(callback) {} + : message(std::move(message)), callback(callback) {} BlimpMessageOutputBuffer::BufferEntry::~BufferEntry() {} @@ -131,7 +131,7 @@ << write_buffer_.front()->message->message_id() << ", type=" << message_to_write->type() << ")"; - output_processor_->ProcessMessage(message_to_write.Pass(), + output_processor_->ProcessMessage(std::move(message_to_write), write_complete_cb_.callback()); VLOG(3) << "Queue size: " << write_buffer_.size(); }
diff --git a/blimp/net/client_connection_manager.cc b/blimp/net/client_connection_manager.cc index 659f6a4..c8238e4 100644 --- a/blimp/net/client_connection_manager.cc +++ b/blimp/net/client_connection_manager.cc
@@ -5,29 +5,55 @@ #include "blimp/net/client_connection_manager.h" #include "base/logging.h" +#include "blimp/net/blimp_connection.h" +#include "blimp/net/blimp_transport.h" +#include "blimp/net/connection_handler.h" +#include "net/base/net_errors.h" namespace blimp { ClientConnectionManager::ClientConnectionManager( - ConnectionHandler* connection_handler) { - NOTIMPLEMENTED(); + ConnectionHandler* connection_handler) + : connection_handler_(connection_handler) { + DCHECK(connection_handler_); } -ClientConnectionManager::~ClientConnectionManager() { - NOTIMPLEMENTED(); +ClientConnectionManager::~ClientConnectionManager() {} + +void ClientConnectionManager::AddTransport( + scoped_ptr<BlimpTransport> transport) { + DCHECK(transport); + transports_.push_back(std::move(transport)); } void ClientConnectionManager::Connect() { - NOTIMPLEMENTED(); + // A |transport| added first is used first. When it fails to connect, + // the next transport is used. + DCHECK(!transports_.empty()); + Connect(0); } -void ClientConnectionManager::HandleConnection( - scoped_ptr<BlimpConnection> connection) { - NOTIMPLEMENTED(); +void ClientConnectionManager::Connect(int transport_index) { + if (static_cast<size_t>(transport_index) < transports_.size()) { + transports_[transport_index]->Connect( + base::Bind(&ClientConnectionManager::OnConnectResult, + base::Unretained(this), transport_index)); + } else { + // TODO(haibinlu): add an error reporting path out for this. + LOG(WARNING) << "All transports failed to connect"; + } } -void ClientConnectionManager::OnConnectionError(int error) { - NOTIMPLEMENTED(); +void ClientConnectionManager::OnConnectResult(int transport_index, int result) { + DCHECK_NE(result, net::ERR_IO_PENDING); + const auto& transport = transports_[transport_index]; + if (result == net::OK) { + connection_handler_->HandleConnection(transport->TakeConnection()); + } else { + DVLOG(1) << "Transport " << transport->GetName() + << " failed to connect:" << net::ErrorToString(result); + Connect(transport_index + 1); + } } } // namespace blimp
diff --git a/blimp/net/client_connection_manager.h b/blimp/net/client_connection_manager.h index ed9c9a9f..f259b62 100644 --- a/blimp/net/client_connection_manager.h +++ b/blimp/net/client_connection_manager.h
@@ -5,37 +5,53 @@ #ifndef BLIMP_NET_CLIENT_CONNECTION_MANAGER_H_ #define BLIMP_NET_CLIENT_CONNECTION_MANAGER_H_ +#include <vector> + #include "base/macros.h" -#include "blimp/net/blimp_connection.h" -#include "blimp/net/connection_error_observer.h" -#include "blimp/net/connection_handler.h" +#include "base/memory/scoped_ptr.h" +#include "blimp/net/blimp_net_export.h" namespace blimp { +class BlimpTransport; +class ConnectionHandler; + // Coordinates the channel creation and authentication workflows for // outgoing (Client) network connections. -// Attempts to reconnect if an authenticated connection is -// disconnected. -class ClientConnectionManager : public ConnectionHandler, - ConnectionErrorObserver { - // Caller is responsible for ensuring that |client_browser_session| +// +// TODO(haibinlu): cope with network changes that may potentially affect the +// endpoint that we're trying to connect to. +class BLIMP_NET_EXPORT ClientConnectionManager { + public: + // Caller is responsible for ensuring that |connection_handler| // outlives |this|. explicit ClientConnectionManager(ConnectionHandler* connection_handler); - ~ClientConnectionManager() override; + ~ClientConnectionManager(); + // Adds a transport. All transports are expected to be added before invoking + // |Connect|. + void AddTransport(scoped_ptr<BlimpTransport> transport); + + // Attempts to create a connection using any of the BlimpTransports in + // |transports_|. + // This will result in the handler being called back at-most-once. + // + // This is also a placeholder for automatic reconnection logic for common + // cases such as network switches, online/offline changes. void Connect(); - // ConnectionHandler implementation. - // Handles a new connection and authenticates it before passing it on to - // the underlying ConnectionHandler. - void HandleConnection(scoped_ptr<BlimpConnection> connection) override; - - // ConnectionErrorObserver implementation. - // Used to implement reconnection logic on unexpected disconnections. - void OnConnectionError(int error) override; - private: + // Tries to connect using the BlimpTransport specified at |transport_index|. + void Connect(int transport_index); + + // Callback invoked by transports_[transport_index] to indicate that it has a + // connection ready to be authenticated or there is an error. + void OnConnectResult(int transport_index, int result); + + ConnectionHandler* connection_handler_; + std::vector<scoped_ptr<BlimpTransport>> transports_; + DISALLOW_COPY_AND_ASSIGN(ClientConnectionManager); };
diff --git a/blimp/net/client_connection_manager_unittest.cc b/blimp/net/client_connection_manager_unittest.cc new file mode 100644 index 0000000..31d6a2bff --- /dev/null +++ b/blimp/net/client_connection_manager_unittest.cc
@@ -0,0 +1,104 @@ +// 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. + +#include <stddef.h> +#include <string> + +#include "base/callback_helpers.h" +#include "base/message_loop/message_loop.h" +#include "blimp/net/blimp_connection.h" +#include "blimp/net/blimp_transport.h" +#include "blimp/net/client_connection_manager.h" +#include "blimp/net/test_common.h" +#include "net/base/completion_callback.h" +#include "net/base/net_errors.h" +#include "net/base/test_completion_callback.h" +#include "testing/gmock/include/gmock/gmock.h" +#include "testing/gtest/include/gtest/gtest.h" + +using testing::_; +using testing::Eq; +using testing::Return; +using testing::SaveArg; + +namespace blimp { + +class ClientConnectionManagerTest : public testing::Test { + public: + ClientConnectionManagerTest() + : manager_(new ClientConnectionManager(&connection_handler_)), + transport1_(new testing::StrictMock<MockTransport>), + transport2_(new testing::StrictMock<MockTransport>), + connection_( + new BlimpConnection(make_scoped_ptr(new MockPacketReader), + make_scoped_ptr(new MockPacketWriter))) {} + + ~ClientConnectionManagerTest() override {} + + protected: + base::MessageLoop message_loop_; + testing::StrictMock<MockConnectionHandler> connection_handler_; + scoped_ptr<ClientConnectionManager> manager_; + scoped_ptr<testing::StrictMock<MockTransport>> transport1_; + scoped_ptr<testing::StrictMock<MockTransport>> transport2_; + scoped_ptr<BlimpConnection> connection_; +}; + +// The 1st transport connects, and the 2nd transport is not used. +TEST_F(ClientConnectionManagerTest, FirstTransportConnects) { + net::CompletionCallback connect_cb_1; + EXPECT_CALL(*transport1_, Connect(_)).WillOnce(SaveArg<0>(&connect_cb_1)); + EXPECT_CALL(connection_handler_, HandleConnectionPtr(Eq(connection_.get()))); + EXPECT_CALL(*transport1_, TakeConnectionPtr()) + .WillOnce(Return(connection_.release())); + + ASSERT_TRUE(connect_cb_1.is_null()); + manager_->AddTransport(std::move(transport1_)); + manager_->AddTransport(std::move(transport2_)); + manager_->Connect(); + ASSERT_FALSE(connect_cb_1.is_null()); + base::ResetAndReturn(&connect_cb_1).Run(net::OK); +} + +// The 1st transport fails to connect, and the 2nd transport connects. +TEST_F(ClientConnectionManagerTest, SecondTransportConnects) { + net::CompletionCallback connect_cb_1; + EXPECT_CALL(*transport1_, Connect(_)).WillOnce(SaveArg<0>(&connect_cb_1)); + net::CompletionCallback connect_cb_2; + EXPECT_CALL(*transport2_, Connect(_)).WillOnce(SaveArg<0>(&connect_cb_2)); + EXPECT_CALL(connection_handler_, HandleConnectionPtr(Eq(connection_.get()))); + EXPECT_CALL(*transport2_, TakeConnectionPtr()) + .WillOnce(Return(connection_.release())); + + ASSERT_TRUE(connect_cb_1.is_null()); + ASSERT_TRUE(connect_cb_2.is_null()); + manager_->AddTransport(std::move(transport1_)); + manager_->AddTransport(std::move(transport2_)); + manager_->Connect(); + ASSERT_FALSE(connect_cb_1.is_null()); + base::ResetAndReturn(&connect_cb_1).Run(net::ERR_FAILED); + ASSERT_FALSE(connect_cb_2.is_null()); + base::ResetAndReturn(&connect_cb_2).Run(net::OK); +} + +// Both transports fail to connect. +TEST_F(ClientConnectionManagerTest, BothTransportsFailToConnect) { + net::CompletionCallback connect_cb_1; + EXPECT_CALL(*transport1_, Connect(_)).WillOnce(SaveArg<0>(&connect_cb_1)); + net::CompletionCallback connect_cb_2; + EXPECT_CALL(*transport2_, Connect(_)).WillOnce(SaveArg<0>(&connect_cb_2)); + + ASSERT_TRUE(connect_cb_1.is_null()); + ASSERT_TRUE(connect_cb_2.is_null()); + manager_->AddTransport(std::move(transport1_)); + manager_->AddTransport(std::move(transport2_)); + manager_->Connect(); + ASSERT_FALSE(connect_cb_1.is_null()); + ASSERT_TRUE(connect_cb_2.is_null()); + base::ResetAndReturn(&connect_cb_1).Run(net::ERR_FAILED); + ASSERT_FALSE(connect_cb_2.is_null()); + base::ResetAndReturn(&connect_cb_2).Run(net::ERR_FAILED); +} + +} // namespace blimp
diff --git a/blimp/net/engine_connection_manager.cc b/blimp/net/engine_connection_manager.cc index 549caa3..053508e 100644 --- a/blimp/net/engine_connection_manager.cc +++ b/blimp/net/engine_connection_manager.cc
@@ -13,7 +13,9 @@ EngineConnectionManager::EngineConnectionManager( ConnectionHandler* connection_handler) - : connection_handler_(connection_handler) {} + : connection_handler_(connection_handler) { + DCHECK(connection_handler_); +} EngineConnectionManager::~EngineConnectionManager() {}
diff --git a/blimp/net/input_message_generator.cc b/blimp/net/input_message_generator.cc index ae0eef04d..507690c2 100644 --- a/blimp/net/input_message_generator.cc +++ b/blimp/net/input_message_generator.cc
@@ -5,6 +5,7 @@ #include "blimp/net/input_message_generator.h" #include "base/logging.h" +#include "blimp/common/create_blimp_message.h" #include "blimp/common/proto/blimp_message.pb.h" #include "blimp/common/proto/input.pb.h" #include "blimp/net/blimp_message_processor.h" @@ -113,9 +114,8 @@ scoped_ptr<BlimpMessage> InputMessageGenerator::GenerateMessage( const blink::WebInputEvent& event) { - scoped_ptr<BlimpMessage> message(new BlimpMessage); - message->set_type(BlimpMessage::INPUT); - InputMessage* details = message->mutable_input(); + InputMessage* details; + scoped_ptr<BlimpMessage> message = CreateBlimpMessage(&details); switch (event.type) { case blink::WebInputEvent::Type::GestureScrollBegin:
diff --git a/build/android/PRESUBMIT.py b/build/android/PRESUBMIT.py index 5e4c988e..38b2f01 100644 --- a/build/android/PRESUBMIT.py +++ b/build/android/PRESUBMIT.py
@@ -12,9 +12,11 @@ def CommonChecks(input_api, output_api): output = [] + build_android_dir = input_api.PresubmitLocalPath() + def J(*dirs): """Returns a path relative to presubmit directory.""" - return input_api.os_path.join(input_api.PresubmitLocalPath(), *dirs) + return input_api.os_path.join(build_android_dir, *dirs) build_pys = [ r'gyp/.*\.py$', @@ -40,7 +42,7 @@ pylib_test_env = dict(input_api.environ) pylib_test_env.update({ - 'PYTHONPATH': input_api.PresubmitLocalPath(), + 'PYTHONPATH': build_android_dir, 'PYTHONDONTWRITEBYTECODE': '1', }) output.extend(input_api.canned_checks.RunUnitTests( @@ -48,13 +50,6 @@ output_api, unit_tests=[ J('.', 'emma_coverage_stats_test.py'), - J('devil', 'android', 'fastboot_utils_test.py'), - J('devil', 'android', 'battery_utils_test.py'), - J('devil', 'android', 'device_utils_test.py'), - J('devil', 'android', 'md5sum_test.py'), - J('devil', 'android', 'logcat_monitor_test.py'), - J('devil', 'utils', 'cmd_helper_test.py'), - J('devil', 'utils', 'timeout_retry_unittest.py'), J('gyp', 'util', 'md5_check_test.py'), J('play_services', 'update_test.py'), J('pylib', 'base', 'test_dispatcher_unittest.py'), @@ -64,6 +59,26 @@ J('pylib', 'results', 'json_results_test.py'), ], env=pylib_test_env)) + + + devil_test_env = dict(pylib_test_env) + devil_test_env.update({ + 'DEVIL_ENV_CONFIG': + input_api.os_path.join(build_android_dir, 'devil_chromium.json') + }) + output.extend(input_api.canned_checks.RunUnitTests( + input_api, + output_api, + unit_tests=[ + J('devil', 'android', 'battery_utils_test.py'), + J('devil', 'android', 'device_utils_test.py'), + J('devil', 'android', 'fastboot_utils_test.py'), + J('devil', 'android', 'md5sum_test.py'), + J('devil', 'android', 'logcat_monitor_test.py'), + J('devil', 'utils', 'cmd_helper_test.py'), + J('devil', 'utils', 'timeout_retry_unittest.py'), + ], + env=devil_test_env)) return output
diff --git a/build/android/adb_gdb b/build/android/adb_gdb index 15320df..78bc182 100755 --- a/build/android/adb_gdb +++ b/build/android/adb_gdb
@@ -949,11 +949,17 @@ # Select correct app_process for architecture. case $TARGET_ARCH in - arm|x86|mips) GDBEXEC=app_process;; + arm|x86|mips) GDBEXEC=app_process32;; arm64|x86_64) GDBEXEC=app_process64;; *) fail_panic "Unknown app_process for architecture!";; esac +# Default to app_process if bit-width specific process isn't found. +adb_shell ls /system/bin/$GDBEXEC +if [ $? != 0 ]; then + GDBEXEC=app_process +fi + # Detect AddressSanitizer setup on the device. In that case app_process is a # script, and the real executable is app_process.real. GDBEXEC_ASAN=app_process.real
diff --git a/build/android/adb_install_apk.py b/build/android/adb_install_apk.py index a816bd4..0914bc1 100755 --- a/build/android/adb_install_apk.py +++ b/build/android/adb_install_apk.py
@@ -12,6 +12,8 @@ import os import sys +import devil_chromium + from devil.android import apk_helper from devil.android import device_blacklist from devil.android import device_errors @@ -62,6 +64,8 @@ run_tests_helper.SetLogLevel(args.verbose) constants.SetBuildType(args.build_type) + devil_chromium.Initialize(output_directory=constants.GetOutDirectory()) + apk = args.apk_path or args.apk_name if not apk.endswith('.apk'): apk += '.apk'
diff --git a/build/android/buildbot/bb_device_status_check.py b/build/android/buildbot/bb_device_status_check.py index 6dd5ca5..eb1e5d9 100755 --- a/build/android/buildbot/bb_device_status_check.py +++ b/build/android/buildbot/bb_device_status_check.py
@@ -16,6 +16,7 @@ import sys sys.path.append(os.path.abspath(os.path.join(os.path.dirname(__file__), '..'))) +import devil_chromium from devil.android import battery_utils from devil.android import device_blacklist from devil.android import device_errors @@ -310,6 +311,8 @@ run_tests_helper.SetLogLevel(args.verbose) + devil_chromium.Initialize() + blacklist = (device_blacklist.Blacklist(args.blacklist_file) if args.blacklist_file else None)
diff --git a/build/android/devil/android/battery_utils_test.py b/build/android/devil/android/battery_utils_test.py index af18e89..cf0a15fd 100755 --- a/build/android/devil/android/battery_utils_test.py +++ b/build/android/devil/android/battery_utils_test.py
@@ -10,20 +10,18 @@ # pylint: disable=protected-access,unused-argument import logging -import os import sys import unittest +from devil import devil_env from devil.android import battery_utils from devil.android import device_errors from devil.android import device_utils from devil.android import device_utils_test from devil.utils import mock_calls -from pylib import constants -sys.path.append(os.path.join( - constants.DIR_SOURCE_ROOT, 'third_party', 'pymock')) -import mock # pylint: disable=F0401 +sys.path.append(devil_env.config.LocalPath('pymock')) +import mock # pylint: disable=import-error _DUMPSYS_OUTPUT = [ '9,0,i,uid,1000,test_package1',
diff --git a/build/android/devil/android/device_utils.py b/build/android/devil/android/device_utils.py index 400c517..2c640b78 100644 --- a/build/android/devil/android/device_utils.py +++ b/build/android/devil/android/device_utils.py
@@ -22,6 +22,7 @@ import zipfile from devil import base_error +from devil import devil_env from devil.utils import cmd_helper from devil.android import apk_helper from devil.android import device_signal @@ -41,7 +42,6 @@ from devil.utils import reraiser_thread from devil.utils import timeout_retry from devil.utils import zip_utils -from pylib import constants from pylib.device.commands import install_commands _DEFAULT_TIMEOUT = 30 @@ -107,7 +107,8 @@ A list containing the configured AVDs. """ lines = cmd_helper.GetCmdOutput([ - os.path.join(constants.ANDROID_SDK_ROOT, 'tools', 'android'), + os.path.join(devil_env.config.LocalPath('android_sdk'), + 'tools', 'android'), 'list', 'avd']).splitlines() avds = [] for line in lines:
diff --git a/build/android/devil/android/device_utils_test.py b/build/android/devil/android/device_utils_test.py index 09c527ef..bed9437d 100755 --- a/build/android/devil/android/device_utils_test.py +++ b/build/android/devil/android/device_utils_test.py
@@ -11,10 +11,10 @@ # pylint: disable=unused-argument import logging -import os import sys import unittest +from devil import devil_env from devil.android import device_errors from devil.android import device_signal from devil.android import device_utils @@ -23,11 +23,9 @@ from devil.android.sdk import version_codes from devil.utils import cmd_helper from devil.utils import mock_calls -from pylib import constants -sys.path.append(os.path.join( - constants.DIR_SOURCE_ROOT, 'third_party', 'pymock')) -import mock # pylint: disable=F0401 +sys.path.append(devil_env.config.LocalPath('pymock')) +import mock # pylint: disable=import-error class _MockApkHelper(object): @@ -71,17 +69,21 @@ class DeviceUtilsGetAVDsTest(mock_calls.TestCase): def testGetAVDs(self): - with self.assertCall( - mock.call.devil.utils.cmd_helper.GetCmdOutput( - [mock.ANY, 'list', 'avd']), - 'Available Android Virtual Devices:\n' - ' Name: my_android5.0\n' - ' Path: /some/path/to/.android/avd/my_android5.0.avd\n' - ' Target: Android 5.0 (API level 21)\n' - ' Tag/ABI: default/x86\n' - ' Skin: WVGA800\n'): - self.assertEquals(['my_android5.0'], - device_utils.GetAVDs()) + mocked_attrs = { + 'android_sdk': '/my/sdk/path' + } + with mock.patch('devil.devil_env._Environment.LocalPath', + mock.Mock(side_effect=lambda a: mocked_attrs[a])): + with self.assertCall( + mock.call.devil.utils.cmd_helper.GetCmdOutput( + [mock.ANY, 'list', 'avd']), + 'Available Android Virtual Devices:\n' + ' Name: my_android5.0\n' + ' Path: /some/path/to/.android/avd/my_android5.0.avd\n' + ' Target: Android 5.0 (API level 21)\n' + ' Tag/ABI: default/x86\n' + ' Skin: WVGA800\n'): + self.assertEquals(['my_android5.0'], device_utils.GetAVDs()) class DeviceUtilsRestartServerTest(mock_calls.TestCase):
diff --git a/build/android/devil/android/fastboot_utils_test.py b/build/android/devil/android/fastboot_utils_test.py index ff2c501..67d5c64 100755 --- a/build/android/devil/android/fastboot_utils_test.py +++ b/build/android/devil/android/fastboot_utils_test.py
@@ -11,19 +11,17 @@ import io import logging -import os import sys import unittest +from devil import devil_env from devil.android import device_errors from devil.android import device_utils from devil.android import fastboot_utils from devil.android.sdk import fastboot from devil.utils import mock_calls -from pylib import constants -sys.path.append(os.path.join( - constants.DIR_SOURCE_ROOT, 'third_party', 'pymock')) +sys.path.append(devil_env.config.LocalPath('pymock')) import mock # pylint: disable=import-error _BOARD = 'board_type'
diff --git a/build/android/devil/android/logcat_monitor_test.py b/build/android/devil/android/logcat_monitor_test.py index 2b7969c4..923c671 100755 --- a/build/android/devil/android/logcat_monitor_test.py +++ b/build/android/devil/android/logcat_monitor_test.py
@@ -6,17 +6,15 @@ # pylint: disable=protected-access import itertools -import os import sys import unittest +from devil import devil_env from devil.android import logcat_monitor from devil.android.sdk import adb_wrapper -from pylib import constants -sys.path.append(os.path.join( - constants.DIR_SOURCE_ROOT, 'third_party', 'pymock')) -import mock # pylint: disable=F0401 +sys.path.append(devil_env.config.LocalPath('pymock')) +import mock # pylint: disable=import-error def _CreateTestLog(raw_logcat=None):
diff --git a/build/android/devil/android/md5sum.py b/build/android/devil/android/md5sum.py index dbd988f..bae134d 100644 --- a/build/android/devil/android/md5sum.py +++ b/build/android/devil/android/md5sum.py
@@ -6,9 +6,9 @@ import posixpath import re +from devil import devil_env from devil.android import device_errors from devil.utils import cmd_helper -from pylib import constants MD5SUM_DEVICE_LIB_PATH = '/data/local/tmp/md5sum' MD5SUM_DEVICE_BIN_PATH = MD5SUM_DEVICE_LIB_PATH + '/md5sum_bin' @@ -30,8 +30,7 @@ if isinstance(paths, basestring): paths = [paths] - md5sum_bin_host_path = os.path.join( - constants.GetOutDirectory(), 'md5sum_bin_host') + md5sum_bin_host_path = devil_env.config.FetchPath('md5sum_host') if not os.path.exists(md5sum_bin_host_path): raise IOError('File not built: %s' % md5sum_bin_host_path) out = cmd_helper.GetCmdOutput([md5sum_bin_host_path] + [p for p in paths]) @@ -58,8 +57,12 @@ # Allow generators paths = list(paths) - md5sum_dist_path = os.path.join(constants.GetOutDirectory(), 'md5sum_dist') - md5sum_dist_bin_path = os.path.join(md5sum_dist_path, 'md5sum_bin') + md5sum_dist_path = devil_env.config.FetchPath('md5sum_device', device=device) + + if os.path.isdir(md5sum_dist_path): + md5sum_dist_bin_path = os.path.join(md5sum_dist_path, 'md5sum_bin') + else: + md5sum_dist_bin_path = md5sum_dist_path if not os.path.exists(md5sum_dist_path): raise IOError('File not built: %s' % md5sum_dist_path) @@ -95,7 +98,13 @@ # actually fail. So, wipe the directory first. device.RunShellCommand(['rm', '-rf', MD5SUM_DEVICE_LIB_PATH], as_root=True, check_return=True) - device.adb.Push(md5sum_dist_path, MD5SUM_DEVICE_LIB_PATH) + if os.path.isdir(md5sum_dist_path): + device.adb.Push(md5sum_dist_path, MD5SUM_DEVICE_LIB_PATH) + else: + mkdir_cmd = 'a=%s;[[ -e $a ]] || mkdir $a' % MD5SUM_DEVICE_LIB_PATH + device.RunShellCommand(mkdir_cmd, check_return=True) + device.adb.Push(md5sum_dist_bin_path, MD5SUM_DEVICE_BIN_PATH) + out = device.RunShellCommand(md5sum_script, check_return=True) else: raise
diff --git a/build/android/devil/android/md5sum_test.py b/build/android/devil/android/md5sum_test.py index e9481b65..86023f7a 100755 --- a/build/android/devil/android/md5sum_test.py +++ b/build/android/devil/android/md5sum_test.py
@@ -7,25 +7,29 @@ import sys import unittest +from devil import devil_env from devil.android import device_errors from devil.android import md5sum -from pylib import constants -sys.path.append( - os.path.join(constants.DIR_SOURCE_ROOT, 'third_party', 'pymock')) +sys.path.append(devil_env.config.LocalPath('pymock')) import mock # pylint: disable=import-error TEST_OUT_DIR = os.path.join('test', 'out', 'directory') HOST_MD5_EXECUTABLE = os.path.join(TEST_OUT_DIR, 'md5sum_bin_host') +MD5_DIST = os.path.join(TEST_OUT_DIR, 'md5sum_dist') class Md5SumTest(unittest.TestCase): def setUp(self): + mocked_attrs = { + 'md5sum_host': HOST_MD5_EXECUTABLE, + 'md5sum_device': MD5_DIST, + } self._patchers = [ - mock.patch('pylib.constants.GetOutDirectory', - new=mock.Mock(return_value=TEST_OUT_DIR)), - mock.patch('os.path.exists', - new=mock.Mock(return_value=True)), + mock.patch('devil.devil_env._Environment.FetchPath', + mock.Mock(side_effect=lambda a, device=None: mocked_attrs[a])), + mock.patch('os.path.exists', + new=mock.Mock(return_value=True)), ] for p in self._patchers: p.start() @@ -217,7 +221,8 @@ device.RunShellCommand = mock.Mock( side_effect=(error, '', device_md5sum_output)) - with mock.patch('os.path.getsize', return_value=1337): + with mock.patch('os.path.isdir', return_value=True), ( + mock.patch('os.path.getsize', return_value=1337)): out = md5sum.CalculateDeviceMd5Sums(test_path, device) self.assertEquals(1, len(out)) self.assertTrue('/storage/emulated/legacy/test/file.dat' in out)
diff --git a/build/android/devil/android/sdk/aapt.py b/build/android/devil/android/sdk/aapt.py index 1c051e0c..7ae3a93 100644 --- a/build/android/devil/android/sdk/aapt.py +++ b/build/android/devil/android/sdk/aapt.py
@@ -4,12 +4,13 @@ """This module wraps the Android Asset Packaging Tool.""" -import os - +from devil.android.sdk import build_tools from devil.utils import cmd_helper -from pylib import constants +from devil.utils import lazy -_AAPT_PATH = os.path.join(constants.ANDROID_SDK_TOOLS, 'aapt') + +_aapt_path = lazy.WeakConstant(lambda: build_tools.GetPath('aapt')) + def _RunAaptCmd(args): """Runs an aapt command. @@ -20,13 +21,14 @@ Returns: The output of the command. """ - cmd = [_AAPT_PATH] + args + cmd = [_aapt_path.read()] + args status, output = cmd_helper.GetCmdStatusAndOutput(cmd) if status != 0: raise Exception('Failed running aapt command: "%s" with output "%s".' % (' '.join(cmd), output)) return output + def Dump(what, apk, assets=None): """Returns the output of the aapt dump command.
diff --git a/build/android/devil/android/sdk/adb_wrapper.py b/build/android/devil/android/sdk/adb_wrapper.py index 3ab7ddc..c184c77 100644 --- a/build/android/devil/android/sdk/adb_wrapper.py +++ b/build/android/devil/android/sdk/adb_wrapper.py
@@ -14,11 +14,15 @@ import os import re +from devil import devil_env from devil.android import decorators from devil.android import device_errors from devil.utils import cmd_helper +from devil.utils import lazy from devil.utils import timeout_retry -from pylib import constants + +with devil_env.SysPath(devil_env.CATAPULT_BASE_PATH): + from catapult_base import dependency_manager # pylint: disable=import-error _DEFAULT_TIMEOUT = 30 @@ -42,6 +46,21 @@ raise IOError(errno.ENOENT, os.strerror(errno.ENOENT), path) +def _FindAdb(): + try: + return devil_env.config.LocalPath('adb') + except dependency_manager.NoPathFoundError: + pass + + try: + return os.path.join(devil_env.config.LocalPath('android_sdk'), + 'platform-tools', 'adb') + except dependency_manager.NoPathFoundError: + pass + + return devil_env.config.FetchPath('adb') + + DeviceStat = collections.namedtuple('DeviceStat', ['st_mode', 'st_size', 'st_time']) @@ -49,6 +68,8 @@ class AdbWrapper(object): """A wrapper around a local Android Debug Bridge executable.""" + _adb_path = lazy.WeakConstant(_FindAdb) + def __init__(self, device_serial): """Initializes the AdbWrapper. @@ -59,19 +80,21 @@ raise ValueError('A device serial must be specified') self._device_serial = str(device_serial) - # pylint: disable=unused-argument + @classmethod + def GetAdbPath(cls): + return cls._adb_path.read() + @classmethod def _BuildAdbCmd(cls, args, device_serial, cpu_affinity=None): if cpu_affinity is not None: cmd = ['taskset', '-c', str(cpu_affinity)] else: cmd = [] - cmd.append(constants.GetAdbPath()) + cmd.append(cls.GetAdbPath()) if device_serial is not None: cmd.extend(['-s', device_serial]) cmd.extend(args) return cmd - # pylint: enable=unused-argument # pylint: disable=unused-argument @classmethod
diff --git a/build/android/devil/android/sdk/build_tools.py b/build/android/devil/android/sdk/build_tools.py new file mode 100644 index 0000000..6965dd4 --- /dev/null +++ b/build/android/devil/android/sdk/build_tools.py
@@ -0,0 +1,51 @@ +# 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. + +import os + +from devil import devil_env +from devil.utils import lazy + +with devil_env.SysPath(devil_env.CATAPULT_BASE_PATH): + from catapult_base import dependency_manager # pylint: disable=import-error + + +def GetPath(build_tool): + try: + return devil_env.config.LocalPath(build_tool) + except dependency_manager.NoPathFoundError: + pass + + try: + return _PathInLocalSdk(build_tool) + except dependency_manager.NoPathFoundError: + pass + + return devil_env.config.FetchPath(build_tool) + + +def _PathInLocalSdk(build_tool): + build_tools_path = _build_tools_path.read() + return (os.path.join(build_tools_path, build_tool) if build_tools_path + else None) + + +def _FindBuildTools(): + android_sdk_path = devil_env.config.LocalPath('android_sdk') + if not android_sdk_path: + return None + + build_tools_contents = os.listdir( + os.path.join(android_sdk_path, 'build-tools')) + + if not build_tools_contents: + return None + else: + if len(build_tools_contents) > 1: + build_tools_contents.sort() + return os.path.join(android_sdk_path, 'build-tools', + build_tools_contents[-1]) + + +_build_tools_path = lazy.WeakConstant(_FindBuildTools)
diff --git a/build/android/devil/android/sdk/dexdump.py b/build/android/devil/android/sdk/dexdump.py index 48d810f..992366e8 100644 --- a/build/android/devil/android/sdk/dexdump.py +++ b/build/android/devil/android/sdk/dexdump.py
@@ -2,12 +2,13 @@ # Use of this source code is governed by a BSD-style license that can be # found in the LICENSE file. -import os - +from devil.android.sdk import build_tools from devil.utils import cmd_helper -from pylib import constants +from devil.utils import lazy -_DEXDUMP_PATH = os.path.join(constants.ANDROID_SDK_TOOLS, 'dexdump') + +_dexdump_path = lazy.WeakConstant(lambda: build_tools.GetPath('dexdump')) + def DexDump(dexfiles, file_summary=False): """A wrapper around the Android SDK's dexdump tool. @@ -22,7 +23,7 @@ # TODO(jbudorick): Add support for more options as necessary. if isinstance(dexfiles, basestring): dexfiles = [dexfiles] - args = [_DEXDUMP_PATH] + dexfiles + args = [_dexdump_path.read()] + dexfiles if file_summary: args.append('-f')
diff --git a/build/android/devil/android/sdk/fastboot.py b/build/android/devil/android/sdk/fastboot.py index cfc566a..aebff203 100644 --- a/build/android/devil/android/sdk/fastboot.py +++ b/build/android/devil/android/sdk/fastboot.py
@@ -11,19 +11,21 @@ import os +from devil import devil_env from devil.android import decorators from devil.android import device_errors from devil.utils import cmd_helper -from pylib import constants +from devil.utils import lazy -_FASTBOOT_CMD = os.path.join( - constants.ANDROID_SDK_ROOT, 'platform-tools', 'fastboot') _DEFAULT_TIMEOUT = 30 _DEFAULT_RETRIES = 3 _FLASH_TIMEOUT = _DEFAULT_TIMEOUT * 10 class Fastboot(object): + _fastboot_path = lazy.WeakConstant(lambda: os.path.join( + devil_env.config.LocalPath('android_sdk'), 'platform-tools', 'adb')) + def __init__(self, device_serial, default_timeout=_DEFAULT_TIMEOUT, default_retries=_DEFAULT_RETRIES): """Initializes the FastbootWrapper. @@ -51,7 +53,7 @@ TypeError: If cmd is not of type list. """ if type(cmd) == list: - cmd = [_FASTBOOT_CMD, '-s', self._device_serial] + cmd + cmd = [self._fastboot_path.read(), '-s', self._device_serial] + cmd else: raise TypeError( 'Command for _RunFastbootCommand must be a list.')
diff --git a/build/android/devil/android/sdk/shared_prefs_test.py b/build/android/devil/android/sdk/shared_prefs_test.py index 63d9aec..6eba2295 100755 --- a/build/android/devil/android/sdk/shared_prefs_test.py +++ b/build/android/devil/android/sdk/shared_prefs_test.py
@@ -8,16 +8,14 @@ """ import logging -import os import sys import unittest +from devil import devil_env from devil.android import device_utils from devil.android.sdk import shared_prefs -from pylib import constants -sys.path.append(os.path.join( - constants.DIR_SOURCE_ROOT, 'third_party', 'pymock')) +sys.path.append(devil_env.config.LocalPath('pymock')) import mock # pylint: disable=import-error
diff --git a/build/android/devil/android/sdk/split_select.py b/build/android/devil/android/sdk/split_select.py index 47fcea3c..b47a21f 100644 --- a/build/android/devil/android/sdk/split_select.py +++ b/build/android/devil/android/sdk/split_select.py
@@ -4,12 +4,14 @@ """This module wraps Android's split-select tool.""" -import os - +from devil.android.sdk import build_tools from devil.utils import cmd_helper -from pylib import constants +from devil.utils import lazy -_SPLIT_SELECT_PATH = os.path.join(constants.ANDROID_SDK_TOOLS, 'split-select') + +_split_select_path = lazy.WeakConstant( + lambda: build_tools.GetPath('split-select')) + def _RunSplitSelectCmd(args): """Runs a split-select command. @@ -20,7 +22,7 @@ Returns: The output of the command. """ - cmd = [_SPLIT_SELECT_PATH] + args + cmd = [_split_select_path.read()] + args status, output = cmd_helper.GetCmdStatusAndOutput(cmd) if status != 0: raise Exception('Failed running command "%s" with output "%s".' %
diff --git a/build/android/devil/devil_dependencies.json b/build/android/devil/devil_dependencies.json new file mode 100644 index 0000000..867d8cbd --- /dev/null +++ b/build/android/devil/devil_dependencies.json
@@ -0,0 +1,116 @@ +{ + "config_type": "BaseConfig", + "dependencies": { + "aapt": { + "cloud_storage_bucket": "chromium-telemetry", + "cloud_storage_base_folder": "binary_dependencies", + "file_info": { + "android_host": { + "cloud_storage_hash": "7448de3cb5e834afdedeaad8b40ba63ac53f3dc4", + "download_path": "../bin/aapt" + } + } + }, + "adb": { + "cloud_storage_bucket": "chromium-telemetry", + "cloud_storage_base_folder": "binary_dependencies", + "file_info": { + "android_host": { + "cloud_storage_hash": "0c2043552619c8ec8bb5d986ba75703a598611fc", + "download_path": "../bin/adb" + } + } + }, + "android_build_tools_libc++": { + "cloud_storage_bucket": "chromium-telemetry", + "cloud_storage_base_folder": "binary_dependencies", + "file_info": { + "android_host": { + "cloud_storage_hash": "52d150a7ccde835f38b4337392152f3013d5f303", + "download_path": "../bin/lib/libc++.so" + } + } + }, + "dexdump": { + "cloud_storage_bucket": "chromium-telemetry", + "cloud_storage_base_folder": "binary_dependencies", + "file_info": { + "android_host": { + "cloud_storage_hash": "38765b5b358c29003e56b1d214606ea13467b6fe", + "download_path": "../bin/dexdump" + } + } + }, + "forwarder_device": { + "cloud_storage_bucket": "chromium-telemetry", + "cloud_storage_base_folder": "binary_dependencies", + "file_info": { + "android_armeabi-v7a": { + "cloud_storage_hash": "4858c9e41da72ad8ff24414731feae2137229361", + "download_path": "../bin/armeabi-v7a/forwarder_device" + }, + "android_arm64-v8a": { + "cloud_storage_hash": "8cbd1ac2079ee82ce5f1cf4d3e85fc1e53a8f018", + "download_path": "../bin/arm64-v8a/forwarder_device" + } + } + }, + "forwarder_host": { + "cloud_storage_bucket": "chromium-telemetry", + "cloud_storage_base_folder": "binary_dependencies", + "file_info": { + "android_host": { + "cloud_storage_hash": "b3dda9fbdd4a3fb933b64111c11070aa809c7ed4", + "download_path": "../bin/forwarder_host" + } + } + }, + "md5sum_device": { + "cloud_storage_bucket": "chromium-telemetry", + "cloud_storage_base_folder": "binary_dependencies", + "file_info": { + "android_armeabi-v7a": { + "cloud_storage_hash": "c8894480be71d5e49118483d83ba7a6e0097cba6", + "download_path": "../bin/armeabi-v7a/md5sum_device" + }, + "android_arm64-v8a": { + "cloud_storage_hash": "bbe410e2ffb48367ac4ca0874598d4f85fd16d9d", + "download_path": "../bin/arm64-v8a/md5sum_device" + }, + "android_x86": { + "cloud_storage_hash": "b578a5c2c400ce39761e2558cdf2237567a57257", + "download_path": "../bin/x86/md5sum_device" + } + } + }, + "md5sum_host": { + "cloud_storage_bucket": "chromium-telemetry", + "cloud_storage_base_folder": "binary_dependencies", + "file_info": { + "android_host": { + "cloud_storage_hash": "49e36c9c4246cfebef26cbd07436c1a8343254aa", + "download_path": "../bin/md5sum_host" + } + } + }, + "pymock": { + "file_info": { + "android_host": { + "local_paths": [ + "../../../tools/telemetry/third_party/mock" + ] + } + } + }, + "split-select": { + "cloud_storage_bucket": "chromium-telemetry", + "cloud_storage_base_folder": "binary_dependencies", + "file_info": { + "android_host": { + "cloud_storage_hash": "3327881fa3951a503b9467425ea8e781cdffeb9f", + "download_path": "../bin/split-select" + } + } + } + } +}
diff --git a/build/android/devil/devil_env.py b/build/android/devil/devil_env.py new file mode 100644 index 0000000..fa7392f4 --- /dev/null +++ b/build/android/devil/devil_env.py
@@ -0,0 +1,138 @@ +# 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. + +import contextlib +import json +import logging +import os +import sys +import tempfile +import threading + +# TODO(jbudorick): Update this once dependency_manager moves to catapult. +CATAPULT_BASE_PATH = os.path.abspath(os.path.join( + os.path.dirname(__file__), os.pardir, os.pardir, os.pardir, + 'tools', 'telemetry')) + +@contextlib.contextmanager +def SysPath(path): + sys.path.append(path) + yield + if sys.path[-1] != path: + logging.debug('Expected %s at the end of sys.path. Full sys.path: %s', + path, str(sys.path)) + sys.path.remove(path) + else: + sys.path.pop() + +with SysPath(CATAPULT_BASE_PATH): + from catapult_base import dependency_manager # pylint: disable=import-error + +_ANDROID_BUILD_TOOLS = {'aapt', 'dexdump', 'split-select'} + +_DEVIL_DEFAULT_CONFIG = os.path.abspath(os.path.join( + os.path.dirname(__file__), 'devil_dependencies.json')) + +_LEGACY_ENVIRONMENT_VARIABLES = { + 'ADB_PATH': { + 'dependency_name': 'adb', + 'platform': 'android_host', + }, + 'ANDROID_SDK_ROOT': { + 'dependency_name': 'android_sdk', + 'platform': 'android_host', + }, +} + + +def _GetEnvironmentVariableConfig(): + env_var_config = {} + for k, v in _LEGACY_ENVIRONMENT_VARIABLES.iteritems(): + path = os.environ.get(k) + if path: + env_var_config[v['dependency_name']] = { + 'file_info': { + v['platform']: { + 'local_paths': [path] + } + } + } + return env_var_config + + +class _Environment(object): + + def __init__(self): + self._dm_init_lock = threading.Lock() + self._dm = None + + def Initialize(self, configs=None, config_files=None): + """Initialize devil's environment from configuration files. + + This uses all configurations provided via |configs| and |config_files| + to determine the locations of devil's dependencies. Configurations should + all take the form described by catapult_base.dependency_manager.BaseConfig. + If no configurations are provided, a default one will be used if available. + + Args: + configs: An optional list of dict configurations. + config_files: An optional list of files to load + """ + + # Make sure we only initialize self._dm once. + with self._dm_init_lock: + if self._dm is None: + if configs is None: + configs = [] + + env_config = _GetEnvironmentVariableConfig() + if env_config: + configs.insert(0, env_config) + self._InitializeRecursive( + configs=configs, + config_files=config_files) + assert self._dm is not None, 'Failed to create dependency manager.' + + def _InitializeRecursive(self, configs=None, config_files=None): + # This recurses through configs to create temporary files for each and + # take advantage of context managers to appropriately close those files. + # TODO(jbudorick): Remove this recursion if/when dependency_manager + # supports loading configurations directly from a dict. + if configs: + with tempfile.NamedTemporaryFile() as next_config_file: + next_config_file.write(json.dumps(configs[0])) + next_config_file.flush() + self._InitializeRecursive( + configs=configs[1:], + config_files=[next_config_file.name] + (config_files or [])) + else: + config_files = config_files or [] + if 'DEVIL_ENV_CONFIG' in os.environ: + config_files.append(os.environ.get('DEVIL_ENV_CONFIG')) + config_files.append(_DEVIL_DEFAULT_CONFIG) + + self._dm = dependency_manager.DependencyManager( + [dependency_manager.BaseConfig(c) for c in config_files]) + + def FetchPath(self, dependency, arch=None, device=None): + if self._dm is None: + self.Initialize() + if dependency in _ANDROID_BUILD_TOOLS: + self.FetchPath('android_build_tools_libc++', arch=arch, device=device) + return self._dm.FetchPath(dependency, _GetPlatform(arch, device)) + + def LocalPath(self, dependency, arch=None, device=None): + if self._dm is None: + self.Initialize() + return self._dm.LocalPath(dependency, _GetPlatform(arch, device)) + + +def _GetPlatform(arch, device): + if not arch: + arch = device.product_cpu_abi if device else 'host' + return 'android_%s' % arch + + +config = _Environment() +
diff --git a/build/android/devil/utils/lazy/__init__.py b/build/android/devil/utils/lazy/__init__.py new file mode 100644 index 0000000..3cc56c0a --- /dev/null +++ b/build/android/devil/utils/lazy/__init__.py
@@ -0,0 +1,5 @@ +# 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. + +from devil.utils.lazy.weak_constant import WeakConstant
diff --git a/build/android/devil/utils/lazy/weak_constant.py b/build/android/devil/utils/lazy/weak_constant.py new file mode 100644 index 0000000..3558f29 --- /dev/null +++ b/build/android/devil/utils/lazy/weak_constant.py
@@ -0,0 +1,29 @@ +# 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. + +import threading + + +class WeakConstant(object): + """A thread-safe, lazily initialized object. + + This does not support modification after initialization. The intended + constant nature of the object is not enforced, though, hence the "weak". + """ + + def __init__(self, initializer): + self._initialized = False + self._initializer = initializer + self._lock = threading.Lock() + self._val = None + + def read(self): + """Get the object, creating it if necessary.""" + if self._initialized: + return self._val + with self._lock: + if not self._initialized: + self._val = self._initializer() + self._initialized = True + return self._val
diff --git a/build/android/devil/utils/lsusb.py b/build/android/devil/utils/lsusb.py index 9c98fa6..d322e5c 100644 --- a/build/android/devil/utils/lsusb.py +++ b/build/android/devil/utils/lsusb.py
@@ -5,7 +5,7 @@ import logging import re -from pylib import cmd_helper +from devil.utils import cmd_helper _INDENTATION_RE = re.compile(r'^( *)') _LSUSB_BUS_DEVICE_RE = re.compile(r'^Bus (\d{3}) Device (\d{3}):')
diff --git a/build/android/devil/utils/mock_calls.py b/build/android/devil/utils/mock_calls.py index 59167bac..bc3b54a0 100644 --- a/build/android/devil/utils/mock_calls.py +++ b/build/android/devil/utils/mock_calls.py
@@ -6,14 +6,12 @@ A test facility to assert call sequences while mocking their behavior. """ -import os import sys import unittest -from pylib import constants +from devil import devil_env -sys.path.append(os.path.join( - constants.DIR_SOURCE_ROOT, 'third_party', 'pymock')) +sys.path.append(devil_env.config.LocalPath('pymock')) import mock # pylint: disable=F0401
diff --git a/build/android/devil/utils/mock_calls_test.py b/build/android/devil/utils/mock_calls_test.py index ae2acbb8..290c184b 100755 --- a/build/android/devil/utils/mock_calls_test.py +++ b/build/android/devil/utils/mock_calls_test.py
@@ -12,12 +12,11 @@ import sys import unittest +from devil import devil_env from devil.android.sdk import version_codes from devil.utils import mock_calls -from pylib import constants -sys.path.append(os.path.join( - constants.DIR_SOURCE_ROOT, 'third_party', 'pymock')) +sys.path.append(devil_env.config.LocalPath('pymock')) import mock # pylint: disable=F0401
diff --git a/build/android/devil_chromium.json b/build/android/devil_chromium.json new file mode 100644 index 0000000..99aabad --- /dev/null +++ b/build/android/devil_chromium.json
@@ -0,0 +1,59 @@ +{ + "config_type": "BaseConfig", + "dependencies": { + "aapt": { + "file_info": { + "android_host": { + "local_paths": [ + "../../third_party/android_tools/sdk/build-tools/23.0.0/aapt" + ] + } + } + }, + "adb": { + "file_info": { + "android_host": { + "local_paths": [ + "../../third_party/android_tools/sdk/platform-tools/adb" + ] + } + } + }, + "android_sdk": { + "file_info": { + "android_host": { + "local_paths": [ + "../../third_party/android_tools/sdk" + ] + } + } + }, + "dexdump": { + "file_info": { + "android_host": { + "local_paths": [ + "../../third_party/android_tools/sdk/build-tools/23.0.0/dexdump" + ] + } + } + }, + "split-select": { + "file_info": { + "android_host": { + "local_paths": [ + "../../third_party/android_tools/sdk/build-tools/23.0.0/split-select" + ] + } + } + }, + "pymock": { + "file_info": { + "android_host": { + "local_paths": [ + "../../third_party/pymock" + ] + } + } + } + } +}
diff --git a/build/android/devil_chromium.py b/build/android/devil_chromium.py new file mode 100644 index 0000000..d626af6 --- /dev/null +++ b/build/android/devil_chromium.py
@@ -0,0 +1,90 @@ +# 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. + +"""Configures devil for use in chromium.""" + +import os + +from devil import devil_env + + +_DEVIL_CONFIG = os.path.abspath( + os.path.join(os.path.dirname(__file__), 'devil_chromium.json')) + +_DEVIL_BUILD_PRODUCT_DEPS = { + 'forwarder_device': { + 'armeabi-v7a': 'forwarder_dist', + 'arm64-v8a': 'forwarder_dist', + 'x86': 'forwarder_dist', + }, + 'forwarder_host': { + 'any': 'host_forwarder', + }, + 'md5sum_device': { + 'armeabi-v7a': 'md5sum_dist', + 'arm64-v8a': 'md5sum_dist', + 'x86': 'md5sum_dist', + }, + 'md5sum_host': { + 'any': 'md5sum_bin_host', + }, +} + + +def Initialize(output_directory=None, custom_deps=None): + """Initializes devil with chromium's binaries and third-party libraries. + + This includes: + - Libraries: + - the android SDK ("android_sdk") + - pymock ("pymock") + - Build products: + - host & device forwarder binaries + ("forwarder_device" and "forwarder_host") + - host & device md5sum binaries ("md5sum_device" and "md5sum_host") + + Args: + output_directory: An optional path to the output directory. If not set, + no built dependencies are configured. + custom_deps: An optional dictionary specifying custom dependencies. + This should be of the form: + + { + 'dependency_name': { + 'platform': 'path', + ... + }, + ... + } + """ + + devil_dynamic_deps = {} + + if output_directory: + for dep_name, arch_dict in _DEVIL_BUILD_PRODUCT_DEPS.iteritems(): + devil_dynamic_deps[dep_name] = {} + for arch, name in arch_dict.iteritems(): + devil_dynamic_deps[dep_name][arch] = os.path.join( + output_directory, name) + + devil_dynamic_config = { + 'config_type': 'BaseConfig', + 'dependencies': { + dep_name: { + 'file_info': { + 'android_%s' % arch: { + 'local_paths': [path] + } + for arch, path in arch_dict.iteritems() + } + } + for dep_name, arch_dict in devil_dynamic_deps.iteritems() + } + } + if custom_deps: + devil_dynamic_config['dependencies'].update(custom_deps) + + devil_env.config.Initialize( + configs=[devil_dynamic_config], config_files=[_DEVIL_CONFIG]) +
diff --git a/build/android/gyp/apk_install.py b/build/android/gyp/apk_install.py index 33697ca..9c907638 100755 --- a/build/android/gyp/apk_install.py +++ b/build/android/gyp/apk_install.py
@@ -17,9 +17,11 @@ from util import build_utils from util import md5_check -BUILD_ANDROID_DIR = os.path.join(os.path.dirname(__file__), '..') +BUILD_ANDROID_DIR = os.path.abspath( + os.path.join(os.path.dirname(__file__), '..')) sys.path.append(BUILD_ANDROID_DIR) +import devil_chromium from devil.android import apk_helper from pylib import constants @@ -74,15 +76,20 @@ help='Path to touch on success.') parser.add_option('--configuration-name', help='The build CONFIGURATION_NAME') + parser.add_option('--output-directory', + help='The output directory.') options, _ = parser.parse_args() + constants.SetBuildType(options.configuration_name) + + devil_chromium.Initialize( + output_directory=os.path.abspath(options.output_directory)) + device = build_device.GetBuildDeviceFromPath( options.build_device_configuration) if not device: return - constants.SetBuildType(options.configuration_name) - serial_number = device.GetSerialNumber() apk_package = apk_helper.GetPackageName(options.apk_path)
diff --git a/build/android/gyp/create_device_library_links.py b/build/android/gyp/create_device_library_links.py index 8c155a0..6b0b24d7 100755 --- a/build/android/gyp/create_device_library_links.py +++ b/build/android/gyp/create_device_library_links.py
@@ -18,9 +18,11 @@ from util import build_device from util import build_utils -BUILD_ANDROID_DIR = os.path.join(os.path.dirname(__file__), '..') +BUILD_ANDROID_DIR = os.path.abspath( + os.path.join(os.path.dirname(__file__), '..')) sys.path.append(BUILD_ANDROID_DIR) +import devil_chromium from devil.android import apk_helper from pylib import constants @@ -96,6 +98,8 @@ help='Path to build device configuration.') parser.add_option('--configuration-name', help='The build CONFIGURATION_NAME') + parser.add_option('--output-directory', + help='The output directory') options, _ = parser.parse_args(args) required_options = ['apk', 'libraries', 'script_host_path', @@ -103,6 +107,9 @@ build_utils.CheckOptions(options, parser, required=required_options) constants.SetBuildType(options.configuration_name) + devil_chromium.Initialize( + output_directory=os.path.abspath(options.output_directory)) + CreateSymlinkScript(options) TriggerSymlinkScript(options)
diff --git a/build/android/gyp/get_device_configuration.py b/build/android/gyp/get_device_configuration.py index 390eb2f..0ec08ef9 100755 --- a/build/android/gyp/get_device_configuration.py +++ b/build/android/gyp/get_device_configuration.py
@@ -11,18 +11,29 @@ """ import optparse +import os import sys -from util import build_utils from util import build_device +from util import build_utils + +BUILD_ANDROID_DIR = os.path.abspath( + os.path.join(os.path.dirname(__file__), '..')) +sys.path.append(BUILD_ANDROID_DIR) + +import devil_chromium def main(argv): parser = optparse.OptionParser() parser.add_option('--stamp', action='store') parser.add_option('--output', action='store') + parser.add_option('--output-directory', action='store') options, _ = parser.parse_args(argv) + devil_chromium.Initialize( + output_directory=os.path.abspath(options.output_directory)) + devices = build_device.GetAttachedDevices() device_configurations = []
diff --git a/build/android/gyp/push_libraries.py b/build/android/gyp/push_libraries.py index 6b31a2e..452b873b 100755 --- a/build/android/gyp/push_libraries.py +++ b/build/android/gyp/push_libraries.py
@@ -12,7 +12,8 @@ import os import sys -BUILD_ANDROID_DIR = os.path.join(os.path.dirname(__file__), os.pardir) +BUILD_ANDROID_DIR = os.path.abspath( + os.path.join(os.path.dirname(__file__), os.pardir)) sys.path.append(BUILD_ANDROID_DIR) from pylib import constants
diff --git a/build/android/gyp/util/build_device.py b/build/android/gyp/util/build_device.py index a19045be..34484ac 100644 --- a/build/android/gyp/util/build_device.py +++ b/build/android/gyp/util/build_device.py
@@ -13,7 +13,8 @@ from util import build_utils -BUILD_ANDROID_DIR = os.path.join(os.path.dirname(__file__), '..', '..') +BUILD_ANDROID_DIR = os.path.abspath( + os.path.join(os.path.dirname(__file__), '..', '..')) sys.path.append(BUILD_ANDROID_DIR) from devil.android import device_errors
diff --git a/build/android/gyp/write_build_config.py b/build/android/gyp/write_build_config.py index b8b8ec8..629ce73 100755 --- a/build/android/gyp/write_build_config.py +++ b/build/android/gyp/write_build_config.py
@@ -37,6 +37,13 @@ import write_ordered_libraries + +# Types that should never be used as a dependency of another build config. +_ROOT_TYPES = ('android_apk', 'deps_dex', 'java_binary', 'resource_rewriter') +# Types that should not allow code deps to pass through. +_RESOURCE_TYPES = ('android_assets', 'android_resources') + + class AndroidManifest(object): def __init__(self, path): self.path = path @@ -143,6 +150,16 @@ return create_list(compressed), create_list(uncompressed) +def _FilterUnwantedDepsPaths(dep_paths, target_type): + # Don't allow root targets to be considered as a dep. + ret = [p for p in dep_paths if GetDepConfig(p)['type'] not in _ROOT_TYPES] + + # Don't allow java libraries to cross through assets/resources. + if target_type in _RESOURCE_TYPES: + ret = [p for p in ret if GetDepConfig(p)['type'] in _RESOURCE_TYPES] + return ret + + def main(argv): parser = optparse.OptionParser() build_utils.AddDepfileOption(parser) @@ -206,6 +223,7 @@ parser.error('No positional arguments should be given.') required_options_map = { + 'java_binary': ['build_config', 'jar_path'], 'java_library': ['build_config', 'jar_path'], 'android_assets': ['build_config'], 'android_resources': ['build_config', 'resources_zip'], @@ -242,8 +260,11 @@ direct_deps_config_paths = [ c for c in possible_deps_config_paths if not c in unknown_deps] + direct_deps_config_paths = _FilterUnwantedDepsPaths(direct_deps_config_paths, + options.type) deps = Deps(direct_deps_config_paths) + direct_library_deps = deps.Direct('java_library') all_library_deps = deps.All('java_library') @@ -265,12 +286,13 @@ 'name': os.path.basename(options.build_config), 'path': options.build_config, 'type': options.type, - 'deps_configs': direct_deps_config_paths, + 'deps_configs': direct_deps_config_paths } } deps_info = config['deps_info'] - if options.type == 'java_library' and not options.bypass_platform_checks: + if (options.type in ('java_binary', 'java_library') and + not options.bypass_platform_checks): deps_info['requires_android'] = options.requires_android deps_info['supports_android'] = options.supports_android @@ -287,7 +309,7 @@ raise Exception('Not all deps support the Android platform: ' + str(deps_not_support_android)) - if options.type in ['java_library', 'android_apk']: + if options.type in ('java_binary', 'java_library', 'android_apk'): javac_classpath = [c['jar_path'] for c in direct_library_deps] java_full_classpath = [c['jar_path'] for c in all_library_deps] deps_info['resources_deps'] = [c['path'] for c in all_resources_deps] @@ -303,7 +325,7 @@ 'full_classpath': java_full_classpath } - if options.type == 'java_library': + if options.type in ('java_binary', 'java_library'): # Only resources might have srcjars (normal srcjar targets are listed in # srcjar_deps). A resource's srcjar contains the R.java file for those # resources, and (like Android's default build system) we allow a library to
diff --git a/build/android/incremental_install/installer.py b/build/android/incremental_install/installer.py index 373889df..15bdbeeb 100755 --- a/build/android/incremental_install/installer.py +++ b/build/android/incremental_install/installer.py
@@ -14,7 +14,9 @@ import shutil import sys -sys.path.append(os.path.join(os.path.dirname(__file__), os.pardir)) +sys.path.append( + os.path.abspath(os.path.join(os.path.dirname(__file__), os.pardir))) +import devil_chromium from devil.android import apk_helper from devil.android import device_utils from devil.android import device_errors @@ -253,6 +255,8 @@ if args.output_directory: constants.SetOutputDirectory(args.output_directory) + devil_chromium.Initialize(output_directory=constants.GetOutDirectory()) + if args.device: # Retries are annoying when commands fail for legitimate reasons. Might want # to enable them if this is ever used on bots though.
diff --git a/build/android/provision_devices.py b/build/android/provision_devices.py index 3a2e100..caa9e23f6 100755 --- a/build/android/provision_devices.py +++ b/build/android/provision_devices.py
@@ -21,6 +21,7 @@ import sys import time +import devil_chromium from devil.android import battery_utils from devil.android import device_blacklist from devil.android import device_errors @@ -103,7 +104,8 @@ try: if should_run_phase(_PHASES.WIPE): - if options.chrome_specific_wipe: + if (options.chrome_specific_wipe or device.build_version_sdk >= + version_codes.MARSHMALLOW): run_phase(WipeChromeData) else: run_phase(WipeDevice) @@ -490,6 +492,8 @@ run_tests_helper.SetLogLevel(args.verbose) + devil_chromium.Initialize() + return ProvisionDevices(args)
diff --git a/build/android/pylib/constants/__init__.py b/build/android/pylib/constants/__init__.py index 772af93..1a48723d 100644 --- a/build/android/pylib/constants/__init__.py +++ b/build/android/pylib/constants/__init__.py
@@ -17,6 +17,7 @@ from devil.android.sdk import version_codes from devil.constants import exit_codes + keyevent = devil.android.sdk.keyevent @@ -243,43 +244,13 @@ GetBuildType() if build_type is None else build_type)) -def _Memoize(func): - def Wrapper(): - try: - return func._result - except AttributeError: - func._result = func() - return func._result - return Wrapper - - -def SetAdbPath(adb_path): - os.environ['ADB_PATH'] = adb_path - - +# TODO(jbudorick): Convert existing callers to AdbWrapper.GetAdbPath() and +# remove this. def GetAdbPath(): - # Check if a custom adb path as been set. If not, try to find adb - # on the system. - if os.environ.get('ADB_PATH'): - return os.environ.get('ADB_PATH') - else: - return _FindAdbPath() + from devil.android.sdk import adb_wrapper + return adb_wrapper.AdbWrapper.GetAdbPath() -@_Memoize -def _FindAdbPath(): - if os.environ.get('ANDROID_SDK_ROOT'): - return 'adb' - # If envsetup.sh hasn't been sourced and there's no adb in the path, - # set it here. - try: - with file(os.devnull, 'w') as devnull: - subprocess.call(['adb', 'version'], stdout=devnull, stderr=devnull) - return 'adb' - except OSError: - logging.debug('No adb found in $PATH, fallback to checked in binary.') - return os.path.join(ANDROID_SDK_ROOT, 'platform-tools', 'adb') - # Exit codes ERROR_EXIT_CODE = exit_codes.ERROR INFRA_EXIT_CODE = exit_codes.INFRA
diff --git a/build/android/pylib/forwarder.py b/build/android/pylib/forwarder.py index 36226d1..b8952cc 100644 --- a/build/android/pylib/forwarder.py +++ b/build/android/pylib/forwarder.py
@@ -9,6 +9,7 @@ import os import psutil +from devil import devil_env from devil.android.valgrind_tools import base_tool from devil.utils import cmd_helper from pylib import constants @@ -77,7 +78,7 @@ device_serial = str(device) redirection_commands = [ - ['--adb=' + constants.GetAdbPath(), + ['--adb=' + devil_env.config.FetchPath('adb'), '--serial-id=' + device_serial, '--map', str(device_port), str(host_port)] for device_port, host_port in port_pairs] @@ -197,11 +198,8 @@ self._initialized_devices = set() self._device_to_host_port_map = dict() self._host_to_device_port_map = dict() - self._host_forwarder_path = os.path.join( - constants.GetOutDirectory(), 'host_forwarder') + self._host_forwarder_path = devil_env.config.FetchPath('forwarder_host') assert os.path.exists(self._host_forwarder_path), 'Please build forwarder2' - self._device_forwarder_path_on_host = os.path.join( - constants.GetOutDirectory(), 'forwarder_dist') self._InitHostLocked() @staticmethod @@ -216,7 +214,7 @@ if not serial_with_port in instance._device_to_host_port_map: logging.error('Trying to unmap non-forwarded port %d', device_port) return - redirection_command = ['--adb=' + constants.GetAdbPath(), + redirection_command = ['--adb=' + devil_env.config.FetchPath('adb'), '--serial-id=' + serial, '--unmap', str(device_port)] logging.info('Undo forwarding using command: %s', redirection_command) @@ -279,9 +277,16 @@ if device_serial in self._initialized_devices: return Forwarder._KillDeviceLocked(device, tool) + forwarder_device_path_on_host = devil_env.config.FetchPath( + 'forwarder_device', device=device) + forwarder_device_path_on_device = ( + Forwarder._DEVICE_FORWARDER_FOLDER + if os.path.isdir(forwarder_device_path_on_host) + else Forwarder._DEVICE_FORWARDER_PATH) device.PushChangedFiles([( - self._device_forwarder_path_on_host, - Forwarder._DEVICE_FORWARDER_FOLDER)]) + forwarder_device_path_on_host, + forwarder_device_path_on_device)]) + cmd = '%s %s' % (tool.GetUtilWrapper(), Forwarder._DEVICE_FORWARDER_PATH) device.RunShellCommand( cmd, env={'LD_LIBRARY_PATH': Forwarder._DEVICE_FORWARDER_FOLDER},
diff --git a/build/android/pylib/gtest/filter/content_browsertests_disabled b/build/android/pylib/gtest/filter/content_browsertests_disabled index b9dd105b..abe4066 100644 --- a/build/android/pylib/gtest/filter/content_browsertests_disabled +++ b/build/android/pylib/gtest/filter/content_browsertests_disabled
@@ -36,17 +36,6 @@ RendererAccessibilityTest.ShowAccessibilityObject RendererAccessibilityTest.TextSelectionShouldSendRoot -# http://crbug.com/215894 -DownloadContentTest.CancelInterruptedDownload -DownloadContentTest.CancelResumingDownload -DownloadContentTest.RemoveDownload -DownloadContentTest.RemoveResumingDownload -DownloadContentTest.ResumeInterruptedDownload -DownloadContentTest.ResumeInterruptedDownloadNoRange -DownloadContentTest.ResumeInterruptedDownloadNoVerifiers -DownloadContentTest.ResumeInterruptedDownloadBadPrecondition -DownloadContentTest.ResumeWithDeletedFile - # http://crbug.com/386227 IndexedDBBrowserTest.VersionChangeCrashResilience
diff --git a/build/android/pylib/perf/test_runner.py b/build/android/pylib/perf/test_runner.py index a580fd4..161c511 100644 --- a/build/android/pylib/perf/test_runner.py +++ b/build/android/pylib/perf/test_runner.py
@@ -74,6 +74,7 @@ def _GetChromiumRevision(): + # pylint: disable=line-too-long """Get the git hash and commit position of the chromium master branch. See: https://chromium.googlesource.com/chromium/tools/build/+/master/scripts/slave/runtest.py#212 @@ -81,6 +82,7 @@ Returns: A dictionary with 'revision' and 'commit_pos' keys. """ + # pylint: enable=line-too-long status, output = cmd_helper.GetCmdStatusAndOutput( ['git', 'log', '-n', '1', '--pretty=format:%H%n%B', 'HEAD'], constants.DIR_SOURCE_ROOT)
diff --git a/build/android/pylintrc b/build/android/pylintrc index 9c2ab5a..8005a5d 100644 --- a/build/android/pylintrc +++ b/build/android/pylintrc
@@ -1,3 +1,7 @@ +[FORMAT] + +max-line-length=80 + [MESSAGES CONTROL] disable=abstract-class-not-used,bad-continuation,bad-indentation,duplicate-code,fixme,invalid-name,locally-disabled,locally-enabled,missing-docstring,star-args,too-few-public-methods,too-many-arguments,too-many-branches,too-many-instance-attributes,too-many-lines,too-many-locals,too-many-public-methods,too-many-statements,
diff --git a/build/android/setup.gyp b/build/android/setup.gyp index 419ed985..0ef0531 100644 --- a/build/android/setup.gyp +++ b/build/android/setup.gyp
@@ -42,6 +42,7 @@ 'action': [ 'python', 'gyp/get_device_configuration.py', '--output=<(build_device_config_path)', + '--output-directory=<(PRODUCT_DIR)', ], } ],
diff --git a/build/android/test_runner.py b/build/android/test_runner.py index 90210b6..9f1b22e 100755 --- a/build/android/test_runner.py +++ b/build/android/test_runner.py
@@ -16,6 +16,8 @@ import threading import unittest +import devil_chromium + from devil import base_error from devil.android import apk_helper from devil.android import device_blacklist @@ -47,6 +49,10 @@ from pylib.results import report_results +_DEVIL_STATIC_CONFIG_FILE = os.path.abspath(os.path.join( + constants.DIR_SOURCE_ROOT, 'build', 'android', 'devil_config.json')) + + def AddCommonOptions(parser): """Adds all common options to |parser|.""" @@ -111,8 +117,19 @@ constants.SetBuildDirectory(args.build_directory) if args.output_directory: constants.SetOutputDirectory(args.output_directory) + + devil_custom_deps = None if args.adb_path: - constants.SetAdbPath(args.adb_path) + devil_custom_deps = { + 'adb': { + 'android_host': [args.adb_path] + } + } + + devil_chromium.Initialize( + output_directory=constants.GetOutDirectory(), + custom_deps=devil_custom_deps) + # Some things such as Forwarder require ADB to be in the environment path. adb_dir = os.path.dirname(constants.GetAdbPath()) if adb_dir and adb_dir not in os.environ['PATH'].split(os.pathsep):
diff --git a/build/android/tombstones.py b/build/android/tombstones.py index f1108dd36..ccb86a4 100755 --- a/build/android/tombstones.py +++ b/build/android/tombstones.py
@@ -18,6 +18,8 @@ import sys import optparse +import devil_chromium + from devil.android import device_blacklist from devil.android import device_errors from devil.android import device_utils @@ -241,6 +243,8 @@ if options.blacklist_file else None) + devil_chromium.Initialize() + if options.device: devices = [device_utils.DeviceUtils(options.device)] else:
diff --git a/build/args/aura_android.gni b/build/args/aura_android.gni index 725c41b..fc67e649 100644 --- a/build/args/aura_android.gni +++ b/build/args/aura_android.gni
@@ -15,4 +15,5 @@ # ui.gni overrides use_aura = true +android_java_ui = false toolkit_views = true
diff --git a/build/buildflag_header.gypi b/build/buildflag_header.gypi index af86677..83b505a 100644 --- a/build/buildflag_header.gypi +++ b/build/buildflag_header.gypi
@@ -115,4 +115,9 @@ ], } ], + + # Allow the file to be included based on the given buildflag_header_path. + 'direct_dependent_settings': { + 'include_dirs': [ '<(SHARED_INTERMEDIATE_DIR)' ], + }, }
diff --git a/build/common.gypi b/build/common.gypi index 0974b49..fe6722e 100644 --- a/build/common.gypi +++ b/build/common.gypi
@@ -756,7 +756,7 @@ }], # Flags to use Wayland server support. - ['chromeos==1', { + ['chromeos==1 and use_ozone==1', { 'enable_wayland_server%': 1, }, { 'enable_wayland_server%': 0, @@ -1492,7 +1492,7 @@ 'sas_dll_exists': '<!pymod_do_main(dir_exists "<(sas_dll_path)")', 'wix_exists': '<!pymod_do_main(dir_exists "<(wix_path)")', - 'windows_sdk_path%': 'C:/Program Files (x86)/Windows Kits/8.1', + 'windows_sdk_path%': 'C:/Program Files (x86)/Windows Kits/10', 'directx_sdk_default_path': '<(DEPTH)/third_party/directxsdk/files', # Whether we are using the rlz library or not. Platforms like Android send @@ -1896,6 +1896,9 @@ ['OS=="mac" or OS=="ios"', { 'clang%': 1, + # On Mac and iOS we just use the default system allocator. + 'use_allocator%': 'none', + 'variables': { # Mac OS X SDK and deployment target support. The SDK identifies # the version of the system headers that will be used, and @@ -2886,9 +2889,9 @@ '__STD_C', '_CRT_SECURE_NO_DEPRECATE', '_SCL_SECURE_NO_DEPRECATE', - # This define is required to pull in the new Win8 interfaces from + # This define is required to pull in the new Win 10 interfaces from # system headers like ShObjIdl.h. - 'NTDDI_VERSION=0x06030000', + 'NTDDI_VERSION=0x0A000000', # This is required for ATL to use XP-safe versions of its functions. '_USING_V110_SDK71_', ], @@ -3337,17 +3340,17 @@ 'MinimumRequiredVersion': '5.02', # Server 2003. 'TargetMachine': '17', # x86 - 64 'AdditionalLibraryDirectories!': - ['<(windows_sdk_path)/Lib/win8/um/x86'], + ['<(windows_sdk_path)/Lib/10.0.10240.0/um/x86'], 'AdditionalLibraryDirectories': - ['<(windows_sdk_path)/Lib/win8/um/x64'], + ['<(windows_sdk_path)/Lib/10.0.10240.0/um/x64'], # Doesn't exist x64 SDK. Should use oleaut32 in any case. 'IgnoreDefaultLibraryNames': [ 'olepro32.lib' ], }, 'VCLibrarianTool': { 'AdditionalLibraryDirectories!': - ['<(windows_sdk_path)/Lib/win8/um/x86'], + ['<(windows_sdk_path)/Lib/10.0.10240.0/um/x86'], 'AdditionalLibraryDirectories': - ['<(windows_sdk_path)/Lib/win8/um/x64'], + ['<(windows_sdk_path)/Lib/10.0.10240.0/um/x64'], 'TargetMachine': '17', # x64 }, }, @@ -4955,20 +4958,14 @@ ], 'target_conditions': [ ['_type=="executable"', { - # Force android tools to export the "main" symbol so they can be - # loaded on ICS using the run_pie wrapper. See crbug.com/373219. - # TODO(primiano): remove -fvisibility and -rdynamic flags below - # when ICS support will be dropped. 'cflags': [ '-fPIE', - '-fvisibility=default', ], 'ldflags': [ '-Bdynamic', '-Wl,--gc-sections', '-Wl,-z,nocopyreloc', '-pie', - '-rdynamic', # crtbegin_dynamic.o should be the last item in ldflags. '<(android_ndk_lib)/crtbegin_dynamic.o', ], @@ -5529,8 +5526,8 @@ ['OS=="win"', { 'target_defaults': { 'defines': [ - '_WIN32_WINNT=0x0603', - 'WINVER=0x0603', + '_WIN32_WINNT=0x0A00', + 'WINVER=0x0A00', 'WIN32', '_WINDOWS', 'NOMINMAX', @@ -5640,9 +5637,9 @@ }], ], 'msvs_system_include_dirs': [ - '<(windows_sdk_path)/Include/shared', - '<(windows_sdk_path)/Include/um', - '<(windows_sdk_path)/Include/winrt', + '<(windows_sdk_path)/Include/10.0.10240.0/shared', + '<(windows_sdk_path)/Include/10.0.10240.0/um', + '<(windows_sdk_path)/Include/10.0.10240.0/winrt', '$(VSInstallDir)/VC/atlmfc/include', ], 'msvs_cygwin_shell': 0,
diff --git a/build/config/android/internal_rules.gni b/build/config/android/internal_rules.gni index 4f1e491..3727e8d 100644 --- a/build/config/android/internal_rules.gni +++ b/build/config/android/internal_rules.gni
@@ -341,7 +341,8 @@ assert(type == "android_apk" || type == "java_library" || type == "android_resources" || type == "deps_dex" || - type == "android_assets" || type == "resource_rewriter") + type == "android_assets" || type == "resource_rewriter" || + type == "java_binary") deps = [] forward_variables_from(invoker, @@ -379,7 +380,7 @@ rebase_path(build_config, root_build_dir), ] - is_java_library = type == "java_library" + is_java = type == "java_library" || type == "java_binary" is_apk = type == "android_apk" is_android_assets = type == "android_assets" is_android_resources = type == "android_resources" @@ -387,30 +388,30 @@ supports_android = is_apk || is_android_assets || is_android_resources || is_deps_dex || - (is_java_library && defined(invoker.supports_android) && + (is_java && defined(invoker.supports_android) && invoker.supports_android) requires_android = is_apk || is_android_assets || is_android_resources || is_deps_dex || - (is_java_library && defined(invoker.requires_android) && + (is_java && defined(invoker.requires_android) && invoker.requires_android) assert(!requires_android || supports_android, "requires_android requires" + " supports_android") # Mark these variables as used. - assert(is_java_library || true) + assert(is_java || true) assert(is_apk || true) assert(is_android_resources || true) assert(is_deps_dex || true) - if (is_java_library || is_apk) { + if (is_java || is_apk) { args += [ "--jar-path", rebase_path(invoker.jar_path, root_build_dir), ] } - if (is_apk || is_deps_dex || (is_java_library && supports_android)) { + if (is_apk || is_deps_dex || (is_java && supports_android)) { args += [ "--dex-path", rebase_path(invoker.dex_path, root_build_dir), @@ -1547,7 +1548,11 @@ write_build_config(build_config_target_name) { forward_variables_from(invoker, [ "deps" ]) - type = "java_library" + if (defined(invoker.is_java_binary) && invoker.is_java_binary) { + type = "java_binary" + } else { + type = "java_library" + } supports_android = _supports_android requires_android = _requires_android bypass_platform_checks = defined(invoker.bypass_platform_checks) &&
diff --git a/build/config/android/rules.gni b/build/config/android/rules.gni index f4219f23..e8b6572 100644 --- a/build/config/android/rules.gni +++ b/build/config/android/rules.gni
@@ -889,12 +889,11 @@ template("java_binary") { set_sources_assignment_filter([]) - # TODO(cjhopman): This should not act like a java_library for dependents (i.e. - # dependents shouldn't get the jar in their classpath, etc.). java_library_impl(target_name) { forward_variables_from(invoker, "*") supports_android = false main_class = invoker.main_class + is_java_binary = true } }
diff --git a/build/config/compiler/BUILD.gn b/build/config/compiler/BUILD.gn index b26f033..49b3737f 100644 --- a/build/config/compiler/BUILD.gn +++ b/build/config/compiler/BUILD.gn
@@ -39,10 +39,6 @@ binutils_path = rebase_path("//third_party/binutils/Linux_x64/Release/bin", root_build_dir) - # Compile in such a way as to enable profiling of the generated code. For - # example, don't omit the frame pointer and leave in symbols. - enable_profiling = false - # Compile in such a way as to make it possible for the profiler to unwind full # stack frames. Setting this flag has a large effect on the performance of the # generated code than just setting profiling, but gives the profiler more @@ -209,11 +205,6 @@ # ----------------------------------- if (is_posix && !(is_mac || is_ios)) { if (enable_profiling && !is_debug) { - # The GYP build spams this define into every compilation unit, as we do - # here, but it only appears to be used in base and a couple other places. - # TODO(abarth): Should we move this define closer to where it's used? - defines += [ "ENABLE_PROFILING" ] - cflags += [ "-fno-omit-frame-pointer", "-g", @@ -557,11 +548,12 @@ "-arch", "arm-nonsfi", "--pnacl-bias=arm-nonsfi", - "--target=arm-unknown-nacl", + "--target=armv7-unknown-nacl-gnueabihf", ] ldflags += [ "-arch", "arm-nonsfi", + "--target=armv7-unknown-nacl-gnueabihf", ] } }
diff --git a/build/config/compiler/compiler.gni b/build/config/compiler/compiler.gni index 5adc470..cc7463e 100644 --- a/build/config/compiler/compiler.gni +++ b/build/config/compiler/compiler.gni
@@ -13,6 +13,10 @@ # 0 means no symbols. # -1 means auto-set according to debug/release and platform. symbol_level = -1 + + # Compile in such a way as to enable profiling of the generated code. For + # example, don't omit the frame pointer and leave in symbols. + enable_profiling = false } # If it wasn't manually set, set to an appropriate default.
diff --git a/build/config/features.gni b/build/config/features.gni index 7a8e96457..c9ad3df8 100644 --- a/build/config/features.gni +++ b/build/config/features.gni
@@ -33,15 +33,9 @@ # TODO(GYP): Get NaCl linking on other platforms. # Also, see if we can always get rid of enable_nacl_untrusted and # enable_pnacl and always build them if enable_nacl is true. - # The "is_nacl" part of the condition is needed to ensure that - # the untrusted code is built properly; arguably it should be - # guarded by "is_nacl" directly rather than enable_nacl_untrusted, but - # this will go away when Mac and Win are working and we can just use - # the commented out logic. - # Eventually we want this to be: - # enable_nacl = !is_ios && !is_android && !is_chromecast - enable_nacl = (is_linux || is_mac || is_nacl) && current_cpu != "mipsel" && - !is_chromecast + # Eventually we want this to be just the first line. + enable_nacl = !is_ios && !is_android && !is_chromecast && + current_cpu != "mipsel" && !(is_win && current_cpu != "x64") enable_nacl_untrusted = enable_nacl enable_pnacl = enable_nacl_untrusted
diff --git a/build/config/sysroot.gni b/build/config/sysroot.gni index debf771..2ca6451 100644 --- a/build/config/sysroot.gni +++ b/build/config/sysroot.gni
@@ -48,6 +48,18 @@ # Any other builds don't use a sysroot. sysroot = "" } + + if (sysroot != "") { + _script_arch = current_cpu + if (_script_arch == "x86") { + _script_arch = "i386" + } else if (_script_arch == "x64") { + _script_arch = "amd64" + } + assert( + exec_script("//build/dir_exists.py", [ sysroot ], "string") == "True", + "Missing sysroot ($sysroot). To fix, run: build/linux/sysroot_scripts/install-sysroot.py --arch=$_script_arch") + } } else if (is_mac) { import("//build/config/mac/mac_sdk.gni") sysroot = mac_sdk_path
diff --git a/build/config/ui.gni b/build/config/ui.gni index 1fc6d0a..fa4f142 100644 --- a/build/config/ui.gni +++ b/build/config/ui.gni
@@ -69,6 +69,11 @@ use_glib = false } +# Turn off Wayland if glib is enabled. +if (use_glib) { + enable_wayland_server = false +} + if (is_linux && !use_ozone) { use_cairo = true use_pango = true
diff --git a/build/config/win/BUILD.gn b/build/config/win/BUILD.gn index 254000b..bdbf7ea 100644 --- a/build/config/win/BUILD.gn +++ b/build/config/win/BUILD.gn
@@ -101,7 +101,7 @@ "_ATL_NO_OPENGL", "_WINDOWS", "CERT_CHAIN_PARA_HAS_EXTRA_FIELDS", - "NTDDI_VERSION=0x06030000", + "NTDDI_VERSION=0x0A000000", "PSAPI_VERSION=1", "WIN32", "_SECURE_ATL", @@ -142,8 +142,8 @@ # targets need to manually override it for their compiles. config("winver") { defines = [ - "_WIN32_WINNT=0x0603", - "WINVER=0x0603", + "_WIN32_WINNT=0x0A00", + "WINVER=0x0A00", ] }
diff --git a/build/gn_migration.gypi b/build/gn_migration.gypi index dc2a6c5..3861cef9 100644 --- a/build/gn_migration.gypi +++ b/build/gn_migration.gypi
@@ -727,11 +727,6 @@ '../tools/win/static_initializers/static_initializers.gyp:static_initializers', ], }], - ['OS=="win" and win_use_allocator_shim==1', { - 'dependencies': [ - '../base/allocator/allocator.gyp:allocator_unittests', - ] - }], ['OS=="win" and target_arch=="ia32"', { 'dependencies': [ # TODO(GYP): All of these targets need to be ported over.
diff --git a/build/java_apk.gypi b/build/java_apk.gypi index 2a62d972..93913b24 100644 --- a/build/java_apk.gypi +++ b/build/java_apk.gypi
@@ -548,6 +548,7 @@ '--apk=<(incomplete_apk_path)', '--stamp=<(link_stamp)', '--configuration-name=<(CONFIGURATION_NAME)', + '--output-directory=<(PRODUCT_DIR)', ], }, ], @@ -695,6 +696,7 @@ '--install-record=<(apk_install_record)', '--configuration-name=<(CONFIGURATION_NAME)', '--android-sdk-tools', '<(android_sdk_tools)', + '--output-directory', '<(PRODUCT_DIR)', ], 'conditions': [ ['create_abi_split == 1', {
diff --git a/build/linux/BUILD.gn b/build/linux/BUILD.gn index a66d86c..6a1939dd 100644 --- a/build/linux/BUILD.gn +++ b/build/linux/BUILD.gn
@@ -100,7 +100,7 @@ } group("udev") { - deps = [ + public_deps = [ ":udev0_loader", ":udev1_loader", ]
diff --git a/build/linux/sysroot_scripts/install-sysroot.py b/build/linux/sysroot_scripts/install-sysroot.py index e922cb7..b53bd889 100755 --- a/build/linux/sysroot_scripts/install-sysroot.py +++ b/build/linux/sysroot_scripts/install-sysroot.py
@@ -31,6 +31,10 @@ import gyp_environment +# Its existence signifies an Android checkout. +ANDROID_ONLY_DIR = os.path.join(SCRIPT_DIR, os.pardir, os.pardir, os.pardir, + 'third_party', 'android_tools') + URL_PREFIX = 'http://storage.googleapis.com' URL_PATH = 'chrome-linux-sysroot/toolchain' REVISION_AMD64 = '402274e42cb72fde4f48a4bb01664d0ad4533c69' @@ -65,7 +69,7 @@ return sha1.hexdigest() -def DetectArch(gyp_defines, is_android): +def DetectArch(gyp_defines): # Check for optional target_arch and only install for that architecture. # If target_arch is not specified, then only install for the host # architecture. @@ -83,9 +87,6 @@ elif target_arch: raise Exception('Unrecognized target_arch: %s' % target_arch) - if is_android: - return 'arm' - # Figure out host arch using build/detect_host_arch.py and # set target_arch to host arch detected_host_arch = detect_host_arch.HostArch() @@ -107,32 +108,28 @@ if options.running_as_hook and not sys.platform.startswith('linux'): return 0 + # TODO(agrieve): Make this script not depend on GYP_DEFINES so that it works + # with GN as well. gyp_environment.SetEnvironment() supplemental_includes = gyp_chromium.GetSupplementalFiles() gyp_defines = gyp_chromium.GetGypVars(supplemental_includes) - is_android = gyp_defines.get('OS') == 'android' - - if (options.running_as_hook and (not is_android) and - (gyp_defines.get('chromeos') or gyp_defines.get('use_sysroot') == '0')): - return 0 if options.arch: target_arch = options.arch + elif os.path.exists(ANDROID_ONLY_DIR): + # 32-bit Android builds (the default for target_os="android") require a + # 32-bit host sysroot for the v8 snapshot, and a 64-bit sysroot for host + # tools. + ret = _InstallSysroot('i386') + if ret: + return ret + target_arch = 'amd64' else: - target_arch = DetectArch(gyp_defines, is_android) + target_arch = DetectArch(gyp_defines) if not target_arch: print 'Unable to detect target architecture' return 1 - if is_android: - # 32-bit Android builds require a 32-bit host sysroot for the v8 snapshot. - if '64' not in target_arch: - ret = _InstallSysroot('i386') - if ret: - return ret - # Always need host sysroot (which we assume is x64). - target_arch = 'amd64' - return _InstallSysroot(target_arch)
diff --git a/build/toolchain/gcc_toolchain.gni b/build/toolchain/gcc_toolchain.gni index 6742f2b..e83b94b 100644 --- a/build/toolchain/gcc_toolchain.gni +++ b/build/toolchain/gcc_toolchain.gni
@@ -9,7 +9,12 @@ import("//build/toolchain/toolchain.gni") # This value will be inherited in the toolchain below. -concurrent_links = exec_script("get_concurrent_links.py", [], "value") +if (is_cfi) { + concurrent_links = + exec_script("get_concurrent_links.py", [ "--lto" ], "value") +} else { + concurrent_links = exec_script("get_concurrent_links.py", [], "value") +} # This template defines a toolchain for something that works like gcc # (including clang).
diff --git a/build/toolchain/get_concurrent_links.py b/build/toolchain/get_concurrent_links.py index f8c927b..32294fab 100644 --- a/build/toolchain/get_concurrent_links.py +++ b/build/toolchain/get_concurrent_links.py
@@ -5,12 +5,13 @@ # This script computs the number of concurrent links we want to run in the build # as a function of machine spec. It's based on GetDefaultConcurrentLinks in GYP. +import optparse import os import re import subprocess import sys -def GetDefaultConcurrentLinks(): +def _GetDefaultConcurrentLinks(is_lto): # Inherit the legacy environment variable for people that have set it in GYP. pool_size = int(os.getenv('GYP_LINK_CONCURRENCY', 0)) if pool_size: @@ -49,7 +50,11 @@ if not match: continue # Allow 8Gb per link on Linux because Gold is quite memory hungry - return max(1, int(match.group(1)) / (8 * (2 ** 20))) + # For LTO builds the RAM requirements are even higher + # Note: it's 15 GB for LTO build to make sure we get 4 link jobs + # for 64 GB, even if the system reports a couple of GBs less. + ram_per_link_gb = 15 if is_lto else 8 + return max(1, int(match.group(1)) / (ram_per_link_gb * (2 ** 20))) return 1 elif sys.platform == 'darwin': try: @@ -63,4 +68,15 @@ # TODO(scottmg): Implement this for other platforms. return 1 -print GetDefaultConcurrentLinks() +def main(): + parser = optparse.OptionParser() + parser.add_option('--lto', action="store_true", default=False, + help='This is an LTO build with higher memory requirements') + parser.disable_interspersed_args() + options, args = parser.parse_args() + + print _GetDefaultConcurrentLinks(is_lto=options.lto) + return 0 + +if __name__ == '__main__': + sys.exit(main())
diff --git a/build/toolchain/win/BUILD.gn b/build/toolchain/win/BUILD.gn index 2054713b..11f9328c 100644 --- a/build/toolchain/win/BUILD.gn +++ b/build/toolchain/win/BUILD.gn
@@ -2,6 +2,7 @@ # Use of this source code is governed by a BSD-style license that can be # found in the LICENSE file. +import("//build/config/sanitizers/sanitizers.gni") import("//build/config/win/visual_studio_version.gni") import("//build/toolchain/goma.gni") import("//build/toolchain/toolchain.gni") @@ -24,7 +25,12 @@ } # This value will be inherited in the toolchain below. -concurrent_links = exec_script("../get_concurrent_links.py", [], "value") +if (is_cfi) { + concurrent_links = + exec_script("../get_concurrent_links.py", [ "--lto" ], "value") +} else { + concurrent_links = exec_script("../get_concurrent_links.py", [], "value") +} # Copy the VS runtime DLL for the default toolchain to the root build directory # so things will run.
diff --git a/build/vs_toolchain.py b/build/vs_toolchain.py index 723106b..eeaaea3 100755 --- a/build/vs_toolchain.py +++ b/build/vs_toolchain.py
@@ -198,7 +198,7 @@ return ['49ae4b60d898182fc3f521c2fcda82c453915011'] else: # Default to VS2013. - return ['ee7d718ec60c2dc5d255bbe325909c2021a7efef'] + return ['9ff97c632ae1fee0c98bcd53e71770eb3a0d8deb'] def Update(force=False):
diff --git a/cc/BUILD.gn b/cc/BUILD.gn index 6a1d321c..88e3524 100644 --- a/cc/BUILD.gn +++ b/cc/BUILD.gn
@@ -563,6 +563,8 @@ "test/animation_timelines_test_common.h", "test/begin_frame_args_test.cc", "test/begin_frame_args_test.h", + "test/begin_frame_source_test.cc", + "test/begin_frame_source_test.h", "test/failure_output_surface.cc", "test/failure_output_surface.h", "test/fake_content_layer_client.cc", @@ -634,6 +636,7 @@ "test/layer_tree_settings_for_testing.h", "test/layer_tree_test.cc", "test/layer_tree_test.h", + "test/mock_helper.h", "test/mock_occlusion_tracker.h", "test/ordered_simple_task_runner.cc", "test/ordered_simple_task_runner.h", @@ -840,7 +843,9 @@ "scheduler/delay_based_time_source_unittest.cc", "scheduler/scheduler_state_machine_unittest.cc", "scheduler/scheduler_unittest.cc", + "test/begin_frame_source_test_unittest.cc", "test/layer_tree_json_parser_unittest.cc", + "test/mock_helper_unittest.cc", "test/ordered_simple_task_runner_unittest.cc", "test/test_web_graphics_context_3d_unittest.cc", "tiles/picture_layer_tiling_set_unittest.cc",
diff --git a/cc/base/rtree.cc b/cc/base/rtree.cc index ca64e87..79a4bcd 100644 --- a/cc/base/rtree.cc +++ b/cc/base/rtree.cc
@@ -89,14 +89,13 @@ return BuildRecursive(branches, level + 1); } -void RTree::Search(const gfx::RectF& query, - std::vector<size_t>* results) const { +void RTree::Search(const gfx::Rect& query, std::vector<size_t>* results) const { if (num_data_elements_ > 0 && query.Intersects(root_.bounds)) SearchRecursive(root_.subtree, query, results); } void RTree::SearchRecursive(Node* node, - const gfx::RectF& query, + const gfx::Rect& query, std::vector<size_t>* results) const { for (uint16_t i = 0; i < node->num_children; ++i) { if (query.Intersects(node->children[i].bounds)) {
diff --git a/cc/base/rtree.h b/cc/base/rtree.h index f765c353..63f7d14 100644 --- a/cc/base/rtree.h +++ b/cc/base/rtree.h
@@ -46,7 +46,7 @@ branches.reserve(items.size()); for (size_t i = 0; i < items.size(); i++) { - const gfx::RectF& bounds = bounds_getter(items[i]); + const gfx::Rect& bounds = bounds_getter(items[i]); if (bounds.IsEmpty()) continue; @@ -70,10 +70,10 @@ template <typename Container> void Build(const Container& items) { - Build(items, [](const gfx::RectF& bounds) { return bounds; }); + Build(items, [](const gfx::Rect& bounds) { return bounds; }); } - void Search(const gfx::RectF& query, std::vector<size_t>* results) const; + void Search(const gfx::Rect& query, std::vector<size_t>* results) const; private: // These values were empirically determined to produce reasonable performance @@ -90,7 +90,7 @@ Node* subtree; size_t index; }; - gfx::RectF bounds; + gfx::Rect bounds; }; struct Node { @@ -100,7 +100,7 @@ }; void SearchRecursive(Node* root, - const gfx::RectF& query, + const gfx::Rect& query, std::vector<size_t>* results) const; // Consumes the input array.
diff --git a/cc/base/rtree_unittest.cc b/cc/base/rtree_unittest.cc index b703a17..e58c9f6 100644 --- a/cc/base/rtree_unittest.cc +++ b/cc/base/rtree_unittest.cc
@@ -9,10 +9,10 @@ namespace cc { TEST(RTreeTest, NoOverlap) { - std::vector<gfx::RectF> rects; + std::vector<gfx::Rect> rects; for (int y = 0; y < 50; ++y) { for (int x = 0; x < 50; ++x) { - rects.push_back(gfx::RectF(x, y, 1.f, 1.f)); + rects.push_back(gfx::Rect(x, y, 1, 1)); } } @@ -20,30 +20,30 @@ rtree.Build(rects); std::vector<size_t> results; - rtree.Search(gfx::RectF(0.f, 0.f, 50.f, 50.f), &results); + rtree.Search(gfx::Rect(0, 0, 50, 50), &results); ASSERT_EQ(2500u, results.size()); for (size_t i = 0; i < 2500; ++i) { ASSERT_EQ(results[i], i); } results.clear(); - rtree.Search(gfx::RectF(0.f, 0.f, 50.f, 49.f), &results); + rtree.Search(gfx::Rect(0, 0, 50, 49), &results); ASSERT_EQ(2450u, results.size()); for (size_t i = 0; i < 2450; ++i) { ASSERT_EQ(results[i], i); } results.clear(); - rtree.Search(gfx::RectF(5.2f, 6.3f, 0.1f, 0.2f), &results); + rtree.Search(gfx::Rect(5, 6, 1, 1), &results); ASSERT_EQ(1u, results.size()); EXPECT_EQ(6u * 50 + 5u, results[0]); } TEST(RTreeTest, Overlap) { - std::vector<gfx::RectF> rects; + std::vector<gfx::Rect> rects; for (int h = 1; h <= 50; ++h) { for (int w = 1; w <= 50; ++w) { - rects.push_back(gfx::RectF(0, 0, w, h)); + rects.push_back(gfx::Rect(0, 0, w, h)); } } @@ -51,14 +51,14 @@ rtree.Build(rects); std::vector<size_t> results; - rtree.Search(gfx::RectF(0.f, 0.f, 1.f, 1.f), &results); + rtree.Search(gfx::Rect(0, 0, 1, 1), &results); ASSERT_EQ(2500u, results.size()); for (size_t i = 0; i < 2500; ++i) { ASSERT_EQ(results[i], i); } results.clear(); - rtree.Search(gfx::RectF(0.f, 49.f, 1.f, 1.f), &results); + rtree.Search(gfx::Rect(0, 49, 1, 1), &results); ASSERT_EQ(50u, results.size()); for (size_t i = 0; i < 50; ++i) { EXPECT_EQ(results[i], 2450u + i);
diff --git a/cc/cc_tests.gyp b/cc/cc_tests.gyp index 03f8ae5..5332133 100644 --- a/cc/cc_tests.gyp +++ b/cc/cc_tests.gyp
@@ -112,7 +112,9 @@ 'scheduler/delay_based_time_source_unittest.cc', 'scheduler/scheduler_state_machine_unittest.cc', 'scheduler/scheduler_unittest.cc', + 'test/begin_frame_source_test_unittest.cc', 'test/layer_tree_json_parser_unittest.cc', + 'test/mock_helper_unittest.cc', 'test/ordered_simple_task_runner_unittest.cc', 'test/test_web_graphics_context_3d_unittest.cc', 'tiles/picture_layer_tiling_set_unittest.cc', @@ -165,6 +167,8 @@ 'test/animation_timelines_test_common.h', 'test/begin_frame_args_test.cc', 'test/begin_frame_args_test.h', + 'test/begin_frame_source_test.cc', + 'test/begin_frame_source_test.h', 'test/failure_output_surface.cc', 'test/failure_output_surface.h', 'test/fake_content_layer_client.cc', @@ -236,6 +240,7 @@ 'test/layer_tree_settings_for_testing.h', 'test/layer_tree_test.cc', 'test/layer_tree_test.h', + 'test/mock_helper.h', 'test/mock_occlusion_tracker.h', 'test/ordered_simple_task_runner.cc', 'test/ordered_simple_task_runner.h',
diff --git a/cc/output/direct_renderer.cc b/cc/output/direct_renderer.cc index 600805a..a55564f 100644 --- a/cc/output/direct_renderer.cc +++ b/cc/output/direct_renderer.cc
@@ -245,7 +245,9 @@ break; } } - if (!has_copy_requests) { + if (has_copy_requests) { + overlay_processor_->SkipProcessForOverlays(); + } else { overlay_processor_->ProcessForOverlays( resource_provider_, render_passes_in_draw_order, &frame.overlay_list, &frame.ca_layer_overlay_list, &frame.root_damage_rect);
diff --git a/cc/output/overlay_candidate.cc b/cc/output/overlay_candidate.cc index 658f153..367f316 100644 --- a/cc/output/overlay_candidate.cc +++ b/cc/output/overlay_candidate.cc
@@ -175,6 +175,7 @@ use_output_surface_for_resource(false), resource_id(0), plane_z_order(0), + is_unoccluded(false), overlay_handled(false) {} OverlayCandidate::~OverlayCandidate() {} @@ -228,6 +229,23 @@ } // static +bool OverlayCandidate::IsOccluded(const OverlayCandidate& candidate, + QuadList::ConstIterator quad_list_begin, + QuadList::ConstIterator quad_list_end) { + // Check that no visible quad overlaps the candidate. + for (auto overlap_iter = quad_list_begin; overlap_iter != quad_list_end; + ++overlap_iter) { + gfx::RectF overlap_rect = MathUtil::MapClippedRect( + overlap_iter->shared_quad_state->quad_to_target_transform, + gfx::RectF(overlap_iter->rect)); + if (candidate.display_rect.Intersects(overlap_rect) && + !OverlayCandidate::IsInvisibleQuad(*overlap_iter)) + return true; + } + return false; +} + +// static bool OverlayCandidate::FromTextureQuad(ResourceProvider* resource_provider, const TextureDrawQuad* quad, OverlayCandidate* candidate) {
diff --git a/cc/output/overlay_candidate.h b/cc/output/overlay_candidate.h index aa42ba11..1a735618 100644 --- a/cc/output/overlay_candidate.h +++ b/cc/output/overlay_candidate.h
@@ -8,6 +8,7 @@ #include <vector> #include "cc/base/cc_export.h" +#include "cc/quads/render_pass.h" #include "cc/resources/resource_format.h" #include "ui/gfx/geometry/rect.h" #include "ui/gfx/geometry/rect_f.h" @@ -38,6 +39,12 @@ // an overlay. static bool IsInvisibleQuad(const DrawQuad* quad); + // Returns true if any any of the quads in the list given by |quad_list_begin| + // and |quad_list_end| are visible and on top of |candidate|. + static bool IsOccluded(const OverlayCandidate& candidate, + QuadList::ConstIterator quad_list_begin, + QuadList::ConstIterator quad_list_end); + OverlayCandidate(); ~OverlayCandidate(); @@ -66,6 +73,10 @@ // Stacking order of the overlay plane relative to the main surface, // which is 0. Signed to allow for "underlays". int plane_z_order; + // True if the overlay does not have any visible quads on top of it. Set by + // the strategy so the OverlayProcessor can consider subtracting damage caused + // by underlay quads. + bool is_unoccluded; // To be modified by the implementer if this candidate can go into // an overlay.
diff --git a/cc/output/overlay_processor.cc b/cc/output/overlay_processor.cc index 40d6da6c..74e68d2 100644 --- a/cc/output/overlay_processor.cc +++ b/cc/output/overlay_processor.cc
@@ -76,23 +76,48 @@ if (!strategy->Attempt(resource_provider, render_passes, candidates)) continue; - // Subtract on-top overlays from the damage rect, unless the overlays use - // the backbuffer as their content (in which case, add their combined rect - // back to the damage at the end). - gfx::Rect output_surface_overlay_damage_rect; - for (const OverlayCandidate& overlay : *candidates) { - if (overlay.plane_z_order > 0) { - const gfx::Rect overlay_display_rect = - ToEnclosedRect(overlay.display_rect); - overlay_damage_rect_.Union(overlay_display_rect); - damage_rect->Subtract(overlay_display_rect); - if (overlay.use_output_surface_for_resource) - output_surface_overlay_damage_rect.Union(overlay_display_rect); - } - } - damage_rect->Union(output_surface_overlay_damage_rect); + UpdateDamageRect(candidates, damage_rect); return; } } +void OverlayProcessor::SkipProcessForOverlays() { + // If overlay processing was skipped for a frame there's no way to be sure + // of the state of the previous frame, so reset. + previous_frame_underlay_rect_ = gfx::Rect(); +} + +// Subtract on-top overlays from the damage rect, unless the overlays use +// the backbuffer as their content (in which case, add their combined rect +// back to the damage at the end). +// Also subtract unoccluded underlays from the damage rect if we know that the +// same underlay was scheduled on the previous frame. If the renderer decides +// not to swap the framebuffer there will still be a transparent hole in the +// previous frame. This only handles the common case of a single underlay quad +// for fullscreen video. +void OverlayProcessor::UpdateDamageRect(OverlayCandidateList* candidates, + gfx::Rect* damage_rect) { + gfx::Rect output_surface_overlay_damage_rect; + gfx::Rect this_frame_underlay_rect; + for (const OverlayCandidate& overlay : *candidates) { + if (overlay.plane_z_order > 0) { + const gfx::Rect overlay_display_rect = + ToEnclosedRect(overlay.display_rect); + overlay_damage_rect_.Union(overlay_display_rect); + damage_rect->Subtract(overlay_display_rect); + if (overlay.use_output_surface_for_resource) + output_surface_overlay_damage_rect.Union(overlay_display_rect); + } else if (overlay.plane_z_order < 0 && overlay.is_unoccluded && + this_frame_underlay_rect.IsEmpty()) { + this_frame_underlay_rect = ToEnclosedRect(overlay.display_rect); + } + } + + if (this_frame_underlay_rect == previous_frame_underlay_rect_) + damage_rect->Subtract(this_frame_underlay_rect); + previous_frame_underlay_rect_ = this_frame_underlay_rect; + + damage_rect->Union(output_surface_overlay_damage_rect); +} + } // namespace cc
diff --git a/cc/output/overlay_processor.h b/cc/output/overlay_processor.h index f348fb8..8f3704cd 100644 --- a/cc/output/overlay_processor.h +++ b/cc/output/overlay_processor.h
@@ -24,9 +24,7 @@ // Returns false if the strategy cannot be made to work with the // current set of render passes. Returns true if the strategy was successful // and adds any additional passes necessary to represent overlays to - // |render_passes|. Strategy can also optimize |damage_rect| as it seems - // fit to reduce GL composition, in case |damage_rect| is obscured by - // overlays. + // |render_passes|. virtual bool Attempt(ResourceProvider* resource_provider, RenderPassList* render_passes, OverlayCandidateList* candidates) = 0; @@ -46,10 +44,14 @@ CALayerOverlayList* ca_layer_overlays, gfx::Rect* damage_rect); + // Notify the processor that ProcessForOverlays is being skipped this frame. + void SkipProcessForOverlays(); + protected: StrategyList strategies_; OutputSurface* surface_; gfx::Rect overlay_damage_rect_; + gfx::Rect previous_frame_underlay_rect_; private: bool ProcessForCALayers(ResourceProvider* resource_provider, @@ -57,6 +59,9 @@ OverlayCandidateList* overlay_candidates, CALayerOverlayList* ca_layer_overlays, gfx::Rect* damage_rect); + // Update |damage_rect| by removing damage casued by |candidates|. + void UpdateDamageRect(OverlayCandidateList* candidates, + gfx::Rect* damage_rect); DISALLOW_COPY_AND_ASSIGN(OverlayProcessor); };
diff --git a/cc/output/overlay_strategy_single_on_top.cc b/cc/output/overlay_strategy_single_on_top.cc index 78e5bf9..10ffcef 100644 --- a/cc/output/overlay_strategy_single_on_top.cc +++ b/cc/output/overlay_strategy_single_on_top.cc
@@ -40,15 +40,9 @@ const OverlayCandidate& candidate, QuadList::Iterator candidate_iterator) { // Check that no prior quads overlap it. - for (auto overlap_iter = quad_list->cbegin(); - overlap_iter != candidate_iterator; ++overlap_iter) { - gfx::RectF overlap_rect = MathUtil::MapClippedRect( - overlap_iter->shared_quad_state->quad_to_target_transform, - gfx::RectF(overlap_iter->rect)); - if (candidate.display_rect.Intersects(overlap_rect) && - !OverlayCandidate::IsInvisibleQuad(*overlap_iter)) - return false; - } + if (OverlayCandidate::IsOccluded(candidate, quad_list->cbegin(), + candidate_iterator)) + return false; // Add the overlay. OverlayCandidateList new_candidate_list = *candidate_list;
diff --git a/cc/output/overlay_strategy_underlay.cc b/cc/output/overlay_strategy_underlay.cc index 9a8a3628..f9bb0391 100644 --- a/cc/output/overlay_strategy_underlay.cc +++ b/cc/output/overlay_strategy_underlay.cc
@@ -38,6 +38,8 @@ // If the candidate can be handled by an overlay, create a pass for it. We // need to switch out the video quad with a black transparent one. if (new_candidate_list.back().overlay_handled) { + new_candidate_list.back().is_unoccluded = + !OverlayCandidate::IsOccluded(candidate, quad_list.cbegin(), it); const SharedQuadState* shared_quad_state = it->shared_quad_state; gfx::Rect rect = it->visible_rect; SolidColorDrawQuad* replacement =
diff --git a/cc/output/overlay_unittest.cc b/cc/output/overlay_unittest.cc index 5d1b05f..79742979 100644 --- a/cc/output/overlay_unittest.cc +++ b/cc/output/overlay_unittest.cc
@@ -1360,7 +1360,8 @@ EXPECT_EQ(pass_list[0]->quad_list.front()->material, DrawQuad::SOLID_COLOR); } -TEST_F(UnderlayTest, DamageRect) { +// The first time an underlay is scheduled its damage must not be subtracted. +TEST_F(UnderlayTest, InitialUnderlayDamageNotSubtracted) { scoped_ptr<RenderPass> pass = CreateRenderPass(); CreateFullscreenCandidateQuad(resource_provider_.get(), pass->shared_quad_state_list.back(), @@ -1368,30 +1369,114 @@ damage_rect_ = kOverlayRect; - // Add something behind it. - CreateFullscreenOpaqueQuad(resource_provider_.get(), - pass->shared_quad_state_list.back(), pass.get()); - CreateFullscreenOpaqueQuad(resource_provider_.get(), - pass->shared_quad_state_list.back(), pass.get()); - RenderPassList pass_list; pass_list.push_back(std::move(pass)); - // Check for potential candidates. OverlayCandidateList candidate_list; - - // Primary plane. - OverlayCandidate output_surface_plane; - output_surface_plane.display_rect = gfx::RectF(kOverlayRect); - output_surface_plane.quad_rect_in_target_space = kOverlayRect; - output_surface_plane.use_output_surface_for_resource = true; - output_surface_plane.overlay_handled = true; - candidate_list.push_back(output_surface_plane); - overlay_processor_->ProcessForOverlays(resource_provider_.get(), &pass_list, &candidate_list, nullptr, &damage_rect_); - DCHECK(!damage_rect_.IsEmpty()); + + EXPECT_EQ(kOverlayRect, damage_rect_); +} + +// An identical underlay for two frames in a row means the damage can be +// subtracted the second time. +TEST_F(UnderlayTest, DamageSubtractedForConsecutiveIdenticalUnderlays) { + for (int i = 0; i < 2; ++i) { + scoped_ptr<RenderPass> pass = CreateRenderPass(); + CreateFullscreenCandidateQuad(resource_provider_.get(), + pass->shared_quad_state_list.back(), + pass.get()); + + damage_rect_ = kOverlayRect; + + // Add something behind it. + CreateFullscreenOpaqueQuad(resource_provider_.get(), + pass->shared_quad_state_list.back(), pass.get()); + + RenderPassList pass_list; + pass_list.push_back(pass.Pass()); + OverlayCandidateList candidate_list; + overlay_processor_->ProcessForOverlays(resource_provider_.get(), &pass_list, + &candidate_list, nullptr, + &damage_rect_); + } + + // The second time the same overlay rect is scheduled it will be subtracted + // from the damage rect. + EXPECT_TRUE(damage_rect_.IsEmpty()); +} + +// Underlay damage can only be subtracted if the previous frame's underlay +// was the same rect. +TEST_F(UnderlayTest, DamageNotSubtractedForNonIdenticalConsecutiveUnderlays) { + gfx::Rect overlay_rects[] = {kOverlayBottomRightRect, kOverlayRect}; + for (int i = 0; i < 2; ++i) { + scoped_ptr<RenderPass> pass = CreateRenderPass(); + + CreateCandidateQuadAt(resource_provider_.get(), + pass->shared_quad_state_list.back(), pass.get(), + overlay_rects[i]); + + damage_rect_ = overlay_rects[i]; + + RenderPassList pass_list; + pass_list.push_back(pass.Pass()); + OverlayCandidateList candidate_list; + overlay_processor_->ProcessForOverlays(resource_provider_.get(), &pass_list, + &candidate_list, nullptr, + &damage_rect_); + + EXPECT_EQ(overlay_rects[i], damage_rect_); + } +} + +TEST_F(UnderlayTest, DamageNotSubtractedWhenQuadsAboveOverlap) { + for (int i = 0; i < 2; ++i) { + scoped_ptr<RenderPass> pass = CreateRenderPass(); + // Add an overlapping quad above the candidate. + CreateFullscreenOpaqueQuad(resource_provider_.get(), + pass->shared_quad_state_list.back(), pass.get()); + CreateFullscreenCandidateQuad(resource_provider_.get(), + pass->shared_quad_state_list.back(), + pass.get()); + + damage_rect_ = kOverlayRect; + + RenderPassList pass_list; + pass_list.push_back(pass.Pass()); + OverlayCandidateList candidate_list; + overlay_processor_->ProcessForOverlays(resource_provider_.get(), &pass_list, + &candidate_list, nullptr, + &damage_rect_); + } + + EXPECT_EQ(kOverlayRect, damage_rect_); +} + +TEST_F(UnderlayTest, DamageSubtractedWhenQuadsAboveDontOverlap) { + for (int i = 0; i < 2; ++i) { + scoped_ptr<RenderPass> pass = CreateRenderPass(); + // Add a non-overlapping quad above the candidate. + CreateOpaqueQuadAt(resource_provider_.get(), + pass->shared_quad_state_list.back(), pass.get(), + kOverlayTopLeftRect); + CreateCandidateQuadAt(resource_provider_.get(), + pass->shared_quad_state_list.back(), pass.get(), + kOverlayBottomRightRect); + + damage_rect_ = kOverlayBottomRightRect; + + RenderPassList pass_list; + pass_list.push_back(pass.Pass()); + OverlayCandidateList candidate_list; + overlay_processor_->ProcessForOverlays(resource_provider_.get(), &pass_list, + &candidate_list, nullptr, + &damage_rect_); + } + + EXPECT_TRUE(damage_rect_.IsEmpty()); } OverlayCandidateList BackbufferOverlayList(const RenderPass* root_render_pass) {
diff --git a/cc/output/renderer.cc b/cc/output/renderer.cc index 7fe0ffb..a0812c6 100644 --- a/cc/output/renderer.cc +++ b/cc/output/renderer.cc
@@ -26,12 +26,12 @@ max_texture_size(0), using_shared_memory_resources(false), using_partial_swap(false), + allow_empty_swap(false), using_egl_image(false), using_image(false), using_discard_framebuffer(false), allow_rasterize_on_demand(false), - max_msaa_samples(0) { -} + max_msaa_samples(0) {} RendererCapabilitiesImpl::~RendererCapabilitiesImpl() {}
diff --git a/cc/playback/discardable_image_map.cc b/cc/playback/discardable_image_map.cc index 1333475..e109e2be 100644 --- a/cc/playback/discardable_image_map.cc +++ b/cc/playback/discardable_image_map.cc
@@ -39,7 +39,7 @@ DiscardableImagesMetadataCanvas( int width, int height, - std::vector<std::pair<DrawImage, gfx::RectF>>* image_set) + std::vector<std::pair<DrawImage, gfx::Rect>>* image_set) : SkNWayCanvas(width, height), image_set_(image_set), canvas_bounds_(SkRect::MakeIWH(width, height)) {} @@ -99,11 +99,11 @@ } image_set_->push_back( std::make_pair(DrawImage(image, ExtractScale(matrix), filter_quality), - gfx::SkRectToRectF(rect))); + gfx::ToEnclosingRect(gfx::SkRectToRectF(rect)))); } } - std::vector<std::pair<DrawImage, gfx::RectF>>* image_set_; + std::vector<std::pair<DrawImage, gfx::Rect>>* image_set_; const SkRect canvas_bounds_; }; @@ -121,8 +121,10 @@ } void DiscardableImageMap::EndGeneratingMetadata() { - images_rtree_.Build( - all_images_, [](const PositionDrawImage& image) { return image.second; }); + images_rtree_.Build(all_images_, + [](const std::pair<DrawImage, gfx::Rect>& image) { + return image.second; + }); } void DiscardableImageMap::GetDiscardableImagesInRect( @@ -130,7 +132,7 @@ float raster_scale, std::vector<DrawImage>* images) const { std::vector<size_t> indices; - images_rtree_.Search(gfx::RectF(rect), &indices); + images_rtree_.Search(rect, &indices); for (size_t index : indices) images->push_back(all_images_[index].first.ApplyScale(raster_scale)); }
diff --git a/cc/playback/discardable_image_map.h b/cc/playback/discardable_image_map.h index db6b17fe..0306e1b 100644 --- a/cc/playback/discardable_image_map.h +++ b/cc/playback/discardable_image_map.h
@@ -49,12 +49,11 @@ private: friend class ScopedMetadataGenerator; friend class DiscardableImageMapTest; - using PositionDrawImage = std::pair<DrawImage, gfx::RectF>; scoped_ptr<SkCanvas> BeginGeneratingMetadata(const gfx::Size& bounds); void EndGeneratingMetadata(); - std::vector<PositionDrawImage> all_images_; + std::vector<std::pair<DrawImage, gfx::Rect>> all_images_; RTree images_rtree_; };
diff --git a/cc/playback/discardable_image_map_unittest.cc b/cc/playback/discardable_image_map_unittest.cc index f68b6963..70253caa 100644 --- a/cc/playback/discardable_image_map_unittest.cc +++ b/cc/playback/discardable_image_map_unittest.cc
@@ -21,10 +21,10 @@ namespace { struct PositionDrawImage { - PositionDrawImage(const SkImage* image, const gfx::RectF& image_rect) + PositionDrawImage(const SkImage* image, const gfx::Rect& image_rect) : image(image), image_rect(image_rect) {} const SkImage* image; - gfx::RectF image_rect; + gfx::Rect image_rect; }; } // namespace @@ -38,7 +38,7 @@ image_map.GetDiscardableImagesInRect(rect, 1.f, &draw_images); std::vector<size_t> indices; - image_map.images_rtree_.Search(gfx::RectF(rect), &indices); + image_map.images_rtree_.Search(rect, &indices); std::vector<PositionDrawImage> position_draw_images; for (size_t index : indices) { position_draw_images.push_back( @@ -104,7 +104,7 @@ EXPECT_EQ(1u, images.size()) << x << " " << y; EXPECT_TRUE(images[0].image == discardable_image[y][x].get()) << x << " " << y; - EXPECT_EQ(gfx::RectF(x * 512 + 6, y * 512 + 6, 500, 500), + EXPECT_EQ(gfx::Rect(x * 512 + 6, y * 512 + 6, 500, 500), images[0].image_rect); } else { EXPECT_EQ(0u, images.size()) << x << " " << y; @@ -117,14 +117,14 @@ GetDiscardableImagesInRect(image_map, gfx::Rect(512, 512, 2048, 2048)); EXPECT_EQ(4u, images.size()); EXPECT_TRUE(images[0].image == discardable_image[1][2].get()); - EXPECT_EQ(gfx::RectF(2 * 512 + 6, 512 + 6, 500, 500), images[0].image_rect); + EXPECT_EQ(gfx::Rect(2 * 512 + 6, 512 + 6, 500, 500), images[0].image_rect); EXPECT_TRUE(images[1].image == discardable_image[2][1].get()); - EXPECT_EQ(gfx::RectF(512 + 6, 2 * 512 + 6, 500, 500), images[1].image_rect); + EXPECT_EQ(gfx::Rect(512 + 6, 2 * 512 + 6, 500, 500), images[1].image_rect); EXPECT_TRUE(images[2].image == discardable_image[2][3].get()); - EXPECT_EQ(gfx::RectF(3 * 512 + 6, 2 * 512 + 6, 500, 500), + EXPECT_EQ(gfx::Rect(3 * 512 + 6, 2 * 512 + 6, 500, 500), images[2].image_rect); EXPECT_TRUE(images[3].image == discardable_image[3][2].get()); - EXPECT_EQ(gfx::RectF(2 * 512 + 6, 3 * 512 + 6, 500, 500), + EXPECT_EQ(gfx::Rect(2 * 512 + 6, 3 * 512 + 6, 500, 500), images[3].image_rect); } @@ -181,7 +181,7 @@ EXPECT_EQ(1u, images.size()) << x << " " << y; EXPECT_TRUE(images[0].image == discardable_image[y][x].get()) << x << " " << y; - EXPECT_EQ(gfx::RectF(1024 + x * 512 + 6, y * 512 + 6, 500, 500), + EXPECT_EQ(gfx::Rect(1024 + x * 512 + 6, y * 512 + 6, 500, 500), images[0].image_rect); } else { EXPECT_EQ(0u, images.size()) << x << " " << y; @@ -194,16 +194,16 @@ image_map, gfx::Rect(1024 + 512, 512, 2048, 2048)); EXPECT_EQ(4u, images.size()); EXPECT_TRUE(images[0].image == discardable_image[1][2].get()); - EXPECT_EQ(gfx::RectF(1024 + 2 * 512 + 6, 512 + 6, 500, 500), + EXPECT_EQ(gfx::Rect(1024 + 2 * 512 + 6, 512 + 6, 500, 500), images[0].image_rect); EXPECT_TRUE(images[1].image == discardable_image[2][1].get()); - EXPECT_EQ(gfx::RectF(1024 + 512 + 6, 2 * 512 + 6, 500, 500), + EXPECT_EQ(gfx::Rect(1024 + 512 + 6, 2 * 512 + 6, 500, 500), images[1].image_rect); EXPECT_TRUE(images[2].image == discardable_image[2][3].get()); - EXPECT_EQ(gfx::RectF(1024 + 3 * 512 + 6, 2 * 512 + 6, 500, 500), + EXPECT_EQ(gfx::Rect(1024 + 3 * 512 + 6, 2 * 512 + 6, 500, 500), images[2].image_rect); EXPECT_TRUE(images[3].image == discardable_image[3][2].get()); - EXPECT_EQ(gfx::RectF(1024 + 2 * 512 + 6, 3 * 512 + 6, 500, 500), + EXPECT_EQ(gfx::Rect(1024 + 2 * 512 + 6, 3 * 512 + 6, 500, 500), images[3].image_rect); } @@ -281,7 +281,7 @@ EXPECT_EQ(1u, images.size()) << x << " " << y; EXPECT_TRUE(images[0].image == discardable_image[y][x].get()) << x << " " << y; - EXPECT_EQ(gfx::RectF(x * 512 + 6, y * 512 + 6, 500, 500), + EXPECT_EQ(gfx::Rect(x * 512 + 6, y * 512 + 6, 500, 500), images[0].image_rect); } else { EXPECT_EQ(0u, images.size()) << x << " " << y; @@ -319,7 +319,7 @@ GetDiscardableImagesInRect(image_map, gfx::Rect(0, 0, 1, 1)); EXPECT_EQ(1u, images.size()); EXPECT_TRUE(images[0].image == discardable_image.get()); - EXPECT_EQ(gfx::RectF(0, 0, 1 << 25, 1 << 25), images[0].image_rect); + EXPECT_EQ(gfx::Rect(0, 0, 1 << 25, 1 << 25), images[0].image_rect); } } // namespace cc
diff --git a/cc/scheduler/begin_frame_source.cc b/cc/scheduler/begin_frame_source.cc index 1ee862b..26819831 100644 --- a/cc/scheduler/begin_frame_source.cc +++ b/cc/scheduler/begin_frame_source.cc
@@ -13,18 +13,6 @@ #include "cc/scheduler/delay_based_time_source.h" #include "cc/scheduler/scheduler.h" -#ifdef NDEBUG -#define DEBUG_FRAMES(...) -#else -#define DEBUG_FRAMES(name, arg1_name, arg1_val, arg2_name, arg2_val) \ - TRACE_EVENT2(TRACE_DISABLED_BY_DEFAULT("cc.debug.scheduler.frames"), \ - name, \ - arg1_name, \ - arg1_val, \ - arg2_name, \ - arg2_val); -#endif - namespace cc { // BeginFrameObserverBase -----------------------------------------------
diff --git a/cc/scheduler/begin_frame_source.h b/cc/scheduler/begin_frame_source.h index f6f1a78..87ed17f6 100644 --- a/cc/scheduler/begin_frame_source.h +++ b/cc/scheduler/begin_frame_source.h
@@ -13,6 +13,14 @@ #include "cc/output/begin_frame_args.h" #include "cc/scheduler/delay_based_time_source.h" +#ifdef NDEBUG +#define DEBUG_FRAMES(...) +#else +#define DEBUG_FRAMES(name, arg1_name, arg1_val, arg2_name, arg2_val) \ + TRACE_EVENT2(TRACE_DISABLED_BY_DEFAULT("cc.debug.scheduler.frames"), name, \ + arg1_name, arg1_val, arg2_name, arg2_val); +#endif + namespace cc { // (Pure) Interface for observing BeginFrame messages from BeginFrameSource
diff --git a/cc/scheduler/begin_frame_source_unittest.cc b/cc/scheduler/begin_frame_source_unittest.cc index 2c12ca90..afc3b30 100644 --- a/cc/scheduler/begin_frame_source_unittest.cc +++ b/cc/scheduler/begin_frame_source_unittest.cc
@@ -2,173 +2,19 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#include <deque> -#include <string> +#include "cc/scheduler/begin_frame_source.h" #include "base/basictypes.h" #include "base/test/test_simple_task_runner.h" -#include "cc/scheduler/begin_frame_source.h" #include "cc/test/begin_frame_args_test.h" +#include "cc/test/begin_frame_source_test.h" #include "cc/test/scheduler_test_common.h" #include "testing/gmock/include/gmock/gmock.h" #include "testing/gtest/include/gtest/gtest.h" -// Macros to help set up expected calls on the MockBeginFrameObserver. -#define EXPECT_BEGIN_FRAME_DROP(obs, frame_time, deadline, interval) \ - { \ - ::testing::Expectation exp = \ - EXPECT_CALL((obs), OnBeginFrame(CreateBeginFrameArgsForTesting( \ - BEGINFRAME_FROM_HERE, frame_time, deadline, \ - interval))).InSequence((obs).sequence); \ - } - -#define EXPECT_BEGIN_FRAME_USED(obs, frame_time, deadline, interval) \ - { \ - BeginFrameArgs args = CreateBeginFrameArgsForTesting( \ - BEGINFRAME_FROM_HERE, frame_time, deadline, interval); \ - ::testing::Expectation exp = \ - EXPECT_CALL((obs), OnBeginFrame(args)).InSequence((obs).sequence); \ - EXPECT_CALL((obs), LastUsedBeginFrameArgs()) \ - .Times(::testing::AnyNumber()) \ - .After(exp) \ - .WillRepeatedly(::testing::Return(args)); \ - } - -// Macros to send BeginFrameArgs on a FakeBeginFrameSink (and verify resulting -// observer behaviour). -#define SEND_BEGIN_FRAME(args_equal_to, source, frame_time, deadline, \ - interval) \ - { \ - BeginFrameArgs old_args = (source).TestLastUsedBeginFrameArgs(); \ - BeginFrameArgs new_args = CreateBeginFrameArgsForTesting( \ - BEGINFRAME_FROM_HERE, frame_time, deadline, interval); \ - ASSERT_FALSE(old_args == new_args); \ - (source).TestOnBeginFrame(new_args); \ - EXPECT_EQ(args_equal_to, (source).TestLastUsedBeginFrameArgs()); \ - } - -// When dropping LastUsedBeginFrameArgs **shouldn't** change. -#define SEND_BEGIN_FRAME_DROP(source, frame_time, deadline, interval) \ - SEND_BEGIN_FRAME(old_args, source, frame_time, deadline, interval); - -// When used LastUsedBeginFrameArgs **should** be updated. -#define SEND_BEGIN_FRAME_USED(source, frame_time, deadline, interval) \ - SEND_BEGIN_FRAME(new_args, source, frame_time, deadline, interval); - namespace cc { namespace { -class MockBeginFrameObserver : public BeginFrameObserver { - public: - MOCK_METHOD1(OnBeginFrame, void(const BeginFrameArgs&)); - MOCK_CONST_METHOD0(LastUsedBeginFrameArgs, const BeginFrameArgs()); - - virtual void AsValueInto(base::trace_event::TracedValue* dict) const { - dict->SetString("type", "MockBeginFrameObserver"); - dict->BeginDictionary("last_begin_frame_args"); - LastUsedBeginFrameArgs().AsValueInto(dict); - dict->EndDictionary(); - } - - // A value different from the normal default returned by a BeginFrameObserver - // so it is easiable traced back here. - static const BeginFrameArgs kDefaultBeginFrameArgs; - - MockBeginFrameObserver() { - // Set a "default" value returned by LastUsedBeginFrameArgs so that gMock - // doesn't fail an assert and instead returns useful information. - EXPECT_CALL(*this, LastUsedBeginFrameArgs()) - .Times(::testing::AnyNumber()) - .InSequence(sequence) - .WillRepeatedly(::testing::Return(kDefaultBeginFrameArgs)); - } - virtual ~MockBeginFrameObserver() {} - - ::testing::Sequence sequence; -}; - -TEST(MockBeginFrameObserverTest, ExpectOnBeginFrame) { - ::testing::NiceMock<MockBeginFrameObserver> obs; - EXPECT_BEGIN_FRAME_USED(obs, 100, 200, 300); - EXPECT_BEGIN_FRAME_USED(obs, 400, 600, 300); - EXPECT_BEGIN_FRAME_USED(obs, 700, 900, 300); - - EXPECT_EQ(obs.LastUsedBeginFrameArgs(), - MockBeginFrameObserver::kDefaultBeginFrameArgs); - - obs.OnBeginFrame(CreateBeginFrameArgsForTesting( - BEGINFRAME_FROM_HERE, 100, 200, - 300)); // One call to LastUsedBeginFrameArgs - EXPECT_EQ( - obs.LastUsedBeginFrameArgs(), - CreateBeginFrameArgsForTesting(BEGINFRAME_FROM_HERE, 100, 200, 300)); - - obs.OnBeginFrame(CreateBeginFrameArgsForTesting( - BEGINFRAME_FROM_HERE, 400, 600, - 300)); // Multiple calls to LastUsedBeginFrameArgs - EXPECT_EQ( - obs.LastUsedBeginFrameArgs(), - CreateBeginFrameArgsForTesting(BEGINFRAME_FROM_HERE, 400, 600, 300)); - EXPECT_EQ( - obs.LastUsedBeginFrameArgs(), - CreateBeginFrameArgsForTesting(BEGINFRAME_FROM_HERE, 400, 600, 300)); - - obs.OnBeginFrame(CreateBeginFrameArgsForTesting( - BEGINFRAME_FROM_HERE, 700, 900, - 300)); // No calls to LastUsedBeginFrameArgs -} - -TEST(MockBeginFrameObserverTest, ExpectOnBeginFrameStatus) { - ::testing::NiceMock<MockBeginFrameObserver> obs; - EXPECT_BEGIN_FRAME_USED(obs, 100, 200, 300); - EXPECT_BEGIN_FRAME_DROP(obs, 400, 600, 300); - EXPECT_BEGIN_FRAME_DROP(obs, 450, 650, 300); - EXPECT_BEGIN_FRAME_USED(obs, 700, 900, 300); - - EXPECT_EQ(obs.LastUsedBeginFrameArgs(), - MockBeginFrameObserver::kDefaultBeginFrameArgs); - - // Used - obs.OnBeginFrame( - CreateBeginFrameArgsForTesting(BEGINFRAME_FROM_HERE, 100, 200, 300)); - EXPECT_EQ( - obs.LastUsedBeginFrameArgs(), - CreateBeginFrameArgsForTesting(BEGINFRAME_FROM_HERE, 100, 200, 300)); - - // Dropped - obs.OnBeginFrame( - CreateBeginFrameArgsForTesting(BEGINFRAME_FROM_HERE, 400, 600, 300)); - EXPECT_EQ( - obs.LastUsedBeginFrameArgs(), - CreateBeginFrameArgsForTesting(BEGINFRAME_FROM_HERE, 100, 200, 300)); - - // Dropped - obs.OnBeginFrame( - CreateBeginFrameArgsForTesting(BEGINFRAME_FROM_HERE, 450, 650, 300)); - EXPECT_EQ( - obs.LastUsedBeginFrameArgs(), - CreateBeginFrameArgsForTesting(BEGINFRAME_FROM_HERE, 100, 200, 300)); - - // Used - obs.OnBeginFrame( - CreateBeginFrameArgsForTesting(BEGINFRAME_FROM_HERE, 700, 900, 300)); - EXPECT_EQ( - obs.LastUsedBeginFrameArgs(), - CreateBeginFrameArgsForTesting(BEGINFRAME_FROM_HERE, 700, 900, 300)); -} - -const BeginFrameArgs MockBeginFrameObserver::kDefaultBeginFrameArgs = - CreateBeginFrameArgsForTesting( -#ifdef NDEBUG - nullptr, -#else - FROM_HERE_WITH_EXPLICIT_FUNCTION( - "MockBeginFrameObserver::kDefaultBeginFrameArgs"), -#endif - -1, - -1, - -1); - // BeginFrameObserverBase testing --------------------------------------- class MockMinimalBeginFrameObserverBase : public BeginFrameObserverBase { public:
diff --git a/cc/test/begin_frame_source_test.cc b/cc/test/begin_frame_source_test.cc new file mode 100644 index 0000000..ef1c033 --- /dev/null +++ b/cc/test/begin_frame_source_test.cc
@@ -0,0 +1,42 @@ +// 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. + +#include "cc/test/begin_frame_source_test.h" + +#include "cc/test/begin_frame_args_test.h" +#include "testing/gmock/include/gmock/gmock.h" +#include "testing/gtest/include/gtest/gtest.h" + +namespace cc { + +void MockBeginFrameObserver::AsValueInto( + base::trace_event::TracedValue* dict) const { + dict->SetString("type", "MockBeginFrameObserver"); + dict->BeginDictionary("last_begin_frame_args"); + last_begin_frame_args.AsValueInto(dict); + dict->EndDictionary(); +} + +MockBeginFrameObserver::MockBeginFrameObserver() + : last_begin_frame_args(kDefaultBeginFrameArgs) { + EXPECT_CALL(*this, LastUsedBeginFrameArgs()) + .Times(::testing::AnyNumber()) + .WillRepeatedly(::testing::ReturnPointee(&last_begin_frame_args)); +} + +MockBeginFrameObserver::~MockBeginFrameObserver() {} + +const BeginFrameArgs MockBeginFrameObserver::kDefaultBeginFrameArgs = + CreateBeginFrameArgsForTesting( +#ifdef NDEBUG + nullptr, +#else + FROM_HERE_WITH_EXPLICIT_FUNCTION( + "MockBeginFrameObserver::kDefaultBeginFrameArgs"), +#endif + -1, + -1, + -1); + +} // namespace cc
diff --git a/cc/test/begin_frame_source_test.h b/cc/test/begin_frame_source_test.h new file mode 100644 index 0000000..98f5d90f --- /dev/null +++ b/cc/test/begin_frame_source_test.h
@@ -0,0 +1,73 @@ +// 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. + +#ifndef CC_TEST_BEGIN_FRAME_SOURCE_TEST_H_ +#define CC_TEST_BEGIN_FRAME_SOURCE_TEST_H_ + +#include "base/basictypes.h" +#include "base/trace_event/trace_event_argument.h" +#include "cc/scheduler/begin_frame_source.h" +#include "cc/test/begin_frame_args_test.h" +#include "testing/gmock/include/gmock/gmock.h" +#include "testing/gtest/include/gtest/gtest.h" + +// Macros to help set up expected calls on the MockBeginFrameObserver. +#define EXPECT_BEGIN_FRAME_DROP(obs, frame_time, deadline, interval) \ + EXPECT_CALL((obs), \ + OnBeginFrame(CreateBeginFrameArgsForTesting( \ + BEGINFRAME_FROM_HERE, frame_time, deadline, interval))) \ + .Times(1) \ + .InSequence((obs).sequence) + +#define EXPECT_BEGIN_FRAME_USED(obs, frame_time, deadline, interval) \ + EXPECT_CALL((obs), \ + OnBeginFrame(CreateBeginFrameArgsForTesting( \ + BEGINFRAME_FROM_HERE, frame_time, deadline, interval))) \ + .InSequence((obs).sequence) \ + .WillOnce(::testing::SaveArg<0>(&((obs).last_begin_frame_args))) + +// Macros to send BeginFrameArgs on a FakeBeginFrameSink (and verify resulting +// observer behaviour). +#define SEND_BEGIN_FRAME(args_equal_to, source, frame_time, deadline, \ + interval) \ + { \ + BeginFrameArgs old_args = (source).TestLastUsedBeginFrameArgs(); \ + BeginFrameArgs new_args = CreateBeginFrameArgsForTesting( \ + BEGINFRAME_FROM_HERE, frame_time, deadline, interval); \ + ASSERT_FALSE(old_args == new_args); \ + (source).TestOnBeginFrame(new_args); \ + EXPECT_EQ(args_equal_to, (source).TestLastUsedBeginFrameArgs()); \ + } + +// When dropping LastUsedBeginFrameArgs **shouldn't** change. +#define SEND_BEGIN_FRAME_DROP(source, frame_time, deadline, interval) \ + SEND_BEGIN_FRAME(old_args, source, frame_time, deadline, interval); + +// When used LastUsedBeginFrameArgs **should** be updated. +#define SEND_BEGIN_FRAME_USED(source, frame_time, deadline, interval) \ + SEND_BEGIN_FRAME(new_args, source, frame_time, deadline, interval); + +namespace cc { + +class MockBeginFrameObserver : public BeginFrameObserver { + public: + MOCK_METHOD1(OnBeginFrame, void(const BeginFrameArgs&)); + MOCK_CONST_METHOD0(LastUsedBeginFrameArgs, const BeginFrameArgs()); + + virtual void AsValueInto(base::trace_event::TracedValue* dict) const; + + // A value different from the normal default returned by a BeginFrameObserver + // so it is easiable traced back here. + static const BeginFrameArgs kDefaultBeginFrameArgs; + + MockBeginFrameObserver(); + virtual ~MockBeginFrameObserver(); + + BeginFrameArgs last_begin_frame_args; + ::testing::Sequence sequence; +}; + +} // namespace cc + +#endif // CC_TEST_BEGIN_FRAME_SOURCE_TEST_H_
diff --git a/cc/test/begin_frame_source_test_unittest.cc b/cc/test/begin_frame_source_test_unittest.cc new file mode 100644 index 0000000..601da31 --- /dev/null +++ b/cc/test/begin_frame_source_test_unittest.cc
@@ -0,0 +1,124 @@ +// 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. + +#include "cc/test/begin_frame_source_test.h" + +#include "cc/test/begin_frame_args_test.h" +#include "cc/test/mock_helper.h" +#include "testing/gmock/include/gmock/gmock.h" +#include "testing/gtest/include/gtest/gtest.h" + +namespace cc { +namespace { +TEST(MockBeginFrameObserverTest, FailOnMissingCalls) { + EXPECT_MOCK_FAILURE({ + ::testing::NiceMock<MockBeginFrameObserver> obs; + EXPECT_BEGIN_FRAME_USED(obs, 100, 200, 300); + EXPECT_BEGIN_FRAME_USED(obs, 400, 600, 300); + + obs.OnBeginFrame( + CreateBeginFrameArgsForTesting(BEGINFRAME_FROM_HERE, 400, 600, 300)); + }); +} + +TEST(MockBeginFrameObserverTest, FailOnMultipleCalls) { + EXPECT_MOCK_FAILURE({ + ::testing::NiceMock<MockBeginFrameObserver> obs; + EXPECT_BEGIN_FRAME_USED(obs, 100, 200, 300); + EXPECT_BEGIN_FRAME_USED(obs, 400, 600, 300); + + obs.OnBeginFrame( + CreateBeginFrameArgsForTesting(BEGINFRAME_FROM_HERE, 100, 200, 300)); + obs.OnBeginFrame( + CreateBeginFrameArgsForTesting(BEGINFRAME_FROM_HERE, 100, 200, 300)); + obs.OnBeginFrame( + CreateBeginFrameArgsForTesting(BEGINFRAME_FROM_HERE, 400, 600, 300)); + }); +} + +TEST(MockBeginFrameObserverTest, FailOnWrongCallOrder) { + EXPECT_MOCK_FAILURE({ + ::testing::NiceMock<MockBeginFrameObserver> obs; + EXPECT_BEGIN_FRAME_USED(obs, 100, 200, 300); + EXPECT_BEGIN_FRAME_USED(obs, 400, 600, 300); + + obs.OnBeginFrame( + CreateBeginFrameArgsForTesting(BEGINFRAME_FROM_HERE, 400, 600, 300)); + obs.OnBeginFrame( + CreateBeginFrameArgsForTesting(BEGINFRAME_FROM_HERE, 100, 200, 300)); + }); +} + +TEST(MockBeginFrameObserverTest, ExpectOnBeginFrame) { + ::testing::NiceMock<MockBeginFrameObserver> obs; + EXPECT_BEGIN_FRAME_USED(obs, 100, 200, 300); + EXPECT_BEGIN_FRAME_USED(obs, 400, 600, 300); + EXPECT_BEGIN_FRAME_USED(obs, 700, 900, 300); + + EXPECT_EQ(obs.LastUsedBeginFrameArgs(), + MockBeginFrameObserver::kDefaultBeginFrameArgs); + + obs.OnBeginFrame(CreateBeginFrameArgsForTesting( + BEGINFRAME_FROM_HERE, 100, 200, + 300)); // One call to LastUsedBeginFrameArgs + EXPECT_EQ( + obs.LastUsedBeginFrameArgs(), + CreateBeginFrameArgsForTesting(BEGINFRAME_FROM_HERE, 100, 200, 300)); + + obs.OnBeginFrame(CreateBeginFrameArgsForTesting( + BEGINFRAME_FROM_HERE, 400, 600, + 300)); // Multiple calls to LastUsedBeginFrameArgs + EXPECT_EQ( + obs.LastUsedBeginFrameArgs(), + CreateBeginFrameArgsForTesting(BEGINFRAME_FROM_HERE, 400, 600, 300)); + EXPECT_EQ( + obs.LastUsedBeginFrameArgs(), + CreateBeginFrameArgsForTesting(BEGINFRAME_FROM_HERE, 400, 600, 300)); + + obs.OnBeginFrame(CreateBeginFrameArgsForTesting( + BEGINFRAME_FROM_HERE, 700, 900, + 300)); // No calls to LastUsedBeginFrameArgs +} + +TEST(MockBeginFrameObserverTest, ExpectOnBeginFrameStatus) { + ::testing::NiceMock<MockBeginFrameObserver> obs; + EXPECT_BEGIN_FRAME_USED(obs, 100, 200, 300); + EXPECT_BEGIN_FRAME_DROP(obs, 400, 600, 300); + EXPECT_BEGIN_FRAME_DROP(obs, 450, 650, 300); + EXPECT_BEGIN_FRAME_USED(obs, 700, 900, 300); + + EXPECT_EQ(obs.LastUsedBeginFrameArgs(), + MockBeginFrameObserver::kDefaultBeginFrameArgs); + + // Used + obs.OnBeginFrame( + CreateBeginFrameArgsForTesting(BEGINFRAME_FROM_HERE, 100, 200, 300)); + EXPECT_EQ( + obs.LastUsedBeginFrameArgs(), + CreateBeginFrameArgsForTesting(BEGINFRAME_FROM_HERE, 100, 200, 300)); + + // Dropped + obs.OnBeginFrame( + CreateBeginFrameArgsForTesting(BEGINFRAME_FROM_HERE, 400, 600, 300)); + EXPECT_EQ( + obs.LastUsedBeginFrameArgs(), + CreateBeginFrameArgsForTesting(BEGINFRAME_FROM_HERE, 100, 200, 300)); + + // Dropped + obs.OnBeginFrame( + CreateBeginFrameArgsForTesting(BEGINFRAME_FROM_HERE, 450, 650, 300)); + EXPECT_EQ( + obs.LastUsedBeginFrameArgs(), + CreateBeginFrameArgsForTesting(BEGINFRAME_FROM_HERE, 100, 200, 300)); + + // Used + obs.OnBeginFrame( + CreateBeginFrameArgsForTesting(BEGINFRAME_FROM_HERE, 700, 900, 300)); + EXPECT_EQ( + obs.LastUsedBeginFrameArgs(), + CreateBeginFrameArgsForTesting(BEGINFRAME_FROM_HERE, 700, 900, 300)); +} + +} // namespace +} // namespace cc
diff --git a/cc/test/layer_tree_host_common_test.cc b/cc/test/layer_tree_host_common_test.cc index 676dc08..c05716df7 100644 --- a/cc/test/layer_tree_host_common_test.cc +++ b/cc/test/layer_tree_host_common_test.cc
@@ -94,6 +94,10 @@ root_layer->layer_tree_host()->inner_viewport_scroll_layer(); Layer* outer_viewport_scroll_layer = root_layer->layer_tree_host()->outer_viewport_scroll_layer(); + const Layer* overscroll_elasticity_layer = + root_layer->layer_tree_host()->overscroll_elasticity_layer(); + gfx::Vector2dF elastic_overscroll = + root_layer->layer_tree_host()->elastic_overscroll(); float page_scale_factor = 1.f; float device_scale_factor = 1.f; gfx::Size device_viewport_size = @@ -101,7 +105,8 @@ root_layer->bounds().height() * device_scale_factor); BuildPropertyTreesAndComputeVisibleRects( root_layer, page_scale_layer, inner_viewport_scroll_layer, - outer_viewport_scroll_layer, page_scale_factor, device_scale_factor, + outer_viewport_scroll_layer, overscroll_elasticity_layer, + elastic_overscroll, page_scale_factor, device_scale_factor, gfx::Rect(device_viewport_size), identity_transform, can_render_to_separate_surface, root_layer->layer_tree_host()->property_trees(), &update_layer_list_); @@ -119,6 +124,11 @@ root_layer->layer_tree_impl()->InnerViewportScrollLayer(); LayerImpl* outer_viewport_scroll_layer = root_layer->layer_tree_impl()->OuterViewportScrollLayer(); + LayerImpl* overscroll_elasticity_layer = + root_layer->layer_tree_impl()->OverscrollElasticityLayer(); + gfx::Vector2dF elastic_overscroll = + root_layer->layer_tree_impl()->elastic_overscroll()->Current( + root_layer->layer_tree_impl()->IsActiveTree()); float page_scale_factor = 1.f; float device_scale_factor = 1.f; gfx::Size device_viewport_size = @@ -127,7 +137,8 @@ std::vector<LayerImpl*> update_layer_list; BuildPropertyTreesAndComputeVisibleRects( root_layer, page_scale_layer, inner_viewport_scroll_layer, - outer_viewport_scroll_layer, page_scale_factor, device_scale_factor, + outer_viewport_scroll_layer, overscroll_elasticity_layer, + elastic_overscroll, page_scale_factor, device_scale_factor, gfx::Rect(device_viewport_size), identity_transform, can_render_to_separate_surface, root_layer->layer_tree_impl()->property_trees(), &update_layer_list);
diff --git a/cc/test/mock_helper.h b/cc/test/mock_helper.h new file mode 100644 index 0000000..9ca9afba --- /dev/null +++ b/cc/test/mock_helper.h
@@ -0,0 +1,29 @@ +// 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. + +#ifndef CC_TEST_MOCK_HELPER_H_ +#define CC_TEST_MOCK_HELPER_H_ + +#include "testing/gmock/include/gmock/gmock.h" +#include "testing/gtest/include/gtest/gtest-spi.h" +#include "testing/gtest/include/gtest/gtest.h" + +#define EXPECT_MOCK_FAILURE(statement) \ + do { \ + class GTestExpectMockFailureHelper { \ + public: \ + static void Execute() { statement; } \ + }; \ + ::testing::TestPartResultArray gtest_failures; \ + { \ + ::testing::ScopedFakeTestPartResultReporter gtest_reporter( \ + ::testing::ScopedFakeTestPartResultReporter:: \ + INTERCEPT_ONLY_CURRENT_THREAD, \ + >est_failures); \ + GTestExpectMockFailureHelper::Execute(); \ + } \ + EXPECT_GT(gtest_failures.size(), 0); \ + } while (::testing::internal::AlwaysFalse()) + +#endif // CC_TEST_MOCK_HELPER_H_
diff --git a/cc/test/mock_helper_unittest.cc b/cc/test/mock_helper_unittest.cc new file mode 100644 index 0000000..d6b9898 --- /dev/null +++ b/cc/test/mock_helper_unittest.cc
@@ -0,0 +1,44 @@ +// 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. + +#include "cc/test/mock_helper.h" + +#include "testing/gtest/include/gtest/gtest-spi.h" + +namespace { +class TestingMock { + public: + MOCK_METHOD0(Test, void(void)); +}; + +TEST(ExpectMockFailureTest, FailsWhenNoMock) { + EXPECT_NONFATAL_FAILURE({ EXPECT_MOCK_FAILURE({ ; }); }, ""); +} + +TEST(ExpectMockFailureTest, FailsWhenMockSucceeds) { + EXPECT_NONFATAL_FAILURE({ + EXPECT_MOCK_FAILURE({ + ::testing::NiceMock<TestingMock> t1; + EXPECT_CALL(t1, Test()); + + t1.Test(); + }); + }, ""); +} + +TEST(ExpectMockFailureTest, PassesWhenMockFailsForMissing) { + EXPECT_MOCK_FAILURE({ + ::testing::NiceMock<TestingMock> t1; + EXPECT_CALL(t1, Test()); + }); +} + +TEST(ExpectMockFailureTest, PassesWhenMockFailsForUnexpected) { + EXPECT_MOCK_FAILURE({ + ::testing::StrictMock<TestingMock> t1; + t1.Test(); + }); +} + +} // namespace
diff --git a/cc/tiles/tile_manager_unittest.cc b/cc/tiles/tile_manager_unittest.cc index 795118f..2c69999b 100644 --- a/cc/tiles/tile_manager_unittest.cc +++ b/cc/tiles/tile_manager_unittest.cc
@@ -1730,7 +1730,7 @@ // Just call CompleteOnOriginThread on each item in the queue. As none of // these items have run yet, they will be treated as cancelled tasks. for (const auto& node : graph->nodes) { - static_cast<RasterTask*>(node.task)->CompleteOnOriginThread(this); + static_cast<TileTask*>(node.task)->CompleteOnOriginThread(this); } } }; @@ -1805,7 +1805,7 @@ void ScheduleTasks(TaskGraph* graph) override { for (const auto& node : graph->nodes) { - RasterTask* task = static_cast<RasterTask*>(node.task); + TileTask* task = static_cast<TileTask*>(node.task); // Triggers a call to AcquireBufferForRaster. task->ScheduleOnOriginThread(this); // Calls TileManager as though task was cancelled.
diff --git a/cc/trees/draw_property_utils.cc b/cc/trees/draw_property_utils.cc index 326e507..971888dc 100644 --- a/cc/trees/draw_property_utils.cc +++ b/cc/trees/draw_property_utils.cc
@@ -634,6 +634,8 @@ const Layer* page_scale_layer, const Layer* inner_viewport_scroll_layer, const Layer* outer_viewport_scroll_layer, + const Layer* overscroll_elasticity_layer, + const gfx::Vector2dF& elastic_overscroll, float page_scale_factor, float device_scale_factor, const gfx::Rect& viewport, @@ -643,8 +645,9 @@ LayerList* update_layer_list) { PropertyTreeBuilder::BuildPropertyTrees( root_layer, page_scale_layer, inner_viewport_scroll_layer, - outer_viewport_scroll_layer, page_scale_factor, device_scale_factor, - viewport, device_transform, property_trees); + outer_viewport_scroll_layer, overscroll_elasticity_layer, + elastic_overscroll, page_scale_factor, device_scale_factor, viewport, + device_transform, property_trees); ComputeVisibleRectsUsingPropertyTrees(root_layer, property_trees, can_render_to_separate_surface, update_layer_list); @@ -655,6 +658,8 @@ const LayerImpl* page_scale_layer, const LayerImpl* inner_viewport_scroll_layer, const LayerImpl* outer_viewport_scroll_layer, + const LayerImpl* overscroll_elasticity_layer, + const gfx::Vector2dF& elastic_overscroll, float page_scale_factor, float device_scale_factor, const gfx::Rect& viewport, @@ -664,8 +669,9 @@ LayerImplList* visible_layer_list) { PropertyTreeBuilder::BuildPropertyTrees( root_layer, page_scale_layer, inner_viewport_scroll_layer, - outer_viewport_scroll_layer, page_scale_factor, device_scale_factor, - viewport, device_transform, property_trees); + outer_viewport_scroll_layer, overscroll_elasticity_layer, + elastic_overscroll, page_scale_factor, device_scale_factor, viewport, + device_transform, property_trees); ComputeVisibleRectsUsingPropertyTrees(root_layer, property_trees, can_render_to_separate_surface, visible_layer_list); @@ -1077,4 +1083,40 @@ device_transform); } +template <typename LayerType> +static void UpdateElasticOverscrollInPropertyTreesInternal( + PropertyTrees* property_trees, + const LayerType* overscroll_elasticity_layer, + const gfx::Vector2dF& elastic_overscroll) { + if (!overscroll_elasticity_layer) { + DCHECK(elastic_overscroll.IsZero()); + return; + } + + TransformNode* node = property_trees->transform_tree.Node( + overscroll_elasticity_layer->transform_tree_index()); + if (node->data.scroll_offset == gfx::ScrollOffset(elastic_overscroll)) + return; + + node->data.scroll_offset = gfx::ScrollOffset(elastic_overscroll); + node->data.needs_local_transform_update = true; + property_trees->transform_tree.set_needs_update(true); +} + +void UpdateElasticOverscrollInPropertyTrees( + PropertyTrees* property_trees, + const LayerImpl* overscroll_elasticity_layer, + const gfx::Vector2dF& elastic_overscroll) { + UpdateElasticOverscrollInPropertyTreesInternal( + property_trees, overscroll_elasticity_layer, elastic_overscroll); +} + +void UpdateElasticOverscrollInPropertyTrees( + PropertyTrees* property_trees, + const Layer* overscroll_elasticity_layer, + const gfx::Vector2dF& elastic_overscroll) { + UpdateElasticOverscrollInPropertyTreesInternal( + property_trees, overscroll_elasticity_layer, elastic_overscroll); +} + } // namespace cc
diff --git a/cc/trees/draw_property_utils.h b/cc/trees/draw_property_utils.h index 5c99458..72d9337 100644 --- a/cc/trees/draw_property_utils.h +++ b/cc/trees/draw_property_utils.h
@@ -11,6 +11,7 @@ namespace gfx { class Rect; class Transform; +class Vector2dF; } // namespace gfx namespace cc { @@ -46,6 +47,8 @@ const Layer* page_scale_layer, const Layer* inner_viewport_scroll_layer, const Layer* outer_viewport_scroll_layer, + const Layer* overscroll_elasticity_layer, + const gfx::Vector2dF& elastic_overscroll, float page_scale_factor, float device_scale_factor, const gfx::Rect& viewport, @@ -59,6 +62,8 @@ const LayerImpl* page_scale_layer, const LayerImpl* inner_viewport_scroll_layer, const LayerImpl* outer_viewport_scroll_layer, + const LayerImpl* overscroll_elasticity_layer, + const gfx::Vector2dF& elastic_overscroll, float page_scale_factor, float device_scale_factor, const gfx::Rect& viewport, @@ -123,6 +128,17 @@ float page_scale_factor, float device_scale_factor, const gfx::Transform device_transform); + +void CC_EXPORT UpdateElasticOverscrollInPropertyTrees( + PropertyTrees* property_trees, + const LayerImpl* overscroll_elasticity_layer, + const gfx::Vector2dF& elastic_overscroll); + +void CC_EXPORT UpdateElasticOverscrollInPropertyTrees( + PropertyTrees* property_trees, + const Layer* overscroll_elasticity_layer, + const gfx::Vector2dF& elastic_overscroll); + } // namespace cc #endif // CC_TREES_DRAW_PROPERTY_UTILS_H_
diff --git a/cc/trees/layer_tree_host.cc b/cc/trees/layer_tree_host.cc index 338bb36..4152b4d 100644 --- a/cc/trees/layer_tree_host.cc +++ b/cc/trees/layer_tree_host.cc
@@ -795,10 +795,10 @@ "LayerTreeHostCommon::ComputeVisibleRectsWithPropertyTrees"); BuildPropertyTreesAndComputeVisibleRects( root_layer, page_scale_layer, inner_viewport_scroll_layer_.get(), - outer_viewport_scroll_layer_.get(), page_scale_factor_, - device_scale_factor_, gfx::Rect(device_viewport_size_), - identity_transform, can_render_to_separate_surface, &property_trees_, - &update_layer_list); + outer_viewport_scroll_layer_.get(), overscroll_elasticity_layer_.get(), + elastic_overscroll_, page_scale_factor_, device_scale_factor_, + gfx::Rect(device_viewport_size_), identity_transform, + can_render_to_separate_surface, &property_trees_, &update_layer_list); } for (const auto& layer : update_layer_list)
diff --git a/cc/trees/layer_tree_host_common.cc b/cc/trees/layer_tree_host_common.cc index 172b01e..9ab91f03 100644 --- a/cc/trees/layer_tree_host_common.cc +++ b/cc/trees/layer_tree_host_common.cc
@@ -2766,7 +2766,9 @@ BuildPropertyTreesAndComputeVisibleRects( inputs->root_layer, inputs->page_scale_layer, inputs->inner_viewport_scroll_layer, - inputs->outer_viewport_scroll_layer, inputs->page_scale_factor, + inputs->outer_viewport_scroll_layer, + inputs->elastic_overscroll_application_layer, + inputs->elastic_overscroll, inputs->page_scale_factor, inputs->device_scale_factor, gfx::Rect(inputs->device_viewport_size), inputs->device_transform, inputs->can_render_to_separate_surface, inputs->property_trees, @@ -2791,14 +2793,18 @@ TRACE_EVENT0( TRACE_DISABLED_BY_DEFAULT("cc.debug.cdp-perf"), "LayerTreeHostCommon::ComputeJustVisibleRectsWithPropertyTrees"); - // Since page scale is a SyncedProperty, changes to page scale on the - // active tree immediately affect the pending tree, so instead of - // trying to update property trees whenever page scale changes, we - // update their page scale before using them. + // Since page scale and elastic overscroll are SyncedProperties, changes + // on the active tree immediately affect the pending tree, so instead of + // trying to update property trees whenever these values change, we + // update property trees before using them. UpdatePageScaleFactorInPropertyTrees( inputs->property_trees, inputs->page_scale_layer, inputs->page_scale_factor, inputs->device_scale_factor, inputs->device_transform); + UpdateElasticOverscrollInPropertyTrees( + inputs->property_trees, + inputs->elastic_overscroll_application_layer, + inputs->elastic_overscroll); // Similarly, the device viewport and device transform are shared // by both trees. inputs->property_trees->clip_tree.SetViewportClip( @@ -2866,9 +2872,12 @@ gfx::Transform(), false); PropertyTrees* property_trees = inputs->root_layer->layer_tree_host()->property_trees(); + Layer* overscroll_elasticity_layer = nullptr; + gfx::Vector2dF elastic_overscroll; BuildPropertyTreesAndComputeVisibleRects( inputs->root_layer, inputs->page_scale_layer, inputs->inner_viewport_scroll_layer, inputs->outer_viewport_scroll_layer, + overscroll_elasticity_layer, elastic_overscroll, inputs->page_scale_factor, inputs->device_scale_factor, gfx::Rect(inputs->device_viewport_size), inputs->device_transform, can_render_to_separate_surface, property_trees, &update_layer_list);
diff --git a/cc/trees/layer_tree_host_impl.cc b/cc/trees/layer_tree_host_impl.cc index fdf32f0..4ab2028 100644 --- a/cc/trees/layer_tree_host_impl.cc +++ b/cc/trees/layer_tree_host_impl.cc
@@ -1070,6 +1070,14 @@ // trigger this DCHECK. DCHECK(!have_copy_request || draw_result == DRAW_SUCCESS); + // TODO(crbug.com/564832): This workaround to prevent creating unnecessarily + // persistent render passes. When a copy request is made, it may force a + // separate render pass for the layer, which will persist until a new commit + // removes it. Force a commit after copy requests, to remove extra render + // passes. + if (have_copy_request) + client_->SetNeedsCommitOnImplThread(); + return draw_result; }
diff --git a/cc/trees/layer_tree_host_unittest.cc b/cc/trees/layer_tree_host_unittest.cc index 152b873..a68cb02 100644 --- a/cc/trees/layer_tree_host_unittest.cc +++ b/cc/trees/layer_tree_host_unittest.cc
@@ -13,6 +13,7 @@ #include "base/thread_task_runner_handle.h" #include "cc/animation/timing_function.h" #include "cc/debug/frame_rate_counter.h" +#include "cc/input/scroll_elasticity_helper.h" #include "cc/layers/content_layer_client.h" #include "cc/layers/io_surface_layer.h" #include "cc/layers/layer_impl.h" @@ -3846,6 +3847,105 @@ MULTI_THREAD_TEST_F(LayerTreeHostTestUpdateLayerInEmptyViewport); +class LayerTreeHostTestElasticOverscroll : public LayerTreeHostTest { + public: + LayerTreeHostTestElasticOverscroll() + : scroll_elasticity_helper_(nullptr), num_draws_(0) {} + + void InitializeSettings(LayerTreeSettings* settings) override { + settings->enable_elastic_overscroll = true; + } + + void SetupTree() override { + root_layer_ = Layer::Create(layer_settings()); + root_layer_->SetBounds(gfx::Size(10, 10)); + + scoped_refptr<Layer> inner_viewport_container_layer = + Layer::Create(layer_settings()); + inner_viewport_container_layer->SetBounds(gfx::Size(10, 10)); + scoped_refptr<Layer> overscroll_elasticity_layer = + Layer::Create(layer_settings()); + scoped_refptr<Layer> page_scale_layer = Layer::Create(layer_settings()); + scoped_refptr<Layer> inner_viewport_scroll_layer = + Layer::Create(layer_settings()); + inner_viewport_scroll_layer->SetScrollClipLayerId( + inner_viewport_container_layer->id()); + inner_viewport_scroll_layer->SetIsContainerForFixedPositionLayers(true); + + root_layer_->AddChild(inner_viewport_container_layer); + inner_viewport_container_layer->AddChild(overscroll_elasticity_layer); + overscroll_elasticity_layer->AddChild(page_scale_layer); + page_scale_layer->AddChild(inner_viewport_scroll_layer); + + scoped_refptr<Layer> content_layer = + FakePictureLayer::Create(layer_settings(), &client_); + content_layer->SetBounds(gfx::Size(10, 10)); + inner_viewport_scroll_layer->AddChild(content_layer); + + layer_tree_host()->SetRootLayer(root_layer_); + layer_tree_host()->RegisterViewportLayers( + overscroll_elasticity_layer, page_scale_layer, + inner_viewport_scroll_layer, nullptr); + LayerTreeHostTest::SetupTree(); + client_.set_bounds(content_layer->bounds()); + } + + void BeginTest() override { PostSetNeedsCommitToMainThread(); } + + void CommitCompleteOnThread(LayerTreeHostImpl* host_impl) override { + if (host_impl->sync_tree()->source_frame_number() == 0) { + scroll_elasticity_helper_ = host_impl->CreateScrollElasticityHelper(); + } + } + + void DrawLayersOnThread(LayerTreeHostImpl* host_impl) override { + num_draws_++; + LayerImpl* content_layer_impl = host_impl->active_tree() + ->InnerViewportScrollLayer() + ->children()[0] + .get(); + gfx::Transform expected_draw_transform; + switch (num_draws_) { + case 1: + // Initially, there's no overscroll. + EXPECT_EQ(expected_draw_transform, content_layer_impl->DrawTransform()); + + // Begin overscrolling. This should be reflected in the draw transform + // the next time we draw. + scroll_elasticity_helper_->SetStretchAmount(gfx::Vector2dF(5.f, 6.f)); + break; + case 2: + expected_draw_transform.Translate(-5.0, -6.0); + EXPECT_EQ(expected_draw_transform, content_layer_impl->DrawTransform()); + + scroll_elasticity_helper_->SetStretchAmount(gfx::Vector2dF(3.f, 2.f)); + break; + case 3: + expected_draw_transform.Translate(-3.0, -2.0); + EXPECT_EQ(expected_draw_transform, content_layer_impl->DrawTransform()); + + scroll_elasticity_helper_->SetStretchAmount(gfx::Vector2dF()); + break; + case 4: + EXPECT_EQ(expected_draw_transform, content_layer_impl->DrawTransform()); + EndTest(); + break; + default: + NOTREACHED(); + } + } + + void AfterTest() override {} + + private: + FakeContentLayerClient client_; + scoped_refptr<Layer> root_layer_; + ScrollElasticityHelper* scroll_elasticity_helper_; + int num_draws_; +}; + +MULTI_THREAD_TEST_F(LayerTreeHostTestElasticOverscroll); + class LayerTreeHostTestSetMemoryPolicyOnLostOutputSurface : public LayerTreeHostTest { protected:
diff --git a/cc/trees/layer_tree_host_unittest_copyrequest.cc b/cc/trees/layer_tree_host_unittest_copyrequest.cc index 86c7dc28..c2171a96 100644 --- a/cc/trees/layer_tree_host_unittest_copyrequest.cc +++ b/cc/trees/layer_tree_host_unittest_copyrequest.cc
@@ -41,7 +41,7 @@ void BeginTest() override { PostSetNeedsCommitToMainThread(); } - void DidCommitAndDrawFrame() override { WaitForCallback(); } + void DidCommit() override { WaitForCallback(); } void WaitForCallback() { base::MessageLoop::current()->PostTask( @@ -61,6 +61,9 @@ EXPECT_EQ(0u, callbacks_.size()); break; case 2: + // This commit is triggered by the copy request having been completed. + break; + case 3: if (callbacks_.size() < 1u) { WaitForCallback(); return; @@ -82,7 +85,10 @@ base::Unretained(this), 3))); EXPECT_EQ(1u, callbacks_.size()); break; - case 3: + case 4: + // This commit is triggered by the copy request having been completed. + break; + case 5: if (callbacks_.size() < 4u) { WaitForCallback(); return; @@ -175,6 +181,66 @@ RunTest(true, false); } +// TODO(crbug.com/564832): Remove this test when the workaround it tests is no +// longer needed. +class LayerTreeHostCopyRequestCompletionCausesCommit + : public LayerTreeHostCopyRequestTest { + protected: + void SetupTree() override { + root_ = FakePictureLayer::Create(layer_settings(), &client_); + root_->SetBounds(gfx::Size(20, 20)); + + layer_ = FakePictureLayer::Create(layer_settings(), &client_); + layer_->SetBounds(gfx::Size(15, 15)); + root_->AddChild(layer_); + + layer_tree_host()->SetRootLayer(root_); + LayerTreeHostCopyRequestTest::SetupTree(); + client_.set_bounds(root_->bounds()); + } + + void BeginTest() override { + callback_count_ = 0; + PostSetNeedsCommitToMainThread(); + } + + void DidCommit() override { + int frame = layer_tree_host()->source_frame_number(); + switch (frame) { + case 1: + layer_->RequestCopyOfOutput(CopyOutputRequest::CreateBitmapRequest( + base::Bind(&LayerTreeHostCopyRequestCompletionCausesCommit:: + CopyOutputCallback, + base::Unretained(this)))); + EXPECT_EQ(0, callback_count_); + break; + case 2: + // This commit was triggered by the copy request. + break; + case 3: + // This commit was triggered by the completion of the copy request. + EXPECT_EQ(1, callback_count_); + EndTest(); + break; + } + } + + void CopyOutputCallback(scoped_ptr<CopyOutputResult> result) { + EXPECT_FALSE(result->IsEmpty()); + ++callback_count_; + } + + void AfterTest() override {} + + int callback_count_; + FakeContentLayerClient client_; + scoped_refptr<FakePictureLayer> root_; + scoped_refptr<FakePictureLayer> layer_; +}; + +SINGLE_AND_MULTI_THREAD_DIRECT_RENDERER_TEST_F( + LayerTreeHostCopyRequestCompletionCausesCommit); + class LayerTreeHostCopyRequestTestLayerDestroyed : public LayerTreeHostCopyRequestTest { protected: @@ -427,8 +493,14 @@ // |copy_layer| should have been rendered to a texture since it was needed // for a copy request. - EXPECT_TRUE(renderer->HasAllocatedResourcesForTesting( - copy_layer->render_surface()->GetRenderPassId())); + if (did_draw_) { + // TODO(crbug.com/564832): Ignore the extra frame that occurs due to copy + // completion. This can be removed when the extra commit is removed. + EXPECT_FALSE(copy_layer->render_surface()); + } else { + EXPECT_TRUE(renderer->HasAllocatedResourcesForTesting( + copy_layer->render_surface()->GetRenderPassId())); + } did_draw_ = true; } @@ -795,7 +867,7 @@ virtual void RequestCopy(Layer* layer) = 0; - void DidCommitAndDrawFrame() override { + void DidCommit() override { switch (layer_tree_host()->source_frame_number()) { case 1: // The layers have been pushed to the impl side. The layer textures have @@ -1100,7 +1172,7 @@ PostSetNeedsCommitToMainThread(); } - void DidCommitAndDrawFrame() override { + void DidCommit() override { // Send a copy request after the first commit. if (layer_tree_host()->source_frame_number() == 1) { child_->RequestCopyOfOutput(
diff --git a/cc/trees/layer_tree_impl.cc b/cc/trees/layer_tree_impl.cc index 02583d2..f7fee78 100644 --- a/cc/trees/layer_tree_impl.cc +++ b/cc/trees/layer_tree_impl.cc
@@ -789,9 +789,11 @@ LayerTreeHostCommon::PreCalculateMetaInformationForTesting(root_layer_.get()); PropertyTreeBuilder::BuildPropertyTrees( root_layer_.get(), PageScaleLayer(), InnerViewportScrollLayer(), - OuterViewportScrollLayer(), current_page_scale_factor(), - device_scale_factor(), gfx::Rect(DrawViewportSize()), - layer_tree_host_impl_->DrawTransform(), &property_trees_); + OuterViewportScrollLayer(), OverscrollElasticityLayer(), + elastic_overscroll()->Current(IsActiveTree()), + current_page_scale_factor(), device_scale_factor(), + gfx::Rect(DrawViewportSize()), layer_tree_host_impl_->DrawTransform(), + &property_trees_); } void LayerTreeImpl::IncrementRenderSurfaceListIdForTesting() {
diff --git a/cc/trees/property_tree_builder.cc b/cc/trees/property_tree_builder.cc index 8bdf7e4..8763b91 100644 --- a/cc/trees/property_tree_builder.cc +++ b/cc/trees/property_tree_builder.cc
@@ -37,6 +37,8 @@ const LayerType* page_scale_layer; const LayerType* inner_viewport_scroll_layer; const LayerType* outer_viewport_scroll_layer; + const LayerType* overscroll_elasticity_layer; + gfx::Vector2dF elastic_overscroll; float page_scale_factor; bool in_subtree_of_page_scale_layer; bool affected_by_inner_viewport_bounds_delta; @@ -213,6 +215,8 @@ DataForRecursion<LayerType>* data_for_children) { const bool is_root = !layer->parent(); const bool is_page_scale_layer = layer == data_from_ancestor.page_scale_layer; + const bool is_overscroll_elasticity_layer = + layer == data_from_ancestor.overscroll_elasticity_layer; const bool is_scrollable = layer->scrollable(); const bool is_fixed = layer->position_constraint().is_fixed_position(); @@ -233,7 +237,7 @@ bool requires_node = is_root || is_scrollable || has_significant_transform || has_any_transform_animation || has_surface || is_fixed || - is_page_scale_layer; + is_page_scale_layer || is_overscroll_elasticity_layer; LayerType* transform_parent = GetTransformParent(data_from_ancestor, layer); DCHECK(is_root || transform_parent); @@ -365,8 +369,13 @@ layer->transform_origin()); } - if (!layer->scroll_parent()) + if (is_overscroll_elasticity_layer) { + DCHECK(!is_scrollable); + node->data.scroll_offset = + gfx::ScrollOffset(data_from_ancestor.elastic_overscroll); + } else if (!layer->scroll_parent()) { node->data.scroll_offset = layer->CurrentScrollOffset(); + } if (is_fixed) { if (data_from_ancestor.affected_by_inner_viewport_bounds_delta) { @@ -526,6 +535,8 @@ const LayerType* page_scale_layer, const LayerType* inner_viewport_scroll_layer, const LayerType* outer_viewport_scroll_layer, + const LayerType* overscroll_elasticity_layer, + const gfx::Vector2dF& elastic_overscroll, float page_scale_factor, float device_scale_factor, const gfx::Rect& viewport, @@ -535,6 +546,8 @@ UpdatePageScaleFactorInPropertyTrees(property_trees, page_scale_layer, page_scale_factor, device_scale_factor, device_transform); + UpdateElasticOverscrollInPropertyTrees( + property_trees, overscroll_elasticity_layer, elastic_overscroll); property_trees->clip_tree.SetViewportClip(gfx::RectF(viewport)); property_trees->transform_tree.SetDeviceTransform(device_transform, root_layer->position()); @@ -555,6 +568,8 @@ data_for_recursion.page_scale_layer = page_scale_layer; data_for_recursion.inner_viewport_scroll_layer = inner_viewport_scroll_layer; data_for_recursion.outer_viewport_scroll_layer = outer_viewport_scroll_layer; + data_for_recursion.overscroll_elasticity_layer = overscroll_elasticity_layer; + data_for_recursion.elastic_overscroll = elastic_overscroll; data_for_recursion.page_scale_factor = page_scale_factor; data_for_recursion.in_subtree_of_page_scale_layer = false; data_for_recursion.affected_by_inner_viewport_bounds_delta = false; @@ -593,6 +608,8 @@ const Layer* page_scale_layer, const Layer* inner_viewport_scroll_layer, const Layer* outer_viewport_scroll_layer, + const Layer* overscroll_elasticity_layer, + const gfx::Vector2dF& elastic_overscroll, float page_scale_factor, float device_scale_factor, const gfx::Rect& viewport, @@ -600,8 +617,9 @@ PropertyTrees* property_trees) { BuildPropertyTreesTopLevelInternal( root_layer, page_scale_layer, inner_viewport_scroll_layer, - outer_viewport_scroll_layer, page_scale_factor, device_scale_factor, - viewport, device_transform, property_trees); + outer_viewport_scroll_layer, overscroll_elasticity_layer, + elastic_overscroll, page_scale_factor, device_scale_factor, viewport, + device_transform, property_trees); } void PropertyTreeBuilder::BuildPropertyTrees( @@ -609,6 +627,8 @@ const LayerImpl* page_scale_layer, const LayerImpl* inner_viewport_scroll_layer, const LayerImpl* outer_viewport_scroll_layer, + const LayerImpl* overscroll_elasticity_layer, + const gfx::Vector2dF& elastic_overscroll, float page_scale_factor, float device_scale_factor, const gfx::Rect& viewport, @@ -616,8 +636,9 @@ PropertyTrees* property_trees) { BuildPropertyTreesTopLevelInternal( root_layer, page_scale_layer, inner_viewport_scroll_layer, - outer_viewport_scroll_layer, page_scale_factor, device_scale_factor, - viewport, device_transform, property_trees); + outer_viewport_scroll_layer, overscroll_elasticity_layer, + elastic_overscroll, page_scale_factor, device_scale_factor, viewport, + device_transform, property_trees); } } // namespace cc
diff --git a/cc/trees/property_tree_builder.h b/cc/trees/property_tree_builder.h index a6cc52b4..23d7e1c 100644 --- a/cc/trees/property_tree_builder.h +++ b/cc/trees/property_tree_builder.h
@@ -20,6 +20,8 @@ const Layer* page_scale_layer, const Layer* inner_viewport_scroll_layer, const Layer* outer_viewport_scroll_layer, + const Layer* overscroll_elasticity_layer, + const gfx::Vector2dF& elastic_overscroll, float page_scale_factor, float device_scale_factor, const gfx::Rect& viewport, @@ -29,6 +31,8 @@ const LayerImpl* page_scale_layer, const LayerImpl* inner_viewport_scroll_layer, const LayerImpl* outer_viewport_scroll_layer, + const LayerImpl* overscroll_elasticity_layer, + const gfx::Vector2dF& elastic_overscroll, float page_scale_factor, float device_scale_factor, const gfx::Rect& viewport,
diff --git a/chrome/BUILD.gn b/chrome/BUILD.gn index efb7dc6..462e318 100644 --- a/chrome/BUILD.gn +++ b/chrome/BUILD.gn
@@ -405,8 +405,6 @@ shared_library("chrome_child") { sources = [ - "app/chrome_crash_reporter_client.cc", - "app/chrome_crash_reporter_client.h", "app/chrome_main.cc", "app/chrome_main_delegate.cc", "app/chrome_main_delegate.h",
diff --git a/chrome/VERSION b/chrome/VERSION index b2e8716..38e2fd6 100644 --- a/chrome/VERSION +++ b/chrome/VERSION
@@ -1,4 +1,4 @@ MAJOR=49 MINOR=0 -BUILD=2581 +BUILD=2584 PATCH=0
diff --git a/chrome/android/BUILD.gn b/chrome/android/BUILD.gn index 9de720c9..3ae8926 100644 --- a/chrome/android/BUILD.gn +++ b/chrome/android/BUILD.gn
@@ -6,6 +6,7 @@ import("//build/config/android/rules.gni") import("//build_overrides/v8.gni") import("//chrome/android/chrome_public_apk_tmpl.gni") +import("//chrome/common/features.gni") import("//chrome/version.gni") import("//testing/test.gni") import("//third_party/icu/config.gni") @@ -128,29 +129,14 @@ # GYP: //chrome/chrome.gyp:chrome_java android_library("chrome_java") { deps = [ - ":chrome_java_resources", - ":document_tab_model_info_proto_java", "//base:base_java", - "//components/bookmarks/common/android:bookmarks_java", - "//components/dom_distiller/android:dom_distiller_content_java", - "//components/dom_distiller/android:dom_distiller_core_java", - "//components/gcm_driver/android:gcm_driver_java", - "//components/invalidation/impl:java", - "//components/navigation_interception/android:navigation_interception_java", - "//components/policy/android:policy_java", - "//components/precache/android:precache_java", "//components/safe_json/android:safe_json_java", - "//components/service_tab_launcher:service_tab_launcher_java", - "//components/signin/core/browser/android:java", "//components/variations/android:variations_java", - "//components/web_contents_delegate_android:web_contents_delegate_android_java", "//content/public/android:content_java", "//media/base/android:media_java", - "//media/base/android:media_java", "//media/midi:midi_java", "//net/android:net_java", "//printing:printing_java", - "//sync/android:sync_java", "//third_party/WebKit/public:blink_headers_java", "//third_party/android_data_chart:android_data_chart_java", "//third_party/android_media:android_media_java", @@ -175,17 +161,41 @@ ":chrome_android_java_enums_srcjar", ":chrome_android_java_google_api_keys_srcjar", ":chrome_version_srcjar", - ":custom_tabs_service_aidl", ":resource_id_javagen", - "//chrome:page_info_connection_type_javagen", "//chrome:content_setting_javagen", "//chrome:content_settings_type_javagen", - "//components/enhanced_bookmarks:enhanced_bookmarks_java_enums_srcjar", - "//components/offline_pages:offline_pages_enums_java", - "//components/omnibox/browser:autocomplete_match_type_javagen", ] - DEPRECATED_java_in_dir = "java/src" + # TODO(sievers): Split java code into components. Not everything + # is really all that UI related here. + if (android_java_ui) { + DEPRECATED_java_in_dir = "java/src" + + srcjar_deps += [ + ":custom_tabs_service_aidl", + "//chrome:page_info_connection_type_javagen", + "//components/enhanced_bookmarks:enhanced_bookmarks_java_enums_srcjar", + "//components/offline_pages:offline_pages_enums_java", + "//components/omnibox/browser:autocomplete_match_type_javagen", + ] + + deps += [ + ":chrome_java_resources", + ":document_tab_model_info_proto_java", + "//components/bookmarks/common/android:bookmarks_java", + "//components/dom_distiller/android:dom_distiller_content_java", + "//components/dom_distiller/android:dom_distiller_core_java", + "//components/gcm_driver/android:gcm_driver_java", + "//components/invalidation/impl:java", + "//components/navigation_interception/android:navigation_interception_java", + "//components/policy/android:policy_java", + "//components/precache/android:precache_java", + "//components/service_tab_launcher:service_tab_launcher_java", + "//components/signin/core/browser/android:java", + "//components/web_contents_delegate_android:web_contents_delegate_android_java", + "//sync/android:sync_java", + ] + } } # GYP: //chrome/chrome_browser.gypi:activity_type_ids_java
diff --git a/chrome/android/chrome_apk_version.gni b/chrome/android/chrome_apk_version.gni new file mode 100644 index 0000000..98401aa --- /dev/null +++ b/chrome/android/chrome_apk_version.gni
@@ -0,0 +1,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. + +declare_args() { + chrome_apk_version_code = "1" + chrome_apk_version_name = "Developer Build" +}
diff --git a/chrome/android/java/res/drawable/most_visited_item_bg.xml b/chrome/android/java/res/drawable/most_visited_item_bg.xml deleted file mode 100644 index 1799b6ff..0000000 --- a/chrome/android/java/res/drawable/most_visited_item_bg.xml +++ /dev/null
@@ -1,10 +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. --> - -<shape xmlns:android="http://schemas.android.com/apk/res/android" - android:shape="rectangle"> - <solid android:color="@color/ntp_most_visited_bg" /> - <corners android:radius="@dimen/most_visited_bg_corner_radius" /> -</shape>
diff --git a/chrome/android/java/res/drawable/most_visited_item_empty.xml b/chrome/android/java/res/drawable/most_visited_item_empty.xml deleted file mode 100644 index 3b9555c7..0000000 --- a/chrome/android/java/res/drawable/most_visited_item_empty.xml +++ /dev/null
@@ -1,28 +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. --> - -<!-- A blank most visited item, for display on the new tab page. --> -<layer-list xmlns:android="http://schemas.android.com/apk/res/android" > - - <item> - <shape android:shape="rectangle"> - <solid android:color="@color/ntp_most_visited_bg" /> - <corners android:radius="@dimen/most_visited_bg_corner_radius" /> - </shape> - </item> - - <item> - <inset - android:insetTop="4dp" - android:insetRight="4dp" - android:insetBottom="4dp" - android:insetLeft="4dp"> - <shape android:shape="rectangle"> - <solid android:color="#fff" /> - </shape> - </inset> - </item> - -</layer-list>
diff --git a/chrome/android/java/res/drawable/most_visited_thumbnail_placeholder.xml b/chrome/android/java/res/drawable/most_visited_thumbnail_placeholder.xml deleted file mode 100644 index 3e065a74..0000000 --- a/chrome/android/java/res/drawable/most_visited_thumbnail_placeholder.xml +++ /dev/null
@@ -1,11 +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. --> - -<!-- The circle in the middle of a most visited item that has no thumbnail. --> -<shape xmlns:android="http://schemas.android.com/apk/res/android" - android:shape="oval"> - <solid android:color="@color/ntp_most_visited_bg" /> - <size android:width="27dp" android:height="27dp" /> -</shape> \ No newline at end of file
diff --git a/chrome/android/java/res/layout/most_visited_item.xml b/chrome/android/java/res/layout/most_visited_item.xml deleted file mode 100644 index de02755..0000000 --- a/chrome/android/java/res/layout/most_visited_item.xml +++ /dev/null
@@ -1,44 +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. --> - -<!-- A most visited item, for display on the new tab page. --> -<org.chromium.chrome.browser.ntp.MostVisitedItemView - xmlns:android="http://schemas.android.com/apk/res/android" - android:layout_width="@dimen/most_visited_tile_width" - android:layout_height="130dp" > - - <LinearLayout - android:layout_width="match_parent" - android:layout_height="match_parent" - android:background="@drawable/most_visited_item_bg" - android:orientation="vertical" - android:padding="4dp" > - <TextView - android:id="@+id/most_visited_title" - android:layout_width="match_parent" - android:layout_height="24dp" - android:layout_marginBottom="4dp" - android:paddingStart="4dp" - android:drawablePadding="8dp" - android:ellipsize="end" - android:gravity="center_vertical" - android:singleLine="true" - android:textAlignment="viewStart" - android:textColor="@color/ntp_most_visited_text" - android:textSize="12sp" /> - - <org.chromium.chrome.browser.ntp.MostVisitedThumbnail - android:id="@+id/most_visited_thumbnail" - android:layout_width="match_parent" - android:layout_height="wrap_content" - android:contentDescription="@null" /> - </LinearLayout> - - <View - android:layout_width="match_parent" - android:layout_height="match_parent" - android:background="?attr/selectableItemBackground" /> - -</org.chromium.chrome.browser.ntp.MostVisitedItemView>
diff --git a/chrome/android/java/res/layout/most_visited_layout.xml b/chrome/android/java/res/layout/most_visited_layout.xml deleted file mode 100644 index 647245a..0000000 --- a/chrome/android/java/res/layout/most_visited_layout.xml +++ /dev/null
@@ -1,10 +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. --> - -<org.chromium.chrome.browser.ntp.MostVisitedLayout - xmlns:android="http://schemas.android.com/apk/res/android" - android:layout_width="0dp" - android:layout_height="0dp" - android:paddingTop="16dp" />
diff --git a/chrome/android/java/res/values-sw600dp/dimens.xml b/chrome/android/java/res/values-sw600dp/dimens.xml index 19e81540..2fd051c 100644 --- a/chrome/android/java/res/values-sw600dp/dimens.xml +++ b/chrome/android/java/res/values-sw600dp/dimens.xml
@@ -43,7 +43,6 @@ <dimen name="widget_column_width">130dp</dimen> <!-- NTP dimensions --> - <dimen name="most_visited_spacing">16dp</dimen> <dimen name="ntp_logo_height">180dp</dimen> <dimen name="snippets_thumbnail_size">120dp</dimen>
diff --git a/chrome/android/java/res/values/colors.xml b/chrome/android/java/res/values/colors.xml index 01b5b25..1d99359 100644 --- a/chrome/android/java/res/values/colors.xml +++ b/chrome/android/java/res/values/colors.xml
@@ -88,8 +88,6 @@ <!-- NTP Colors. Used on the bookmarks and recent tabs pages. --> <color name="ntp_bg">#fff</color> <color name="ntp_bg_incognito">#222</color> - <color name="ntp_most_visited_text">#333</color> - <color name="ntp_most_visited_bg">#f2f2f2</color> <color name="ntp_list_item_text">#333</color> <color name="ntp_list_header_text">#333</color> <color name="ntp_list_header_subtext">#969696</color>
diff --git a/chrome/android/java/res/values/dimens.xml b/chrome/android/java/res/values/dimens.xml index 7b142f3d..da9a429f 100644 --- a/chrome/android/java/res/values/dimens.xml +++ b/chrome/android/java/res/values/dimens.xml
@@ -247,19 +247,7 @@ <dimen name="document_toolbar_menu_offset">5dp</dimen> <!-- NTP dimensions --> - <dimen name="most_visited_spacing">16dp</dimen> - <dimen name="most_visited_tile_width">156dp</dimen> - <dimen name="most_visited_thumbnail_width">148dp</dimen> - <dimen name="most_visited_thumbnail_height">94dp</dimen> <dimen name="most_visited_bg_corner_radius">2dp</dimen> - <!-- 250dp was chosen because it's smaller than the smallest dimension on the smallest device, - so we'll always have at least two columns of tiles (except in multiwindow with a narrow - window). --> - <dimen name="most_visited_two_column_min_width">250dp</dimen> - <!-- 450dp was chosen because it's greater than the width of the largest phone in portrait yet - less than the width of the smallest phone in landscape. So, we'll always have two columns - in portrait and three in landscape (except in atypical situations, like multiwindow). --> - <dimen name="most_visited_three_column_min_width">450dp</dimen> <dimen name="icon_most_visited_layout_max_width">504dp</dimen> <dimen name="icon_most_visited_layout_padding_top">16dp</dimen> <dimen name="icon_most_visited_layout_no_logo_padding_top">28dp</dimen>
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/ChromeActivity.java b/chrome/android/java/src/org/chromium/chrome/browser/ChromeActivity.java index 1e4f198..ebeaa20 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/ChromeActivity.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/ChromeActivity.java
@@ -130,6 +130,7 @@ import org.chromium.content.common.ContentSwitches; import org.chromium.content_public.browser.ContentBitmapCallback; import org.chromium.content_public.browser.LoadUrlParams; +import org.chromium.content_public.browser.WebContents; import org.chromium.content_public.browser.readback_types.ReadbackResponse; import org.chromium.policy.CombinedPolicyProvider.PolicyChangeListener; import org.chromium.printing.PrintManagerDelegateImpl; @@ -1603,6 +1604,18 @@ } } + /** + * @see Activity#onContextMenuClosed(Menu) + */ + @Override + public void onContextMenuClosed(Menu menu) { + final Tab currentTab = getActivityTab(); + if (currentTab == null) return; + WebContents webContents = currentTab.getWebContents(); + if (webContents == null) return; + webContents.onContextMenuClosed(); + } + private void enableHardwareAcceleration() { // HW acceleration is disabled in the manifest. Enable it only on high-end devices. if (!SysUtils.isLowEndDevice()) {
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/FrozenNativePage.java b/chrome/android/java/src/org/chromium/chrome/browser/FrozenNativePage.java index 98c4d2c..4f4cbc24 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/FrozenNativePage.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/FrozenNativePage.java
@@ -39,7 +39,6 @@ @Override public View getView() { - assert false; return null; }
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/compositor/bottombar/OverlayPanel.java b/chrome/android/java/src/org/chromium/chrome/browser/compositor/bottombar/OverlayPanel.java index 1038d34..beb8190 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/compositor/bottombar/OverlayPanel.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/compositor/bottombar/OverlayPanel.java
@@ -158,6 +158,8 @@ @Override public void closePanel(StateChangeReason reason, boolean animate) { + if (!isShowing()) return; + super.closePanel(reason, animate); // If the close action is animated, the Layout will be hidden when @@ -173,6 +175,8 @@ * @param reason The reason the panel is being shown. */ public void requestPanelShow(StateChangeReason reason) { + if (isShowing()) return; + if (mPanelManager != null) { mPanelManager.requestPanelShow(this, reason); }
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/contextmenu/ContextMenuHelper.java b/chrome/android/java/src/org/chromium/chrome/browser/contextmenu/ContextMenuHelper.java index 06be21a..e8e5785 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/contextmenu/ContextMenuHelper.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/contextmenu/ContextMenuHelper.java
@@ -17,6 +17,7 @@ import org.chromium.base.annotations.CalledByNative; import org.chromium.chrome.browser.share.ShareHelper; import org.chromium.content.browser.ContentViewCore; +import org.chromium.content_public.browser.WebContents; import org.chromium.ui.base.WindowAndroid; /** @@ -60,21 +61,26 @@ * @param params The {@link ContextMenuParams} that indicate what menu items to show. */ @CalledByNative - private void showContextMenu(ContentViewCore contentViewCore, ContextMenuParams params) { + private boolean showContextMenu(ContentViewCore contentViewCore, ContextMenuParams params) { final View view = contentViewCore.getContainerView(); if (!shouldShowMenu(params) || view == null || view.getVisibility() != View.VISIBLE || view.getParent() == null) { - return; + return false; } mCurrentContextMenuParams = params; view.performHapticFeedback(HapticFeedbackConstants.LONG_PRESS); view.setOnCreateContextMenuListener(this); - view.showContextMenu(); + if (view.showContextMenu()) { + WebContents webContents = contentViewCore.getWebContents(); + if (webContents != null) webContents.onContextMenuOpened(); + return true; + } + return false; } /**
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/contextualsearch/ContextualSearchManager.java b/chrome/android/java/src/org/chromium/chrome/browser/contextualsearch/ContextualSearchManager.java index 93ae6526..53d60dd 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/contextualsearch/ContextualSearchManager.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/contextualsearch/ContextualSearchManager.java
@@ -60,7 +60,6 @@ import java.util.LinkedHashSet; import java.util.List; import java.util.Locale; -import java.util.Set; import javax.annotation.Nullable; @@ -125,8 +124,9 @@ private boolean mIsShowingPromo; private boolean mDidLogPromoOutcome; - // Cached target languages for translation; - private List<String> mTargetLanguages; + // Cached native language data for translation; + private String mTranslateServiceTargetLanguage; + private String mAcceptLanguages; /** * Whether contextual search manager is currently promoting a tab. We should be ignoring hide @@ -485,8 +485,8 @@ mNetworkCommunicator.startSearchTermResolutionRequest( mSelectionController.getSelectedText()); didRequestSurroundings = true; - // Cache the target languages in case they are needed for translation. - if (!mPolicy.disableForceTranslationOnebox()) getReadableLanguages(); + // Cache the native translate data, so JNI calls won't be made when time-critical. + cacheNativeTranslateData(); } else { boolean shouldPrefetch = mPolicy.shouldPrefetchSearchResult(isTap); mSearchRequest = new ContextualSearchRequest(mSelectionController.getSelectedText(), @@ -792,50 +792,50 @@ /** * Gets the list of readable languages for the current user, with the first - * item in the list being the user's primary language. + * item in the list being the user's primary language (according to the Translate Service). * We assume that the user can read all languages that they can write. * @return The {@link List} of languages the user understands with their primary language first. */ private List<String> getReadableLanguages() { - // May be cached. - if (mTargetLanguages != null) return mTargetLanguages; - // Using LinkedHashSet keeps the entries both unique and ordered. - Set<String> uniqueLanguages = new LinkedHashSet<String>(); + LinkedHashSet<String> uniqueLanguages = getProficientLanguages(); - // The primary language always comes first. - uniqueLanguages.add( - trimLocaleToLanguage(nativeGetTargetLanguage(mNativeContextualSearchManagerPtr))); - - // Next add languages the user knows how to write. - List<String> writable = getWritableLanguages(); - for (int i = 0; i < writable.size(); i++) { - uniqueLanguages.add(trimLocaleToLanguage(writable.get(i))); - } - - // Add the accept languages last, since they are a weaker hint than presence of a keyboard. + // Add the accept languages to the end, since they are a weaker hint than + // the proficient languages. List<String> acceptLanguages = getAcceptLanguages(); for (int i = 0; i < acceptLanguages.size(); i++) { uniqueLanguages.add(trimLocaleToLanguage(acceptLanguages.get(i))); } - mTargetLanguages = new ArrayList<String>(uniqueLanguages); - return mTargetLanguages; + return new ArrayList<String>(uniqueLanguages); } /** - * Gets the list of writable languages for the current user, based on their IME keyboards. - * @return An ordered {@link List} of languages the user reads. + * Gets the list of languages that the current user is proficient using. + * The list produced is based on the Translation-Service's target language, supplemented + * with the user's IME keyboard locales. + * @return An ordered {@link List} of languages the user is proficient using. */ - private List<String> getWritableLanguages() { - List<String> result = new ArrayList<String>(); + private ArrayList<String> getProficientLanguageList() { + return new ArrayList<String>(getProficientLanguages()); + } + + /** + * Similar to {@link #getProficientLanguageList} except the the result is provided in + * a {@link LinkedHashSet} to provide access to a unique ordered list. + * @return a {@link LinkedHashSet} of languages the user is proficient using. + */ + private LinkedHashSet<String> getProficientLanguages() { + LinkedHashSet<String> uniqueLanguages = new LinkedHashSet<String>(); + // The primary language, according to the translation-service, always comes first. + uniqueLanguages.add(trimLocaleToLanguage(getNativeTranslateServiceTargetLanguage())); + // Merge in the IME locales, if possible. Context context = mActivity.getApplicationContext(); - List<String> locales = context != null - ? new ArrayList<String>(UiUtils.getIMELocales(context)) - : new ArrayList<String>(); - for (int i = 0; i < locales.size(); i++) { - result.add(trimLocaleToLanguage(locales.get(i))); + if (context != null) { + for (String locale : UiUtils.getIMELocales(context)) { + uniqueLanguages.add(trimLocaleToLanguage(locale)); + } } - return result; + return uniqueLanguages; } /** @@ -843,7 +843,7 @@ * @return The {@link List} of languages the user understands or does not want translated. */ private List<String> getAcceptLanguages() { - String acceptLanguages = nativeGetAcceptLanguages(mNativeContextualSearchManagerPtr); + String acceptLanguages = getNativeAcceptLanguages(); List<String> result = new ArrayList<String>(); for (String language : acceptLanguages.split(",")) { result.add(language); @@ -875,7 +875,7 @@ boolean doForceTranslate = !mPolicy.disableForceTranslationOnebox(); if (doForceTranslate && searchRequest != null) { searchRequest.forceTranslation(sourceLanguage, - mPolicy.bestTargetLanguage(getWritableLanguages())); + mPolicy.bestTargetLanguage(getProficientLanguageList())); } // Log that conditions were right for translation, even though it may be disabled // for an experiment so we can compare with the counter factual data. @@ -897,13 +897,45 @@ // The translation one-box won't actually show when the source text ends up being // the same as the target text, so we err on over-triggering. searchRequest.forceAutoDetectTranslation( - mPolicy.bestTargetLanguage(getWritableLanguages())); + mPolicy.bestTargetLanguage(getProficientLanguageList())); } // Log that conditions were right for translation, even though it may be disabled // for an experiment so we can compare with the counter factual data. ContextualSearchUma.logTranslateOnebox(shouldAutoDetectTranslate); } + /** + * Caches all the native translate language info, so we can avoid repeated JNI calls. + */ + private void cacheNativeTranslateData() { + if (!mPolicy.disableForceTranslationOnebox()) { + getNativeTranslateServiceTargetLanguage(); + getNativeAcceptLanguages(); + } + } + + /** + * @return The accept-languages string from the cache or from native code (when not cached). + */ + private String getNativeAcceptLanguages() { + if (mAcceptLanguages == null) { + mAcceptLanguages = nativeGetAcceptLanguages(mNativeContextualSearchManagerPtr); + } + return mAcceptLanguages; + } + + /** + * @return The Translate Service's target language string from the cache or from + * native code (when not cached). + */ + private String getNativeTranslateServiceTargetLanguage() { + if (mTranslateServiceTargetLanguage == null) { + mTranslateServiceTargetLanguage = nativeGetTargetLanguage( + mNativeContextualSearchManagerPtr); + } + return mTranslateServiceTargetLanguage; + } + // ============================================================================================ // OverlayContentDelegate // ============================================================================================ @@ -1330,6 +1362,7 @@ private native void nativeGatherSurroundingText(long nativeContextualSearchManager, String selection, boolean useResolvedSearchTerm, ContentViewCore baseContentViewCore, boolean maySendBasePageUrl); + // Don't call these directly, instead call the private methods that cache the results. private native String nativeGetTargetLanguage(long nativeContextualSearchManager); private native String nativeGetAcceptLanguages(long nativeContextualSearchManager); }
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/contextualsearch/ContextualSearchPolicy.java b/chrome/android/java/src/org/chromium/chrome/browser/contextualsearch/ContextualSearchPolicy.java index 3041cb31..54d19a2e 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/contextualsearch/ContextualSearchPolicy.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/contextualsearch/ContextualSearchPolicy.java
@@ -447,7 +447,8 @@ } /** - * Determines the best target language. + * @return The best target language from the ordered list, or the empty string if + * none is available. */ String bestTargetLanguage(List<String> targetLanguages) { // For now, we just return the first language, unless it's English @@ -456,11 +457,13 @@ // E.g. If this language doesn't match the user's server preferences, they might see a page // in one language and the one box translation in another, which might be confusing. // Also this logic should only apply on Android, where English setup is over used. - if (TextUtils.equals(targetLanguages.get(0), Locale.ENGLISH.getLanguage()) - && targetLanguages.size() > 1) { + if (targetLanguages.size() > 1 + && TextUtils.equals(targetLanguages.get(0), Locale.ENGLISH.getLanguage())) { return targetLanguages.get(1); - } else { + } else if (targetLanguages.size() > 0) { return targetLanguages.get(0); + } else { + return ""; } }
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/enhancedbookmarks/EnhancedBookmarkSigninActivity.java b/chrome/android/java/src/org/chromium/chrome/browser/enhancedbookmarks/EnhancedBookmarkSigninActivity.java index 93724dc9..2d0618d 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/enhancedbookmarks/EnhancedBookmarkSigninActivity.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/enhancedbookmarks/EnhancedBookmarkSigninActivity.java
@@ -15,7 +15,7 @@ import org.chromium.chrome.browser.profiles.Profile; import org.chromium.chrome.browser.signin.SigninManager; import org.chromium.chrome.browser.signin.SigninManager.SignInStateObserver; -import org.chromium.chrome.browser.sync.SyncController; +import org.chromium.chrome.browser.sync.ProfileSyncService; import org.chromium.sync.AndroidSyncSettings; import org.chromium.sync.AndroidSyncSettings.AndroidSyncSettingsObserver; import org.chromium.sync.signin.ChromeSigninController; @@ -99,9 +99,9 @@ @Override public void enableSync() { - final SyncController syncController = SyncController.get(this); - if (syncController != null) { - syncController.start(); + ProfileSyncService syncService = ProfileSyncService.get(); + if (syncService != null) { + syncService.requestStart(); } }
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/invalidation/InvalidationController.java b/chrome/android/java/src/org/chromium/chrome/browser/invalidation/InvalidationController.java index 06887d1..13cf984 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/invalidation/InvalidationController.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/invalidation/InvalidationController.java
@@ -237,6 +237,13 @@ } /** + * Returns whether the invalidation client has been started. + */ + public boolean isStarted() { + return mStarted; + } + + /** * Called when a RecentTabsPage is opened. */ public void onRecentTabsPageOpened() {
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/metrics/StartupMetrics.java b/chrome/android/java/src/org/chromium/chrome/browser/metrics/StartupMetrics.java index 23ea0eaa..53dd01c 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/metrics/StartupMetrics.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/metrics/StartupMetrics.java
@@ -4,9 +4,12 @@ package org.chromium.chrome.browser.metrics; +import android.content.Context; import android.content.Intent; import android.os.Handler; +import android.preference.PreferenceManager; +import org.chromium.base.ApplicationStatus; import org.chromium.base.metrics.RecordHistogram; /** @@ -28,14 +31,26 @@ private int mFirstActionTaken = NO_ACTIVITY; private boolean mIsMainIntent; - private long mSessionStartTimestamp; private Handler mHandler; - private boolean mRecordedHistogram; + // This ensures metrics are recorded only once per updateIntent(...) call. + private boolean mShouldRecordHistogram; + + // Startup time is measured by two different time sources. + // {@code mStartTimeNanoMonotonic} is measured from a monotonic time source with nanosecond + // precision whereas {@code mStartTimeMilli} is measured from the wall clock with millisecond + // precision. The monotonic time source may not persist across reboots whereas the wall clock + // is subject to change by the user. + private long mStartTimeNanoMonotonic; + private long mStartTimeMilli; private static StartupMetrics sInstance; // Record only the first 10s. private static final long RECORDING_THRESHOLD_NS = 10000000000L; + private static final int MILLI_SEC_PER_MINUTE = 60000; + private static final int MINUTES_PER_30DAYS = 43200; + // Bucket sizes are exponential so we get minute level granularity for first 10 minutes. + private static final int NUM_BUCKETS = 50; public static StartupMetrics getInstance() { if (sInstance == null) { @@ -46,7 +61,6 @@ // Singleton private StartupMetrics() { - mSessionStartTimestamp = System.nanoTime(); mHandler = new Handler(); } @@ -58,12 +72,13 @@ public void updateIntent(Intent intent) { mIsMainIntent = intent != null && Intent.ACTION_MAIN.equals(intent.getAction()); mFirstActionTaken = NO_ACTIVITY; - mSessionStartTimestamp = System.nanoTime(); - mRecordedHistogram = false; + mStartTimeNanoMonotonic = System.nanoTime(); + mStartTimeMilli = System.currentTimeMillis(); + mShouldRecordHistogram = true; } private boolean isShortlyAfterChromeStarted() { - return (System.nanoTime() - mSessionStartTimestamp) <= RECORDING_THRESHOLD_NS; + return (System.nanoTime() - mStartTimeNanoMonotonic) <= RECORDING_THRESHOLD_NS; } private void setFirstAction(int type) { @@ -103,12 +118,22 @@ /** Records the startup data in a histogram. Should only be called after native is loaded. */ public void recordHistogram(boolean onStop) { - if (mRecordedHistogram) return; + if (!mShouldRecordHistogram) return; if (!isShortlyAfterChromeStarted() || mFirstActionTaken != NO_ACTIVITY || onStop) { String histogramName = mIsMainIntent ? "MobileStartup.MainIntentAction" : "MobileStartup.NonMainIntentAction"; RecordHistogram.recordEnumeratedHistogram(histogramName, mFirstActionTaken, MAX_INDEX); - mRecordedHistogram = true; + mShouldRecordHistogram = false; + Context ctx = ApplicationStatus.getApplicationContext(); + long lastUsedTimeMilli = PreferenceManager.getDefaultSharedPreferences(ctx).getLong( + UmaSessionStats.LAST_USED_TIME_PREF, 0); + if (mIsMainIntent && (lastUsedTimeMilli > 0) && (mStartTimeMilli > lastUsedTimeMilli) + && (mStartTimeMilli - lastUsedTimeMilli > Integer.MAX_VALUE)) { + // Measured in minutes and capped at a day with a bucket precision of 6 minutes. + RecordHistogram.recordCustomCountHistogram("MobileStartup.TimeSinceLastUse", + (int) (mStartTimeMilli - lastUsedTimeMilli) / MILLI_SEC_PER_MINUTE, 1, + MINUTES_PER_30DAYS, NUM_BUCKETS); + } } else { // Call back later to record the histogram after 10s have elapsed. mHandler.postDelayed(new Runnable() { @@ -116,8 +141,7 @@ public void run() { recordHistogram(false); } - } , (RECORDING_THRESHOLD_NS - (System.nanoTime() - mSessionStartTimestamp)) / 1000000); + }, (RECORDING_THRESHOLD_NS - (System.nanoTime() - mStartTimeNanoMonotonic)) / 1000000); } } - }
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/metrics/UmaSessionStats.java b/chrome/android/java/src/org/chromium/chrome/browser/metrics/UmaSessionStats.java index 941e38c..ccaea0d 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/metrics/UmaSessionStats.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/metrics/UmaSessionStats.java
@@ -7,6 +7,7 @@ import android.content.ComponentCallbacks; import android.content.Context; import android.content.res.Configuration; +import android.preference.PreferenceManager; import android.text.TextUtils; import org.chromium.chrome.browser.preferences.PrefServiceBridge; @@ -26,6 +27,8 @@ * and the framework's MetricService. */ public class UmaSessionStats implements NetworkChangeNotifier.ConnectionTypeObserver { + public static final String LAST_USED_TIME_PREF = "umasessionstats.lastusedtime"; + private static final String SAMSUNG_MULTWINDOW_PACKAGE = "com.sec.feature.multiwindow"; private static long sNativeUmaSessionStats = 0; @@ -141,6 +144,10 @@ nativeUmaEndSession(sNativeUmaSessionStats); NetworkChangeNotifier.removeConnectionTypeObserver(this); + PreferenceManager.getDefaultSharedPreferences(mContext) + .edit() + .putLong(LAST_USED_TIME_PREF, System.currentTimeMillis()) + .apply(); } public static void logRendererCrash() {
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/ntp/MostVisitedItemView.java b/chrome/android/java/src/org/chromium/chrome/browser/ntp/MostVisitedItemView.java deleted file mode 100644 index b2167f2..0000000 --- a/chrome/android/java/src/org/chromium/chrome/browser/ntp/MostVisitedItemView.java +++ /dev/null
@@ -1,85 +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.content.Context; -import android.content.res.Resources; -import android.graphics.Bitmap; -import android.graphics.drawable.BitmapDrawable; -import android.graphics.drawable.ColorDrawable; -import android.graphics.drawable.Drawable; -import android.util.AttributeSet; -import android.widget.FrameLayout; -import android.widget.TextView; - -import org.chromium.base.ApiCompatibilityUtils; -import org.chromium.chrome.R; - -/** - * Displays the title, thumbnail, and favicon of a most visited page. The item can be clicked, or - * long-pressed to trigger a context menu with options to "open in new tab", "open in incognito - * tab", or "remove". - */ -public class MostVisitedItemView extends FrameLayout { - - private static final int MISSING_FAVICON_COLOR = 0xffe6e6e8; - - private TextView mTitleView; - private MostVisitedThumbnail mThumbnailView; - private int mFaviconSize; - private int mTitlePaddingStart; - - /** - * Constructor for inflating from XML. - */ - public MostVisitedItemView(Context context, AttributeSet attrs) { - super(context, attrs); - } - - /** - * Initializes the item. This must be called immediately after construction. - * - * @param title The title of the page. - */ - public void init(String title) { - mTitleView = (TextView) findViewById(R.id.most_visited_title); - mThumbnailView = (MostVisitedThumbnail) findViewById(R.id.most_visited_thumbnail); - - mTitleView.setText(title); - - // Add padding to fill the space where the favicon will be shown. Once the favicon is - // available (in setFavicon()), this extra padding will be removed and the favicon will be - // added as a compound drawable. This prevents the text from jumping around when the favicon - // becomes available. - mTitlePaddingStart = ApiCompatibilityUtils.getPaddingStart(mTitleView); - mFaviconSize = getResources().getDimensionPixelSize(R.dimen.default_favicon_size); - int extraPaddingStart = mFaviconSize + mTitleView.getCompoundDrawablePadding(); - ApiCompatibilityUtils.setPaddingRelative(mTitleView, mTitlePaddingStart + extraPaddingStart, - 0, 0, 0); - } - - /** - * Update the thumbnail and trigger a redraw with the new thumbnail. - */ - public void setThumbnail(Bitmap thumbnail) { - mThumbnailView.setThumbnail(thumbnail); - } - - /** - * Update the favicon and trigger a redraw with the new favicon. - */ - public void setFavicon(Bitmap favicon) { - Resources res = getResources(); - Drawable d; - if (favicon != null) { - d = new BitmapDrawable(res, favicon); - } else { - d = new ColorDrawable(MISSING_FAVICON_COLOR); - } - d.setBounds(0, 0, mFaviconSize, mFaviconSize); - ApiCompatibilityUtils.setCompoundDrawablesRelative(mTitleView, d, null, null, null); - ApiCompatibilityUtils.setPaddingRelative(mTitleView, mTitlePaddingStart, 0, 0, 0); - } -}
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/ntp/MostVisitedLayout.java b/chrome/android/java/src/org/chromium/chrome/browser/ntp/MostVisitedLayout.java deleted file mode 100644 index bdf95cb9..0000000 --- a/chrome/android/java/src/org/chromium/chrome/browser/ntp/MostVisitedLayout.java +++ /dev/null
@@ -1,150 +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.content.Context; -import android.content.res.Resources; -import android.graphics.Canvas; -import android.graphics.drawable.Drawable; -import android.util.AttributeSet; -import android.view.View; -import android.widget.FrameLayout; - -import org.chromium.base.ApiCompatibilityUtils; -import org.chromium.chrome.R; - -/** - * A layout that arranges most visited items in a grid. All items must be the same size. - */ -public class MostVisitedLayout extends FrameLayout { - - private int mHorizontalSpacing; - private int mVerticalSpacing; - private int mTwoColumnMinWidth; - private int mThreeColumnMinWidth; - - /** - * The ideal width of a child. The children may need be stretched or shrunk a bit to fill the - * available width. - */ - private int mDefaultChildWidth; - - private Drawable mEmptyTileDrawable; - private int mNumEmptyTiles; - private int mEmptyTileTop; - private int mFirstEmptyTileLeft; - - /** - * @param context The view context in which this item will be shown. - * @param attrs The attributes of the XML tag that is inflating the view. - */ - public MostVisitedLayout(Context context, AttributeSet attrs) { - super(context, attrs); - setWillNotDraw(false); - - Resources res = getResources(); - mHorizontalSpacing = res.getDimensionPixelOffset(R.dimen.most_visited_spacing); - mVerticalSpacing = mHorizontalSpacing; - mDefaultChildWidth = res.getDimensionPixelSize(R.dimen.most_visited_tile_width); - mTwoColumnMinWidth = res.getDimensionPixelOffset(R.dimen.most_visited_two_column_min_width); - mThreeColumnMinWidth = res.getDimensionPixelOffset( - R.dimen.most_visited_three_column_min_width); - } - - @Override - protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { - // Determine the number of columns in the grid. - final int totalWidth = MeasureSpec.getSize(widthMeasureSpec); - int childWidth = mDefaultChildWidth; - int childWidthWithSpacing = childWidth + mHorizontalSpacing; - - int numColumns; - if (totalWidth + mHorizontalSpacing >= 3 * childWidthWithSpacing) { - numColumns = 3; - } else if (totalWidth < mTwoColumnMinWidth) { - numColumns = 1; - } else { - numColumns = totalWidth < mThreeColumnMinWidth ? 2 : 3; - - // Resize the tiles to make them fill the entire available width. - childWidthWithSpacing = Math.max(mHorizontalSpacing, - (totalWidth + mHorizontalSpacing) / numColumns); - childWidth = childWidthWithSpacing - mHorizontalSpacing; - } - - int childCount = getChildCount(); - int childHeight = 0; - if (childCount > 0) { - // Measure the children. - int childWidthSpec = MeasureSpec.makeMeasureSpec(childWidth, MeasureSpec.EXACTLY); - int childHeightSpec = MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED); - for (int i = 0; i < childCount; i++) { - getChildAt(i).measure(childWidthSpec, childHeightSpec); - } - childHeight = getChildAt(0).getMeasuredHeight(); - } - - // Arrange the children in a grid. - int childStart = 0; - int childTop = 0; - int column = 0; - boolean isRtl = ApiCompatibilityUtils.isLayoutRtl(this); - for (int i = 0; i < childCount; i++) { - View child = getChildAt(i); - MarginLayoutParams layoutParams = (MarginLayoutParams) child.getLayoutParams(); - layoutParams.setMargins(isRtl ? 0 : childStart, childTop, - isRtl ? childStart : 0, 0); - child.setLayoutParams(layoutParams); - column++; - if (column == numColumns) { - column = 0; - childStart = 0; - childTop += childHeight + mVerticalSpacing; - } else { - childStart += childWidthWithSpacing; - } - } - - // Fill the rest of the current row with empty tiles. - if (column != 0) { - mNumEmptyTiles = numColumns - column; - mEmptyTileTop = childTop + getPaddingTop(); - mFirstEmptyTileLeft = isRtl ? 0 : childStart; - } else { - mNumEmptyTiles = 0; - } - - int numRows = (childCount + mNumEmptyTiles) / numColumns; - int totalHeight = getPaddingTop() + getPaddingBottom() + numRows * childHeight - + (numRows - 1) * mVerticalSpacing; - - int gridWidth = numColumns * childWidthWithSpacing - mHorizontalSpacing; - setMeasuredDimension(gridWidth, resolveSize(totalHeight, heightMeasureSpec)); - } - - @Override - protected void onDraw(Canvas canvas) { - super.onDraw(canvas); - if (mNumEmptyTiles == 0 || getChildCount() == 0) return; - - // Draw empty tiles. - if (mEmptyTileDrawable == null) { - mEmptyTileDrawable = ApiCompatibilityUtils.getDrawable( - getResources(), R.drawable.most_visited_item_empty); - } - int tileLeft = mFirstEmptyTileLeft; - int tileWidth = getChildAt(0).getMeasuredWidth(); - int tileHeight = getChildAt(0).getMeasuredHeight(); - for (int i = 0; i < mNumEmptyTiles; i++) { - mEmptyTileDrawable.setBounds( - tileLeft, - mEmptyTileTop, - tileLeft + tileWidth, - mEmptyTileTop + tileHeight); - mEmptyTileDrawable.draw(canvas); - tileLeft += tileWidth + mHorizontalSpacing; - } - } -}
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/ntp/MostVisitedThumbnail.java b/chrome/android/java/src/org/chromium/chrome/browser/ntp/MostVisitedThumbnail.java deleted file mode 100644 index 0d3edc6..0000000 --- a/chrome/android/java/src/org/chromium/chrome/browser/ntp/MostVisitedThumbnail.java +++ /dev/null
@@ -1,97 +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.content.Context; -import android.content.res.Resources; -import android.graphics.Bitmap; -import android.graphics.Color; -import android.graphics.Matrix; -import android.util.AttributeSet; -import android.widget.ImageView; - -import org.chromium.chrome.R; - -/** - * Displays a thumbnail for a most visited item on the NTP. - */ -public class MostVisitedThumbnail extends ImageView { - - private final int mDesiredWidth; - private final int mDesiredHeight; - private Bitmap mThumbnail; - private Matrix mImageMatrix; - - /** - * Constructor for inflating from XML. - */ - public MostVisitedThumbnail(Context context, AttributeSet attrs) { - super(context, attrs); - Resources res = getResources(); - mDesiredWidth = res.getDimensionPixelSize(R.dimen.most_visited_thumbnail_width); - mDesiredHeight = res.getDimensionPixelSize(R.dimen.most_visited_thumbnail_height); - } - - /** - * Updates the thumbnail and trigger a redraw with the new thumbnail. - */ - void setThumbnail(Bitmap thumbnail) { - mThumbnail = thumbnail; - if (thumbnail != null) { - setImageBitmap(thumbnail); - setScaleType(ImageView.ScaleType.MATRIX); - updateThumbnailMatrix(); - } else { - setBackgroundColor(Color.WHITE); - setImageResource(R.drawable.most_visited_thumbnail_placeholder); - setScaleType(ImageView.ScaleType.CENTER); - } - } - - /** - * Updates the matrix used to scale the thumbnail when drawing it. This needs to be called - * whenever the thumbnail changes or this view's size changes. - * - * This matrix ensures that the thumbnail is anchored at the top left corner of this view and - * is scaled as small as possible while still covering the entire view. Surprisingly, there's - * no way to get this behavior using the other ImageView.ScaleTypes. - */ - private void updateThumbnailMatrix() { - if (mThumbnail == null) return; - - if (mImageMatrix == null) mImageMatrix = new Matrix(); - float widthScale = (float) getMeasuredWidth() / mThumbnail.getWidth(); - float heightScale = (float) getMeasuredHeight() / mThumbnail.getHeight(); - float scale = Math.max(widthScale, heightScale); - mImageMatrix.setScale(scale, scale); - setImageMatrix(mImageMatrix); - } - - @Override - protected void onSizeChanged(int w, int h, int oldw, int oldh) { - super.onSizeChanged(w, h, oldw, oldh); - updateThumbnailMatrix(); - } - - /** - * Maintains this view's aspect ratio, even when its width is constrained. We can't just use - * android:adjustViewBounds, since that won't work when the source drawable isn't set or when - * it's the "missing thumbnail" gray circle, which has a different aspect ratio than thumbnails. - */ - @Override - protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { - int width = resolveSize(mDesiredWidth, widthMeasureSpec); - int height; - if (width == mDesiredWidth) { - height = mDesiredHeight; - } else { - // The width is fixed. Find the height that keeps the proper aspect ratio. - height = Math.round((float) mDesiredHeight / mDesiredWidth * width); - height = resolveSize(height, heightMeasureSpec); - } - super.onMeasure(MeasureSpec.makeMeasureSpec(width, MeasureSpec.EXACTLY), - MeasureSpec.makeMeasureSpec(height, MeasureSpec.EXACTLY)); - } -}
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 2c10a2fd..8539a53 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
@@ -96,7 +96,6 @@ private LargeIconBridge mLargeIconBridge; private LogoBridge mLogoBridge; private boolean mSearchProviderHasLogo; - private boolean mIsIconMode; private final boolean mOptOutPromoShown; private String mOnLogoClickUrl; private String mAnimatedLogoUrl; @@ -421,7 +420,7 @@ for (int i = 0; i < items.length; i++) { tileTypes[i] = items[i].getTileType(); } - mMostVisitedSites.recordTileTypeMetrics(tileTypes, mIsIconMode); + mMostVisitedSites.recordTileTypeMetrics(tileTypes); } }; @@ -471,10 +470,8 @@ LayoutInflater inflater = LayoutInflater.from(activity); mNewTabPageView = (NewTabPageView) inflater.inflate(R.layout.new_tab_page, null); - // TODO(newt): delete thumbnail mode once we're sure that icon mode has stuck for good. - mIsIconMode = true; mNewTabPageView.initialize(mNewTabPageManager, isInSingleUrlBarMode(activity), - mSearchProviderHasLogo, mIsIconMode); + mSearchProviderHasLogo); RecordHistogram.recordBooleanHistogram( "NewTabPage.MobileIsUserOnline", NetworkChangeNotifier.isOnline());
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 d167031..d38d11b1 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
@@ -236,21 +236,18 @@ * with the page. * @param isSingleUrlBarMode Whether the NTP is in single URL bar mode. * @param searchProviderHasLogo Whether the search provider has a logo. - * @param isIconMode Whether to show the icon-based design, as opposed to the thumbnail design. */ public void initialize(NewTabPageManager manager, boolean isSingleUrlBarMode, - boolean searchProviderHasLogo, boolean isIconMode) { + boolean searchProviderHasLogo) { mManager = manager; mScrollView = (NewTabScrollView) findViewById(R.id.ntp_scrollview); mScrollView.enableBottomShadow(SHADOW_COLOR); mContentView = (ViewGroup) findViewById(R.id.ntp_content); - mMostVisitedDesign = isIconMode - ? new IconMostVisitedDesign(getContext()) - : new ThumbnailMostVisitedDesign(getContext()); + mMostVisitedDesign = new MostVisitedDesign(getContext()); ViewStub mostVisitedLayoutStub = (ViewStub) findViewById(R.id.most_visited_layout_stub); - mostVisitedLayoutStub.setLayoutResource(mMostVisitedDesign.getMostVisitedLayoutId()); + mostVisitedLayoutStub.setLayoutResource(R.layout.icon_most_visited_layout); mMostVisitedLayout = (ViewGroup) mostVisitedLayoutStub.inflate(); mMostVisitedDesign.initMostVisitedLayout(mMostVisitedLayout, searchProviderHasLogo); @@ -783,7 +780,7 @@ if (item == null) { String displayTitle = getTitleForDisplay(title, url); item = new MostVisitedItem(mManager, title, url, i); - View view = mMostVisitedDesign.createMostVisitedItemView(inflater, url, title, + View view = mMostVisitedDesign.createMostVisitedItemView(inflater, url, displayTitle, item, isInitialLoad); item.initView(view); } @@ -810,8 +807,7 @@ String[] urls, String[] faviconUrls, String[] largeIconUrls) { for (int i = 0; i < urls.length; i++) { final String url = urls[i]; - boolean useLargeIcon = - mMostVisitedDesign.preferLargeIcons() && !largeIconUrls[i].isEmpty(); + boolean useLargeIcon = !largeIconUrls[i].isEmpty(); // Only fetch one of favicon or large icon based on what is required on the NTP. // The other will be fetched on visiting the site. String iconUrl = useLargeIcon ? largeIconUrls[i] : faviconUrls[i]; @@ -858,144 +854,9 @@ } /** - * Interface for creating the most visited layout and tiles. - * TODO(newt): delete this once a single design has been chosen. - */ - private interface MostVisitedDesign { - int getNumberOfTiles(boolean searchProviderHasLogo); - int getMostVisitedLayoutId(); - int getMostVisitedLayoutBleed(); - void initMostVisitedLayout(ViewGroup mostVisitedLayout, boolean searchProviderHasLogo); - void setSearchProviderHasLogo(View mostVisitedLayout, boolean hasLogo); - View createMostVisitedItemView(LayoutInflater inflater, String url, String title, - String displayTitle, MostVisitedItem item, boolean isInitialLoad); - void onIconUpdated(String url); - boolean preferLargeIcons(); - } - - /** - * The old most visited design, where each tile shows a thumbnail of the page, a small favicon, - * and the title. - */ - private class ThumbnailMostVisitedDesign implements MostVisitedDesign { - - private static final int NUM_TILES = 6; - private static final int FAVICON_CORNER_RADIUS_DP = 2; - private static final int FAVICON_TEXT_SIZE_DP = 10; - private static final int FAVICON_BACKGROUND_COLOR = 0xff969696; - - private int mDesiredFaviconSize; - private RoundedIconGenerator mFaviconGenerator; - - ThumbnailMostVisitedDesign(Context context) { - Resources res = context.getResources(); - mDesiredFaviconSize = res.getDimensionPixelSize(R.dimen.default_favicon_size); - int desiredFaviconSizeDp = Math.round( - mDesiredFaviconSize / res.getDisplayMetrics().density); - mFaviconGenerator = new RoundedIconGenerator( - context, desiredFaviconSizeDp, desiredFaviconSizeDp, FAVICON_CORNER_RADIUS_DP, - FAVICON_BACKGROUND_COLOR, FAVICON_TEXT_SIZE_DP); - } - - @Override - public int getNumberOfTiles(boolean searchProviderHasLogo) { - return NUM_TILES; - } - - @Override - public int getMostVisitedLayoutId() { - return R.layout.most_visited_layout; - } - - @Override - public int getMostVisitedLayoutBleed() { - return 0; - } - - @Override - public void initMostVisitedLayout(ViewGroup mostVisitedLayout, - boolean searchProviderHasLogo) { - } - - @Override - public void setSearchProviderHasLogo(View mostVisitedLayout, boolean hasLogo) {} - - @Override - public View createMostVisitedItemView(LayoutInflater inflater, final String url, - String title, String displayTitle, final MostVisitedItem item, - final boolean isInitialLoad) { - final MostVisitedItemView view = (MostVisitedItemView) inflater.inflate( - R.layout.most_visited_item, mMostVisitedLayout, false); - view.init(displayTitle); - - ThumbnailCallback thumbnailCallback = new ThumbnailCallback() { - @Override - public void onMostVisitedURLsThumbnailAvailable(Bitmap thumbnail, - boolean isLocalThumbnail) { - view.setThumbnail(thumbnail); - if (thumbnail == null) { - item.setTileType(MostVisitedTileType.THUMBNAIL_DEFAULT); - } else if (isLocalThumbnail) { - item.setTileType(MostVisitedTileType.THUMBNAIL_LOCAL); - } else { - item.setTileType(MostVisitedTileType.THUMBNAIL_SERVER); - } - mSnapshotMostVisitedChanged = true; - if (isInitialLoad) loadTaskCompleted(); - } - }; - if (isInitialLoad) mPendingLoadTasks++; - mManager.getURLThumbnail(url, thumbnailCallback); - - FaviconImageCallback faviconCallback = new FaviconImageCallback() { - @Override - public void onFaviconAvailable(Bitmap image, String iconUrl) { - if (image == null) { - image = mFaviconGenerator.generateIconForUrl(url); - } - view.setFavicon(image); - mSnapshotMostVisitedChanged = true; - if (isInitialLoad) loadTaskCompleted(); - } - }; - if (isInitialLoad) mPendingLoadTasks++; - mManager.getLocalFaviconImageForURL(url, mDesiredFaviconSize, faviconCallback); - - return view; - } - - @Override - public void onIconUpdated(final String url) { - // Find a matching most visited item. - for (MostVisitedItem item : mMostVisitedItems) { - if (!item.getUrl().equals(url)) continue; - - final MostVisitedItemView view = (MostVisitedItemView) item.getView(); - FaviconImageCallback faviconCallback = new FaviconImageCallback() { - @Override - public void onFaviconAvailable(Bitmap image, String iconUrl) { - if (image == null) { - image = mFaviconGenerator.generateIconForUrl(url); - } - view.setFavicon(image); - mSnapshotMostVisitedChanged = true; - } - }; - mManager.getLocalFaviconImageForURL(url, mDesiredFaviconSize, faviconCallback); - break; - } - } - - @Override - public boolean preferLargeIcons() { - return false; - } - } - - /** * The new-fangled design for most visited tiles, where each tile shows a large icon and title. */ - private class IconMostVisitedDesign implements MostVisitedDesign { + private class MostVisitedDesign { private static final int NUM_TILES = 8; private static final int NUM_TILES_NO_LOGO = 12; @@ -1012,7 +873,7 @@ private int mDesiredIconSize; private RoundedIconGenerator mIconGenerator; - IconMostVisitedDesign(Context context) { + MostVisitedDesign(Context context) { Resources res = context.getResources(); mMostVisitedLayoutBleed = res.getDimensionPixelSize( R.dimen.icon_most_visited_layout_bleed); @@ -1026,29 +887,20 @@ ICON_BACKGROUND_COLOR, ICON_TEXT_SIZE_DP); } - @Override public int getNumberOfTiles(boolean searchProviderHasLogo) { return searchProviderHasLogo ? NUM_TILES : NUM_TILES_NO_LOGO; } - @Override - public int getMostVisitedLayoutId() { - return R.layout.icon_most_visited_layout; - } - - @Override public int getMostVisitedLayoutBleed() { return mMostVisitedLayoutBleed; } - @Override public void initMostVisitedLayout(ViewGroup mostVisitedLayout, boolean searchProviderHasLogo) { ((IconMostVisitedLayout) mostVisitedLayout).setMaxRows( searchProviderHasLogo ? MAX_ROWS : MAX_ROWS_NO_LOGO); } - @Override public void setSearchProviderHasLogo(View mostVisitedLayout, boolean hasLogo) { int paddingTop = getResources().getDimensionPixelSize(hasLogo ? R.dimen.icon_most_visited_layout_padding_top @@ -1091,9 +943,8 @@ } } - @Override public View createMostVisitedItemView(LayoutInflater inflater, final String url, - String title, String displayTitle, MostVisitedItem item, + String displayTitle, MostVisitedItem item, final boolean isInitialLoad) { final IconMostVisitedItemView view = (IconMostVisitedItemView) inflater.inflate( R.layout.icon_most_visited_item, mMostVisitedLayout, false); @@ -1106,7 +957,6 @@ return view; } - @Override public void onIconUpdated(final String url) { // Find a matching most visited item. for (MostVisitedItem item : mMostVisitedItems) { @@ -1117,10 +967,5 @@ } } } - - @Override - public boolean preferLargeIcons() { - return true; - } } }
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 ff37261bd..445f69b 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
@@ -24,7 +24,7 @@ import org.chromium.chrome.browser.profiles.Profile; import org.chromium.chrome.browser.signin.SigninManager; import org.chromium.chrome.browser.signin.SigninManager.SignInStateObserver; -import org.chromium.chrome.browser.sync.SyncController; +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; @@ -442,9 +442,9 @@ @Override public void enableSync() { - SyncController syncController = SyncController.get(mContext); - if (syncController != null) { - syncController.start(); + ProfileSyncService syncService = ProfileSyncService.get(); + if (syncService != null) { + syncService.requestStart(); } }
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/omnibox/LocationBarLayout.java b/chrome/android/java/src/org/chromium/chrome/browser/omnibox/LocationBarLayout.java index 3d6fc680..f959c8a 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/omnibox/LocationBarLayout.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/omnibox/LocationBarLayout.java
@@ -205,7 +205,6 @@ private boolean mSuggestionsShown; private boolean mUrlHasFocus; private boolean mUrlFocusedFromFakebox; - private boolean mHasRecordedUrlFocusSource; // Set to true when the user has started typing new input in the omnibox, set to false // when the omnibox loses focus or becomes empty. @@ -276,7 +275,6 @@ if (mIgnoreURLBarModification) return; if (!mHasStartedNewOmniboxEditSession && mNativeInitialized) { - RecordUserAction.record("MobileFirstEditInOmnibox"); mAutocomplete.resetSession(); mHasStartedNewOmniboxEditSession = true; mNewOmniboxEditSessionTimestamp = SystemClock.elapsedRealtime(); @@ -951,12 +949,13 @@ public void onUrlFocusChange(boolean hasFocus) { mUrlHasFocus = hasFocus; mUrlContainer.onUrlFocusChanged(hasFocus); - updateFocusSource(hasFocus); updateDeleteButtonVisibility(); Tab currentTab = getCurrentTab(); if (hasFocus) { + RecordUserAction.record("FocusLocation"); mUrlBar.deEmphasizeUrl(); } else { + mUrlFocusedFromFakebox = false; hideSuggestions(); // Focus change caused by a close-tab may result in an invalid current tab. @@ -2376,37 +2375,6 @@ loadUrl(url, PageTransition.TYPED); } - /** - * Tracks how the URL bar was focused (i.e. from the omnibox or the fakebox) and records a UMA - * stat for this. Should be called whenever the URL bar gains or loses focus. - * @param hasFocus Whether the URL bar now has focus. - */ - private void updateFocusSource(boolean hasFocus) { - if (!hasFocus) { - mUrlFocusedFromFakebox = false; - mHasRecordedUrlFocusSource = false; - return; - } - - // Record UMA event for how the URL bar was focused. - if (mHasRecordedUrlFocusSource) return; - - Tab currentTab = getCurrentTab(); - if (currentTab == null) return; - - String url = currentTab.getUrl(); - if (mUrlFocusedFromFakebox) { - RecordUserAction.record("MobileFocusedFakeboxOnNtp"); - } else { - if (currentTab.isNativePage() && NewTabPage.isNTPUrl(url)) { - RecordUserAction.record("MobileFocusedOmniboxOnNtp"); - } else { - RecordUserAction.record("MobileFocusedOmniboxNotOnNtp"); - } - } - mHasRecordedUrlFocusSource = true; - } - @Override public void onTabLoadingNTP(NewTabPage ntp) { ntp.setFakeboxDelegate(this);
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/preferences/privacy/PrivacyPreferences.java b/chrome/android/java/src/org/chromium/chrome/browser/preferences/privacy/PrivacyPreferences.java index 021ece74..a4540e60e 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/preferences/privacy/PrivacyPreferences.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/preferences/privacy/PrivacyPreferences.java
@@ -26,7 +26,6 @@ import org.chromium.chrome.browser.preferences.PrefServiceBridge; import org.chromium.chrome.browser.preferences.Preferences; import org.chromium.chrome.browser.profiles.Profile; -import org.chromium.chrome.browser.safebrowsing.SafeBrowsingFieldTrial; /** * Fragment to keep track of the all the privacy related preferences. @@ -143,12 +142,6 @@ safeBrowsingPref.setOnPreferenceChangeListener(this); safeBrowsingPref.setManagedPreferenceDelegate(mManagedPreferenceDelegate); - if (!SafeBrowsingFieldTrial.isEnabled()) { - preferenceScreen.removePreference( - findPreference(PREF_SAFE_BROWSING_EXTENDED_REPORTING)); - preferenceScreen.removePreference(findPreference(PREF_SAFE_BROWSING)); - } - ButtonPreference clearBrowsingData = (ButtonPreference) findPreference(PREF_CLEAR_BROWSING_DATA); clearBrowsingData.setOnPreferenceClickListener(new OnPreferenceClickListener() { @@ -234,16 +227,12 @@ CheckBoxPreference extendedReportingPref = (CheckBoxPreference) findPreference(PREF_SAFE_BROWSING_EXTENDED_REPORTING); - if (extendedReportingPref != null) { - extendedReportingPref.setChecked( - prefServiceBridge.isSafeBrowsingExtendedReportingEnabled()); - } + extendedReportingPref.setChecked( + prefServiceBridge.isSafeBrowsingExtendedReportingEnabled()); CheckBoxPreference safeBrowsingPref = (CheckBoxPreference) findPreference(PREF_SAFE_BROWSING); - if (safeBrowsingPref != null) { - safeBrowsingPref.setChecked(prefServiceBridge.isSafeBrowsingEnabled()); - } + safeBrowsingPref.setChecked(prefServiceBridge.isSafeBrowsingEnabled()); Preference doNotTrackPref = findPreference(PREF_DO_NOT_TRACK); if (prefServiceBridge.isDoNotTrackEnabled()) {
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/profiles/MostVisitedSites.java b/chrome/android/java/src/org/chromium/chrome/browser/profiles/MostVisitedSites.java index c290dac6..176b3f6 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/profiles/MostVisitedSites.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/profiles/MostVisitedSites.java
@@ -139,11 +139,9 @@ * Records metrics about which types of tiles are displayed. * @param tileTypes An array of values from MostVisitedTileType indicating the type of each * tile that's currently showing. - * @paral isIconMode Whether the icon-based version of the NTP is showing (as opposed to the - * thumbnail-based version). */ - public void recordTileTypeMetrics(int[] tileTypes, boolean isIconMode) { - nativeRecordTileTypeMetrics(mNativeMostVisitedSites, tileTypes, isIconMode); + public void recordTileTypeMetrics(int[] tileTypes) { + nativeRecordTileTypeMetrics(mNativeMostVisitedSites, tileTypes); } /** @@ -162,8 +160,7 @@ private native void nativeGetURLThumbnail(long nativeMostVisitedSites, String url, ThumbnailCallback callback); private native void nativeBlacklistUrl(long nativeMostVisitedSites, String url); - private native void nativeRecordTileTypeMetrics(long nativeMostVisitedSites, int[] tileTypes, - boolean isIconMode); + private native void nativeRecordTileTypeMetrics(long nativeMostVisitedSites, int[] tileTypes); private native void nativeRecordOpenedMostVisitedItem(long nativeMostVisitedSites, int index, int tileType);
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/safebrowsing/SafeBrowsingFieldTrial.java b/chrome/android/java/src/org/chromium/chrome/browser/safebrowsing/SafeBrowsingFieldTrial.java deleted file mode 100644 index 5935f72..0000000 --- a/chrome/android/java/src/org/chromium/chrome/browser/safebrowsing/SafeBrowsingFieldTrial.java +++ /dev/null
@@ -1,28 +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.safebrowsing; - -import android.text.TextUtils; - -import org.chromium.components.variations.VariationsAssociatedData; - -/** - * Field Trial support for Safe Browsing on Chrome for Android. - */ -public final class SafeBrowsingFieldTrial { - private static final String FIELD_TRIAL_NAME = "SafeBrowsingAndroid"; - private static final String ENABLED_PARAM = "enabled"; - private static final String ENABLED_VALUE = "true"; - - /* - * @return whether the SafeBrowsingAndroid field trial is marked as "enabled" - */ - public static boolean isEnabled() { - return TextUtils.equals(ENABLED_VALUE, - VariationsAssociatedData.getVariationParamValue(FIELD_TRIAL_NAME, ENABLED_PARAM)); - } - - private SafeBrowsingFieldTrial() {} -}
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/signin/SigninHelper.java b/chrome/android/java/src/org/chromium/chrome/browser/signin/SigninHelper.java index f8f658e2..e3fbd3438 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/signin/SigninHelper.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/signin/SigninHelper.java
@@ -22,7 +22,6 @@ import org.chromium.chrome.browser.profiles.Profile; import org.chromium.chrome.browser.signin.SigninManager.SignInFlowObserver; import org.chromium.chrome.browser.sync.ProfileSyncService; -import org.chromium.chrome.browser.sync.SyncController; import org.chromium.sync.AndroidSyncSettings; import org.chromium.sync.signin.AccountManagerHelper; import org.chromium.sync.signin.ChromeSigninController; @@ -113,7 +112,6 @@ private final OAuth2TokenService mOAuth2TokenService; - @Nullable private final SyncController mSyncController; public static SigninHelper get(Context context) { synchronized (LOCK) { @@ -130,7 +128,6 @@ mSigninManager = SigninManager.get(mContext); mAccountTrackerService = AccountTrackerService.get(mContext); mOAuth2TokenService = OAuth2TokenService.getForProfile(Profile.getLastUsedProfile()); - mSyncController = SyncController.get(context); mChromeSigninController = ChromeSigninController.get(mContext); } @@ -266,13 +263,10 @@ public void onSigninComplete() { if (mProfileSyncService != null) { mProfileSyncService.setSetupInProgress(false); - } - - if (mSyncController != null) { if (isSyncWanted) { - mSyncController.start(); + mProfileSyncService.requestStart(); } else { - mSyncController.stop(); + mProfileSyncService.requestStop(); } }
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/signin/SigninManager.java b/chrome/android/java/src/org/chromium/chrome/browser/signin/SigninManager.java index 5fa4567..97026a51 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/signin/SigninManager.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/signin/SigninManager.java
@@ -25,7 +25,6 @@ import org.chromium.chrome.R; import org.chromium.chrome.browser.notifications.GoogleServicesNotificationController; import org.chromium.chrome.browser.sync.ProfileSyncService; -import org.chromium.chrome.browser.sync.SyncController; import org.chromium.sync.AndroidSyncSettings; import org.chromium.sync.signin.ChromeSigninController; @@ -503,7 +502,7 @@ if (profileSyncService != null) { profileSyncService.setSetupInProgress( signInSync == SIGNIN_SYNC_SETUP_IN_PROGRESS); - SyncController.get(mContext).start(); + profileSyncService.requestStart(); } if (observer != null) observer.onSigninComplete();
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/sync/SyncController.java b/chrome/android/java/src/org/chromium/chrome/browser/sync/SyncController.java index d3a8c6a..e988f75 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/sync/SyncController.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/sync/SyncController.java
@@ -4,7 +4,6 @@ package org.chromium.chrome.browser.sync; -import android.accounts.Account; import android.app.Activity; import android.content.Context; @@ -19,13 +18,10 @@ import org.chromium.chrome.browser.identity.UniqueIdentificationGeneratorFactory; import org.chromium.chrome.browser.invalidation.InvalidationController; import org.chromium.chrome.browser.signin.AccountManagementFragment; -import org.chromium.chrome.browser.signin.SigninManager; -import org.chromium.chrome.browser.signin.SigninManager.SignInFlowObserver; import org.chromium.chrome.browser.sync.ui.PassphraseActivity; import org.chromium.sync.AndroidSyncSettings; import org.chromium.sync.ModelType; import org.chromium.sync.PassphraseType; -import org.chromium.sync.signin.AccountManagerHelper; import org.chromium.sync.signin.ChromeSigninController; import javax.annotation.Nullable; @@ -121,79 +117,15 @@ } /** - * Trigger Chromium sign in of the given account. - * - * This also ensure that sync setup is not in progress anymore, so sync will start after - * sync initialization has happened. - * - * @param activity the current activity. - * @param accountName the full account name. - */ - @VisibleForTesting - public void signIn(Activity activity, String accountName) { - final Account account = AccountManagerHelper.createAccountFromName(accountName); - - // The SigninManager handles most of the sign-in flow, and doFinishSignIn handles the - // ChromeShell specific details. - SigninManager signinManager = SigninManager.get(mContext); - signinManager.onFirstRunCheckDone(); - final boolean passive = false; - signinManager.startSignIn(activity, account, passive, new SignInFlowObserver() { - @Override - public void onSigninComplete() { - SigninManager.get(mContext).logInSignedInUser(); - mProfileSyncService.setSetupInProgress(false); - start(); - } - - @Override - public void onSigninCancelled() { - stop(); - } - }); - } - - /** * Updates sync to reflect the state of the Android sync settings. */ - public void updateSyncStateFromAndroid() { - if (AndroidSyncSettings.isSyncEnabled(mContext)) { - start(); - } else { - stop(); - } - } - - /** - * Starts sync if the master sync flag is enabled. - * - * Affects native sync, the invalidation controller, and the Android sync settings. - */ - public void start() { - ThreadUtils.assertOnUiThread(); - if (AndroidSyncSettings.isMasterSyncEnabled(mContext)) { - Log.d(TAG, "Enabling sync"); - InvalidationController.get(mContext).ensureStartedAndUpdateRegisteredTypes(); + private void updateSyncStateFromAndroid() { + boolean isSyncEnabled = AndroidSyncSettings.isSyncEnabled(mContext); + if (isSyncEnabled == mProfileSyncService.isSyncRequested()) return; + if (isSyncEnabled) { mProfileSyncService.requestStart(); - AndroidSyncSettings.enableChromeSync(mContext); - } - } - - /** - * Stops Sync if a user is currently signed in. - * - * Affects native sync, the invalidation controller, and the Android sync settings. - */ - public void stop() { - ThreadUtils.assertOnUiThread(); - Log.d(TAG, "Disabling sync"); - InvalidationController.get(mContext).stop(); - mProfileSyncService.requestStop(); - if (AndroidSyncSettings.isMasterSyncEnabled(mContext)) { - // Only disable Android's Chrome sync setting if we weren't disabled - // by the master sync setting. This way, when master sync is enabled - // they will both be on and sync will start again. - AndroidSyncSettings.disableChromeSync(mContext); + } else { + mProfileSyncService.requestStop(); } } @@ -206,12 +138,24 @@ @Override public void syncStateChanged() { ThreadUtils.assertOnUiThread(); - // Make the Java state match the native state. + InvalidationController invalidationController = InvalidationController.get(mContext); if (mProfileSyncService.isSyncRequested()) { - AndroidSyncSettings.enableChromeSync(mContext); + if (!invalidationController.isStarted()) { + invalidationController.ensureStartedAndUpdateRegisteredTypes(); + } + if (!AndroidSyncSettings.isSyncEnabled(mContext)) { + assert AndroidSyncSettings.isMasterSyncEnabled(mContext); + AndroidSyncSettings.enableChromeSync(mContext); + } } else { - if (AndroidSyncSettings.isMasterSyncEnabled(mContext)) { - // See comment in stop(). + if (invalidationController.isStarted()) { + invalidationController.stop(); + } + if (AndroidSyncSettings.isSyncEnabled(mContext)) { + // Both Android's master and Chrome sync setting are enabled, so we want to disable + // the Chrome sync setting to match isSyncRequested. We have to be careful not to + // disable it when isSyncRequested becomes false due to master sync being disabled + // so that sync will turn back on if master sync is re-enabled. AndroidSyncSettings.disableChromeSync(mContext); } }
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/sync/ui/SyncCustomizationFragment.java b/chrome/android/java/src/org/chromium/chrome/browser/sync/ui/SyncCustomizationFragment.java index 7b29116..a175a3a 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/sync/ui/SyncCustomizationFragment.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/sync/ui/SyncCustomizationFragment.java
@@ -31,7 +31,6 @@ import org.chromium.chrome.browser.invalidation.InvalidationController; import org.chromium.chrome.browser.preferences.ChromeSwitchPreference; import org.chromium.chrome.browser.sync.ProfileSyncService; -import org.chromium.chrome.browser.sync.SyncController; import org.chromium.sync.AndroidSyncSettings; import org.chromium.sync.ModelType; import org.chromium.sync.PassphraseType; @@ -151,11 +150,10 @@ @Override public boolean onPreferenceChange(Preference preference, Object newValue) { assert canDisableSync(); - SyncController syncController = SyncController.get(getActivity()); if ((boolean) newValue) { - syncController.start(); + mProfileSyncService.requestStart(); } else { - syncController.stop(); + mProfileSyncService.requestStop(); } // Must be done asynchronously because the switch state isn't updated // until after this function exits. @@ -562,7 +560,7 @@ || !canDisableSync()) { return false; } - SyncController.get(getActivity()).stop(); + mProfileSyncService.requestStop(); mSyncSwitchPreference.setChecked(false); // setChecked doesn't trigger the callback, so update manually. updateSyncStateFromSwitch();
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/tab/Tab.java b/chrome/android/java/src/org/chromium/chrome/browser/tab/Tab.java index 8066da2..84c53ae 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/tab/Tab.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/tab/Tab.java
@@ -2015,8 +2015,8 @@ private void destroyNativePage() { if (mNativePage == null) return; + if (mTabView != null) mTabView.removeView(mNativePage.getView()); - mTabView.removeView(mNativePage.getView()); mNativePage.destroy(); mNativePage = null; }
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/BindingManagerInDocumentModeIntegrationTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/BindingManagerInDocumentModeIntegrationTest.java index 742ae00..beb0bc84 100644 --- a/chrome/android/javatests/src/org/chromium/chrome/browser/BindingManagerInDocumentModeIntegrationTest.java +++ b/chrome/android/javatests/src/org/chromium/chrome/browser/BindingManagerInDocumentModeIntegrationTest.java
@@ -43,12 +43,12 @@ void assertIsInForeground(final int pid) { try { - assertTrue(CriteriaHelper.pollForCriteria(new Criteria() { + CriteriaHelper.pollForCriteria(new Criteria() { @Override public boolean isSatisfied() { return mProcessInForegroundMap.get(pid); } - })); + }); } catch (InterruptedException ie) { fail(); } @@ -56,12 +56,12 @@ void assertIsInBackground(final int pid) { try { - assertTrue(CriteriaHelper.pollForCriteria(new Criteria() { + CriteriaHelper.pollForCriteria(new Criteria() { @Override public boolean isSatisfied() { return !mProcessInForegroundMap.get(pid); } - })); + }); } catch (InterruptedException ie) { fail(); } @@ -69,12 +69,12 @@ void assertSetInForegroundWasCalled(String message, final int pid) { try { - assertTrue(message, CriteriaHelper.pollForCriteria(new Criteria() { + CriteriaHelper.pollForCriteria(new Criteria(message) { @Override public boolean isSatisfied() { return mProcessInForegroundMap.indexOfKey(pid) >= 0; } - })); + }); } catch (InterruptedException ie) { fail(); } @@ -82,12 +82,12 @@ void assertIsReleaseAllModerateBindingsCalled() { try { - assertTrue(CriteriaHelper.pollForCriteria(new Criteria() { + CriteriaHelper.pollForCriteria(new Criteria() { @Override public boolean isSatisfied() { return mIsReleaseAllModerateBindingsCalled; } - })); + }); } catch (InterruptedException ie) { fail(); } @@ -218,13 +218,13 @@ assertTrue(ChildProcessLauncher.crashProcessForTesting( tab.getContentViewCore().getCurrentRenderProcessId())); - assertTrue("Renderer crash wasn't noticed by the browser.", - CriteriaHelper.pollForCriteria(new Criteria() { + CriteriaHelper.pollForCriteria( + new Criteria("Renderer crash wasn't noticed by the browser.") { @Override public boolean isSatisfied() { return tab.getContentViewCore().getCurrentRenderProcessId() == 0; } - })); + }); // Reload the tab, respawning the renderer. getInstrumentation().runOnMainSync(new Runnable() { @@ -235,13 +235,13 @@ }); // Wait until the process is spawned and its visibility is determined. - assertTrue("Process for the crashed tab was not respawned.", - CriteriaHelper.pollForCriteria(new Criteria() { + CriteriaHelper.pollForCriteria( + new Criteria("Process for the crashed tab was not respawned.") { @Override public boolean isSatisfied() { return tab.getContentViewCore().getCurrentRenderProcessId() != 0; } - })); + }); mBindingManager.assertSetInForegroundWasCalled( "isInForeground() was not called for the process.",
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/BindingManagerIntegrationTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/BindingManagerIntegrationTest.java index 078f8d9..b4d54a7f 100644 --- a/chrome/android/javatests/src/org/chromium/chrome/browser/BindingManagerIntegrationTest.java +++ b/chrome/android/javatests/src/org/chromium/chrome/browser/BindingManagerIntegrationTest.java
@@ -50,12 +50,12 @@ void assertIsInForeground(final int pid) { try { - assertTrue(CriteriaHelper.pollForCriteria(new Criteria() { + CriteriaHelper.pollForCriteria(new Criteria() { @Override public boolean isSatisfied() { return mProcessInForegroundMap.get(pid); } - })); + }); } catch (InterruptedException ie) { fail(); } @@ -63,12 +63,12 @@ void assertIsInBackground(final int pid) { try { - assertTrue(CriteriaHelper.pollForCriteria(new Criteria() { + CriteriaHelper.pollForCriteria(new Criteria() { @Override public boolean isSatisfied() { return !mProcessInForegroundMap.get(pid); } - })); + }); } catch (InterruptedException ie) { fail(); } @@ -76,12 +76,12 @@ void assertSetInForegroundWasCalled(String message, final int pid) { try { - assertTrue(message, CriteriaHelper.pollForCriteria(new Criteria() { + CriteriaHelper.pollForCriteria(new Criteria(message) { @Override public boolean isSatisfied() { return mProcessInForegroundMap.indexOfKey(pid) >= 0; } - })); + }); } catch (InterruptedException ie) { fail(); } @@ -89,12 +89,12 @@ void assertIsReleaseAllModerateBindingsCalled() { try { - assertTrue(CriteriaHelper.pollForCriteria(new Criteria() { + CriteriaHelper.pollForCriteria(new Criteria() { @Override public boolean isSatisfied() { return mIsReleaseAllModerateBindingsCalled; } - })); + }); } catch (InterruptedException ie) { fail(); } @@ -206,15 +206,14 @@ // Wait for the new tab animations on phones to finish. if (!DeviceFormFactor.isTablet(getActivity())) { final ChromeActivity activity = getActivity(); - assertTrue("Did not finish animation", - CriteriaHelper.pollForUIThreadCriteria(new Criteria() { - @Override - public boolean isSatisfied() { - Layout layout = activity.getCompositorViewHolder() - .getLayoutManager().getActiveLayout(); - return !layout.isLayoutAnimating(); - } - })); + CriteriaHelper.pollForUIThreadCriteria(new Criteria("Did not finish animation") { + @Override + public boolean isSatisfied() { + Layout layout = activity.getCompositorViewHolder() + .getLayoutManager().getActiveLayout(); + return !layout.isLayoutAnimating(); + } + }); } getInstrumentation().waitForIdleSync(); @@ -278,15 +277,14 @@ // Wait for the new tab animations on phones to finish. if (!DeviceFormFactor.isTablet(getActivity())) { final ChromeActivity activity = getActivity(); - assertTrue("Did not finish animation", - CriteriaHelper.pollForUIThreadCriteria(new Criteria() { - @Override - public boolean isSatisfied() { - Layout layout = activity.getCompositorViewHolder() - .getLayoutManager().getActiveLayout(); - return !layout.isLayoutAnimating(); - } - })); + CriteriaHelper.pollForUIThreadCriteria(new Criteria("Did not finish animation") { + @Override + public boolean isSatisfied() { + Layout layout = activity.getCompositorViewHolder() + .getLayoutManager().getActiveLayout(); + return !layout.isLayoutAnimating(); + } + }); } getInstrumentation().waitForIdleSync(); @@ -311,13 +309,13 @@ assertTrue(ChildProcessLauncher.crashProcessForTesting( tabs[1].getContentViewCore().getCurrentRenderProcessId())); - assertTrue("Renderer crash wasn't noticed by the browser.", - CriteriaHelper.pollForCriteria(new Criteria() { + CriteriaHelper.pollForCriteria( + new Criteria("Renderer crash wasn't noticed by the browser.") { @Override public boolean isSatisfied() { return tabs[1].getContentViewCore().getCurrentRenderProcessId() == 0; } - })); + }); // Switch to the tab that crashed in background. getInstrumentation().runOnMainSync(new Runnable() { @@ -328,13 +326,13 @@ }); // Wait until the process is spawned and its visibility is determined. - assertTrue("Process for the crashed tab was not respawned.", - CriteriaHelper.pollForCriteria(new Criteria() { + CriteriaHelper.pollForCriteria( + new Criteria("Process for the crashed tab was not respawned.") { @Override public boolean isSatisfied() { return tabs[1].getContentViewCore().getCurrentRenderProcessId() != 0; } - })); + }); mBindingManager.assertSetInForegroundWasCalled( "isInForeground() was not called for the process.", @@ -377,13 +375,13 @@ assertTrue(ChildProcessLauncher.crashProcessForTesting( tab.getContentViewCore().getCurrentRenderProcessId())); - assertTrue("Renderer crash wasn't noticed by the browser.", - CriteriaHelper.pollForCriteria(new Criteria() { + CriteriaHelper.pollForCriteria( + new Criteria("Renderer crash wasn't noticed by the browser.") { @Override public boolean isSatisfied() { return tab.getContentViewCore().getCurrentRenderProcessId() == 0; } - })); + }); // Reload the tab, respawning the renderer. getInstrumentation().runOnMainSync(new Runnable() { @@ -394,13 +392,13 @@ }); // Wait until the process is spawned and its visibility is determined. - assertTrue("Process for the crashed tab was not respawned.", - CriteriaHelper.pollForCriteria(new Criteria() { + CriteriaHelper.pollForCriteria( + new Criteria("Process for the crashed tab was not respawned.") { @Override public boolean isSatisfied() { return tab.getContentViewCore().getCurrentRenderProcessId() != 0; } - })); + }); mBindingManager.assertSetInForegroundWasCalled( "isInForeground() was not called for the process.", @@ -536,7 +534,7 @@ tabs[0] = getActivity().getActivityTab(); singleClickView(tabs[0].getView()); - assertTrue("Child tab isn't opened.", CriteriaHelper.pollForCriteria(new Criteria() { + CriteriaHelper.pollForCriteria(new Criteria("Child tab isn't opened.") { @Override public boolean isSatisfied() { return getActivity().getCurrentTabModel().getCount() == 2 @@ -547,7 +545,7 @@ .getCurrentRenderProcessId() != 0; } - })); + }); tabs[1] = getActivity().getActivityTab(); assertEquals(tabs[0].getContentViewCore().getCurrentRenderProcessId(), tabs[1].getContentViewCore().getCurrentRenderProcessId()); @@ -564,13 +562,13 @@ assertTrue(ChildProcessLauncher.crashProcessForTesting( tabs[1].getContentViewCore().getCurrentRenderProcessId())); - assertTrue("Renderer crash wasn't noticed by the browser.", - CriteriaHelper.pollForCriteria(new Criteria() { + CriteriaHelper.pollForCriteria( + new Criteria("Renderer crash wasn't noticed by the browser.") { @Override public boolean isSatisfied() { return tabs[1].getContentViewCore().getCurrentRenderProcessId() == 0; } - })); + }); // Reload the tab, respawning the renderer. getInstrumentation().runOnMainSync(new Runnable() { @Override @@ -580,13 +578,13 @@ }); // Wait until the process is spawned and its visibility is determined. - assertTrue("Process for the crashed tab was not respawned.", - CriteriaHelper.pollForCriteria(new Criteria() { + CriteriaHelper.pollForCriteria( + new Criteria("Process for the crashed tab was not respawned.") { @Override public boolean isSatisfied() { return tabs[1].getContentViewCore().getCurrentRenderProcessId() != 0; } - })); + }); mBindingManager.assertSetInForegroundWasCalled( "setInForeground() was not called for the process.",
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/ChromeTabbedActivityLollipopAndAboveTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/ChromeTabbedActivityLollipopAndAboveTest.java index 87d6146..a7b6ddc 100644 --- a/chrome/android/javatests/src/org/chromium/chrome/browser/ChromeTabbedActivityLollipopAndAboveTest.java +++ b/chrome/android/javatests/src/org/chromium/chrome/browser/ChromeTabbedActivityLollipopAndAboveTest.java
@@ -40,13 +40,13 @@ // Make sure that ChromeTabbedActivity started up. Context context = getInstrumentation().getTargetContext(); assertFalse(FeatureUtilities.isDocumentMode(context)); - assertTrue(CriteriaHelper.pollForUIThreadCriteria(new Criteria() { + CriteriaHelper.pollForUIThreadCriteria(new Criteria() { @Override public boolean isSatisfied() { Activity lastActivity = ApplicationStatus.getLastTrackedFocusedActivity(); return lastActivity instanceof ChromeTabbedActivity; } - })); + }); // Try launching a DocumentActivity. Runnable runnable = new Runnable() { @@ -66,7 +66,7 @@ getInstrumentation(), DocumentActivity.class, runnable); // ApplicationStatus should note that the DocumentActivity isn't running anymore. - assertTrue(CriteriaHelper.pollForUIThreadCriteria(new Criteria() { + CriteriaHelper.pollForUIThreadCriteria(new Criteria() { @Override public boolean isSatisfied() { List<WeakReference<Activity>> activities = ApplicationStatus.getRunningActivities(); @@ -75,7 +75,7 @@ } return true; } - })); + }); } @Override
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/ContentViewFocusTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/ContentViewFocusTest.java index 6abcc3f..ee23283 100644 --- a/chrome/android/javatests/src/org/chromium/chrome/browser/ContentViewFocusTest.java +++ b/chrome/android/javatests/src/org/chromium/chrome/browser/ContentViewFocusTest.java
@@ -106,14 +106,14 @@ } }); - assertTrue("Layout still requesting Tab Android view be attached", - CriteriaHelper.pollForUIThreadCriteria(new Criteria() { + CriteriaHelper.pollForUIThreadCriteria( + new Criteria("Layout still requesting Tab Android view be attached") { @Override public boolean isSatisfied() { LayoutManager driver = getActivity().getLayoutManager(); return !driver.getActiveLayout().shouldDisplayContentOverlay(); } - })); + }); // Make sure the view loses focus. It is immediately given focus back // because it's the only focusable view. @@ -127,14 +127,14 @@ } }); - assertTrue("Layout not requesting Tab Android view be attached", - CriteriaHelper.pollForUIThreadCriteria(new Criteria() { + CriteriaHelper.pollForUIThreadCriteria( + new Criteria("Layout not requesting Tab Android view be attached") { @Override public boolean isSatisfied() { LayoutManager driver = getActivity().getLayoutManager(); return driver.getActiveLayout().shouldDisplayContentOverlay(); } - })); + }); assertTrue("Content view didn't regain focus", blockForFocusChanged()); assertFalse("Unexpected focus change", haveFocusChanges());
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/HistoryUITest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/HistoryUITest.java index 748cb1e1..c24aa9a 100644 --- a/chrome/android/javatests/src/org/chromium/chrome/browser/HistoryUITest.java +++ b/chrome/android/javatests/src/org/chromium/chrome/browser/HistoryUITest.java
@@ -143,7 +143,7 @@ */ private void assertResultCountReaches(final ContentViewCore cvc, final int expected) throws InterruptedException { - assertTrue(CriteriaHelper.pollForCriteria( + CriteriaHelper.pollForCriteria( new Criteria() { @Override public boolean isSatisfied() { @@ -157,7 +157,7 @@ return false; } } - })); + }); } /* @@ -280,13 +280,12 @@ assertNotNull("Could not find Clear button.", clearButton); TestTouchUtils.performClickOnMainSync(getInstrumentation(), clearButton); - assertTrue("Clear browsing dialog never hidden", - CriteriaHelper.pollForUIThreadCriteria(new Criteria() { - @Override - public boolean isSatisfied() { - return !clearBrowsingFragment.isVisible(); - } - })); + CriteriaHelper.pollForUIThreadCriteria(new Criteria("Clear browsing dialog never hidden") { + @Override + public boolean isSatisfied() { + return !clearBrowsingFragment.isVisible(); + } + }); final ChromeActivity mainActivity = ActivityUtils.waitForActivity( getInstrumentation(), getActivity().getClass(), new Runnable() { @@ -301,14 +300,13 @@ } }); assertNotNull("Main never resumed", mainActivity); - assertTrue("Main tab never restored", CriteriaHelper.pollForUIThreadCriteria( - new Criteria() { - @Override - public boolean isSatisfied() { - return mainActivity.getActivityTab() != null - && !mainActivity.getActivityTab().isFrozen(); - } - })); + CriteriaHelper.pollForUIThreadCriteria(new Criteria("Main tab never restored") { + @Override + public boolean isSatisfied() { + return mainActivity.getActivityTab() != null + && !mainActivity.getActivityTab().isFrozen(); + } + }); JavaScriptUtils.executeJavaScriptAndWaitForResult( mainActivity.getCurrentContentViewCore().getWebContents(), "reloadHistory()"); assertResultCountReaches(getActivity().getCurrentContentViewCore(), 0);
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/ItemChooserDialogTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/ItemChooserDialogTest.java index 8559fda..f7e15e55 100644 --- a/chrome/android/javatests/src/org/chromium/chrome/browser/ItemChooserDialogTest.java +++ b/chrome/android/javatests/src/org/chromium/chrome/browser/ItemChooserDialogTest.java
@@ -77,8 +77,8 @@ return dialog; } - private void selectItem(Dialog dialog, int position, final String expectedItemId) - throws InterruptedException { + private void selectItem(Dialog dialog, int position, final String expectedItemId, + final boolean expectedEnabledState) throws InterruptedException { final ListView items = (ListView) dialog.findViewById(R.id.items); final Button button = (Button) dialog.findViewById(R.id.positive); @@ -96,10 +96,12 @@ CriteriaHelper.pollForUIThreadCriteria(new Criteria() { @Override public boolean isSatisfied() { - return button.isEnabled(); + return button.isEnabled() == expectedEnabledState; } }); + if (!expectedEnabledState) return; + // TODO(finnur): Stop using coordinates 10, 10 when crbug.com/532237 is fixed. TouchCommon.singleClickView(button, 10, 10); @@ -151,7 +153,7 @@ assertFalse(button.isEnabled()); // Select the first item and verify it got selected. - selectItem(dialog, 1, "key"); + selectItem(dialog, 1, "key", true); mChooserDialog.dismiss(); } @@ -169,9 +171,9 @@ // Disable one item and try to select it. mChooserDialog.setEnabled("key", false); - selectItem(dialog, 1, "None"); + selectItem(dialog, 1, "None", false); // The other is still selectable. - selectItem(dialog, 2, "key2"); + selectItem(dialog, 2, "key2", true); mChooserDialog.dismiss(); }
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/ModalDialogTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/ModalDialogTest.java index 0ffc5d8..c080911 100644 --- a/chrome/android/javatests/src/org/chromium/chrome/browser/ModalDialogTest.java +++ b/chrome/android/javatests/src/org/chromium/chrome/browser/ModalDialogTest.java
@@ -282,10 +282,8 @@ }); // Closing the tab should have dismissed the dialog. - boolean criteriaSatisfied = CriteriaHelper.pollForCriteria( - new JavascriptAppModalDialogShownCriteria(false)); - assertTrue("The dialog should have been dismissed when its tab was closed.", - criteriaSatisfied); + CriteriaHelper.pollForCriteria(new JavascriptAppModalDialogShownCriteria( + "The dialog should have been dismissed when its tab was closed.", false)); } /** @@ -307,9 +305,8 @@ helper.evaluateJavaScriptForTests( getActivity().getCurrentContentViewCore().getWebContents(), script); - boolean criteriaSatisfied = CriteriaHelper.pollForCriteria( - new JavascriptAppModalDialogShownCriteria(true)); - assertTrue("Could not spawn or locate a modal dialog.", criteriaSatisfied); + CriteriaHelper.pollForCriteria(new JavascriptAppModalDialogShownCriteria( + "Could not spawn or locate a modal dialog.", true)); return helper; } @@ -344,10 +341,11 @@ }); } - private static class JavascriptAppModalDialogShownCriteria implements Criteria { + private static class JavascriptAppModalDialogShownCriteria extends Criteria { private final boolean mShouldBeShown; - public JavascriptAppModalDialogShownCriteria(boolean shouldBeShown) { + public JavascriptAppModalDialogShownCriteria(String error, boolean shouldBeShown) { + super(error); mShouldBeShown = shouldBeShown; }
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/NavigateTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/NavigateTest.java index 672c12f..be7e7fa 100644 --- a/chrome/android/javatests/src/org/chromium/chrome/browser/NavigateTest.java +++ b/chrome/android/javatests/src/org/chromium/chrome/browser/NavigateTest.java
@@ -59,7 +59,7 @@ throws InterruptedException { new TabLoadObserver(getActivity().getActivityTab(), startUrl).assertLoaded(); - assertTrue(CriteriaHelper.pollForUIThreadCriteria(new Criteria() { + CriteriaHelper.pollForUIThreadCriteria(new Criteria() { @Override public boolean isSatisfied() { final UrlBar urlBar = (UrlBar) getActivity().findViewById(R.id.url_bar); @@ -68,7 +68,7 @@ return TextUtils.equals(expectedLocation(endUrl), urlBar.getText().toString()) && TextUtils.equals(endUrl, getActivity().getActivityTab().getUrl()); } - })); + }); } /** @@ -91,8 +91,7 @@ }); final LocationBarLayout locationBar = (LocationBarLayout) getActivity().findViewById(R.id.location_bar); - assertTrue("Omnibox Suggestions never shown.", - OmniboxTestUtils.waitForOmniboxSuggestions(locationBar)); + OmniboxTestUtils.waitForOmniboxSuggestions(locationBar); Tab currentTab = getActivity().getActivityTab(); final CallbackHelper loadedCallback = new CallbackHelper(); @@ -261,12 +260,12 @@ TestHttpServerClient.getUrl("chrome/test/data/android/redirect/one.html"); typeInOmniboxAndNavigate(initialUrl); - assertTrue(CriteriaHelper.pollForCriteria(new Criteria() { + CriteriaHelper.pollForCriteria(new Criteria() { @Override public boolean isSatisfied() { return getActivity().getActivityTab().getUrl().equals(redirectedUrl); } - })); + }); } /** @@ -291,12 +290,12 @@ typeInOmniboxAndNavigate(initialUrl); // Now intent fallback should be triggered assuming 'non_existent' scheme cannot be handled. - assertTrue(CriteriaHelper.pollForCriteria(new Criteria() { + CriteriaHelper.pollForCriteria(new Criteria() { @Override public boolean isSatisfied() { return getActivity().getActivityTab().getUrl().equals(targetUrl); } - })); + }); // Check if Java redirections were removed from the history. // Note that if we try to go back in the test: NavigateToEntry() is called, but @@ -416,13 +415,12 @@ // Wait for the url to change. final Tab tab = TabModelUtils.getCurrentTab(model); assertWaitForPageScaleFactorMatch(0.75f); - assertTrue("Page url didn't change", - CriteriaHelper.pollForCriteria(new Criteria() { - @Override - public boolean isSatisfied() { - return mockedUrl.equals(getTabUrlOnUIThread(tab)); - } - }, 5000, 50)); + CriteriaHelper.pollForCriteria(new Criteria("Page url didn't change") { + @Override + public boolean isSatisfied() { + return mockedUrl.equals(getTabUrlOnUIThread(tab)); + } + }, 5000, 50); // Make sure that we're showing new content now. assertEquals("Still showing spoofed data", "\"Real\"", getTabBodyText(tab));
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/NavigationPopupTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/NavigationPopupTest.java index 45419d1..df79606c 100644 --- a/chrome/android/javatests/src/org/chromium/chrome/browser/NavigationPopupTest.java +++ b/chrome/android/javatests/src/org/chromium/chrome/browser/NavigationPopupTest.java
@@ -233,19 +233,18 @@ } }); - assertTrue("All favicons did not get updated.", - CriteriaHelper.pollForUIThreadCriteria(new Criteria() { - @Override - public boolean isSatisfied() { - NavigationHistory history = controller.mHistory; - for (int i = 0; i < history.getEntryCount(); i++) { - if (history.getEntryAtIndex(i).getFavicon() == null) { - return false; - } - } - return true; + CriteriaHelper.pollForUIThreadCriteria(new Criteria("All favicons did not get updated.") { + @Override + public boolean isSatisfied() { + NavigationHistory history = controller.mHistory; + for (int i = 0; i < history.getEntryCount(); i++) { + if (history.getEntryAtIndex(i).getFavicon() == null) { + return false; } - })); + } + return true; + } + }); ThreadUtils.runOnUiThreadBlocking(new Runnable() { @Override
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/PopupTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/PopupTest.java index 6fd25ef9..b91c3d0 100644 --- a/chrome/android/javatests/src/org/chromium/chrome/browser/PopupTest.java +++ b/chrome/android/javatests/src/org/chromium/chrome/browser/PopupTest.java
@@ -60,12 +60,12 @@ @Feature({"Popup"}) public void testPopupInfobarAppears() throws Exception { loadUrl(POPUP_HTML_FILENAME); - assertTrue(CriteriaHelper.pollForUIThreadCriteria(new Criteria() { + CriteriaHelper.pollForUIThreadCriteria(new Criteria() { @Override public boolean isSatisfied() { return getNumInfobarsShowing() == 1; } - })); + }); } @MediumTest @@ -78,12 +78,12 @@ : getActivity().getTabModelSelector(); loadUrl(POPUP_HTML_FILENAME); - assertTrue(CriteriaHelper.pollForUIThreadCriteria(new Criteria() { + CriteriaHelper.pollForUIThreadCriteria(new Criteria() { @Override public boolean isSatisfied() { return getNumInfobarsShowing() == 1; } - })); + }); assertEquals(1, selector.getTotalTabCount()); final InfoBarContainer container = selector.getCurrentTab().getInfoBarContainer(); ArrayList<InfoBar> infobars = container.getInfoBars(); @@ -91,37 +91,37 @@ // Wait until the animations are done, then click the "open popups" button. final InfoBar infobar = infobars.get(0); - assertTrue(CriteriaHelper.pollForUIThreadCriteria(new Criteria() { + CriteriaHelper.pollForUIThreadCriteria(new Criteria() { @Override public boolean isSatisfied() { return !container.isAnimating(); } - })); + }); TouchCommon.singleClickView(infobar.getView().findViewById(R.id.button_primary)); // Document mode popups appear slowly and sequentially to prevent Android from throwing them // away, so use a long timeout. http://crbug.com/498920. - assertTrue(CriteriaHelper.pollForUIThreadCriteria(new Criteria() { + CriteriaHelper.pollForUIThreadCriteria(new Criteria() { @Override public boolean isSatisfied() { if (getNumInfobarsShowing() != 0) return false; return TextUtils.equals("Popup #3", selector.getCurrentTab().getTitle()); } - }, 7500, CriteriaHelper.DEFAULT_POLLING_INTERVAL)); + }, 7500, CriteriaHelper.DEFAULT_POLLING_INTERVAL); assertEquals(4, selector.getTotalTabCount()); int currentTabId = selector.getCurrentTab().getId(); // Test that revisiting the original page makes popup windows immediately. loadUrl(POPUP_HTML_FILENAME); - assertTrue(CriteriaHelper.pollForUIThreadCriteria(new Criteria() { + CriteriaHelper.pollForUIThreadCriteria(new Criteria() { @Override public boolean isSatisfied() { if (getNumInfobarsShowing() != 0) return false; if (selector.getTotalTabCount() != 7) return false; return TextUtils.equals("Popup #3", selector.getCurrentTab().getTitle()); } - }, 7500, CriteriaHelper.DEFAULT_POLLING_INTERVAL)); + }, 7500, CriteriaHelper.DEFAULT_POLLING_INTERVAL); assertNotSame(currentTabId, selector.getCurrentTab().getId()); } }
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/PowerBroadcastReceiverTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/PowerBroadcastReceiverTest.java index 88658d7d..6d26ffe 100644 --- a/chrome/android/javatests/src/org/chromium/chrome/browser/PowerBroadcastReceiverTest.java +++ b/chrome/android/javatests/src/org/chromium/chrome/browser/PowerBroadcastReceiverTest.java
@@ -102,15 +102,13 @@ /** * Waits to see if the runnable was run. */ - public boolean runnableRan(final MockServiceRunnable runnable) throws Exception { - return CriteriaHelper.pollForCriteria( - new Criteria() { - @Override - public boolean isSatisfied() { - return runnable.mRan; - } - }, - MS_TIMEOUT, MS_INTERVAL); + public void waitForRunnableRan(final MockServiceRunnable runnable) throws Exception { + CriteriaHelper.pollForCriteria(new Criteria() { + @Override + public boolean isSatisfied() { + return runnable.mRan; + } + }, MS_TIMEOUT, MS_INTERVAL); } /** @@ -134,7 +132,7 @@ pauseMain(true); // Check to see that the runnable gets run. - assertTrue("MockServiceRunnable didn't run after resuming Chrome.", runnableRan(runnable)); + waitForRunnableRan(runnable); assertFalse("PowerBroadcastReceiver was still registered.", receiver.isRegistered()); } @@ -157,7 +155,13 @@ pauseMain(false); // Wait enough time for the runnable to run(), if it's still in the handler. - assertFalse("MockServiceRunnable ran after resuming Chrome.", runnableRan(runnable)); + try { + waitForRunnableRan(runnable); + fail("MockServiceRunnable ran after resuming Chrome."); + } catch (AssertionError e) { + // TODO(tedchoc): This is horrible. This test should be rewritten. It should not + // require timing out a criteria to determine success. + } assertFalse("PowerBroadcastReceiver was still registered.", receiver.isRegistered()); } @@ -184,8 +188,13 @@ pauseMain(true); // Wait enough time for the runnable to run(), if it's still in the handler. - boolean ranWhileScreenOff = runnableRan(runnable); - assertFalse("MockServiceRunnable ran even though screen was off.", ranWhileScreenOff); + try { + waitForRunnableRan(runnable); + fail("MockServiceRunnable ran after resuming Chrome."); + } catch (AssertionError e) { + // TODO(tedchoc): This is horrible. This test should be rewritten. It should not + // require timing out a criteria to determine success. + } assertTrue("PowerBroadcastReceiver was not registered.", receiver.isRegistered()); // Pretend to turn the screen on. @@ -194,8 +203,7 @@ receiver.onReceive(main, intent); // Wait enough time for the runnable to run(), if it's still in the handler. - boolean ranWhileScreenOn = runnableRan(runnable); - assertTrue("MockServiceRunnable didn't run when screen turned on.", ranWhileScreenOn); + waitForRunnableRan(runnable); assertFalse("PowerBroadcastReceiver wasn't unregistered.", receiver.isRegistered()); } }
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/RepostFormWarningTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/RepostFormWarningTest.java index d385b6a..559ddf9 100644 --- a/chrome/android/javatests/src/org/chromium/chrome/browser/RepostFormWarningTest.java +++ b/chrome/android/javatests/src/org/chromium/chrome/browser/RepostFormWarningTest.java
@@ -114,13 +114,13 @@ } private AlertDialog waitForRepostFormWarningDialog() throws InterruptedException { - assertTrue("Form resubmission warning not shown", CriteriaHelper.pollForUIThreadCriteria( - new Criteria() { + CriteriaHelper.pollForUIThreadCriteria( + new Criteria("Form resubmission warning not shown") { @Override public boolean isSatisfied() { return RepostFormWarningDialog.getCurrentDialog() != null; } - })); + }); return ThreadUtils.runOnUiThreadBlockingNoException(new Callable<AlertDialog>() { @Override public AlertDialog call() throws Exception {
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/SelectFileDialogTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/SelectFileDialogTest.java index 62df886..bd6757f 100644 --- a/chrome/android/javatests/src/org/chromium/chrome/browser/SelectFileDialogTest.java +++ b/chrome/android/javatests/src/org/chromium/chrome/browser/SelectFileDialogTest.java
@@ -60,7 +60,11 @@ } } - private class IntentSentCriteria implements Criteria { + private class IntentSentCriteria extends Criteria { + public IntentSentCriteria() { + super("SelectFileDialog never sent an intent."); + } + @Override public boolean isSatisfied() { return mActivityWindowAndroidForTest.lastIntent != null; @@ -89,8 +93,7 @@ mContentViewCore = getActivity().getCurrentContentViewCore(); // TODO(aurimas) remove this wait once crbug.com/179511 is fixed. assertWaitForPageScaleFactorMatch(2); - assertTrue( - DOMUtils.waitForNonZeroNodeBounds(mContentViewCore.getWebContents(), "input_file")); + DOMUtils.waitForNonZeroNodeBounds(mContentViewCore.getWebContents(), "input_file"); } /** @@ -101,14 +104,12 @@ @Feature({"TextInput", "Main"}) public void testSelectFileAndCancelRequest() throws Throwable { DOMUtils.clickNode(this, mContentViewCore, "input_file"); - assertTrue("SelectFileDialog never sent an intent.", - CriteriaHelper.pollForCriteria(new IntentSentCriteria())); + CriteriaHelper.pollForCriteria(new IntentSentCriteria()); assertEquals(Intent.ACTION_CHOOSER, mActivityWindowAndroidForTest.lastIntent.getAction()); resetActivityWindowAndroidForTest(); DOMUtils.clickNode(this, mContentViewCore, "input_file_multiple"); - assertTrue("SelectFileDialog never sent an intent.", - CriteriaHelper.pollForCriteria(new IntentSentCriteria())); + CriteriaHelper.pollForCriteria(new IntentSentCriteria()); assertEquals(Intent.ACTION_CHOOSER, mActivityWindowAndroidForTest.lastIntent.getAction()); Intent contentIntent = (Intent) mActivityWindowAndroidForTest.lastIntent.getParcelableExtra(Intent.EXTRA_INTENT); @@ -119,15 +120,13 @@ resetActivityWindowAndroidForTest(); DOMUtils.clickNode(this, mContentViewCore, "input_image"); - assertTrue("SelectFileDialog never sent an intent.", - CriteriaHelper.pollForCriteria(new IntentSentCriteria())); + CriteriaHelper.pollForCriteria(new IntentSentCriteria()); assertEquals(MediaStore.ACTION_IMAGE_CAPTURE, mActivityWindowAndroidForTest.lastIntent.getAction()); resetActivityWindowAndroidForTest(); DOMUtils.clickNode(this, mContentViewCore, "input_audio"); - assertTrue("SelectFileDialog never sent an intent.", - CriteriaHelper.pollForCriteria(new IntentSentCriteria())); + CriteriaHelper.pollForCriteria(new IntentSentCriteria()); assertEquals(MediaStore.Audio.Media.RECORD_SOUND_ACTION, mActivityWindowAndroidForTest.lastIntent.getAction()); resetActivityWindowAndroidForTest();
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/TabTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/TabTest.java index a3ea6d1..5d4e037 100644 --- a/chrome/android/javatests/src/org/chromium/chrome/browser/TabTest.java +++ b/chrome/android/javatests/src/org/chromium/chrome/browser/TabTest.java
@@ -97,24 +97,24 @@ } }); - assertTrue(CriteriaHelper.pollForUIThreadCriteria(new Criteria() { + CriteriaHelper.pollForUIThreadCriteria(new Criteria() { @Override public boolean isSatisfied() { return mTab.isHidden(); } - })); + }); assertTrue(mTab.needsReload()); assertFalse(mTab.isShowingSadTab()); ApplicationTestUtils.launchChrome(getInstrumentation().getTargetContext()); // The tab should be restored and visible. - assertTrue(CriteriaHelper.pollForUIThreadCriteria(new Criteria() { + CriteriaHelper.pollForUIThreadCriteria(new Criteria() { @Override public boolean isSatisfied() { return !mTab.isHidden(); } - })); + }); assertFalse(mTab.needsReload()); assertFalse(mTab.isShowingSadTab()); }
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/TabsOpenedFromExternalAppTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/TabsOpenedFromExternalAppTest.java index 2ec9546..e4ca854 100644 --- a/chrome/android/javatests/src/org/chromium/chrome/browser/TabsOpenedFromExternalAppTest.java +++ b/chrome/android/javatests/src/org/chromium/chrome/browser/TabsOpenedFromExternalAppTest.java
@@ -48,11 +48,12 @@ private static final String EXTERNAL_APP_1_ID = "app1"; private static final String EXTERNAL_APP_2_ID = "app2"; - static class ElementFocusedCriteria implements Criteria { + static class ElementFocusedCriteria extends Criteria { private final Tab mTab; private final String mElementId; public ElementFocusedCriteria(Tab tab, String elementId) { + super("Text-field in page not focused."); mTab = tab; // Add quotes to match returned value from JS. mElementId = "\"" + elementId + "\""; @@ -89,12 +90,13 @@ } } - static class ElementTextIsCriteria implements Criteria { + static class ElementTextIsCriteria extends Criteria { private final Tab mTab; private final String mElementId; private final String mExpectedText; public ElementTextIsCriteria(Tab tab, String elementId, String expectedText) { + super("Page does not have the text typed in."); mTab = tab; mElementId = elementId; mExpectedText = expectedText; @@ -145,13 +147,12 @@ } }); if (createNewTab) { - assertTrue("Failed to select different tab", - CriteriaHelper.pollForUIThreadCriteria(new Criteria() { - @Override - public boolean isSatisfied() { - return getActivity().getActivityTab() != originalTab; - } - })); + CriteriaHelper.pollForUIThreadCriteria(new Criteria("Failed to select different tab") { + @Override + public boolean isSatisfied() { + return getActivity().getActivityTab() != originalTab; + } + }); } ChromeTabUtils.waitForTabPageLoaded(getActivity().getActivityTab(), url); } @@ -428,17 +429,15 @@ DOMUtils.clickNode(this, tab.getContentViewCore(), "textField"); // Some processing needs to happen before the test-field has the focus. - assertTrue("Text-field in page not focused.", CriteriaHelper.pollForCriteria( - new ElementFocusedCriteria( - getActivity().getActivityTab(), "textField"), 2000, 200)); + CriteriaHelper.pollForCriteria(new ElementFocusedCriteria( + getActivity().getActivityTab(), "textField"), 2000, 200); // Now type something. getInstrumentation().sendStringSync("banana"); // We also have to wait for the text to happen in the page. - assertTrue("Page does not have the text typed in.", CriteriaHelper.pollForCriteria( - new ElementTextIsCriteria(getActivity().getActivityTab(), "textField", - "banana"), 2000, 200)); + CriteriaHelper.pollForCriteria(new ElementTextIsCriteria( + getActivity().getActivityTab(), "textField", "banana"), 2000, 200); // Launch a second URL from the same app, it should open in a new tab. int originalTabCount = ChromeTabUtils.getNumOpenTabs(getActivity()); @@ -473,12 +472,12 @@ TabModelUtils.closeTabByIndex(getActivity().getCurrentTabModel(), 0); } }); - assertTrue(CriteriaHelper.pollForUIThreadCriteria(new Criteria() { + CriteriaHelper.pollForUIThreadCriteria(new Criteria() { @Override public boolean isSatisfied() { return getActivity().getTabModelSelector().getTotalTabCount() == 0; } - })); + }); // Open a tab via an external application. final Intent intent = new Intent( @@ -489,12 +488,12 @@ intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK); getInstrumentation().getTargetContext().startActivity(intent); - assertTrue(CriteriaHelper.pollForUIThreadCriteria(new Criteria() { + CriteriaHelper.pollForUIThreadCriteria(new Criteria() { @Override public boolean isSatisfied() { return getActivity().getTabModelSelector().getTotalTabCount() == 1; } - })); + }); ApplicationTestUtils.assertWaitForPageScaleFactorMatch(getActivity(), 0.5f, false); // Long press the center of the page, which should bring up the context menu. @@ -508,12 +507,12 @@ } }); TouchCommon.longPressView(view); - assertTrue(CriteriaHelper.pollForUIThreadCriteria(new Criteria() { + CriteriaHelper.pollForUIThreadCriteria(new Criteria() { @Override public boolean isSatisfied() { return observer.mContextMenu != null; } - })); + }); getActivity().getActivityTab().removeObserver(observer); // Select the "open in new tab" option. @@ -526,21 +525,21 @@ }); // The second tab should open in the background. - assertTrue(CriteriaHelper.pollForUIThreadCriteria(new Criteria() { + CriteriaHelper.pollForUIThreadCriteria(new Criteria() { @Override public boolean isSatisfied() { return getActivity().getTabModelSelector().getTotalTabCount() == 2; } - })); + }); // Hitting "back" should close the tab, minimize Chrome, and select the background tab. // Confirm that the number of tabs is correct and that closing the tab didn't cause a crash. getActivity().onBackPressed(); - assertTrue(CriteriaHelper.pollForUIThreadCriteria(new Criteria() { + CriteriaHelper.pollForUIThreadCriteria(new Criteria() { @Override public boolean isSatisfied() { return getActivity().getTabModelSelector().getTotalTabCount() == 1; } - })); + }); } }
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/TabsTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/TabsTest.java index 9256c08..bdf2052f 100644 --- a/chrome/android/javatests/src/org/chromium/chrome/browser/TabsTest.java +++ b/chrome/android/javatests/src/org/chromium/chrome/browser/TabsTest.java
@@ -141,13 +141,12 @@ } }); - assertTrue("Tab never spawned in normal model.", - CriteriaHelper.pollForUIThreadCriteria(new Criteria() { - @Override - public boolean isSatisfied() { - return getActivity().getTabModelSelector().getModel(false).getCount() == 2; - } - })); + CriteriaHelper.pollForUIThreadCriteria(new Criteria("Tab never spawned in normal model.") { + @Override + public boolean isSatisfied() { + return getActivity().getTabModelSelector().getModel(false).getCount() == 2; + } + }); } @MediumTest @@ -239,7 +238,7 @@ } }); - assertTrue(CriteriaHelper.pollForUIThreadCriteria(new Criteria() { + CriteriaHelper.pollForUIThreadCriteria(new Criteria() { @Override public boolean isSatisfied() { Tab tab = getActivity().getCurrentTabModel().getTabAt(1); @@ -247,7 +246,7 @@ String expectedTitle = "new tab"; return title.startsWith(expectedTitle); } - })); + }); ChromeTabUtils.closeCurrentTab(getInstrumentation(), getActivity()); getInstrumentation().runOnMainSync(new Runnable() { @@ -271,7 +270,7 @@ // Make sure we're on the NTP Tab tab = getActivity().getActivityTab(); - assertTrue("NTP never fully loaded.", NewTabPageTestUtils.waitForNtpLoaded(tab)); + NewTabPageTestUtils.waitForNtpLoaded(tab); loadUrl(INITIAL_SIZE_TEST_URL); @@ -914,14 +913,14 @@ } } }); - assertTrue("Did not finish animation", - CriteriaHelper.pollForUIThreadCriteria(new Criteria() { - @Override - public boolean isSatisfied() { - Layout layout = getActivity().getLayoutManager().getActiveLayout(); - return !layout.isLayoutAnimating(); - } - })); + + CriteriaHelper.pollForUIThreadCriteria(new Criteria("Did not finish animation") { + @Override + public boolean isSatisfied() { + Layout layout = getActivity().getLayoutManager().getActiveLayout(); + return !layout.isLayoutAnimating(); + } + }); } private void swipeToCloseNTabs(int number, boolean isLandscape, boolean isIncognito, @@ -1203,12 +1202,12 @@ R.id.close_all_tabs_menu_id); UiUtils.settleDownUI(getInstrumentation()); - assertTrue("Should be in overview mode", CriteriaHelper.pollForCriteria(new Criteria() { + CriteriaHelper.pollForCriteria(new Criteria("Should be in overview mode") { @Override public boolean isSatisfied() { return getActivity().isInOverviewMode(); } - })); + }); int initialTabCount = getActivity().getCurrentTabModel().getCount(); assertEquals("Tab count is expected to be 0 after closing all the tabs", @@ -1397,8 +1396,8 @@ } private void waitForStaticLayout() throws InterruptedException { - assertTrue("Static Layout never selected after side swipe", - CriteriaHelper.pollForUIThreadCriteria(new Criteria() { + CriteriaHelper.pollForUIThreadCriteria( + new Criteria("Static Layout never selected after side swipe") { @Override public boolean isSatisfied() { CompositorViewHolder compositorViewHolder = (CompositorViewHolder) @@ -1407,7 +1406,7 @@ return layoutManager.getActiveLayout() instanceof StaticLayout; } - })); + }); } /** @@ -1455,14 +1454,14 @@ } }); - assertTrue("Layout still requesting Tab Android view be attached", - CriteriaHelper.pollForUIThreadCriteria(new Criteria() { + CriteriaHelper.pollForUIThreadCriteria( + new Criteria("Layout still requesting Tab Android view be attached") { @Override public boolean isSatisfied() { LayoutManager driver = getActivity().getLayoutManager(); return !driver.getActiveLayout().shouldDisplayContentOverlay(); } - })); + }); ThreadUtils.runOnUiThread(new Runnable() { @Override @@ -1473,14 +1472,14 @@ } }); - assertTrue("Layout not requesting Tab Android view be attached", - CriteriaHelper.pollForUIThreadCriteria(new Criteria() { + CriteriaHelper.pollForUIThreadCriteria( + new Criteria("Layout not requesting Tab Android view be attached") { @Override public boolean isSatisfied() { LayoutManager driver = getActivity().getLayoutManager(); return driver.getActiveLayout().shouldDisplayContentOverlay(); } - })); + }); assertFalse("Keyboard should not be shown", org.chromium.ui.UiUtils.isKeyboardShowing(getActivity(), urlBar));
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/appmenu/AppMenuTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/appmenu/AppMenuTest.java index e15d3c8..07a79878 100644 --- a/chrome/android/javatests/src/org/chromium/chrome/browser/appmenu/AppMenuTest.java +++ b/chrome/android/javatests/src/org/chromium/chrome/browser/appmenu/AppMenuTest.java
@@ -92,12 +92,12 @@ mAppMenu.getPopup().getListView().setSelection(0); } }); - assertTrue(CriteriaHelper.pollForCriteria(new Criteria() { + CriteriaHelper.pollForCriteria(new Criteria() { @Override public boolean isSatisfied() { return getCurrentFocusedRow() == 0; } - })); + }); getInstrumentation().waitForIdleSync(); } @@ -202,13 +202,12 @@ getActivity().setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE); showAppMenuAndAssertMenuShown(); getActivity().setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT); - assertTrue("AppMenu did not dismiss", - CriteriaHelper.pollForCriteria(new Criteria() { - @Override - public boolean isSatisfied() { - return !mAppMenuHandler.isAppMenuShowing(); - } - })); + CriteriaHelper.pollForCriteria(new Criteria("AppMenu did not dismiss") { + @Override + public boolean isSatisfied() { + return !mAppMenuHandler.isAppMenuShowing(); + } + }); } private void showAppMenuAndAssertMenuShown() throws InterruptedException { @@ -218,25 +217,23 @@ mAppMenuHandler.showAppMenu(null, false); } }); - assertTrue("AppMenu did not show", - CriteriaHelper.pollForCriteria(new Criteria() { - @Override - public boolean isSatisfied() { - return mAppMenuHandler.isAppMenuShowing(); - } - })); + CriteriaHelper.pollForCriteria(new Criteria("AppMenu did not show") { + @Override + public boolean isSatisfied() { + return mAppMenuHandler.isAppMenuShowing(); + } + }); } private void hitEnterAndAssertAppMenuDismissed() throws InterruptedException { getInstrumentation().waitForIdleSync(); pressKey(KeyEvent.KEYCODE_ENTER); - assertTrue("AppMenu did not dismiss", - CriteriaHelper.pollForCriteria(new Criteria() { - @Override - public boolean isSatisfied() { - return !mAppMenuHandler.isAppMenuShowing(); - } - })); + CriteriaHelper.pollForCriteria(new Criteria("AppMenu did not dismiss") { + @Override + public boolean isSatisfied() { + return !mAppMenuHandler.isAppMenuShowing(); + } + }); } private void moveToBoundary(boolean towardsTop, boolean movePast) throws InterruptedException { @@ -246,25 +243,24 @@ for (int index = getCurrentFocusedRow(); index != end; index += increment) { pressKey(towardsTop ? KeyEvent.KEYCODE_DPAD_UP : KeyEvent.KEYCODE_DPAD_DOWN); final int expectedPosition = index + increment; - assertTrue("Focus did not move to the next menu item", - CriteriaHelper.pollForCriteria(new Criteria() { + CriteriaHelper.pollForCriteria( + new Criteria("Focus did not move to the next menu item") { @Override public boolean isSatisfied() { return getCurrentFocusedRow() == expectedPosition; } - })); + }); } // Try moving past it by one. if (movePast) { pressKey(towardsTop ? KeyEvent.KEYCODE_DPAD_UP : KeyEvent.KEYCODE_DPAD_DOWN); - assertTrue("Focus moved past the edge menu item", - CriteriaHelper.pollForCriteria(new Criteria() { - @Override - public boolean isSatisfied() { - return getCurrentFocusedRow() == end; - } - })); + CriteriaHelper.pollForCriteria(new Criteria("Focus moved past the edge menu item") { + @Override + public boolean isSatisfied() { + return getCurrentFocusedRow() == end; + } + }); } // The menu should stay open.
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/autofill/AutofillDialogControllerTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/autofill/AutofillDialogControllerTest.java index d196c99f..44d96d7 100644 --- a/chrome/android/javatests/src/org/chromium/chrome/browser/autofill/AutofillDialogControllerTest.java +++ b/chrome/android/javatests/src/org/chromium/chrome/browser/autofill/AutofillDialogControllerTest.java
@@ -713,22 +713,21 @@ } private void waitForInputFieldFill(final WebContents webContents) throws InterruptedException { - assertTrue("requestAutocomplete() never completed.", - CriteriaHelper.pollForCriteria(new Criteria() { - @Override - public boolean isSatisfied() { - String wasAutocompleted; - try { - wasAutocompleted = DOMUtils.getNodeContents( - webContents, "was-autocompleted"); - } catch (InterruptedException e) { - return false; - } catch (TimeoutException e) { - return false; - } - return TextUtils.equals("succeeded", wasAutocompleted) - || TextUtils.equals("failed", wasAutocompleted); - } - })); + CriteriaHelper.pollForCriteria(new Criteria("requestAutocomplete() never completed.") { + @Override + public boolean isSatisfied() { + String wasAutocompleted; + try { + wasAutocompleted = DOMUtils.getNodeContents( + webContents, "was-autocompleted"); + } catch (InterruptedException e) { + return false; + } catch (TimeoutException e) { + return false; + } + return TextUtils.equals("succeeded", wasAutocompleted) + || TextUtils.equals("failed", wasAutocompleted); + } + }); } }
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/autofill/AutofillKeyboardAccessoryTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/autofill/AutofillKeyboardAccessoryTest.java index 54fee236..39bafc4 100644 --- a/chrome/android/javatests/src/org/chromium/chrome/browser/autofill/AutofillKeyboardAccessoryTest.java +++ b/chrome/android/javatests/src/org/chromium/chrome/browser/autofill/AutofillKeyboardAccessoryTest.java
@@ -91,7 +91,7 @@ getActivity().getWindowAndroid().getKeyboardAccessoryView()); } }); - assertTrue(DOMUtils.waitForNonZeroNodeBounds(mWebContentsRef.get(), "fn")); + DOMUtils.waitForNonZeroNodeBounds(mWebContentsRef.get(), "fn"); } /** @@ -120,13 +120,12 @@ InterruptedException, TimeoutException { loadTestPage(false); DOMUtils.clickNode(this, mViewCoreRef.get(), "fn"); - assertTrue("Keyboard should be showing.", - CriteriaHelper.pollForUIThreadCriteria(new Criteria() { - @Override - public boolean isSatisfied() { - return UiUtils.isKeyboardShowing(getActivity(), mContainerRef.get()); - } - })); + CriteriaHelper.pollForUIThreadCriteria(new Criteria("Keyboard should be showing.") { + @Override + public boolean isSatisfied() { + return UiUtils.isKeyboardShowing(getActivity(), mContainerRef.get()); + } + }); assertTrue("Keyboard accessory should be showing.", ThreadUtils.runOnUiThreadBlocking(new Callable<Boolean>() { @Override @@ -145,21 +144,20 @@ InterruptedException, TimeoutException { loadTestPage(false); DOMUtils.clickNode(this, mViewCoreRef.get(), "fn"); - assertTrue("Keyboard should be showing.", - CriteriaHelper.pollForUIThreadCriteria(new Criteria() { - @Override - public boolean isSatisfied() { - return UiUtils.isKeyboardShowing(getActivity(), mContainerRef.get()); - } - })); + CriteriaHelper.pollForUIThreadCriteria(new Criteria("Keyboard should be showing.") { + @Override + public boolean isSatisfied() { + return UiUtils.isKeyboardShowing(getActivity(), mContainerRef.get()); + } + }); ThreadUtils.runOnUiThreadBlocking(new Runnable() { @Override public void run() { ((HorizontalScrollView) mKeyboardAccessoryRef.get()).scrollTo(2000, 0); } }); - assertTrue("First suggestion should be off the screen after manual scroll.", - CriteriaHelper.pollForUIThreadCriteria(new Criteria() { + CriteriaHelper.pollForUIThreadCriteria( + new Criteria("First suggestion should be off the screen after manual scroll.") { @Override public boolean isSatisfied() { View suggestion = getSuggestionAt(0); @@ -171,17 +169,17 @@ return false; } } - })); + }); DOMUtils.clickNode(this, mViewCoreRef.get(), "ln"); - assertTrue("First suggestion should be on the screen after switching fields.", - CriteriaHelper.pollForUIThreadCriteria(new Criteria() { + CriteriaHelper.pollForUIThreadCriteria( + new Criteria("First suggestion should be on the screen after switching fields.") { @Override public boolean isSatisfied() { int[] location = new int[2]; getSuggestionAt(0).getLocationOnScreen(location); return location[0] > 0; } - })); + }); } /** @@ -193,21 +191,20 @@ InterruptedException, TimeoutException { loadTestPage(true); DOMUtils.clickNode(this, mViewCoreRef.get(), "fn"); - assertTrue("Keyboard should be showing.", - CriteriaHelper.pollForUIThreadCriteria(new Criteria() { - @Override - public boolean isSatisfied() { - return UiUtils.isKeyboardShowing(getActivity(), mContainerRef.get()); - } - })); + CriteriaHelper.pollForUIThreadCriteria(new Criteria("Keyboard should be showing.") { + @Override + public boolean isSatisfied() { + return UiUtils.isKeyboardShowing(getActivity(), mContainerRef.get()); + } + }); ThreadUtils.runOnUiThreadBlocking(new Runnable() { @Override public void run() { ((HorizontalScrollView) mKeyboardAccessoryRef.get()).scrollTo(0, 0); } }); - assertTrue("Last suggestion should be on the screen after manual scroll.", - CriteriaHelper.pollForUIThreadCriteria(new Criteria() { + CriteriaHelper.pollForUIThreadCriteria( + new Criteria("Last suggestion should be on the screen after manual scroll.") { @Override public boolean isSatisfied() { View suggestion = getSuggestionAt(2); @@ -219,10 +216,10 @@ return false; } } - })); + }); DOMUtils.clickNode(this, mViewCoreRef.get(), "ln"); - assertTrue("Last suggestion should be off the screen after switching fields.", - CriteriaHelper.pollForUIThreadCriteria(new Criteria() { + CriteriaHelper.pollForUIThreadCriteria( + new Criteria("Last suggestion should be off the screen after switching fields.") { @Override public boolean isSatisfied() { View suggestion = getSuggestionAt(2); @@ -234,7 +231,7 @@ return false; } } - })); + }); } /** @@ -247,13 +244,12 @@ InterruptedException, TimeoutException { loadTestPage(false); DOMUtils.clickNode(this, mViewCoreRef.get(), "fn"); - assertTrue("Keyboard should be showing.", - CriteriaHelper.pollForUIThreadCriteria(new Criteria() { - @Override - public boolean isSatisfied() { - return UiUtils.isKeyboardShowing(getActivity(), mContainerRef.get()); - } - })); + CriteriaHelper.pollForUIThreadCriteria(new Criteria("Keyboard should be showing.") { + @Override + public boolean isSatisfied() { + return UiUtils.isKeyboardShowing(getActivity(), mContainerRef.get()); + } + }); ThreadUtils.runOnUiThreadBlocking(new Runnable() { @Override public void run() { @@ -263,13 +259,12 @@ } } }); - assertTrue("Keyboard should be hidden.", - CriteriaHelper.pollForUIThreadCriteria(new Criteria() { - @Override - public boolean isSatisfied() { - return !UiUtils.isKeyboardShowing(getActivity(), mContainerRef.get()); - } - })); + CriteriaHelper.pollForUIThreadCriteria(new Criteria("Keyboard should be hidden.") { + @Override + public boolean isSatisfied() { + return !UiUtils.isKeyboardShowing(getActivity(), mContainerRef.get()); + } + }); assertTrue("Keyboard accessory should be hidden.", ThreadUtils.runOnUiThreadBlocking(new Callable<Boolean>() { @Override
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/autofill/AutofillPopupTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/autofill/AutofillPopupTest.java index 8bc5a6d..e8c6be4 100644 --- a/chrome/android/javatests/src/org/chromium/chrome/browser/autofill/AutofillPopupTest.java +++ b/chrome/android/javatests/src/org/chromium/chrome/browser/autofill/AutofillPopupTest.java
@@ -168,7 +168,7 @@ assertEquals(1, mHelper.getNumberOfProfiles()); // Click the input field for the first name. - assertTrue(DOMUtils.waitForNonZeroNodeBounds(webContents, "fn")); + DOMUtils.waitForNonZeroNodeBounds(webContents, "fn"); DOMUtils.clickNode(this, viewCore, "fn"); waitForKeyboardShowRequest(immw, 1); @@ -303,52 +303,51 @@ private void waitForKeyboardShowRequest(final TestInputMethodManagerWrapper immw, final int count) throws InterruptedException { - assertTrue("Keyboard was never requested to be shown.", - CriteriaHelper.pollForUIThreadCriteria(new Criteria() { + CriteriaHelper.pollForUIThreadCriteria( + new Criteria("Keyboard was never requested to be shown.") { @Override public boolean isSatisfied() { return immw.getShowSoftInputCounter() == count; } - })); + }); } private void waitForAnchorViewAdd(final ViewGroup view) throws InterruptedException { - assertTrue("Autofill Popup anchor view was never added.", - CriteriaHelper.pollForUIThreadCriteria(new Criteria() { - @Override - public boolean isSatisfied() { - return view.findViewById(R.id.dropdown_popup_window) != null; - } - })); + CriteriaHelper.pollForUIThreadCriteria(new Criteria( + "Autofill Popup anchor view was never added.") { + @Override + public boolean isSatisfied() { + return view.findViewById(R.id.dropdown_popup_window) != null; + } + }); } private void waitForAutofillPopopShow(final AutofillPopup popup) throws InterruptedException { - assertTrue("Autofill Popup anchor view was never added.", - CriteriaHelper.pollForUIThreadCriteria(new Criteria() { + CriteriaHelper.pollForUIThreadCriteria( + new Criteria("Autofill Popup anchor view was never added.") { @Override public boolean isSatisfied() { // Wait until the popup is showing and onLayout() has happened. return popup.isShowing() && popup.getListView() != null && popup.getListView().getHeight() != 0; } - })); + }); } private void waitForInputFieldFill(final WebContents webContents) throws InterruptedException { - assertTrue("First name field was never filled.", - CriteriaHelper.pollForCriteria(new Criteria() { - @Override - public boolean isSatisfied() { - try { - return TextUtils.equals(FIRST_NAME, - DOMUtils.getNodeValue(webContents, "fn")); - } catch (InterruptedException e) { - return false; - } catch (TimeoutException e) { - return false; - } - } - })); + CriteriaHelper.pollForCriteria(new Criteria("First name field was never filled.") { + @Override + public boolean isSatisfied() { + try { + return TextUtils.equals(FIRST_NAME, + DOMUtils.getNodeValue(webContents, "fn")); + } catch (InterruptedException e) { + return false; + } catch (TimeoutException e) { + return false; + } + } + }); } private void assertLogged(String autofilledValue, String profileFullName) {
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/autofill/AutofillPopupWithKeyboardTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/autofill/AutofillPopupWithKeyboardTest.java index f514e76..6314a1f 100644 --- a/chrome/android/javatests/src/org/chromium/chrome/browser/autofill/AutofillPopupWithKeyboardTest.java +++ b/chrome/android/javatests/src/org/chromium/chrome/browser/autofill/AutofillPopupWithKeyboardTest.java
@@ -82,7 +82,7 @@ viewRef.set(viewCoreRef.get().getContainerView()); } }); - assertTrue(DOMUtils.waitForNonZeroNodeBounds(webContentsRef.get(), "fn")); + DOMUtils.waitForNonZeroNodeBounds(webContentsRef.get(), "fn"); // Click on the unfocused input element for the first time to focus on it. This brings up // the autofill popup and shows the keyboard at the same time. Showing the keyboard should @@ -90,24 +90,23 @@ DOMUtils.clickNode(this, viewCoreRef.get(), "fn"); // Wait until the keyboard is showing. - assertTrue("Keyboard was never shown.", - CriteriaHelper.pollForUIThreadCriteria(new Criteria() { - @Override - public boolean isSatisfied() { - return UiUtils.isKeyboardShowing( - getActivity(), - getActivity().getCurrentContentViewCore().getContainerView()); - } - })); + CriteriaHelper.pollForUIThreadCriteria(new Criteria("Keyboard was never shown.") { + @Override + public boolean isSatisfied() { + return UiUtils.isKeyboardShowing( + getActivity(), + getActivity().getCurrentContentViewCore().getContainerView()); + } + }); // Verify that the autofill popup is showing. - assertTrue("Autofill Popup anchor view was never added.", - CriteriaHelper.pollForUIThreadCriteria(new Criteria() { + CriteriaHelper.pollForUIThreadCriteria( + new Criteria("Autofill Popup anchor view was never added.") { @Override public boolean isSatisfied() { return viewRef.get().findViewById(R.id.dropdown_popup_window) != null; } - })); + }); Object popupObject = ThreadUtils.runOnUiThreadBlocking(new Callable<Object>() { @Override public Object call() { @@ -116,12 +115,11 @@ }); assertTrue(popupObject instanceof AutofillPopup); final AutofillPopup popup = (AutofillPopup) popupObject; - assertTrue("Autofill Popup was never shown.", - CriteriaHelper.pollForUIThreadCriteria(new Criteria() { - @Override - public boolean isSatisfied() { - return popup.isShowing(); - } - })); + CriteriaHelper.pollForUIThreadCriteria(new Criteria("Autofill Popup was never shown.") { + @Override + public boolean isSatisfied() { + return popup.isShowing(); + } + }); } }
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/autofill/AutofillTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/autofill/AutofillTest.java index 9c57cb3..42ec87c 100644 --- a/chrome/android/javatests/src/org/chromium/chrome/browser/autofill/AutofillTest.java +++ b/chrome/android/javatests/src/org/chromium/chrome/browser/autofill/AutofillTest.java
@@ -84,8 +84,8 @@ public void deleteSuggestion(int listIndex) { } - public boolean waitForCallback() throws InterruptedException { - return CriteriaHelper.pollForCriteria(new Criteria() { + public void waitForCallback() throws InterruptedException { + CriteriaHelper.pollForCriteria(new Criteria() { @Override public boolean isSatisfied() { return mGotPopupSelection.get(); @@ -117,7 +117,7 @@ }; } - public boolean openAutofillPopupAndWaitUntilReady(final AutofillSuggestion[] suggestions) + public void openAutofillPopupAndWaitUntilReady(final AutofillSuggestion[] suggestions) throws InterruptedException { ThreadUtils.runOnUiThreadBlocking(new Runnable() { @Override @@ -125,7 +125,7 @@ mAutofillPopup.filterAndShow(suggestions, false); } }); - return CriteriaHelper.pollForCriteria(new Criteria() { + CriteriaHelper.pollForCriteria(new Criteria() { @Override public boolean isSatisfied() { return mAutofillPopup.getListView().getChildCount() > 0; @@ -136,10 +136,10 @@ @SmallTest @Feature({"autofill"}) public void testAutofillWithDifferentNumberSuggestions() throws Exception { - assertTrue(openAutofillPopupAndWaitUntilReady(createTwoAutofillSuggestionArray())); + openAutofillPopupAndWaitUntilReady(createTwoAutofillSuggestionArray()); assertEquals(2, mAutofillPopup.getListView().getCount()); - assertTrue(openAutofillPopupAndWaitUntilReady(createFiveAutofillSuggestionArray())); + openAutofillPopupAndWaitUntilReady(createFiveAutofillSuggestionArray()); assertEquals(5, mAutofillPopup.getListView().getCount()); } @@ -147,11 +147,11 @@ @Feature({"autofill"}) public void testAutofillClickFirstSuggestion() throws Exception { AutofillSuggestion[] suggestions = createTwoAutofillSuggestionArray(); - assertTrue(openAutofillPopupAndWaitUntilReady(suggestions)); + openAutofillPopupAndWaitUntilReady(suggestions); assertEquals(2, mAutofillPopup.getListView().getCount()); TouchCommon.singleClickView(mAutofillPopup.getListView().getChildAt(0)); - assertTrue(mMockAutofillCallback.waitForCallback()); + mMockAutofillCallback.waitForCallback(); assertEquals(0, mMockAutofillCallback.mListIndex); }
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/banners/AppBannerManagerTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/banners/AppBannerManagerTest.java index 06d74ac..5749fe9 100644 --- a/chrome/android/javatests/src/org/chromium/chrome/browser/banners/AppBannerManagerTest.java +++ b/chrome/android/javatests/src/org/chromium/chrome/browser/banners/AppBannerManagerTest.java
@@ -189,8 +189,8 @@ AppBannerManager.setEngagementWeights(1, 1); } - private boolean waitUntilNoInfoBarsExist() throws Exception { - return CriteriaHelper.pollForUIThreadCriteria(new Criteria() { + private void waitUntilNoInfoBarsExist() throws Exception { + CriteriaHelper.pollForUIThreadCriteria(new Criteria() { @Override public boolean isSatisfied() { InfoBarContainer container = getActivity().getActivityTab().getInfoBarContainer(); @@ -199,8 +199,8 @@ }); } - private boolean waitUntilAppDetailsRetrieved(final int numExpected) throws Exception { - return CriteriaHelper.pollForUIThreadCriteria(new Criteria() { + private void waitUntilAppDetailsRetrieved(final int numExpected) throws Exception { + CriteriaHelper.pollForUIThreadCriteria(new Criteria() { @Override public boolean isSatisfied() { AppBannerManager manager = @@ -211,8 +211,8 @@ }); } - private boolean waitUntilAppBannerInfoBarAppears(final String title) throws Exception { - return CriteriaHelper.pollForUIThreadCriteria(new Criteria() { + private void waitUntilAppBannerInfoBarAppears(final String title) throws Exception { + CriteriaHelper.pollForUIThreadCriteria(new Criteria() { @Override public boolean isSatisfied() { InfoBarContainer container = getActivity().getActivityTab().getInfoBarContainer(); @@ -231,9 +231,9 @@ private void runFullNativeInstallPathway(String url, String expectedReferrer) throws Exception { // Visit a site that requests a banner. new TabLoadObserver(getActivity().getActivityTab(), url).assertLoaded(); - assertTrue(waitUntilAppDetailsRetrieved(1)); + waitUntilAppDetailsRetrieved(1); assertEquals(mDetailsDelegate.mReferrer, expectedReferrer); - assertTrue(waitUntilNoInfoBarsExist()); + waitUntilNoInfoBarsExist(); // Indicate a day has passed, then revisit the page to get the banner to appear. InfoBarContainer container = getActivity().getActivityTab().getInfoBarContainer(); @@ -241,14 +241,14 @@ container.setAnimationListener(listener); AppBannerManager.setTimeDeltaForTesting(1); new TabLoadObserver(getActivity().getActivityTab(), url).assertLoaded(); - assertTrue(waitUntilAppDetailsRetrieved(2)); - assertTrue(waitUntilAppBannerInfoBarAppears(NATIVE_APP_TITLE)); - assertTrue(CriteriaHelper.pollForUIThreadCriteria(new Criteria() { + waitUntilAppDetailsRetrieved(2); + waitUntilAppBannerInfoBarAppears(NATIVE_APP_TITLE); + CriteriaHelper.pollForUIThreadCriteria(new Criteria() { @Override public boolean isSatisfied() { return listener.mDoneAnimating; } - })); + }); // Check that the button asks if the user wants to install the app. InfoBar infobar = container.getInfoBars().get(0); @@ -266,24 +266,24 @@ // Wait for the infobar to register that the app is installing. final String installingText = getInstrumentation().getTargetContext().getString(R.string.app_banner_installing); - assertTrue(CriteriaHelper.pollForCriteria(new Criteria() { + CriteriaHelper.pollForCriteria(new Criteria() { @Override public boolean isSatisfied() { return getInstrumentation().checkMonitorHit(activityMonitor, 1) && TextUtils.equals(button.getText(), installingText); } - })); + }); // Say that the package is installed. Infobar should say that the app is ready to open. mPackageManager.isInstalled = true; final String openText = getInstrumentation().getTargetContext().getString(R.string.app_banner_open); - assertTrue(CriteriaHelper.pollForCriteria(new Criteria() { + CriteriaHelper.pollForCriteria(new Criteria() { @Override public boolean isSatisfied() { return TextUtils.equals(button.getText(), openText); } - })); + }); } @SmallTest @@ -303,42 +303,42 @@ public void testBannerAppearsThenDoesNotAppearAgainForMonths() throws Exception { // Visit a site that requests a banner. new TabLoadObserver(getActivity().getActivityTab(), NATIVE_APP_URL).assertLoaded(); - assertTrue(waitUntilAppDetailsRetrieved(1)); - assertTrue(waitUntilNoInfoBarsExist()); + waitUntilAppDetailsRetrieved(1); + waitUntilNoInfoBarsExist(); // Indicate a day has passed, then revisit the page. AppBannerManager.setTimeDeltaForTesting(1); new TabLoadObserver(getActivity().getActivityTab(), NATIVE_APP_URL).assertLoaded(); - assertTrue(waitUntilAppDetailsRetrieved(2)); - assertTrue(waitUntilAppBannerInfoBarAppears(NATIVE_APP_TITLE)); + waitUntilAppDetailsRetrieved(2); + waitUntilAppBannerInfoBarAppears(NATIVE_APP_TITLE); // Revisit the page to make the banner go away, but don't explicitly dismiss it. // This hides the banner for a few months. new TabLoadObserver(getActivity().getActivityTab(), NATIVE_APP_URL).assertLoaded(); - assertTrue(waitUntilAppDetailsRetrieved(3)); - assertTrue(waitUntilNoInfoBarsExist()); + waitUntilAppDetailsRetrieved(3); + waitUntilNoInfoBarsExist(); // Wait a month until revisiting the page. AppBannerManager.setTimeDeltaForTesting(31); new TabLoadObserver(getActivity().getActivityTab(), NATIVE_APP_URL).assertLoaded(); - assertTrue(waitUntilAppDetailsRetrieved(4)); - assertTrue(waitUntilNoInfoBarsExist()); + waitUntilAppDetailsRetrieved(4); + waitUntilNoInfoBarsExist(); AppBannerManager.setTimeDeltaForTesting(32); new TabLoadObserver(getActivity().getActivityTab(), NATIVE_APP_URL).assertLoaded(); - assertTrue(waitUntilAppDetailsRetrieved(5)); - assertTrue(waitUntilNoInfoBarsExist()); + waitUntilAppDetailsRetrieved(5); + waitUntilNoInfoBarsExist(); // Wait two months until revisiting the page, which should pop up the banner. AppBannerManager.setTimeDeltaForTesting(61); new TabLoadObserver(getActivity().getActivityTab(), NATIVE_APP_URL).assertLoaded(); - assertTrue(waitUntilAppDetailsRetrieved(6)); - assertTrue(waitUntilNoInfoBarsExist()); + waitUntilAppDetailsRetrieved(6); + waitUntilNoInfoBarsExist(); AppBannerManager.setTimeDeltaForTesting(62); new TabLoadObserver(getActivity().getActivityTab(), NATIVE_APP_URL).assertLoaded(); - assertTrue(waitUntilAppDetailsRetrieved(7)); - assertTrue(waitUntilAppBannerInfoBarAppears(NATIVE_APP_TITLE)); + waitUntilAppDetailsRetrieved(7); + waitUntilAppBannerInfoBarAppears(NATIVE_APP_TITLE); } @MediumTest @@ -346,8 +346,8 @@ public void testBlockedBannerDoesNotAppearAgainForMonths() throws Exception { // Visit a site that requests a banner. new TabLoadObserver(getActivity().getActivityTab(), NATIVE_APP_URL).assertLoaded(); - assertTrue(waitUntilAppDetailsRetrieved(1)); - assertTrue(waitUntilNoInfoBarsExist()); + waitUntilAppDetailsRetrieved(1); + waitUntilNoInfoBarsExist(); // Indicate a day has passed, then revisit the page. InfoBarContainer container = getActivity().getActivityTab().getInfoBarContainer(); @@ -355,42 +355,42 @@ container.setAnimationListener(listener); AppBannerManager.setTimeDeltaForTesting(1); new TabLoadObserver(getActivity().getActivityTab(), NATIVE_APP_URL).assertLoaded(); - assertTrue(waitUntilAppDetailsRetrieved(2)); - assertTrue(waitUntilAppBannerInfoBarAppears(NATIVE_APP_TITLE)); + waitUntilAppDetailsRetrieved(2); + waitUntilAppBannerInfoBarAppears(NATIVE_APP_TITLE); // Explicitly dismiss the banner. - assertTrue(CriteriaHelper.pollForUIThreadCriteria(new Criteria() { + CriteriaHelper.pollForUIThreadCriteria(new Criteria() { @Override public boolean isSatisfied() { return listener.mDoneAnimating; } - })); + }); ArrayList<InfoBar> infobars = container.getInfoBars(); View close = infobars.get(0).getView().findViewById(R.id.infobar_close_button); TouchCommon.singleClickView(close); - assertTrue(waitUntilNoInfoBarsExist()); + waitUntilNoInfoBarsExist(); // Waiting two months shouldn't be long enough. AppBannerManager.setTimeDeltaForTesting(61); new TabLoadObserver(getActivity().getActivityTab(), NATIVE_APP_URL).assertLoaded(); - assertTrue(waitUntilAppDetailsRetrieved(3)); - assertTrue(waitUntilNoInfoBarsExist()); + waitUntilAppDetailsRetrieved(3); + waitUntilNoInfoBarsExist(); AppBannerManager.setTimeDeltaForTesting(62); new TabLoadObserver(getActivity().getActivityTab(), NATIVE_APP_URL).assertLoaded(); - assertTrue(waitUntilAppDetailsRetrieved(4)); - assertTrue(waitUntilNoInfoBarsExist()); + waitUntilAppDetailsRetrieved(4); + waitUntilNoInfoBarsExist(); // Waiting three months should allow banners to reappear. AppBannerManager.setTimeDeltaForTesting(91); new TabLoadObserver(getActivity().getActivityTab(), NATIVE_APP_URL).assertLoaded(); - assertTrue(waitUntilAppDetailsRetrieved(5)); - assertTrue(waitUntilNoInfoBarsExist()); + waitUntilAppDetailsRetrieved(5); + waitUntilNoInfoBarsExist(); AppBannerManager.setTimeDeltaForTesting(92); new TabLoadObserver(getActivity().getActivityTab(), NATIVE_APP_URL).assertLoaded(); - assertTrue(waitUntilAppDetailsRetrieved(6)); - assertTrue(waitUntilAppBannerInfoBarAppears(NATIVE_APP_TITLE)); + waitUntilAppDetailsRetrieved(6); + waitUntilAppBannerInfoBarAppears(NATIVE_APP_TITLE); } @MediumTest @@ -401,12 +401,12 @@ new TabLoadObserver(getActivity().getActivityTab(), NATIVE_APP_URL).assertLoaded(); final Integer iteration = Integer.valueOf(i); - assertTrue(CriteriaHelper.pollForUIThreadCriteria(new Criteria() { + CriteriaHelper.pollForUIThreadCriteria(new Criteria() { @Override public boolean isSatisfied() { return mDetailsDelegate.mNumRetrieved == iteration; } - })); + }); } } @@ -417,28 +417,28 @@ loadUrlInNewTab("about:blank"); new TabLoadObserver(getActivity().getActivityTab(), WEB_APP_URL).assertLoaded(); - assertTrue(CriteriaHelper.pollForUIThreadCriteria(new Criteria() { + CriteriaHelper.pollForUIThreadCriteria(new Criteria() { @Override public boolean isSatisfied() { AppBannerManager manager = getActivity().getActivityTab().getAppBannerManagerForTesting(); return !manager.isFetcherActiveForTesting(); } - })); - assertTrue(waitUntilNoInfoBarsExist()); + }); + waitUntilNoInfoBarsExist(); // Indicate a day has passed, then revisit the page to show the banner. AppBannerManager.setTimeDeltaForTesting(1); new TabLoadObserver(getActivity().getActivityTab(), WEB_APP_URL).assertLoaded(); - assertTrue(CriteriaHelper.pollForUIThreadCriteria(new Criteria() { + CriteriaHelper.pollForUIThreadCriteria(new Criteria() { @Override public boolean isSatisfied() { AppBannerManager manager = getActivity().getActivityTab().getAppBannerManagerForTesting(); return !manager.isFetcherActiveForTesting(); } - })); - assertTrue(waitUntilAppBannerInfoBarAppears(WEB_APP_TITLE)); + }); + waitUntilAppBannerInfoBarAppears(WEB_APP_TITLE); } @SmallTest @@ -452,15 +452,15 @@ loadUrlInNewTab("about:blank"); new TabLoadObserver(getActivity().getActivityTab(), WEB_APP_URL).assertLoaded(); - assertTrue(CriteriaHelper.pollForUIThreadCriteria(new Criteria() { + CriteriaHelper.pollForUIThreadCriteria(new Criteria() { @Override public boolean isSatisfied() { AppBannerManager manager = getActivity().getActivityTab().getAppBannerManagerForTesting(); return !manager.isFetcherActiveForTesting(); } - })); - assertTrue(waitUntilNoInfoBarsExist()); + }); + waitUntilNoInfoBarsExist(); // Add the animation listener in. InfoBarContainer container = getActivity().getActivityTab().getInfoBarContainer(); @@ -470,21 +470,21 @@ // Indicate a day has passed, then revisit the page to show the banner. AppBannerManager.setTimeDeltaForTesting(1); new TabLoadObserver(getActivity().getActivityTab(), WEB_APP_URL).assertLoaded(); - assertTrue(CriteriaHelper.pollForUIThreadCriteria(new Criteria() { + CriteriaHelper.pollForUIThreadCriteria(new Criteria() { @Override public boolean isSatisfied() { AppBannerManager manager = getActivity().getActivityTab().getAppBannerManagerForTesting(); return !manager.isFetcherActiveForTesting(); } - })); - assertTrue(waitUntilAppBannerInfoBarAppears(WEB_APP_TITLE)); - assertTrue(CriteriaHelper.pollForUIThreadCriteria(new Criteria() { + }); + waitUntilAppBannerInfoBarAppears(WEB_APP_TITLE); + CriteriaHelper.pollForUIThreadCriteria(new Criteria() { @Override public boolean isSatisfied() { return listener.mDoneAnimating; } - })); + }); // Click the button to trigger the adding of the shortcut. InfoBar infobar = container.getInfoBars().get(0); @@ -493,12 +493,12 @@ TouchCommon.singleClickView(button); // Make sure that the splash screen icon was downloaded. - assertTrue(CriteriaHelper.pollForUIThreadCriteria(new Criteria() { + CriteriaHelper.pollForUIThreadCriteria(new Criteria() { @Override public boolean isSatisfied() { return dataStorageFactory.mSplashImage != null; } - })); + }); // Test that bitmap sizes match expectations. int idealSize = getActivity().getResources().getDimensionPixelSize(
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/banners/InstallerDelegateTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/banners/InstallerDelegateTest.java index 779078fb..29a1c5fa 100644 --- a/chrome/android/javatests/src/org/chromium/chrome/browser/banners/InstallerDelegateTest.java +++ b/chrome/android/javatests/src/org/chromium/chrome/browser/banners/InstallerDelegateTest.java
@@ -93,21 +93,21 @@ mInstallStarted = true; // Wait until we know that the Thread is running the InstallerDelegate task. - assertTrue(CriteriaHelper.pollForCriteria(new Criteria() { + CriteriaHelper.pollForCriteria(new Criteria() { @Override public boolean isSatisfied() { return mTestDelegate.isRunning(); } - })); + }); } private void checkResults(boolean expectedResult) throws InterruptedException { - assertTrue(CriteriaHelper.pollForCriteria(new Criteria() { + CriteriaHelper.pollForCriteria(new Criteria() { @Override public boolean isSatisfied() { return !mTestDelegate.isRunning() && mResultFinished; } - })); + }); assertEquals(expectedResult, mResultSuccess); assertEquals(mTestDelegate, mResultDelegate);
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/contextmenu/ContextMenuTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/contextmenu/ContextMenuTest.java index cc00414d..a7d39da9 100644 --- a/chrome/android/javatests/src/org/chromium/chrome/browser/contextmenu/ContextMenuTest.java +++ b/chrome/android/javatests/src/org/chromium/chrome/browser/contextmenu/ContextMenuTest.java
@@ -12,8 +12,6 @@ import android.view.ContextMenu; import android.view.KeyEvent; -import junit.framework.Assert; - import org.chromium.base.ThreadUtils; import org.chromium.base.test.util.CommandLineFlags; import org.chromium.base.test.util.DisabledTest; @@ -156,13 +154,12 @@ assertFalse("Context menu did not have window focus", getActivity().hasWindowFocus()); getInstrumentation().sendKeyDownUpSync(KeyEvent.KEYCODE_BACK); - Assert.assertTrue("Activity did not regain focus.", - CriteriaHelper.pollForCriteria(new Criteria() { - @Override - public boolean isSatisfied() { - return getActivity().hasWindowFocus(); - } - })); + CriteriaHelper.pollForCriteria(new Criteria("Activity did not regain focus.") { + @Override + public boolean isSatisfied() { + return getActivity().hasWindowFocus(); + } + }); } @MediumTest @@ -175,13 +172,12 @@ TestTouchUtils.singleClickView(getInstrumentation(), tab.getView(), 0, 0); - Assert.assertTrue("Activity did not regain focus.", - CriteriaHelper.pollForCriteria(new Criteria() { - @Override - public boolean isSatisfied() { - return getActivity().hasWindowFocus(); - } - })); + CriteriaHelper.pollForCriteria(new Criteria("Activity did not regain focus.") { + @Override + public boolean isSatisfied() { + return getActivity().hasWindowFocus(); + } + }); } @MediumTest @@ -247,13 +243,13 @@ // Wait for any new tab animation to finish if we're being driven by the compositor. final LayoutManager layoutDriver = getActivity() .getCompositorViewHolder().getLayoutManager(); - assertTrue("Background tab animation not finished.", - CriteriaHelper.pollForUIThreadCriteria(new Criteria() { + CriteriaHelper.pollForUIThreadCriteria( + new Criteria("Background tab animation not finished.") { @Override public boolean isSatisfied() { return layoutDriver.getActiveLayout().shouldDisplayContentOverlay(); } - })); + }); ContextMenuUtils.selectContextMenuItem(this, tab, "testLink2", R.id.contextmenu_open_in_new_tab);
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/contextualsearch/ContextualSearchManagerTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/contextualsearch/ContextualSearchManagerTest.java index 15a6814..456a007 100644 --- a/chrome/android/javatests/src/org/chromium/chrome/browser/contextualsearch/ContextualSearchManagerTest.java +++ b/chrome/android/javatests/src/org/chromium/chrome/browser/contextualsearch/ContextualSearchManagerTest.java
@@ -141,7 +141,7 @@ public void longPressNode(String nodeId) throws InterruptedException, TimeoutException { Tab tab = getActivity().getActivityTab(); DOMUtils.longPressNode(this, tab.getContentViewCore(), nodeId); - waitForPanelToPeekAndAssert(); + waitForPanelToPeek(); } /** @@ -158,13 +158,12 @@ * @param text The string to wait for the selection to become. */ public void waitForSelectionToBe(final String text) throws InterruptedException { - assertTrue("Bar never showed desired text.", - CriteriaHelper.pollForCriteria(new Criteria() { - @Override - public boolean isSatisfied() { - return TextUtils.equals(text, getSelectedText()); - } - }, TEST_TIMEOUT, DEFAULT_POLLING_INTERVAL)); + CriteriaHelper.pollForCriteria(new Criteria("Bar never showed desired text.") { + @Override + public boolean isSatisfied() { + return TextUtils.equals(text, getSelectedText()); + } + }, TEST_TIMEOUT, DEFAULT_POLLING_INTERVAL); } /** @@ -173,13 +172,12 @@ */ public void waitForSearchTermResolutionToStart( final ContextualSearchFakeServer.FakeTapSearch search) throws InterruptedException { - assertTrue("Fake Search Term Resolution never started.", - CriteriaHelper.pollForCriteria(new Criteria() { - @Override - public boolean isSatisfied() { - return search.didStartSearchTermResolution(); - } - }, TEST_TIMEOUT, DEFAULT_POLLING_INTERVAL)); + CriteriaHelper.pollForCriteria(new Criteria("Fake Search Term Resolution never started.") { + @Override + public boolean isSatisfied() { + return search.didStartSearchTermResolution(); + } + }, TEST_TIMEOUT, DEFAULT_POLLING_INTERVAL); } /** @@ -188,13 +186,12 @@ */ public void waitForSearchTermResolutionToFinish( final ContextualSearchFakeServer.FakeTapSearch search) throws InterruptedException { - assertTrue("Fake Search was never ready.", - CriteriaHelper.pollForCriteria(new Criteria() { - @Override - public boolean isSatisfied() { - return search.didFinishSearchTermResolution(); - } - }, TEST_TIMEOUT, DEFAULT_POLLING_INTERVAL)); + CriteriaHelper.pollForCriteria(new Criteria("Fake Search was never ready.") { + @Override + public boolean isSatisfied() { + return search.didFinishSearchTermResolution(); + } + }, TEST_TIMEOUT, DEFAULT_POLLING_INTERVAL); } /** @@ -226,7 +223,7 @@ ContextualSearchFakeServer.FakeLongPressSearch search = mFakeServer.getFakeLongPressSearch(nodeId); search.simulate(); - waitForPanelToPeekAndAssert(); + waitForPanelToPeek(); } /** @@ -240,7 +237,7 @@ ContextualSearchFakeServer.FakeTapSearch search = mFakeServer.getFakeTapSearch(nodeId); search.simulate(); assertLoadedSearchTermMatches(search.getSearchTerm()); - waitForPanelToPeekAndAssert(); + waitForPanelToPeek(); } /** @@ -420,7 +417,7 @@ */ private void clickWordNode(String nodeId) throws InterruptedException, TimeoutException { clickNode(nodeId); - waitForPanelToPeekAndAssert(); + waitForPanelToPeek(); } /** @@ -542,32 +539,32 @@ * did peek. * @throws InterruptedException */ - private void waitForPanelToPeekAndAssert() throws InterruptedException { - waitForPanelToEnterStateAndAssert(PanelState.PEEKED); + private void waitForPanelToPeek() throws InterruptedException { + waitForPanelToEnterState(PanelState.PEEKED); } /** * Waits for the Search Panel to expand, and asserts that it did expand. * @throws InterruptedException */ - private void waitForPanelToExpandAndAssert() throws InterruptedException { - waitForPanelToEnterStateAndAssert(PanelState.EXPANDED); + private void waitForPanelToExpand() throws InterruptedException { + waitForPanelToEnterState(PanelState.EXPANDED); } /** * Waits for the Search Panel to maximize, and asserts that it did maximize. * @throws InterruptedException */ - private void waitForPanelToMaximizeAndAssert() throws InterruptedException { - waitForPanelToEnterStateAndAssert(PanelState.MAXIMIZED); + private void waitForPanelToMaximize() throws InterruptedException { + waitForPanelToEnterState(PanelState.MAXIMIZED); } /** * Waits for the Search Panel to close, and asserts that it did close. * @throws InterruptedException */ - private void waitForPanelToCloseAndAssert() throws InterruptedException { - waitForPanelToEnterStateAndAssert(PanelState.CLOSED); + private void waitForPanelToClose() throws InterruptedException { + waitForPanelToEnterState(PanelState.CLOSED); } /** @@ -575,40 +572,24 @@ * @throws InterruptedException */ private void assertPanelNeverOpened() throws InterruptedException { - assertTrue( - "Search Panel actually did open.", waitForPanelToEnterState(PanelState.UNDEFINED)); - } - - /** - * Waits for the Search Panel to enter the given {@code PanelState}. - * @throws InterruptedException - */ - private boolean waitForPanelToEnterState(final PanelState state) throws InterruptedException { - return CriteriaHelper.pollForCriteria(new Criteria() { - @Override - public boolean isSatisfied() { - return mPanel != null - && mPanel.getPanelState() == state; - } - }, TEST_TIMEOUT, DEFAULT_POLLING_INTERVAL); + waitForPanelToEnterState(PanelState.UNDEFINED); } /** * Waits for the Search Panel to enter the given {@code PanelState} and assert. * @throws InterruptedException */ - private void waitForPanelToEnterStateAndAssert(final PanelState state) + private void waitForPanelToEnterState(final PanelState state) throws InterruptedException { - boolean success = - CriteriaHelper.pollForCriteria(new Criteria() { - @Override - public boolean isSatisfied() { - return mPanel != null - && mPanel.getPanelState() == state; - } - }, TEST_TIMEOUT, DEFAULT_POLLING_INTERVAL); - assertTrue("Panel did not enter " + state + " state. " - + "Instead, the current state is " + mPanel.getPanelState() + ".", success); + CriteriaHelper.pollForCriteria(new Criteria() { + @Override + public boolean isSatisfied() { + if (mPanel == null) return false; + updateFailureReason("Panel did not enter " + state + " state. " + + "Instead, the current state is " + mPanel.getPanelState() + "."); + return mPanel.getPanelState() == state; + } + }, TEST_TIMEOUT, DEFAULT_POLLING_INTERVAL); } /** @@ -616,14 +597,13 @@ * Tells the manager that a gesture has started, and then waits for it to complete. * @throws InterruptedException */ - private void waitForGestureProcessingAndAssert() throws InterruptedException { - assertTrue("Gesture processing did not complete.", - CriteriaHelper.pollForCriteria(new Criteria() { - @Override - public boolean isSatisfied() { - return !mSelectionController.wasAnyTapGestureDetected(); - } - }, TEST_TIMEOUT, DEFAULT_POLLING_INTERVAL)); + private void waitForGestureProcessing() throws InterruptedException { + CriteriaHelper.pollForCriteria(new Criteria("Gesture processing did not complete.") { + @Override + public boolean isSatisfied() { + return !mSelectionController.wasAnyTapGestureDetected(); + } + }, TEST_TIMEOUT, DEFAULT_POLLING_INTERVAL); } /** @@ -634,8 +614,8 @@ * @throws InterruptedException */ private void waitForGestureToClosePanelAndAssertNoSelection() throws InterruptedException { - waitForGestureProcessingAndAssert(); - waitForPanelToCloseAndAssert(); + waitForGestureProcessing(); + waitForPanelToClose(); assertPanelClosedOrUndefined(); assertNull(getSelectedText()); } @@ -648,19 +628,19 @@ * and a subsequent tap may think there's a current selection until it has been dissolved. */ private void waitForSelectionDissolved() throws InterruptedException { - assertTrue("Selection never dissolved.", CriteriaHelper.pollForCriteria(new Criteria() { + CriteriaHelper.pollForCriteria(new Criteria("Selection never dissolved.") { @Override public boolean isSatisfied() { return !mSelectionController.isSelectionEstablished(); } - }, TEST_TIMEOUT, DEFAULT_POLLING_INTERVAL)); + }, TEST_TIMEOUT, DEFAULT_POLLING_INTERVAL); } /** * Waits for the panel to close and then waits for the selection to dissolve. */ private void waitForPanelToCloseAndSelectionDissolved() throws InterruptedException { - waitForPanelToCloseAndAssert(); + waitForPanelToClose(); waitForSelectionDissolved(); } @@ -755,7 +735,7 @@ // long press and trying to close with the bar peeking, with a long press selection // established). tapBasePage(0.9f, 0.35f); - waitForPanelToCloseAndAssert(); + waitForPanelToClose(); } /** @@ -806,7 +786,7 @@ */ private void tapPeekingBarToExpandAndAssert() throws InterruptedException { clickPanelBar(0.95f); - waitForPanelToExpandAndAssert(); + waitForPanelToExpand(); } /** @@ -834,7 +814,7 @@ clickWordNode("states"); assertSearchTermRequested(); fakeResponse(false, 200, "States", "display-text", "alternate-term", false); - waitForPanelToPeekAndAssert(); + waitForPanelToPeek(); clickNode("states-far"); waitForPanelToCloseAndSelectionDissolved(); } @@ -848,7 +828,7 @@ assertSearchTermRequested(); fakeResponse(false, 200, "states", "United States Intelligence", "alternate-term", false); - waitForPanelToPeekAndAssert(); + waitForPanelToPeek(); assertLoadedLowPriorityUrl(); assertContainsParameters("states", "alternate-term"); } @@ -893,7 +873,7 @@ assertEquals("Intelligence", mFakeServer.getSearchTermRequested()); fakeResponse(false, 200, "Intelligence", "display-text", "alternate-term", false); assertContainsParameters("Intelligence", "alternate-term"); - waitForPanelToPeekAndAssert(); + waitForPanelToPeek(); OmniboxTestUtils.toggleUrlBarFocus((UrlBar) getActivity().findViewById(R.id.url_bar), true); @@ -955,7 +935,7 @@ assertEquals("Intelligence", mFakeServer.getSearchTermRequested()); fakeResponse(false, 200, "Intelligence", "display-text", "alternate-term", false); assertContainsParameters("Intelligence", "alternate-term"); - waitForPanelToPeekAndAssert(); + waitForPanelToPeek(); assertLoadedLowPriorityUrl(); } @@ -969,7 +949,7 @@ longPressNode("states"); assertNull(mFakeServer.getSearchTermRequested()); - waitForPanelToPeekAndAssert(); + waitForPanelToPeek(); assertLoadedNoUrl(); assertNoContentViewCore(); } @@ -992,9 +972,9 @@ assertEquals(1, mFakeServer.getLoadedUrlCount()); assertLoadedLowPriorityUrl(); - waitForPanelToPeekAndAssert(); + waitForPanelToPeek(); flingPanelUp(); - waitForPanelToExpandAndAssert(); + waitForPanelToExpand(); assertEquals(1, mFakeServer.getLoadedUrlCount()); assertLoadedLowPriorityUrl(); } @@ -1019,11 +999,11 @@ false); assertContainsParameters("Intelligence", "alternate-term"); - waitForPanelToPeekAndAssert(); + waitForPanelToPeek(); assertLoadedNoUrl(); assertNoContentViewCore(); flingPanelUp(); - waitForPanelToExpandAndAssert(); + waitForPanelToExpand(); assertContentViewCoreCreated(); assertLoadedNormalPriorityUrl(); assertEquals(1, mFakeServer.getLoadedUrlCount()); @@ -1148,7 +1128,7 @@ assertSearchTermRequested(); fakeResponse(false, 200, "Intelligence", "display-text", "alternate-term", true); assertContainsNoParameters(); - waitForPanelToPeekAndAssert(); + waitForPanelToPeek(); assertLoadedNoUrl(); } @@ -1163,10 +1143,10 @@ assertEquals("Intelligence", getSelectedText()); fakeResponse(false, 200, "Intelligence", "Intelligence", "alternate-term", false); assertContainsParameters("Intelligence", "alternate-term"); - waitForPanelToPeekAndAssert(); + waitForPanelToPeek(); assertLoadedNoUrl(); // No load after long-press until opening panel. clickNode("question-mark"); - waitForGestureProcessingAndAssert(); + waitForGestureProcessing(); assertNull(getSelectedText()); assertPanelClosedOrUndefined(); assertLoadedNoUrl(); @@ -1183,10 +1163,10 @@ assertEquals("Intelligence", getSelectedText()); fakeResponse(false, 200, "Intelligence", "Intelligence", "alternate-term", false); assertContainsParameters("Intelligence", "alternate-term"); - waitForPanelToPeekAndAssert(); + waitForPanelToPeek(); assertLoadedLowPriorityUrl(); clickNode("question-mark"); - waitForGestureProcessingAndAssert(); + waitForGestureProcessing(); assertNull(getSelectedText()); } @@ -1199,7 +1179,7 @@ public void testTapGestureOnSpecialCharacterDoesntSelect() throws InterruptedException, TimeoutException { clickNode("question-mark"); - waitForGestureProcessingAndAssert(); + waitForGestureProcessing(); assertNull(getSelectedText()); assertPanelClosedOrUndefined(); assertLoadedNoUrl(); @@ -1216,7 +1196,7 @@ clickWordNode("intelligence"); fakeResponse(false, 200, "Intelligence", "Intelligence", "alternate-term", false); assertContainsParameters("Intelligence", "alternate-term"); - waitForPanelToPeekAndAssert(); + waitForPanelToPeek(); assertLoadedLowPriorityUrl(); scrollBasePage(); assertPanelClosedOrUndefined(); @@ -1232,9 +1212,9 @@ public void testTapGestureFollowedByInvalidTextTapCloses() throws InterruptedException, TimeoutException { clickWordNode("states-far"); - waitForPanelToPeekAndAssert(); + waitForPanelToPeek(); clickNode("question-mark"); - waitForGestureProcessingAndAssert(); + waitForGestureProcessing(); assertPanelClosedOrUndefined(); assertNull(mSelectionController.getSelectedText()); } @@ -1249,9 +1229,9 @@ public void testTapGestureFollowedByNonTextTap() throws InterruptedException, TimeoutException { clickWordNode("states-far"); - waitForPanelToPeekAndAssert(); + waitForPanelToPeek(); clickNode("button"); - waitForGestureProcessingAndAssert(); + waitForGestureProcessing(); assertPanelClosedOrUndefined(); assertNull(mSelectionController.getSelectedText()); } @@ -1266,14 +1246,14 @@ throws InterruptedException, TimeoutException { clickWordNode("states"); assertEquals("States", getSelectedText()); - waitForPanelToPeekAndAssert(); + waitForPanelToPeek(); clickNode("states-far"); - waitForGestureProcessingAndAssert(); + waitForGestureProcessing(); assertNull(getSelectedText()); assertPanelClosedOrUndefined(); clickNode("states-far"); - waitForGestureProcessingAndAssert(); - waitForPanelToPeekAndAssert(); + waitForGestureProcessing(); + waitForPanelToPeek(); assertEquals("States", getSelectedText()); } @@ -1287,7 +1267,7 @@ throws InterruptedException, TimeoutException { clickWordNode("states"); assertEquals("States", getSelectedText()); - waitForPanelToPeekAndAssert(); + waitForPanelToPeek(); // Avoid issues with double-tap detection by ensuring sequential taps // aren't treated as such. Double-tapping can also select words much as // longpress, in turn showing the pins and preventing contextual tap @@ -1313,7 +1293,7 @@ public void testLongPressGestureFollowedByScrollMaintainsSelection() throws InterruptedException, TimeoutException { longPressNode("intelligence"); - waitForPanelToPeekAndAssert(); + waitForPanelToPeek(); scrollBasePage(); assertPanelClosedOrUndefined(); assertEquals("Intelligence", getSelectedText()); @@ -1329,7 +1309,7 @@ public void testLongPressGestureFollowedByTapDoesntSelect() throws InterruptedException, TimeoutException { longPressNode("intelligence"); - waitForPanelToPeekAndAssert(); + waitForPanelToPeek(); clickWordNode("states-far"); waitForGestureToClosePanelAndAssertNoSelection(); assertLoadedNoUrl(); @@ -1345,7 +1325,7 @@ throws InterruptedException, TimeoutException { clickWordNode("states"); assertEquals("States", getSelectedText()); - waitForPanelToPeekAndAssert(); + waitForPanelToPeek(); ThreadUtils.runOnUiThread(new Runnable() { @Override @@ -1389,7 +1369,7 @@ clickWordNode("states"); assertEquals("States", getSelectedText()); - waitForPanelToPeekAndAssert(); + waitForPanelToPeek(); ThreadUtils.runOnUiThread(new Runnable() { @Override @@ -1398,16 +1378,7 @@ } }); - // Give the panelState time to change - CriteriaHelper.pollForCriteria(new Criteria(){ - @Override - public boolean isSatisfied() { - PanelState panelState = mPanel.getPanelState(); - return panelState != PanelState.PEEKED; - } - }); - - waitForPanelToPeekAndAssert(); + waitForPanelToPeek(); } /* @@ -1426,11 +1397,11 @@ assertSearchTermRequested(); // Wait for the panel to peek. - waitForPanelToPeekAndAssert(); + waitForPanelToPeek(); // Swipe Panel up and wait for it to maximize. flingPanelUpToTop(); - waitForPanelToMaximizeAndAssert(); + waitForPanelToMaximize(); // Create an observer to track that a new tab is created. final CallbackHelper tabCreatedHelper = new CallbackHelper(); @@ -1448,7 +1419,7 @@ // The Search Term Resolution response hasn't arrived yet, so the Panel should not // be promoted. Therefore, we are asserting that the Panel is still maximized. - waitForPanelToMaximizeAndAssert(); + waitForPanelToMaximize(); // Get a Search Term Resolution response. fakeResponse(false, 200, "Intelligence", "display-text", "alternate-term", false); @@ -1459,7 +1430,7 @@ // Now that the response has arrived, tapping on the Search Panel should promote it // to a Tab. Therefore, we are asserting that the Panel got closed. - waitForPanelToCloseAndAssert(); + waitForPanelToClose(); // Finally, make sure a tab was created. if (!FeatureUtilities.isDocumentMode(getInstrumentation().getContext())) { @@ -1631,7 +1602,7 @@ // A long-press should still show the promo bar. longPressNode("states"); - waitForPanelToPeekAndAssert(); + waitForPanelToPeek(); // Expanding the panel should deactivate the limit. tapBarToExpandAndClosePanel(); @@ -1789,14 +1760,14 @@ * Asserts whether the App Menu is visible. */ private void assertAppMenuVisibility(final boolean isVisible) throws InterruptedException { - assertTrue(CriteriaHelper.pollForCriteria(new Criteria() { + CriteriaHelper.pollForCriteria(new Criteria() { @Override public boolean isSatisfied() { if (getActivity() .getAppMenuHandler().isAppMenuShowing() == isVisible) return true; return false; } - })); + }); } /** @@ -1827,13 +1798,13 @@ public void testAppMenuSuppressedWhenMaximized() throws InterruptedException, TimeoutException { clickWordNode("states"); flingPanelUpToTop(); - waitForPanelToMaximizeAndAssert(); + waitForPanelToMaximize(); pressAppMenuKey(); assertAppMenuVisibility(false); pressBackButton(); - waitForPanelToCloseAndAssert(); + waitForPanelToClose(); pressAppMenuKey(); assertAppMenuVisibility(true); @@ -2016,13 +1987,13 @@ private void assertWaitForSelectActionBarVisible(final boolean visible) throws InterruptedException { - assertTrue(CriteriaHelper.pollForUIThreadCriteria(new Criteria() { + CriteriaHelper.pollForUIThreadCriteria(new Criteria() { @Override public boolean isSatisfied() { return visible == getActivity().getActivityTab().getContentViewCore() .isSelectActionBarShowing(); } - })); + }); } /** @@ -2050,7 +2021,7 @@ }); assertWaitForSelectActionBarVisible(false); - waitForPanelToCloseAndAssert(); + waitForPanelToClose(); assertEquals(1, observer.hideCount); } @@ -2065,7 +2036,7 @@ public void testPreventHandlingCurrentSelectionModification() throws InterruptedException, TimeoutException { longPressNode("intelligence"); - waitForPanelToPeekAndAssert(); + waitForPanelToPeek(); // Dismiss the Contextual Search panel. scrollBasePage(); @@ -2079,7 +2050,7 @@ // Select a different word and assert that the panel has appeared. longPressNode("states-far"); - waitForPanelToPeekAndAssert(); + waitForPanelToPeek(); } /** @@ -2193,7 +2164,7 @@ throws InterruptedException, TimeoutException { mFakeServer.reset(); clickWordNode("intelligence"); - waitForPanelToPeekAndAssert(); + waitForPanelToPeek(); fakeResponse(false, 200, "Intelligence", "United States Intelligence", "alternate-term", false, -14, 0, ""); @@ -2218,12 +2189,12 @@ // Long press and make sure the Promo shows. longPressNode("intelligence"); - waitForPanelToPeekAndAssert(); + waitForPanelToPeek(); assertTrue(mPanel.isPeekPromoVisible()); // After expanding the Panel the Promo should be invisible. flingPanelUp(); - waitForPanelToExpandAndAssert(); + waitForPanelToExpand(); assertFalse(mPanel.isPeekPromoVisible()); // After closing the Panel the Promo should still be invisible. @@ -2236,7 +2207,7 @@ // Now that the Panel was opened at least once, the Promo should not show again. longPressNode("intelligence"); - waitForPanelToPeekAndAssert(); + waitForPanelToPeek(); assertFalse(mPanel.isPeekPromoVisible()); } @@ -2307,7 +2278,7 @@ // Swiping the Panel down should not change the visibility or load content again. swipePanelDown(); - waitForPanelToPeekAndAssert(); + waitForPanelToPeek(); assertContentViewCoreVisible(); assertEquals(1, mFakeServer.getLoadedUrlCount()); @@ -2343,7 +2314,7 @@ // Swiping the Panel down should not change the visibility or load content again. swipePanelDown(); - waitForPanelToPeekAndAssert(); + waitForPanelToPeek(); assertContentViewCoreVisible(); assertEquals(1, mFakeServer.getLoadedUrlCount()); @@ -2418,7 +2389,7 @@ // Swiping the Panel down should not change the visibility or load content again. swipePanelDown(); - waitForPanelToPeekAndAssert(); + waitForPanelToPeek(); assertContentViewCoreVisible(); assertEquals(1, mFakeServer.getLoadedUrlCount());
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/contextualsearch/ContextualSearchPolicyTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/contextualsearch/ContextualSearchPolicyTest.java new file mode 100644 index 0000000..96ec178 --- /dev/null +++ b/chrome/android/javatests/src/org/chromium/chrome/browser/contextualsearch/ContextualSearchPolicyTest.java
@@ -0,0 +1,71 @@ +// 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.contextualsearch; + +import android.test.suitebuilder.annotation.SmallTest; + +import org.chromium.base.test.util.Feature; +import org.chromium.chrome.test.ChromeTabbedActivityTestBase; + +import java.util.ArrayList; + +/** + * Tests for the ContextualSearchPolicy class. + */ +public class ContextualSearchPolicyTest extends ChromeTabbedActivityTestBase { + ContextualSearchPolicy mPolicy; + + @Override + public void startMainActivity() throws InterruptedException { + startMainActivityOnBlankPage(); + } + + @Override + protected void setUp() throws Exception { + super.setUp(); + + getInstrumentation().runOnMainSync(new Runnable() { + @Override + public void run() { + mPolicy = ContextualSearchPolicy.getInstance(getActivity().getApplicationContext()); + } + }); + } + + @SmallTest + @Feature({"ContextualSearch"}) + public void testBestTargetLanguageFromMultiple() { + ArrayList<String> list = new ArrayList<String>(); + list.add("br"); + list.add("de"); + assertEquals("br", mPolicy.bestTargetLanguage(list)); + } + + @SmallTest + @Feature({"ContextualSearch"}) + public void testBestTargetLanguageSkipsEnglish() { + ArrayList<String> list = new ArrayList<String>(); + list.add("en"); + list.add("de"); + assertEquals("de", mPolicy.bestTargetLanguage(list)); + } + + @SmallTest + @Feature({"ContextualSearch"}) + public void testBestTargetLanguageUsesEnglishWhenOnlyChoice() { + ArrayList<String> list = new ArrayList<String>(); + list.add("en"); + assertEquals("en", mPolicy.bestTargetLanguage(list)); + } + + @SmallTest + @Feature({"ContextualSearch"}) + public void testBestTargetLanguageReturnsEmptyWhenNoChoice() { + ArrayList<String> list = new ArrayList<String>(); + assertEquals("", mPolicy.bestTargetLanguage(list)); + } + + // TODO(donnd): This set of tests is not complete, add more tests. +}
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/crash/MinidumpUploadServiceTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/crash/MinidumpUploadServiceTest.java index 407c2549..2ce4ea1 100644 --- a/chrome/android/javatests/src/org/chromium/chrome/browser/crash/MinidumpUploadServiceTest.java +++ b/chrome/android/javatests/src/org/chromium/chrome/browser/crash/MinidumpUploadServiceTest.java
@@ -320,18 +320,17 @@ service.onHandleIntent(uploadIntent); // Verify asynchronously. - assertTrue("All callables should have a call-count of 1", - CriteriaHelper.pollForCriteria(new Criteria() { - @Override - public boolean isSatisfied() { - for (CountedMinidumpUploadCallable callable : callables) { - if (callable.mCalledCount != 1) { - return false; - } - } - return true; + CriteriaHelper.pollForCriteria(new Criteria("All callables should have a call-count of 1") { + @Override + public boolean isSatisfied() { + for (CountedMinidumpUploadCallable callable : callables) { + if (callable.mCalledCount != 1) { + return false; } - }, MAX_TIMEOUT_MS, CHECK_INTERVAL_MS)); + } + return true; + } + }, MAX_TIMEOUT_MS, CHECK_INTERVAL_MS); } /**
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/customtabs/CustomTabActivityTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/customtabs/CustomTabActivityTest.java index e37e82ec..b68e047 100644 --- a/chrome/android/javatests/src/org/chromium/chrome/browser/customtabs/CustomTabActivityTest.java +++ b/chrome/android/javatests/src/org/chromium/chrome/browser/customtabs/CustomTabActivityTest.java
@@ -165,12 +165,12 @@ } }); - assertTrue("App menu was not shown", CriteriaHelper.pollForUIThreadCriteria(new Criteria() { + CriteriaHelper.pollForUIThreadCriteria(new Criteria("App menu was not shown") { @Override public boolean isSatisfied() { return mActivity.getAppMenuHandler().isAppMenuShowing(); } - })); + }); } /** @@ -301,12 +301,12 @@ } }); - assertTrue("Pending Intent was not sent.", CriteriaHelper.pollForCriteria(new Criteria() { + CriteriaHelper.pollForCriteria(new Criteria("Pending Intent was not sent.") { @Override public boolean isSatisfied() { return onFinished.isSent(); } - })); + }); } /** @@ -338,14 +338,14 @@ final ChromeActivity chromeActivity = (ChromeActivity) monitor .waitForActivityWithTimeout(ACTIVITY_START_TIMEOUT_MS); assertNotNull("A normal chrome activity did not start.", chromeActivity); - assertTrue("The normal tab was not initiated correctly.", - CriteriaHelper.pollForUIThreadCriteria(new Criteria() { + CriteriaHelper.pollForUIThreadCriteria( + new Criteria("The normal tab was not initiated correctly.") { @Override public boolean isSatisfied() { Tab tab = chromeActivity.getActivityTab(); return tab != null && tab.getUrl().equals(TEST_PAGE); } - })); + }); } /** @@ -409,12 +409,12 @@ } }); - assertTrue("Pending Intent was not sent.", CriteriaHelper.pollForCriteria(new Criteria() { + CriteriaHelper.pollForCriteria(new Criteria("Pending Intent was not sent.") { @Override public boolean isSatisfied() { return onFinished.isSent(); } - })); + }); } /** @@ -468,12 +468,12 @@ (new CustomTabsTestUtils.DummyCallback()).asBinder())); } })); - assertTrue(CriteriaHelper.pollForCriteria(new Criteria() { - @Override - public boolean isSatisfied() { - return mActivity.getActivityTab().getUrl().equals(TEST_PAGE); - } - })); + CriteriaHelper.pollForCriteria(new Criteria() { + @Override + public boolean isSatisfied() { + return mActivity.getActivityTab().getUrl().equals(TEST_PAGE); + } + }); assertTrue("CustomTabContentHandler can't handle intent with same session", ThreadUtils.runOnUiThreadBlockingNoException(new Callable<Boolean>() { @Override @@ -496,12 +496,12 @@ } catch (TimeoutException e) { fail(); } - assertTrue(CriteriaHelper.pollForCriteria(new Criteria() { - @Override - public boolean isSatisfied() { - return mActivity.getActivityTab().getUrl().equals(TEST_PAGE_2); - } - })); + CriteriaHelper.pollForCriteria(new Criteria() { + @Override + public boolean isSatisfied() { + return mActivity.getActivityTab().getUrl().equals(TEST_PAGE_2); + } + }); } @SmallTest
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/customtabs/CustomTabActivityTestBase.java b/chrome/android/javatests/src/org/chromium/chrome/browser/customtabs/CustomTabActivityTestBase.java index b4b113f1..181276c 100644 --- a/chrome/android/javatests/src/org/chromium/chrome/browser/customtabs/CustomTabActivityTestBase.java +++ b/chrome/android/javatests/src/org/chromium/chrome/browser/customtabs/CustomTabActivityTestBase.java
@@ -51,13 +51,12 @@ */ protected void startCustomTabActivityWithIntent(Intent intent) throws InterruptedException { startActivityCompletely(intent); - assertTrue("Tab never selected/initialized.", - CriteriaHelper.pollForUIThreadCriteria(new Criteria() { - @Override - public boolean isSatisfied() { - return getActivity().getActivityTab() != null; - } - })); + CriteriaHelper.pollForUIThreadCriteria(new Criteria("Tab never selected/initialized.") { + @Override + public boolean isSatisfied() { + return getActivity().getActivityTab() != null; + } + }); final Tab tab = getActivity().getActivityTab(); final CallbackHelper pageLoadFinishedHelper = new CallbackHelper(); tab.addObserver(new EmptyTabObserver() { @@ -71,13 +70,12 @@ } catch (TimeoutException e) { fail(); } - assertTrue("Deferred startup never completed", - CriteriaHelper.pollForUIThreadCriteria(new Criteria() { - @Override - public boolean isSatisfied() { - return DeferredStartupHandler.getInstance().isDeferredStartupComplete(); - } - }, 5000, 200)); + CriteriaHelper.pollForUIThreadCriteria(new Criteria("Deferred startup never completed") { + @Override + public boolean isSatisfied() { + return DeferredStartupHandler.getInstance().isDeferredStartupComplete(); + } + }, 5000, 200); assertNotNull(tab); assertNotNull(tab.getView()); }
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/document/DocumentModeReferrerTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/document/DocumentModeReferrerTest.java index b583fc29..ce05191 100644 --- a/chrome/android/javatests/src/org/chromium/chrome/browser/document/DocumentModeReferrerTest.java +++ b/chrome/android/javatests/src/org/chromium/chrome/browser/document/DocumentModeReferrerTest.java
@@ -51,12 +51,12 @@ ApplicationTestUtils.launchChrome(mContext); // Wait for tab model to become initialized. - assertTrue(CriteriaHelper.pollForCriteria(new Criteria() { + CriteriaHelper.pollForCriteria(new Criteria() { @Override public boolean isSatisfied() { return ChromeApplication.isDocumentTabModelSelectorInitializedForTests(); } - })); + }); DocumentTabModelSelector selector = ChromeApplication.getDocumentTabModelSelector(); mObserver = new TabModelSelectorTabObserver(selector) { @@ -86,12 +86,12 @@ IntentHandler.addTrustedIntentExtras(intent, mContext); mContext.startActivity(intent); - assertTrue(CriteriaHelper.pollForUIThreadCriteria(new Criteria() { + CriteriaHelper.pollForUIThreadCriteria(new Criteria() { @Override public boolean isSatisfied() { return URL_1.equals(mUrl); } - })); + }); assertEquals(URL_2, mReferrer); } @@ -103,12 +103,12 @@ ApplicationTestUtils.launchChrome(mContext); // Wait for tab model to become initialized. - assertTrue(CriteriaHelper.pollForCriteria(new Criteria() { + CriteriaHelper.pollForCriteria(new Criteria() { @Override public boolean isSatisfied() { return ChromeApplication.isDocumentTabModelSelectorInitializedForTests(); } - })); + }); DocumentTabModelSelector selector = ChromeApplication.getDocumentTabModelSelector(); mObserver = new TabModelSelectorTabObserver(selector) { @@ -138,12 +138,12 @@ intent.putExtra(Intent.EXTRA_REFERRER, Uri.parse(androidAppReferrer)); mContext.startActivity(intent); - assertTrue(CriteriaHelper.pollForUIThreadCriteria(new Criteria() { + CriteriaHelper.pollForUIThreadCriteria(new Criteria() { @Override public boolean isSatisfied() { return URL_1.equals(mUrl); } - })); + }); assertEquals(androidAppReferrer, mReferrer); } @@ -155,12 +155,12 @@ ApplicationTestUtils.launchChrome(mContext); // Wait for tab model to become initialized. - assertTrue(CriteriaHelper.pollForCriteria(new Criteria() { + CriteriaHelper.pollForCriteria(new Criteria() { @Override public boolean isSatisfied() { return ChromeApplication.isDocumentTabModelSelectorInitializedForTests(); } - })); + }); DocumentTabModelSelector selector = ChromeApplication.getDocumentTabModelSelector(); mObserver = new TabModelSelectorTabObserver(selector) { @@ -190,12 +190,12 @@ intent.putExtra(Intent.EXTRA_REFERRER, Uri.parse(nonAppExtra)); mContext.startActivity(intent); - assertTrue(CriteriaHelper.pollForUIThreadCriteria(new Criteria() { + CriteriaHelper.pollForUIThreadCriteria(new Criteria() { @Override public boolean isSatisfied() { return URL_1.equals(mUrl); } - })); + }); // Check that referrer is not carried over assertNull(mReferrer); @@ -208,12 +208,12 @@ ApplicationTestUtils.launchChrome(mContext); // Wait for tab model to become initialized. - assertTrue(CriteriaHelper.pollForCriteria(new Criteria() { + CriteriaHelper.pollForCriteria(new Criteria() { @Override public boolean isSatisfied() { return ChromeApplication.isDocumentTabModelSelectorInitializedForTests(); } - })); + }); DocumentTabModelSelector selector = ChromeApplication.getDocumentTabModelSelector(); mObserver = new TabModelSelectorTabObserver(selector) { @@ -244,12 +244,12 @@ IntentHandler.setPendingReferrer(intent, "http://www.google.com"); mContext.startActivity(intent); - assertTrue(CriteriaHelper.pollForUIThreadCriteria(new Criteria() { + CriteriaHelper.pollForUIThreadCriteria(new Criteria() { @Override public boolean isSatisfied() { return URL_1.equals(mUrl); } - })); + }); // Check that referrer is not carried over assertEquals("http://www.google.com", mReferrer);
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/document/DocumentModeTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/document/DocumentModeTest.java index c596374..67b96e33 100644 --- a/chrome/android/javatests/src/org/chromium/chrome/browser/document/DocumentModeTest.java +++ b/chrome/android/javatests/src/org/chromium/chrome/browser/document/DocumentModeTest.java
@@ -92,7 +92,7 @@ startTabbedActivity(URL_1); // ApplicationStatus should note that the ChromeTabbedActivity isn't running anymore. - assertTrue(CriteriaHelper.pollForUIThreadCriteria(new Criteria() { + CriteriaHelper.pollForUIThreadCriteria(new Criteria() { @Override public boolean isSatisfied() { List<WeakReference<Activity>> activities = ApplicationStatus.getRunningActivities(); @@ -101,7 +101,7 @@ } return true; } - })); + }); } /** @@ -126,22 +126,22 @@ // A DocumentActivity gets started, but it should immediately call finishAndRemoveTask() // because of the broken Intent. - assertTrue(CriteriaHelper.pollForUIThreadCriteria(new Criteria() { + CriteriaHelper.pollForUIThreadCriteria(new Criteria() { @Override public boolean isSatisfied() { Activity activity = ApplicationStatus.getLastTrackedFocusedActivity(); return activity != lastTrackedActivity; } - })); + }); // We shouldn't record that a new Tab exists. - assertTrue(CriteriaHelper.pollForUIThreadCriteria(new Criteria() { + CriteriaHelper.pollForUIThreadCriteria(new Criteria() { @Override public boolean isSatisfied() { return selector.getCurrentModel().getCount() == 3 && selector.getTotalTabCount() == 3; } - })); + }); } /** @@ -167,7 +167,7 @@ // Funnily enough, Android doesn't differentiate between URIs with different queries when // refocusing Activities based on the Intent data. This means we can't do a check to see // that the new Activity appears with URL_4 -- we just get a new instance of URL_3. - assertTrue(CriteriaHelper.pollForUIThreadCriteria(new Criteria() { + CriteriaHelper.pollForUIThreadCriteria(new Criteria() { @Override public boolean isSatisfied() { Activity activity = ApplicationStatus.getLastTrackedFocusedActivity(); @@ -179,16 +179,16 @@ && !selector.isIncognitoSelected() && lastTabId == selector.getCurrentTabId(); } - })); + }); // Although we get a new DocumentActivity, the old one with the same tab ID gets killed. - assertTrue(CriteriaHelper.pollForUIThreadCriteria(new Criteria() { + CriteriaHelper.pollForUIThreadCriteria(new Criteria() { @Override public boolean isSatisfied() { return selector.getCurrentModel().getCount() == 3 && selector.getTotalTabCount() == 3; } - })); + }); } /** @@ -212,14 +212,14 @@ mContext.startActivity(intent); ApplicationTestUtils.waitUntilChromeInForeground(); - assertTrue(CriteriaHelper.pollForCriteria(new Criteria() { + CriteriaHelper.pollForCriteria(new Criteria() { @Override public boolean isSatisfied() { return lastTrackedActivity == ApplicationStatus.getLastTrackedFocusedActivity() && !selector.isIncognitoSelected() && lastTabId == selector.getCurrentTabId(); } - })); + }); assertEquals(3, selector.getCurrentModel().getCount()); assertEquals(3, selector.getTotalTabCount()); @@ -241,12 +241,12 @@ ApplicationTestUtils.fireHomeScreenIntent(mContext); ApplicationTestUtils.launchChrome(mContext); - assertTrue(CriteriaHelper.pollForCriteria(new Criteria() { + CriteriaHelper.pollForCriteria(new Criteria() { @Override public boolean isSatisfied() { return !selector.isIncognitoSelected() && lastTabId == selector.getCurrentTabId(); } - })); + }); assertEquals(3, selector.getCurrentModel().getCount()); assertEquals(3, selector.getTotalTabCount()); @@ -268,12 +268,12 @@ } }); - assertTrue(CriteriaHelper.pollForCriteria(new Criteria() { + CriteriaHelper.pollForCriteria(new Criteria() { @Override public boolean isSatisfied() { return !selector.isIncognitoSelected() && selector.getCurrentModel().index() == 0; } - })); + }); assertEquals(3, selector.getCurrentModel().getCount()); assertEquals(3, selector.getTotalTabCount()); @@ -304,25 +304,25 @@ }; ActivityUtils.waitForActivity(getInstrumentation(), ChromeLauncherActivity.class, runnable); ApplicationTestUtils.waitUntilChromeInForeground(); - assertTrue(CriteriaHelper.pollForUIThreadCriteria(new Criteria() { + CriteriaHelper.pollForUIThreadCriteria(new Criteria() { @Override public boolean isSatisfied() { Activity lastActivity = ApplicationStatus.getLastTrackedFocusedActivity(); return lastActivity instanceof DocumentActivity; } - })); + }); assertEquals(tabId, selector.getCurrentTabId()); assertFalse(selector.isIncognitoSelected()); // Create another tab. final int secondTabId = launchViaViewIntent(false, URL_2, "Page 2"); - assertTrue(CriteriaHelper.pollForUIThreadCriteria(new Criteria() { + CriteriaHelper.pollForUIThreadCriteria(new Criteria() { @Override public boolean isSatisfied() { return selector.getModel(false).getCount() == 2 && selector.getCurrentTabId() == secondTabId; } - })); + }); } /** @@ -358,45 +358,45 @@ final DocumentTabModelSelector selector = ChromeApplication.getDocumentTabModelSelector(); final TabModel incognitoModel = selector.getModel(true); - assertTrue(CriteriaHelper.pollForUIThreadCriteria(new Criteria() { + CriteriaHelper.pollForUIThreadCriteria(new Criteria() { @Override public boolean isSatisfied() { return firstId == selector.getCurrentTabId() && selector.getTotalTabCount() == 1; } - })); + }); assertEquals(incognitoModel, selector.getCurrentModel()); // Make sure the URL isn't in the Intent of the first IncognitoDocumentActivity. - assertTrue(CriteriaHelper.pollForUIThreadCriteria(new Criteria() { + CriteriaHelper.pollForUIThreadCriteria(new Criteria() { @Override public boolean isSatisfied() { return ApplicationStatus.getLastTrackedFocusedActivity() instanceof IncognitoDocumentActivity; } - })); + }); assertNull("URL is in the Incognito Intent", IntentHandler.getUrlFromIntent( ApplicationStatus.getLastTrackedFocusedActivity().getIntent())); // Launch via ChromeLauncherActivity.launchInstance(). final int secondId = launchViaLaunchDocumentInstance(true, URL_3, "Page 3"); - assertTrue(CriteriaHelper.pollForUIThreadCriteria(new Criteria() { + CriteriaHelper.pollForUIThreadCriteria(new Criteria() { @Override public boolean isSatisfied() { return secondId == selector.getCurrentTabId() && selector.getTotalTabCount() == 2; } - })); + }); assertTrue(selector.isIncognitoSelected()); assertEquals(incognitoModel, selector.getCurrentModel()); assertEquals(secondId, TabModelUtils.getCurrentTabId(incognitoModel)); // Make sure the URL isn't in the Intent of the second IncognitoDocumentActivity. - assertTrue(CriteriaHelper.pollForUIThreadCriteria(new Criteria() { + CriteriaHelper.pollForUIThreadCriteria(new Criteria() { @Override public boolean isSatisfied() { return ApplicationStatus.getLastTrackedFocusedActivity() instanceof IncognitoDocumentActivity; } - })); + }); assertNull("URL is in the Incognito Intent", IntentHandler.getUrlFromIntent( ApplicationStatus.getLastTrackedFocusedActivity().getIntent())); } @@ -414,12 +414,12 @@ final DocumentTabModelSelector selector = ChromeApplication.getDocumentTabModelSelector(); final TabModel incognitoModel = selector.getModel(true); - assertTrue(CriteriaHelper.pollForUIThreadCriteria(new Criteria() { + CriteriaHelper.pollForUIThreadCriteria(new Criteria() { @Override public boolean isSatisfied() { return firstId == selector.getCurrentTabId() && selector.getTotalTabCount() == 1; } - })); + }); assertEquals(incognitoModel, selector.getCurrentModel()); Activity firstActivity = ApplicationStatus.getLastTrackedFocusedActivity(); @@ -428,12 +428,12 @@ // The context menu for links in Incognito mode lacks an "Open in new Incognito tab" option. // Instead, the regular "Open in new tab" option opens a new incognito tab. openLinkInNewTabViaContextMenu(false, true); - assertTrue(CriteriaHelper.pollForUIThreadCriteria(new Criteria() { + CriteriaHelper.pollForUIThreadCriteria(new Criteria() { @Override public boolean isSatisfied() { return firstId == selector.getCurrentTabId() && selector.getTotalTabCount() == 2; } - })); + }); assertEquals(incognitoModel, selector.getCurrentModel()); assertEquals(firstActivity, ApplicationStatus.getLastTrackedFocusedActivity()); } @@ -450,12 +450,12 @@ assertFalse(selector.isIncognitoSelected()); final int incognitoId = launchViaLaunchDocumentInstance(true, URL_2, "Page 2"); - assertTrue(CriteriaHelper.pollForUIThreadCriteria(new Criteria() { + CriteriaHelper.pollForUIThreadCriteria(new Criteria() { @Override public boolean isSatisfied() { return selector.isIncognitoSelected() && selector.getCurrentTabId() == incognitoId; } - })); + }); assertEquals(0, selector.getCurrentModel().index()); assertEquals(1, selector.getCurrentModel().getCount()); @@ -463,12 +463,12 @@ ChromeLauncherActivity.getRemoveAllIncognitoTabsIntent(mContext); closeAllIntent.send(); - assertTrue(CriteriaHelper.pollForUIThreadCriteria(new Criteria() { + CriteriaHelper.pollForUIThreadCriteria(new Criteria() { @Override public boolean isSatisfied() { return selector.getCurrentTabId() == regularId; } - })); + }); OffTheRecordDocumentTabModel tabModel = (OffTheRecordDocumentTabModel) selector.getModel(true); assertFalse(selector.isIncognitoSelected()); @@ -510,13 +510,13 @@ // Re-open the other tab. TabModelUtils.setIndex(regularTabModel, 0); - assertTrue(CriteriaHelper.pollForUIThreadCriteria(new Criteria() { + CriteriaHelper.pollForUIThreadCriteria(new Criteria() { @Override public boolean isSatisfied() { return !selector.isIncognitoSelected() && selector.getCurrentTabId() == regularTabId; } - })); + }); // Try to open a new Incognito Tab in the background using the TabModelSelector directly. // Should open it in the foreground, instead.
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/document/DocumentModeTestBase.java b/chrome/android/javatests/src/org/chromium/chrome/browser/document/DocumentModeTestBase.java index d4fc773b..7b33af79 100644 --- a/chrome/android/javatests/src/org/chromium/chrome/browser/document/DocumentModeTestBase.java +++ b/chrome/android/javatests/src/org/chromium/chrome/browser/document/DocumentModeTestBase.java
@@ -165,7 +165,7 @@ ApplicationTestUtils.waitUntilChromeInForeground(); // Wait until the selector is ready and the Tabs have been added to the DocumentTabModel. - assertTrue(CriteriaHelper.pollForCriteria(new Criteria() { + CriteriaHelper.pollForCriteria(new Criteria() { @Override public boolean isSatisfied() { if (!ChromeApplication.isDocumentTabModelSelectorInitializedForTests()) { @@ -179,7 +179,7 @@ if (selector.getCurrentTabId() == tabId) return false; return true; } - })); + }); if (launchedInBackground) { ChromeTabUtils.waitForTabPageLoaded(newActivity.getActivityTab(), (String) null); @@ -206,7 +206,7 @@ openLinkInNewTabViaContextMenu(false, false); - assertTrue(CriteriaHelper.pollForUIThreadCriteria(new Criteria() { + CriteriaHelper.pollForUIThreadCriteria(new Criteria() { @Override public boolean isSatisfied() { if (expectedTabCount != tabModel.getCount()) return false; @@ -214,7 +214,7 @@ if (expectedTabId != selector.getCurrentTabId()) return false; return true; } - })); + }); assertEquals(expectedActivity, ApplicationStatus.getLastTrackedFocusedActivity()); } @@ -250,12 +250,12 @@ } }); TouchCommon.longPressView(view); - assertTrue(CriteriaHelper.pollForUIThreadCriteria(new Criteria() { + CriteriaHelper.pollForUIThreadCriteria(new Criteria() { @Override public boolean isSatisfied() { return observer.mContextMenu != null; } - })); + }); activity.getActivityTab().removeObserver(observer); // Select the "open in new tab" option. @@ -287,7 +287,7 @@ protected void switchToTab(final DocumentTab tab) throws Exception { final TabModel tabModel = ChromeApplication.getDocumentTabModelSelector().getCurrentModel(); - assertTrue(CriteriaHelper.pollForCriteria(new Criteria() { + CriteriaHelper.pollForCriteria(new Criteria() { @Override public boolean isSatisfied() { // http://crbug.com/509866: TabModelUtils#setIndex() sometimes fails. @@ -304,7 +304,7 @@ if (activity == null) return false; return ApplicationStatus.getStateForActivity(activity) == ActivityState.RESUMED; } - })); + }); } /**
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/document/LauncherActivityTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/document/LauncherActivityTest.java index 1a006a1..913c952 100644 --- a/chrome/android/javatests/src/org/chromium/chrome/browser/document/LauncherActivityTest.java +++ b/chrome/android/javatests/src/org/chromium/chrome/browser/document/LauncherActivityTest.java
@@ -41,13 +41,13 @@ mContext.startActivity(intent); // Check that Chrome launched successfully - assertTrue(CriteriaHelper.pollForCriteria(new Criteria() { + CriteriaHelper.pollForCriteria(new Criteria() { @Override public boolean isSatisfied() { int state = ApplicationStatus.getStateForApplication(); return state == ApplicationState.HAS_RUNNING_ACTIVITIES; } - })); + }); } @Override
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/dom_distiller/ReaderModeManagerTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/dom_distiller/ReaderModeManagerTest.java index 0a7d394a..6d590bd 100644 --- a/chrome/android/javatests/src/org/chromium/chrome/browser/dom_distiller/ReaderModeManagerTest.java +++ b/chrome/android/javatests/src/org/chromium/chrome/browser/dom_distiller/ReaderModeManagerTest.java
@@ -55,13 +55,15 @@ private int mPanelHideCount; @Override - public void requestPanelShow(OverlayPanel p, StateChangeReason r) { + public void requestPanelShow(OverlayPanel panel, StateChangeReason reason) { mRequestPanelShowCount++; + super.requestPanelShow(panel, reason); } @Override - public void notifyPanelClosed(OverlayPanel p, StateChangeReason r) { + public void notifyPanelClosed(OverlayPanel panel, StateChangeReason reason) { mPanelHideCount++; + super.notifyPanelClosed(panel, reason); } public int getRequestPanelShowCount() { @@ -162,12 +164,14 @@ @SmallTest @Feature({"ReaderModeManager"}) public void testInfoBarEvents() { + mPanel.requestPanelShow(StateChangeReason.UNKNOWN); + mReaderManager.onAddInfoBar(null, null, true); - assertEquals(0, mPanelManager.getRequestPanelShowCount()); + assertEquals(1, mPanelManager.getRequestPanelShowCount()); assertEquals(1, mPanelManager.getPanelHideCount()); mReaderManager.onRemoveInfoBar(null, null, true); - assertEquals(1, mPanelManager.getRequestPanelShowCount()); + assertEquals(2, mPanelManager.getRequestPanelShowCount()); assertEquals(1, mPanelManager.getPanelHideCount()); } @@ -177,12 +181,14 @@ @SmallTest @Feature({"ReaderModeManager"}) public void testFullscreenEvents() { + mPanel.requestPanelShow(StateChangeReason.UNKNOWN); + mReaderManager.onToggleFullscreenMode(null, true); - assertEquals(0, mPanelManager.getRequestPanelShowCount()); + assertEquals(1, mPanelManager.getRequestPanelShowCount()); assertEquals(1, mPanelManager.getPanelHideCount()); mReaderManager.onToggleFullscreenMode(null, false); - assertEquals(1, mPanelManager.getRequestPanelShowCount()); + assertEquals(2, mPanelManager.getRequestPanelShowCount()); assertEquals(1, mPanelManager.getPanelHideCount()); }
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/download/DownloadManagerServiceTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/download/DownloadManagerServiceTest.java index ed5260d..8f1d438 100644 --- a/chrome/android/javatests/src/org/chromium/chrome/browser/download/DownloadManagerServiceTest.java +++ b/chrome/android/javatests/src/org/chromium/chrome/browser/download/DownloadManagerServiceTest.java
@@ -68,18 +68,17 @@ } public void waitTillExpectedCallsComplete() { - boolean result = false; try { - result = CriteriaHelper.pollForCriteria(new Criteria() { - @Override - public boolean isSatisfied() { - return mExpectedCalls.isEmpty(); - } - }); + CriteriaHelper.pollForCriteria( + new Criteria("Failed while waiting for all calls to complete.") { + @Override + public boolean isSatisfied() { + return mExpectedCalls.isEmpty(); + } + }); } catch (InterruptedException e) { fail("Failed while waiting for all calls to complete." + e); } - assertTrue("Failed while waiting for all calls to complete.", result); } public MockDownloadNotifier andThen(MethodID method, Object param) { @@ -135,18 +134,17 @@ } public void waitForSnackbarControllerToFinish(final boolean success) { - boolean result = false; try { - result = CriteriaHelper.pollForCriteria(new Criteria() { - @Override - public boolean isSatisfied() { - return success ? mSucceeded : mFailed; - } - }); + CriteriaHelper.pollForCriteria( + new Criteria("Failed while waiting for all calls to complete.") { + @Override + public boolean isSatisfied() { + return success ? mSucceeded : mFailed; + } + }); } catch (InterruptedException e) { fail("Failed while waiting for all calls to complete." + e); } - assertTrue("Failed while waiting for all calls to complete.", result); } @Override @@ -451,13 +449,12 @@ dService.setOMADownloadHandler(handler); dService.addOMADownloadToSharedPrefs(String.valueOf(downloadId) + "," + INSTALL_NOTIFY_URI); dService.clearPendingDownloadNotifications(); - boolean result = CriteriaHelper.pollForUIThreadCriteria(new Criteria() { + CriteriaHelper.pollForUIThreadCriteria(new Criteria() { @Override public boolean isSatisfied() { return handler.mSuccess; } }); - assertTrue(result); assertEquals(handler.mNofityURI, "http://test/test"); manager.remove(downloadId); } @@ -483,13 +480,12 @@ dService.setOMADownloadHandler(handler); handler.setDownloadId(0); dService.enqueueDownloadManagerRequest(info, true); - boolean result = CriteriaHelper.pollForUIThreadCriteria(new Criteria() { + CriteriaHelper.pollForUIThreadCriteria(new Criteria() { @Override public boolean isSatisfied() { return handler.mDownloadId != 0; } }); - assertTrue(result); handler.mDownloadId = handler.mDownloadInfo.getDownloadId(); Set<String> downloads = dService.getStoredDownloadInfo( DownloadManagerService.PENDING_OMA_DOWNLOADS);
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/download/DownloadTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/download/DownloadTest.java index cd7777a..3edf0bc 100644 --- a/chrome/android/javatests/src/org/chromium/chrome/browser/download/DownloadTest.java +++ b/chrome/android/javatests/src/org/chromium/chrome/browser/download/DownloadTest.java
@@ -262,13 +262,13 @@ } }); - assertTrue(CriteriaHelper.pollForUIThreadCriteria(new Criteria() { + CriteriaHelper.pollForUIThreadCriteria(new Criteria() { @Override public boolean isSatisfied() { return getActivity().getActivityTab() == model.getTabAt(count - 1) && getActivity().getActivityTab().isReady(); } - })); + }); } private void waitForNewTabToStabilize(final int numTabsAfterNewTab) @@ -276,17 +276,18 @@ // Wait until we have a new tab first. This should be called before checking the active // layout because the active layout changes StaticLayout --> SimpleAnimationLayout // --> (tab added) --> StaticLayout. - assertTrue("Actual tab count: " + getActivity().getCurrentTabModel().getCount(), - CriteriaHelper.pollForUIThreadCriteria(new Criteria() { - @Override - public boolean isSatisfied() { - return getActivity().getCurrentTabModel().getCount() >= numTabsAfterNewTab; - } - })); + CriteriaHelper.pollForUIThreadCriteria(new Criteria() { + @Override + public boolean isSatisfied() { + updateFailureReason( + "Actual tab count: " + getActivity().getCurrentTabModel().getCount()); + return getActivity().getCurrentTabModel().getCount() >= numTabsAfterNewTab; + } + }); // Now wait until the new tab animation finishes. Something wonky happens // if we try to go to the new tab before this. - assertTrue(CriteriaHelper.pollForUIThreadCriteria(new Criteria() { + CriteriaHelper.pollForUIThreadCriteria(new Criteria() { @Override public boolean isSatisfied() { CompositorViewHolder compositorViewHolder = @@ -296,7 +297,7 @@ return layoutManager.getActiveLayout() instanceof StaticLayout; } - })); + }); } /* @@ -371,13 +372,13 @@ */ private void assertPollForInfoBarSize(final int size) throws InterruptedException { final InfoBarContainer container = getActivity().getActivityTab().getInfoBarContainer(); - assertTrue("There should be " + size + " infobar but there are " - + getInfoBars().size() + " infobars.", - CriteriaHelper.pollForUIThreadCriteria(new Criteria() { - @Override - public boolean isSatisfied() { - return getInfoBars().size() == size && !container.isAnimating(); - } - })); + CriteriaHelper.pollForUIThreadCriteria(new Criteria() { + @Override + public boolean isSatisfied() { + updateFailureReason("There should be " + size + " infobar but there are " + + getInfoBars().size() + " infobars."); + return getInfoBars().size() == size && !container.isAnimating(); + } + }); } }
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/download/DownloadTestBase.java b/chrome/android/javatests/src/org/chromium/chrome/browser/download/DownloadTestBase.java index 6d516e2..674bb40 100644 --- a/chrome/android/javatests/src/org/chromium/chrome/browser/download/DownloadTestBase.java +++ b/chrome/android/javatests/src/org/chromium/chrome/browser/download/DownloadTestBase.java
@@ -210,7 +210,7 @@ cleanUpAllDownloads(); try { - assertTrue(ApplicationUtils.waitForLibraryDependencies(getInstrumentation())); + ApplicationUtils.waitForLibraryDependencies(getInstrumentation()); } catch (InterruptedException e) { fail("Library dependencies were never initialized."); }
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/externalnav/UrlOverridingTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/externalnav/UrlOverridingTest.java index 1d556b6..a3468595 100644 --- a/chrome/android/javatests/src/org/chromium/chrome/browser/externalnav/UrlOverridingTest.java +++ b/chrome/android/javatests/src/org/chromium/chrome/browser/externalnav/UrlOverridingTest.java
@@ -184,7 +184,7 @@ // For sub frames, the |loadFailCallback| run through different threads // from the ExternalNavigationHandler. As a result, there is no guarantee // when url override result would come. - assertTrue(CriteriaHelper.pollForUIThreadCriteria( + CriteriaHelper.pollForUIThreadCriteria( new Criteria() { @Override public boolean isSatisfied() { @@ -202,7 +202,7 @@ return expectedFinalUrl == null || TextUtils.equals(expectedFinalUrl, tab.getUrl()); } - })); + }); } @SmallTest @@ -296,12 +296,12 @@ intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK); targetContext.startActivity(intent); - assertTrue(CriteriaHelper.pollForUIThreadCriteria(new Criteria() { + CriteriaHelper.pollForUIThreadCriteria(new Criteria() { @Override public boolean isSatisfied() { return mActivityMonitor.getHits() == 1; } - })); + }); } @Override
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 e4f6de0..5e3a821 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
@@ -45,13 +45,12 @@ } }); - boolean gotResult = CriteriaHelper.pollForUIThreadCriteria(new Criteria() { + CriteriaHelper.pollForUIThreadCriteria(new Criteria("Should be finished by now.") { @Override public boolean isSatisfied() { return task.isDone(); } }, TIMEOUT_MS, RESULT_CHECK_INTERVAL_MS); - assertTrue("Should be finished by now.", gotResult); FeedbackData feedback = getResult(task); verifyConnections(feedback, ConnectivityCheckResult.NOT_CONNECTED); assertEquals("The timeout value is wrong.", TIMEOUT_MS, feedback.getTimeoutMs()); @@ -160,13 +159,17 @@ null); } }); - boolean gotResult = CriteriaHelper.pollForUIThreadCriteria(new Criteria() { - @Override - public boolean isSatisfied() { - return task.isDone(); - } - }, TIMEOUT_MS / 5, RESULT_CHECK_INTERVAL_MS); - assertFalse("Should not be finished by now.", gotResult); + try { + CriteriaHelper.pollForUIThreadCriteria(new Criteria() { + @Override + public boolean isSatisfied() { + return task.isDone(); + } + }, TIMEOUT_MS / 5, RESULT_CHECK_INTERVAL_MS); + fail("Should not be finished by now."); + } catch (AssertionError e) { + // TODO(tedchoc): This is horrible and should never timeout to determine success. + } FeedbackData feedback = getResult(task); verifyConnections(feedback, ConnectivityCheckResult.UNKNOWN); assertEquals("The timeout value is wrong.", TIMEOUT_MS, feedback.getTimeoutMs());
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/fullscreen/FullscreenManagerTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/fullscreen/FullscreenManagerTest.java index ed33716..51a599c 100644 --- a/chrome/android/javatests/src/org/chromium/chrome/browser/fullscreen/FullscreenManagerTest.java +++ b/chrome/android/javatests/src/org/chromium/chrome/browser/fullscreen/FullscreenManagerTest.java
@@ -83,16 +83,16 @@ Tab tab = getActivity().getActivityTab(); final TabWebContentsDelegateAndroid delegate = tab.getTabWebContentsDelegateAndroid(); - assertTrue(waitForFullscreenFlag(tab, false)); - assertTrue(waitForPersistentFullscreen(delegate, false)); + waitForFullscreenFlag(tab, false); + waitForPersistentFullscreen(delegate, false); togglePersistentFullscreen(delegate, true); - assertTrue(waitForFullscreenFlag(tab, true)); - assertTrue(waitForPersistentFullscreen(delegate, true)); + waitForFullscreenFlag(tab, true); + waitForPersistentFullscreen(delegate, true); togglePersistentFullscreen(delegate, false); - assertTrue(waitForFullscreenFlag(tab, false)); - assertTrue(waitForPersistentFullscreen(delegate, false)); + waitForFullscreenFlag(tab, false); + waitForPersistentFullscreen(delegate, false); } @LargeTest @@ -106,12 +106,12 @@ final Tab tab = getActivity().getActivityTab(); final TabWebContentsDelegateAndroid delegate = tab.getTabWebContentsDelegateAndroid(); - assertTrue(waitForFullscreenFlag(tab, false)); - assertTrue(waitForPersistentFullscreen(delegate, false)); + waitForFullscreenFlag(tab, false); + waitForPersistentFullscreen(delegate, false); togglePersistentFullscreen(delegate, true); - assertTrue(waitForFullscreenFlag(tab, true)); - assertTrue(waitForPersistentFullscreen(delegate, true)); + waitForFullscreenFlag(tab, true); + waitForPersistentFullscreen(delegate, true); // There is a race condition in android when setting various system UI flags. // Adding this wait to allow the animation transitions to complete before continuing @@ -126,8 +126,8 @@ view.getSystemUiVisibility() & ~View.SYSTEM_UI_FLAG_FULLSCREEN); } }); - assertTrue(waitForFullscreenFlag(tab, true)); - assertTrue(waitForPersistentFullscreen(delegate, true)); + waitForFullscreenFlag(tab, true); + waitForPersistentFullscreen(delegate, true); } @LargeTest @@ -206,14 +206,13 @@ // When the top-controls are removed, we need a layout to trigger the // transparent region for the app to be updated. scrollTopControls(false); - boolean layoutOccured = CriteriaHelper.pollForUIThreadCriteria( + CriteriaHelper.pollForUIThreadCriteria( new Criteria() { @Override public boolean isSatisfied() { return layoutCount.get() > 0; } }); - assertTrue(layoutOccured); getInstrumentation().runOnMainSync(new Runnable() { @Override @@ -268,7 +267,7 @@ ChromeFullscreenManager fullscreenManager = getActivity().getFullscreenManager(); fullscreenManager.setAnimationDurationsForTest(1, 1); - assertTrue(waitForNoBrowserTopControlsOffset()); + waitForNoBrowserTopControlsOffset(); assertEquals(fullscreenManager.getControlOffset(), 0f); scrollTopControls(false); @@ -290,7 +289,7 @@ delegate.rendererResponsive(); } }); - assertTrue(waitForNoBrowserTopControlsOffset()); + waitForNoBrowserTopControlsOffset(); } /* @@ -349,7 +348,7 @@ dragStart(dragX, dragStartY, downTime); dragTo(dragX, dragX, dragStartY, dragEndY, 100, downTime); dragEnd(dragX, dragEndY, downTime); - assertTrue(waitForNoBrowserTopControlsOffset()); + waitForNoBrowserTopControlsOffset(); assertEquals(fullscreenManager.getControlOffset(), 0f); Tab tab = getActivity().getActivityTab(); @@ -416,9 +415,9 @@ } } - private boolean waitForFullscreenFlag(final Tab tab, final boolean state) + private void waitForFullscreenFlag(final Tab tab, final boolean state) throws InterruptedException { - return CriteriaHelper.pollForUIThreadCriteria(new Criteria() { + CriteriaHelper.pollForUIThreadCriteria(new Criteria() { @Override public boolean isSatisfied() { return isFullscreenFlagSet(tab, state); @@ -426,9 +425,9 @@ }); } - private boolean waitForPersistentFullscreen(final TabWebContentsDelegateAndroid delegate, + private void waitForPersistentFullscreen(final TabWebContentsDelegateAndroid delegate, final boolean state) throws InterruptedException { - return CriteriaHelper.pollForUIThreadCriteria(new Criteria() { + CriteriaHelper.pollForUIThreadCriteria(new Criteria() { @Override public boolean isSatisfied() { return state == delegate.isFullscreenForTabOrPending(); @@ -453,9 +452,9 @@ }); } - private boolean waitForNoBrowserTopControlsOffset() throws InterruptedException { + private void waitForNoBrowserTopControlsOffset() throws InterruptedException { final ChromeFullscreenManager fullscreenManager = getActivity().getFullscreenManager(); - return CriteriaHelper.pollForUIThreadCriteria(new Criteria() { + CriteriaHelper.pollForUIThreadCriteria(new Criteria() { @Override public boolean isSatisfied() { return !fullscreenManager.hasBrowserControlOffsetOverride(); @@ -463,8 +462,8 @@ }); } - private boolean waitForPageToBeScrollable(final Tab tab) throws InterruptedException { - return CriteriaHelper.pollForUIThreadCriteria(new Criteria() { + private void waitForPageToBeScrollable(final Tab tab) throws InterruptedException { + CriteriaHelper.pollForUIThreadCriteria(new Criteria() { @Override public boolean isSatisfied() { ContentViewCore contentViewCore = tab.getContentViewCore(); @@ -474,8 +473,8 @@ }); } - private boolean waitForEditableNodeToLoseFocus(final Tab tab) throws InterruptedException { - return CriteriaHelper.pollForUIThreadCriteria(new Criteria() { + private void waitForEditableNodeToLoseFocus(final Tab tab) throws InterruptedException { + CriteriaHelper.pollForUIThreadCriteria(new Criteria() { @Override public boolean isSatisfied() { ContentViewCore contentViewCore = tab.getContentViewCore();
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/infobar/InfoBarTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/infobar/InfoBarTest.java index 1fe81c88..86fc188 100644 --- a/chrome/android/javatests/src/org/chromium/chrome/browser/infobar/InfoBarTest.java +++ b/chrome/android/javatests/src/org/chromium/chrome/browser/infobar/InfoBarTest.java
@@ -57,14 +57,14 @@ super.setUp(); // Register for animation notifications - assertTrue(CriteriaHelper.pollForCriteria(new Criteria() { + CriteriaHelper.pollForCriteria(new Criteria() { @Override public boolean isSatisfied() { if (getActivity().getActivityTab() == null) return false; if (getActivity().getActivityTab().getInfoBarContainer() == null) return false; return true; } - })); + }); InfoBarContainer container = getActivity().getActivityTab().getInfoBarContainer(); mListener = new InfoBarTestAnimationListener(); container.setAnimationListener(mListener);
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/infobar/InfoBarTest2.java b/chrome/android/javatests/src/org/chromium/chrome/browser/infobar/InfoBarTest2.java index a73cd0fd..8e3a55c 100644 --- a/chrome/android/javatests/src/org/chromium/chrome/browser/infobar/InfoBarTest2.java +++ b/chrome/android/javatests/src/org/chromium/chrome/browser/infobar/InfoBarTest2.java
@@ -175,7 +175,7 @@ networkPredictionOptions); } }; - }; + } /** * Same as testInfoBarExpiration but with prerender turned-off. @@ -375,14 +375,13 @@ addInfoBarToCurrentTab(infoBar); // A layout must occur to recalculate the transparent region. - boolean layoutOccured = CriteriaHelper.pollForUIThreadCriteria( + CriteriaHelper.pollForUIThreadCriteria( new Criteria() { @Override public boolean isSatisfied() { return layoutCount.get() > 0; } }); - assertTrue(layoutOccured); final Rect fullDisplayFrame = new Rect(); final Rect fullDisplayFrameMinusContainer = new Rect(); @@ -414,14 +413,13 @@ dismissInfoBar(infoBar); // A layout must occur to recalculate the transparent region. - layoutOccured = CriteriaHelper.pollForUIThreadCriteria( + CriteriaHelper.pollForUIThreadCriteria( new Criteria() { @Override public boolean isSatisfied() { return layoutCount.get() > 0; } }); - assertTrue(layoutOccured); getInstrumentation().runOnMainSync(new Runnable() { @Override
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/infobar/PermissionUpdateInfobarTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/infobar/PermissionUpdateInfobarTest.java index 5fb164a..dbc5484d 100644 --- a/chrome/android/javatests/src/org/chromium/chrome/browser/infobar/PermissionUpdateInfobarTest.java +++ b/chrome/android/javatests/src/org/chromium/chrome/browser/infobar/PermissionUpdateInfobarTest.java
@@ -56,14 +56,14 @@ ChromeTabUtils.newTabFromMenu(getInstrumentation(), getActivity()); // Register for animation notifications - assertTrue(CriteriaHelper.pollForCriteria(new Criteria() { + CriteriaHelper.pollForCriteria(new Criteria() { @Override public boolean isSatisfied() { if (getActivity().getActivityTab() == null) return false; if (getActivity().getActivityTab().getInfoBarContainer() == null) return false; return true; } - })); + }); InfoBarContainer container = getActivity().getActivityTab().getInfoBarContainer(); mListener = new InfoBarTestAnimationListener(); container.setAnimationListener(mListener); @@ -114,19 +114,19 @@ assertFalse(webContents.isDestroyed()); ChromeTabUtils.closeCurrentTab(getInstrumentation(), getActivity()); - assertTrue(CriteriaHelper.pollForUIThreadCriteria(new Criteria() { + CriteriaHelper.pollForUIThreadCriteria(new Criteria() { @Override public boolean isSatisfied() { return webContents.isDestroyed(); } - })); + }); - assertTrue(CriteriaHelper.pollForUIThreadCriteria(new Criteria() { + CriteriaHelper.pollForUIThreadCriteria(new Criteria() { @Override public boolean isSatisfied() { return getActivity().getTabModelSelector().getModel(false).getCount() == 1; } - })); + }); } finally { ThreadUtils.runOnUiThreadBlocking(new Runnable() { @Override
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/input/SelectPopupOtherContentViewTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/input/SelectPopupOtherContentViewTest.java index 5bda355d..84682c8f 100644 --- a/chrome/android/javatests/src/org/chromium/chrome/browser/input/SelectPopupOtherContentViewTest.java +++ b/chrome/android/javatests/src/org/chromium/chrome/browser/input/SelectPopupOtherContentViewTest.java
@@ -37,7 +37,11 @@ + "</select>" + "</body></html>"); - private class PopupShowingCriteria implements Criteria { + private class PopupShowingCriteria extends Criteria { + public PopupShowingCriteria() { + super("The select popup did not show up on click."); + } + @Override public boolean isSatisfied() { ContentViewCore contentViewCore = getActivity().getCurrentContentViewCore(); @@ -72,8 +76,7 @@ // Once clicked, the popup should show up. DOMUtils.clickNode(this, viewCore, "select"); - assertTrue("The select popup did not show up on click.", - CriteriaHelper.pollForCriteria(new PopupShowingCriteria())); + CriteriaHelper.pollForCriteria(new PopupShowingCriteria()); // Now create and destroy a different ContentView. ThreadUtils.runOnUiThreadBlocking(new Runnable() {
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/invalidation/ChromeBrowserSyncAdapterTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/invalidation/ChromeBrowserSyncAdapterTest.java index d707bdd..932cb9f 100644 --- a/chrome/android/javatests/src/org/chromium/chrome/browser/invalidation/ChromeBrowserSyncAdapterTest.java +++ b/chrome/android/javatests/src/org/chromium/chrome/browser/invalidation/ChromeBrowserSyncAdapterTest.java
@@ -45,13 +45,13 @@ intent.addCategory(Intent.CATEGORY_HOME); context.startActivity(intent); - assertTrue("Activity should have been sent to background", - CriteriaHelper.pollForCriteria(new Criteria() { - @Override - public boolean isSatisfied() { - return !ApplicationStatus.hasVisibleActivities(); - } - }, WAIT_FOR_LAUNCHER_MS, POLL_INTERVAL_MS)); + CriteriaHelper.pollForCriteria(new Criteria( + "Activity should have been sent to background") { + @Override + public boolean isSatisfied() { + return !ApplicationStatus.hasVisibleActivities(); + } + }, WAIT_FOR_LAUNCHER_MS, POLL_INTERVAL_MS); } private void performSyncWithBundle(Bundle bundle) {
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/invalidation/ChromiumSyncAdapterTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/invalidation/ChromiumSyncAdapterTest.java index 35e5d719..da63fb0 100644 --- a/chrome/android/javatests/src/org/chromium/chrome/browser/invalidation/ChromiumSyncAdapterTest.java +++ b/chrome/android/javatests/src/org/chromium/chrome/browser/invalidation/ChromiumSyncAdapterTest.java
@@ -95,13 +95,12 @@ intent.addCategory(Intent.CATEGORY_HOME); activity.startActivity(intent); - assertTrue( - "Activity should have been resumed", CriteriaHelper.pollForCriteria(new Criteria() { - @Override - public boolean isSatisfied() { - return !isActivityResumed(); - } - }, WAIT_FOR_LAUNCHER_MS, POLL_INTERVAL_MS)); + CriteriaHelper.pollForCriteria(new Criteria("Activity should have been resumed") { + @Override + public boolean isSatisfied() { + return !isActivityResumed(); + } + }, WAIT_FOR_LAUNCHER_MS, POLL_INTERVAL_MS); } private boolean isActivityResumed() {
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/media/ui/PauseOnHeadsetUnplugTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/media/ui/PauseOnHeadsetUnplugTest.java index 5a1c982..944174b 100644 --- a/chrome/android/javatests/src/org/chromium/chrome/browser/media/ui/PauseOnHeadsetUnplugTest.java +++ b/chrome/android/javatests/src/org/chromium/chrome/browser/media/ui/PauseOnHeadsetUnplugTest.java
@@ -41,11 +41,11 @@ assertTrue(DOMUtils.isMediaPaused(tab.getWebContents(), VIDEO_ID)); DOMUtils.playMedia(tab.getWebContents(), VIDEO_ID); - assertTrue(DOMUtils.waitForMediaPlay(tab.getWebContents(), VIDEO_ID)); - assertTrue(waitForNotificationReady()); + DOMUtils.waitForMediaPlay(tab.getWebContents(), VIDEO_ID); + waitForNotificationReady(); simulateHeadsetUnplug(); - assertTrue(DOMUtils.waitForMediaPause(tab.getWebContents(), VIDEO_ID)); + DOMUtils.waitForMediaPause(tab.getWebContents(), VIDEO_ID); } @Override @@ -53,15 +53,14 @@ startMainActivityWithURL(TestHttpServerClient.getUrl(TEST_URL)); } - private boolean waitForNotificationReady() - throws InterruptedException { - return CriteriaHelper.pollForCriteria(new Criteria() { - @Override - public boolean isSatisfied() { - return MediaNotificationManager.hasManagerForTesting( - R.id.media_playback_notification); - } - }); + private void waitForNotificationReady() throws InterruptedException { + CriteriaHelper.pollForCriteria(new Criteria() { + @Override + public boolean isSatisfied() { + return MediaNotificationManager.hasManagerForTesting( + R.id.media_playback_notification); + } + }); } private void simulateHeadsetUnplug() {
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/notifications/NotificationTestBase.java b/chrome/android/javatests/src/org/chromium/chrome/browser/notifications/NotificationTestBase.java index d812ff2..0105338 100644 --- a/chrome/android/javatests/src/org/chromium/chrome/browser/notifications/NotificationTestBase.java +++ b/chrome/android/javatests/src/org/chromium/chrome/browser/notifications/NotificationTestBase.java
@@ -95,7 +95,7 @@ * @return The NotificationEntry object tracked by the MockNotificationManagerProxy. */ protected NotificationEntry waitForNotification() throws Exception { - assertTrue(waitForNotificationManagerMutation()); + waitForNotificationManagerMutation(); List<NotificationEntry> notifications = getNotificationEntries(); assertEquals(1, notifications.size()); return notifications.get(0); @@ -108,11 +108,9 @@ /** * Waits for a mutation to occur in the mocked notification manager. This indicates that Chrome * called into Android to notify or cancel a notification. - * - * @return Whether the wait was successful. */ - protected boolean waitForNotificationManagerMutation() throws Exception { - return CriteriaHelper.pollForUIThreadCriteria(new Criteria() { + protected void waitForNotificationManagerMutation() throws Exception { + CriteriaHelper.pollForUIThreadCriteria(new Criteria() { @Override public boolean isSatisfied() { return mMockNotificationManager.getMutationCountAndDecrement() > 0;
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/notifications/NotificationUIManagerTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/notifications/NotificationUIManagerTest.java index 397d1dc..d134f2d 100644 --- a/chrome/android/javatests/src/org/chromium/chrome/browser/notifications/NotificationUIManagerTest.java +++ b/chrome/android/javatests/src/org/chromium/chrome/browser/notifications/NotificationUIManagerTest.java
@@ -212,7 +212,7 @@ // The Service Worker will close the notification upon receiving the notificationclick // event. This will eventually bubble up to a call to cancel() in the NotificationManager. - assertTrue(waitForNotificationManagerMutation()); + waitForNotificationManagerMutation(); assertTrue(getNotificationEntries().isEmpty()); } @@ -228,13 +228,13 @@ setNotificationContentSettingForCurrentOrigin(ContentSetting.ALLOW); runJavaScriptCodeInCurrentTab("showNotification('MyNotification', {tag: 'myTag'});"); - assertTrue(waitForNotificationManagerMutation()); + waitForNotificationManagerMutation(); List<NotificationEntry> notifications = getNotificationEntries(); String tag = notifications.get(0).tag; int id = notifications.get(0).id; runJavaScriptCodeInCurrentTab("showNotification('SecondNotification', {tag: 'myTag'});"); - assertTrue(waitForNotificationManagerMutation()); + waitForNotificationManagerMutation(); // Verify that the notification was successfully replaced. notifications = getNotificationEntries(); @@ -262,7 +262,7 @@ // Open the first notification and verify it is displayed. runJavaScriptCodeInCurrentTab("showNotification('One');"); - assertTrue(waitForNotificationManagerMutation()); + waitForNotificationManagerMutation(); List<NotificationEntry> notifications = getNotificationEntries(); assertEquals(1, notifications.size()); Notification notificationOne = notifications.get(0).notification; @@ -270,7 +270,7 @@ // Open the second notification and verify it is displayed. runJavaScriptCodeInCurrentTab("showNotification('Two');"); - assertTrue(waitForNotificationManagerMutation()); + waitForNotificationManagerMutation(); notifications = getNotificationEntries(); assertEquals(2, notifications.size()); Notification notificationTwo = notifications.get(1).notification; @@ -294,7 +294,7 @@ // notificationclick event is fired. The test service worker will close the notification // upon receiving the event. notificationOne.contentIntent.send(); - assertTrue(waitForNotificationManagerMutation()); + waitForNotificationManagerMutation(); notifications = getNotificationEntries(); assertEquals(1, notifications.size()); assertEquals("Two", @@ -302,7 +302,7 @@ // Close the last notification and verify that none remain. notifications.get(0).notification.contentIntent.send(); - assertTrue(waitForNotificationManagerMutation()); + waitForNotificationManagerMutation(); assertTrue(getNotificationEntries().isEmpty()); }
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/ntp/DocumentModeRecentlyClosedTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/ntp/DocumentModeRecentlyClosedTest.java index 5741dbb6..e7111cd7 100644 --- a/chrome/android/javatests/src/org/chromium/chrome/browser/ntp/DocumentModeRecentlyClosedTest.java +++ b/chrome/android/javatests/src/org/chromium/chrome/browser/ntp/DocumentModeRecentlyClosedTest.java
@@ -106,21 +106,21 @@ // DocumentTabModel update. activityDelegate.mExtraRegularTask = null; ApplicationTestUtils.launchChrome(mContext); - assertTrue(CriteriaHelper.pollForCriteria(new Criteria() { + CriteriaHelper.pollForCriteria(new Criteria() { @Override public boolean isSatisfied() { Activity lastActivity = ApplicationStatus.getLastTrackedFocusedActivity(); return lastActivity instanceof DocumentActivity; } - })); + }); // Wait until the DocumentTabModel updates and shows a single tab. - assertTrue(CriteriaHelper.pollForCriteria(new Criteria() { + CriteriaHelper.pollForCriteria(new Criteria() { @Override public boolean isSatisfied() { return selector.getTotalTabCount() == 1; } - })); + }); // Check recently closed, make sure it shows one open and one closed tab. DocumentActivity activity = @@ -165,12 +165,12 @@ selector.getModel(false).closeTabAt(0); } }); - assertTrue(CriteriaHelper.pollForUIThreadCriteria(new Criteria() { + CriteriaHelper.pollForUIThreadCriteria(new Criteria() { @Override public boolean isSatisfied() { return selector.getTotalTabCount() == 2; } - })); + }); // Check that the right things appear in Recent Tabs. List<CurrentlyOpenTab> afterOpenTabs = recentTabsManager.getCurrentlyOpenTabs(); @@ -239,12 +239,12 @@ ActivityDelegate delegate = new ActivityDelegateImpl(DocumentActivity.class, IncognitoDocumentActivity.class); delegate.finishAndRemoveTask(false, tabIds[0]); - assertTrue(CriteriaHelper.pollForCriteria(new Criteria() { + CriteriaHelper.pollForCriteria(new Criteria() { @Override public boolean isSatisfied() { return selector.getTotalTabCount() == 2; } - })); + }); // Check that the Tab shows up under Recently closed. final DocumentRecentTabsManager recentTabsManager = getRecentTabsManager(thirdActivity);
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/ntp/FakeMostVisitedSites.java b/chrome/android/javatests/src/org/chromium/chrome/browser/ntp/FakeMostVisitedSites.java index d97a21e..3b2da986d 100644 --- a/chrome/android/javatests/src/org/chromium/chrome/browser/ntp/FakeMostVisitedSites.java +++ b/chrome/android/javatests/src/org/chromium/chrome/browser/ntp/FakeMostVisitedSites.java
@@ -67,7 +67,7 @@ } @Override - public void recordTileTypeMetrics(int[] tileTypes, boolean isIconMode) { + public void recordTileTypeMetrics(int[] tileTypes) { // Metrics are stubbed out. }
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/ntp/NewTabPageTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/ntp/NewTabPageTest.java index 248f646e..abce9bdf4 100644 --- a/chrome/android/javatests/src/org/chromium/chrome/browser/ntp/NewTabPageTest.java +++ b/chrome/android/javatests/src/org/chromium/chrome/browser/ntp/NewTabPageTest.java
@@ -98,13 +98,13 @@ singleClickView(mFakebox); waitForFakeboxFocusAnimationComplete(mNtp); UrlBar urlBar = (UrlBar) getActivity().findViewById(R.id.url_bar); - assertTrue(OmniboxTestUtils.waitForFocusAndKeyboardActive(urlBar, true)); + OmniboxTestUtils.waitForFocusAndKeyboardActive(urlBar, true); int afterFocusFakeboxTop = getFakeboxTop(mNtp); assertTrue(afterFocusFakeboxTop < initialFakeboxTop); OmniboxTestUtils.toggleUrlBarFocus(urlBar, false); waitForFakeboxTopPosition(mNtp, initialFakeboxTop); - assertTrue(OmniboxTestUtils.waitForFocusAndKeyboardActive(urlBar, false)); + OmniboxTestUtils.waitForFocusAndKeyboardActive(urlBar, false); } /** @@ -117,7 +117,7 @@ singleClickView(mFakebox); waitForFakeboxFocusAnimationComplete(mNtp); final UrlBar urlBar = (UrlBar) getActivity().findViewById(R.id.url_bar); - assertTrue(OmniboxTestUtils.waitForFocusAndKeyboardActive(urlBar, true)); + OmniboxTestUtils.waitForFocusAndKeyboardActive(urlBar, true); getInstrumentation().sendStringSync(TEST_PAGE); LocationBarLayout locationBar = @@ -253,8 +253,8 @@ final View v = urlBar; KeyUtils.singleKeyEventView(getInstrumentation(), v, KeyEvent.KEYCODE_ENTER); - assertTrue(waitForUrlFocusAnimationsDisabledState(true)); - assertTrue(waitForTabLoading()); + waitForUrlFocusAnimationsDisabledState(true); + waitForTabLoading(); ThreadUtils.runOnUiThreadBlocking(new Runnable() { @Override @@ -262,7 +262,7 @@ mTab.stopLoading(); } }); - assertTrue(waitForUrlFocusAnimationsDisabledState(false)); + waitForUrlFocusAnimationsDisabledState(false); delaySemaphore.release(); loadedCallback.waitForCallback(0); assertFalse(getUrlFocusAnimatonsDisabled()); @@ -280,9 +280,9 @@ }); } - private boolean waitForUrlFocusAnimationsDisabledState(final boolean disabled) + private void waitForUrlFocusAnimationsDisabledState(final boolean disabled) throws InterruptedException { - return CriteriaHelper.pollForCriteria(new Criteria() { + CriteriaHelper.pollForCriteria(new Criteria() { @Override public boolean isSatisfied() { return getUrlFocusAnimatonsDisabled() == disabled; @@ -290,8 +290,8 @@ }); } - private boolean waitForTabLoading() throws InterruptedException { - return CriteriaHelper.pollForUIThreadCriteria(new Criteria() { + private void waitForTabLoading() throws InterruptedException { + CriteriaHelper.pollForUIThreadCriteria(new Criteria() { @Override public boolean isSatisfied() { return mTab.isLoading(); @@ -303,19 +303,14 @@ waitForUrlFocusPercent(ntp, 1f); } - private void waitForFakeboxUnfocusAnimationComplete(NewTabPage ntp) - throws InterruptedException { - waitForUrlFocusPercent(ntp, 0f); - } - private void waitForUrlFocusPercent(final NewTabPage ntp, final float percent) throws InterruptedException { - assertTrue(CriteriaHelper.pollForUIThreadCriteria(new Criteria() { + CriteriaHelper.pollForUIThreadCriteria(new Criteria() { @Override public boolean isSatisfied() { return ntp.getNewTabPageView().getUrlFocusChangeAnimationPercent() == percent; } - })); + }); } private void clickFakebox() { @@ -343,11 +338,11 @@ */ private void waitForFakeboxTopPosition(final NewTabPage ntp, final int position) throws InterruptedException { - assertTrue(CriteriaHelper.pollForUIThreadCriteria(new Criteria() { + CriteriaHelper.pollForUIThreadCriteria(new Criteria() { @Override public boolean isSatisfied() { return getFakeboxTop(ntp) == position; } - })); + }); } }
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 f3580fd..357a47d 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
@@ -183,14 +183,14 @@ mOfflinePageBridge.markPageAccessed(bookmarkId); } }); - assertTrue(CriteriaHelper.pollForUIThreadCriteria(new Criteria() { + CriteriaHelper.pollForUIThreadCriteria(new Criteria() { @Override public boolean isSatisfied() { OfflinePageItem offlinePage = mOfflinePageBridge.getPageByBookmarkId(bookmarkId); return offlinePage.getAccessCount() == expectedAccessCount; } - })); + }); } private void deletePage(BookmarkId bookmarkId, final int expectedResult)
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/omaha/OmahaUpdateInfoBarTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/omaha/OmahaUpdateInfoBarTest.java index 95e3385..8cf0327 100644 --- a/chrome/android/javatests/src/org/chromium/chrome/browser/omaha/OmahaUpdateInfoBarTest.java +++ b/chrome/android/javatests/src/org/chromium/chrome/browser/omaha/OmahaUpdateInfoBarTest.java
@@ -127,12 +127,12 @@ startMainActivityWithURL(url); // Check to make sure that the version numbers get queried. - assertTrue("Main didn't ask Omaha for version numbers.", versionNumbersQueried()); + waitForVersionNumbersQueried(); } - private boolean versionNumbersQueried() throws Exception { - return CriteriaHelper.pollForCriteria( - new Criteria() { + private void waitForVersionNumbersQueried() throws Exception { + CriteriaHelper.pollForCriteria( + new Criteria("Main didn't ask Omaha for version numbers.") { @Override public boolean isSatisfied() { return mMockVersionNumberGetter.askedForCurrentVersion() @@ -169,8 +169,8 @@ /** * Waits until the NavigateToURLInfoBar appears for the current tab. */ - private boolean correctInfoBarAdded() throws Exception { - return CriteriaHelper.pollForCriteria( + private void correctInfoBarAdded() throws Exception { + CriteriaHelper.pollForCriteria( new Criteria() { @Override public boolean isSatisfied() { @@ -184,8 +184,8 @@ /** * Waits until the NavigateToURLInfoBar goes away. */ - private boolean correctInfoBarRemoved() throws Exception { - return CriteriaHelper.pollForCriteria( + private void correctInfoBarRemoved() throws Exception { + CriteriaHelper.pollForCriteria( new Criteria() { @Override public boolean isSatisfied() { @@ -205,23 +205,32 @@ if (url == null) { // The InfoBar shouldn't be created yet because we're on the NTP. - assertFalse("InfoBar shown on NTP.", correctInfoBarAdded()); + try { + correctInfoBarAdded(); + fail("Infobar should not have been added"); + } catch (AssertionError e) { + // TODO(tedchoc): This is horrible and should never timeout to determine success. + } // Navigate somewhere else and then check for the InfoBar. loadUrl(UrlUtils.getIsolatedTestFileUrl(HTML_FILENAME_1)); - assertTrue("InfoBar failed to show after navigating from NTP.", - correctInfoBarAdded()); + correctInfoBarAdded(); } else { // The InfoBar be shown ASAP since we're not on the NTP. - assertTrue("InfoBar failed to show.", correctInfoBarAdded()); + correctInfoBarAdded(); } // Make sure the InfoBar doesn't disappear immediately. - assertFalse("InfoBar was removed too quickly.", correctInfoBarRemoved()); + try { + correctInfoBarRemoved(); + fail("InfoBar was removed too quickly."); + } catch (AssertionError e) { + // TODO(tedchoc): This is horrible and should never timeout to determine success. + } // Make sure the InfoBar goes away once we navigate somewhere else on the same tab. loadUrl(UrlUtils.getIsolatedTestFileUrl(HTML_FILENAME_2)); - assertTrue("InfoBar is still showing", correctInfoBarRemoved()); + correctInfoBarRemoved(); } /** @@ -231,9 +240,19 @@ private void checkInfobarDoesNotAppear(String currentVersion, String latestVersion, String url) throws Exception { prepareAndStartMainActivity(currentVersion, latestVersion, url); - assertFalse("Infobar is showing.", correctInfoBarAdded()); + try { + correctInfoBarAdded(); + fail("Infobar is showing."); + } catch (AssertionError e) { + // TODO(tedchoc): This is horrible and should never timeout to determine success. + } loadUrl(UrlUtils.getIsolatedTestFileUrl(HTML_FILENAME_2)); - assertFalse("Infobar is now showing", correctInfoBarAdded()); + try { + correctInfoBarAdded(); + fail("Infobar is now showing"); + } catch (AssertionError e) { + // TODO(tedchoc): This is horrible and should never timeout to determine success. + } } @MediumTest
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/omnibox/OmniboxTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/omnibox/OmniboxTest.java index be88d60..222c248c 100644 --- a/chrome/android/javatests/src/org/chromium/chrome/browser/omnibox/OmniboxTest.java +++ b/chrome/android/javatests/src/org/chromium/chrome/browser/omnibox/OmniboxTest.java
@@ -102,24 +102,22 @@ final UrlBar urlBar = (UrlBar) getActivity().findViewById(R.id.url_bar); OmniboxTestUtils.toggleUrlBarFocus(urlBar, true); - assertTrue("Soft input mode failed to switch on focus", - CriteriaHelper.pollForCriteria(new Criteria() { - @Override - public boolean isSatisfied() { - return getActivity().getWindow().getAttributes().softInputMode - == WindowManager.LayoutParams.SOFT_INPUT_ADJUST_PAN; - } - })); + CriteriaHelper.pollForCriteria(new Criteria("Soft input mode failed to switch on focus") { + @Override + public boolean isSatisfied() { + return getActivity().getWindow().getAttributes().softInputMode + == WindowManager.LayoutParams.SOFT_INPUT_ADJUST_PAN; + } + }); OmniboxTestUtils.toggleUrlBarFocus(urlBar, false); - assertTrue("Soft input mode failed to switch on unfocus", - CriteriaHelper.pollForCriteria(new Criteria() { - @Override - public boolean isSatisfied() { - return getActivity().getWindow().getAttributes().softInputMode - == WindowManager.LayoutParams.SOFT_INPUT_ADJUST_RESIZE; - } - })); + CriteriaHelper.pollForCriteria(new Criteria("Soft input mode failed to switch on unfocus") { + @Override + public boolean isSatisfied() { + return getActivity().getWindow().getAttributes().softInputMode + == WindowManager.LayoutParams.SOFT_INPUT_ADJUST_RESIZE; + } + }); } /** @@ -146,13 +144,13 @@ OmniboxTestUtils.toggleUrlBarFocus(urlBar, true); - assertTrue("Should have requested zero suggest on focusing", - CriteriaHelper.pollForCriteria(new Criteria() { - @Override - public boolean isSatisfied() { - return controller.numZeroSuggestRequests() == 1; - } - })); + CriteriaHelper.pollForCriteria(new Criteria( + "Should have requested zero suggest on focusing") { + @Override + public boolean isSatisfied() { + return controller.numZeroSuggestRequests() == 1; + } + }); } /** @@ -188,13 +186,12 @@ } }); - assertTrue("Should have drawn the delete button", - CriteriaHelper.pollForCriteria(new Criteria() { - @Override - public boolean isSatisfied() { - return deleteButton.getWidth() > 0; - } - })); + CriteriaHelper.pollForCriteria(new Criteria("Should have drawn the delete button") { + @Override + public boolean isSatisfied() { + return deleteButton.getWidth() > 0; + } + }); // The click view below ends up clicking on the menu button underneath the delete button // for some time after the delete button appears. Wait for UI to settle down before @@ -203,13 +200,13 @@ singleClickView(deleteButton); - assertTrue("Should have requested zero suggest results on url bar empty", - CriteriaHelper.pollForCriteria(new Criteria() { - @Override - public boolean isSatisfied() { - return controller.numZeroSuggestRequests() == 1; - } - })); + CriteriaHelper.pollForCriteria(new Criteria( + "Should have requested zero suggest results on url bar empty") { + @Override + public boolean isSatisfied() { + return controller.numZeroSuggestRequests() == 1; + } + }); } @MediumTest @@ -244,13 +241,13 @@ assertEquals("No calls to zero suggest yet", 0, controller.numZeroSuggestRequests()); KeyUtils.singleKeyEventView(getInstrumentation(), urlBar, KeyEvent.KEYCODE_DEL); - assertTrue("Should have requested zero suggest results on url bar empty", - CriteriaHelper.pollForCriteria(new Criteria() { - @Override - public boolean isSatisfied() { - return controller.numZeroSuggestRequests() == 1; - } - })); + CriteriaHelper.pollForCriteria(new Criteria( + "Should have requested zero suggest results on url bar empty") { + @Override + public boolean isSatisfied() { + return controller.numZeroSuggestRequests() == 1; + } + }); } // Sanity check that no text is displayed in the omnibox when on the NTP page and that the hint @@ -740,8 +737,7 @@ private void verifyOmniboxSuggestionAlignment( final LocationBarLayout locationBar, final int expectedSuggestionCount, final int expectedLayoutDirection) throws InterruptedException { - assertTrue(OmniboxTestUtils.waitForOmniboxSuggestions( - locationBar, expectedSuggestionCount)); + OmniboxTestUtils.waitForOmniboxSuggestions(locationBar, expectedSuggestionCount); ThreadUtils.runOnUiThreadBlocking(new Runnable() { @Override public void run() {
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/omnibox/UrlBarTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/omnibox/UrlBarTest.java index f4c5de5..fa733fc 100644 --- a/chrome/android/javatests/src/org/chromium/chrome/browser/omnibox/UrlBarTest.java +++ b/chrome/android/javatests/src/org/chromium/chrome/browser/omnibox/UrlBarTest.java
@@ -544,7 +544,7 @@ UrlBar urlBar = getUrlBar(); assertNotNull(urlBar); OmniboxTestUtils.toggleUrlBarFocus(urlBar, true); - assertTrue(OmniboxTestUtils.waitForFocusAndKeyboardActive(urlBar, true)); + OmniboxTestUtils.waitForFocusAndKeyboardActive(urlBar, true); } @SmallTest
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/partnercustomizations/PartnerDisableIncognitoModeIntegrationTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/partnercustomizations/PartnerDisableIncognitoModeIntegrationTest.java index ff00a9d..2e8fb3c 100644 --- a/chrome/android/javatests/src/org/chromium/chrome/browser/partnercustomizations/PartnerDisableIncognitoModeIntegrationTest.java +++ b/chrome/android/javatests/src/org/chromium/chrome/browser/partnercustomizations/PartnerDisableIncognitoModeIntegrationTest.java
@@ -73,9 +73,9 @@ } } - private boolean waitForParentalControlsEnabledState(final boolean parentalControlsEnabled) + private void waitForParentalControlsEnabledState(final boolean parentalControlsEnabled) throws InterruptedException { - return CriteriaHelper.pollForUIThreadCriteria(new Criteria() { + CriteriaHelper.pollForUIThreadCriteria(new Criteria() { @Override public boolean isSatisfied() { // areParentalControlsEnabled is updated on a background thread, so we @@ -122,7 +122,7 @@ public void testIncognitoEnabledIfNoParentalControls() throws InterruptedException { setParentalControlsEnabled(false); startMainActivityOnBlankPage(); - assertTrue(waitForParentalControlsEnabledState(false)); + waitForParentalControlsEnabledState(false); newIncognitoTabFromMenu(); } @@ -132,12 +132,12 @@ throws InterruptedException, ExecutionException { setParentalControlsEnabled(true); startMainActivityOnBlankPage(); - assertTrue(waitForParentalControlsEnabledState(true)); + waitForParentalControlsEnabledState(true); assertIncognitoMenuItemEnabled(false); setParentalControlsEnabled(false); toggleActivityForegroundState(); - assertTrue(waitForParentalControlsEnabledState(false)); + waitForParentalControlsEnabledState(false); assertIncognitoMenuItemEnabled(true); } @@ -146,7 +146,7 @@ public void testEnabledParentalControlsClosesIncognitoTabs() throws InterruptedException { setParentalControlsEnabled(false); startMainActivityOnBlankPage(); - assertTrue(waitForParentalControlsEnabledState(false)); + waitForParentalControlsEnabledState(false); loadUrlInNewTab(TEST_URLS[0], true); loadUrlInNewTab(TEST_URLS[1], true); @@ -155,14 +155,13 @@ setParentalControlsEnabled(true); toggleActivityForegroundState(); - assertTrue(waitForParentalControlsEnabledState(true)); + waitForParentalControlsEnabledState(true); - assertTrue("Incognito tabs did not close as expected", - CriteriaHelper.pollForCriteria(new Criteria() { - @Override - public boolean isSatisfied() { - return incognitoTabsCount() == 0; - } - })); + CriteriaHelper.pollForCriteria(new Criteria("Incognito tabs did not close as expected") { + @Override + public boolean isSatisfied() { + return incognitoTabsCount() == 0; + } + }); } }
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/partnercustomizations/PartnerHomepageIntegrationTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/partnercustomizations/PartnerHomepageIntegrationTest.java index 4ea31a8..d0da38e 100644 --- a/chrome/android/javatests/src/org/chromium/chrome/browser/partnercustomizations/PartnerHomepageIntegrationTest.java +++ b/chrome/android/javatests/src/org/chromium/chrome/browser/partnercustomizations/PartnerHomepageIntegrationTest.java
@@ -11,7 +11,6 @@ import android.test.suitebuilder.annotation.MediumTest; import android.view.View; import android.widget.Button; -import android.widget.Checkable; import android.widget.EditText; import org.chromium.base.ThreadUtils; @@ -111,7 +110,7 @@ (SwitchCompat) homepagePreferenceActivity.findViewById(R.id.switch_widget); assertNotNull(homepageSwitch); TouchCommon.singleClickView(homepageSwitch); - waitForCheckedState(homepageSwitch, false); + waitForCheckedState(homepagePreferenceActivity, false); homepagePreferenceActivity.finish(); // Assert no homepage button. @@ -129,7 +128,7 @@ homepageSwitch = (SwitchCompat) homepagePreferenceActivity.findViewById(R.id.switch_widget); assertNotNull(homepageSwitch); TouchCommon.singleClickView(homepageSwitch); - waitForCheckedState(homepageSwitch, true); + waitForCheckedState(homepagePreferenceActivity, true); homepagePreferenceActivity.finish(); // Assert homepage button. @@ -143,12 +142,16 @@ }); } - private boolean waitForCheckedState(final Checkable view, final boolean isChecked) + private void waitForCheckedState(final Preferences preferenceActivity, final boolean isChecked) throws InterruptedException { - return CriteriaHelper.pollForUIThreadCriteria(new Criteria() { + CriteriaHelper.pollForUIThreadCriteria(new Criteria() { @Override public boolean isSatisfied() { - return view.isChecked() == isChecked; + // The underlying switch view in the preference can change, so we need to fetch + // it each time to ensure we are checking the activity view. + SwitchCompat homepageSwitch = + (SwitchCompat) preferenceActivity.findViewById(R.id.switch_widget); + return homepageSwitch.isChecked() == isChecked; } }); }
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/preferences/privacy/ClearBrowsingDataDialogFragmentTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/preferences/privacy/ClearBrowsingDataDialogFragmentTest.java index 3ea1a98..0a85e4f 100644 --- a/chrome/android/javatests/src/org/chromium/chrome/browser/preferences/privacy/ClearBrowsingDataDialogFragmentTest.java +++ b/chrome/android/javatests/src/org/chromium/chrome/browser/preferences/privacy/ClearBrowsingDataDialogFragmentTest.java
@@ -52,12 +52,12 @@ mCallbackCalled = true; } }); - assertTrue(CriteriaHelper.pollForUIThreadCriteria(new Criteria() { + CriteriaHelper.pollForUIThreadCriteria(new Criteria() { @Override public boolean isSatisfied() { return mCallbackCalled; } - })); + }); mCallbackCalled = false; ThreadUtils.runOnUiThreadBlocking(new Runnable() { @@ -67,12 +67,12 @@ ClearBrowsingDataDialogFragment.FRAGMENT_TAG); } }); - assertTrue(CriteriaHelper.pollForUIThreadCriteria(new Criteria() { + CriteriaHelper.pollForUIThreadCriteria(new Criteria() { @Override public boolean isSatisfied() { return mFragment.getDialog() != null; } - })); + }); ThreadUtils.runOnUiThreadBlocking(new Runnable() { @Override @@ -82,12 +82,12 @@ clearButton.performClick(); } }); - assertTrue(CriteriaHelper.pollForUIThreadCriteria(new Criteria() { + CriteriaHelper.pollForUIThreadCriteria(new Criteria() { @Override public boolean isSatisfied() { return mFragment.getProgressDialog() == null; } - })); + }); WebappRegistry.getRegisteredWebappIds(getActivity(), new WebappRegistry.FetchCallback() { @Override @@ -96,12 +96,12 @@ mCallbackCalled = true; } }); - assertTrue(CriteriaHelper.pollForUIThreadCriteria(new Criteria() { + CriteriaHelper.pollForUIThreadCriteria(new Criteria() { @Override public boolean isSatisfied() { return mCallbackCalled; } - })); + }); } private static class TestClearDataDialogFragment extends ClearBrowsingDataDialogFragment {
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/prerender/PrerenderServiceTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/prerender/PrerenderServiceTest.java index b69e555..63096878 100644 --- a/chrome/android/javatests/src/org/chromium/chrome/browser/prerender/PrerenderServiceTest.java +++ b/chrome/android/javatests/src/org/chromium/chrome/browser/prerender/PrerenderServiceTest.java
@@ -146,15 +146,16 @@ } }); // TODO(yusufo): We should be using the NotificationCenter for checking the page loading. - assertTrue(CriteriaHelper.pollForCriteria(new Criteria() { + CriteriaHelper.pollForCriteria(new Criteria() { @Override public boolean isSatisfied() { return chromeActivity.getActivityTab() != null && chromeActivity.getActivityTab().isLoadingAndRenderingDone(); } - })); + }); assertTrue(chromeActivity.getActivityTab().getUrl().equals(url)); - ThreadUtils.runOnUiThreadBlocking(new Runnable(){ + ThreadUtils.runOnUiThreadBlocking(new Runnable() { + @Override public void run() { assertFalse(WarmupManager.getInstance().hasAnyPrerenderedUrl()); } @@ -162,11 +163,11 @@ } private void assertServiceHasPrerenderedUrl(final String url) throws InterruptedException { - assertTrue(CriteriaHelper.pollForUIThreadCriteria(new Criteria() { + CriteriaHelper.pollForUIThreadCriteria(new Criteria() { @Override public boolean isSatisfied() { return WarmupManager.getInstance().hasPrerenderedUrl(url); } - })); + }); } }
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/search_engines/TemplateUrlServiceTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/search_engines/TemplateUrlServiceTest.java index 9037daa..1aa9e85a 100644 --- a/chrome/android/javatests/src/org/chromium/chrome/browser/search_engines/TemplateUrlServiceTest.java +++ b/chrome/android/javatests/src/org/chromium/chrome/browser/search_engines/TemplateUrlServiceTest.java
@@ -160,13 +160,13 @@ } }); - assertTrue("Observer wasn't notified of TemplateUrlService load.", - CriteriaHelper.pollForCriteria(new Criteria() { - @Override - public boolean isSatisfied() { - return observerNotified.get(); - } - })); + CriteriaHelper.pollForCriteria(new Criteria( + "Observer wasn't notified of TemplateUrlService load.") { + @Override + public boolean isSatisfied() { + return observerNotified.get(); + } + }); return templateUrlService; } }
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/tab/InterceptNavigationDelegateTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/tab/InterceptNavigationDelegateTest.java index f01645b..2b6e9b3 100644 --- a/chrome/android/javatests/src/org/chromium/chrome/browser/tab/InterceptNavigationDelegateTest.java +++ b/chrome/android/javatests/src/org/chromium/chrome/browser/tab/InterceptNavigationDelegateTest.java
@@ -66,9 +66,9 @@ } private void waitTillExpectedCallsComplete(final int count, long timeout) { - boolean result = false; try { - result = CriteriaHelper.pollForCriteria(new Criteria() { + CriteriaHelper.pollForCriteria(new Criteria( + "Failed while waiting for all calls to complete.") { @Override public boolean isSatisfied() { return mHistory.size() == count; @@ -77,7 +77,6 @@ } catch (InterruptedException e) { fail("Failed while waiting for all calls to complete." + e); } - assertTrue("Failed while waiting for all calls to complete.", result); } @Override
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/tabmodel/document/AsyncDocumentLauncherTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/tabmodel/document/AsyncDocumentLauncherTest.java index 2b6b699..8326836 100644 --- a/chrome/android/javatests/src/org/chromium/chrome/browser/tabmodel/document/AsyncDocumentLauncherTest.java +++ b/chrome/android/javatests/src/org/chromium/chrome/browser/tabmodel/document/AsyncDocumentLauncherTest.java
@@ -40,7 +40,7 @@ AsyncDocumentLauncher.getInstance().enqueueLaunch(false, Tab.INVALID_TAB_ID, secondParams); AsyncDocumentLauncher.getInstance().enqueueLaunch(false, Tab.INVALID_TAB_ID, finalParams); - assertTrue(CriteriaHelper.pollForCriteria(new Criteria() { + CriteriaHelper.pollForCriteria(new Criteria() { @Override public boolean isSatisfied() { Activity lastActivity = ApplicationStatus.getLastTrackedFocusedActivity(); @@ -51,7 +51,7 @@ return TextUtils.equals(URL_3, documentActivity.getActivityTab().getUrl()); } - })); + }); TabModelSelector selector = ChromeApplication.getDocumentTabModelSelector(); assertEquals(3, selector.getTotalTabCount()); @@ -74,7 +74,7 @@ AsyncDocumentLauncher.getInstance().enqueueLaunch(false, parentId, secondParams); AsyncDocumentLauncher.getInstance().enqueueLaunch(false, parentId, finalParams); - assertTrue(CriteriaHelper.pollForCriteria(new Criteria() { + CriteriaHelper.pollForCriteria(new Criteria() { @Override public boolean isSatisfied() { Activity lastActivity = ApplicationStatus.getLastTrackedFocusedActivity(); @@ -85,7 +85,7 @@ return TextUtils.equals(URL_4, documentActivity.getActivityTab().getUrl()); } - })); + }); TabModelSelector selector = ChromeApplication.getDocumentTabModelSelector(); assertEquals(4, selector.getTotalTabCount()); @@ -116,7 +116,7 @@ AsyncDocumentLauncher.getInstance().enqueueLaunch(false, parentId, secondParams); AsyncDocumentLauncher.getInstance().enqueueLaunch(false, Tab.INVALID_TAB_ID, finalParams); - assertTrue(CriteriaHelper.pollForCriteria(new Criteria() { + CriteriaHelper.pollForCriteria(new Criteria() { @Override public boolean isSatisfied() { Activity lastActivity = ApplicationStatus.getLastTrackedFocusedActivity(); @@ -127,7 +127,7 @@ return TextUtils.equals(URL_4, documentActivity.getActivityTab().getUrl()); } - })); + }); TabModelSelector selector = ChromeApplication.getDocumentTabModelSelector(); assertEquals(3, selector.getTotalTabCount());
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/toolbar/BrandColorTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/toolbar/BrandColorTest.java index cbce4f5..84341a0 100644 --- a/chrome/android/javatests/src/org/chromium/chrome/browser/toolbar/BrandColorTest.java +++ b/chrome/android/javatests/src/org/chromium/chrome/browser/toolbar/BrandColorTest.java
@@ -64,35 +64,35 @@ @TargetApi(Build.VERSION_CODES.LOLLIPOP) private void checkForBrandColor(final int brandColor) { try { - assertTrue("The toolbar background doesn't contain the right color", - CriteriaHelper.pollForUIThreadCriteria(new Criteria() { - @Override - public boolean isSatisfied() { - if (mToolbarDataProvider.getPrimaryColor() != brandColor) return false; - return mToolbarDataProvider.getPrimaryColor() - == mToolbar.getBackgroundDrawable().getColor(); - } - })); - assertTrue("The overlay drawable doesn't contain the right color", - CriteriaHelper.pollForUIThreadCriteria(new Criteria() { - @Override - public boolean isSatisfied() { - return mToolbar.getOverlayDrawable().getColor() == brandColor; - } - })); + CriteriaHelper.pollForUIThreadCriteria(new Criteria( + "The toolbar background doesn't contain the right color") { + @Override + public boolean isSatisfied() { + if (mToolbarDataProvider.getPrimaryColor() != brandColor) return false; + return mToolbarDataProvider.getPrimaryColor() + == mToolbar.getBackgroundDrawable().getColor(); + } + }); + CriteriaHelper.pollForUIThreadCriteria(new Criteria( + "The overlay drawable doesn't contain the right color") { + @Override + public boolean isSatisfied() { + return mToolbar.getOverlayDrawable().getColor() == brandColor; + } + }); if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP && !SysUtils.isLowEndDevice()) { final int expectedStatusBarColor = brandColor == mDefaultColor ? Color.BLACK : ColorUtils.getDarkenedColorForStatusBar(brandColor); - assertTrue("The status bar is not set to the right color", - CriteriaHelper.pollForUIThreadCriteria(new Criteria() { - @Override - public boolean isSatisfied() { - return expectedStatusBarColor - == getActivity().getWindow().getStatusBarColor(); - } - })); + CriteriaHelper.pollForUIThreadCriteria(new Criteria( + "The status bar is not set to the right color") { + @Override + public boolean isSatisfied() { + return expectedStatusBarColor + == getActivity().getWindow().getStatusBarColor(); + } + }); } } catch (InterruptedException e) { @@ -215,12 +215,12 @@ brandColorUrl, delegate.getNative()); } }); - assertTrue(CriteriaHelper.pollForUIThreadCriteria(new Criteria() { + CriteriaHelper.pollForUIThreadCriteria(new Criteria() { @Override public boolean isSatisfied() { return getActivity().getActivityTab().isShowingInterstitialPage(); } - })); + }); checkForBrandColor(ApiCompatibilityUtils.getColor( getActivity().getResources(), R.color.default_primary_color)); }
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/toolbar/ToolbarTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/toolbar/ToolbarTest.java index 2569edd..4950e795 100644 --- a/chrome/android/javatests/src/org/chromium/chrome/browser/toolbar/ToolbarTest.java +++ b/chrome/android/javatests/src/org/chromium/chrome/browser/toolbar/ToolbarTest.java
@@ -42,7 +42,7 @@ } private void waitForFindInPageVisibility(final boolean visible) throws InterruptedException { - assertTrue(CriteriaHelper.pollForUIThreadCriteria(new Criteria() { + CriteriaHelper.pollForUIThreadCriteria(new Criteria() { @Override public boolean isSatisfied() { FindToolbar findToolbar = (FindToolbar) getActivity().findViewById( @@ -51,7 +51,7 @@ boolean isVisible = findToolbar != null && findToolbar.isShown(); return (visible == isVisible) && !findToolbar.isAnimating(); } - })); + }); } @MediumTest
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/video/FullscreenVideoTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/video/FullscreenVideoTest.java index 4991c4d..4d5373a 100644 --- a/chrome/android/javatests/src/org/chromium/chrome/browser/video/FullscreenVideoTest.java +++ b/chrome/android/javatests/src/org/chromium/chrome/browser/video/FullscreenVideoTest.java
@@ -75,20 +75,20 @@ } void waitForVideoToEnterFullscreen() throws InterruptedException { - assertTrue(CriteriaHelper.pollForCriteria(new Criteria() { + CriteriaHelper.pollForCriteria(new Criteria() { @Override public boolean isSatisfied() { return mIsTabFullscreen; } - }, TEST_TIMEOUT, CriteriaHelper.DEFAULT_POLLING_INTERVAL)); + }, TEST_TIMEOUT, CriteriaHelper.DEFAULT_POLLING_INTERVAL); } void waitForTabToExitFullscreen() throws InterruptedException { - assertTrue(CriteriaHelper.pollForCriteria(new Criteria() { + CriteriaHelper.pollForCriteria(new Criteria() { @Override public boolean isSatisfied() { return !mIsTabFullscreen; } - }, TEST_TIMEOUT, CriteriaHelper.DEFAULT_POLLING_INTERVAL)); + }, TEST_TIMEOUT, CriteriaHelper.DEFAULT_POLLING_INTERVAL); } }
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/webapps/AddToHomescreenDialogHelperTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/webapps/AddToHomescreenDialogHelperTest.java index 4056420..553167a 100644 --- a/chrome/android/javatests/src/org/chromium/chrome/browser/webapps/AddToHomescreenDialogHelperTest.java +++ b/chrome/android/javatests/src/org/chromium/chrome/browser/webapps/AddToHomescreenDialogHelperTest.java
@@ -201,12 +201,12 @@ addShortcutToURL(MANIFEST_URL, MANIFEST_TITLE, ""); // Make sure that the splash screen image was downloaded. - assertTrue(CriteriaHelper.pollForUIThreadCriteria(new Criteria() { + CriteriaHelper.pollForUIThreadCriteria(new Criteria() { @Override public boolean isSatisfied() { return dataStorageFactory.mSplashImage != null; } - })); + }); // Test that bitmap sizes match expectations. int idealSize = mActivity.getResources().getDimensionPixelSize( @@ -245,12 +245,12 @@ ThreadUtils.runOnUiThreadBlockingNoException(callable); // Make sure that the shortcut was added. - assertTrue(CriteriaHelper.pollForUIThreadCriteria(new Criteria() { + CriteriaHelper.pollForUIThreadCriteria(new Criteria() { @Override public boolean isSatisfied() { return mShortcutHelperDelegate.mBroadcastedIntent != null; } - })); + }); ThreadUtils.runOnUiThreadBlocking(new Runnable() { @Override
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/webapps/WebappActivityTestBase.java b/chrome/android/javatests/src/org/chromium/chrome/browser/webapps/WebappActivityTestBase.java index 29318bcf..39f0a40 100644 --- a/chrome/android/javatests/src/org/chromium/chrome/browser/webapps/WebappActivityTestBase.java +++ b/chrome/android/javatests/src/org/chromium/chrome/browser/webapps/WebappActivityTestBase.java
@@ -126,7 +126,7 @@ protected void waitUntilIdle() { getInstrumentation().waitForIdleSync(); try { - assertTrue(CriteriaHelper.pollForCriteria(new Criteria() { + CriteriaHelper.pollForCriteria(new Criteria() { @Override public boolean isSatisfied() { return getActivity().getActivityTab() != null @@ -134,7 +134,7 @@ } }, MultiActivityTestBase.DEFAULT_MAX_TIME_TO_POLL_FOR_ACTIVITY_MS, - CriteriaHelper.DEFAULT_POLLING_INTERVAL)); + CriteriaHelper.DEFAULT_POLLING_INTERVAL); } catch (InterruptedException exception) { fail(); } @@ -184,15 +184,14 @@ } /** - * Waits for the splash screen to be hidden and return whether it was hidden - * (true) or if it timed out (false). + * Waits for the splash screen to be hidden. */ - protected boolean waitUntilSplashscreenHides() throws InterruptedException { - return CriteriaHelper.pollForCriteria(new Criteria() { - @Override - public boolean isSatisfied() { - return !getActivity().isSplashScreenVisibleForTests(); - } - }); + protected void waitUntilSplashscreenHides() throws InterruptedException { + CriteriaHelper.pollForCriteria(new Criteria() { + @Override + public boolean isSatisfied() { + return !getActivity().isSplashScreenVisibleForTests(); + } + }); } }
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/webapps/WebappDirectoryManagerTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/webapps/WebappDirectoryManagerTest.java index 3ac7b29a..6fafa65c6 100644 --- a/chrome/android/javatests/src/org/chromium/chrome/browser/webapps/WebappDirectoryManagerTest.java +++ b/chrome/android/javatests/src/org/chromium/chrome/browser/webapps/WebappDirectoryManagerTest.java
@@ -156,11 +156,11 @@ private void runCleanup() throws Exception { final AsyncTask task = mWebappDirectoryManager.cleanUpDirectories(mMockContext, WEBAPP_ID_1); - assertTrue(CriteriaHelper.pollForCriteria(new Criteria() { + CriteriaHelper.pollForCriteria(new Criteria() { @Override public boolean isSatisfied() { return task.getStatus() == AsyncTask.Status.FINISHED; } - })); + }); } }
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/webapps/WebappModeTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/webapps/WebappModeTest.java index 3f29466..5f23172 100644 --- a/chrome/android/javatests/src/org/chromium/chrome/browser/webapps/WebappModeTest.java +++ b/chrome/android/javatests/src/org/chromium/chrome/browser/webapps/WebappModeTest.java
@@ -64,8 +64,8 @@ + "IWXMAAAsTAAALEwEAmpwYAAAAB3RJTUUH3wQIFB4cxOfiSQAAABl0RVh0Q29tbWVudABDcmVhdGVkIHdpdG" + "ggR0lNUFeBDhcAAAAMSURBVAjXY2AUawEAALcAnI/TkI8AAAAASUVORK5CYII="; - private boolean isNumberOfRunningActivitiesCorrect(final int numActivities) throws Exception { - return CriteriaHelper.pollForCriteria(new Criteria() { + private void isNumberOfRunningActivitiesCorrect(final int numActivities) throws Exception { + CriteriaHelper.pollForCriteria(new Criteria() { @Override public boolean isSatisfied() { Context context = getInstrumentation().getTargetContext(); @@ -126,29 +126,29 @@ public void testWebappLaunches() throws Exception { final Activity firstActivity = startWebappActivity(WEBAPP_1_ID, WEBAPP_1_URL, WEBAPP_1_TITLE, WEBAPP_ICON); - assertTrue(isNumberOfRunningActivitiesCorrect(1)); + isNumberOfRunningActivitiesCorrect(1); // Firing a different Intent should start a new WebappActivity instance. fireWebappIntent(WEBAPP_2_ID, WEBAPP_2_URL, WEBAPP_2_TITLE, WEBAPP_ICON, true); - assertTrue(CriteriaHelper.pollForUIThreadCriteria(new Criteria() { + CriteriaHelper.pollForUIThreadCriteria(new Criteria() { @Override public boolean isSatisfied() { Activity lastActivity = ApplicationStatus.getLastTrackedFocusedActivity(); return isWebappActivityReady(lastActivity) && lastActivity != firstActivity; } - })); - assertTrue(isNumberOfRunningActivitiesCorrect(2)); + }); + isNumberOfRunningActivitiesCorrect(2); // Firing the first Intent should bring back the first WebappActivity instance. fireWebappIntent(WEBAPP_1_ID, WEBAPP_1_URL, WEBAPP_1_TITLE, WEBAPP_ICON, true); - assertTrue(CriteriaHelper.pollForUIThreadCriteria(new Criteria() { + CriteriaHelper.pollForUIThreadCriteria(new Criteria() { @Override public boolean isSatisfied() { Activity lastActivity = ApplicationStatus.getLastTrackedFocusedActivity(); return isWebappActivityReady(lastActivity) && lastActivity == firstActivity; } - })); - assertTrue(isNumberOfRunningActivitiesCorrect(2)); + }); + isNumberOfRunningActivitiesCorrect(2); } /** @@ -164,7 +164,7 @@ final WebappActivity webappActivity = startWebappActivity(WEBAPP_1_ID, WEBAPP_1_URL, WEBAPP_1_TITLE, WEBAPP_ICON); - assertTrue(isNumberOfRunningActivitiesCorrect(1)); + isNumberOfRunningActivitiesCorrect(1); assertEquals("Wrong Tab ID was used", 11684, webappActivity.getActivityTab().getId()); } @@ -196,7 +196,7 @@ // Start the WebappActivity. final WebappActivity activity = startWebappActivity(WEBAPP_1_ID, WEBAPP_1_URL, WEBAPP_1_TITLE, WEBAPP_ICON); - assertTrue(isNumberOfRunningActivitiesCorrect(1)); + isNumberOfRunningActivitiesCorrect(1); // Return home. final Context context = getInstrumentation().getTargetContext(); @@ -217,14 +217,14 @@ // When Chrome is back in the foreground, confirm that the original Activity was restored. getInstrumentation().waitForIdleSync(); ApplicationTestUtils.waitUntilChromeInForeground(); - assertTrue(CriteriaHelper.pollForCriteria(new Criteria() { + CriteriaHelper.pollForCriteria(new Criteria() { @Override public boolean isSatisfied() { return activity == ApplicationStatus.getLastTrackedFocusedActivity() && activity.hasWindowFocus(); } - })); - assertTrue(isNumberOfRunningActivitiesCorrect(1)); + }); + isNumberOfRunningActivitiesCorrect(1); } /** @@ -234,7 +234,7 @@ public void testWebappRequiresValidMac() throws Exception { // Try to start a WebappActivity. Fail because the Intent is insecure. fireWebappIntent(WEBAPP_1_ID, WEBAPP_1_URL, WEBAPP_1_TITLE, WEBAPP_ICON, false); - assertTrue(CriteriaHelper.pollForUIThreadCriteria(new Criteria() { + CriteriaHelper.pollForUIThreadCriteria(new Criteria() { @Override public boolean isSatisfied() { Activity lastActivity = ApplicationStatus.getLastTrackedFocusedActivity(); @@ -242,18 +242,18 @@ return lastActivity instanceof ChromeTabbedActivity || lastActivity instanceof DocumentActivity; } - })); + }); final Activity firstActivity = ApplicationStatus.getLastTrackedFocusedActivity(); // Firing a correct Intent should start a new WebappActivity instance. fireWebappIntent(WEBAPP_2_ID, WEBAPP_2_URL, WEBAPP_2_TITLE, WEBAPP_ICON, true); - assertTrue(CriteriaHelper.pollForUIThreadCriteria(new Criteria() { + CriteriaHelper.pollForUIThreadCriteria(new Criteria() { @Override public boolean isSatisfied() { Activity lastActivity = ApplicationStatus.getLastTrackedFocusedActivity(); return isWebappActivityReady(lastActivity) && lastActivity != firstActivity; } - })); + }); } /** @@ -296,7 +296,7 @@ Class<T> classToWaitFor, String linkHtml, boolean checkContents) throws Exception { final WebappActivity webappActivity = startWebappActivity(WEBAPP_1_ID, WEBAPP_1_URL, WEBAPP_1_TITLE, WEBAPP_ICON); - assertTrue(isNumberOfRunningActivitiesCorrect(1)); + isNumberOfRunningActivitiesCorrect(1); // Load up the test page. new TabLoadObserver(webappActivity.getActivityTab(), linkHtml).assertLoaded( @@ -330,12 +330,12 @@ // Close the child window to kick the user back to the WebappActivity. JavaScriptUtils.executeJavaScript( secondActivity.getActivityTab().getWebContents(), "window.close()"); - assertTrue(CriteriaHelper.pollForUIThreadCriteria(new Criteria() { + CriteriaHelper.pollForUIThreadCriteria(new Criteria() { @Override public boolean isSatisfied() { return webappActivity == ApplicationStatus.getLastTrackedFocusedActivity(); } - })); + }); ApplicationTestUtils.waitUntilChromeInForeground(); } @@ -347,13 +347,13 @@ private WebappActivity startWebappActivity(String id, String url, String title, String icon) throws Exception { fireWebappIntent(id, url, title, icon, true); - assertTrue(CriteriaHelper.pollForUIThreadCriteria(new Criteria() { + CriteriaHelper.pollForUIThreadCriteria(new Criteria() { @Override public boolean isSatisfied() { Activity lastActivity = ApplicationStatus.getLastTrackedFocusedActivity(); return isWebappActivityReady(lastActivity); } - })); + }); return (WebappActivity) ApplicationStatus.getLastTrackedFocusedActivity(); }
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/webapps/WebappSplashScreenTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/webapps/WebappSplashScreenTest.java index db1a9d2..aff1ce04 100644 --- a/chrome/android/javatests/src/org/chromium/chrome/browser/webapps/WebappSplashScreenTest.java +++ b/chrome/android/javatests/src/org/chromium/chrome/browser/webapps/WebappSplashScreenTest.java
@@ -86,7 +86,7 @@ } }); - assertTrue(waitUntilSplashscreenHides()); + waitUntilSplashscreenHides(); } @SmallTest @@ -102,7 +102,7 @@ } }); - assertTrue(waitUntilSplashscreenHides()); + waitUntilSplashscreenHides(); } @SmallTest @@ -118,7 +118,7 @@ } }); - assertTrue(waitUntilSplashscreenHides()); + waitUntilSplashscreenHides(); } @SmallTest @@ -134,7 +134,7 @@ } }); - assertTrue(waitUntilSplashscreenHides()); + waitUntilSplashscreenHides(); } @SmallTest @@ -154,7 +154,7 @@ } }); - assertTrue(waitUntilSplashscreenHides()); + waitUntilSplashscreenHides(); } @SmallTest @@ -201,7 +201,7 @@ } }); - assertTrue(waitUntilSplashscreenHides()); + waitUntilSplashscreenHides(); // DURATION and HIDES should now have a value. assertTrue(hasHistogramEntry(WebappUma.HISTOGRAM_SPLASHSCREEN_DURATION, 3000));
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/webapps/WebappSplashScreenThemeColorTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/webapps/WebappSplashScreenThemeColorTest.java index 3bfecf3..d6600c91 100644 --- a/chrome/android/javatests/src/org/chromium/chrome/browser/webapps/WebappSplashScreenThemeColorTest.java +++ b/chrome/android/javatests/src/org/chromium/chrome/browser/webapps/WebappSplashScreenThemeColorTest.java
@@ -63,13 +63,13 @@ }); // Waits for theme-color to change so the test doesn't rely on system timing. - assertTrue(CriteriaHelper.pollForCriteria(new Criteria() { - @Override - public boolean isSatisfied() { - return getActivity().getWindow().getStatusBarColor() - == ColorUtils.getDarkenedColorForStatusBar(Color.GREEN); - } - })); + CriteriaHelper.pollForCriteria(new Criteria() { + @Override + public boolean isSatisfied() { + return getActivity().getWindow().getStatusBarColor() + == ColorUtils.getDarkenedColorForStatusBar(Color.GREEN); + } + }); } @SmallTest
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/widget/OverviewListLayoutTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/widget/OverviewListLayoutTest.java index 7cb2600..984fcfc5 100644 --- a/chrome/android/javatests/src/org/chromium/chrome/browser/widget/OverviewListLayoutTest.java +++ b/chrome/android/javatests/src/org/chromium/chrome/browser/widget/OverviewListLayoutTest.java
@@ -49,7 +49,7 @@ private static final int SWIPE_START_Y_OFFSET = 10; private static final int SWIPE_END_X = 20; - private class ChildCountCriteria implements Criteria { + private class ChildCountCriteria extends Criteria { private final int mChildCount; public ChildCountCriteria(int count) { @@ -68,7 +68,7 @@ } } - private class TabModelCountCountCriteria implements Criteria { + private class TabModelCountCountCriteria extends Criteria { private final boolean mIncognito; private final int mTabCount; @@ -79,7 +79,7 @@ @Override public boolean isSatisfied() { - return mTabCount == ThreadUtils.runOnUiThreadBlockingNoException( + int actualTabCount = ThreadUtils.runOnUiThreadBlockingNoException( new Callable<Integer>() { @Override public Integer call() { @@ -87,6 +87,8 @@ .getModel(mIncognito).getCount(); } }); + updateFailureReason("Expected tab count: " + mTabCount + ", Actual: " + actualTabCount); + return mTabCount == actualTabCount; } } @@ -110,8 +112,7 @@ TestTouchUtils.performClickOnMainSync( getInstrumentation(), getActivity().findViewById(R.id.tab_switcher_button)); - assertTrue( - "Wrong number of tabs", CriteriaHelper.pollForCriteria(new ChildCountCriteria(4))); + CriteriaHelper.pollForCriteria(new ChildCountCriteria(4)); } private AccessibilityTabModelListItem getListItemAndDisableAnimations(int index) { @@ -136,13 +137,13 @@ private void toggleTabSwitcher(final boolean expectVisible) throws Exception { TestTouchUtils.performClickOnMainSync( getInstrumentation(), getActivity().findViewById(R.id.tab_switcher_button)); - assertTrue(CriteriaHelper.pollForUIThreadCriteria(new Criteria() { + CriteriaHelper.pollForUIThreadCriteria(new Criteria() { @Override public boolean isSatisfied() { boolean isVisible = (getContainer() != null && getContainer().getParent() != null); return isVisible == expectVisible; } - })); + }); } @Restriction(RESTRICTION_TYPE_PHONE) @@ -301,10 +302,8 @@ MenuUtils.invokeCustomMenuActionSync( getInstrumentation(), getActivity(), R.id.close_all_tabs_menu_id); - assertTrue( - "Wrong number of tabs", CriteriaHelper.pollForCriteria(new ChildCountCriteria(0))); - assertTrue("Tabs not closed on the model", - CriteriaHelper.pollForCriteria(new TabModelCountCountCriteria(false, 0))); + CriteriaHelper.pollForCriteria(new ChildCountCriteria(0)); + CriteriaHelper.pollForCriteria(new TabModelCountCountCriteria(false, 0)); assertFalse(getActivity().findViewById(R.id.tab_switcher_button).isEnabled()); } @@ -316,25 +315,20 @@ newIncognitoTabsFromMenu(2); TestTouchUtils.performClickOnMainSync( getInstrumentation(), getActivity().findViewById(R.id.tab_switcher_button)); - assertTrue( - "Wrong number of tabs", CriteriaHelper.pollForCriteria(new ChildCountCriteria(2))); + CriteriaHelper.pollForCriteria(new ChildCountCriteria(2)); MenuUtils.invokeCustomMenuActionSync( getInstrumentation(), getActivity(), R.id.close_all_incognito_tabs_menu_id); - assertTrue("Tabs not closed on the model", - CriteriaHelper.pollForCriteria(new TabModelCountCountCriteria(true, 0))); + CriteriaHelper.pollForCriteria(new TabModelCountCountCriteria(true, 0)); - assertTrue( - "Wrong number of tabs", CriteriaHelper.pollForCriteria(new ChildCountCriteria(4))); + CriteriaHelper.pollForCriteria(new ChildCountCriteria(4)); assertTrue(getActivity().findViewById(R.id.tab_switcher_button).isEnabled()); MenuUtils.invokeCustomMenuActionSync( getInstrumentation(), getActivity(), R.id.close_all_tabs_menu_id); - assertTrue( - "Wrong number of tabs", CriteriaHelper.pollForCriteria(new ChildCountCriteria(0))); - assertTrue("Tabs not closed on the model", - CriteriaHelper.pollForCriteria(new TabModelCountCountCriteria(false, 0))); + CriteriaHelper.pollForCriteria(new ChildCountCriteria(0)); + CriteriaHelper.pollForCriteria(new TabModelCountCountCriteria(false, 0)); assertFalse(getActivity().findViewById(R.id.tab_switcher_button).isEnabled()); } @@ -380,14 +374,12 @@ TestTouchUtils.performClickOnMainSync(getInstrumentation(), incognitoButton); - assertTrue( - "Wrong number of tabs", CriteriaHelper.pollForCriteria(new ChildCountCriteria(2))); + CriteriaHelper.pollForCriteria(new ChildCountCriteria(2)); TestTouchUtils.performClickOnMainSync( getInstrumentation(), switcherButtons.findViewById(R.id.standard_tabs_button)); - assertTrue( - "Wrong number of tabs", CriteriaHelper.pollForCriteria(new ChildCountCriteria(4))); + CriteriaHelper.pollForCriteria(new ChildCountCriteria(4)); } /**
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/widget/findinpage/FindTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/widget/findinpage/FindTest.java index 163b5c9..c1aeeb8 100644 --- a/chrome/android/javatests/src/org/chromium/chrome/browser/widget/findinpage/FindTest.java +++ b/chrome/android/javatests/src/org/chromium/chrome/browser/widget/findinpage/FindTest.java
@@ -47,12 +47,12 @@ final TextView findResults = (TextView) getActivity().findViewById(R.id.find_status); assertNotNull(expectedResult); assertNotNull(findResults); - assertTrue(CriteriaHelper.pollForUIThreadCriteria(new Criteria() { + CriteriaHelper.pollForUIThreadCriteria(new Criteria() { @Override public boolean isSatisfied() { return expectedResult.equals(findResults.getText()); } - })); + }); return findResults.getText().toString(); } @@ -69,7 +69,7 @@ } private void waitForFindInPageVisibility(final boolean visible) throws InterruptedException { - assertTrue(CriteriaHelper.pollForUIThreadCriteria(new Criteria() { + CriteriaHelper.pollForUIThreadCriteria(new Criteria() { @Override public boolean isSatisfied() { FindToolbar findToolbar = (FindToolbar) getActivity().findViewById( @@ -78,7 +78,7 @@ boolean isVisible = findToolbar != null && findToolbar.isShown(); return (visible == isVisible) && !findToolbar.isAnimating(); } - })); + }); } private String findStringInPage(final String query, String expectedResult)
diff --git a/chrome/android/sync_shell/javatests/src/org/chromium/chrome/browser/sync/AutofillTest.java b/chrome/android/sync_shell/javatests/src/org/chromium/chrome/browser/sync/AutofillTest.java index d4eca1e..b529e9d 100644 --- a/chrome/android/sync_shell/javatests/src/org/chromium/chrome/browser/sync/AutofillTest.java +++ b/chrome/android/sync_shell/javatests/src/org/chromium/chrome/browser/sync/AutofillTest.java
@@ -174,7 +174,8 @@ } private void waitForClientAutofillProfileCount(final int count) throws InterruptedException { - boolean success = CriteriaHelper.pollForCriteria(new Criteria() { + CriteriaHelper.pollForCriteria(new Criteria( + "Expected " + count + " local autofill profiles.") { @Override public boolean isSatisfied() { try { @@ -184,12 +185,12 @@ } } }, SyncTestUtil.TIMEOUT_MS, SyncTestUtil.INTERVAL_MS); - assertTrue("Expected " + count + " local autofill profiles.", success); } private void waitForServerAutofillProfileCountWithName(final int count, final String name) throws InterruptedException { - boolean success = CriteriaHelper.pollForCriteria(new Criteria() { + CriteriaHelper.pollForCriteria(new Criteria( + "Expected " + count + " server autofill profiles with name " + name + ".") { @Override public boolean isSatisfied() { try { @@ -200,7 +201,5 @@ } } }, SyncTestUtil.TIMEOUT_MS, SyncTestUtil.INTERVAL_MS); - assertTrue("Expected " + count + " server autofill profiles with name " + name + ".", - success); } }
diff --git a/chrome/android/sync_shell/javatests/src/org/chromium/chrome/browser/sync/BookmarksTest.java b/chrome/android/sync_shell/javatests/src/org/chromium/chrome/browser/sync/BookmarksTest.java index 8caf1443..adbe3f1 100644 --- a/chrome/android/sync_shell/javatests/src/org/chromium/chrome/browser/sync/BookmarksTest.java +++ b/chrome/android/sync_shell/javatests/src/org/chromium/chrome/browser/sync/BookmarksTest.java
@@ -456,7 +456,7 @@ } private void waitForClientBookmarkCount(final int n) throws InterruptedException { - boolean success = CriteriaHelper.pollForCriteria(new Criteria() { + CriteriaHelper.pollForCriteria(new Criteria("There should be " + n + " local bookmarks.") { @Override public boolean isSatisfied() { try { @@ -466,12 +466,12 @@ } } }, SyncTestUtil.TIMEOUT_MS, SyncTestUtil.INTERVAL_MS); - assertTrue("There should be " + n + " local bookmarks.", success); } private void waitForServerBookmarkCountWithName(final int count, final String name) throws InterruptedException { - boolean success = CriteriaHelper.pollForCriteria(new Criteria() { + CriteriaHelper.pollForCriteria(new Criteria( + "Expected " + count + " remote bookmarks with name " + name + ".") { @Override public boolean isSatisfied() { try { @@ -482,6 +482,5 @@ } } }, SyncTestUtil.TIMEOUT_MS, SyncTestUtil.INTERVAL_MS); - assertTrue("Expected " + count + " remote bookmarks with name " + name + ".", success); } }
diff --git a/chrome/android/sync_shell/javatests/src/org/chromium/chrome/browser/sync/GmsCoreSyncListenerTest.java b/chrome/android/sync_shell/javatests/src/org/chromium/chrome/browser/sync/GmsCoreSyncListenerTest.java index 84c6377..a41ca09 100644 --- a/chrome/android/sync_shell/javatests/src/org/chromium/chrome/browser/sync/GmsCoreSyncListenerTest.java +++ b/chrome/android/sync_shell/javatests/src/org/chromium/chrome/browser/sync/GmsCoreSyncListenerTest.java
@@ -106,7 +106,8 @@ } private void waitForCryptographer() throws InterruptedException { - boolean isReady = CriteriaHelper.pollForUIThreadCriteria(new Criteria() { + CriteriaHelper.pollForUIThreadCriteria(new Criteria( + "Timed out waiting for cryptographer to be ready.") { @Override public boolean isSatisfied() { ProfileSyncService syncService = ProfileSyncService.get(); @@ -114,7 +115,6 @@ && syncService.isCryptographerReady(); } }); - assertTrue("Timed out waiting for cryptographer to be ready.", isReady); } private void waitForCallCount(final int count) throws InterruptedException {
diff --git a/chrome/android/sync_shell/javatests/src/org/chromium/chrome/browser/sync/OpenTabsTest.java b/chrome/android/sync_shell/javatests/src/org/chromium/chrome/browser/sync/OpenTabsTest.java index a4d58d4f..b591002 100644 --- a/chrome/android/sync_shell/javatests/src/org/chromium/chrome/browser/sync/OpenTabsTest.java +++ b/chrome/android/sync_shell/javatests/src/org/chromium/chrome/browser/sync/OpenTabsTest.java
@@ -245,7 +245,9 @@ throws InterruptedException { final List<String> urlList = new ArrayList<String>(urls.length); for (String url : urls) urlList.add(url); - boolean success = CriteriaHelper.pollForCriteria(new Criteria() { + CriteriaHelper.pollForCriteria(new Criteria( + "Expected local open tabs for client " + clientName + ": " + + Arrays.toString(urls)) { @Override public boolean isSatisfied() { try { @@ -255,13 +257,12 @@ } } }, SyncTestUtil.TIMEOUT_MS, SyncTestUtil.INTERVAL_MS); - assertTrue("Expected local open tabs for client " + clientName + ": " - + Arrays.toString(urls), success); } private void waitForServerTabs(final String... urls) throws InterruptedException { - boolean success = CriteriaHelper.pollForCriteria(new Criteria() { + CriteriaHelper.pollForCriteria(new Criteria( + "Expected server open tabs: " + Arrays.toString(urls)) { @Override public boolean isSatisfied() { try { @@ -271,7 +272,6 @@ } } }, SyncTestUtil.TIMEOUT_MS, SyncTestUtil.INTERVAL_MS); - assertTrue("Expected server open tabs: " + Arrays.toString(urls), success); } private String getClientName() throws JSONException {
diff --git a/chrome/android/sync_shell/javatests/src/org/chromium/chrome/browser/sync/SyncCustomizationFragmentTest.java b/chrome/android/sync_shell/javatests/src/org/chromium/chrome/browser/sync/SyncCustomizationFragmentTest.java index 0d8db0ae..6b00ee1d 100644 --- a/chrome/android/sync_shell/javatests/src/org/chromium/chrome/browser/sync/SyncCustomizationFragmentTest.java +++ b/chrome/android/sync_shell/javatests/src/org/chromium/chrome/browser/sync/SyncCustomizationFragmentTest.java
@@ -523,13 +523,13 @@ } private void waitForBackendInitialized() throws InterruptedException { - boolean success = CriteriaHelper.pollForUIThreadCriteria(new Criteria() { + CriteriaHelper.pollForUIThreadCriteria(new Criteria( + "Timed out waiting for sync's backend to be initialized.") { @Override public boolean isSatisfied() { return mProfileSyncService.isBackendInitialized(); } }, SyncTestUtil.TIMEOUT_MS, SyncTestUtil.INTERVAL_MS); - assertTrue("Timed out waiting for sync's backend to be initialized.", success); } // UI interaction convenience methods.
diff --git a/chrome/android/sync_shell/javatests/src/org/chromium/chrome/browser/sync/SyncTest.java b/chrome/android/sync_shell/javatests/src/org/chromium/chrome/browser/sync/SyncTest.java index 3ac169e..33bc734 100644 --- a/chrome/android/sync_shell/javatests/src/org/chromium/chrome/browser/sync/SyncTest.java +++ b/chrome/android/sync_shell/javatests/src/org/chromium/chrome/browser/sync/SyncTest.java
@@ -66,7 +66,7 @@ @LargeTest @Feature({"Sync"}) - public void testDisableAndEnableSyncThroughAndroid() throws InterruptedException { + public void testStopAndStartSyncThroughAndroid() throws InterruptedException { Account account = setUpTestAccountAndSignInToSync(); SyncTestUtil.waitForSyncActive(); @@ -79,6 +79,27 @@ // Enabling Android sync should turn Chrome sync engine on. mSyncContentResolver.setSyncAutomatically(account, authority, true); SyncTestUtil.verifySyncIsActiveForAccount(mContext, account); + + // Disabling Android's master sync should turn Chrome sync engine off. + mSyncContentResolver.setMasterSyncAutomatically(false); + SyncTestUtil.verifySyncIsDisabled(mContext, account); + + // Enabling Android's master sync should turn Chrome sync engine on. + mSyncContentResolver.setMasterSyncAutomatically(true); + SyncTestUtil.verifySyncIsActiveForAccount(mContext, account); + + // Disabling both should definitely turn sync off. + mSyncContentResolver.setSyncAutomatically(account, authority, false); + mSyncContentResolver.setMasterSyncAutomatically(false); + SyncTestUtil.verifySyncIsDisabled(mContext, account); + + // Re-enabling master sync should not turn sync back on. + mSyncContentResolver.setMasterSyncAutomatically(true); + SyncTestUtil.verifySyncIsDisabled(mContext, account); + + // But then re-enabling Chrome sync should. + mSyncContentResolver.setSyncAutomatically(account, authority, true); + SyncTestUtil.verifySyncIsActiveForAccount(mContext, account); } private static ContentViewCore getContentViewCore(ChromeActivity activity) {
diff --git a/chrome/android/sync_shell/javatests/src/org/chromium/chrome/browser/sync/SyncTestBase.java b/chrome/android/sync_shell/javatests/src/org/chromium/chrome/browser/sync/SyncTestBase.java index fd59063..1eb72c1 100644 --- a/chrome/android/sync_shell/javatests/src/org/chromium/chrome/browser/sync/SyncTestBase.java +++ b/chrome/android/sync_shell/javatests/src/org/chromium/chrome/browser/sync/SyncTestBase.java
@@ -13,6 +13,7 @@ import org.chromium.chrome.browser.identity.UniqueIdentificationGeneratorFactory; import org.chromium.chrome.browser.identity.UuidBasedUniqueIdentificationGenerator; import org.chromium.chrome.browser.signin.SigninManager; +import org.chromium.chrome.browser.signin.SigninManager.SignInFlowObserver; import org.chromium.chrome.test.ChromeActivityTestCaseBase; import org.chromium.chrome.test.util.browser.signin.SigninTestUtil; import org.chromium.chrome.test.util.browser.sync.SyncTestUtil; @@ -47,7 +48,6 @@ })); protected Context mContext; - protected SyncController mSyncController; protected FakeServerHelper mFakeServerHelper; protected ProfileSyncService mProfileSyncService; protected MockSyncContentResolverDelegate mSyncContentResolver; @@ -76,9 +76,8 @@ ThreadUtils.runOnUiThreadBlocking(new Runnable() { @Override public void run() { - mSyncController = SyncController.get(mContext); // Ensure SyncController is registered with the new AndroidSyncSettings. - AndroidSyncSettings.registerObserver(mContext, mSyncController); + AndroidSyncSettings.registerObserver(mContext, SyncController.get(mContext)); mFakeServerHelper = FakeServerHelper.get(); } }); @@ -105,7 +104,7 @@ ThreadUtils.runOnUiThreadBlocking(new Runnable() { @Override public void run() { - mSyncController.stop(); + mProfileSyncService.requestStop(); FakeServerHelper.deleteFakeServer(); } }); @@ -136,7 +135,7 @@ ThreadUtils.runOnUiThreadBlocking(new Runnable() { @Override public void run() { - SyncController.get(mContext).start(); + mProfileSyncService.requestStart(); } }); SyncTestUtil.waitForSyncActive(); @@ -146,7 +145,7 @@ ThreadUtils.runOnUiThreadBlocking(new Runnable() { @Override public void run() { - SyncController.get(mContext).stop(); + mProfileSyncService.requestStop(); } }); getInstrumentation().waitForIdleSync(); @@ -156,7 +155,17 @@ ThreadUtils.runOnUiThreadBlocking(new Runnable() { @Override public void run() { - mSyncController.signIn(getActivity(), account.name); + SigninManager signinManager = SigninManager.get(mContext); + signinManager.startSignIn(null, account, false, new SignInFlowObserver() { + @Override + public void onSigninComplete() { + mProfileSyncService.requestStart(); + } + + @Override + public void onSigninCancelled() { + } + }); } }); SyncTestUtil.verifySyncIsActiveForAccount(mContext, account); @@ -182,13 +191,12 @@ protected void clearServerData() throws InterruptedException { mFakeServerHelper.clearServerData(); SyncTestUtil.triggerSync(); - boolean syncStopped = CriteriaHelper.pollForUIThreadCriteria(new Criteria() { + CriteriaHelper.pollForUIThreadCriteria(new Criteria("Timed out waiting for sync to stop.") { @Override public boolean isSatisfied() { return !ProfileSyncService.get().isSyncRequested(); } }, SyncTestUtil.TIMEOUT_MS, SyncTestUtil.INTERVAL_MS); - assertTrue("Timed out waiting for sync to stop.", syncStopped); } protected void disableDataType(final int modelType) {
diff --git a/chrome/android/sync_shell/javatests/src/org/chromium/chrome/browser/sync/TypedUrlsTest.java b/chrome/android/sync_shell/javatests/src/org/chromium/chrome/browser/sync/TypedUrlsTest.java index f76f5c3..f982a3d 100644 --- a/chrome/android/sync_shell/javatests/src/org/chromium/chrome/browser/sync/TypedUrlsTest.java +++ b/chrome/android/sync_shell/javatests/src/org/chromium/chrome/browser/sync/TypedUrlsTest.java
@@ -142,7 +142,8 @@ } private void waitForClientTypedUrlCount(final int count) throws InterruptedException { - boolean success = CriteriaHelper.pollForCriteria(new Criteria() { + CriteriaHelper.pollForCriteria(new Criteria( + "Expected " + count + " local typed URL entities.") { @Override public boolean isSatisfied() { try { @@ -152,12 +153,12 @@ } } }, SyncTestUtil.TIMEOUT_MS, SyncTestUtil.INTERVAL_MS); - assertTrue("Expected " + count + " local typed URL entities.", success); } private void waitForServerTypedUrlCountWithName(final int count, final String name) throws InterruptedException { - boolean success = CriteriaHelper.pollForCriteria(new Criteria() { + CriteriaHelper.pollForCriteria(new Criteria( + "Expected " + count + " server typed URLs with name " + name + ".") { @Override public boolean isSatisfied() { try { @@ -168,6 +169,5 @@ } } }, SyncTestUtil.TIMEOUT_MS, SyncTestUtil.INTERVAL_MS); - assertTrue("Expected " + count + " server typed URLs with name " + name + ".", success); } }
diff --git a/chrome/app/chrome_crash_reporter_client.cc b/chrome/app/chrome_crash_reporter_client.cc index 2663a08..4cac4f1 100644 --- a/chrome/app/chrome_crash_reporter_client.cc +++ b/chrome/app/chrome_crash_reporter_client.cc
@@ -16,6 +16,7 @@ #include "chrome/common/chrome_result_codes.h" #include "chrome/common/crash_keys.h" #include "chrome/common/env_vars.h" +#include "chrome/installer/util/browser_distribution.h" #include "chrome/installer/util/google_update_settings.h" #include "content/public/common/content_switches.h" @@ -278,6 +279,22 @@ bool ChromeCrashReporterClient::GetCrashDumpLocation( base::FilePath* crash_dir) { +#if defined(OS_WIN) + // In order to be able to start crash handling very early, we do not rely on + // chrome's PathService entries (for DIR_CRASH_DUMPS) being available on + // Windows. See https://crbug.com/564398. + base::FilePath result; + if (!PathService::Get(base::DIR_LOCAL_APP_DATA, &result)) + return false; + BrowserDistribution* dist = BrowserDistribution::GetDistribution(); + result = result.Append(dist->GetInstallSubDir()); + // TODO(scottmg): Consider supporting --user-data-dir. See + // https://crbug.com/565446. + result = result.Append(chrome::kUserDataDirname); + result = result.Append(FILE_PATH_LITERAL("Crashpad")); + *crash_dir = result; + return true; +#else // By setting the BREAKPAD_DUMP_LOCATION environment variable, an alternate // location to write breakpad crash dumps can be set. scoped_ptr<base::Environment> env(base::Environment::Create()); @@ -289,6 +306,7 @@ } return PathService::Get(chrome::DIR_CRASH_DUMPS, crash_dir); +#endif } size_t ChromeCrashReporterClient::RegisterCrashKeys() {
diff --git a/chrome/app/chrome_exe_main_win.cc b/chrome/app/chrome_exe_main_win.cc index cf91743e..c052283 100644 --- a/chrome/app/chrome_exe_main_win.cc +++ b/chrome/app/chrome_exe_main_win.cc
@@ -13,16 +13,20 @@ #include "base/at_exit.h" #include "base/command_line.h" #include "base/files/file_path.h" +#include "base/lazy_instance.h" #include "base/logging.h" #include "base/strings/utf_string_conversions.h" #include "base/time/time.h" #include "base/win/windows_version.h" +#include "chrome/app/chrome_crash_reporter_client.h" #include "chrome/app/main_dll_loader_win.h" #include "chrome/browser/chrome_process_finder_win.h" #include "chrome/browser/policy/policy_path_parser.h" #include "chrome/common/chrome_paths_internal.h" #include "chrome/common/chrome_switches.h" #include "chrome_elf/chrome_elf_main.h" +#include "components/crash/content/app/crash_reporter_client.h" +#include "components/crash/content/app/crashpad.h" #include "components/startup_metric_utils/browser/startup_metric_utils.h" #include "content/public/common/content_switches.h" #include "content/public/common/result_codes.h" @@ -30,6 +34,13 @@ #include "ui/gfx/win/dpi.h" namespace { + +base::LazyInstance<ChromeCrashReporterClient>::Leaky g_chrome_crash_client = + LAZY_INSTANCE_INITIALIZER; + +base::LazyInstance<std::vector<crash_reporter::UploadedReport>>::Leaky + g_uploaded_reports = LAZY_INSTANCE_INITIALIZER; + // List of switches that it's safe to rendezvous early with. Fast start should // not be done if a command line contains a switch not in this set. // Note this is currently stored as a list of two because it's probably faster @@ -125,46 +136,61 @@ } } -bool RunAsCrashpadHandler(wchar_t* command_line, int* rc) { - const base::CommandLine cmdline = base::CommandLine::FromString(command_line); - if (cmdline.GetSwitchValueASCII(switches::kProcessType) == - switches::kCrashpadHandler) { - std::vector<base::string16> argv = cmdline.argv(); - base::string16 process_type = - L"--" + base::UTF8ToUTF16(switches::kProcessType) + L"="; - argv.erase(std::remove_if(argv.begin(), argv.end(), - [&process_type](const base::string16& str) { - return str.compare(0, process_type.size(), - process_type) == 0; - }), - argv.end()); +int RunAsCrashpadHandler(const base::CommandLine& command_line) { + std::vector<base::string16> argv = command_line.argv(); + base::string16 process_type = + L"--" + base::UTF8ToUTF16(switches::kProcessType) + L"="; + argv.erase(std::remove_if(argv.begin(), argv.end(), + [&process_type](const base::string16& str) { + return str.compare(0, process_type.size(), + process_type) == 0; + }), + argv.end()); - scoped_ptr<char* []> argv_as_utf8(new char*[argv.size() + 1]); - std::vector<std::string> storage; - storage.reserve(argv.size()); - for (size_t i = 0; i < argv.size(); ++i) { - storage.push_back(base::UTF16ToUTF8(argv[i])); - argv_as_utf8[i] = &storage[i][0]; - } - argv_as_utf8[argv.size()] = nullptr; - *rc = crashpad::HandlerMain(static_cast<int>(argv.size()), - argv_as_utf8.get()); - return true; + scoped_ptr<char* []> argv_as_utf8(new char*[argv.size() + 1]); + std::vector<std::string> storage; + storage.reserve(argv.size()); + for (size_t i = 0; i < argv.size(); ++i) { + storage.push_back(base::UTF16ToUTF8(argv[i])); + argv_as_utf8[i] = &storage[i][0]; } - return false; + argv_as_utf8[argv.size()] = nullptr; + return crashpad::HandlerMain(static_cast<int>(argv.size()), + argv_as_utf8.get()); } } // namespace +// This helper is looked up in the browser to retrieve the crash reports. See +// CrashUploadListCrashpad. Note that we do not pass an std::vector here, +// because we do not want to allocate/free in different modules. The returned +// pointer is read-only. +extern "C" __declspec(dllexport) void GetUploadedReportsImpl( + const crash_reporter::UploadedReport** reports, + size_t* report_count) { + crash_reporter::GetUploadedReports(g_uploaded_reports.Pointer()); + *reports = g_uploaded_reports.Pointer()->data(); + *report_count = g_uploaded_reports.Pointer()->size(); +} + #if !defined(WIN_CONSOLE_APP) int APIENTRY wWinMain(HINSTANCE instance, HINSTANCE prev, wchar_t*, int) { #else int main() { - HINSTANCE instance = GetModuleHandle(NULL); + HINSTANCE instance = GetModuleHandle(nullptr); #endif - int rc; - if (RunAsCrashpadHandler(GetCommandLine(), &rc)) - return rc; + // Initialize the CommandLine singleton from the environment. + base::CommandLine::Init(0, nullptr); + + std::string process_type = + base::CommandLine::ForCurrentProcess()->GetSwitchValueASCII( + switches::kProcessType); + + if (process_type == switches::kCrashpadHandler) + return RunAsCrashpadHandler(*base::CommandLine::ForCurrentProcess()); + + crash_reporter::SetCrashReporterClient(g_chrome_crash_client.Pointer()); + crash_reporter::InitializeCrashpad(process_type.empty(), process_type); SwitchToLFHeap(); @@ -173,8 +199,6 @@ // Signal Chrome Elf that Chrome has begun to start. SignalChromeElf(); - // Initialize the commandline singleton from the environment. - base::CommandLine::Init(0, NULL); // The exit manager is in charge of calling the dtors of singletons. base::AtExitManager exit_manager; @@ -190,7 +214,7 @@ // Load and launch the chrome dll. *Everything* happens inside. VLOG(1) << "About to load main DLL."; MainDllLoader* loader = MakeMainDllLoader(); - rc = loader->Launch(instance); + int rc = loader->Launch(instance); loader->RelaunchChromeBrowserWithNewCommandLineIfNeeded(); delete loader; return rc;
diff --git a/chrome/app/chrome_main_delegate.cc b/chrome/app/chrome_main_delegate.cc index 2d8b3951..f61a4a56 100644 --- a/chrome/app/chrome_main_delegate.cc +++ b/chrome/app/chrome_main_delegate.cc
@@ -31,6 +31,7 @@ #include "chrome/common/chrome_result_codes.h" #include "chrome/common/chrome_switches.h" #include "chrome/common/crash_keys.h" +#include "chrome/common/features.h" #include "chrome/common/logging_chrome.h" #include "chrome/common/profiling.h" #include "chrome/common/switch_utils.h" @@ -89,8 +90,11 @@ #include "chromeos/chromeos_switches.h" #endif -#if defined(OS_ANDROID) +#if BUILDFLAG(ANDROID_JAVA_UI) #include "chrome/browser/android/java_exception_reporter.h" +#endif + +#if defined(OS_ANDROID) #include "chrome/common/descriptors_android.h" #else // Diagnostics is only available on non-android platforms. @@ -146,7 +150,7 @@ LAZY_INSTANCE_INITIALIZER; #endif -#if defined(OS_POSIX) || defined(OS_WIN) +#if defined(OS_POSIX) base::LazyInstance<ChromeCrashReporterClient>::Leaky g_chrome_crash_client = LAZY_INSTANCE_INITIALIZER; #endif @@ -665,7 +669,7 @@ std::string process_type = command_line.GetSwitchValueASCII(switches::kProcessType); -#if defined(OS_POSIX) || defined(OS_WIN) +#if defined(OS_POSIX) crash_reporter::SetCrashReporterClient(g_chrome_crash_client.Pointer()); #endif @@ -680,16 +684,6 @@ #endif #if defined(OS_WIN) - // TODO(scottmg): It would be nice to do this earlier to catch early crashes, - // perhaps as early as WinMain in chrome.exe. This would require some code - // restructuring to have paths and command lines set up, and also to handle - // having some of the code live in chrome.exe, while having the database be - // accessed by browser code in chrome.dll (to get a list of uploaded crashes - // for chrome://crashes). - crash_reporter::InitializeCrashpad(process_type.empty(), process_type); -#endif // OS_WIN - -#if defined(OS_WIN) child_process_logging::Init(); #endif #if defined(ARCH_CPU_ARM_FAMILY) && (defined(OS_ANDROID) || defined(OS_LINUX)) @@ -802,7 +796,11 @@ #if defined(OS_ANDROID) if (process_type.empty()) { breakpad::InitCrashReporter(process_type); +// TODO(crbug.com/551176): Exception reporting should work without +// ANDROID_JAVA_UI +#if BUILDFLAG(ANDROID_JAVA_UI) chrome::android::InitJavaExceptionReporter(); +#endif } else { breakpad::InitNonBrowserCrashReporterForAndroid(process_type); }
diff --git a/chrome/app/generated_resources.grd b/chrome/app/generated_resources.grd index c9a811d..5ccdbe7 100644 --- a/chrome/app/generated_resources.grd +++ b/chrome/app/generated_resources.grd
@@ -5832,12 +5832,6 @@ <message name="IDS_FLAGS_GPU_RASTERIZATION_MSAA_SAMPLE_COUNT_SIXTEEN" desc=""> 16 </message> - <message name="IDS_FLAGS_ENABLE_SLIMMING_PAINT_V2_NAME" desc="Title for the flag to enable slimming paint phase 2."> - Enable slimming paint phase 2. - </message> - <message name="IDS_FLAGS_ENABLE_SLIMMING_PAINT_V2_DESCRIPTION" desc="Description for the flag to enable slimming paint phase 2."> - Enable slimming paint phase 2 (display list based layerization, sub-tree painting optimization, etc.) - </message> <message name="IDS_FLAGS_EXPERIMENTAL_SECURITY_FEATURES_NAME" desc="Name for the flag to enable experimental security features."> Potentially annoying security features </message> @@ -6508,6 +6502,14 @@ <message name="IDS_FLAGS_WIFI_CREDENTIAL_SYNC_DESCRIPTION" desc="Decription for the flag to enable WiFi credential sync, a feature which enables synchronizing WiFi network settings across devices."> Enables synchronizing WiFi network settings across devices. When enabled, the WiFi credential datatype is registered with Chrome Sync, and WiFi credentials are synchronized subject to user preferences. (See also, chrome://settings/syncSetup.) </message> + <if expr="is_win"> + <message name="IDS_FLAGS_WINDOWS_DESKTOP_SEARCH_REDIRECTION_DESCRIPTION" desc="Description for the flag to enable a preference that allows redirection of Windows desktop searches to the default search engine."> + Enables a preference that allows redirection of Windows desktop searches to the default search engine. + </message> + <message name="IDS_FLAGS_WINDOWS_DESKTOP_SEARCH_REDIRECTION_NAME" desc="Title for the flag to enable a preference that allows redirection of Windows desktop searches to the default search engine."> + Windows desktop search redirection preference + </message> + </if> <message name="IDS_FLAGS_SYNC_SANDBOX_NAME" desc="Name for the flag that causes Chrome to use the sandbox (testing) server for Sync."> Use Chrome Sync sandbox </message> @@ -6673,6 +6675,18 @@ Enables a new option to upload credit cards to Google Payments for sync to all Chrome devices. </message> </if> + <message name="IDS_FLAGS_FORCE_UI_DIRECTION_NAME" desc="Name for the flag to force a specific UI direction."> + Force UI direction + </message> + <message name="IDS_FLAGS_FORCE_UI_DIRECTION_DESCRIPTION" desc="Description for the flag to force a specific UI direction."> + Explicitly force the UI to left-to-right or right-to-left mode, overriding the default direction of the UI language. + </message> + <message name="IDS_FLAGS_FORCE_UI_DIRECTION_LTR" desc="Name for the option to force left-to-right UI direction mode."> + Left-to-right + </message> + <message name="IDS_FLAGS_FORCE_UI_DIRECTION_RTL" desc="Name for the option to force right-to-left UI direction mode."> + Right-to-left + </message> <!-- WebRTC logs --> <message name="IDS_WEBRTC_LOGS_TITLE" desc="Title for the chrome://webrtc-logs page.">
diff --git a/chrome/app/settings_strings.grdp b/chrome/app/settings_strings.grdp index ce3f6bf87..905c1a3 100644 --- a/chrome/app/settings_strings.grdp +++ b/chrome/app/settings_strings.grdp
@@ -564,6 +564,9 @@ <message name="IDS_SETTINGS_SYNC_DISCONNECT_CONFIRM" desc="The text to display on the button to confirm the user wishes to stop syncing."> Clear and Disconnect </message> + <message name="IDS_SETTINGS_SYNC_MANAGE_OTHER_PEOPLE" desc="Label for the button that opens the multi profile user manager."> + Manage other people + </message> <message name="IDS_SETTINGS_SYNC" desc="Name of the settings page which manages syncing data between multiple browser instances with the same Google profile."> Advanced sync settings @@ -574,12 +577,9 @@ <message name="IDS_SETTINGS_SYNC_TIMEOUT" desc="Text explaining what to do if sync times out."> Please make sure your network connection is working and if the problem persists, please sign out and sign in again to refresh your credentials. </message> - <message name="IDS_SETTINGS_SYNC_EVERYTHING_MENU_OPTION" desc="Name of the menu option which, when selected, causes all properties to be synced."> + <message name="IDS_SETTINGS_SYNC_EVERYTHING_CHECKBOX_LABEL" desc="Label for the checkbox which causes all properties to be synced."> Sync everything </message> - <message name="IDS_SETTINGS_CHOOSE_WHAT_TO_SYNC_MENU_OPTION" desc="Name of the menu option which, when selected, allows the user to select a subset of properties to be synced."> - Choose what to sync - </message> <message name="IDS_SETTINGS_APPS_CHECKBOX_LABEL" desc="Label for the checkbox which enables or disables syncing apps between multiple browser instances."> Apps </message>
diff --git a/chrome/app/theme/default_100_percent/common/notification_tray_attention.png b/chrome/app/theme/default_100_percent/common/notification_tray_attention.png deleted file mode 100644 index f7bff3bb..0000000 --- a/chrome/app/theme/default_100_percent/common/notification_tray_attention.png +++ /dev/null Binary files differ
diff --git a/chrome/app/theme/default_100_percent/common/notification_tray_do_not_disturb_attention.png b/chrome/app/theme/default_100_percent/common/notification_tray_do_not_disturb_attention.png deleted file mode 100644 index 6b4a2c4..0000000 --- a/chrome/app/theme/default_100_percent/common/notification_tray_do_not_disturb_attention.png +++ /dev/null Binary files differ
diff --git a/chrome/app/theme/default_100_percent/common/notification_tray_do_not_disturb_empty.png b/chrome/app/theme/default_100_percent/common/notification_tray_do_not_disturb_empty.png deleted file mode 100644 index c1e2bb0..0000000 --- a/chrome/app/theme/default_100_percent/common/notification_tray_do_not_disturb_empty.png +++ /dev/null Binary files differ
diff --git a/chrome/app/theme/default_100_percent/common/notification_tray_empty.png b/chrome/app/theme/default_100_percent/common/notification_tray_empty.png deleted file mode 100644 index 65ff93d..0000000 --- a/chrome/app/theme/default_100_percent/common/notification_tray_empty.png +++ /dev/null Binary files differ
diff --git a/chrome/app/theme/default_100_percent/common/discard_wide.png b/chrome/app/theme/default_100_percent/cros/discard_wide.png similarity index 100% rename from chrome/app/theme/default_100_percent/common/discard_wide.png rename to chrome/app/theme/default_100_percent/cros/discard_wide.png Binary files differ
diff --git a/chrome/app/theme/default_100_percent/common/downloads/cancel.png b/chrome/app/theme/default_100_percent/cros/downloads/cancel.png similarity index 100% rename from chrome/app/theme/default_100_percent/common/downloads/cancel.png rename to chrome/app/theme/default_100_percent/cros/downloads/cancel.png Binary files differ
diff --git a/chrome/app/theme/default_100_percent/common/downloads/delete.png b/chrome/app/theme/default_100_percent/cros/downloads/delete.png similarity index 100% rename from chrome/app/theme/default_100_percent/common/downloads/delete.png rename to chrome/app/theme/default_100_percent/cros/downloads/delete.png Binary files differ
diff --git a/chrome/app/theme/default_100_percent/common/downloads/download.png b/chrome/app/theme/default_100_percent/cros/downloads/download.png similarity index 100% rename from chrome/app/theme/default_100_percent/common/downloads/download.png rename to chrome/app/theme/default_100_percent/cros/downloads/download.png Binary files differ
diff --git a/chrome/app/theme/default_100_percent/common/downloads/folder.png b/chrome/app/theme/default_100_percent/cros/downloads/folder.png similarity index 100% rename from chrome/app/theme/default_100_percent/common/downloads/folder.png rename to chrome/app/theme/default_100_percent/cros/downloads/folder.png Binary files differ
diff --git a/chrome/app/theme/default_100_percent/common/downloads/pause.png b/chrome/app/theme/default_100_percent/cros/downloads/pause.png similarity index 100% rename from chrome/app/theme/default_100_percent/common/downloads/pause.png rename to chrome/app/theme/default_100_percent/cros/downloads/pause.png Binary files differ
diff --git a/chrome/app/theme/default_100_percent/common/snapshot_wide.png b/chrome/app/theme/default_100_percent/cros/snapshot_wide.png similarity index 100% rename from chrome/app/theme/default_100_percent/common/snapshot_wide.png rename to chrome/app/theme/default_100_percent/cros/snapshot_wide.png Binary files differ
diff --git a/chrome/app/theme/default_200_percent/common/notification_tray_attention.png b/chrome/app/theme/default_200_percent/common/notification_tray_attention.png deleted file mode 100644 index 13eec9b..0000000 --- a/chrome/app/theme/default_200_percent/common/notification_tray_attention.png +++ /dev/null Binary files differ
diff --git a/chrome/app/theme/default_200_percent/common/notification_tray_do_not_disturb_attention.png b/chrome/app/theme/default_200_percent/common/notification_tray_do_not_disturb_attention.png deleted file mode 100644 index 6f81568..0000000 --- a/chrome/app/theme/default_200_percent/common/notification_tray_do_not_disturb_attention.png +++ /dev/null Binary files differ
diff --git a/chrome/app/theme/default_200_percent/common/notification_tray_do_not_disturb_empty.png b/chrome/app/theme/default_200_percent/common/notification_tray_do_not_disturb_empty.png deleted file mode 100644 index 919cbd8..0000000 --- a/chrome/app/theme/default_200_percent/common/notification_tray_do_not_disturb_empty.png +++ /dev/null Binary files differ
diff --git a/chrome/app/theme/default_200_percent/common/notification_tray_empty.png b/chrome/app/theme/default_200_percent/common/notification_tray_empty.png deleted file mode 100644 index fcaf932..0000000 --- a/chrome/app/theme/default_200_percent/common/notification_tray_empty.png +++ /dev/null Binary files differ
diff --git a/chrome/app/theme/default_200_percent/common/discard_wide.png b/chrome/app/theme/default_200_percent/cros/discard_wide.png similarity index 100% rename from chrome/app/theme/default_200_percent/common/discard_wide.png rename to chrome/app/theme/default_200_percent/cros/discard_wide.png Binary files differ
diff --git a/chrome/app/theme/default_200_percent/common/downloads/cancel.png b/chrome/app/theme/default_200_percent/cros/downloads/cancel.png similarity index 100% rename from chrome/app/theme/default_200_percent/common/downloads/cancel.png rename to chrome/app/theme/default_200_percent/cros/downloads/cancel.png Binary files differ
diff --git a/chrome/app/theme/default_200_percent/common/downloads/delete.png b/chrome/app/theme/default_200_percent/cros/downloads/delete.png similarity index 100% rename from chrome/app/theme/default_200_percent/common/downloads/delete.png rename to chrome/app/theme/default_200_percent/cros/downloads/delete.png Binary files differ
diff --git a/chrome/app/theme/default_200_percent/common/downloads/download.png b/chrome/app/theme/default_200_percent/cros/downloads/download.png similarity index 100% rename from chrome/app/theme/default_200_percent/common/downloads/download.png rename to chrome/app/theme/default_200_percent/cros/downloads/download.png Binary files differ
diff --git a/chrome/app/theme/default_200_percent/common/downloads/folder.png b/chrome/app/theme/default_200_percent/cros/downloads/folder.png similarity index 100% rename from chrome/app/theme/default_200_percent/common/downloads/folder.png rename to chrome/app/theme/default_200_percent/cros/downloads/folder.png Binary files differ
diff --git a/chrome/app/theme/default_200_percent/common/downloads/pause.png b/chrome/app/theme/default_200_percent/cros/downloads/pause.png similarity index 100% rename from chrome/app/theme/default_200_percent/common/downloads/pause.png rename to chrome/app/theme/default_200_percent/cros/downloads/pause.png Binary files differ
diff --git a/chrome/app/theme/default_200_percent/common/snapshot_wide.png b/chrome/app/theme/default_200_percent/cros/snapshot_wide.png similarity index 100% rename from chrome/app/theme/default_200_percent/common/snapshot_wide.png rename to chrome/app/theme/default_200_percent/cros/snapshot_wide.png Binary files differ
diff --git a/chrome/app/theme/theme_resources.grd b/chrome/app/theme/theme_resources.grd index 261f3f4..77b7c33 100644 --- a/chrome/app/theme/theme_resources.grd +++ b/chrome/app/theme/theme_resources.grd
@@ -247,11 +247,11 @@ <structure type="chrome_scaled_image" name="IDR_DOWNLOAD_PROGRESS_BACKGROUND_32" file="common/download_progress_background32.png" /> <structure type="chrome_scaled_image" name="IDR_DOWNLOAD_PROGRESS_FOREGROUND_32" file="common/download_progress_foreground32.png" /> <if expr="chromeos"> - <structure type="chrome_scaled_image" name="IDR_DOWNLOAD_NOTIFICATION_MENU_CANCEL" file="common/downloads/cancel.png" /> - <structure type="chrome_scaled_image" name="IDR_DOWNLOAD_NOTIFICATION_MENU_DELETE" file="common/downloads/delete.png" /> - <structure type="chrome_scaled_image" name="IDR_DOWNLOAD_NOTIFICATION_MENU_DOWNLOAD" file="common/downloads/download.png" /> - <structure type="chrome_scaled_image" name="IDR_DOWNLOAD_NOTIFICATION_MENU_FOLDER" file="common/downloads/folder.png" /> - <structure type="chrome_scaled_image" name="IDR_DOWNLOAD_NOTIFICATION_MENU_PAUSE" file="common/downloads/pause.png" /> + <structure type="chrome_scaled_image" name="IDR_DOWNLOAD_NOTIFICATION_MENU_CANCEL" file="cros/downloads/cancel.png" /> + <structure type="chrome_scaled_image" name="IDR_DOWNLOAD_NOTIFICATION_MENU_DELETE" file="cros/downloads/delete.png" /> + <structure type="chrome_scaled_image" name="IDR_DOWNLOAD_NOTIFICATION_MENU_DOWNLOAD" file="cros/downloads/download.png" /> + <structure type="chrome_scaled_image" name="IDR_DOWNLOAD_NOTIFICATION_MENU_FOLDER" file="cros/downloads/folder.png" /> + <structure type="chrome_scaled_image" name="IDR_DOWNLOAD_NOTIFICATION_MENU_PAUSE" file="cros/downloads/pause.png" /> <structure type="chrome_scaled_image" name="IDR_ENABLE_DEBUGGING_FAILURE" file="cros/enable_debugging_failure.png" /> <structure type="chrome_scaled_image" name="IDR_ENABLE_DEBUGGING_SUCCESS" file="cros/enable_debugging_success.png" /> </if> @@ -421,8 +421,6 @@ <!-- TODO(nkostylev): This resource needs to be removed when cros login code is moved to ash. --> <structure type="chrome_scaled_image" name="IDR_LAUNCHER_BACKGROUND" file="cros/launcher_background.png" /> <structure type="chrome_scaled_image" name="IDR_LOGIN_PASSWORD_CAPS_LOCK" file="cros/login_password_capslock.png" /> - </if> - <if expr="chromeos"> <structure type="chrome_scaled_image" name="IDR_KIOSK_APP_USER_POD_ICON" file="cros/kiosk_app_user_pod_icon.png" /> <structure type="chrome_scaled_image" name="IDR_LEGACY_SUPERVISED_USER_ICON" file="cros/limited_user.png" /> </if> @@ -442,8 +440,6 @@ <structure type="chrome_scaled_image" name="IDR_MINIMIZE_BUTTON_MASK" file="common/minimize_button_mask.png" /> <if expr="chromeos"> <structure type="chrome_scaled_image" name="IDR_MIRROR_FLIP" file="cros/mirror_flip.png" /> - </if> - <if expr="chromeos"> <structure type="chrome_scaled_image" name="IDR_NETWORK_ADD_CONNECTION" file="cros/network_add_connection.png" /> <structure type="chrome_scaled_image" name="IDR_NETWORK_HIDE_PASSWORD" file="cros/network_hide_password.png" /> <structure type="chrome_scaled_image" name="IDR_NETWORK_HIDE_PASSWORD_HOVER" file="cros/network_hide_password_hover.png" /> @@ -471,12 +467,6 @@ <structure type="chrome_scaled_image" name="IDR_NOTIFICATION_PERIPHERAL_BATTERY_LOW" file="cros/notification_peripheral_battery_low.png" /> <structure type="chrome_scaled_image" name="IDR_PORTAL_DETECTION_ALERT" file="cros/captive_portal_icon.png" /> </if> - <if expr="is_win or desktop_linux"> - <structure type="chrome_scaled_image" name="IDR_NOTIFICATION_TRAY_DO_NOT_DISTURB_ATTENTION" file="common/notification_tray_do_not_disturb_attention.png" /> - <structure type="chrome_scaled_image" name="IDR_NOTIFICATION_TRAY_DO_NOT_DISTURB_EMPTY" file="common/notification_tray_do_not_disturb_empty.png" /> - <structure type="chrome_scaled_image" name="IDR_NOTIFICATION_TRAY_ATTENTION" file="common/notification_tray_attention.png" /> - <structure type="chrome_scaled_image" name="IDR_NOTIFICATION_TRAY_EMPTY" file="common/notification_tray_empty.png" /> - </if> <structure type="chrome_scaled_image" name="IDR_NOTIFICATION_WELCOME_ICON" file="common/notification_welcome_icon.png" /> <structure type="chrome_scaled_image" name="IDR_NOTIFICATION_WELCOME_LEARN_MORE" file="common/notification_welcome_learn_more.png" /> <structure type="chrome_scaled_image" name="IDR_NOTIFIER_BLOCK_BUTTON" file="common/block_notifier.png" /> @@ -976,8 +966,8 @@ <structure type="chrome_scaled_image" name="IDR_UPDATE_MENU_SEVERITY_HIGH" file="common/update_menu_severity_high.png" /> <structure type="chrome_scaled_image" name="IDR_USB_NOTIFICATION_ICON" file="common/notification_usb_icon.png" /> <if expr="chromeos"> - <structure type="chrome_scaled_image" name="IDR_USER_IMAGE_CAPTURE" file="common/snapshot_wide.png" /> - <structure type="chrome_scaled_image" name="IDR_USER_IMAGE_RECYCLE" file="common/discard_wide.png" /> + <structure type="chrome_scaled_image" name="IDR_USER_IMAGE_CAPTURE" file="cros/snapshot_wide.png" /> + <structure type="chrome_scaled_image" name="IDR_USER_IMAGE_RECYCLE" file="cros/discard_wide.png" /> </if> <structure type="chrome_scaled_image" name="IDR_WARNING" file="common/alert_small.png" /> <if expr="is_macosx"> @@ -1010,12 +1000,14 @@ </if> <!-- People search images --> - <structure type="chrome_scaled_image" name="IDR_PEOPLE_SEARCH_ACTION_EMAIL" file="common/mail.png" /> - <structure type="chrome_scaled_image" name="IDR_PEOPLE_SEARCH_ACTION_EMAIL_HOVER" file="common/mail_hover.png" /> - <structure type="chrome_scaled_image" name="IDR_PEOPLE_SEARCH_ACTION_EMAIL_PRESSED" file="common/mail_pressed.png" /> - <structure type="chrome_scaled_image" name="IDR_PEOPLE_SEARCH_ACTION_CHAT" file="common/chat.png" /> - <structure type="chrome_scaled_image" name="IDR_PEOPLE_SEARCH_ACTION_CHAT_HOVER" file="common/chat_hover.png" /> - <structure type="chrome_scaled_image" name="IDR_PEOPLE_SEARCH_ACTION_CHAT_PRESSED" file="common/chat_pressed.png" /> + <if expr="enable_app_list"> + <structure type="chrome_scaled_image" name="IDR_PEOPLE_SEARCH_ACTION_EMAIL" file="common/mail.png" /> + <structure type="chrome_scaled_image" name="IDR_PEOPLE_SEARCH_ACTION_EMAIL_HOVER" file="common/mail_hover.png" /> + <structure type="chrome_scaled_image" name="IDR_PEOPLE_SEARCH_ACTION_EMAIL_PRESSED" file="common/mail_pressed.png" /> + <structure type="chrome_scaled_image" name="IDR_PEOPLE_SEARCH_ACTION_CHAT" file="common/chat.png" /> + <structure type="chrome_scaled_image" name="IDR_PEOPLE_SEARCH_ACTION_CHAT_HOVER" file="common/chat_hover.png" /> + <structure type="chrome_scaled_image" name="IDR_PEOPLE_SEARCH_ACTION_CHAT_PRESSED" file="common/chat_pressed.png" /> + </if> </structures> </release> </grit>
diff --git a/chrome/browser/BUILD.gn b/chrome/browser/BUILD.gn index 22dc1a5..1a4b876 100644 --- a/chrome/browser/BUILD.gn +++ b/chrome/browser/BUILD.gn
@@ -276,6 +276,34 @@ sources += rebase_path(gypi_values.chrome_browser_web_resource_sources, ".", "//chrome") + if (android_java_ui) { + sources += + rebase_path(gypi_values.chrome_browser_sync_android_java_ui_sources, + ".", + "//chrome") + sources += + rebase_path(gypi_values.chrome_browser_ssl_android_java_ui_sources, + ".", + "//chrome") + sources += rebase_path( + gypi_values.chrome_browser_history_android_java_ui_sources, + ".", + "//chrome") + sources += rebase_path( + gypi_values.chrome_browser_permissions_android_java_ui_sources, + ".", + "//chrome") + sources += rebase_path( + gypi_values.chrome_browser_search_engines_android_java_ui_sources, + ".", + "//chrome") + if (enable_supervised_users) { + sources += rebase_path( + gypi_values.chrome_browser_supervised_user_android_java_ui_sources, + ".", + "//chrome") + } + } deps += [ "//apps", @@ -358,13 +386,6 @@ if (toolkit_views) { deps += [ "//ui/views" ] } - - if (is_android && use_aura) { - sources -= [ - # Aura Android uses platform_util_aura implementation. - "platform_util_android.cc", - ] - } } else { # iOS sources += rebase_path(gypi_values.chrome_browser_ios_sources, ".", "//chrome") @@ -622,7 +643,7 @@ } else { sources -= [ "password_manager/password_store_x.cc" ] } - if ((is_posix && !is_mac && !is_ios) || is_win) { + if (is_posix && !is_mac && !is_ios) { sources += [ "//chrome/app/chrome_crash_reporter_client.cc", "//chrome/app/chrome_crash_reporter_client.h", @@ -644,11 +665,11 @@ sources += rebase_path(gypi_values.chrome_browser_notifications_sources, ".", "//chrome") - if (is_android) { - sources += - rebase_path(gypi_values.chrome_browser_notifications_android_sources, - ".", - "//chrome") + if (android_java_ui) { + sources += rebase_path( + gypi_values.chrome_browser_notifications_android_java_ui_sources, + ".", + "//chrome") } else { sources += rebase_path( gypi_values.chrome_browser_notifications_non_android_sources, @@ -727,6 +748,12 @@ if (is_android) { sources += rebase_path(gypi_values.chrome_browser_android_sources, ".", "//chrome") + } + + if (android_java_ui) { + sources += rebase_path(gypi_values.chrome_browser_android_java_ui_sources, + ".", + "//chrome") sources += rebase_path(gypi_values.chrome_browser_bookmark_android_sources, ".", "//chrome") @@ -734,7 +761,6 @@ ":client_discourse_context_proto", ":delta_file_proto", ":jni_headers", - "//components/cdm/browser", "//components/data_usage/android", "//components/enhanced_bookmarks", "//components/precache/content", @@ -743,16 +769,25 @@ "//components/service_tab_launcher", "//components/toolbar", "//components/web_contents_delegate_android", + ] + + defines += [ "ENABLE_DATA_REDUCTION_PROXY_DEBUGGING" ] + } + + if (is_android) { + deps += [ + "//components/cdm/browser", + "//components/resources:components_resources", "//third_party/android_opengl/etc1", "//third_party/android_tools:cpu_features", "//third_party/libaddressinput:util", ] + deps -= [ "//components/storage_monitor", "//components/web_modal", "//third_party/libaddressinput", ] - defines += [ "ENABLE_DATA_REDUCTION_PROXY_DEBUGGING" ] if (use_seccomp_bpf) { defines += [ "USE_SECCOMP_BPF" ] @@ -924,7 +959,7 @@ } } -if (is_android) { +if (android_java_ui) { # GYP version: chrome/chrome_browser.gypi:chrome_browser_jni_headers generate_jni("jni_headers") { sources =
diff --git a/chrome/browser/about_flags.cc b/chrome/browser/about_flags.cc index bdd2f74..62afd84a 100644 --- a/chrome/browser/about_flags.cc +++ b/chrome/browser/about_flags.cc
@@ -13,6 +13,7 @@ #include "base/callback.h" #include "base/command_line.h" #include "base/feature_list.h" +#include "base/i18n/base_i18n_switches.h" #include "base/memory/singleton.h" #include "base/metrics/metrics_hashes.h" #include "base/metrics/sparse_histogram.h" @@ -67,15 +68,15 @@ #include "ui/message_center/message_center_switches.h" #endif -#if defined(USE_ASH) -#include "ash/ash_switches.h" -#endif - #if defined(OS_CHROMEOS) #include "chromeos/chromeos_switches.h" #include "third_party/cros_system_api/switches/chrome_switches.h" #endif +#if defined(OS_WIN) +#include "components/search_engines/desktop_search_win.h" +#endif // defined(OS_WIN) + #if defined(ENABLE_APP_LIST) #include "ui/app_list/app_list_switches.h" #endif @@ -88,6 +89,10 @@ #include "chrome/browser/ui/webui/print_preview/print_preview_distiller.h" #endif +#if defined(USE_ASH) +#include "ash/ash_switches.h" +#endif + #if defined(USE_OZONE) #include "ui/ozone/public/ozone_switches.h" #endif @@ -509,6 +514,14 @@ }; #endif // defined(OS_WIN) +const FeatureEntry::Choice kForceUIDirectionChoices[] = { + {IDS_GENERIC_EXPERIMENT_CHOICE_DEFAULT, "", ""}, + {IDS_FLAGS_FORCE_UI_DIRECTION_LTR, switches::kForceUIDirection, + switches::kForceUIDirectionLTR}, + {IDS_FLAGS_FORCE_UI_DIRECTION_RTL, switches::kForceUIDirection, + switches::kForceUIDirectionRTL}, +}; + // RECORDING USER METRICS FOR FLAGS: // ----------------------------------------------------------------------------- // The first line of the entry is the internal name. If you'd like to gather @@ -754,11 +767,6 @@ IDS_FLAGS_GPU_RASTERIZATION_MSAA_SAMPLE_COUNT_DESCRIPTION, kOsAll, MULTI_VALUE_TYPE(kGpuRasterizationMSAASampleCountChoices)}, - {"enable-slimming-paint-v2", - IDS_FLAGS_ENABLE_SLIMMING_PAINT_V2_NAME, - IDS_FLAGS_ENABLE_SLIMMING_PAINT_V2_DESCRIPTION, - kOsAll, - SINGLE_VALUE_TYPE(switches::kEnableSlimmingPaintV2)}, {"enable-experimental-web-platform-features", IDS_FLAGS_EXPERIMENTAL_WEB_PLATFORM_FEATURES_NAME, IDS_FLAGS_EXPERIMENTAL_WEB_PLATFORM_FEATURES_DESCRIPTION, @@ -2078,6 +2086,18 @@ IDS_FLAGS_ENABLE_MATERIAL_DESIGN_HISTORY_DESCRIPTION, kOsDesktop | kOsAndroid, SINGLE_VALUE_TYPE(switches::kEnableMaterialDesignHistory)}, +#if defined(OS_WIN) + {"enable-windows-desktop-search-redirection", + IDS_FLAGS_WINDOWS_DESKTOP_SEARCH_REDIRECTION_NAME, + IDS_FLAGS_WINDOWS_DESKTOP_SEARCH_REDIRECTION_DESCRIPTION, + kOsWin, + FEATURE_VALUE_TYPE(kWindowsDesktopSearchRedirectionFeature)}, +#endif // defined(OS_WIN) + {"force-ui-direction", + IDS_FLAGS_FORCE_UI_DIRECTION_NAME, + IDS_FLAGS_FORCE_UI_DIRECTION_DESCRIPTION, + kOsAll, + MULTI_VALUE_TYPE(kForceUIDirectionChoices)}, // NOTE: Adding new command-line switches requires adding corresponding // entries to enum "LoginCustomFlags" in histograms.xml. See note in // histograms.xml and don't forget to run AboutFlagsHistogramTest unit test.
diff --git a/chrome/browser/android/compositor/scene_layer/static_tab_scene_layer.cc b/chrome/browser/android/compositor/scene_layer/static_tab_scene_layer.cc index 26d7e8a..715d9c6a 100644 --- a/chrome/browser/android/compositor/scene_layer/static_tab_scene_layer.cc +++ b/chrome/browser/android/compositor/scene_layer/static_tab_scene_layer.cc
@@ -127,14 +127,24 @@ const JavaParamRef<jobject>& jobj, const JavaParamRef<jobject>& jcontent_scene_layer) { SceneLayer* content_scene_layer = FromJavaObject(env, jcontent_scene_layer); - if (content_scene_layer && content_scene_layer->layer()) { - content_scene_layer_ = content_scene_layer->layer(); - if (content_scene_layer_.get()) - layer_->AddChild(content_scene_layer_); - } else if (content_scene_layer_) { + scoped_refptr<cc::Layer> layer = content_scene_layer ? + content_scene_layer->layer() : nullptr; + + if (content_scene_layer_ && content_scene_layer_ != layer) { content_scene_layer_->RemoveFromParent(); content_scene_layer_ = nullptr; } + + // TODO(pedrosimonetti): Consider being smarter with regards to when to + // add the layer to the hierarchy. For now, we need to keep adding the + // content_scene_layer on every frame because the content_layer is also + // added on every frame. This means that if we only add it once, the + // content_layer will be added again on the next frame and will + // occlude the content_scene_layer. + if (layer) { + content_scene_layer_ = layer; + layer_->AddChild(layer); + } } static jlong Init(JNIEnv* env, const JavaParamRef<jobject>& jobj) {
diff --git a/chrome/browser/android/most_visited_sites.cc b/chrome/browser/android/most_visited_sites.cc index 15bc063..c3001eb3 100644 --- a/chrome/browser/android/most_visited_sites.cc +++ b/chrome/browser/android/most_visited_sites.cc
@@ -82,12 +82,6 @@ ICON_COLOR, // The item displays a default gray box in place of an icon. ICON_DEFAULT, - // The item displays a locally-captured thumbnail of the site content. - THUMBNAIL_LOCAL, - // The item displays a server-provided thumbnail of the site content. - THUMBNAIL_SERVER, - // The item displays a default graphic in place of a thumbnail. - THUMBNAIL_DEFAULT, NUM_TILE_TYPES, }; @@ -379,8 +373,7 @@ void MostVisitedSites::RecordTileTypeMetrics( JNIEnv* env, const JavaParamRef<jobject>& obj, - const JavaParamRef<jintArray>& jtile_types, - jboolean is_icon_mode) { + const JavaParamRef<jintArray>& jtile_types) { std::vector<int> tile_types; base::android::JavaIntArrayToIntVector(env, jtile_types, &tile_types); DCHECK_EQ(current_suggestions_.size(), tile_types.size()); @@ -395,21 +388,12 @@ LogHistogramEvent(histogram, tile_type, NUM_TILE_TYPES); } - if (is_icon_mode) { - UMA_HISTOGRAM_SPARSE_SLOWLY("NewTabPage.IconsReal", - counts_per_type[ICON_REAL]); - UMA_HISTOGRAM_SPARSE_SLOWLY("NewTabPage.IconsColor", - counts_per_type[ICON_COLOR]); - UMA_HISTOGRAM_SPARSE_SLOWLY("NewTabPage.IconsGray", - counts_per_type[ICON_DEFAULT]); - } else { - UMA_HISTOGRAM_SPARSE_SLOWLY("NewTabPage.NumberOfThumbnailTiles", - counts_per_type[THUMBNAIL_LOCAL]); - UMA_HISTOGRAM_SPARSE_SLOWLY("NewTabPage.NumberOfExternalTiles", - counts_per_type[THUMBNAIL_SERVER]); - UMA_HISTOGRAM_SPARSE_SLOWLY("NewTabPage.NumberOfGrayTiles", - counts_per_type[THUMBNAIL_DEFAULT]); - } + UMA_HISTOGRAM_SPARSE_SLOWLY("NewTabPage.IconsReal", + counts_per_type[ICON_REAL]); + UMA_HISTOGRAM_SPARSE_SLOWLY("NewTabPage.IconsColor", + counts_per_type[ICON_COLOR]); + UMA_HISTOGRAM_SPARSE_SLOWLY("NewTabPage.IconsGray", + counts_per_type[ICON_DEFAULT]); } void MostVisitedSites::RecordOpenedMostVisitedItem(
diff --git a/chrome/browser/android/most_visited_sites.h b/chrome/browser/android/most_visited_sites.h index 9a0bb35..b921d21 100644 --- a/chrome/browser/android/most_visited_sites.h +++ b/chrome/browser/android/most_visited_sites.h
@@ -54,8 +54,7 @@ void RecordTileTypeMetrics( JNIEnv* env, const base::android::JavaParamRef<jobject>& obj, - const base::android::JavaParamRef<jintArray>& jtile_types, - jboolean is_icon_mode); + const base::android::JavaParamRef<jintArray>& jtile_types); void RecordOpenedMostVisitedItem( JNIEnv* env, const base::android::JavaParamRef<jobject>& obj,
diff --git a/chrome/browser/apps/guest_view/web_view_browsertest.cc b/chrome/browser/apps/guest_view/web_view_browsertest.cc index 337b21f..1cb92bd9 100644 --- a/chrome/browser/apps/guest_view/web_view_browsertest.cc +++ b/chrome/browser/apps/guest_view/web_view_browsertest.cc
@@ -1076,6 +1076,14 @@ NO_TEST_SERVER); } +IN_PROC_BROWSER_TEST_F( + WebViewTest, + Shim_TestExecuteScriptIsAbortedWhenWebViewSourceIsInvalid) { + TestHelper("testExecuteScriptIsAbortedWhenWebViewSourceIsInvalid", + "web_view/shim", + NO_TEST_SERVER); +} + IN_PROC_BROWSER_TEST_F(WebViewTest, Shim_TestTerminateAfterExit) { TestHelper("testTerminateAfterExit", "web_view/shim", NO_TEST_SERVER); }
diff --git a/chrome/browser/autofill/autofill_interactive_uitest.cc b/chrome/browser/autofill/autofill_interactive_uitest.cc index c8b9980..51f13be 100644 --- a/chrome/browser/autofill/autofill_interactive_uitest.cc +++ b/chrome/browser/autofill/autofill_interactive_uitest.cc
@@ -52,6 +52,7 @@ #include "net/url_request/url_request_status.h" #include "testing/gmock/include/gmock/gmock.h" #include "testing/gtest/include/gtest/gtest.h" +#include "ui/base/clipboard/scoped_clipboard_writer.h" #include "ui/events/keycodes/keyboard_codes.h" using base::ASCIIToUTF16; @@ -89,14 +90,26 @@ "<label for=\"phone\">Phone number:</label>" " <input type=\"text\" id=\"phone\"><br>" "</form>"; - +static const char kTestPasswordFormString[] = + "<form>" + "<label for=\"user\">User:</label>" + " <input id=\"user\" type=\"text\" name=\"name\"" + "onfocus=\"domAutomationController.send(true)\">" + "<br>" + "<label for=\"password\">Password:</label>" + " <input id=\"password\" type=\"password\" name=\"password\"" + "onfocus=\"domAutomationController.send(true)\">" + "<br>" + "<input type=\"submit\" value=\"Submit\">" + "</form>"; // AutofillManagerTestDelegateImpl -------------------------------------------- class AutofillManagerTestDelegateImpl : public autofill::AutofillManagerTestDelegate { public: - AutofillManagerTestDelegateImpl() {} + AutofillManagerTestDelegateImpl() + : waiting_for_text_change_(false) {} ~AutofillManagerTestDelegateImpl() override {} // autofill::AutofillManagerTestDelegate: @@ -115,6 +128,14 @@ loop_runner_->Quit(); } + void OnTextFieldChanged() override { + if (!waiting_for_text_change_) + return; + waiting_for_text_change_ = false; + ASSERT_TRUE(loop_runner_->loop_running()); + loop_runner_->Quit(); + } + void Reset() { loop_runner_ = new content::MessageLoopRunner(); } @@ -123,8 +144,14 @@ loop_runner_->Run(); } + void WaitForTextChange() { + waiting_for_text_change_ = true; + loop_runner_->Run(); + } + private: scoped_refptr<content::MessageLoopRunner> loop_runner_; + bool waiting_for_text_change_; DISALLOW_COPY_AND_ASSIGN(AutofillManagerTestDelegateImpl); }; @@ -263,6 +290,18 @@ fetcher->delegate()->OnURLFetchComplete(fetcher); } + void FocusFieldByName(const std::string& name) { + bool result = false; + ASSERT_TRUE(content::ExecuteScriptAndExtractBool( + GetRenderViewHost(), + "if (document.readyState === 'complete')" + " document.getElementById('" + name + "').focus();" + "else" + " domAutomationController.send(false);", + &result)); + ASSERT_TRUE(result); + } + void FocusFirstNameField() { bool result = false; ASSERT_TRUE(content::ExecuteScriptAndExtractBool( @@ -333,6 +372,16 @@ test_delegate_.Wait(); } + void PasteStringAndWait(const std::string& pastedata) { + { + ui::ScopedClipboardWriter writer(ui::CLIPBOARD_TYPE_COPY_PASTE); + writer.WriteText(base::ASCIIToUTF16(pastedata)); + } + test_delegate_.Reset(); + GetWebContents()->Paste(); + test_delegate_.WaitForTextChange(); + } + bool HandleKeyPressEvent(const content::NativeWebKeyboardEvent& event) { return true; } @@ -1396,4 +1445,15 @@ SendKeyToPopupAndWait(ui::VKEY_DOWN); } +IN_PROC_BROWSER_TEST_F(AutofillInteractiveTest, + PastedPasswordIsSaved) { + ASSERT_NO_FATAL_FAILURE(ui_test_utils::NavigateToURL(browser(), + GURL(std::string(kDataURIPrefix) + kTestPasswordFormString))); + ASSERT_TRUE(content::ExecuteScript( + GetRenderViewHost(), + "document.getElementById('user').value = 'user';")); + FocusFieldByName("password"); + PasteStringAndWait("foobar"); +} + } // namespace autofill
diff --git a/chrome/browser/background_sync/background_sync_controller_impl.cc b/chrome/browser/background_sync/background_sync_controller_impl.cc index 895f8aeb..3c9238b7 100644 --- a/chrome/browser/background_sync/background_sync_controller_impl.cc +++ b/chrome/browser/background_sync/background_sync_controller_impl.cc
@@ -6,9 +6,10 @@ #include "chrome/browser/browser_process.h" #include "chrome/browser/profiles/profile.h" +#include "chrome/common/features.h" #include "components/rappor/rappor_utils.h" -#if defined(OS_ANDROID) +#if BUILDFLAG(ANDROID_JAVA_UI) #include "chrome/browser/android/background_sync_launcher_android.h" #endif @@ -39,7 +40,7 @@ if (profile_->IsOffTheRecord()) return; -#if defined(OS_ANDROID) +#if BUILDFLAG(ANDROID_JAVA_UI) BackgroundSyncLauncherAndroid::LaunchBrowserIfStopped(enabled, min_ms); #else // TODO(jkarlin): Use BackgroundModeManager to enter background mode. See
diff --git a/chrome/browser/banners/app_banner_data_fetcher.cc b/chrome/browser/banners/app_banner_data_fetcher.cc index 0090d10..321e8d3e 100644 --- a/chrome/browser/banners/app_banner_data_fetcher.cc +++ b/chrome/browser/banners/app_banner_data_fetcher.cc
@@ -188,6 +188,9 @@ return; } + AppBannerSettingsHelper::RecordMinutesFromFirstVisitToShow( + web_contents, validated_url_, GetAppIdentifier(), GetCurrentTime()); + // Definitely going to show the banner now. FOR_EACH_OBSERVER(Observer, observer_list_, OnDecidedWhetherToShow(this, true));
diff --git a/chrome/browser/banners/app_banner_data_fetcher_browsertest.cc b/chrome/browser/banners/app_banner_data_fetcher_browsertest.cc index b37df5f..c868268 100644 --- a/chrome/browser/banners/app_banner_data_fetcher_browsertest.cc +++ b/chrome/browser/banners/app_banner_data_fetcher_browsertest.cc
@@ -9,8 +9,10 @@ #include "base/run_loop.h" #include "base/single_thread_task_runner.h" #include "base/task_runner.h" +#include "base/test/histogram_tester.h" #include "base/thread_task_runner_handle.h" #include "chrome/browser/banners/app_banner_data_fetcher_desktop.h" +#include "chrome/browser/banners/app_banner_metrics.h" #include "chrome/browser/banners/app_banner_settings_helper.h" #include "chrome/browser/ui/browser.h" #include "chrome/browser/ui/tabs/tab_strip_model.h" @@ -97,6 +99,7 @@ weak_factory_.GetWeakPtr(), 128, 128)); + base::HistogramTester histograms; base::RunLoop run_loop; quit_closure_ = run_loop.QuitClosure(); scoped_ptr<TestObserver> observer(new TestObserver(fetcher.get(), @@ -107,6 +110,10 @@ EXPECT_EQ(expected_non_web_platform, non_web_platform_); EXPECT_EQ(expected_to_show, observer->will_show()); ASSERT_FALSE(fetcher->is_active()); + + // If showing the banner, ensure that the minutes histogram is recorded. + histograms.ExpectTotalCount(banners::kMinutesHistogram, + (observer->will_show() ? 1 : 0)); } void RunBannerTest(const std::string& manifest_page,
diff --git a/chrome/browser/banners/app_banner_metrics.cc b/chrome/browser/banners/app_banner_metrics.cc index 5ab6f59a..f9bbd34 100644 --- a/chrome/browser/banners/app_banner_metrics.cc +++ b/chrome/browser/banners/app_banner_metrics.cc
@@ -4,32 +4,48 @@ #include "chrome/browser/banners/app_banner_metrics.h" +#include "base/metrics/histogram_macros.h" #include "base/metrics/sparse_histogram.h" namespace banners { +const char kDismissEventHistogram[] = "AppBanners.DismissEvent"; +const char kDisplayEventHistogram[] = "AppBanners.DisplayEvent"; +const char kInstallEventHistogram[] = "AppBanners.InstallEvent"; +const char kMinutesHistogram[] = + "AppBanners.MinutesFromFirstVisitToBannerShown"; +const char kUserResponseHistogram[] = "AppBanners.UserResponse"; + void TrackDismissEvent(int event) { DCHECK_LT(DISMISS_EVENT_MIN, event); DCHECK_LT(event, DISMISS_EVENT_MAX); - UMA_HISTOGRAM_SPARSE_SLOWLY("AppBanners.DismissEvent", event); + UMA_HISTOGRAM_SPARSE_SLOWLY(kDismissEventHistogram, event); } void TrackDisplayEvent(int event) { DCHECK_LT(DISPLAY_EVENT_MIN, event); DCHECK_LT(event, DISPLAY_EVENT_MAX); - UMA_HISTOGRAM_SPARSE_SLOWLY("AppBanners.DisplayEvent", event); + UMA_HISTOGRAM_SPARSE_SLOWLY(kDisplayEventHistogram, event); } void TrackInstallEvent(int event) { DCHECK_LT(INSTALL_EVENT_MIN, event); DCHECK_LT(event, INSTALL_EVENT_MAX); - UMA_HISTOGRAM_SPARSE_SLOWLY("AppBanners.InstallEvent", event); + UMA_HISTOGRAM_SPARSE_SLOWLY(kInstallEventHistogram, event); +} + +void TrackMinutesFromFirstVisitToBannerShown(int minutes) { + // Histogram ranges from 1 minute to the number of minutes in 21 days. + // This is one more day than the decay length of time for site engagement, + // and seven more days than the expiry of visits for the app banner + // navigation heuristic. + UMA_HISTOGRAM_CUSTOM_COUNTS(kMinutesHistogram, minutes, 1, 30240, 100); } void TrackUserResponse(int event) { DCHECK_LT(USER_RESPONSE_MIN, event); DCHECK_LT(event, USER_RESPONSE_MAX); - UMA_HISTOGRAM_SPARSE_SLOWLY("AppBanners.UserResponse", event); + UMA_HISTOGRAM_SPARSE_SLOWLY(kUserResponseHistogram, event); } } // namespace banners
diff --git a/chrome/browser/banners/app_banner_metrics.h b/chrome/browser/banners/app_banner_metrics.h index 7c781792..0b0939ee 100644 --- a/chrome/browser/banners/app_banner_metrics.h +++ b/chrome/browser/banners/app_banner_metrics.h
@@ -57,9 +57,16 @@ USER_RESPONSE_MAX = 7, }; +extern const char kDismissEventHistogram[]; +extern const char kDisplayEventHistogram[]; +extern const char kInstallEventHistogram[]; +extern const char kMinutesHistogram[]; +extern const char kUserResponseHistogram[]; + void TrackDismissEvent(int event); void TrackDisplayEvent(int event); void TrackInstallEvent(int event); +void TrackMinutesFromFirstVisitToBannerShown(int minutes); void TrackUserResponse(int event); }; // namespace banners
diff --git a/chrome/browser/banners/app_banner_settings_helper.cc b/chrome/browser/banners/app_banner_settings_helper.cc index 2f0bb43..aca24f6 100644 --- a/chrome/browser/banners/app_banner_settings_helper.cc +++ b/chrome/browser/banners/app_banner_settings_helper.cc
@@ -8,11 +8,14 @@ #include <string> #include "base/command_line.h" +#include "base/metrics/field_trial.h" #include "base/strings/string_number_conversions.h" +#include "base/strings/string_util.h" #include "chrome/browser/banners/app_banner_data_fetcher.h" #include "chrome/browser/banners/app_banner_metrics.h" #include "chrome/browser/browser_process.h" #include "chrome/browser/content_settings/host_content_settings_map_factory.h" +#include "chrome/browser/engagement/site_engagement_service.h" #include "chrome/browser/profiles/profile.h" #include "chrome/common/chrome_switches.h" #include "components/content_settings/core/browser/host_content_settings_map.h" @@ -63,9 +66,11 @@ const char kBannerParamsIndirectKey[] = "indirect"; const char kBannerParamsTotalKey[] = "total"; const char kBannerParamsMinutesKey[] = "minutes"; +const char kBannerSiteEngagementParamsKey[] = "app_banner_triggering"; +const char kBannerSiteEngagementParamsTotalKey[] = + "app_banner_triggering_total"; -// Total site engagements where a banner could have been shown before -// a banner will actually be triggered. +// Total engagement score required before a banner will actually be triggered. double gTotalEngagementToTrigger = 2; // Engagement weight assigned to direct and indirect navigations. @@ -115,10 +120,26 @@ } } +// Queries variations for the maximum site engagement score required to trigger +// the banner showing. +void UpdateSiteEngagementToTrigger() { + std::string total_param = variations::GetVariationParamValue( + SiteEngagementService::kEngagementParams, + kBannerSiteEngagementParamsTotalKey); + + if (!total_param.empty()) { + double total_engagement = -1; + + if (base::StringToDouble(total_param, &total_engagement) && + total_engagement > 0) { + AppBannerSettingsHelper::SetTotalEngagementToTrigger(total_engagement); + } + } +} + // Queries variations for updates to the default engagement values assigned // to direct and indirect navigations. void UpdateEngagementWeights() { - std::map<std::string, std::string> params; std::string direct_param = variations::GetVariationParamValue( kBannerParamsKey, kBannerParamsDirectKey); std::string indirect_param = variations::GetVariationParamValue( @@ -160,6 +181,16 @@ } } +// Returns the site engagement karma score for the given origin URL under the +// current profile. +double GetSiteEngagementScoreForOrigin( + content::WebContents* web_contents, + const GURL& origin_url) { + SiteEngagementService* service = SiteEngagementService::Get( + Profile::FromBrowserContext(web_contents->GetBrowserContext())); + return service ? service->GetScore(origin_url) : 0; +} + } // namespace void AppBannerSettingsHelper::ClearHistoryForURLs( @@ -352,6 +383,10 @@ return true; } + // Never show a banner when the package name or URL is empty. + if (package_name_or_start_url.empty()) + return false; + // Don't show if it has been added to the homescreen. base::Time added_time = GetSingleBannerEvent(web_contents, origin_url, package_name_or_start_url, @@ -382,14 +417,17 @@ return false; } - std::vector<BannerEvent> could_show_events = GetCouldShowBannerEvents( - web_contents, origin_url, package_name_or_start_url); - - // Return true if the total engagement of each applicable could show event - // meets the trigger threshold. double total_engagement = 0; - for (const auto& event : could_show_events) - total_engagement += event.engagement; + if (ShouldUseSiteEngagementScore()) { + total_engagement = + GetSiteEngagementScoreForOrigin(web_contents, origin_url); + } else { + std::vector<BannerEvent> could_show_events = GetCouldShowBannerEvents( + web_contents, origin_url, package_name_or_start_url); + + for (const auto& event : could_show_events) + total_engagement += event.engagement; + } if (total_engagement < gTotalEngagementToTrigger) { banners::TrackDisplayEvent(banners::DISPLAY_EVENT_NOT_VISITED_ENOUGH); @@ -405,8 +443,6 @@ const GURL& origin_url, const std::string& package_name_or_start_url) { std::vector<BannerEvent> result; - if (package_name_or_start_url.empty()) - return result; Profile* profile = Profile::FromBrowserContext(web_contents->GetBrowserContext()); @@ -454,9 +490,6 @@ DCHECK(event != APP_BANNER_EVENT_COULD_SHOW); DCHECK(event < APP_BANNER_EVENT_NUM_EVENTS); - if (package_name_or_start_url.empty()) - return base::Time(); - Profile* profile = Profile::FromBrowserContext(web_contents->GetBrowserContext()); HostContentSettingsMap* settings = @@ -480,6 +513,21 @@ return base::Time::FromInternalValue(internal_time); } +void AppBannerSettingsHelper::RecordMinutesFromFirstVisitToShow( + content::WebContents* web_contents, + const GURL& origin_url, + const std::string& package_name_or_start_url, + base::Time time) { + std::vector<BannerEvent> could_show_events = GetCouldShowBannerEvents( + web_contents, origin_url, package_name_or_start_url); + + int minutes = 0; + if (could_show_events.size()) + minutes = (time - could_show_events[0].time).InMinutes(); + + banners::TrackMinutesFromFirstVisitToBannerShown(minutes); +} + void AppBannerSettingsHelper::SetEngagementWeights(double direct_engagement, double indirect_engagement) { gDirectNavigationEngagement = direct_engagement; @@ -523,6 +571,32 @@ } void AppBannerSettingsHelper::UpdateFromFieldTrial() { - UpdateEngagementWeights(); - UpdateMinutesBetweenVisits(); + // If we are using the site engagement score, only extract the total + // engagement to trigger from the params variations. + if (ShouldUseSiteEngagementScore()) { + UpdateSiteEngagementToTrigger(); + } else { + UpdateEngagementWeights(); + UpdateMinutesBetweenVisits(); + } +} + +bool AppBannerSettingsHelper::ShouldUseSiteEngagementScore() { + if (base::CommandLine::ForCurrentProcess()->HasSwitch( + switches::kEnableSiteEngagementAppBanner)) { + return true; + } + + // This experiment is controlled under the same key as the broader site + // engagement experiment rather than the banner experiment. This avoids cross + // pollution with other site engagement experiments. However, this experiment + // must only be active when there is one singular group under the banner + // experiment, otherwise the banner and site engagement banner experiments + // will conflict. + // + // Making the experiment active when a variations key is present allows us + // to have experiments which enable multiple features under site engagement. + std::string param = variations::GetVariationParamValue( + SiteEngagementService::kEngagementParams, kBannerSiteEngagementParamsKey); + return !param.empty(); }
diff --git a/chrome/browser/banners/app_banner_settings_helper.h b/chrome/browser/banners/app_banner_settings_helper.h index 3ff877c0..b46bc168 100644 --- a/chrome/browser/banners/app_banner_settings_helper.h +++ b/chrome/browser/banners/app_banner_settings_helper.h
@@ -117,6 +117,14 @@ const std::string& package_name_or_start_url, AppBannerEvent event); + // Record a UMA statistic measuring the minutes between the first visit to the + // site and the first showing of the banner. + static void RecordMinutesFromFirstVisitToShow( + content::WebContents* web_contents, + const GURL& origin_url, + const std::string& package_name_or_start_url, + base::Time time); + // Set the engagement weights assigned to direct and indirect navigations. static void SetEngagementWeights(double direct_engagement, double indirect_engagement); @@ -137,6 +145,10 @@ // Updates all values from field trial. static void UpdateFromFieldTrial(); + // Returns true if the app banner trigger condition should use the site + // engagement score instead of the navigation-based heuristic. + static bool ShouldUseSiteEngagementScore(); + private: DISALLOW_IMPLICIT_CONSTRUCTORS(AppBannerSettingsHelper); };
diff --git a/chrome/browser/banners/app_banner_settings_helper_unittest.cc b/chrome/browser/banners/app_banner_settings_helper_unittest.cc index 82550f1..254758a 100644 --- a/chrome/browser/banners/app_banner_settings_helper_unittest.cc +++ b/chrome/browser/banners/app_banner_settings_helper_unittest.cc
@@ -4,8 +4,14 @@ #include <vector> +#include "base/command_line.h" +#include "chrome/browser/banners/app_banner_metrics.h" #include "chrome/browser/banners/app_banner_settings_helper.h" +#include "chrome/browser/engagement/site_engagement_service.h" +#include "chrome/browser/engagement/site_engagement_service_factory.h" +#include "chrome/common/chrome_switches.h" #include "chrome/test/base/chrome_render_view_host_test_harness.h" +#include "chrome/test/base/testing_profile.h" #include "ui/base/page_transition_types.h" namespace { @@ -731,3 +737,93 @@ EXPECT_TRUE(AppBannerSettingsHelper::ShouldShowBanner( web_contents(), url, kTestPackageName, reference_time)); } + +TEST_F(AppBannerSettingsHelperTest, ShouldShowWithHigherTotal) { + AppBannerSettingsHelper::SetEngagementWeights(1, 1); + AppBannerSettingsHelper::SetTotalEngagementToTrigger(5); + GURL url(kTestURL); + NavigateAndCommit(url); + + base::Time reference_time = GetReferenceTime(); + base::Time second_day = reference_time + base::TimeDelta::FromDays(1); + base::Time third_day = reference_time + base::TimeDelta::FromDays(2); + base::Time fourth_day = reference_time + base::TimeDelta::FromDays(3); + base::Time fifth_day = reference_time + base::TimeDelta::FromDays(4); + + EXPECT_FALSE(AppBannerSettingsHelper::ShouldShowBanner( + web_contents(), url, kTestPackageName, reference_time)); + + // It should take five visits to trigger the banner. + AppBannerSettingsHelper::RecordBannerCouldShowEvent( + web_contents(), url, kTestPackageName, reference_time, + ui::PAGE_TRANSITION_LINK); + EXPECT_FALSE(AppBannerSettingsHelper::ShouldShowBanner( + web_contents(), url, kTestPackageName, reference_time)); + + AppBannerSettingsHelper::RecordBannerCouldShowEvent( + web_contents(), url, kTestPackageName, second_day, + ui::PAGE_TRANSITION_TYPED); + EXPECT_FALSE(AppBannerSettingsHelper::ShouldShowBanner( + web_contents(), url, kTestPackageName, second_day)); + + AppBannerSettingsHelper::RecordBannerCouldShowEvent( + web_contents(), url, kTestPackageName, third_day, + ui::PAGE_TRANSITION_GENERATED); + EXPECT_FALSE(AppBannerSettingsHelper::ShouldShowBanner( + web_contents(), url, kTestPackageName, third_day)); + + AppBannerSettingsHelper::RecordBannerCouldShowEvent( + web_contents(), url, kTestPackageName, fourth_day, + ui::PAGE_TRANSITION_LINK); + EXPECT_FALSE(AppBannerSettingsHelper::ShouldShowBanner( + web_contents(), url, kTestPackageName, fourth_day)); + + // Visit the site again; now it should be shown. + AppBannerSettingsHelper::RecordBannerCouldShowEvent( + web_contents(), url, kTestPackageName, fifth_day, + ui::PAGE_TRANSITION_TYPED); + EXPECT_TRUE(AppBannerSettingsHelper::ShouldShowBanner( + web_contents(), url, kTestPackageName, fifth_day)); +} + +// Test that the banner triggers correctly using site engagement. +TEST_F(AppBannerSettingsHelperTest, SiteEngagementTrigger) { + AppBannerSettingsHelper::SetTotalEngagementToTrigger(2); + base::CommandLine* command_line = base::CommandLine::ForCurrentProcess(); + command_line->AppendSwitch(switches::kEnableSiteEngagementAppBanner); + + SiteEngagementService* service = + SiteEngagementServiceFactory::GetForProfile(profile()); + DCHECK(service); + + // Not used, but needed for method call. + base::Time reference_time = GetReferenceTime(); + GURL url(kTestURL); + + EXPECT_FALSE(AppBannerSettingsHelper::ShouldShowBanner( + web_contents(), url, kTestPackageName, reference_time)); + + service->AddPoints(url, 1); + EXPECT_FALSE(AppBannerSettingsHelper::ShouldShowBanner( + web_contents(), url, kTestPackageName, reference_time)); + + service->AddPoints(url, 1); + EXPECT_TRUE(AppBannerSettingsHelper::ShouldShowBanner( + web_contents(), url, kTestPackageName, reference_time)); + + AppBannerSettingsHelper::SetTotalEngagementToTrigger(5); + EXPECT_FALSE(AppBannerSettingsHelper::ShouldShowBanner( + web_contents(), url, kTestPackageName, reference_time)); + + service->AddPoints(url, 1.5); + EXPECT_FALSE(AppBannerSettingsHelper::ShouldShowBanner( + web_contents(), url, kTestPackageName, reference_time)); + + service->AddPoints(url, 0.5); + EXPECT_FALSE(AppBannerSettingsHelper::ShouldShowBanner( + web_contents(), url, kTestPackageName, reference_time)); + + service->AddPoints(url, 1.5); + EXPECT_TRUE(AppBannerSettingsHelper::ShouldShowBanner( + web_contents(), url, kTestPackageName, reference_time)); +}
diff --git a/chrome/browser/bookmarks/bookmark_model_factory.cc b/chrome/browser/bookmarks/bookmark_model_factory.cc index b4be798b5..faef18ce 100644 --- a/chrome/browser/bookmarks/bookmark_model_factory.cc +++ b/chrome/browser/bookmarks/bookmark_model_factory.cc
@@ -16,6 +16,7 @@ #include "chrome/browser/profiles/profile.h" #include "chrome/browser/undo/bookmark_undo_service_factory.h" #include "chrome/common/chrome_switches.h" +#include "chrome/common/features.h" #include "chrome/common/pref_names.h" #include "components/bookmarks/browser/bookmark_model.h" #include "components/bookmarks/browser/bookmark_utils.h" @@ -24,11 +25,11 @@ #include "components/undo/bookmark_undo_service.h" #include "content/public/browser/browser_thread.h" -#if defined(OS_ANDROID) +#if BUILDFLAG(ANDROID_JAVA_UI) #include "chrome/browser/android/offline_pages/offline_page_model_factory.h" #include "components/offline_pages/offline_page_feature.h" #include "components/offline_pages/offline_page_model.h" -#endif // defined(OS_ANDROID) +#endif // BUILDFLAG(ANDROID_JAVA_UI) using bookmarks::BookmarkModel; @@ -56,7 +57,7 @@ DependsOn(BookmarkUndoServiceFactory::GetInstance()); DependsOn(ChromeBookmarkClientFactory::GetInstance()); DependsOn(StartupTaskRunnerServiceFactory::GetInstance()); -#if defined(OS_ANDROID) +#if BUILDFLAG(ANDROID_JAVA_UI) if (offline_pages::IsOfflinePagesEnabled()) DependsOn(offline_pages::OfflinePageModelFactory::GetInstance()); #endif @@ -80,20 +81,20 @@ content::BrowserThread::GetMessageLoopProxyForThread( content::BrowserThread::UI)); bool register_bookmark_undo_service_as_observer = true; -#if !defined(OS_IOS) && !defined(OS_ANDROID) +#if !defined(OS_IOS) && !BUILDFLAG(ANDROID_JAVA_UI) register_bookmark_undo_service_as_observer = base::CommandLine::ForCurrentProcess()->HasSwitch( switches::kEnableBookmarkUndo); -#endif // !defined(OS_IOS) && !defined(OS_ANDROID) +#endif // !defined(OS_IOS) && !BUILDFLAG(ANDROID_JAVA_UI) if (register_bookmark_undo_service_as_observer) BookmarkUndoServiceFactory::GetForProfile(profile)->Start(bookmark_model); -#if defined(OS_ANDROID) +#if BUILDFLAG(ANDROID_JAVA_UI) if (offline_pages::IsOfflinePagesEnabled()) { offline_pages::OfflinePageModelFactory::GetForBrowserContext(profile)-> Start(bookmark_model); } -#endif // defined(OS_ANDROID) +#endif // BUILDFLAG(ANDROID_JAVA_UI) return bookmark_model; }
diff --git a/chrome/browser/browser_process_impl.cc b/chrome/browser/browser_process_impl.cc index 603dff56..467f552 100644 --- a/chrome/browser/browser_process_impl.cc +++ b/chrome/browser/browser_process_impl.cc
@@ -69,6 +69,7 @@ #include "chrome/common/chrome_paths.h" #include "chrome/common/chrome_switches.h" #include "chrome/common/extensions/chrome_extensions_client.h" +#include "chrome/common/features.h" #include "chrome/common/pref_names.h" #include "chrome/common/switch_utils.h" #include "chrome/common/url_constants.h" @@ -837,10 +838,10 @@ #endif // defined(OS_CHROMEOS) registry->RegisterBooleanPref(metrics::prefs::kMetricsReportingEnabled, GoogleUpdateSettings::GetCollectStatsConsent()); -#if defined(OS_ANDROID) +#if BUILDFLAG(ANDROID_JAVA_UI) registry->RegisterBooleanPref( prefs::kCrashReportingEnabled, false); -#endif // defined(OS_ANDROID) +#endif // BUILDFLAG(ANDROID_JAVA_UI) } DownloadRequestLimiter* BrowserProcessImpl::download_request_limiter() {
diff --git a/chrome/browser/browser_resources.grd b/chrome/browser/browser_resources.grd index e41e967..f8e2f4d 100644 --- a/chrome/browser/browser_resources.grd +++ b/chrome/browser/browser_resources.grd
@@ -153,6 +153,9 @@ <include name="IDR_MD_EXTENSIONS_ITEM_CSS" file="resources\md_extensions\item.css" type="BINDATA" /> <include name="IDR_MD_EXTENSIONS_ITEM_HTML" file="resources\md_extensions\item.html" type="BINDATA" /> <include name="IDR_MD_EXTENSIONS_ITEM_JS" file="resources\md_extensions\item.js" type="BINDATA" /> + <include name="IDR_MD_EXTENSIONS_ITEM_LIST_CSS" file="resources\md_extensions\item_list.css" type="BINDATA" /> + <include name="IDR_MD_EXTENSIONS_ITEM_LIST_HTML" file="resources\md_extensions\item_list.html" type="BINDATA" /> + <include name="IDR_MD_EXTENSIONS_ITEM_LIST_JS" file="resources\md_extensions\item_list.js" type="BINDATA" /> <include name="IDR_MD_EXTENSIONS_SERVICE_HTML" file="resources\md_extensions\service.html" type="BINDATA" /> <include name="IDR_MD_EXTENSIONS_SERVICE_JS" file="resources\md_extensions\service.js" type="BINDATA" /> <include name="IDR_MD_EXTENSIONS_SIDEBAR_CSS" file="resources\md_extensions\sidebar.css" type="BINDATA" />
diff --git a/chrome/browser/browsing_data/browsing_data_remover.cc b/chrome/browser/browsing_data/browsing_data_remover.cc index f8865d3..7779d42 100644 --- a/chrome/browser/browsing_data/browsing_data_remover.cc +++ b/chrome/browser/browsing_data/browsing_data_remover.cc
@@ -39,6 +39,7 @@ #include "chrome/browser/sessions/session_service_factory.h" #include "chrome/browser/sessions/tab_restore_service_factory.h" #include "chrome/browser/web_data_service_factory.h" +#include "chrome/common/features.h" #include "chrome/common/pref_names.h" #include "chrome/common/url_constants.h" #include "components/autofill/core/browser/personal_data_manager.h" @@ -76,7 +77,7 @@ #include "storage/browser/quota/special_storage_policy.h" #include "url/origin.h" -#if defined(OS_ANDROID) +#if BUILDFLAG(ANDROID_JAVA_UI) #include "chrome/browser/android/offline_pages/offline_page_model_factory.h" #include "chrome/browser/android/webapps/webapp_registry.h" #include "chrome/browser/precache/precache_manager_factory.h" @@ -429,7 +430,7 @@ if (profile_->GetSSLHostStateDelegate()) profile_->GetSSLHostStateDelegate()->Clear(); -#if defined(OS_ANDROID) +#if BUILDFLAG(ANDROID_JAVA_UI) precache::PrecacheManager* precache_manager = precache::PrecacheManagerFactory::GetForBrowserContext(profile_); // |precache_manager| could be nullptr if the profile is off the record. @@ -801,7 +802,7 @@ } } -#if defined(OS_ANDROID) +#if BUILDFLAG(ANDROID_JAVA_UI) if (remove_mask & REMOVE_WEBAPP_DATA) { waiting_for_clear_webapp_data_ = true; WebappRegistry::UnregisterWebapps( @@ -897,7 +898,7 @@ !waiting_for_clear_platform_keys_ && !waiting_for_clear_plugin_data_ && !waiting_for_clear_pnacl_cache_ && -#if defined(OS_ANDROID) +#if BUILDFLAG(ANDROID_JAVA_UI) !waiting_for_clear_precache_history_ && !waiting_for_clear_webapp_data_ && !waiting_for_clear_offline_page_data_ && @@ -1193,7 +1194,7 @@ } #endif -#if defined(OS_ANDROID) +#if BUILDFLAG(ANDROID_JAVA_UI) void BrowsingDataRemover::OnClearedPrecacheHistory() { DCHECK_CURRENTLY_ON(BrowserThread::UI); waiting_for_clear_precache_history_ = false;
diff --git a/chrome/browser/browsing_data/browsing_data_remover.h b/chrome/browser/browsing_data/browsing_data_remover.h index 62cd36ea..fd04850 100644 --- a/chrome/browser/browsing_data/browsing_data_remover.h +++ b/chrome/browser/browsing_data/browsing_data_remover.h
@@ -16,6 +16,7 @@ #include "base/task/cancelable_task_tracker.h" #include "base/time/time.h" #include "chrome/browser/pepper_flash_settings_manager.h" +#include "chrome/common/features.h" #include "components/search_engines/template_url_service.h" #if defined(OS_CHROMEOS) #include "chromeos/dbus/dbus_method_call_status.h" @@ -83,7 +84,7 @@ REMOVE_NOCHECKS = 1 << 16, REMOVE_WEBRTC_IDENTITY = 1 << 17, REMOVE_CACHE_STORAGE = 1 << 18, -#if defined(OS_ANDROID) +#if BUILDFLAG(ANDROID_JAVA_UI) REMOVE_WEBAPP_DATA = 1 << 19, REMOVE_OFFLINE_PAGE_DATA = 1 << 20, #endif @@ -104,7 +105,7 @@ REMOVE_WEBSQL | REMOVE_CHANNEL_IDS | REMOVE_SITE_USAGE_DATA | -#if defined(OS_ANDROID) +#if BUILDFLAG(ANDROID_JAVA_UI) REMOVE_WEBAPP_DATA | REMOVE_OFFLINE_PAGE_DATA | #endif @@ -397,7 +398,7 @@ void OnClearedWebRtcLogs(); #endif -#if defined(OS_ANDROID) +#if BUILDFLAG(ANDROID_JAVA_UI) // Callback on UI thread when the precache history has been cleared. void OnClearedPrecacheHistory(); @@ -465,7 +466,7 @@ bool waiting_for_clear_platform_keys_ = false; bool waiting_for_clear_plugin_data_ = false; bool waiting_for_clear_pnacl_cache_ = false; -#if defined(OS_ANDROID) +#if BUILDFLAG(ANDROID_JAVA_UI) bool waiting_for_clear_precache_history_ = false; bool waiting_for_clear_webapp_data_ = false; bool waiting_for_clear_offline_page_data_ = false;
diff --git a/chrome/browser/chrome_browser_main.cc b/chrome/browser/chrome_browser_main.cc index 3a41ca91b..6f18aad0 100644 --- a/chrome/browser/chrome_browser_main.cc +++ b/chrome/browser/chrome_browser_main.cc
@@ -97,6 +97,7 @@ #include "chrome/common/chrome_switches.h" #include "chrome/common/crash_keys.h" #include "chrome/common/env_vars.h" +#include "chrome/common/features.h" #include "chrome/common/logging_chrome.h" #include "chrome/common/net/net_resource_provider.h" #include "chrome/common/pref_names.h" @@ -150,12 +151,16 @@ #include "ui/base/resource/resource_bundle.h" #include "ui/strings/grit/app_locale_settings.h" -#if defined(OS_ANDROID) +#if BUILDFLAG(ANDROID_JAVA_UI) #include "chrome/browser/android/dev_tools_discovery_provider_android.h" +#else +#include "chrome/browser/devtools/chrome_devtools_discovery_provider.h" +#endif + +#if defined(OS_ANDROID) #include "chrome/browser/metrics/thread_watcher_android.h" #include "ui/base/resource/resource_bundle_android.h" #else -#include "chrome/browser/devtools/chrome_devtools_discovery_provider.h" #include "chrome/browser/feedback/feedback_profile_observer.h" #endif // defined(OS_ANDROID) @@ -789,6 +794,8 @@ // On Android, first run is handled in Java code, and the C++ side of Chrome // doesn't know if this is the first run. This will cause some inaccuracy in // the UMA statistics, but this should be minor (first runs are rare). + // TODO(bshe): Figure out which first run code to use for Aura Android. See + // crbug.com/560498 is_first_run = first_run::IsChromeFirstRun(); #endif // defined(OS_ANDROID) @@ -862,11 +869,13 @@ result_code_ = PreCreateThreadsImpl(); if (result_code_ == content::RESULT_CODE_NORMAL_EXIT) { -#if !defined(OS_ANDROID) + // TODO(bshe): Use !defined(ANDROID_JAVA_UI) once + // codereview.chromium.org/1459793002 landed. +#if !defined(OS_ANDROID) || defined(USE_AURA) // These members must be initialized before exiting this function normally. DCHECK(master_prefs_.get()); DCHECK(browser_creator_.get()); -#endif // !defined(OS_ANDROID) +#endif // !defined(OS_ANDROID) || defined(USE_AURA) for (size_t i = 0; i < chrome_extra_parts_.size(); ++i) chrome_extra_parts_[i]->PreCreateThreads(); } @@ -887,6 +896,8 @@ MediaCaptureDevicesDispatcher::GetInstance(); // Android's first run is done in Java instead of native. + // TODO(bshe): Figure out which first run code to use for Aura Android. See + // crbug.com/560498 #if !defined(OS_ANDROID) process_singleton_.reset(new ChromeProcessSingleton( user_data_dir_, base::Bind(&ProcessSingletonNotificationCallback))); @@ -924,14 +935,16 @@ local_state_ = InitializeLocalState( local_state_task_runner.get(), parsed_command_line()); -#if !defined(OS_ANDROID) + // TODO(bshe): Use !defined(ANDROID_JAVA_UI) once + // codereview.chromium.org/1459793002 landed. +#if !defined(OS_ANDROID) || defined(USE_AURA) // These members must be initialized before returning from this function. master_prefs_.reset(new first_run::MasterPrefs); // Android doesn't use StartupBrowserCreator. browser_creator_.reset(new StartupBrowserCreator); // TODO(yfriedman): Refactor Android to re-use UMABrowsingActivityObserver chrome::UMABrowsingActivityObserver::Init(); -#endif // !defined(OS_ANDROID) +#endif // !defined(OS_ANDROID) || defined(USE_AURA) #if !defined(OS_CHROMEOS) // Convert active labs into switches. This needs to be done before @@ -1006,6 +1019,7 @@ base::FilePath resources_pack_path; PathService::Get(chrome::FILE_RESOURCES_PACK, &resources_pack_path); #if defined(OS_ANDROID) + // Uses Android resources even without ANDROID_JAVA_UI. ui::LoadMainAndroidPackFile("assets/resources.pak", resources_pack_path); #else ResourceBundle::GetSharedInstance().AddDataPackFromPath( @@ -1016,6 +1030,8 @@ // Android does first run in Java instead of native. // Chrome OS has its own out-of-box-experience code. + // TODO(bshe): Figure out which first run code to use for Aura Android. See + // crbug.com/560498 #if !defined(OS_ANDROID) && !defined(OS_CHROMEOS) // On first run, we need to process the predictor preferences before the // browser's profile_manager object is created, but after ResourceBundle @@ -1163,11 +1179,11 @@ void ChromeBrowserMainParts::PostProfileInit() { TRACE_EVENT0("startup", "ChromeBrowserMainParts::PostProfileInit"); -#if defined(OS_ANDROID) +#if BUILDFLAG(ANDROID_JAVA_UI) DevToolsDiscoveryProviderAndroid::Install(); #else ChromeDevToolsDiscoveryProvider::Install(); -#endif // defined(OS_ANDROID) +#endif // BUILDFLAG(ANDROID_JAVA_UI) LaunchDevToolsHandlerIfNeeded(parsed_command_line()); for (size_t i = 0; i < chrome_extra_parts_.size(); ++i) @@ -1449,12 +1465,14 @@ if (!profile_) return content::RESULT_CODE_NORMAL_EXIT; -#if !defined(OS_ANDROID) + // TODO(bshe): Use !defined(ANDROID_JAVA_UI) once + // codereview.chromium.org/1459793002 landed. +#if !defined(OS_ANDROID) || defined(USE_AURA) const base::TimeTicks start_time_step2 = base::TimeTicks::Now(); // The first run sentinel must be created after the process singleton was // grabbed and no early return paths were otherwise hit above. first_run::CreateSentinelIfNeeded(); -#endif // !defined(OS_ANDROID) +#endif // !defined(OS_ANDROID) || defined(USE_AURA) #if defined(ENABLE_BACKGROUND) // Autoload any profiles which are running background apps. @@ -1496,6 +1514,8 @@ // Note that this be done _after_ the PrefService is initialized and all // preferences are registered, since some of the code that the importer // touches reads preferences. + // TODO(bshe): Figure out which first run code to use for Aura Android. See + // crbug.com/560498 if (first_run::IsChromeFirstRun()) { first_run::AutoImport(profile_, master_prefs_->homepage_defined, @@ -1630,9 +1650,10 @@ g_browser_process->local_state()); ThreadWatcherList::StartWatchingAll(parsed_command_line()); -#if defined(OS_ANDROID) + // TODO(bshe): Aura Android may need this call. See crbug.com/565317. +#if defined(OS_ANDROID) && !defined(USE_AURA) ThreadWatcherAndroid::RegisterApplicationStatusListener(); -#endif // defined(OS_ANDROID) +#endif // defined(OS_ANDROID) && !defined(USE_AURA) #if !defined(DISABLE_NACL) BrowserThread::PostTask( @@ -1659,7 +1680,9 @@ if (!parsed_command_line().HasSwitch(switches::kDisableComponentUpdate)) RegisterComponentsForUpdate(); -#if defined(OS_ANDROID) + // TODO(bshe): Use defined(ANDROID_JAVA_UI) once + // codereview.chromium.org/1459793002 landed. +#if defined(OS_ANDROID) && !defined(USE_AURA) variations::VariationsService* variations_service = browser_process_->variations_service(); if (variations_service) { @@ -1669,7 +1692,6 @@ } translate::TranslateDownloadManager::RequestLanguageList( profile_->GetPrefs()); - #else // Most general initialization is behind us, but opening a // tab and/or session restore and such is still to be done. @@ -1746,9 +1768,11 @@ content::StartPowerUsageMonitor(); #endif // !defined(OS_LINUX) || defined(OS_CHROMEOS) +#if !defined(OS_ANDROID) process_power_collector_.reset(new ProcessPowerCollector); process_power_collector_->Initialize(); #endif // !defined(OS_ANDROID) +#endif // defined(OS_ANDROID) && !defined(USE_AURA) PostBrowserStart(); @@ -1766,10 +1790,12 @@ } #endif // defined(OS_ANDROID) -#if !defined(OS_ANDROID) + // TODO(bshe): Use !defined(ANDROID_JAVA_UI) once + // codereview.chromium.org/1459793002 landed. +#if !defined(OS_ANDROID) || defined(USE_AURA) UMA_HISTOGRAM_TIMES("Startup.PreMainMessageLoopRunImplStep3Time", base::TimeTicks::Now() - start_time_step3); -#endif // !defined(OS_ANDROID) +#endif // !defined(OS_ANDROID) || defined(USE_AURA) return result_code_; }
diff --git a/chrome/browser/chrome_browser_main.h b/chrome/browser/chrome_browser_main.h index 140a960..e142ad2 100644 --- a/chrome/browser/chrome_browser_main.h +++ b/chrome/browser/chrome_browser_main.h
@@ -164,7 +164,10 @@ scoped_ptr<BrowserProcessImpl> browser_process_; scoped_refptr<metrics::TrackingSynchronizer> tracking_synchronizer_; -#if !defined(OS_ANDROID) + + // TODO(bshe): Use !defined(ANDROID_JAVA_UI) once + // codereview.chromium.org/1459793002 landed. +#if !defined(OS_ANDROID) || defined(USE_AURA) // Browser creation happens on the Java side in Android. scoped_ptr<StartupBrowserCreator> browser_creator_; @@ -174,7 +177,7 @@ // Android's first run is done in Java instead of native. scoped_ptr<first_run::MasterPrefs> master_prefs_; -#endif +#endif // !defined(OS_ANDROID) || defined(USE_AURA) Profile* profile_; bool run_message_loop_; ProcessSingleton::NotifyResult notify_result_;
diff --git a/chrome/browser/chrome_browser_main_extra_parts_exo.cc b/chrome/browser/chrome_browser_main_extra_parts_exo.cc index d13c14d9..9cecfbd3 100644 --- a/chrome/browser/chrome_browser_main_extra_parts_exo.cc +++ b/chrome/browser/chrome_browser_main_extra_parts_exo.cc
@@ -4,10 +4,6 @@ #include "chrome/browser/chrome_browser_main_extra_parts_exo.h" -#if defined(USE_GLIB) -#include <glib.h> -#endif - #include "base/command_line.h" #include "base/message_loop/message_loop.h" #include "chrome/browser/ui/ash/ash_util.h" @@ -16,61 +12,6 @@ #include "components/exo/wayland/server.h" #include "content/public/browser/browser_thread.h" -#if defined(USE_GLIB) -namespace { - -gboolean WaylandSourcePrepare(GSource* source, gint* timeout_ms) { - *timeout_ms = -1; - return FALSE; -} - -gboolean WaylandSourceCheck(GSource* source) { - return TRUE; -} - -gboolean WaylandSourceDispatch(GSource* source, - GSourceFunc unused_func, - gpointer data) { - exo::wayland::Server* server = static_cast<exo::wayland::Server*>(data); - server->Dispatch(base::TimeDelta()); - server->Flush(); - return TRUE; -} - -GSourceFuncs g_wayland_source_funcs = {WaylandSourcePrepare, WaylandSourceCheck, - WaylandSourceDispatch, nullptr}; - -} // namespace - -class ChromeBrowserMainExtraPartsExo::WaylandWatcher { - public: - explicit WaylandWatcher(exo::wayland::Server* server) - : wayland_poll_(new GPollFD), - wayland_source_( - g_source_new(&g_wayland_source_funcs, sizeof(GSource))) { - wayland_poll_->fd = server->GetFileDescriptor(); - wayland_poll_->events = G_IO_IN; - wayland_poll_->revents = 0; - g_source_add_poll(wayland_source_, wayland_poll_.get()); - g_source_set_can_recurse(wayland_source_, TRUE); - g_source_set_callback(wayland_source_, nullptr, server, nullptr); - g_source_attach(wayland_source_, g_main_context_default()); - } - ~WaylandWatcher() { - g_source_destroy(wayland_source_); - g_source_unref(wayland_source_); - } - - private: - // The poll attached to |wayland_source_|. - scoped_ptr<GPollFD> wayland_poll_; - - // The GLib event source for wayland events. - GSource* wayland_source_; - - DISALLOW_COPY_AND_ASSIGN(WaylandWatcher); -}; -#else class ChromeBrowserMainExtraPartsExo::WaylandWatcher : public base::MessagePumpLibevent::Watcher { public: @@ -94,7 +35,6 @@ DISALLOW_COPY_AND_ASSIGN(WaylandWatcher); }; -#endif ChromeBrowserMainExtraPartsExo::ChromeBrowserMainExtraPartsExo() : display_(new exo::Display) {}
diff --git a/chrome/browser/chrome_content_browser_client.cc b/chrome/browser/chrome_content_browser_client.cc index e0707b57..14ee957 100644 --- a/chrome/browser/chrome_content_browser_client.cc +++ b/chrome/browser/chrome_content_browser_client.cc
@@ -93,6 +93,7 @@ #include "chrome/common/chrome_paths.h" #include "chrome/common/chrome_switches.h" #include "chrome/common/env_vars.h" +#include "chrome/common/features.h" #include "chrome/common/logging_chrome.h" #include "chrome/common/pepper_permission_util.h" #include "chrome/common/pref_names.h" @@ -197,6 +198,12 @@ #include "components/crash/content/browser/crash_handler_host_linux.h" #endif +#if BUILDFLAG(ANDROID_JAVA_UI) +#include "chrome/browser/android/new_tab_page_url_handler.h" +#include "chrome/browser/android/webapps/single_tab_mode_tab_helper.h" +#include "components/service_tab_launcher/browser/android/service_tab_launcher.h" +#endif + #if defined(OS_ANDROID) #include "ui/base/ui_base_paths.h" #include "ui/gfx/android/device_display_info.h" @@ -277,12 +284,6 @@ #include "chrome/browser/chrome_browser_main_extra_parts_exo.h" #endif -#if defined(OS_ANDROID) && !defined(USE_AURA) -#include "chrome/browser/android/new_tab_page_url_handler.h" -#include "chrome/browser/android/webapps/single_tab_mode_tab_helper.h" -#include "components/service_tab_launcher/browser/android/service_tab_launcher.h" -#endif - using base::FileDescriptor; using blink::WebWindowFeatures; using content::AccessTokenStore; @@ -589,10 +590,7 @@ safe_browsing_ui_manager_; }; - - // TODO(bshe): Use defined(ANDROID_JAVA_UI) once - // codereview.chromium.org/1459793002 landed. -#if defined(OS_ANDROID) && !defined(USE_AURA) +#if BUILDFLAG(ANDROID_JAVA_UI) void HandleSingleTabModeBlockOnUIThread(const BlockedWindowParams& params) { WebContents* web_contents = tab_util::GetWebContentsByFrameID( params.render_process_id(), params.opener_render_frame_id()); @@ -601,7 +599,7 @@ SingleTabModeTabHelper::FromWebContents(web_contents)->HandleOpenUrl(params); } -#endif +#endif // BUILDFLAG(ANDROID_JAVA_UI) #if defined(OS_ANDROID) float GetDeviceScaleAdjustment() { @@ -2176,9 +2174,7 @@ } } - // TODO(bshe): Use defined(ANDROID_JAVA_UI) once - // codereview.chromium.org/1459793002 landed. -#if defined(OS_ANDROID) && !defined(USE_AURA) +#if BUILDFLAG(ANDROID_JAVA_UI) if (SingleTabModeTabHelper::IsRegistered(render_process_id, opener_render_view_id)) { BrowserThread::PostTask(BrowserThread::UI, @@ -2294,7 +2290,6 @@ web_prefs->password_echo_enabled = browser_defaults::kPasswordEchoEnabled; #endif - web_prefs->asynchronous_spell_checking_enabled = true; web_prefs->unified_textchecker_enabled = true; web_prefs->uses_universal_detector = @@ -2349,9 +2344,7 @@ handler->AddHandlerPair(&WillHandleBrowserAboutURL, BrowserURLHandler::null_handler()); - // TODO(bshe): Use defined(ANDROID_JAVA_UI) once - // codereview.chromium.org/1459793002 landed. -#if defined(OS_ANDROID) && !defined(USE_AURA) +#if BUILDFLAG(ANDROID_JAVA_UI) // Handler to rewrite chrome://newtab on Android. handler->AddHandlerPair(&chrome::android::HandleAndroidNativePageURL, BrowserURLHandler::null_handler()); @@ -2637,9 +2630,10 @@ const base::Callback<void(content::WebContents*)>& callback) { DCHECK_CURRENTLY_ON(BrowserThread::UI); - // TODO(bshe): Use !defined(ANDROID_JAVA_UI) once - // codereview.chromium.org/1459793002 landed. -#if (!defined(OS_ANDROID) || defined(USE_AURA)) && !defined(OS_IOS) +#if BUILDFLAG(ANDROID_JAVA_UI) + service_tab_launcher::ServiceTabLauncher::GetInstance()->LaunchTab( + browser_context, params, callback); +#elif !defined(OS_IOS) chrome::NavigateParams nav_params( Profile::FromBrowserContext(browser_context), params.url, @@ -2649,9 +2643,6 @@ Navigate(&nav_params); callback.Run(nav_params.target_contents); -#elif defined(OS_ANDROID) - service_tab_launcher::ServiceTabLauncher::GetInstance()->LaunchTab( - browser_context, params, callback); #else NOTIMPLEMENTED(); #endif
diff --git a/chrome/browser/chromeos/app_mode/fake_cws.cc b/chrome/browser/chromeos/app_mode/fake_cws.cc index a1f25c4..43474b5 100644 --- a/chrome/browser/chromeos/app_mode/fake_cws.cc +++ b/chrome/browser/chromeos/app_mode/fake_cws.cc
@@ -93,6 +93,8 @@ update_check_end_point_ = update_check_end_point; SetupWebStoreURL(embedded_test_server->base_url()); + OverrideGalleryCommandlineSwitches(); + embedded_test_server->RegisterRequestHandler( base::Bind(&FakeCWS::HandleRequest, base::Unretained(this))); }
diff --git a/chrome/browser/chromeos/app_mode/startup_app_launcher.cc b/chrome/browser/chromeos/app_mode/startup_app_launcher.cc index 15156245..fed5be6a 100644 --- a/chrome/browser/chromeos/app_mode/startup_app_launcher.cc +++ b/chrome/browser/chromeos/app_mode/startup_app_launcher.cc
@@ -72,12 +72,7 @@ : profile_(profile), app_id_(app_id), diagnostic_mode_(diagnostic_mode), - delegate_(delegate), - network_ready_handled_(false), - launch_attempt_(0), - ready_to_launch_(false), - wait_for_crx_update_(false), - secondary_apps_updated_(false) { + delegate_(delegate) { DCHECK(profile_); DCHECK(crx_file::id_util::IdIsValid(app_id_)); KioskAppManager::Get()->AddObserver(this); @@ -269,6 +264,59 @@ } } +void StartupAppLauncher::MaybeCheckExtensionUpdate() { + extensions::ExtensionUpdater* updater = + extensions::ExtensionSystem::Get(profile_) + ->extension_service() + ->updater(); + if (!delegate_->IsNetworkReady() || !updater) { + MaybeLaunchApp(); + return; + } + + extension_update_found_ = false; + registrar_.Add(this, extensions::NOTIFICATION_EXTENSION_UPDATE_FOUND, + content::NotificationService::AllSources()); + + // Enforce an immediate version update check for all extensions before + // launching the primary app. After the chromeos is updated, the shared + // module(e.g. ARC runtime) may need to be updated to a newer version + // compatible with the new chromeos. See crbug.com/555083. + extensions::ExtensionUpdater::CheckParams params; + params.install_immediately = true; + params.callback = base::Bind( + &StartupAppLauncher::OnExtensionUpdateCheckFinished, AsWeakPtr()); + updater->CheckNow(params); +} + +void StartupAppLauncher::OnExtensionUpdateCheckFinished() { + if (extension_update_found_) { + // Reload the primary app to make sure any reference to the previous version + // of the shared module, extension, etc will be cleaned up andthe new + // version will be loaded. + extensions::ExtensionSystem::Get(profile_) + ->extension_service() + ->ReloadExtension(app_id_); + extension_update_found_ = false; + } + registrar_.Remove(this, extensions::NOTIFICATION_EXTENSION_UPDATE_FOUND, + content::NotificationService::AllSources()); + + MaybeLaunchApp(); +} + +void StartupAppLauncher::Observe(int type, + const content::NotificationSource& source, + const content::NotificationDetails& details) { + DCHECK(type == extensions::NOTIFICATION_EXTENSION_UPDATE_FOUND); + typedef const std::pair<std::string, Version> UpdateDetails; + const std::string& id = content::Details<UpdateDetails>(details)->first; + const Version& version = content::Details<UpdateDetails>(details)->second; + VLOG(1) << "Found extension update id=" << id + << " version=" << version.GetString(); + extension_update_found_ = true; +} + void StartupAppLauncher::OnFinishCrxInstall(const std::string& extension_id, bool success) { // Wait for pending updates or dependent extensions to download. @@ -293,10 +341,10 @@ } if (GetPrimaryAppExtension()) { - if (!secondary_apps_updated_) + if (!secondary_apps_installed_) MaybeInstallSecondaryApps(); else - MaybeLaunchApp(); + MaybeCheckExtensionUpdate(); } } @@ -465,7 +513,7 @@ return; } - secondary_apps_updated_ = true; + secondary_apps_installed_ = true; extensions::KioskModeInfo* info = extensions::KioskModeInfo::Get(GetPrimaryAppExtension()); KioskAppManager::Get()->InstallSecondaryApps(info->secondary_app_ids); @@ -479,8 +527,8 @@ } if (AreSecondaryAppsInstalled()) { - // Launch the primary app. - MaybeLaunchApp(); + // Check extension update before launching the primary kiosk app. + MaybeCheckExtensionUpdate(); } else { OnLaunchFailure(KioskAppLaunchError::UNABLE_TO_INSTALL); }
diff --git a/chrome/browser/chromeos/app_mode/startup_app_launcher.h b/chrome/browser/chromeos/app_mode/startup_app_launcher.h index 3ac3547..d113450 100644 --- a/chrome/browser/chromeos/app_mode/startup_app_launcher.h +++ b/chrome/browser/chromeos/app_mode/startup_app_launcher.h
@@ -13,6 +13,8 @@ #include "chrome/browser/chromeos/app_mode/kiosk_app_launch_error.h" #include "chrome/browser/chromeos/app_mode/kiosk_app_manager_observer.h" #include "chrome/browser/extensions/install_observer.h" +#include "content/public/browser/notification_observer.h" +#include "content/public/browser/notification_registrar.h" #include "google_apis/gaia/oauth2_token_service.h" class Profile; @@ -32,7 +34,8 @@ class StartupAppLauncher : public base::SupportsWeakPtr<StartupAppLauncher>, public OAuth2TokenService::Observer, public extensions::InstallObserver, - public KioskAppManagerObserver { + public KioskAppManagerObserver, + public content::NotificationObserver { public: class Delegate { public: @@ -94,6 +97,9 @@ void MaybeInstallSecondaryApps(); void MaybeLaunchApp(); + void MaybeCheckExtensionUpdate(); + void OnExtensionUpdateCheckFinished(); + void StartLoadingOAuthFile(); static void LoadOAuthFileOnBlockingPool(KioskOAuthParams* auth_params); void OnOAuthFileLoaded(KioskOAuthParams* auth_params); @@ -128,17 +134,24 @@ void OnKioskExtensionLoadedInCache(const std::string& app_id) override; void OnKioskExtensionDownloadFailed(const std::string& app_id) override; + // content::NotificationObserver implementation. + void Observe(int type, + const content::NotificationSource& source, + const content::NotificationDetails& details) override; + Profile* profile_; const std::string app_id_; const bool diagnostic_mode_; Delegate* delegate_; - bool network_ready_handled_; - int launch_attempt_; - bool ready_to_launch_; - bool wait_for_crx_update_; - bool secondary_apps_updated_; + bool network_ready_handled_ = false; + int launch_attempt_ = 0; + bool ready_to_launch_ = false; + bool wait_for_crx_update_ = false; + bool secondary_apps_installed_ = false; + bool extension_update_found_ = false; KioskOAuthParams auth_params_; + content::NotificationRegistrar registrar_; DISALLOW_COPY_AND_ASSIGN(StartupAppLauncher); };
diff --git a/chrome/browser/chromeos/login/kiosk_browsertest.cc b/chrome/browser/chromeos/login/kiosk_browsertest.cc index 4322d44..5bc093d5 100644 --- a/chrome/browser/chromeos/login/kiosk_browsertest.cc +++ b/chrome/browser/chromeos/login/kiosk_browsertest.cc
@@ -117,19 +117,50 @@ // An app to test local access to file systems via the // chrome.fileSystem.requestFileSystem API. // Webstore data json is in -// chrome/test/data/chromeos/app_mode/webstore/inlineinstall/ -// detail/aaedpojejpghjkedenggihopfhfijcko +// chrome/test/data/chromeos/app_mode/webstore/inlineinstall/ +// detail/aaedpojejpghjkedenggihopfhfijcko const char kTestGetVolumeListKioskApp[] = "aaedpojejpghjkedenggihopfhfijcko"; -// Testing apps for testing kiosk multi-app feature. -const char kTestPrimaryKioskApp[] = "ceobkcclegcliomogfoeoheahogoecgl"; -const char kTestSecondaryApp1[] = "ihplaomghjbeafnpnjkhppmfpnmdihgd"; -const char kTestSecondaryApp2[] = "fiehokkcgaojmbhfhlpiheggjhaedjoc"; -const char kTestSecondaryApp3[] = "aabnpdpieclcikafhdkkpldcaodmfoai"; -const char kTestSecondaryExtension[] = "imlgadjgphbjkaceoiapiephhgeofhic"; +// Testing apps for testing kiosk multi-app feature. All the crx files are in +// chrome/test/data/chromeos/app_mode/webstore/downloads. + +// Source files are in +// chrome/test/data/chromeos/app_mode/multi_app_kiosk/src/primary_app +const char kTestPrimaryKioskApp[] = "dpejijbnadgcgmabkmcoajkgongfgnii"; + +// Source files are in +// chrome/test/data/chromeos/app_mode/multi_app_kiosk/src/secondary_app_1 +const char kTestSecondaryApp1[] = "emnbflhfbllbehnpjmjddklbkeeoaaeg"; + +// Source files are in +// chrome/test/data/chromeos/app_mode/multi_app_kiosk/src/secondary_app_2 +const char kTestSecondaryApp2[] = "blmjgfbajihimkjmepbhgmjbopjchlda"; + +// Source files are in +// chrome/test/data/chromeos/app_mode/multi_app_kiosk/src/secondary_app_3 +const char kTestSecondaryApp3[] = "jkofhenkpndpdflehcjpcekgecjkpggg"; + +// Source files are in +// chrome/test/data/chromeos/app_mode/multi_app_kiosk/src/ +// secondary_extensions_1 +const char kTestSecondaryExtension[] = "gdmgkkoghcihimdfoabkefdkccllcfea"; + +// Source files are in +// chrome/test/data/chromeos/app_mode/multi_app_kiosk/src/ +// shared_module_primary_app const char kTestSharedModulePrimaryApp[] = "ofmeihgcmabfalhhgooajcijiaoekhkg"; + +// Source files are in +// chrome/test/data/chromeos/app_mode/multi_app_kiosk/src/secondary_app const char kTestSecondaryApp[] = "bbmaiojbgkkmfaglfhaplfomobgojhke"; + +// Source files are in +// chrome/test/data/chromeos/app_mode/multi_app_kiosk/src/shared_module const char kTestSharedModuleId[] = "biebhpdepndljbnkadldcbjkiedldnmn"; + +// Source files are in +// chrome/test/data/chromeos/app_mode/multi_app_kiosk/src/ +// secondary_extension const char kTestSecondaryExt[] = "kcoobopfcjmbfeppibolpaolbgbmkcjd"; // Fake usb stick mount path. @@ -203,14 +234,14 @@ lock->Release(); } -bool IsAppInstalled(const std::string& app_id) { +bool IsAppInstalled(const std::string& app_id, const std::string& version) { Profile* app_profile = ProfileManager::GetPrimaryUserProfile(); DCHECK(app_profile); const extensions::Extension* app = extensions::ExtensionSystem::Get(app_profile) ->extension_service() ->GetInstalledExtension(app_id); - return app != nullptr; + return app != nullptr && version == app->version()->GetString(); } extensions::Manifest::Type GetAppType(const std::string& app_id) { @@ -484,6 +515,9 @@ settings_helper_.ReplaceProvider(kAccountsPrefDeviceLocalAccounts); owner_settings_service_ = settings_helper_.CreateOwnerSettingsService( ProfileManager::GetPrimaryUserProfile()); + + // Set up local cache for app update check. + CreateAndInitializeLocalCache(); } void TearDownOnMainThread() override { @@ -498,6 +532,19 @@ KioskAppManager::Get()->CleanUp(); } + // The local cache is supposed to be initialized on chromeos device, and a + // ready flag file will be pre-created to mark the ready state, before chrome + // starts. In order for the tests to run without being on real chromeos + // device, we need to manually create this file. + void CreateAndInitializeLocalCache() { + base::FilePath extension_cache_dir; + CHECK(PathService::Get(chromeos::DIR_DEVICE_EXTENSION_LOCAL_CACHE, + &extension_cache_dir)); + base::FilePath cache_init_file = extension_cache_dir.Append( + extensions::LocalExtensionCache::kCacheReadyFlagFileName); + EXPECT_EQ(base::WriteFile(cache_init_file, "", 0), 0); + } + void SetUpCommandLine(base::CommandLine* command_line) override { OobeBaseTest::SetUpCommandLine(command_line); fake_cws_->Init(embedded_test_server()); @@ -1328,8 +1375,6 @@ // next startup) and copy the list to our stub settings provider as well. settings_helper_.CopyStoredValue(kAccountsPrefDeviceLocalAccounts); - CreateAndInitializeLocalCache(); - KioskTest::SetUpOnMainThread(); } @@ -1425,9 +1470,9 @@ WaitForAppLaunchWithOptions(false, true); // Verify the primary app and the secondary apps are all installed. - EXPECT_EQ(primary_app.version, GetInstalledAppVersion().GetString()); + EXPECT_TRUE(IsAppInstalled(primary_app.id, primary_app.version)); for (const auto& app : secondary_apps) { - EXPECT_TRUE(IsAppInstalled(app.id)); + EXPECT_TRUE(IsAppInstalled(app.id, app.version)); EXPECT_EQ(GetAppType(app.id), app.type); } } @@ -1484,7 +1529,24 @@ secondary_apps.push_back(shared_module); LaunchKioskWithSecondaryApps(primary_app, secondary_apps); - EXPECT_TRUE(IsAppInstalled(kTestSharedModuleId)); + EXPECT_TRUE(IsAppInstalled(shared_module.id, shared_module.version)); + } + + void LaunchAppWithSharedModule() { + TestAppInfo primary_app( + kTestSharedModulePrimaryApp, "2.0.0", + std::string(kTestSharedModulePrimaryApp) + "-2.0.0.crx", + extensions::Manifest::TYPE_PLATFORM_APP); + + std::vector<TestAppInfo> secondary_apps; + // Setting up FakeCWS for shared module is the same for shared module as + // for kiosk secondary apps. + TestAppInfo shared_module(kTestSharedModuleId, "1.0.0", + std::string(kTestSharedModuleId) + "-1.0.0.crx", + extensions::Manifest::TYPE_SHARED_MODULE); + secondary_apps.push_back(shared_module); + + LaunchKioskWithSecondaryApps(primary_app, secondary_apps); } private: @@ -1539,19 +1601,6 @@ DISALLOW_COPY_AND_ASSIGN(KioskAppExternalUpdateWaiter); }; - // The local cache is supposed to be initialized on chromeos device, and a - // ready flag file will be pre-created to mark the ready state, before chrome - // starts. In order for the tests to run without being on real chromeos - // device, we need to manually create this file. - void CreateAndInitializeLocalCache() { - base::FilePath extension_cache_dir; - CHECK(PathService::Get(chromeos::DIR_DEVICE_EXTENSION_LOCAL_CACHE, - &extension_cache_dir)); - base::FilePath cache_init_file = extension_cache_dir.Append( - extensions::LocalExtensionCache::kCacheReadyFlagFileName); - EXPECT_EQ(base::WriteFile(cache_init_file, "", 0), 0); - } - // Owned by DiskMountManager. KioskFakeDiskMountManager* fake_disk_mount_manager_; @@ -1886,9 +1935,9 @@ // from its manifest. IN_PROC_BROWSER_TEST_F(KioskUpdateTest, UpdateMultiAppKioskRemoveOneApp) { set_test_app_id(kTestPrimaryKioskApp); - fake_cws()->SetUpdateCrx( - kTestPrimaryKioskApp, - std::string(kTestPrimaryKioskApp) + "-2.0.0-1app.crx", "2.0.0"); + fake_cws()->SetUpdateCrx(kTestPrimaryKioskApp, + std::string(kTestPrimaryKioskApp) + "-2.0.0.crx", + "2.0.0"); fake_cws()->SetNoUpdate(kTestSecondaryApp1); fake_cws()->SetNoUpdate(kTestSecondaryApp2); @@ -1899,8 +1948,8 @@ // Verify the secondary app kTestSecondaryApp1 is removed. EXPECT_EQ("2.0.0", GetInstalledAppVersion().GetString()); - EXPECT_FALSE(IsAppInstalled(kTestSecondaryApp1)); - EXPECT_TRUE(IsAppInstalled(kTestSecondaryApp2)); + EXPECT_FALSE(IsAppInstalled(kTestSecondaryApp1, "1.0.0")); + EXPECT_TRUE(IsAppInstalled(kTestSecondaryApp2, "1.0.0")); } IN_PROC_BROWSER_TEST_F(KioskUpdateTest, PRE_UpdateMultiAppKioskAddOneApp) { @@ -1911,9 +1960,9 @@ // manifest. IN_PROC_BROWSER_TEST_F(KioskUpdateTest, UpdateMultiAppKioskAddOneApp) { set_test_app_id(kTestPrimaryKioskApp); - fake_cws()->SetUpdateCrx( - kTestPrimaryKioskApp, - std::string(kTestPrimaryKioskApp) + "-3.0.0-3app.crx", "3.0.0"); + fake_cws()->SetUpdateCrx(kTestPrimaryKioskApp, + std::string(kTestPrimaryKioskApp) + "-3.0.0.crx", + "3.0.0"); fake_cws()->SetNoUpdate(kTestSecondaryApp1); fake_cws()->SetNoUpdate(kTestSecondaryApp2); fake_cws()->SetUpdateCrx(kTestSecondaryApp3, @@ -1927,9 +1976,9 @@ // Verify the secondary app kTestSecondaryApp3 is installed. EXPECT_EQ("3.0.0", GetInstalledAppVersion().GetString()); - EXPECT_TRUE(IsAppInstalled(kTestSecondaryApp1)); - EXPECT_TRUE(IsAppInstalled(kTestSecondaryApp2)); - EXPECT_TRUE(IsAppInstalled(kTestSecondaryApp3)); + EXPECT_TRUE(IsAppInstalled(kTestSecondaryApp1, "1.0.0")); + EXPECT_TRUE(IsAppInstalled(kTestSecondaryApp2, "1.0.0")); + EXPECT_TRUE(IsAppInstalled(kTestSecondaryApp3, "1.0.0")); } IN_PROC_BROWSER_TEST_F(KioskUpdateTest, LaunchKioskAppWithSecondaryExtension) { @@ -1961,27 +2010,41 @@ WaitForAppLaunchWithOptions(false, true); // Verify the secondary app is removed. - EXPECT_TRUE(IsAppInstalled(kTestSharedModuleId)); - EXPECT_FALSE(IsAppInstalled(kTestSecondaryApp1)); + EXPECT_TRUE(IsAppInstalled(kTestSharedModuleId, "1.0.0")); + EXPECT_FALSE(IsAppInstalled(kTestSecondaryApp1, "1.0.0")); } // This simulates the stand-alone ARC kiosk app case. The primary app has a // shared ARC runtime but no secondary apps. IN_PROC_BROWSER_TEST_F(KioskUpdateTest, LaunchAppWithSharedModuleNoSecondary) { - TestAppInfo primary_app( - kTestSharedModulePrimaryApp, "2.0.0", - std::string(kTestSharedModulePrimaryApp) + "-2.0.0.crx", - extensions::Manifest::TYPE_PLATFORM_APP); + LaunchAppWithSharedModule(); +} - std::vector<TestAppInfo> secondary_apps; - // Setting up FakeCWS for shared module is the same for shared module as - // for kiosk secondary apps. - TestAppInfo shared_module(kTestSharedModuleId, "1.0.0", - std::string(kTestSharedModuleId) + "-1.0.0.crx", - extensions::Manifest::TYPE_SHARED_MODULE); - secondary_apps.push_back(shared_module); +IN_PROC_BROWSER_TEST_F(KioskUpdateTest, PRE_LaunchAppWithUpdatedModule) { + LaunchAppWithSharedModule(); + // Verify the shared module is installed with version 1.0.0. + EXPECT_TRUE(IsAppInstalled(kTestSharedModuleId, "1.0.0")); +} - LaunchKioskWithSecondaryApps(primary_app, secondary_apps); +// This simulates the case the shared module is updated to a newer version. +// See crbug.com/555083. +IN_PROC_BROWSER_TEST_F(KioskUpdateTest, LaunchAppWithUpdatedModule) { + // No update for primary app, while the shared module is set up to a new + // version on cws. + set_test_app_id(kTestSharedModulePrimaryApp); + fake_cws()->SetNoUpdate(kTestSharedModulePrimaryApp); + fake_cws()->SetUpdateCrx(kTestSharedModuleId, + std::string(kTestSharedModuleId) + "-2.0.0.crx", + "2.0.0"); + + StartUIForAppLaunch(); + SimulateNetworkOnline(); + LaunchApp(test_app_id(), false); + WaitForAppLaunchWithOptions(false, true); + + // Verify the shared module is updated to the new version after primary app + // is launched. + EXPECT_TRUE(IsAppInstalled(kTestSharedModuleId, "2.0.0")); } IN_PROC_BROWSER_TEST_F(KioskUpdateTest,
diff --git a/chrome/browser/chromeos/login/lock/webui_screen_locker.cc b/chrome/browser/chromeos/login/lock/webui_screen_locker.cc index 318f36b..00c7dded 100644 --- a/chrome/browser/chromeos/login/lock/webui_screen_locker.cc +++ b/chrome/browser/chromeos/login/lock/webui_screen_locker.cc
@@ -347,7 +347,7 @@ void WebUIScreenLocker::RenderProcessGone(base::TerminationStatus status) { if (browser_shutdown::GetShutdownType() == browser_shutdown::NOT_VALID && status != base::TERMINATION_STATUS_NORMAL_TERMINATION) { - LOG(ERROR) << "Renderer crash on lock screen"; + LOG(ERROR) << "Renderer crash on lock screen; signing out"; Signout(); } }
diff --git a/chrome/browser/chromeos/platform_keys/platform_keys_service.cc b/chrome/browser/chromeos/platform_keys/platform_keys_service.cc index ce4e9247..d61e41f 100644 --- a/chrome/browser/chromeos/platform_keys/platform_keys_service.cc +++ b/chrome/browser/chromeos/platform_keys/platform_keys_service.cc
@@ -4,6 +4,8 @@ #include "chrome/browser/chromeos/platform_keys/platform_keys_service.h" +#include <utility> + #include "base/bind.h" #include "base/bind_helpers.h" #include "base/callback.h" @@ -424,7 +426,7 @@ } } - matches_.push_back(certificate.Pass()); + matches_.push_back(std::move(certificate)); } DoStep(); }
diff --git a/chrome/browser/chromeos/printer_detector/printer_detector_unittest.cc b/chrome/browser/chromeos/printer_detector/printer_detector_unittest.cc index e547d4a..2aa8e424 100644 --- a/chrome/browser/chromeos/printer_detector/printer_detector_unittest.cc +++ b/chrome/browser/chromeos/printer_detector/printer_detector_unittest.cc
@@ -247,14 +247,12 @@ TEST_F(PrinterDetectorAppSearchEnabledTest, PrinterProvider_UsbPrinters_NotFound) { - scoped_refptr<extensions::Extension> extension = - CreateTestExtension( - ListBuilder().Append("usb").Append("printerProvider").Pass(), - DictionaryBuilder().Set( - "filters", ListBuilder().Append(DictionaryBuilder() - .Set("vendorId", 123) - .Set("productId", 001)))) - .Pass(); + scoped_refptr<extensions::Extension> extension = CreateTestExtension( + ListBuilder().Append("usb").Append("printerProvider").Pass(), + DictionaryBuilder().Set( + "filters", + ListBuilder().Append( + DictionaryBuilder().Set("vendorId", 123).Set("productId", 001)))); ASSERT_TRUE(extensions::ExtensionRegistry::Get(profile_.get()) ->AddEnabled(extension)); @@ -271,14 +269,12 @@ TEST_F(PrinterDetectorAppSearchEnabledTest, PrinterProvider_UsbPrinters_WithProductId) { - scoped_refptr<extensions::Extension> extension = - CreateTestExtension( - ListBuilder().Append("usb").Append("printerProvider").Pass(), - DictionaryBuilder().Set( - "filters", ListBuilder().Append(DictionaryBuilder() - .Set("vendorId", 123) - .Set("productId", 456)))) - .Pass(); + scoped_refptr<extensions::Extension> extension = CreateTestExtension( + ListBuilder().Append("usb").Append("printerProvider").Pass(), + DictionaryBuilder().Set( + "filters", + ListBuilder().Append( + DictionaryBuilder().Set("vendorId", 123).Set("productId", 456)))); ASSERT_TRUE(extensions::ExtensionRegistry::Get(profile_.get()) ->AddEnabled(extension)); @@ -295,15 +291,13 @@ TEST_F(PrinterDetectorAppSearchEnabledTest, PrinterProvider_UsbPrinters_WithInterfaceClass) { - scoped_refptr<extensions::Extension> extension = - CreateTestExtension( - ListBuilder().Append("usb").Append("printerProvider").Pass(), - DictionaryBuilder().Set( - "filters", - ListBuilder().Append( - DictionaryBuilder() - .Set("vendorId", 123) - .Set("interfaceClass", kPrinterInterfaceClass)))).Pass(); + scoped_refptr<extensions::Extension> extension = CreateTestExtension( + ListBuilder().Append("usb").Append("printerProvider").Pass(), + DictionaryBuilder().Set( + "filters", ListBuilder().Append( + DictionaryBuilder() + .Set("vendorId", 123) + .Set("interfaceClass", kPrinterInterfaceClass)))); ASSERT_TRUE(extensions::ExtensionRegistry::Get(profile_.get()) ->AddEnabled(extension)); @@ -319,15 +313,13 @@ } TEST_F(PrinterDetectorAppSearchEnabledTest, IgnoreNonPrinters) { - scoped_refptr<extensions::Extension> extension = - CreateTestExtension( - ListBuilder().Append("usb").Append("printerProvider").Pass(), - DictionaryBuilder().Set( - "filters", - ListBuilder().Append( - DictionaryBuilder() - .Set("vendorId", 123) - .Set("interfaceClass", kPrinterInterfaceClass)))).Pass(); + scoped_refptr<extensions::Extension> extension = CreateTestExtension( + ListBuilder().Append("usb").Append("printerProvider").Pass(), + DictionaryBuilder().Set( + "filters", ListBuilder().Append( + DictionaryBuilder() + .Set("vendorId", 123) + .Set("interfaceClass", kPrinterInterfaceClass)))); ASSERT_TRUE(extensions::ExtensionRegistry::Get(profile_.get()) ->AddEnabled(extension));
diff --git a/chrome/browser/crash_upload_list.cc b/chrome/browser/crash_upload_list.cc index 9e30d84..95aa101 100644 --- a/chrome/browser/crash_upload_list.cc +++ b/chrome/browser/crash_upload_list.cc
@@ -17,14 +17,14 @@ scoped_refptr<CrashUploadList> CreateCrashUploadList( UploadList::Delegate* delegate) { +#if defined(OS_MACOSX) || defined(OS_WIN) + return new CrashUploadListCrashpad(delegate, + content::BrowserThread::GetBlockingPool()); +#else base::FilePath crash_dir_path; PathService::Get(chrome::DIR_CRASH_DUMPS, &crash_dir_path); base::FilePath upload_log_path = crash_dir_path.AppendASCII(CrashUploadList::kReporterLogFilename); -#if defined(OS_MACOSX) || defined(OS_WIN) - return new CrashUploadListCrashpad(delegate, upload_log_path, - content::BrowserThread::GetBlockingPool()); -#else return new CrashUploadList(delegate, upload_log_path, content::BrowserThread::GetBlockingPool()); #endif
diff --git a/chrome/browser/crash_upload_list_crashpad.cc b/chrome/browser/crash_upload_list_crashpad.cc index a2a4bbdd..6d2ee263 100644 --- a/chrome/browser/crash_upload_list_crashpad.cc +++ b/chrome/browser/crash_upload_list_crashpad.cc
@@ -6,19 +6,55 @@ #include "base/threading/sequenced_worker_pool.h" #include "base/time/time.h" +#include "chrome/common/chrome_constants.h" #include "components/crash/content/app/crashpad.h" +namespace { + +#if defined(OS_WIN) +typedef void (*GetUploadedReportsPointer)( + const crash_reporter::UploadedReport** reports, + size_t* report_count); + +void GetUploadedReportsThunk( + std::vector<crash_reporter::UploadedReport>* uploaded_reports) { + static GetUploadedReportsPointer get_uploaded_reports = []() { + HMODULE exe_module = GetModuleHandle(chrome::kBrowserProcessExecutableName); + return reinterpret_cast<GetUploadedReportsPointer>( + exe_module ? GetProcAddress(exe_module, "GetUploadedReportsImpl") + : nullptr); + }(); + + if (get_uploaded_reports) { + const crash_reporter::UploadedReport* reports; + size_t report_count; + get_uploaded_reports(&reports, &report_count); + *uploaded_reports = std::vector<crash_reporter::UploadedReport>( + reports, reports + report_count); + } +} +#endif // OS_WIN + +} // namespace + CrashUploadListCrashpad::CrashUploadListCrashpad( Delegate* delegate, - const base::FilePath& upload_log_path, const scoped_refptr<base::SequencedWorkerPool>& worker_pool) - : CrashUploadList(delegate, upload_log_path, worker_pool) {} + : CrashUploadList(delegate, base::FilePath(), worker_pool) {} CrashUploadListCrashpad::~CrashUploadListCrashpad() {} void CrashUploadListCrashpad::LoadUploadList() { std::vector<crash_reporter::UploadedReport> uploaded_reports; +#if defined(OS_WIN) + // On Windows, we only link crash client into chrome.exe (not the dlls), and + // it does the registration. That means the global that holds the crash report + // database lives in the .exe, so we need to grab a pointer to a helper in the + // exe to get our uploaded reports list. + GetUploadedReportsThunk(&uploaded_reports); +#else crash_reporter::GetUploadedReports(&uploaded_reports); +#endif ClearUploads(); for (const crash_reporter::UploadedReport& uploaded_report :
diff --git a/chrome/browser/crash_upload_list_crashpad.h b/chrome/browser/crash_upload_list_crashpad.h index d884640e..2f8281b5 100644 --- a/chrome/browser/crash_upload_list_crashpad.h +++ b/chrome/browser/crash_upload_list_crashpad.h
@@ -17,12 +17,8 @@ // Crashpad database. class CrashUploadListCrashpad : public CrashUploadList { public: - // The |upload_log_path| argument is unused. It is only accepted because the - // base class constructor requires it, although it is entirely unused with - // LoadUploadList() being overridden. CrashUploadListCrashpad( Delegate* delegate, - const base::FilePath& upload_log_path, const scoped_refptr<base::SequencedWorkerPool>& worker_pool); protected:
diff --git a/chrome/browser/devtools/device/adb/adb_client_socket_browsertest.cc b/chrome/browser/devtools/device/adb/adb_client_socket_browsertest.cc index 0f30260..e770085 100644 --- a/chrome/browser/devtools/device/adb/adb_client_socket_browsertest.cc +++ b/chrome/browser/devtools/device/adb/adb_client_socket_browsertest.cc
@@ -134,21 +134,24 @@ DevToolsAndroidBridge::RemoteDevices devices_; }; -IN_PROC_BROWSER_TEST_F(AdbClientSocketTest, TestFlushWithoutSize) { +// Flaky due to failure to bind a hardcoded port. crbug.com/566057 +IN_PROC_BROWSER_TEST_F(AdbClientSocketTest, DISABLED_TestFlushWithoutSize) { StartMockAdbServer(FlushWithoutSize); StartTest(); CheckDevices(); StopMockAdbServer(); } -IN_PROC_BROWSER_TEST_F(AdbClientSocketTest, TestFlushWithSize) { +// Flaky due to failure to bind a hardcoded port. crbug.com/566057 +IN_PROC_BROWSER_TEST_F(AdbClientSocketTest, DISABLED_TestFlushWithSize) { StartMockAdbServer(FlushWithSize); StartTest(); CheckDevices(); StopMockAdbServer(); } -IN_PROC_BROWSER_TEST_F(AdbClientSocketTest, TestFlushWithData) { +// Flaky due to failure to bind a hardcoded port. crbug.com/566057 +IN_PROC_BROWSER_TEST_F(AdbClientSocketTest, DISABLED_TestFlushWithData) { StartMockAdbServer(FlushWithData); StartTest(); CheckDevices();
diff --git a/chrome/browser/devtools/device/usb/android_rsa.cc b/chrome/browser/devtools/device/usb/android_rsa.cc index eb34077..9581067 100644 --- a/chrome/browser/devtools/device/usb/android_rsa.cc +++ b/chrome/browser/devtools/device/usb/android_rsa.cc
@@ -4,6 +4,10 @@ #include "chrome/browser/devtools/device/usb/android_rsa.h" +#include <stdint.h> + +#include <limits> + #include "base/base64.h" #include "base/memory/scoped_ptr.h" #include "chrome/browser/profiles/profile.h" @@ -27,21 +31,25 @@ "WO5ywp0UWRiGZCkK+wOFQIDAQAB"; typedef struct RSAPublicKey { - int len; // Length of n[] in number of uint32 - uint32 n0inv; // -1 / n[0] mod 2^32 - uint32 n[kRSANumWords]; // modulus as little endian array - uint32 rr[kRSANumWords]; // R^2 as little endian array - int exponent; // 3 or 65537 + int len; // Length of n[] in number of uint32_t + uint32_t n0inv; // -1 / n[0] mod 2^32 + uint32_t n[kRSANumWords]; // modulus as little endian array + uint32_t rr[kRSANumWords]; // R^2 as little endian array + int exponent; // 3 or 65537 } RSAPublicKey; // http://en.wikipedia.org/wiki/Extended_Euclidean_algorithm // a * x + b * y = gcd(a, b) = d -void ExtendedEuclid(uint64 a, uint64 b, uint64 *x, uint64 *y, uint64 *d) { - uint64 x1 = 0, x2 = 1, y1 = 1, y2 = 0; +void ExtendedEuclid(uint64_t a, + uint64_t b, + uint64_t* x, + uint64_t* y, + uint64_t* d) { + uint64_t x1 = 0, x2 = 1, y1 = 1, y2 = 0; while (b > 0) { - uint64 q = a / b; - uint64 r = a % b; + uint64_t q = a / b; + uint64_t r = a % b; *x = x2 - q * x1; *y = y2 - q * y1; a = b; @@ -57,63 +65,62 @@ *y = y2; } -uint32 ModInverse(uint64 a, uint64 m) -{ - uint64 d, x, y; +uint32_t ModInverse(uint64_t a, uint64_t m) { + uint64_t d, x, y; ExtendedEuclid(a, m, &x, &y, &d); if (d == 1) - return static_cast<uint32>(x); + return static_cast<uint32_t>(x); return 0; } -uint32* BnNew() { - uint32* result = new uint32[kBigIntSize]; - memset(result, 0, kBigIntSize * sizeof(uint32)); +uint32_t* BnNew() { + uint32_t* result = new uint32_t[kBigIntSize]; + memset(result, 0, kBigIntSize * sizeof(uint32_t)); return result; } -void BnFree(uint32* a) { +void BnFree(uint32_t* a) { delete[] a; } -uint32* BnCopy(uint32* a) { - uint32* result = new uint32[kBigIntSize]; - memcpy(result, a, kBigIntSize * sizeof(uint32)); +uint32_t* BnCopy(uint32_t* a) { + uint32_t* result = new uint32_t[kBigIntSize]; + memcpy(result, a, kBigIntSize * sizeof(uint32_t)); return result; } -uint32* BnMul(uint32* a, uint32 b) { - uint32* result = BnNew(); - uint64 carry_over = 0; +uint32_t* BnMul(uint32_t* a, uint32_t b) { + uint32_t* result = BnNew(); + uint64_t carry_over = 0; for (size_t i = 0; i < kBigIntSize; ++i) { - carry_over += static_cast<uint64>(a[i]) * b; - result[i] = carry_over & kuint32max; + carry_over += static_cast<uint64_t>(a[i]) * b; + result[i] = carry_over & std::numeric_limits<uint32_t>::max(); carry_over >>= 32; } return result; } -void BnSub(uint32* a, uint32* b) { +void BnSub(uint32_t* a, uint32_t* b) { int carry_over = 0; for (size_t i = 0; i < kBigIntSize; ++i) { - int64 sub = static_cast<int64>(a[i]) - b[i] - carry_over; + int64_t sub = static_cast<int64_t>(a[i]) - b[i] - carry_over; carry_over = 0; if (sub < 0) { carry_over = 1; sub += 0x100000000LL; } - a[i] = static_cast<uint32>(sub); + a[i] = static_cast<uint32_t>(sub); } } -void BnLeftShift(uint32* a, int offset) { +void BnLeftShift(uint32_t* a, int offset) { for (int i = kBigIntSize - offset - 1; i >= 0; --i) a[i + offset] = a[i]; for (int i = 0; i < offset; ++i) a[i] = 0; } -int BnCompare(uint32* a, uint32* b) { +int BnCompare(uint32_t* a, uint32_t* b) { for (int i = kBigIntSize - 1; i >= 0; --i) { if (a[i] > b[i]) return 1; @@ -123,12 +130,12 @@ return 0; } -uint64 BnGuess(uint32* a, uint32* b, uint64 from, uint64 to) { +uint64_t BnGuess(uint32_t* a, uint32_t* b, uint64_t from, uint64_t to) { if (from + 1 >= to) return from; - uint64 guess = (from + to) / 2; - uint32* t = BnMul(b, static_cast<uint32>(guess)); + uint64_t guess = (from + to) / 2; + uint32_t* t = BnMul(b, static_cast<uint32_t>(guess)); int result = BnCompare(a, t); BnFree(t); if (result > 0) @@ -138,7 +145,7 @@ return guess; } -void BnDiv(uint32* a, uint32* b, uint32** pq, uint32** pr) { +void BnDiv(uint32_t* a, uint32_t* b, uint32_t** pq, uint32_t** pr) { if (BnCompare(a, b) < 0) { if (pq) *pq = BnNew(); @@ -151,18 +158,19 @@ int ob = kBigIntSize - 1; for (; oa > 0 && !a[oa]; --oa) {} for (; ob > 0 && !b[ob]; --ob) {} - uint32* q = BnNew(); - uint32* ca = BnCopy(a); + uint32_t* q = BnNew(); + uint32_t* ca = BnCopy(a); int digit = a[oa] < b[ob] ? oa - ob - 1 : oa - ob; for (; digit >= 0; --digit) { - uint32* shifted_b = BnCopy(b); + uint32_t* shifted_b = BnCopy(b); BnLeftShift(shifted_b, digit); - uint32 value = static_cast<uint32>( - BnGuess(ca, shifted_b, 0, static_cast<uint64>(kuint32max) + 1)); + uint32_t value = static_cast<uint32_t>(BnGuess( + ca, shifted_b, 0, + static_cast<uint64_t>(std::numeric_limits<uint32_t>::max()) + 1)); q[digit] = value; - uint32* t = BnMul(shifted_b, value); + uint32_t* t = BnMul(shifted_b, value); BnSub(ca, t); BnFree(t); BnFree(shifted_b); @@ -186,12 +194,12 @@ std::string decoded_key; scoped_ptr<crypto::RSAPrivateKey> key; if (!encoded_key.empty() && base::Base64Decode(encoded_key, &decoded_key)) { - std::vector<uint8> key_info(decoded_key.begin(), decoded_key.end()); + std::vector<uint8_t> key_info(decoded_key.begin(), decoded_key.end()); key.reset(crypto::RSAPrivateKey::CreateFromPrivateKeyInfo(key_info)); } if (!key) { key.reset(crypto::RSAPrivateKey::Create(2048)); - std::vector<uint8> key_info; + std::vector<uint8_t> key_info; if (!key || !key->ExportPrivateKey(&key_info)) return NULL; @@ -204,7 +212,7 @@ } std::string AndroidRSAPublicKey(crypto::RSAPrivateKey* key) { - std::vector<uint8> public_key; + std::vector<uint8_t> public_key; if (!key) return kDummyRSAPublicKey; @@ -216,10 +224,10 @@ return kDummyRSAPublicKey; // Skip 10 byte asn1 prefix to the modulus. - std::vector<uint8> pk_data(pk.data() + 10, pk.data() + pk.length()); - uint32* n = BnNew(); + std::vector<uint8_t> pk_data(pk.data() + 10, pk.data() + pk.length()); + uint32_t* n = BnNew(); for (size_t i = 0; i < kRSANumWords; ++i) { - uint32 t = pk_data[4 * i]; + uint32_t t = pk_data[4 * i]; t = t << 8; t += pk_data[4 * i + 1]; t = t << 8; @@ -228,7 +236,7 @@ t += pk_data[4 * i + 3]; n[kRSANumWords - i - 1] = t; } - uint64 n0 = n[0]; + uint64_t n0 = n[0]; RSAPublicKey pkey; pkey.len = kRSANumWords; @@ -237,10 +245,10 @@ if (pkey.n0inv == 0) return kDummyRSAPublicKey; - uint32* r = BnNew(); + uint32_t* r = BnNew(); r[kRSANumWords * 2] = 1; - uint32* rr; + uint32_t* rr; BnDiv(r, n, NULL, &rr); for (size_t i = 0; i < kRSANumWords; ++i) { @@ -260,8 +268,8 @@ std::string AndroidRSASign(crypto::RSAPrivateKey* key, const std::string& body) { - std::vector<uint8> digest(body.begin(), body.end()); - std::vector<uint8> result; + std::vector<uint8_t> digest(body.begin(), body.end()); + std::vector<uint8_t> result; if (!crypto::SignatureCreator::Sign(key, crypto::SignatureCreator::SHA1, digest.data(), digest.size(), &result)) { return std::string();
diff --git a/chrome/browser/dom_distiller/profile_utils.cc b/chrome/browser/dom_distiller/profile_utils.cc index 3eab2bb..a94ade8b 100644 --- a/chrome/browser/dom_distiller/profile_utils.cc +++ b/chrome/browser/dom_distiller/profile_utils.cc
@@ -11,6 +11,7 @@ #include "chrome/browser/profiles/profile.h" #include "chrome/common/chrome_isolated_world_ids.h" #include "chrome/common/chrome_switches.h" +#include "chrome/common/features.h" #include "components/dom_distiller/content/browser/distiller_javascript_utils.h" #include "components/dom_distiller/content/browser/distiller_ui_handle.h" #include "components/dom_distiller/content/browser/dom_distiller_viewer_source.h" @@ -21,9 +22,9 @@ #include "chrome/browser/ui/webui/print_preview/print_preview_distiller.h" #endif // defined(ENABLE_PRINT_PREVIEW) -#if defined(OS_ANDROID) +#if BUILDFLAG(ANDROID_JAVA_UI) #include "chrome/browser/android/dom_distiller/distiller_ui_handle_android.h" -#endif // defined(OS_ANDROID) +#endif // BUILDFLAG(ANDROID_JAVA_UI) void RegisterDomDistillerViewerSource(Profile* profile) { bool enabled_distiller = base::CommandLine::ForCurrentProcess()->HasSwitch( @@ -42,10 +43,10 @@ profile, dom_distiller_service_factory); scoped_ptr<dom_distiller::DistillerUIHandle> ui_handle; -#if defined(OS_ANDROID) +#if BUILDFLAG(ANDROID_JAVA_UI) ui_handle.reset( new dom_distiller::android::DistillerUIHandleAndroid()); -#endif // defined(OS_ANDROID) +#endif // BUILDFLAG(ANDROID_JAVA_UI) // Set the JavaScript world ID. if (!dom_distiller::DistillerJavaScriptWorldIdIsSet()) {
diff --git a/chrome/browser/download/chrome_download_manager_delegate.cc b/chrome/browser/download/chrome_download_manager_delegate.cc index 3d609fb..17f3076 100644 --- a/chrome/browser/download/chrome_download_manager_delegate.cc +++ b/chrome/browser/download/chrome_download_manager_delegate.cc
@@ -40,6 +40,7 @@ #include "chrome/browser/ui/browser_finder.h" #include "chrome/browser/ui/scoped_tabbed_browser_displayer.h" #include "chrome/common/chrome_constants.h" +#include "chrome/common/features.h" #include "chrome/common/pref_names.h" #include "components/pref_registry/pref_registry_syncable.h" #include "content/public/browser/download_item.h" @@ -49,7 +50,7 @@ #include "net/base/filename_util.h" #include "net/base/mime_util.h" -#if defined(OS_ANDROID) +#if BUILDFLAG(ANDROID_JAVA_UI) #include "chrome/browser/android/download/chrome_download_manager_overwrite_infobar_delegate.h" #include "chrome/browser/infobars/infobar_service.h" #endif @@ -579,7 +580,7 @@ const base::FilePath& suggested_path, const DownloadTargetDeterminerDelegate::FileSelectedCallback& callback) { DCHECK_CURRENTLY_ON(BrowserThread::UI); -#if defined(OS_ANDROID) +#if BUILDFLAG(ANDROID_JAVA_UI) chrome::android::ChromeDownloadManagerOverwriteInfoBarDelegate::Create( InfoBarService::FromWebContents(download->GetWebContents()), suggested_path, callback);
diff --git a/chrome/browser/download/download_query.cc b/chrome/browser/download/download_query.cc index 415b622..c6310dc 100644 --- a/chrome/browser/download/download_query.cc +++ b/chrome/browser/download/download_query.cc
@@ -4,7 +4,10 @@ #include "chrome/browser/download/download_query.h" +#include <stdint.h> + #include <algorithm> +#include <limits> #include <string> #include <vector> @@ -69,11 +72,11 @@ // The next several functions are helpers for making Callbacks that access // DownloadItem fields. -static int64 GetStartTimeMsEpoch(const DownloadItem& item) { +static int64_t GetStartTimeMsEpoch(const DownloadItem& item) { return (item.GetStartTime() - base::Time::UnixEpoch()).InMilliseconds(); } -static int64 GetEndTimeMsEpoch(const DownloadItem& item) { +static int64_t GetEndTimeMsEpoch(const DownloadItem& item) { return (item.GetEndTime() - base::Time::UnixEpoch()).InMilliseconds(); } @@ -239,7 +242,8 @@ return true; } -DownloadQuery::DownloadQuery() : limit_(kuint32max), skip_(0U) {} +DownloadQuery::DownloadQuery() + : limit_(std::numeric_limits<uint32_t>::max()), skip_(0U) {} DownloadQuery::~DownloadQuery() {} // AddFilter() pushes a new FilterCallback to filters_. Most FilterCallbacks are @@ -388,10 +392,11 @@ DownloadQuery::SortDirection direction) { switch (type) { case SORT_END_TIME: - sorters_.push_back(Sorter::Build<int64>(direction, &GetEndTimeMsEpoch)); + sorters_.push_back(Sorter::Build<int64_t>(direction, &GetEndTimeMsEpoch)); break; case SORT_START_TIME: - sorters_.push_back(Sorter::Build<int64>(direction, &GetStartTimeMsEpoch)); + sorters_.push_back( + Sorter::Build<int64_t>(direction, &GetStartTimeMsEpoch)); break; case SORT_URL: sorters_.push_back(Sorter::Build<std::string>(direction, &GetUrl));
diff --git a/chrome/browser/download/download_request_limiter.cc b/chrome/browser/download/download_request_limiter.cc index c2d40049..4650c7a 100644 --- a/chrome/browser/download/download_request_limiter.cc +++ b/chrome/browser/download/download_request_limiter.cc
@@ -11,6 +11,7 @@ #include "chrome/browser/infobars/infobar_service.h" #include "chrome/browser/profiles/profile.h" #include "chrome/browser/tab_contents/tab_util.h" +#include "chrome/common/features.h" #include "components/content_settings/core/browser/host_content_settings_map.h" #include "content/public/browser/browser_context.h" #include "content/public/browser/browser_thread.h" @@ -24,7 +25,7 @@ #include "content/public/browser/web_contents_delegate.h" #include "url/gurl.h" -#if defined(OS_ANDROID) +#if BUILDFLAG(ANDROID_JAVA_UI) #include "chrome/browser/download/download_request_infobar_delegate_android.h" #else #include "chrome/browser/download/download_permission_request.h" @@ -99,7 +100,7 @@ return; } -#if defined(OS_ANDROID) +#if BUILDFLAG(ANDROID_JAVA_UI) bool promptable = InfoBarService::FromWebContents(web_contents()) != nullptr; #else bool promptable = @@ -133,7 +134,7 @@ if (is_showing_prompt()) return; -#if defined(OS_ANDROID) +#if BUILDFLAG(ANDROID_JAVA_UI) DownloadRequestInfoBarDelegateAndroid::Create( InfoBarService::FromWebContents(web_contents_), factory_.GetWeakPtr()); #else
diff --git a/chrome/browser/download/download_resource_throttle_unittest.cc b/chrome/browser/download/download_resource_throttle_unittest.cc index dd4365d..8c320f7 100644 --- a/chrome/browser/download/download_resource_throttle_unittest.cc +++ b/chrome/browser/download/download_resource_throttle_unittest.cc
@@ -7,6 +7,7 @@ #include "chrome/browser/download/download_request_limiter.h" #include "chrome/browser/download/download_resource_throttle.h" #include "chrome/browser/tab_contents/tab_util.h" +#include "chrome/common/features.h" #include "chrome/test/base/chrome_render_view_host_test_harness.h" #include "content/public/browser/browser_thread.h" #include "content/public/browser/render_process_host.h" @@ -18,7 +19,7 @@ #include "testing/gmock/include/gmock/gmock.h" #include "testing/gtest/include/gtest/gtest.h" -#if defined(OS_ANDROID) +#if BUILDFLAG(ANDROID_JAVA_UI) #include "chrome/browser/android/download/mock_download_controller_android.h" #endif @@ -62,7 +63,7 @@ ChromeRenderViewHostTestHarness::SetUp(); web_contents()->SetDelegate(&delegate_); run_loop_.reset(new base::RunLoop()); -#if defined(OS_ANDROID) +#if BUILDFLAG(ANDROID_JAVA_UI) content::DownloadControllerAndroid::SetDownloadControllerAndroid( &download_controller_); #endif @@ -71,7 +72,7 @@ void TearDown() override { content::BrowserThread::DeleteSoon(content::BrowserThread::IO, FROM_HERE, throttle_); -#if defined(OS_ANDROID) +#if BUILDFLAG(ANDROID_JAVA_UI) content::DownloadControllerAndroid::SetDownloadControllerAndroid(nullptr); #endif ChromeRenderViewHostTestHarness::TearDown(); @@ -104,7 +105,7 @@ scoped_refptr<DownloadRequestLimiter> limiter_; ::testing::NiceMock<MockResourceController> resource_controller_; scoped_ptr<base::RunLoop> run_loop_; -#if defined(OS_ANDROID) +#if BUILDFLAG(ANDROID_JAVA_UI) chrome::android::MockDownloadControllerAndroid download_controller_; #endif }; @@ -115,7 +116,7 @@ StartThrottle(); } -#if defined(OS_ANDROID) +#if BUILDFLAG(ANDROID_JAVA_UI) TEST_F(DownloadResourceThrottleTest, DownloadWithFailedFileAcecssRequest) { content::DownloadControllerAndroid::Get() ->SetApproveFileAccessRequestForTesting(false);
diff --git a/chrome/browser/engagement/site_engagement_service.cc b/chrome/browser/engagement/site_engagement_service.cc index b875eb6..52cbaf0 100644 --- a/chrome/browser/engagement/site_engagement_service.cc +++ b/chrome/browser/engagement/site_engagement_service.cc
@@ -15,6 +15,7 @@ #include "base/time/clock.h" #include "base/time/default_clock.h" #include "base/values.h" +#include "chrome/browser/banners/app_banner_settings_helper.h" #include "chrome/browser/content_settings/host_content_settings_map_factory.h" #include "chrome/browser/engagement/site_engagement_eviction_policy.h" #include "chrome/browser/engagement/site_engagement_helper.h" @@ -281,7 +282,8 @@ // return true immediately. if (base::CommandLine::ForCurrentProcess()->HasSwitch( switches::kEnableSiteEngagementService) || - SiteEngagementEvictionPolicy::IsEnabled()) { + SiteEngagementEvictionPolicy::IsEnabled() || + AppBannerSettingsHelper::ShouldUseSiteEngagementScore()) { return true; }
diff --git a/chrome/browser/engagement/site_engagement_service.h b/chrome/browser/engagement/site_engagement_service.h index 6489fff..46bf9896 100644 --- a/chrome/browser/engagement/site_engagement_service.h +++ b/chrome/browser/engagement/site_engagement_service.h
@@ -180,6 +180,7 @@ FRIEND_TEST_ALL_PREFIXES(SiteEngagementServiceTest, GetTotalUserInputPoints); FRIEND_TEST_ALL_PREFIXES(SiteEngagementServiceTest, CleanupOriginsOnHistoryDeletion); + FRIEND_TEST_ALL_PREFIXES(AppBannerSettingsHelperTest, SiteEngagementTrigger); // Only used in tests. SiteEngagementService(Profile* profile, scoped_ptr<base::Clock> clock);
diff --git a/chrome/browser/extensions/extension_action.cc b/chrome/browser/extensions/extension_action.cc index c6033e53f..3b2225452 100644 --- a/chrome/browser/extensions/extension_action.cc +++ b/chrome/browser/extensions/extension_action.cc
@@ -8,6 +8,7 @@ #include "base/base64.h" #include "base/logging.h" +#include "base/strings/string_number_conversions.h" #include "extensions/browser/extension_icon_image.h" #include "extensions/browser/extension_icon_placeholder.h" #include "extensions/common/constants.h" @@ -22,6 +23,7 @@ #include "third_party/skia/include/core/SkCanvas.h" #include "third_party/skia/include/core/SkPaint.h" #include "third_party/skia/include/effects/SkGradientShader.h" +#include "ui/base/resource/material_design/material_design_controller.h" #include "ui/base/resource/resource_bundle.h" #include "ui/gfx/animation/animation_delegate.h" #include "ui/gfx/canvas.h" @@ -43,23 +45,6 @@ IDR_EXTENSIONS_FAVICON); } -// Given the extension action type, returns the size the extension action icon -// should have. The icon should be square, so only one dimension is -// returned. -int GetIconSizeForType(extensions::ActionInfo::Type type) { - switch (type) { - case extensions::ActionInfo::TYPE_BROWSER: - case extensions::ActionInfo::TYPE_PAGE: - case extensions::ActionInfo::TYPE_SYSTEM_INDICATOR: - // TODO(dewittj) Report the actual icon size of the system - // indicator. - return extension_misc::EXTENSION_ICON_ACTION; - default: - NOTREACHED(); - return 0; - } -} - class GetAttentionImageSource : public gfx::ImageSkiaSource { public: explicit GetAttentionImageSource(const gfx::ImageSkia& icon) @@ -86,9 +71,6 @@ ui::ScaleFactor scale; }; -const IconRepresentationInfo kIconSizes[] = {{"19", ui::SCALE_FACTOR_100P}, - {"38", ui::SCALE_FACTOR_200P}}; - template <class T> bool HasValue(const std::map<int, T>& map, int tab_id) { return map.find(tab_id) != map.end(); @@ -96,9 +78,13 @@ } // namespace +extension_misc::ExtensionIcons ExtensionAction::ActionIconSize() { + return ui::MaterialDesignController::IsModeMaterial() + ? extension_misc::EXTENSION_ICON_BITTY + : extension_misc::EXTENSION_ICON_ACTION; +} + const int ExtensionAction::kDefaultTabId = -1; -const int ExtensionAction::kPageActionIconMaxSize = - extension_misc::EXTENSION_ICON_ACTION; ExtensionAction::ExtensionAction(const extensions::Extension& extension, extensions::ActionInfo::Type action_type, @@ -140,14 +126,18 @@ bool ExtensionAction::ParseIconFromCanvasDictionary( const base::DictionaryValue& dict, gfx::ImageSkia* icon) { - // Try to extract an icon for each known scale. - for (size_t i = 0; i < arraysize(kIconSizes); i++) { + for (base::DictionaryValue::Iterator iter(dict); !iter.IsAtEnd(); + iter.Advance()) { + int icon_size = 0; + if (!base::StringToInt(iter.key(), &icon_size)) + continue; + const base::BinaryValue* image_data; std::string binary_string64; IPC::Message pickle; - if (dict.GetBinary(kIconSizes[i].size_string, &image_data)) { + if (iter.value().GetAsBinary(&image_data)) { pickle = IPC::Message(image_data->GetBuffer(), image_data->GetSize()); - } else if (dict.GetString(kIconSizes[i].size_string, &binary_string64)) { + } else if (iter.value().GetAsString(&binary_string64)) { std::string binary_string; if (!base::Base64Decode(binary_string64, &binary_string)) return false; @@ -155,12 +145,13 @@ } else { continue; } - base::PickleIterator iter(pickle); + base::PickleIterator pickle_iter(pickle); SkBitmap bitmap; - if (!IPC::ReadParam(&pickle, &iter, &bitmap)) + if (!IPC::ReadParam(&pickle, &pickle_iter, &bitmap)) return false; CHECK(!bitmap.isNull()); - float scale = ui::GetScaleForScaleFactor(kIconSizes[i].scale); + float scale = + static_cast<float>(icon_size) / ExtensionAction::ActionIconSize(); icon->AddRepresentation(gfx::ImageSkiaRep(bitmap, scale)); } return true; @@ -240,12 +231,8 @@ content::BrowserContext* browser_context) { if (default_icon_ && !default_icon_image_) { default_icon_image_.reset(new extensions::IconImage( - browser_context, - &extension, - *default_icon(), - GetIconSizeForType(action_type_), - *GetDefaultIcon().ToImageSkia(), - nullptr)); + browser_context, &extension, *default_icon(), ActionIconSize(), + *GetDefaultIcon().ToImageSkia(), nullptr)); } return default_icon_image_.get(); } @@ -262,8 +249,8 @@ // default (puzzle piece). if (extensions::FeatureSwitch::extension_action_redesign()->IsEnabled()) { placeholder_icon_image_ = - extensions::ExtensionIconPlaceholder::CreateImage( - extension_misc::EXTENSION_ICON_ACTION, extension_name_); + extensions::ExtensionIconPlaceholder::CreateImage(ActionIconSize(), + extension_name_); } else { placeholder_icon_image_ = GetDefaultIcon(); } @@ -316,32 +303,14 @@ set_id(manifest_data.id); // Initialize the specified icon set. - if (!manifest_data.default_icon.empty()) + if (!manifest_data.default_icon.empty()) { default_icon_.reset(new ExtensionIconSet(manifest_data.default_icon)); - - const ExtensionIconSet& extension_icons = - extensions::IconsInfo::GetIcons(&extension); - // Look for any other icons. - std::string largest_icon = extension_icons.Get( - extension_misc::EXTENSION_ICON_GIGANTOR, ExtensionIconSet::MATCH_SMALLER); - - if (!largest_icon.empty()) { - // We found an icon to use, so create an icon set if one doesn't exist. - if (!default_icon_) - default_icon_.reset(new ExtensionIconSet()); - int largest_icon_size = extension_icons.GetIconSizeFromPath(largest_icon); - // Replace any missing extension action icons with the largest icon - // retrieved from |extension|'s manifest so long as the largest icon is - // larger than the current key. - for (int i = extension_misc::kNumExtensionActionIconSizes - 1; i >= 0; - --i) { - int size = extension_misc::kExtensionActionIconSizes[i].size; - if (default_icon_->Get(size, ExtensionIconSet::MATCH_BIGGER).empty() && - largest_icon_size > size) { - default_icon_->Add(size, largest_icon); - break; - } - } + } else { + // Fall back to the product icons if no action icon exists. + const ExtensionIconSet& product_icons = + extensions::IconsInfo::GetIcons(&extension); + if (!product_icons.empty()) + default_icon_.reset(new ExtensionIconSet(product_icons)); } } @@ -354,7 +323,7 @@ // If there is a default icon, the icon width will be set depending on our // action type. if (default_icon_) - return GetIconSizeForType(action_type()); + return ActionIconSize(); // If no icon has been set and there is no default icon, we need favicon // width.
diff --git a/chrome/browser/extensions/extension_action.h b/chrome/browser/extensions/extension_action.h index ff29481..866c1e4 100644 --- a/chrome/browser/extensions/extension_action.h +++ b/chrome/browser/extensions/extension_action.h
@@ -12,6 +12,7 @@ #include "base/memory/scoped_ptr.h" #include "base/stl_util.h" #include "chrome/common/extensions/api/extension_action/action_info.h" +#include "extensions/common/constants.h" #include "third_party/skia/include/core/SkColor.h" #include "ui/gfx/image/image.h" @@ -47,13 +48,12 @@ // the UI. }; + static extension_misc::ExtensionIcons ActionIconSize(); + // Use this ID to indicate the default state for properties that take a tab_id // parameter. static const int kDefaultTabId; - // Max size (both dimensions) for page actions. - static const int kPageActionIconMaxSize; - ExtensionAction(const extensions::Extension& extension, extensions::ActionInfo::Type action_type, const extensions::ActionInfo& manifest_data);
diff --git a/chrome/browser/extensions/extension_action_manager_unittest.cc b/chrome/browser/extensions/extension_action_manager_unittest.cc index b29328e..d040762 100644 --- a/chrome/browser/extensions/extension_action_manager_unittest.cc +++ b/chrome/browser/extensions/extension_action_manager_unittest.cc
@@ -98,9 +98,9 @@ const ExtensionAction& action, int action_key) { return action.default_icon()->Get(action_key, - ExtensionIconSet::MATCH_EXACTLY) == - IconsInfo::GetIcons(&extension).Get(extension_key, - ExtensionIconSet::MATCH_EXACTLY); + ExtensionIconSet::MATCH_BIGGER) == + IconsInfo::GetIcons(&extension) + .Get(extension_key, ExtensionIconSet::MATCH_EXACTLY); } ExtensionAction* ExtensionActionManagerTest::GetAction( @@ -127,7 +127,7 @@ ASSERT_TRUE(action); ASSERT_TRUE(TitlesMatch(*extension.get(), *action)); - ASSERT_TRUE(IconsMatch(*extension.get(), 128, *action, 38)); + ASSERT_TRUE(IconsMatch(*extension.get(), 48, *action, 38)); // Test that the action's missing default_icons are not replaced with smaller // icons.
diff --git a/chrome/browser/extensions/extension_action_storage_manager.cc b/chrome/browser/extensions/extension_action_storage_manager.cc index a7de1e6..401e077 100644 --- a/chrome/browser/extensions/extension_action_storage_manager.cc +++ b/chrome/browser/extensions/extension_action_storage_manager.cc
@@ -75,8 +75,7 @@ } // Conversion function for reading/writing to storage. -std::string RepresentationToString(const gfx::ImageSkia& image, float scale) { - SkBitmap bitmap = image.GetRepresentation(scale).sk_bitmap(); +std::string BitmapToString(const SkBitmap& bitmap) { SkAutoLockPixels lock_image(bitmap); std::vector<unsigned char> data; bool success = gfx::PNGCodec::EncodeBGRASkBitmap(bitmap, false, &data); @@ -95,9 +94,6 @@ ExtensionAction* action) { const int kDefaultTabId = ExtensionAction::kDefaultTabId; std::string str_value; - int int_value; - SkBitmap bitmap; - gfx::ImageSkia icon; // For each value, don't set it if it has been modified already. if (dict->GetString(kPopupUrlStorageKey, &str_value) && @@ -121,9 +117,11 @@ !action->HasBadgeTextColor(kDefaultTabId)) { action->SetBadgeTextColor(kDefaultTabId, RawStringToSkColor(str_value)); } - if (dict->GetInteger(kAppearanceStorageKey, &int_value) && + + int appearance_storage = 0; + if (dict->GetInteger(kAppearanceStorageKey, &appearance_storage) && !action->HasIsVisible(kDefaultTabId)) { - switch (int_value) { + switch (appearance_storage) { case INVISIBLE: case OBSOLETE_WANTS_ATTENTION: action->SetIsVisible(kDefaultTabId, false); @@ -137,13 +135,18 @@ const base::DictionaryValue* icon_value = NULL; if (dict->GetDictionary(kIconStorageKey, &icon_value) && !action->HasIcon(kDefaultTabId)) { - for (size_t i = 0; i < extension_misc::kNumExtensionActionIconSizes; i++) { - const extension_misc::IconRepresentationInfo& icon_info = - extension_misc::kExtensionActionIconSizes[i]; - if (icon_value->GetString(icon_info.size_string, &str_value) && - StringToSkBitmap(str_value, &bitmap)) { + gfx::ImageSkia icon; + SkBitmap bitmap; + for (base::DictionaryValue::Iterator iter(*icon_value); !iter.IsAtEnd(); + iter.Advance()) { + int icon_size = 0; + std::string icon_string; + if (base::StringToInt(iter.key(), &icon_size) && + iter.value().GetAsString(&icon_string) && + StringToSkBitmap(icon_string, &bitmap)) { CHECK(!bitmap.isNull()); - float scale = ui::GetScaleForScaleFactor(icon_info.scale); + float scale = + static_cast<float>(icon_size) / ExtensionAction::ActionIconSize(); icon.AddRepresentation(gfx::ImageSkiaRep(bitmap, scale)); } } @@ -173,18 +176,15 @@ action->GetExplicitlySetIcon(kDefaultTabId).AsImageSkia(); if (!icon.isNull()) { scoped_ptr<base::DictionaryValue> icon_value(new base::DictionaryValue()); - for (size_t i = 0; i < extension_misc::kNumExtensionActionIconSizes; i++) { - const extension_misc::IconRepresentationInfo& icon_info = - extension_misc::kExtensionActionIconSizes[i]; - float scale = ui::GetScaleForScaleFactor(icon_info.scale); - if (icon.HasRepresentation(scale)) { - icon_value->SetString(icon_info.size_string, - RepresentationToString(icon, scale)); - } + std::vector<gfx::ImageSkiaRep> image_reps = icon.image_reps(); + for (const gfx::ImageSkiaRep& rep : image_reps) { + int size = static_cast<int>(rep.scale() * icon.width()); + std::string size_string = base::IntToString(size); + icon_value->SetString(size_string, BitmapToString(rep.sk_bitmap())); } - dict->Set(kIconStorageKey, icon_value.release()); + dict->Set(kIconStorageKey, icon_value.Pass()); } - return dict.Pass(); + return dict; } } // namespace
diff --git a/chrome/browser/extensions/install_verifier.cc b/chrome/browser/extensions/install_verifier.cc index b5bdbd7..2ede600 100644 --- a/chrome/browser/extensions/install_verifier.cc +++ b/chrome/browser/extensions/install_verifier.cc
@@ -67,7 +67,11 @@ return ENFORCE_STRICT; } +#if defined(OS_WIN) + VerifyStatus default_status = ENFORCE; +#else VerifyStatus default_status = NONE; +#endif if (group == "EnforceStrict") return ENFORCE_STRICT;
diff --git a/chrome/browser/extensions/service_worker_apitest.cc b/chrome/browser/extensions/service_worker_apitest.cc index 9870d41..0d7a9a97 100644 --- a/chrome/browser/extensions/service_worker_apitest.cc +++ b/chrome/browser/extensions/service_worker_apitest.cc
@@ -171,7 +171,8 @@ // ExtensionApiTest overrides. void SetUpCommandLine(base::CommandLine* command_line) override { - command_line->AppendSwitch(switches::kEnablePushMessagePayload); + command_line->AppendSwitch( + switches::kEnableExperimentalWebPlatformFeatures); ServiceWorkerTest::SetUpCommandLine(command_line); } void SetUpOnMainThread() override {
diff --git a/chrome/browser/geolocation/geolocation_permission_context_factory.cc b/chrome/browser/geolocation/geolocation_permission_context_factory.cc index 27742b6..2f9625b 100644 --- a/chrome/browser/geolocation/geolocation_permission_context_factory.cc +++ b/chrome/browser/geolocation/geolocation_permission_context_factory.cc
@@ -6,10 +6,11 @@ #include "chrome/browser/profiles/incognito_helpers.h" #include "chrome/browser/profiles/profile.h" +#include "chrome/common/features.h" #include "chrome/common/pref_names.h" #include "components/keyed_service/content/browser_context_dependency_manager.h" #include "components/pref_registry/pref_registry_syncable.h" -#if defined(OS_ANDROID) +#if BUILDFLAG(ANDROID_JAVA_UI) #include "chrome/browser/geolocation/geolocation_permission_context_android.h" #else #include "chrome/browser/geolocation/geolocation_permission_context.h" @@ -29,7 +30,7 @@ return base::Singleton<GeolocationPermissionContextFactory>::get(); } -#if !defined(OS_ANDROID) +#if !BUILDFLAG(ANDROID_JAVA_UI) GeolocationPermissionContextFactory::GeolocationPermissionContextFactory() : PermissionContextFactoryBase( "GeolocationPermissionContext", @@ -50,7 +51,7 @@ KeyedService* GeolocationPermissionContextFactory::BuildServiceInstanceFor( content::BrowserContext* profile) const { -#if !defined(OS_ANDROID) +#if !BUILDFLAG(ANDROID_JAVA_UI) return new GeolocationPermissionContext(static_cast<Profile*>(profile)); #else return new GeolocationPermissionContextAndroid( @@ -60,7 +61,7 @@ void GeolocationPermissionContextFactory::RegisterProfilePrefs( user_prefs::PrefRegistrySyncable* registry) { -#if defined(OS_ANDROID) +#if BUILDFLAG(ANDROID_JAVA_UI) registry->RegisterBooleanPref(prefs::kGeolocationEnabled, true); #endif }
diff --git a/chrome/browser/geolocation/geolocation_permission_context_unittest.cc b/chrome/browser/geolocation/geolocation_permission_context_unittest.cc index e33acba..42273ac 100644 --- a/chrome/browser/geolocation/geolocation_permission_context_unittest.cc +++ b/chrome/browser/geolocation/geolocation_permission_context_unittest.cc
@@ -25,6 +25,7 @@ #include "chrome/browser/permissions/permission_request_id.h" #include "chrome/browser/ui/website_settings/permission_bubble_request.h" #include "chrome/common/chrome_switches.h" +#include "chrome/common/features.h" #include "chrome/test/base/chrome_render_view_host_test_harness.h" #include "chrome/test/base/testing_profile.h" #include "components/content_settings/core/browser/host_content_settings_map.h" @@ -44,7 +45,7 @@ #include "content/public/test/web_contents_tester.h" #include "testing/gtest/include/gtest/gtest.h" -#if defined(OS_ANDROID) +#if BUILDFLAG(ANDROID_JAVA_UI) #include "base/prefs/pref_service.h" #include "chrome/browser/android/mock_location_settings.h" #include "chrome/browser/geolocation/geolocation_permission_context_android.h" @@ -143,7 +144,7 @@ void AddNewTab(const GURL& url); void CheckTabContentsState(const GURL& requesting_frame, ContentSetting expected_content_setting); -#if !defined(OS_ANDROID) +#if !BUILDFLAG(ANDROID_JAVA_UI) size_t GetBubblesQueueSize(PermissionBubbleManager* manager); void AcceptBubble(PermissionBubbleManager* manager); void DenyBubble(PermissionBubbleManager* manager); @@ -239,7 +240,7 @@ #if defined(ENABLE_EXTENSIONS) extensions::SetViewType(new_tab, extensions::VIEW_TYPE_TAB_CONTENTS); #endif -#if defined(OS_ANDROID) +#if BUILDFLAG(ANDROID_JAVA_UI) InfoBarService::CreateForWebContents(new_tab); #else PermissionBubbleManager::CreateForWebContents(new_tab); @@ -279,7 +280,7 @@ TabSpecificContentSettings::CreateForWebContents(web_contents()); geolocation_permission_context_ = GeolocationPermissionContextFactory::GetForProfile(profile()); -#if defined(OS_ANDROID) +#if BUILDFLAG(ANDROID_JAVA_UI) static_cast<GeolocationPermissionContextAndroid*>( geolocation_permission_context_) ->SetLocationSettingsForTesting( @@ -299,7 +300,7 @@ ChromeRenderViewHostTestHarness::TearDown(); } -#if !defined(OS_ANDROID) +#if !BUILDFLAG(ANDROID_JAVA_UI) size_t GeolocationPermissionContextTests::GetBubblesQueueSize( PermissionBubbleManager* manager) { return manager->requests_.size(); @@ -328,7 +329,7 @@ void GeolocationPermissionContextTests::BubbleManagerDocumentLoadCompleted( content::WebContents* web_contents) { -#if !defined(OS_ANDROID) +#if !BUILDFLAG(ANDROID_JAVA_UI) PermissionBubbleManager::FromWebContents(web_contents)-> DocumentOnLoadCompletedInMainFrame(); #endif @@ -344,7 +345,7 @@ } size_t GeolocationPermissionContextTests::GetNumberOfPrompts() { -#if !defined(OS_ANDROID) +#if !BUILDFLAG(ANDROID_JAVA_UI) PermissionBubbleManager* manager = PermissionBubbleManager::FromWebContents(web_contents()); return GetBubblesQueueSize(manager); @@ -354,7 +355,7 @@ } void GeolocationPermissionContextTests::AcceptPrompt() { -#if !defined(OS_ANDROID) +#if !BUILDFLAG(ANDROID_JAVA_UI) PermissionBubbleManager* manager = PermissionBubbleManager::FromWebContents(web_contents()); AcceptBubble(manager); @@ -367,7 +368,7 @@ } base::string16 GeolocationPermissionContextTests::GetPromptText() { -#if !defined(OS_ANDROID) +#if !BUILDFLAG(ANDROID_JAVA_UI) PermissionBubbleManager* manager = PermissionBubbleManager::FromWebContents(web_contents()); return manager->requests_.front()->GetMessageText(); @@ -392,7 +393,7 @@ ASSERT_EQ(1U, GetNumberOfPrompts()); } -#if defined(OS_ANDROID) +#if BUILDFLAG(ANDROID_JAVA_UI) TEST_F(GeolocationPermissionContextTests, SinglePermissionInfobar) { GURL requesting_frame("http://www.example.com/geolocation"); NavigateAndCommit(requesting_frame); @@ -490,7 +491,7 @@ CheckTabContentsState(requesting_frame_0, CONTENT_SETTING_ALLOW); CheckPermissionMessageSent(0, true); -#if defined(OS_ANDROID) +#if BUILDFLAG(ANDROID_JAVA_UI) infobars::InfoBar* infobar_0 = infobar_service()->infobar_at(0); infobar_service()->RemoveInfoBar(infobar_0); EXPECT_EQ(1U, closed_infobar_tracker_.size()); @@ -506,7 +507,7 @@ EXPECT_NE(text_0, text_1); // Cancel (block) this frame. -#if !defined(OS_ANDROID) +#if !BUILDFLAG(ANDROID_JAVA_UI) PermissionBubbleManager* manager = PermissionBubbleManager::FromWebContents(web_contents()); DenyBubble(manager); @@ -536,7 +537,7 @@ // Check permission is requested. ASSERT_EQ(0U, GetNumberOfPrompts()); -#if defined(OS_ANDROID) +#if BUILDFLAG(ANDROID_JAVA_UI) const bool user_gesture = false; #else const bool user_gesture = true; @@ -556,7 +557,7 @@ CheckPermissionMessageSent(0, true); // Cleanup. -#if defined(OS_ANDROID) +#if BUILDFLAG(ANDROID_JAVA_UI) infobars::InfoBar* infobar = infobar_service()->infobar_at(0); infobar_service()->RemoveInfoBar(infobar); EXPECT_EQ(1U, closed_infobar_tracker_.size()); @@ -566,7 +567,7 @@ // TODO(felt): The bubble is rejecting file:// permission requests. // Fix and enable this test. crbug.com/444047 -#if defined(OS_ANDROID) +#if BUILDFLAG(ANDROID_JAVA_UI) #define MAYBE_PermissionForFileScheme PermissionForFileScheme #else #define MAYBE_PermissionForFileScheme DISABLED_PermissionForFileScheme @@ -618,7 +619,7 @@ ASSERT_FALSE(text_0.empty()); // Simulate the frame going away; the request should be removed. -#if !defined(OS_ANDROID) +#if !BUILDFLAG(ANDROID_JAVA_UI) PermissionBubbleManager* manager = PermissionBubbleManager::FromWebContents(web_contents()); CloseBubble(manager); @@ -667,7 +668,7 @@ BubbleManagerDocumentLoadCompleted(); BubbleManagerDocumentLoadCompleted(extra_tabs_[0]); BubbleManagerDocumentLoadCompleted(extra_tabs_[1]); -#if !defined(OS_ANDROID) +#if !BUILDFLAG(ANDROID_JAVA_UI) PermissionBubbleManager* manager_a0 = PermissionBubbleManager::FromWebContents(web_contents()); PermissionBubbleManager* manager_b = @@ -684,7 +685,7 @@ RequestGeolocationPermission( extra_tabs_[1], RequestIDForTab(1, 0), url_a, true); ASSERT_EQ(1U, GetNumberOfPrompts()); // For A0. -#if !defined(OS_ANDROID) +#if !BUILDFLAG(ANDROID_JAVA_UI) ASSERT_EQ(1U, GetBubblesQueueSize(manager_b)); ASSERT_EQ(1U, GetBubblesQueueSize(manager_a1)); #else @@ -693,7 +694,7 @@ #endif // Accept the permission in tab A0. -#if !defined(OS_ANDROID) +#if !BUILDFLAG(ANDROID_JAVA_UI) AcceptBubble(manager_a0); #else infobars::InfoBar* infobar_a0 = infobar_service()->infobar_at(0); @@ -710,7 +711,7 @@ // disappear. It does not cause the bubble to disappear: crbug.com/443013. // TODO(felt): Update this test when the bubble's behavior is changed. // Either way, tab B should still have a pending permission request. -#if !defined(OS_ANDROID) +#if !BUILDFLAG(ANDROID_JAVA_UI) ASSERT_EQ(1U, GetBubblesQueueSize(manager_a1)); ASSERT_EQ(1U, GetBubblesQueueSize(manager_b)); #else @@ -724,7 +725,7 @@ GURL url_b("http://www.example-2.com/geolocation"); NavigateAndCommit(url_a); // Tab A0. AddNewTab(url_a); // Tab A1. -#if !defined(OS_ANDROID) +#if !BUILDFLAG(ANDROID_JAVA_UI) BubbleManagerDocumentLoadCompleted(); BubbleManagerDocumentLoadCompleted(extra_tabs_[0]); PermissionBubbleManager* manager_a0 = @@ -741,7 +742,7 @@ extra_tabs_[0], RequestIDForTab(0, 0), url_a, true); RequestGeolocationPermission( extra_tabs_[0], RequestIDForTab(0, 1), url_b, true); -#if !defined(OS_ANDROID) +#if !BUILDFLAG(ANDROID_JAVA_UI) ASSERT_EQ(1U, GetBubblesQueueSize(manager_a0)); ASSERT_EQ(1U, GetBubblesQueueSize(manager_a1)); #else @@ -750,7 +751,7 @@ #endif // Accept the first request in tab A1. -#if !defined(OS_ANDROID) +#if !BUILDFLAG(ANDROID_JAVA_UI) AcceptBubble(manager_a1); #else infobars::InfoBar* infobar_a1 = infobar_service_for_tab(0)->infobar_at(0); @@ -767,7 +768,7 @@ // Because they're the same origin, this will cause tab A0's infobar to // disappear. It does not cause the bubble to disappear: crbug.com/443013. // TODO(felt): Update this test when the bubble's behavior is changed. -#if !defined(OS_ANDROID) +#if !BUILDFLAG(ANDROID_JAVA_UI) EXPECT_EQ(1U, GetBubblesQueueSize(manager_a0)); #else EXPECT_EQ(0U, infobar_service()->infobar_count()); @@ -775,14 +776,14 @@ #endif // The second request should now be visible in tab A1. -#if !defined(OS_ANDROID) +#if !BUILDFLAG(ANDROID_JAVA_UI) ASSERT_EQ(1U, GetBubblesQueueSize(manager_a1)); #else ASSERT_EQ(1U, infobar_service_for_tab(0)->infobar_count()); #endif // Accept the second request and check that it's gone. -#if !defined(OS_ANDROID) +#if !BUILDFLAG(ANDROID_JAVA_UI) AcceptBubble(manager_a1); EXPECT_EQ(0U, GetBubblesQueueSize(manager_a1)); #else @@ -817,7 +818,7 @@ ASSERT_EQ(1U, GetNumberOfPrompts()); // Delete the tab contents. -#if defined(OS_ANDROID) +#if BUILDFLAG(ANDROID_JAVA_UI) infobars::InfoBar* infobar = infobar_service()->infobar_at(0); DeleteContents(); ASSERT_EQ(1U, closed_infobar_tracker_.size()); @@ -915,7 +916,7 @@ // Accept the first frame. AcceptPrompt(); -#if defined(OS_ANDROID) +#if BUILDFLAG(ANDROID_JAVA_UI) infobar_service()->RemoveInfoBar(infobar_service()->infobar_at(0)); #endif CheckTabContentsState(requesting_frame_0, CONTENT_SETTING_ALLOW); @@ -940,7 +941,7 @@ AcceptPrompt(); CheckTabContentsState(requesting_frame_1, CONTENT_SETTING_ALLOW); CheckPermissionMessageSent(1, true); -#if defined(OS_ANDROID) +#if BUILDFLAG(ANDROID_JAVA_UI) infobar_service()->RemoveInfoBar(infobar_service()->infobar_at(0)); #endif
diff --git a/chrome/browser/history/chrome_history_backend_client.cc b/chrome/browser/history/chrome_history_backend_client.cc index 1d0e841..595994b 100644 --- a/chrome/browser/history/chrome_history_backend_client.cc +++ b/chrome/browser/history/chrome_history_backend_client.cc
@@ -5,18 +5,19 @@ #include "chrome/browser/history/chrome_history_backend_client.h" #include "chrome/common/channel_info.h" +#include "chrome/common/features.h" #include "components/bookmarks/browser/bookmark_model.h" #include "components/version_info/version_info.h" #include "url/gurl.h" -#if defined(OS_ANDROID) +#if BUILDFLAG(ANDROID_JAVA_UI) #include "base/files/file_path.h" #include "base/logging.h" #include "chrome/browser/history/android/android_provider_backend.h" #include "components/history/core/browser/history_backend.h" #endif -#if defined(OS_ANDROID) +#if BUILDFLAG(ANDROID_JAVA_UI) namespace { const base::FilePath::CharType kAndroidCacheFilename[] = FILE_PATH_LITERAL("AndroidCache"); @@ -70,7 +71,7 @@ channel != version_info::Channel::BETA; } -#if defined(OS_ANDROID) +#if BUILDFLAG(ANDROID_JAVA_UI) void ChromeHistoryBackendClient::OnHistoryBackendInitialized( history::HistoryBackend* history_backend, history::HistoryDatabase* history_database, @@ -91,4 +92,4 @@ const base::FilePath& history_dir) { sql::Connection::Delete(history_dir.Append(kAndroidCacheFilename)); } -#endif // defined(OS_ANDROID) +#endif // BUILDFLAG(ANDROID_JAVA_UI)
diff --git a/chrome/browser/importer/importer_list.cc b/chrome/browser/importer/importer_list.cc index e006503..be62f423 100644 --- a/chrome/browser/importer/importer_list.cc +++ b/chrome/browser/importer/importer_list.cc
@@ -29,30 +29,29 @@ namespace { #if defined(OS_WIN) -void DetectIEProfiles(std::vector<importer::SourceProfile*>* profiles) { +void DetectIEProfiles(std::vector<importer::SourceProfile>* profiles) { DCHECK_CURRENTLY_ON(BrowserThread::FILE); // IE always exists and doesn't have multiple profiles. - importer::SourceProfile* ie = new importer::SourceProfile; - ie->importer_name = l10n_util::GetStringUTF16(IDS_IMPORT_FROM_IE); - ie->importer_type = importer::TYPE_IE; - ie->source_path.clear(); - ie->app_path.clear(); - ie->services_supported = importer::HISTORY | importer::FAVORITES | - importer::COOKIES | importer::PASSWORDS | importer::SEARCH_ENGINES; + importer::SourceProfile ie; + ie.importer_name = l10n_util::GetStringUTF16(IDS_IMPORT_FROM_IE); + ie.importer_type = importer::TYPE_IE; + ie.services_supported = importer::HISTORY | importer::FAVORITES | + importer::COOKIES | importer::PASSWORDS | + importer::SEARCH_ENGINES; profiles->push_back(ie); } -void DetectEdgeProfiles(std::vector<importer::SourceProfile*>* profiles) { - importer::SourceProfile* edge = new importer::SourceProfile; - edge->importer_name = l10n_util::GetStringUTF16(IDS_IMPORT_FROM_EDGE); - edge->importer_type = importer::TYPE_EDGE; - edge->services_supported = importer::FAVORITES; - edge->source_path = importer::GetEdgeDataFilePath(); +void DetectEdgeProfiles(std::vector<importer::SourceProfile>* profiles) { + importer::SourceProfile edge; + edge.importer_name = l10n_util::GetStringUTF16(IDS_IMPORT_FROM_EDGE); + edge.importer_type = importer::TYPE_EDGE; + edge.services_supported = importer::FAVORITES; + edge.source_path = importer::GetEdgeDataFilePath(); profiles->push_back(edge); } void DetectBuiltinWindowsProfiles( - std::vector<importer::SourceProfile*>* profiles) { + std::vector<importer::SourceProfile>* profiles) { // Make the assumption on Windows 10 that Edge exists and is probably default. if (importer::EdgeImporterCanImport()) DetectEdgeProfiles(profiles); @@ -62,18 +61,16 @@ #endif // defined(OS_WIN) #if defined(OS_MACOSX) -void DetectSafariProfiles(std::vector<importer::SourceProfile*>* profiles) { +void DetectSafariProfiles(std::vector<importer::SourceProfile>* profiles) { DCHECK_CURRENTLY_ON(BrowserThread::FILE); uint16 items = importer::NONE; if (!SafariImporterCanImport(base::mac::GetUserLibraryPath(), &items)) return; - importer::SourceProfile* safari = new importer::SourceProfile; - safari->importer_name = l10n_util::GetStringUTF16(IDS_IMPORT_FROM_SAFARI); - safari->importer_type = importer::TYPE_SAFARI; - safari->source_path.clear(); - safari->app_path.clear(); - safari->services_supported = items; + importer::SourceProfile safari; + safari.importer_name = l10n_util::GetStringUTF16(IDS_IMPORT_FROM_SAFARI); + safari.importer_type = importer::TYPE_SAFARI; + safari.services_supported = items; profiles->push_back(safari); } #endif // defined(OS_MACOSX) @@ -82,7 +79,7 @@ // locale-specific search engines feature (see firefox_importer.cc for // details). void DetectFirefoxProfiles(const std::string locale, - std::vector<importer::SourceProfile*>* profiles) { + std::vector<importer::SourceProfile>* profiles) { DCHECK_CURRENTLY_ON(BrowserThread::FILE); base::FilePath profile_path = GetFirefoxProfilePath(); if (profile_path.empty()) @@ -105,28 +102,28 @@ return; } - importer::SourceProfile* firefox = new importer::SourceProfile; - firefox->importer_name = GetFirefoxImporterName(app_path); - firefox->importer_type = firefox_type; - firefox->source_path = profile_path; + importer::SourceProfile firefox; + firefox.importer_name = GetFirefoxImporterName(app_path); + firefox.importer_type = firefox_type; + firefox.source_path = profile_path; #if defined(OS_WIN) - firefox->app_path = GetFirefoxInstallPathFromRegistry(); + firefox.app_path = GetFirefoxInstallPathFromRegistry(); #endif - if (firefox->app_path.empty()) - firefox->app_path = app_path; - firefox->services_supported = importer::HISTORY | importer::FAVORITES | - importer::PASSWORDS | importer::SEARCH_ENGINES | - importer::AUTOFILL_FORM_DATA; - firefox->locale = locale; + if (firefox.app_path.empty()) + firefox.app_path = app_path; + firefox.services_supported = importer::HISTORY | importer::FAVORITES | + importer::PASSWORDS | importer::SEARCH_ENGINES | + importer::AUTOFILL_FORM_DATA; + firefox.locale = locale; profiles->push_back(firefox); } -std::vector<importer::SourceProfile*> DetectSourceProfilesWorker( +std::vector<importer::SourceProfile> DetectSourceProfilesWorker( const std::string& locale, bool include_interactive_profiles) { DCHECK_CURRENTLY_ON(BrowserThread::FILE); - std::vector<importer::SourceProfile*> profiles; + std::vector<importer::SourceProfile> profiles; // The first run import will automatically take settings from the first // profile detected, which should be the user's current default. @@ -150,11 +147,11 @@ DetectFirefoxProfiles(locale, &profiles); #endif if (include_interactive_profiles) { - importer::SourceProfile* bookmarks_profile = new importer::SourceProfile; - bookmarks_profile->importer_name = + importer::SourceProfile bookmarks_profile; + bookmarks_profile.importer_name = l10n_util::GetStringUTF16(IDS_IMPORT_FROM_BOOKMARKS_HTML_FILE); - bookmarks_profile->importer_type = importer::TYPE_BOOKMARKS_FILE; - bookmarks_profile->services_supported = importer::FAVORITES; + bookmarks_profile.importer_type = importer::TYPE_BOOKMARKS_FILE; + bookmarks_profile.services_supported = importer::FAVORITES; profiles.push_back(bookmarks_profile); } @@ -191,12 +188,12 @@ const importer::SourceProfile& ImporterList::GetSourceProfileAt( size_t index) const { DCHECK_LT(index, count()); - return *source_profiles_[index]; + return source_profiles_[index]; } void ImporterList::SourceProfilesLoaded( const base::Closure& profiles_loaded_callback, - const std::vector<importer::SourceProfile*>& profiles) { + const std::vector<importer::SourceProfile>& profiles) { DCHECK_CURRENTLY_ON(BrowserThread::UI); source_profiles_.assign(profiles.begin(), profiles.end());
diff --git a/chrome/browser/importer/importer_list.h b/chrome/browser/importer/importer_list.h index 03ba8be3..2a5e4d9c 100644 --- a/chrome/browser/importer/importer_list.h +++ b/chrome/browser/importer/importer_list.h
@@ -10,13 +10,9 @@ #include "base/basictypes.h" #include "base/callback_forward.h" -#include "base/memory/scoped_vector.h" #include "base/memory/weak_ptr.h" #include "base/strings/string16.h" - -namespace importer { -struct SourceProfile; -} +#include "chrome/common/importer/importer_data_types.h" // ImporterList detects installed browsers and profiles via // DetectSourceProfilesWorker(). ImporterList lives on the UI thread. @@ -47,14 +43,14 @@ const importer::SourceProfile& GetSourceProfileAt(size_t index) const; private: - // Called when the source profiles are loaded. Takes ownership of the - // loaded profiles in |profiles| and calls |profiles_loaded_callback|. + // Called when the source profiles are loaded. Copies the loaded profiles + // in |profiles| and calls |profiles_loaded_callback|. void SourceProfilesLoaded( const base::Closure& profiles_loaded_callback, - const std::vector<importer::SourceProfile*>& profiles); + const std::vector<importer::SourceProfile>& profiles); // The list of profiles with the default one first. - ScopedVector<importer::SourceProfile> source_profiles_; + std::vector<importer::SourceProfile> source_profiles_; base::WeakPtrFactory<ImporterList> weak_ptr_factory_;
diff --git a/chrome/browser/io_thread.cc b/chrome/browser/io_thread.cc index a5ae645c..cc33dc19 100644 --- a/chrome/browser/io_thread.cc +++ b/chrome/browser/io_thread.cc
@@ -116,7 +116,7 @@ #include "net/cert_net/nss_ocsp.h" #endif -#if defined(OS_ANDROID) +#if BUILDFLAG(ANDROID_JAVA_UI) #include "base/android/build_info.h" #include "chrome/browser/android/data_usage/external_data_use_observer.h" #include "chrome/browser/android/net/external_estimate_provider_android.h" @@ -636,7 +636,7 @@ #endif scoped_ptr<data_usage::DataUseAmortizer> data_use_amortizer; -#if defined(OS_ANDROID) +#if BUILDFLAG(ANDROID_JAVA_UI) data_use_amortizer.reset(new data_usage::android::TrafficStatsAmortizer()); #endif @@ -658,7 +658,7 @@ globals_->data_use_aggregator.get(), true /* is_data_usage_off_the_record */); -#if defined(OS_ANDROID) +#if BUILDFLAG(ANDROID_JAVA_UI) globals_->external_data_use_observer.reset( new chrome::android::ExternalDataUseObserver( globals_->data_use_aggregator.get(), @@ -679,7 +679,7 @@ &network_quality_estimator_params); scoped_ptr<net::ExternalEstimateProvider> external_estimate_provider; -#if defined(OS_ANDROID) +#if BUILDFLAG(ANDROID_JAVA_UI) external_estimate_provider.reset( new chrome::android::ExternalEstimateProviderAndroid()); #endif
diff --git a/chrome/browser/io_thread.h b/chrome/browser/io_thread.h index 96e10964..e8b4ac3 100644 --- a/chrome/browser/io_thread.h +++ b/chrome/browser/io_thread.h
@@ -19,6 +19,7 @@ #include "base/strings/string_piece.h" #include "base/time/time.h" #include "chrome/browser/net/chrome_network_delegate.h" +#include "chrome/common/features.h" #include "components/ssl_config/ssl_config_service_manager.h" #include "content/public/browser/browser_thread.h" #include "content/public/browser/browser_thread_delegate.h" @@ -35,13 +36,13 @@ class CommandLine; } -#if defined(OS_ANDROID) +#if BUILDFLAG(ANDROID_JAVA_UI) namespace chrome { namespace android { class ExternalDataUseObserver; } } -#endif // defined(OS_ANDROID) +#endif // BUILDFLAG(ANDROID_JAVA_UI) namespace chrome_browser_net { class DnsProbeService; @@ -138,11 +139,11 @@ // Global aggregator of data use. It must outlive the // |system_network_delegate|. scoped_ptr<data_usage::DataUseAggregator> data_use_aggregator; -#if defined(OS_ANDROID) +#if BUILDFLAG(ANDROID_JAVA_UI) // An external observer of data use. scoped_ptr<chrome::android::ExternalDataUseObserver> external_data_use_observer; -#endif // defined(OS_ANDROID) +#endif // BUILDFLAG(ANDROID_JAVA_UI) // The "system" NetworkDelegate, used for Profile-agnostic network events. scoped_ptr<net::NetworkDelegate> system_network_delegate; scoped_ptr<net::HostResolver> host_resolver;
diff --git a/chrome/browser/media/media_stream_devices_controller.cc b/chrome/browser/media/media_stream_devices_controller.cc index c01e52e..44f449b 100644 --- a/chrome/browser/media/media_stream_devices_controller.cc +++ b/chrome/browser/media/media_stream_devices_controller.cc
@@ -22,6 +22,7 @@ #include "chrome/browser/profiles/profile.h" #include "chrome/browser/ui/browser.h" #include "chrome/common/chrome_switches.h" +#include "chrome/common/features.h" #include "chrome/common/pref_names.h" #include "chrome/grit/generated_resources.h" #include "components/content_settings/core/browser/host_content_settings_map.h" @@ -37,14 +38,14 @@ #include "grit/theme_resources.h" #include "ui/base/l10n/l10n_util.h" -#if defined(OS_ANDROID) +#if BUILDFLAG(ANDROID_JAVA_UI) #include <vector> #include "chrome/browser/android/preferences/pref_service_bridge.h" #include "chrome/browser/permissions/permission_update_infobar_delegate_android.h" #include "content/public/browser/android/content_view_core.h" #include "ui/android/window_android.h" -#endif // OS_ANDROID +#endif // BUILDFLAG(ANDROID_JAVA_UI) using content::BrowserThread; @@ -170,7 +171,7 @@ return; } -#if defined(OS_ANDROID) +#if BUILDFLAG(ANDROID_JAVA_UI) std::vector<ContentSettingsType> content_settings_types; if (IsAllowedForAudio()) content_settings_types.push_back(CONTENT_SETTINGS_TYPE_MEDIASTREAM_MIC); @@ -584,7 +585,7 @@ bool MediaStreamDevicesController::IsUserAcceptAllowed( ContentSettingsType content_type) const { -#if defined(OS_ANDROID) +#if BUILDFLAG(ANDROID_JAVA_UI) content::ContentViewCore* cvc = content::ContentViewCore::FromWebContents(web_contents_); if (!cvc)
diff --git a/chrome/browser/media/permission_bubble_media_access_handler.cc b/chrome/browser/media/permission_bubble_media_access_handler.cc index 4c89392..abdec56d 100644 --- a/chrome/browser/media/permission_bubble_media_access_handler.cc +++ b/chrome/browser/media/permission_bubble_media_access_handler.cc
@@ -9,6 +9,7 @@ #include "chrome/browser/media/media_stream_device_permissions.h" #include "chrome/browser/media/media_stream_devices_controller.h" #include "chrome/browser/profiles/profile.h" +#include "chrome/common/features.h" #include "chrome/common/pref_names.h" #include "components/content_settings/core/browser/host_content_settings_map.h" #include "content/public/browser/browser_thread.h" @@ -16,7 +17,7 @@ #include "content/public/browser/notification_types.h" #include "content/public/browser/web_contents.h" -#if defined(OS_ANDROID) +#if BUILDFLAG(ANDROID_JAVA_UI) #include <vector> #include "base/bind.h" @@ -25,9 +26,9 @@ #include "chrome/browser/permissions/permission_update_infobar_delegate_android.h" #else #include "chrome/browser/ui/website_settings/permission_bubble_manager.h" -#endif // OS_ANDROID +#endif // BUILDFLAG(ANDROID_JAVA_UI) -#if defined(OS_ANDROID) +#if BUILDFLAG(ANDROID_JAVA_UI) namespace { // Callback for the permission update infobar when the site and Chrome // permissions are mismatched on Android. @@ -40,7 +41,7 @@ } } // namespace -#endif // OS_ANDROID +#endif // BUILDFLAG(ANDROID_JAVA_UI) using content::BrowserThread; @@ -141,7 +142,7 @@ &PermissionBubbleMediaAccessHandler::OnAccessRequestResponse, base::Unretained(this), web_contents))); if (!controller->IsAskingForAudio() && !controller->IsAskingForVideo()) { -#if defined(OS_ANDROID) +#if BUILDFLAG(ANDROID_JAVA_UI) // If either audio or video was previously allowed and Chrome no longer has // the necessary permissions, show a infobar to attempt to address this // mismatch. @@ -165,7 +166,7 @@ return; } -#if defined(OS_ANDROID) +#if BUILDFLAG(ANDROID_JAVA_UI) MediaStreamInfoBarDelegateAndroid::Create(web_contents, controller.Pass()); #else PermissionBubbleManager* bubble_manager =
diff --git a/chrome/browser/media/router/media_router.mojom b/chrome/browser/media/router/media_router.mojom index 6289a2d..060ad71b 100644 --- a/chrome/browser/media/router/media_router.mojom +++ b/chrome/browser/media/router/media_router.mojom
@@ -18,6 +18,8 @@ string sink_id; // The human-readable name, e.g. "Janet's Chromecast". string name; + // Optional description of the sink. + string? description; // The type of icon to show in the UI for this media sink. IconType icon_type; };
diff --git a/chrome/browser/media/router/media_router_dialog_controller.cc b/chrome/browser/media/router/media_router_dialog_controller.cc index 0d8506a..757bc9d 100644 --- a/chrome/browser/media/router/media_router_dialog_controller.cc +++ b/chrome/browser/media/router/media_router_dialog_controller.cc
@@ -5,11 +5,12 @@ #include "chrome/browser/media/router/media_router_dialog_controller.h" #include "chrome/browser/media/router/media_router_metrics.h" +#include "chrome/common/features.h" #include "content/public/browser/browser_thread.h" #include "content/public/browser/web_contents.h" #include "content/public/browser/web_contents_delegate.h" -#if defined(OS_ANDROID) +#if BUILDFLAG(ANDROID_JAVA_UI) #include "chrome/browser/media/android/router/media_router_dialog_controller_android.h" #else #include "chrome/browser/ui/webui/media_router/media_router_dialog_controller_impl.h" @@ -21,7 +22,7 @@ MediaRouterDialogController* MediaRouterDialogController::GetOrCreateForWebContents( content::WebContents* contents) { -#if defined(OS_ANDROID) +#if BUILDFLAG(ANDROID_JAVA_UI) return MediaRouterDialogControllerAndroid::GetOrCreateForWebContents( contents); #else
diff --git a/chrome/browser/media/router/media_router_type_converters.cc b/chrome/browser/media/router/media_router_type_converters.cc index 627bf9de..6541dbfb 100644 --- a/chrome/browser/media/router/media_router_type_converters.cc +++ b/chrome/browser/media/router/media_router_type_converters.cc
@@ -59,8 +59,12 @@ media_router::MediaSink TypeConverter<media_router::MediaSink, MediaSinkPtr>::Convert( const MediaSinkPtr& input) { - return media_router::MediaSink(input->sink_id, input->name, - SinkIconTypeFromMojo(input->icon_type)); + media_router::MediaSink sink(input->sink_id, input->name, + SinkIconTypeFromMojo(input->icon_type)); + if (!input->description.get().empty()) + sink.set_description(input->description); + + return sink; } // static
diff --git a/chrome/browser/media/router/media_router_type_converters_unittest.cc b/chrome/browser/media/router/media_router_type_converters_unittest.cc index 0f6d20e..6838d006 100644 --- a/chrome/browser/media/router/media_router_type_converters_unittest.cc +++ b/chrome/browser/media/router/media_router_type_converters_unittest.cc
@@ -12,9 +12,12 @@ TEST(MediaRouterTypeConvertersTest, ConvertMediaSink) { MediaSink expected_media_sink("sinkId1", "Sink 1", MediaSink::IconType::CAST); + expected_media_sink.set_description("description"); + interfaces::MediaSinkPtr mojo_sink(interfaces::MediaSink::New()); mojo_sink->sink_id = "sinkId1"; mojo_sink->name = "Sink 1"; + mojo_sink->description = "description"; mojo_sink->icon_type = media_router::interfaces::MediaSink::IconType::ICON_TYPE_CAST; @@ -25,7 +28,8 @@ // Convert MediaSink and back should result in identical object. EXPECT_EQ(expected_media_sink.name(), media_sink.name()); EXPECT_EQ(expected_media_sink.id(), media_sink.id()); - EXPECT_EQ(expected_media_sink.icon_type(), media_sink.icon_type()); + EXPECT_FALSE(media_sink.description().empty()); + EXPECT_EQ(expected_media_sink.description(), media_sink.description()); EXPECT_EQ(expected_media_sink.icon_type(), media_sink.icon_type()); EXPECT_TRUE(expected_media_sink.Equals(media_sink)); }
diff --git a/chrome/browser/media/router/media_sink.cc b/chrome/browser/media/router/media_sink.cc index 66768c3..0b59c5f 100644 --- a/chrome/browser/media/router/media_sink.cc +++ b/chrome/browser/media/router/media_sink.cc
@@ -18,8 +18,4 @@ return sink_id_ == other.sink_id_; } -bool MediaSink::Empty() const { - return sink_id_.empty(); -} - } // namespace media_router
diff --git a/chrome/browser/media/router/media_sink.h b/chrome/browser/media/router/media_sink.h index 23df7b19..44d2ed58 100644 --- a/chrome/browser/media/router/media_sink.h +++ b/chrome/browser/media/router/media_sink.h
@@ -30,19 +30,26 @@ const MediaSink::Id& id() const { return sink_id_; } const std::string& name() const { return name_; } - MediaSink::IconType icon_type() const { return icon_type_; } + void set_description(const std::string& description) { + description_ = description; + } + const std::string& description() const { return description_; } + IconType icon_type() const { return icon_type_; } bool Equals(const MediaSink& other) const; - bool Empty() const; private: // Unique identifier for the MediaSink. MediaSink::Id sink_id_; + // Descriptive name of the MediaSink. - // Optional, can use an empty string if no sink name is available. std::string name_; + + // Optional description of the MediaSink. + std::string description_; + // The type of icon that corresponds with the MediaSink. - MediaSink::IconType icon_type_; + IconType icon_type_; }; } // namespace media_router
diff --git a/chrome/browser/media_galleries/linux/mtp_device_delegate_impl_linux.cc b/chrome/browser/media_galleries/linux/mtp_device_delegate_impl_linux.cc index aacc58a..d00847a 100644 --- a/chrome/browser/media_galleries/linux/mtp_device_delegate_impl_linux.cc +++ b/chrome/browser/media_galleries/linux/mtp_device_delegate_impl_linux.cc
@@ -6,7 +6,9 @@ #include <errno.h> #include <fcntl.h> + #include <algorithm> +#include <limits> #include <vector> #include "base/bind.h" @@ -102,7 +104,7 @@ void CreateDirectoryOnUIThread( const std::string& storage_name, const bool read_only, - const uint32 parent_id, + const uint32_t parent_id, const std::string& directory_name, const MTPDeviceTaskHelper::CreateDirectorySuccessCallback& success_callback, const MTPDeviceTaskHelper::ErrorCallback& error_callback) { @@ -130,7 +132,7 @@ void ReadDirectoryOnUIThread( const std::string& storage_name, const bool read_only, - const uint32 directory_id, + const uint32_t directory_id, const size_t max_size, const MTPDeviceTaskHelper::ReadDirectorySuccessCallback& success_callback, const MTPDeviceTaskHelper::ErrorCallback& error_callback) { @@ -156,7 +158,7 @@ void GetFileInfoOnUIThread( const std::string& storage_name, const bool read_only, - uint32 file_id, + uint32_t file_id, const MTPDeviceTaskHelper::GetFileInfoSuccessCallback& success_callback, const MTPDeviceTaskHelper::ErrorCallback& error_callback) { DCHECK_CURRENTLY_ON(content::BrowserThread::UI); @@ -226,7 +228,7 @@ void RenameObjectOnUIThread( const std::string& storage_name, const bool read_only, - const uint32 object_id, + const uint32_t object_id, const std::string& new_name, const MTPDeviceTaskHelper::RenameObjectSuccessCallback& success_callback, const MTPDeviceTaskHelper::ErrorCallback& error_callback) { @@ -254,7 +256,7 @@ const std::string& storage_name, const bool read_only, const int source_file_descriptor, - const uint32 parent_id, + const uint32_t parent_id, const std::string& file_name, const MTPDeviceTaskHelper::CopyFileFromLocalSuccessCallback& success_callback, @@ -283,7 +285,7 @@ void DeleteObjectOnUIThread( const std::string storage_name, const bool read_only, - const uint32 object_id, + const uint32_t object_id, const MTPDeviceTaskHelper::DeleteObjectSuccessCallback success_callback, const MTPDeviceTaskHelper::ErrorCallback error_callback) { DCHECK_CURRENTLY_ON(content::BrowserThread::UI); @@ -348,8 +350,7 @@ } // A fake callback to be passed as CopyFileProgressCallback. -void FakeCopyFileProgressCallback(int64 size) { -} +void FakeCopyFileProgressCallback(int64_t size) {} } // namespace @@ -371,7 +372,7 @@ // Lives on the IO thread. class MTPDeviceDelegateImplLinux::MTPFileNode { public: - MTPFileNode(uint32 file_id, + MTPFileNode(uint32_t file_id, const std::string& file_name, MTPFileNode* parent, FileIdToMTPFileNodeMap* file_id_to_node_map); @@ -379,17 +380,17 @@ const MTPFileNode* GetChild(const std::string& name) const; - void EnsureChildExists(const std::string& name, uint32 id); + void EnsureChildExists(const std::string& name, uint32_t id); // Clears all the children, except those in |children_to_keep|. void ClearNonexistentChildren( const std::set<std::string>& children_to_keep); - bool DeleteChild(uint32 file_id); + bool DeleteChild(uint32_t file_id); bool HasChildren() const; - uint32 file_id() const { return file_id_; } + uint32_t file_id() const { return file_id_; } const std::string& file_name() const { return file_name_; } MTPFileNode* parent() { return parent_; } @@ -398,7 +399,7 @@ typedef base::ScopedPtrHashMap<std::string, scoped_ptr<MTPFileNode>> ChildNodes; - const uint32 file_id_; + const uint32_t file_id_; const std::string file_name_; ChildNodes children_; @@ -409,7 +410,7 @@ }; MTPDeviceDelegateImplLinux::MTPFileNode::MTPFileNode( - uint32 file_id, + uint32_t file_id, const std::string& file_name, MTPFileNode* parent, FileIdToMTPFileNodeMap* file_id_to_node_map) @@ -438,7 +439,7 @@ void MTPDeviceDelegateImplLinux::MTPFileNode::EnsureChildExists( const std::string& name, - uint32 id) { + uint32_t id) { DCHECK_CURRENTLY_ON(content::BrowserThread::IO); const MTPFileNode* child = GetChild(name); if (child && child->file_id() == id) @@ -465,7 +466,7 @@ } } -bool MTPDeviceDelegateImplLinux::MTPFileNode::DeleteChild(uint32 file_id) { +bool MTPDeviceDelegateImplLinux::MTPFileNode::DeleteChild(uint32_t file_id) { DCHECK_CURRENTLY_ON(content::BrowserThread::IO); for (ChildNodes::iterator it = children_.begin(); it != children_.end(); ++it) { @@ -615,7 +616,7 @@ void MTPDeviceDelegateImplLinux::ReadBytes( const base::FilePath& device_file_path, const scoped_refptr<net::IOBuffer>& buf, - int64 offset, + int64_t offset, int buf_len, const ReadBytesSuccessCallback& success_callback, const ErrorCallback& error_callback) { @@ -835,7 +836,7 @@ const ErrorCallback& error_callback) { DCHECK_CURRENTLY_ON(content::BrowserThread::IO); - uint32 file_id; + uint32_t file_id; if (CachedPathToId(file_path, &file_id)) { GetFileInfoSuccessCallback success_callback_wrapper = base::Bind(&MTPDeviceDelegateImplLinux::OnDidGetFileInfo, @@ -878,7 +879,7 @@ if (other_components.empty()) { // Either we reached the last component in the recursive case, or this is // the non-recursive case. - uint32 parent_id; + uint32_t parent_id; if (CachedPathToId(current_component.DirName(), &parent_id)) { const base::Closure closure = base::Bind(&MTPDeviceDelegateImplLinux::CreateSingleDirectory, @@ -891,7 +892,7 @@ } } else { // Ensures that parent directories are created for recursive case. - uint32 directory_id; + uint32_t directory_id; if (CachedPathToId(current_component, &directory_id)) { // Parent directory |current_component| already exists, continue creating // directories. @@ -934,7 +935,7 @@ const ErrorCallback& error_callback) { DCHECK_CURRENTLY_ON(content::BrowserThread::IO); - uint32 dir_id; + uint32_t dir_id; if (CachedPathToId(root, &dir_id)) { GetFileInfoSuccessCallback success_callback_wrapper = base::Bind(&MTPDeviceDelegateImplLinux::OnDidGetFileInfoToReadDirectory, @@ -970,7 +971,7 @@ const ErrorCallback& error_callback) { DCHECK_CURRENTLY_ON(content::BrowserThread::IO); - uint32 file_id; + uint32_t file_id; if (CachedPathToId(device_file_path, &file_id)) { scoped_ptr<SnapshotRequestInfo> request_info( new SnapshotRequestInfo(file_id, @@ -1005,12 +1006,14 @@ void MTPDeviceDelegateImplLinux::ReadBytesInternal( const base::FilePath& device_file_path, - net::IOBuffer* buf, int64 offset, int buf_len, + net::IOBuffer* buf, + int64_t offset, + int buf_len, const ReadBytesSuccessCallback& success_callback, const ErrorCallback& error_callback) { DCHECK_CURRENTLY_ON(content::BrowserThread::IO); - uint32 file_id; + uint32_t file_id; if (CachedPathToId(device_file_path, &file_id)) { ReadBytesRequest request( file_id, buf, offset, buf_len, @@ -1050,7 +1053,7 @@ if (source_file_path.DirName() == device_file_path.DirName()) { // If a file is moved in a same directory, rename the file. - uint32 file_id; + uint32_t file_id; if (CachedPathToId(source_file_path, &file_id)) { const MTPDeviceTaskHelper::RenameObjectSuccessCallback success_callback_wrapper = base::Bind( @@ -1097,7 +1100,7 @@ } const int source_file_descriptor = open_fd_result.first; - uint32 parent_id; + uint32_t parent_id; if (CachedPathToId(device_file_path.DirName(), &parent_id)) { CopyFileFromLocalSuccessCallback success_callback_wrapper = base::Bind(&MTPDeviceDelegateImplLinux::OnDidCopyFileFromLocal, @@ -1135,7 +1138,7 @@ if (file_info.is_directory) { error_callback.Run(base::File::FILE_ERROR_NOT_A_FILE); } else { - uint32 file_id; + uint32_t file_id; if (CachedPathToId(file_path, &file_id)) RunDeleteObjectOnUIThread(file_path, file_id, success_callback, error_callback); @@ -1156,7 +1159,7 @@ return; } - uint32 directory_id; + uint32_t directory_id; if (!CachedPathToId(file_path, &directory_id)) { error_callback.Run(base::File::FILE_ERROR_NOT_FOUND); return; @@ -1234,7 +1237,7 @@ void MTPDeviceDelegateImplLinux::OnDidReadDirectoryToDeleteDirectory( const base::FilePath& directory_path, - const uint32 directory_id, + const uint32_t directory_id, const DeleteDirectorySuccessCallback& success_callback, const ErrorCallback& error_callback, const MTPDeviceTaskHelper::MTPEntries& entries, @@ -1254,7 +1257,7 @@ void MTPDeviceDelegateImplLinux::RunDeleteObjectOnUIThread( const base::FilePath& object_path, - const uint32 object_id, + const uint32_t object_id, const DeleteObjectSuccessCallback& success_callback, const ErrorCallback& error_callback) { const MTPDeviceTaskHelper::DeleteObjectSuccessCallback @@ -1406,7 +1409,7 @@ return; } - uint32 parent_id; + uint32_t parent_id; if (!CachedPathToId(directory_path.DirName(), &parent_id)) { error_callback.Run(base::File::FILE_ERROR_NOT_FOUND); return; @@ -1428,7 +1431,7 @@ } void MTPDeviceDelegateImplLinux::OnDidGetFileInfoToReadDirectory( - uint32 dir_id, + uint32_t dir_id, const ReadDirectorySuccessCallback& success_callback, const ErrorCallback& error_callback, const base::File::Info& file_info) { @@ -1462,7 +1465,8 @@ base::File::Error error = base::File::FILE_OK; if (file_info.is_directory) error = base::File::FILE_ERROR_NOT_A_FILE; - else if (file_info.size < 0 || file_info.size > kuint32max) + else if (file_info.size < 0 || + file_info.size > std::numeric_limits<uint32_t>::max()) error = base::File::FILE_ERROR_FAILED; if (error != base::File::FILE_OK) @@ -1560,7 +1564,7 @@ } void MTPDeviceDelegateImplLinux::OnDidReadDirectory( - uint32 dir_id, + uint32_t dir_id, const ReadDirectorySuccessCallback& success_callback, const MTPDeviceTaskHelper::MTPEntries& mtp_entries, bool has_more) { @@ -1717,7 +1721,7 @@ void MTPDeviceDelegateImplLinux::OnDidMoveFileLocalWithRename( const MoveFileLocalSuccessCallback& success_callback, const base::FilePath& source_file_path, - const uint32 file_id) { + const uint32_t file_id) { DCHECK_CURRENTLY_ON(content::BrowserThread::IO); EvictCachedPathToId(file_id); @@ -1775,7 +1779,7 @@ void MTPDeviceDelegateImplLinux::OnDidDeleteObject( const base::FilePath& object_path, - const uint32 object_id, + const uint32_t object_id, const DeleteObjectSuccessCallback success_callback) { DCHECK_CURRENTLY_ON(content::BrowserThread::IO); @@ -1798,7 +1802,7 @@ void MTPDeviceDelegateImplLinux::HandleDeviceFileError( const ErrorCallback& error_callback, - uint32 file_id, + uint32_t file_id, base::File::Error error) { DCHECK_CURRENTLY_ON(content::BrowserThread::IO); @@ -1855,9 +1859,8 @@ ReadDirectoryInternal(uncached_path, success_callback, error_callback); } - bool MTPDeviceDelegateImplLinux::CachedPathToId(const base::FilePath& path, - uint32* id) const { + uint32_t* id) const { DCHECK(id); std::string device_relpath = GetDeviceRelativePath(device_path_, path); @@ -1878,7 +1881,7 @@ return true; } -void MTPDeviceDelegateImplLinux::EvictCachedPathToId(const uint32 id) { +void MTPDeviceDelegateImplLinux::EvictCachedPathToId(const uint32_t id) { FileIdToMTPFileNodeMap::iterator it = file_id_to_node_map_.find(id); if (it != file_id_to_node_map_.end()) { DCHECK(!it->second->HasChildren());
diff --git a/chrome/browser/media_galleries/linux/mtp_device_delegate_impl_linux.h b/chrome/browser/media_galleries/linux/mtp_device_delegate_impl_linux.h index 5b5cee18..97371501 100644 --- a/chrome/browser/media_galleries/linux/mtp_device_delegate_impl_linux.h +++ b/chrome/browser/media_galleries/linux/mtp_device_delegate_impl_linux.h
@@ -5,6 +5,8 @@ #ifndef CHROME_BROWSER_MEDIA_GALLERIES_LINUX_MTP_DEVICE_DELEGATE_IMPL_LINUX_H_ #define CHROME_BROWSER_MEDIA_GALLERIES_LINUX_MTP_DEVICE_DELEGATE_IMPL_LINUX_H_ +#include <stdint.h> + #include <deque> #include <map> #include <set> @@ -60,7 +62,7 @@ class MTPFileNode; // Maps file ids to file nodes. - typedef std::map<uint32, MTPFileNode*> FileIdToMTPFileNodeMap; + typedef std::map<uint32_t, MTPFileNode*> FileIdToMTPFileNodeMap; // Maps file paths to file info. typedef std::map<base::FilePath, MTPDeviceTaskHelper::MTPEntry> FileInfoCache; @@ -96,7 +98,7 @@ bool IsStreaming() override; void ReadBytes(const base::FilePath& device_file_path, const scoped_refptr<net::IOBuffer>& buf, - int64 offset, + int64_t offset, int buf_len, const ReadBytesSuccessCallback& success_callback, const ErrorCallback& error_callback) override; @@ -160,7 +162,9 @@ const ErrorCallback& error_callback); virtual void ReadBytesInternal( const base::FilePath& device_file_path, - net::IOBuffer* buf, int64 offset, int buf_len, + net::IOBuffer* buf, + int64_t offset, + int buf_len, const ReadBytesSuccessCallback& success_callback, const ErrorCallback& error_callback); virtual void MoveFileLocalInternal( @@ -207,7 +211,7 @@ // Called when ReadDirectory succeeds. virtual void OnDidReadDirectoryToDeleteDirectory( const base::FilePath& directory_path, - const uint32 directory_id, + const uint32_t directory_id, const DeleteDirectorySuccessCallback& success_callback, const ErrorCallback& error_callback, const MTPDeviceTaskHelper::MTPEntries& entries, @@ -216,7 +220,7 @@ // Calls DeleteObjectOnUIThread on UI thread. virtual void RunDeleteObjectOnUIThread( const base::FilePath& object_path, - const uint32 object_id, + const uint32_t object_id, const DeleteObjectSuccessCallback& success_callback, const ErrorCallback& error_callback); @@ -289,7 +293,7 @@ // If |dir_id| is not a directory, |error_callback| is invoked to notify the // caller about the file error and process the next pending request. void OnDidGetFileInfoToReadDirectory( - uint32 dir_id, + uint32_t dir_id, const ReadDirectorySuccessCallback& success_callback, const ErrorCallback& error_callback, const base::File::Info& file_info); @@ -347,7 +351,7 @@ // file entries. // |file_list| contains the directory file entries with their file ids. // |has_more| is true if there are more file entries to read. - void OnDidReadDirectory(uint32 dir_id, + void OnDidReadDirectory(uint32_t dir_id, const ReadDirectorySuccessCallback& success_callback, const MTPDeviceTaskHelper::MTPEntries& mtp_entries, bool has_more); @@ -413,7 +417,7 @@ void OnDidMoveFileLocalWithRename( const MoveFileLocalSuccessCallback& success_callback, const base::FilePath& source_file_path, - const uint32 file_id); + const uint32_t file_id); // Called when CopyFileFromLocal() succeeds. void OnDidCopyFileFromLocal( @@ -433,7 +437,7 @@ // Called when DeleteObject() succeeds. void OnDidDeleteObject(const base::FilePath& object_path, - const uint32 object_id, + const uint32_t object_id, const DeleteObjectSuccessCallback success_callback); // Called when DeleteFileOrDirectory() fails. @@ -443,7 +447,7 @@ // Handles the device file |error| while operating on |file_id|. // |error_callback| is invoked to notify the caller about the file error. void HandleDeviceFileError(const ErrorCallback& error_callback, - uint32 file_id, + uint32_t file_id, base::File::Error error); // Given a full path, returns a non-empty sub-path that needs to be read into @@ -458,10 +462,10 @@ // Given a full path, if it exists in the cache, writes the file's id to |id| // and return true. - bool CachedPathToId(const base::FilePath& path, uint32* id) const; + bool CachedPathToId(const base::FilePath& path, uint32_t* id) const; // Evict the cache of |id|. - void EvictCachedPathToId(const uint32 id); + void EvictCachedPathToId(const uint32_t id); // MTP device initialization state. InitializationState init_state_;
diff --git a/chrome/browser/media_galleries/linux/mtp_device_task_helper.cc b/chrome/browser/media_galleries/linux/mtp_device_task_helper.cc index c7596ea..48a790f 100644 --- a/chrome/browser/media_galleries/linux/mtp_device_task_helper.cc +++ b/chrome/browser/media_galleries/linux/mtp_device_task_helper.cc
@@ -5,6 +5,7 @@ #include "chrome/browser/media_galleries/linux/mtp_device_task_helper.h" #include <algorithm> +#include <limits> #include "base/logging.h" #include "chrome/browser/media_galleries/linux/mtp_device_object_enumerator.h" @@ -76,7 +77,7 @@ } void MTPDeviceTaskHelper::GetFileInfo( - uint32 file_id, + uint32_t file_id, const GetFileInfoSuccessCallback& success_callback, const ErrorCallback& error_callback) { DCHECK_CURRENTLY_ON(content::BrowserThread::UI); @@ -92,7 +93,7 @@ } void MTPDeviceTaskHelper::CreateDirectory( - const uint32 parent_id, + const uint32_t parent_id, const std::string& directory_name, const CreateDirectorySuccessCallback& success_callback, const ErrorCallback& error_callback) { @@ -108,7 +109,7 @@ } void MTPDeviceTaskHelper::ReadDirectory( - const uint32 directory_id, + const uint32_t directory_id, const size_t max_size, const ReadDirectorySuccessCallback& success_callback, const ErrorCallback& error_callback) { @@ -153,7 +154,7 @@ } void MTPDeviceTaskHelper::RenameObject( - const uint32 object_id, + const uint32_t object_id, const std::string& new_name, const RenameObjectSuccessCallback& success_callback, const ErrorCallback& error_callback) { @@ -172,7 +173,7 @@ void MTPDeviceTaskHelper::CopyFileFromLocal( const std::string& storage_name, const int source_file_descriptor, - const uint32 parent_id, + const uint32_t parent_id, const std::string& file_name, const CopyFileFromLocalSuccessCallback& success_callback, const ErrorCallback& error_callback) { @@ -186,7 +187,7 @@ } void MTPDeviceTaskHelper::DeleteObject( - const uint32 object_id, + const uint32_t object_id, const DeleteObjectSuccessCallback& success_callback, const ErrorCallback& error_callback) { DCHECK_CURRENTLY_ON(content::BrowserThread::UI); @@ -296,7 +297,8 @@ if (file_info.is_directory) { return HandleDeviceError(request.error_callback, base::File::FILE_ERROR_NOT_A_FILE); - } else if (file_info.size < 0 || file_info.size > kuint32max || + } else if (file_info.size < 0 || + file_info.size > std::numeric_limits<uint32_t>::max() || request.offset > file_info.size) { return HandleDeviceError(request.error_callback, base::File::FILE_ERROR_FAILED); @@ -308,15 +310,13 @@ return; } - uint32 bytes_to_read = std::min( - base::checked_cast<uint32>(request.buf_len), - base::saturated_cast<uint32>(file_info.size - request.offset)); + uint32_t bytes_to_read = + std::min(base::checked_cast<uint32_t>(request.buf_len), + base::saturated_cast<uint32_t>(file_info.size - request.offset)); GetMediaTransferProtocolManager()->ReadFileChunk( - device_handle_, - request.file_id, - base::checked_cast<uint32>(request.offset), - bytes_to_read, + device_handle_, request.file_id, + base::checked_cast<uint32_t>(request.offset), bytes_to_read, base::Bind(&MTPDeviceTaskHelper::OnDidReadBytes, weak_ptr_factory_.GetWeakPtr(), request, file_info)); }
diff --git a/chrome/browser/media_galleries/linux/mtp_device_task_helper.h b/chrome/browser/media_galleries/linux/mtp_device_task_helper.h index 5af1487..2a73e17 100644 --- a/chrome/browser/media_galleries/linux/mtp_device_task_helper.h +++ b/chrome/browser/media_galleries/linux/mtp_device_task_helper.h
@@ -5,6 +5,8 @@ #ifndef CHROME_BROWSER_MEDIA_GALLERIES_LINUX_MTP_DEVICE_TASK_HELPER_H_ #define CHROME_BROWSER_MEDIA_GALLERIES_LINUX_MTP_DEVICE_TASK_HELPER_H_ +#include <stdint.h> + #include <string> #include <vector>
diff --git a/chrome/browser/media_galleries/linux/snapshot_file_details.cc b/chrome/browser/media_galleries/linux/snapshot_file_details.cc index e2408bad..1058fd5 100644 --- a/chrome/browser/media_galleries/linux/snapshot_file_details.cc +++ b/chrome/browser/media_galleries/linux/snapshot_file_details.cc
@@ -4,6 +4,8 @@ #include "chrome/browser/media_galleries/linux/snapshot_file_details.h" +#include <limits> + #include "base/numerics/safe_conversions.h" //////////////////////////////////////////////////////////////////////////////// @@ -11,7 +13,7 @@ //////////////////////////////////////////////////////////////////////////////// SnapshotRequestInfo::SnapshotRequestInfo( - uint32 file_id, + uint32_t file_id, const base::FilePath& snapshot_file_path, const MTPDeviceAsyncDelegate::CreateSnapshotFileSuccessCallback& success_callback, @@ -19,8 +21,7 @@ : file_id(file_id), snapshot_file_path(snapshot_file_path), success_callback(success_callback), - error_callback(error_callback) { -} + error_callback(error_callback) {} SnapshotRequestInfo::~SnapshotRequestInfo() { } @@ -45,9 +46,9 @@ error_occurred_ = error; } -bool SnapshotFileDetails::AddBytesWritten(uint32 bytes_written) { +bool SnapshotFileDetails::AddBytesWritten(uint32_t bytes_written) { if ((bytes_written == 0) || - (bytes_written_ > kuint32max - bytes_written) || + (bytes_written_ > std::numeric_limits<uint32_t>::max() - bytes_written) || (bytes_written_ + bytes_written > file_info_.size)) return false; @@ -59,10 +60,10 @@ return !error_occurred_ && (bytes_written_ == file_info_.size); } -uint32 SnapshotFileDetails::BytesToRead() const { +uint32_t SnapshotFileDetails::BytesToRead() const { // Read data in 1MB chunks. - static const uint32 kReadChunkSize = 1024 * 1024; + static const uint32_t kReadChunkSize = 1024 * 1024; return std::min( kReadChunkSize, - base::checked_cast<uint32>(file_info_.size) - bytes_written_); + base::checked_cast<uint32_t>(file_info_.size) - bytes_written_); }
diff --git a/chrome/browser/media_galleries/linux/snapshot_file_details.h b/chrome/browser/media_galleries/linux/snapshot_file_details.h index 0457210..e0e3c39 100644 --- a/chrome/browser/media_galleries/linux/snapshot_file_details.h +++ b/chrome/browser/media_galleries/linux/snapshot_file_details.h
@@ -5,9 +5,10 @@ #ifndef CHROME_BROWSER_MEDIA_GALLERIES_LINUX_SNAPSHOT_FILE_DETAILS_H_ #define CHROME_BROWSER_MEDIA_GALLERIES_LINUX_SNAPSHOT_FILE_DETAILS_H_ +#include <stdint.h> + #include <string> -#include "base/basictypes.h" #include "base/callback.h" #include "base/files/file.h" #include "base/files/file_path.h" @@ -16,7 +17,7 @@ // Used to represent snapshot file request params. struct SnapshotRequestInfo { SnapshotRequestInfo( - uint32 file_id, + uint32_t file_id, const base::FilePath& snapshot_file_path, const MTPDeviceAsyncDelegate::CreateSnapshotFileSuccessCallback& success_callback, @@ -24,7 +25,7 @@ ~SnapshotRequestInfo(); // MTP device file id. - const uint32 file_id; + const uint32_t file_id; // Local platform path of the snapshot file. const base::FilePath snapshot_file_path; @@ -47,17 +48,13 @@ ~SnapshotFileDetails(); - uint32 file_id() const { - return request_info_.file_id; - } + uint32_t file_id() const { return request_info_.file_id; } base::FilePath snapshot_file_path() const { return request_info_.snapshot_file_path; } - uint32 bytes_written() const { - return bytes_written_; - } + uint32_t bytes_written() const { return bytes_written_; } const base::File::Info& file_info() const { return file_info_; @@ -85,13 +82,13 @@ // |bytes_written_|. // If |bytes_written| is invalid, returns false and does not add // |bytes_written| to |bytes_written_|. - bool AddBytesWritten(uint32 bytes_written); + bool AddBytesWritten(uint32_t bytes_written); // Returns true if the snapshot file is created successfully (no more write // operation is required to complete the snapshot file). bool IsSnapshotFileWriteComplete() const; - uint32 BytesToRead() const; + uint32_t BytesToRead() const; private: // Snapshot file request params. @@ -101,7 +98,7 @@ const base::File::Info file_info_; // Number of bytes written into the snapshot file. - uint32 bytes_written_; + uint32_t bytes_written_; // Whether an error occurred during file transfer. bool error_occurred_;
diff --git a/chrome/browser/metrics/chrome_metrics_service_accessor.cc b/chrome/browser/metrics/chrome_metrics_service_accessor.cc index e4416f7c..0fe57ab5 100644 --- a/chrome/browser/metrics/chrome_metrics_service_accessor.cc +++ b/chrome/browser/metrics/chrome_metrics_service_accessor.cc
@@ -6,6 +6,7 @@ #include "base/prefs/pref_service.h" #include "chrome/browser/browser_process.h" +#include "chrome/common/features.h" #include "chrome/common/pref_names.h" #include "content/public/browser/browser_thread.h" @@ -29,7 +30,7 @@ return false; } -#if !defined(OS_ANDROID) +#if !BUILDFLAG(ANDROID_JAVA_UI) return IsMetricsReportingEnabled(g_browser_process->local_state()); #else // Android currently obtain the value for whether the user has @@ -42,7 +43,7 @@ pref_value = g_browser_process->local_state()->GetBoolean( prefs::kCrashReportingEnabled); return IsMetricsReportingEnabledWithPrefValue(pref_value); -#endif // !defined(OS_ANDROID) +#endif // !BUILDFLAG(ANDROID_JAVA_UI) } // static
diff --git a/chrome/browser/metrics/chrome_metrics_service_client.cc b/chrome/browser/metrics/chrome_metrics_service_client.cc index 5ffa6f6c..1fbe66d 100644 --- a/chrome/browser/metrics/chrome_metrics_service_client.cc +++ b/chrome/browser/metrics/chrome_metrics_service_client.cc
@@ -28,6 +28,7 @@ #include "chrome/common/chrome_paths.h" #include "chrome/common/chrome_switches.h" #include "chrome/common/crash_keys.h" +#include "chrome/common/features.h" #include "components/metrics/call_stack_profile_metrics_provider.h" #include "components/metrics/drive_metrics_provider.h" #include "components/metrics/gpu/gpu_metrics_provider.h" @@ -48,7 +49,7 @@ #include "content/public/browser/histogram_fetcher.h" #include "content/public/browser/notification_service.h" -#if defined(OS_ANDROID) +#if BUILDFLAG(ANDROID_JAVA_UI) #include "chrome/browser/metrics/android_metrics_provider.h" #endif @@ -113,7 +114,7 @@ // This should happen only once as the used preference will be initialized // afterwards in |UmaSessionStats.java|. bool ShouldClearSavedMetrics() { -#if defined(OS_ANDROID) +#if BUILDFLAG(ANDROID_JAVA_UI) PrefService* local_state = g_browser_process->local_state(); return !local_state->HasPrefPath(metrics::prefs::kMetricsReportingEnabled) && variations::GetVariationParamValue("UMA_EnableCellularLogUpload", @@ -170,9 +171,9 @@ metrics::MetricsService::RegisterPrefs(registry); metrics::StabilityMetricsHelper::RegisterPrefs(registry); -#if defined(OS_ANDROID) +#if BUILDFLAG(ANDROID_JAVA_UI) AndroidMetricsProvider::RegisterPrefs(registry); -#endif // defined(OS_ANDROID) +#endif // BUILDFLAG(ANDROID_JAVA_UI) #if defined(ENABLE_PLUGINS) PluginMetricsProvider::RegisterPrefs(registry); @@ -343,11 +344,11 @@ scoped_ptr<metrics::MetricsProvider>( new metrics::CallStackProfileMetricsProvider)); -#if defined(OS_ANDROID) +#if BUILDFLAG(ANDROID_JAVA_UI) metrics_service_->RegisterMetricsProvider( scoped_ptr<metrics::MetricsProvider>( new AndroidMetricsProvider(g_browser_process->local_state()))); -#endif // defined(OS_ANDROID) +#endif // BUILDFLAG(ANDROID_JAVA_UI) #if defined(OS_WIN) google_update_metrics_provider_ = new GoogleUpdateMetricsProviderWin;
diff --git a/chrome/browser/metrics/field_trial_synchronizer.cc b/chrome/browser/metrics/field_trial_synchronizer.cc index 9dab6c1..906f637 100644 --- a/chrome/browser/metrics/field_trial_synchronizer.cc +++ b/chrome/browser/metrics/field_trial_synchronizer.cc
@@ -51,7 +51,11 @@ void FieldTrialSynchronizer::OnFieldTrialGroupFinalized( const std::string& field_trial_name, const std::string& group_name) { + // TODO(asvitkine): Remove these CHECKs once http://crbug.com/359406 is fixed. CHECK(!field_trial_name.empty() && !group_name.empty()); + CHECK_EQ(group_name, base::FieldTrialList::FindFullName(field_trial_name)) + << field_trial_name << ":" << group_name << "=>" + << base::FieldTrialList::FindFullName(field_trial_name); BrowserThread::PostTask( BrowserThread::UI, FROM_HERE, base::Bind(&FieldTrialSynchronizer::NotifyAllRenderers,
diff --git a/chrome/browser/net/chrome_network_delegate.cc b/chrome/browser/net/chrome_network_delegate.cc index 8fd4f9b..b7fc936 100644 --- a/chrome/browser/net/chrome_network_delegate.cc +++ b/chrome/browser/net/chrome_network_delegate.cc
@@ -35,6 +35,7 @@ #include "chrome/browser/profiles/profile_manager.h" #include "chrome/browser/task_management/task_manager_interface.h" #include "chrome/common/chrome_constants.h" +#include "chrome/common/features.h" #include "chrome/common/pref_names.h" #include "components/content_settings/core/browser/cookie_settings.h" #include "components/data_usage/core/data_use_aggregator.h" @@ -56,7 +57,7 @@ #include "net/log/net_log.h" #include "net/url_request/url_request.h" -#if defined(OS_ANDROID) +#if BUILDFLAG(ANDROID_JAVA_UI) #include "chrome/browser/io_thread.h" #include "chrome/browser/precache/precache_manager_factory.h" #include "components/precache/content/precache_manager.h" @@ -106,7 +107,7 @@ callback.Run(rv); } -#if defined(OS_ANDROID) +#if BUILDFLAG(ANDROID_JAVA_UI) void RecordPrecacheStatsOnUIThread(const GURL& url, const GURL& referrer, base::TimeDelta latency, @@ -129,7 +130,7 @@ precache_manager->RecordStatsForFetch(url, referrer, latency, fetch_time, size, was_cached); } -#endif // defined(OS_ANDROID) +#endif // BUILDFLAG(ANDROID_JAVA_UI) void ReportInvalidReferrerSendOnUI() { base::RecordAction( @@ -526,7 +527,7 @@ } if (request->status().status() == net::URLRequestStatus::SUCCESS) { -#if defined(OS_ANDROID) +#if BUILDFLAG(ANDROID_JAVA_UI) // For better accuracy, we use the actual bytes read instead of the length // specified with the Content-Length header, which may be inaccurate, // or missing, as is the case with chunked encoding. @@ -540,7 +541,7 @@ base::Bind(&RecordPrecacheStatsOnUIThread, request->url(), GURL(request->referrer()), latency, base::Time::Now(), received_content_length, request->was_cached(), profile_)); -#endif // defined(OS_ANDROID) +#endif // BUILDFLAG(ANDROID_JAVA_UI) extensions_delegate_->OnCompleted(request, started); } else if (request->status().status() == net::URLRequestStatus::FAILED || request->status().status() == net::URLRequestStatus::CANCELED) {
diff --git a/chrome/browser/net/net_error_tab_helper.cc b/chrome/browser/net/net_error_tab_helper.cc index 25b9e7a950..bc0f9a7 100644 --- a/chrome/browser/net/net_error_tab_helper.cc +++ b/chrome/browser/net/net_error_tab_helper.cc
@@ -13,6 +13,7 @@ #include "chrome/browser/net/net_error_diagnostics_dialog.h" #include "chrome/browser/platform_util.h" #include "chrome/browser/profiles/profile.h" +#include "chrome/common/features.h" #include "chrome/common/localized_error.h" #include "chrome/common/pref_names.h" #include "chrome/common/render_messages.h" @@ -25,13 +26,13 @@ #include "net/base/net_errors.h" #include "url/gurl.h" -#if defined(OS_ANDROID) +#if BUILDFLAG(ANDROID_JAVA_UI) #include "chrome/browser/android/offline_pages/offline_page_model_factory.h" #include "chrome/browser/android/tab_android.h" #include "components/offline_pages/offline_page_feature.h" #include "components/offline_pages/offline_page_item.h" #include "components/offline_pages/offline_page_model.h" -#endif // defined(OS_ANDROID) +#endif // BUILDFLAG(ANDROID_JAVA_UI) using content::BrowserContext; using content::BrowserThread; @@ -131,9 +132,9 @@ is_error_page_ = is_error_page; -#if defined(OS_ANDROID) +#if BUILDFLAG(ANDROID_JAVA_UI) SetOfflinePageInfo(render_frame_host, validated_url); -#endif // defined(OS_ANDROID) +#endif // BUILDFLAG(ANDROID_JAVA_UI) } void NetErrorTabHelper::DidCommitProvisionalLoadForFrame( @@ -185,10 +186,10 @@ IPC_BEGIN_MESSAGE_MAP(NetErrorTabHelper, message) IPC_MESSAGE_HANDLER(ChromeViewHostMsg_RunNetworkDiagnostics, RunNetworkDiagnostics) -#if defined(OS_ANDROID) +#if BUILDFLAG(ANDROID_JAVA_UI) IPC_MESSAGE_HANDLER(ChromeViewHostMsg_ShowOfflinePages, ShowOfflinePages) IPC_MESSAGE_HANDLER(ChromeViewHostMsg_LoadOfflineCopy, LoadOfflineCopy) -#endif // defined(OS_ANDROID) +#endif // BUILDFLAG(ANDROID_JAVA_UI) IPC_MESSAGE_UNHANDLED(handled = false) IPC_END_MESSAGE_MAP() @@ -296,7 +297,7 @@ ShowNetworkDiagnosticsDialog(web_contents(), sanitized_url); } -#if defined(OS_ANDROID) +#if BUILDFLAG(ANDROID_JAVA_UI) void NetErrorTabHelper::SetOfflinePageInfo( content::RenderFrameHost* render_frame_host, const GURL& url) { @@ -354,6 +355,6 @@ return entry && (entry->GetPageType() == content::PAGE_TYPE_ERROR); } -#endif // defined(OS_ANDROID) +#endif // BUILDFLAG(ANDROID_JAVA_UI) } // namespace chrome_browser_net
diff --git a/chrome/browser/net/net_error_tab_helper.h b/chrome/browser/net/net_error_tab_helper.h index 169c81a..37dcf37 100644 --- a/chrome/browser/net/net_error_tab_helper.h +++ b/chrome/browser/net/net_error_tab_helper.h
@@ -13,6 +13,7 @@ #include "base/memory/weak_ptr.h" #include "base/prefs/pref_member.h" #include "chrome/browser/net/dns_probe_service.h" +#include "chrome/common/features.h" #include "components/error_page/common/net_error_info.h" #include "content/public/browser/web_contents_observer.h" #include "content/public/browser/web_contents_user_data.h" @@ -103,13 +104,13 @@ virtual void RunNetworkDiagnosticsHelper(const std::string& sanitized_url); // Relates to offline pages handling. -#if defined(OS_ANDROID) +#if BUILDFLAG(ANDROID_JAVA_UI) void SetOfflinePageInfo(content::RenderFrameHost* render_frame_host, const GURL& url); void ShowOfflinePages(); void LoadOfflineCopy(const GURL& url); bool IsFromErrorPage() const; -#endif // defined(OS_ANDROID) +#endif // BUILDFLAG(ANDROID_JAVA_UI) // True if the last provisional load that started was for an error page. bool is_error_page_;
diff --git a/chrome/browser/page_load_metrics/page_load_metrics_browsertest.cc b/chrome/browser/page_load_metrics/page_load_metrics_browsertest.cc index d56a7ec..897e062 100644 --- a/chrome/browser/page_load_metrics/page_load_metrics_browsertest.cc +++ b/chrome/browser/page_load_metrics/page_load_metrics_browsertest.cc
@@ -6,7 +6,7 @@ #include "chrome/test/base/in_process_browser_test.h" #include "chrome/test/base/ui_test_utils.h" #include "components/page_load_metrics/browser/metrics_web_contents_observer.h" -#include "net/test/spawned_test_server/spawned_test_server.h" +#include "net/test/embedded_test_server/embedded_test_server.h" namespace page_load_metrics { @@ -22,7 +22,7 @@ }; IN_PROC_BROWSER_TEST_F(MetricsWebContentsObserverBrowserTest, NoNavigation) { - ASSERT_TRUE(test_server()->Start()); + ASSERT_TRUE(embedded_test_server()->Start()); histogram_tester_.ExpectTotalCount(kHistogramDomContentLoaded, 0); histogram_tester_.ExpectTotalCount(kHistogramLoad, 0); @@ -30,12 +30,12 @@ } IN_PROC_BROWSER_TEST_F(MetricsWebContentsObserverBrowserTest, NewPage) { - ASSERT_TRUE(test_server()->Start()); + ASSERT_TRUE(embedded_test_server()->Start()); ui_test_utils::NavigateToURL(browser(), - test_server()->GetURL("/title1.html")); + embedded_test_server()->GetURL("/title1.html")); ui_test_utils::NavigateToURL(browser(), - test_server()->GetURL("/title2.html")); + embedded_test_server()->GetURL("/title2.html")); histogram_tester_.ExpectTotalCount(kHistogramDomContentLoaded, 1); histogram_tester_.ExpectTotalCount(kHistogramLoad, 1); @@ -43,14 +43,14 @@ } IN_PROC_BROWSER_TEST_F(MetricsWebContentsObserverBrowserTest, AnchorLink) { - ASSERT_TRUE(test_server()->Start()); + ASSERT_TRUE(embedded_test_server()->Start()); ui_test_utils::NavigateToURL(browser(), - test_server()->GetURL("/title1.html")); + embedded_test_server()->GetURL("/title1.html")); + ui_test_utils::NavigateToURL( + browser(), embedded_test_server()->GetURL("/title1.html#hash")); ui_test_utils::NavigateToURL(browser(), - test_server()->GetURL("/title1.html#hash")); - ui_test_utils::NavigateToURL(browser(), - test_server()->GetURL("/title2.html")); + embedded_test_server()->GetURL("/title2.html")); histogram_tester_.ExpectTotalCount(kHistogramDomContentLoaded, 1); histogram_tester_.ExpectTotalCount(kHistogramLoad, 1);
diff --git a/chrome/browser/password_manager/chrome_password_manager_client.cc b/chrome/browser/password_manager/chrome_password_manager_client.cc index 6bbdc00..bdd0a1e 100644 --- a/chrome/browser/password_manager/chrome_password_manager_client.cc +++ b/chrome/browser/password_manager/chrome_password_manager_client.cc
@@ -22,6 +22,7 @@ #include "chrome/browser/ui/passwords/passwords_client_ui_delegate.h" #include "chrome/common/channel_info.h" #include "chrome/common/chrome_switches.h" +#include "chrome/common/features.h" #include "chrome/common/url_constants.h" #include "components/autofill/content/browser/content_autofill_driver.h" #include "components/autofill/content/browser/content_autofill_driver_factory.h" @@ -53,11 +54,11 @@ #include "net/base/url_util.h" #include "third_party/re2/re2/re2.h" -#if defined(OS_MACOSX) || defined(OS_ANDROID) +#if defined(OS_MACOSX) || BUILDFLAG(ANDROID_JAVA_UI) #include "chrome/browser/password_manager/save_password_infobar_delegate.h" #endif -#if defined(OS_ANDROID) +#if BUILDFLAG(ANDROID_JAVA_UI) #include "chrome/browser/android/tab_android.h" #include "chrome/browser/password_manager/account_chooser_dialog_android.h" #include "chrome/browser/password_manager/generated_password_saved_infobar_delegate_android.h" @@ -228,7 +229,7 @@ manage_passwords_ui_controller->OnPasswordSubmitted(form_to_save.Pass()); } } else { -#if defined(OS_MACOSX) || defined(OS_ANDROID) +#if defined(OS_MACOSX) || BUILDFLAG(ANDROID_JAVA_UI) if (form_to_save->IsBlacklisted()) return false; std::string uma_histogram_suffix( @@ -273,7 +274,7 @@ void ChromePasswordManagerClient::NotifyUserAutoSignin( ScopedVector<autofill::PasswordForm> local_forms) { DCHECK(!local_forms.empty()); -#if defined(OS_ANDROID) +#if BUILDFLAG(ANDROID_JAVA_UI) ShowAutoSigninPrompt(web_contents(), local_forms[0]->username_value); #else PasswordsClientUIDelegateFromWebContents(web_contents()) @@ -284,7 +285,7 @@ void ChromePasswordManagerClient::AutomaticPasswordSave( scoped_ptr<password_manager::PasswordFormManager> saved_form) { -#if defined(OS_ANDROID) +#if BUILDFLAG(ANDROID_JAVA_UI) GeneratedPasswordSavedInfoBarDelegateAndroid::Create(web_contents()); #else if (IsTheHotNewBubbleUIEnabled()) { @@ -473,7 +474,7 @@ } bool ChromePasswordManagerClient::IsTheHotNewBubbleUIEnabled() { -#if defined(OS_ANDROID) +#if BUILDFLAG(ANDROID_JAVA_UI) return false; #elif defined(OS_MACOSX) // Query the group first for correct UMA reporting.
diff --git a/chrome/browser/password_manager/password_manager_browsertest.cc b/chrome/browser/password_manager/password_manager_browsertest.cc index 2cecdc1..5cb9c09 100644 --- a/chrome/browser/password_manager/password_manager_browsertest.cc +++ b/chrome/browser/password_manager/password_manager_browsertest.cc
@@ -1433,7 +1433,7 @@ } IN_PROC_BROWSER_TEST_F(PasswordManagerBrowserTestBase, - AutofillSuggetionsForPasswordFormWithoutUsernameField) { + AutofillSuggestionsForPasswordFormWithoutUsernameField) { std::string submit = "document.getElementById('password').value = 'mypassword';" "document.getElementById('submit-button').click();"; @@ -1795,7 +1795,7 @@ // Tests that if a site embeds the login and signup forms into one <form>, the // login form still gets autofilled. IN_PROC_BROWSER_TEST_F(PasswordManagerBrowserTestBase, - AutofillSuggetionsForLoginSignupForm) { + AutofillSuggestionsForLoginSignupForm) { std::string submit = "document.getElementById('username').value = 'myusername';" "document.getElementById('password').value = 'mypassword';" @@ -2261,7 +2261,7 @@ // ambiguity in id attribute gets autofilled correctly. IN_PROC_BROWSER_TEST_F( PasswordManagerBrowserTestBase, - AutofillSuggetionsForPasswordFormWithAmbiguousIdAttribute) { + AutofillSuggestionsForPasswordFormWithAmbiguousIdAttribute) { // At first let us save credentials to the PasswordManager. scoped_refptr<password_manager::PasswordStore> password_store = PasswordStoreFactory::GetForProfile(browser()->profile(), @@ -2309,7 +2309,7 @@ // name and id attribute gets autofilled correctly. IN_PROC_BROWSER_TEST_F( PasswordManagerBrowserTestBase, - AutofillSuggetionsForPasswordFormWithoutNameOrIdAttribute) { + AutofillSuggestionsForPasswordFormWithoutNameOrIdAttribute) { // At first let us save credentials to the PasswordManager. scoped_refptr<password_manager::PasswordStore> password_store = PasswordStoreFactory::GetForProfile(browser()->profile(), @@ -2356,7 +2356,7 @@ // Test whether the change password form having username and password fields // without name and id attribute gets autofilled correctly. IN_PROC_BROWSER_TEST_F(PasswordManagerBrowserTestBase, - AutofillSuggetionsForChangePwdWithEmptyNames) { + AutofillSuggestionsForChangePwdWithEmptyNames) { // At first let us save credentials to the PasswordManager. scoped_refptr<password_manager::PasswordStore> password_store = PasswordStoreFactory::GetForProfile(browser()->profile(), @@ -2416,7 +2416,7 @@ // correctly. IN_PROC_BROWSER_TEST_F( PasswordManagerBrowserTestBase, - AutofillSuggetionsForChangePwdWithEmptyNamesAndAutocomplete) { + AutofillSuggestionsForChangePwdWithEmptyNamesAndAutocomplete) { // At first let us save credentials to the PasswordManager. scoped_refptr<password_manager::PasswordStore> password_store = PasswordStoreFactory::GetForProfile(browser()->profile(), @@ -2473,7 +2473,7 @@ // |autocomplete='new-password'| atrribute do not get autofilled. IN_PROC_BROWSER_TEST_F( PasswordManagerBrowserTestBase, - AutofillSuggetionsForChangePwdWithEmptyNamesButOnlyNewPwdField) { + AutofillSuggestionsForChangePwdWithEmptyNamesButOnlyNewPwdField) { // At first let us save credentials to the PasswordManager. scoped_refptr<password_manager::PasswordStore> password_store = PasswordStoreFactory::GetForProfile(browser()->profile(), @@ -2588,10 +2588,10 @@ // Test whether the password form which is loaded as hidden is autofilled // correctly. This happens very often in situations when in order to sign-in the // user clicks a sign-in button and a hidden passsword form becomes visible. -// This test differs from AutofillSuggetionsForProblematicPasswordForm in that +// This test differs from AutofillSuggestionsForProblematicPasswordForm in that // the form is hidden and in that test only some fields are hidden. IN_PROC_BROWSER_TEST_F(PasswordManagerBrowserTestBase, - AutofillSuggetionsHiddenPasswordForm) { + AutofillSuggestionsHiddenPasswordForm) { // At first let us save credentials to the PasswordManager. scoped_refptr<password_manager::PasswordStore> password_store = PasswordStoreFactory::GetForProfile(browser()->profile(), @@ -2638,7 +2638,7 @@ // Test whether the password form with the problematic invisible password field // gets autofilled correctly. IN_PROC_BROWSER_TEST_F(PasswordManagerBrowserTestBase, - AutofillSuggetionsForProblematicPasswordForm) { + AutofillSuggestionsForProblematicPasswordForm) { // At first let us save credentials to the PasswordManager. scoped_refptr<password_manager::PasswordStore> password_store = PasswordStoreFactory::GetForProfile(browser()->profile(), @@ -2685,7 +2685,7 @@ // Test whether the password form with the problematic invisible password field // in ambiguous password form gets autofilled correctly. IN_PROC_BROWSER_TEST_F(PasswordManagerBrowserTestBase, - AutofillSuggetionsForProblematicAmbiguousPasswordForm) { + AutofillSuggestionsForProblematicAmbiguousPasswordForm) { // At first let us save credentials to the PasswordManager. scoped_refptr<password_manager::PasswordStore> password_store = PasswordStoreFactory::GetForProfile(browser()->profile(), @@ -2871,4 +2871,35 @@ } #endif +// Tests that the prompt to save the password is still shown if the fields have +// the "autocomplete" attribute set off. +IN_PROC_BROWSER_TEST_F(PasswordManagerBrowserTestBase, + PromptForSubmitWithAutocompleteOff) { + NavigateToFile("/password/password_autocomplete_off_test.html"); + + NavigationObserver observer(WebContents()); + scoped_ptr<PromptObserver> prompt_observer( + PromptObserver::Create(WebContents())); + std::string fill_and_submit = + "document.getElementById('username').value = 'temp';" + "document.getElementById('password').value = 'random';" + "document.getElementById('submit').click()"; + ASSERT_TRUE(content::ExecuteScript(RenderViewHost(), fill_and_submit)); + observer.Wait(); + EXPECT_TRUE(prompt_observer->IsShowingPrompt()); +} + +// Tests that password suggestions still work if the fields have the +// "autocomplete" attribute set to off. +IN_PROC_BROWSER_TEST_F(PasswordManagerBrowserTestBase, + AutofillSuggestionsForPasswordFormWithAutocompleteOff) { + std::string submit = + "document.getElementById('username').value = 'temp';" + "document.getElementById('password').value = 'mypassword';" + "document.getElementById('submit').click();"; + VerifyPasswordIsSavedAndFilled( + "/password/password_autocomplete_off_test.html", submit, "password", + "mypassword"); +} + } // namespace password_manager
diff --git a/chrome/browser/platform_util.h b/chrome/browser/platform_util.h index 651ae89..7a9494d9 100644 --- a/chrome/browser/platform_util.h +++ b/chrome/browser/platform_util.h
@@ -9,6 +9,7 @@ #include "base/callback_forward.h" #include "base/strings/string16.h" +#include "chrome/common/features.h" #include "ui/gfx/native_widget_types.h" class GURL; @@ -98,7 +99,7 @@ bool IsSwipeTrackingFromScrollEventsEnabled(); #endif -#if defined(OS_ANDROID) && !defined(USE_AURA) +#if BUILDFLAG(ANDROID_JAVA_UI) bool RegisterPlatformUtil(JNIEnv* env); #endif } // namespace platform_util
diff --git a/chrome/browser/platform_util_aura.cc b/chrome/browser/platform_util_aura.cc index 6ef69e57..db3a3438 100644 --- a/chrome/browser/platform_util_aura.cc +++ b/chrome/browser/platform_util_aura.cc
@@ -13,25 +13,6 @@ namespace platform_util { -#if defined(OS_ANDROID) -// TODO(bshe): We might want to use platform_util_android.cc for Aura Android. -// See crbug.com/561664 -void ShowItemInFolder(Profile* profile, const base::FilePath& full_path) { - NOTIMPLEMENTED(); -} - -void OpenItem(Profile* profile, - const base::FilePath& full_path, - OpenItemType item_type, - const OpenOperationCallback& callback) { - NOTIMPLEMENTED(); -} - -void OpenExternal(Profile* profile, const GURL& url) { - NOTIMPLEMENTED(); -} -#endif - gfx::NativeWindow GetTopLevel(gfx::NativeView view) { return view->GetToplevelWindow(); }
diff --git a/chrome/browser/policy/configuration_policy_handler_list_factory.cc b/chrome/browser/policy/configuration_policy_handler_list_factory.cc index 6de0567..ba44e2cb 100644 --- a/chrome/browser/policy/configuration_policy_handler_list_factory.cc +++ b/chrome/browser/policy/configuration_policy_handler_list_factory.cc
@@ -12,6 +12,7 @@ #include "chrome/browser/policy/managed_bookmarks_policy_handler.h" #include "chrome/browser/profiles/incognito_mode_policy_handler.h" #include "chrome/common/chrome_switches.h" +#include "chrome/common/features.h" #include "chrome/common/pref_names.h" #include "components/bookmarks/common/bookmark_pref_names.h" #include "components/content_settings/core/common/pref_names.h" @@ -35,7 +36,7 @@ #include "components/variations/pref_names.h" #include "policy/policy_constants.h" -#if defined(OS_ANDROID) +#if BUILDFLAG(ANDROID_JAVA_UI) #include "chrome/browser/search/contextual_search_policy_handler_android.h" #endif @@ -507,14 +508,14 @@ base::Value::TYPE_BOOLEAN }, #endif // !defined(OS_MACOSX) && !defined(OS_CHROMEOS) -#if defined(OS_ANDROID) +#if BUILDFLAG(ANDROID_JAVA_UI) { key::kDataCompressionProxyEnabled, data_reduction_proxy::prefs::kDataReductionProxyEnabled, base::Value::TYPE_BOOLEAN }, { key::kAuthAndroidNegotiateAccountType, prefs::kAuthAndroidNegotiateAccountType, base::Value::TYPE_STRING }, -#endif // defined(OS_ANDROID) +#endif // BUILDFLAG(ANDROID_JAVA_UI) #if !defined(OS_CHROMEOS) && !defined(OS_ANDROID) && !defined(OS_IOS) { key::kNativeMessagingUserLevelHosts, @@ -622,7 +623,7 @@ handlers->AddHandler(make_scoped_ptr(new ProxyPolicyHandler())); handlers->AddHandler(make_scoped_ptr(new URLBlacklistPolicyHandler())); -#if defined(OS_ANDROID) +#if BUILDFLAG(ANDROID_JAVA_UI) handlers->AddHandler( make_scoped_ptr(new ContextualSearchPolicyHandlerAndroid())); #endif
diff --git a/chrome/browser/prefs/browser_prefs.cc b/chrome/browser/prefs/browser_prefs.cc index ee136d2..57862ff 100644 --- a/chrome/browser/prefs/browser_prefs.cc +++ b/chrome/browser/prefs/browser_prefs.cc
@@ -66,6 +66,7 @@ #include "chrome/browser/ui/webui/ntp/new_tab_ui.h" #include "chrome/browser/ui/webui/plugins_ui.h" #include "chrome/browser/ui/webui/print_preview/sticky_settings.h" +#include "chrome/common/features.h" #include "chrome/common/pref_names.h" #include "components/autofill/core/browser/autofill_manager.h" #include "components/content_settings/core/browser/host_content_settings_map.h" @@ -116,10 +117,8 @@ #include "chrome/browser/signin/easy_unlock_service.h" #include "chrome/browser/ui/webui/extensions/extension_settings_handler.h" #include "extensions/browser/extension_prefs.h" -#if !defined(OS_ANDROID) && !defined(OS_IOS) #include "chrome/browser/extensions/api/copresence/copresence_api.h" #include "chrome/browser/ui/toolbar/toolbar_actions_bar.h" -#endif #endif // defined(ENABLE_EXTENSIONS) #if defined(ENABLE_PLUGIN_INSTALLATION) @@ -138,7 +137,7 @@ #include "chrome/browser/ui/webui/local_discovery/local_discovery_ui.h" #endif -#if defined(OS_ANDROID) +#if BUILDFLAG(ANDROID_JAVA_UI) #include "chrome/browser/android/bookmarks/partner_bookmarks_shim.h" #include "chrome/browser/android/most_visited_sites.h" #include "chrome/browser/android/new_tab_page_prefs.h" @@ -200,6 +199,7 @@ #endif #if defined(OS_CHROMEOS) && defined(ENABLE_APP_LIST) +#include "chrome/browser/ui/app_list/arc/arc_app_list_prefs.h" #include "chrome/browser/ui/app_list/google_now_extension.h" #endif @@ -298,10 +298,18 @@ TaskManager::RegisterPrefs(registry); #endif // defined(ENABLE_TASK_MANAGER) -#if !defined(OS_ANDROID) +#if defined(ENABLE_BACKGROUND) BackgroundModeManager::RegisterPrefs(registry); - ChromeTracingDelegate::RegisterPrefs(registry); +#endif + + // TODO(bshe): Use !defined(ANDROID_JAVA_UI) once + // codereview.chromium.org/1459793002 landed. +#if !defined(OS_ANDROID) || defined(USE_AURA) RegisterBrowserPrefs(registry); +#endif + +#if !defined(OS_ANDROID) + ChromeTracingDelegate::RegisterPrefs(registry); StartupBrowserCreator::RegisterLocalStatePrefs(registry); // The native GCM is used on Android instead. gcm::GCMChannelStatusSyncer::RegisterPrefs(registry); @@ -422,10 +430,8 @@ extensions::launch_util::RegisterProfilePrefs(registry); ExtensionWebUI::RegisterProfilePrefs(registry); extensions::ExtensionPrefs::RegisterProfilePrefs(registry); -#if !defined(OS_ANDROID) && !defined(OS_IOS) ToolbarActionsBar::RegisterProfilePrefs(registry); extensions::CopresenceService::RegisterProfilePrefs(registry); -#endif RegisterAnimationPolicyPrefs(registry); #endif // defined(ENABLE_EXTENSIONS) @@ -462,7 +468,7 @@ SupervisedUserWhitelistService::RegisterProfilePrefs(registry); #endif -#if defined(OS_ANDROID) +#if BUILDFLAG(ANDROID_JAVA_UI) variations::VariationsService::RegisterProfilePrefs(registry); MostVisitedSites::RegisterProfilePrefs(registry); NewTabPagePrefs::RegisterProfilePrefs(registry); @@ -484,7 +490,9 @@ signin::RegisterProfilePrefs(registry); #endif -#if !defined(OS_ANDROID) && !defined(OS_CHROMEOS) + // TODO(bshe): Revisit this once it is more clear on what should we do with + // default apps on Aura Android. See crbug.com/564738 +#if (!defined(OS_ANDROID) || defined(USE_AURA)) && !defined(OS_CHROMEOS) default_apps::RegisterProfilePrefs(registry); #endif @@ -503,6 +511,10 @@ flags_ui::PrefServiceFlagsStorage::RegisterProfilePrefs(registry); #endif +#if defined(OS_CHROMEOS) && defined(ENABLE_APP_LIST) + ArcAppListPrefs::RegisterProfilePrefs(registry); +#endif + #if defined(OS_WIN) component_updater::RegisterProfilePrefsForSwReporter(registry); NetworkProfileBubble::RegisterProfilePrefs(registry);
diff --git a/chrome/browser/prefs/incognito_mode_prefs.cc b/chrome/browser/prefs/incognito_mode_prefs.cc index e3d7499..543451d 100644 --- a/chrome/browser/prefs/incognito_mode_prefs.cc +++ b/chrome/browser/prefs/incognito_mode_prefs.cc
@@ -12,6 +12,7 @@ #include "base/time/time.h" #include "chrome/browser/profiles/profile.h" #include "chrome/common/chrome_switches.h" +#include "chrome/common/features.h" #include "chrome/common/pref_names.h" #include "components/pref_registry/pref_registry_syncable.h" #include "content/public/browser/browser_thread.h" @@ -26,9 +27,9 @@ #include "base/win/windows_version.h" #endif // OS_WIN -#if defined(OS_ANDROID) +#if BUILDFLAG(ANDROID_JAVA_UI) #include "chrome/browser/android/chrome_application.h" -#endif // OS_ANDROID +#endif // BUILDFLAG(ANDROID_JAVA_UI) using content::BrowserThread; @@ -208,7 +209,12 @@ bool IncognitoModePrefs::ArePlatformParentalControlsEnabled() { #if defined(OS_WIN) return PlatformParentalControlsValue::GetInstance()->is_enabled(); -#elif defined(OS_ANDROID) +#elif defined(OS_ANDROID) && defined(USE_AURA) + // TODO(bshe): Support parental controls for Aura Android. See + // crbug.com/564742 + NOTIMPLEMENTED(); + return false; +#elif BUILDFLAG(ANDROID_JAVA_UI) return chrome::android::ChromeApplication::AreParentalControlsEnabled(); #else return false;
diff --git a/chrome/browser/printing/print_job_worker.cc b/chrome/browser/printing/print_job_worker.cc index 771ce18..0b2552e 100644 --- a/chrome/browser/printing/print_job_worker.cc +++ b/chrome/browser/printing/print_job_worker.cc
@@ -16,6 +16,7 @@ #include "chrome/browser/browser_process.h" #include "chrome/browser/chrome_notification_types.h" #include "chrome/browser/printing/print_job.h" +#include "chrome/common/features.h" #include "chrome/grit/generated_resources.h" #include "content/public/browser/browser_thread.h" #include "content/public/browser/notification_service.h" @@ -27,7 +28,7 @@ #include "printing/printing_utils.h" #include "ui/base/l10n/l10n_util.h" -#if defined(OS_ANDROID) && !defined(USE_AURA) +#if BUILDFLAG(ANDROID_JAVA_UI) #include "chrome/browser/android/tab_android.h" #endif @@ -213,7 +214,7 @@ bool is_scripted) { DCHECK_CURRENTLY_ON(BrowserThread::UI); -#if defined(OS_ANDROID) && !defined(USE_AURA) +#if BUILDFLAG(ANDROID_JAVA_UI) if (is_scripted) { PrintingContextDelegate* printing_context_delegate = static_cast<PrintingContextDelegate*>(printing_context_delegate_.get());
diff --git a/chrome/browser/profile_resetter/profile_resetter.h b/chrome/browser/profile_resetter/profile_resetter.h index 31f92cd5..e230a15 100644 --- a/chrome/browser/profile_resetter/profile_resetter.h +++ b/chrome/browser/profile_resetter/profile_resetter.h
@@ -61,11 +61,11 @@ // Resets |resettable_flags| and calls |callback| on the UI thread on // completion. |default_settings| allows the caller to specify some default // settings. |default_settings| shouldn't be NULL. - void Reset(ResettableFlags resettable_flags, - scoped_ptr<BrandcodedDefaultSettings> master_settings, - const base::Closure& callback); + virtual void Reset(ResettableFlags resettable_flags, + scoped_ptr<BrandcodedDefaultSettings> master_settings, + const base::Closure& callback); - bool IsActive() const; + virtual bool IsActive() const; private: // Marks |resettable| as done and triggers |callback_| if all pending jobs
diff --git a/chrome/browser/profiles/profile.cc b/chrome/browser/profiles/profile.cc index 8566442..f967a254 100644 --- a/chrome/browser/profiles/profile.cc +++ b/chrome/browser/profiles/profile.cc
@@ -79,7 +79,7 @@ prefs::kSearchSuggestEnabled, true, user_prefs::PrefRegistrySyncable::SYNCABLE_PREF); -#if defined(OS_ANDROID) +#if BUILDFLAG(ANDROID_JAVA_UI) registry->RegisterStringPref( prefs::kContextualSearchEnabled, std::string(),
diff --git a/chrome/browser/profiles/profile_io_data.cc b/chrome/browser/profiles/profile_io_data.cc index e581281..d4f4c98f 100644 --- a/chrome/browser/profiles/profile_io_data.cc +++ b/chrome/browser/profiles/profile_io_data.cc
@@ -47,6 +47,7 @@ #include "chrome/browser/ui/search/new_tab_page_interceptor_service_factory.h" #include "chrome/common/chrome_paths.h" #include "chrome/common/chrome_switches.h" +#include "chrome/common/features.h" #include "chrome/common/pref_names.h" #include "chrome/common/url_constants.h" #include "components/about_handler/about_protocol_handler.h" @@ -867,7 +868,7 @@ void ProfileIOData::InitializeMetricsEnabledStateOnUIThread() { DCHECK_CURRENTLY_ON(BrowserThread::UI); -#if defined(OS_ANDROID) +#if BUILDFLAG(ANDROID_JAVA_UI) // TODO(dwkang): rename or unify the pref for UMA once we have conclusion // in crbugs.com/246495. // Android has it's own preferences for metrics / crash uploading. @@ -882,7 +883,7 @@ g_browser_process->local_state()); enable_metrics_.MoveToThread( BrowserThread::GetMessageLoopProxyForThread(BrowserThread::IO)); -#endif // defined(OS_ANDROID) +#endif // BUILDFLAG(ANDROID_JAVA_UI) } bool ProfileIOData::GetMetricsEnabledStateOnIOThread() const {
diff --git a/chrome/browser/push_messaging/push_messaging_browsertest.cc b/chrome/browser/push_messaging/push_messaging_browsertest.cc index 6e21fb0..a768787 100644 --- a/chrome/browser/push_messaging/push_messaging_browsertest.cc +++ b/chrome/browser/push_messaging/push_messaging_browsertest.cc
@@ -79,7 +79,9 @@ // InProcessBrowserTest: void SetUpCommandLine(base::CommandLine* command_line) override { - command_line->AppendSwitch(switches::kEnablePushMessagePayload); + command_line->AppendSwitch( + switches::kEnableExperimentalWebPlatformFeatures); + InProcessBrowserTest::SetUpCommandLine(command_line); }
diff --git a/chrome/browser/push_messaging/push_messaging_notification_manager.cc b/chrome/browser/push_messaging/push_messaging_notification_manager.cc index 88e0aa1..e5ec50aa 100644 --- a/chrome/browser/push_messaging/push_messaging_notification_manager.cc +++ b/chrome/browser/push_messaging/push_messaging_notification_manager.cc
@@ -13,6 +13,7 @@ #include "chrome/browser/notifications/platform_notification_service_impl.h" #include "chrome/browser/profiles/profile.h" #include "chrome/browser/push_messaging/push_messaging_constants.h" +#include "chrome/common/features.h" #include "chrome/common/pref_names.h" #include "chrome/grit/generated_resources.h" #include "components/rappor/rappor_utils.h" @@ -29,7 +30,7 @@ #include "ui/base/l10n/l10n_util.h" #include "url/gurl.h" -#if defined(OS_ANDROID) +#if BUILDFLAG(ANDROID_JAVA_UI) #include "chrome/browser/ui/android/tab_model/tab_model.h" #include "chrome/browser/ui/android/tab_model/tab_model_list.h" #else @@ -144,7 +145,7 @@ bool notification_needed = true; // Sites with a currently visible tab don't need to show notifications. -#if defined(OS_ANDROID) +#if BUILDFLAG(ANDROID_JAVA_UI) for (auto it = TabModelList::begin(); it != TabModelList::end(); ++it) { Profile* profile = (*it)->GetProfile(); WebContents* active_web_contents = (*it)->GetActiveWebContents(); @@ -158,11 +159,7 @@ notification_needed = false; break; } -#if defined(OS_ANDROID) } -#else - } -#endif // If more than one notification is showing for this Service Worker, close // the default notification if it happens to be part of this group.
diff --git a/chrome/browser/push_messaging/push_messaging_service_impl.cc b/chrome/browser/push_messaging/push_messaging_service_impl.cc index e1333d23..c26b3b5 100644 --- a/chrome/browser/push_messaging/push_messaging_service_impl.cc +++ b/chrome/browser/push_messaging/push_messaging_service_impl.cc
@@ -754,7 +754,7 @@ bool PushMessagingServiceImpl::AreMessagePayloadsEnabled() const { return base::CommandLine::ForCurrentProcess()->HasSwitch( - switches::kEnablePushMessagePayload); + switches::kEnableExperimentalWebPlatformFeatures); } gcm::GCMDriver* PushMessagingServiceImpl::GetGCMDriver() const {
diff --git a/chrome/browser/push_messaging/push_messaging_service_unittest.cc b/chrome/browser/push_messaging/push_messaging_service_unittest.cc index 22edd632..52a7069d 100644 --- a/chrome/browser/push_messaging/push_messaging_service_unittest.cc +++ b/chrome/browser/push_messaging/push_messaging_service_unittest.cc
@@ -95,7 +95,7 @@ // Force-enable encrypted payloads for incoming push messages. base::CommandLine::ForCurrentProcess()->AppendSwitch( - switches::kEnablePushMessagePayload); + switches::kEnableExperimentalWebPlatformFeatures); } ~PushMessagingServiceTest() override {}
diff --git a/chrome/browser/renderer_context_menu/render_view_context_menu_browsertest.cc b/chrome/browser/renderer_context_menu/render_view_context_menu_browsertest.cc index d1a19c8..7c4f707f 100644 --- a/chrome/browser/renderer_context_menu/render_view_context_menu_browsertest.cc +++ b/chrome/browser/renderer_context_menu/render_view_context_menu_browsertest.cc
@@ -476,8 +476,8 @@ ui_test_utils::WindowedTabAddedNotificationObserver tab_observer( content::NotificationService::AllSources()); - ASSERT_TRUE(test_server()->Start()); - GURL url(test_server()->GetURL(std::string())); + ASSERT_TRUE(embedded_test_server()->Start()); + GURL url(embedded_test_server()->GetURL("/")); scoped_ptr<TestRenderViewContextMenu> menu( CreateContextMenuMediaTypeNone(url, url));
diff --git a/chrome/browser/renderer_host/chrome_render_message_filter.cc b/chrome/browser/renderer_host/chrome_render_message_filter.cc index 75f77c05..d4ad767 100644 --- a/chrome/browser/renderer_host/chrome_render_message_filter.cc +++ b/chrome/browser/renderer_host/chrome_render_message_filter.cc
@@ -35,10 +35,6 @@ #include "extensions/common/manifest_handlers/default_locale_handler.h" #endif -#if defined(USE_TCMALLOC) -#include "chrome/browser/browser_about_handler.h" -#endif - using content::BrowserThread; using blink::WebCache;
diff --git a/chrome/browser/renderer_host/chrome_resource_dispatcher_host_delegate.cc b/chrome/browser/renderer_host/chrome_resource_dispatcher_host_delegate.cc index 351d35a9..f552005 100644 --- a/chrome/browser/renderer_host/chrome_resource_dispatcher_host_delegate.cc +++ b/chrome/browser/renderer_host/chrome_resource_dispatcher_host_delegate.cc
@@ -25,7 +25,6 @@ #include "chrome/browser/prerender/prerender_util.h" #include "chrome/browser/profiles/profile.h" #include "chrome/browser/profiles/profile_io_data.h" -#include "chrome/browser/renderer_host/data_reduction_proxy_resource_throttle_android.h" #include "chrome/browser/renderer_host/safe_browsing_resource_throttle.h" #include "chrome/browser/renderer_host/thread_hop_resource_throttle.h" #include "chrome/browser/safe_browsing/safe_browsing_service.h" @@ -33,6 +32,7 @@ #include "chrome/browser/tab_contents/tab_util.h" #include "chrome/browser/ui/login/login_prompt.h" #include "chrome/common/chrome_switches.h" +#include "chrome/common/features.h" #include "chrome/common/url_constants.h" #include "components/content_settings/core/browser/host_content_settings_map.h" #include "components/data_reduction_proxy/core/browser/data_reduction_proxy_io_data.h" @@ -88,8 +88,12 @@ #include "third_party/protobuf/src/google/protobuf/repeated_field.h" #endif -#if defined(OS_ANDROID) +#if BUILDFLAG(ANDROID_JAVA_UI) #include "chrome/browser/android/intercept_download_resource_throttle.h" +#endif + +#if defined(OS_ANDROID) +#include "chrome/browser/renderer_host/data_reduction_proxy_resource_throttle_android.h" #include "components/navigation_interception/intercept_navigation_delegate.h" #endif @@ -424,7 +428,7 @@ throttles->push_back(new DownloadResourceThrottle( download_request_limiter_, info->GetWebContentsGetterForRequest(), request->url(), request->method())); -#if defined(OS_ANDROID) +#if BUILDFLAG(ANDROID_JAVA_UI) throttles->push_back( new chrome::InterceptDownloadResourceThrottle( request, child_id, route_id, request_id));
diff --git a/chrome/browser/resources/chromeos/login/header_bar.html b/chrome/browser/resources/chromeos/login/header_bar.html index c6cd2fd..40ec8aca 100644 --- a/chrome/browser/resources/chromeos/login/header_bar.html +++ b/chrome/browser/resources/chromeos/login/header_bar.html
@@ -35,10 +35,4 @@ <button id="cancel-multiple-sign-in-button" class="custom-appearance" i18n-content="cancel"></button> </div> - <div id="cancel-consumer-management-enrollment" class="header-bar-item" - hidden> - <button id="cancel-consumer-management-enrollment-button" - class="custom-appearance" i18n-content="cancel"> - </button> - </div> </div>
diff --git a/chrome/browser/resources/chromeos/login/header_bar.js b/chrome/browser/resources/chromeos/login/header_bar.js index d9668e1..524e5ac 100644 --- a/chrome/browser/resources/chromeos/login/header_bar.js +++ b/chrome/browser/resources/chromeos/login/header_bar.js
@@ -62,9 +62,6 @@ this.handleSignoutClick_); $('cancel-multiple-sign-in-button').addEventListener('click', this.handleCancelMultipleSignInClick_); - $('cancel-consumer-management-enrollment-button').addEventListener( - 'click', - this.handleCancelConsumerManagementEnrollmentClick_); this.addSupervisedUserMenu.addEventListener('click', this.handleAddSupervisedUserClick_.bind(this)); if (Oobe.getInstance().displayType == DISPLAY_TYPE.LOGIN || @@ -214,16 +211,6 @@ }, /** - * Cancel consumer management enrollment button handler. - * - * @private - */ - handleCancelConsumerManagementEnrollmentClick_: function(e) { - chrome.send('cancelConsumerManagementEnrollment'); - e.stopPropagation(); - }, - - /** * If true then "Browse as Guest" button is shown. * * @type {boolean} @@ -300,8 +287,6 @@ (this.signinUIState_ == SIGNIN_UI_STATE.WRONG_HWID_WARNING); var isSamlPasswordConfirm = (this.signinUIState_ == SIGNIN_UI_STATE.SAML_PASSWORD_CONFIRM); - var isEnrollingConsumerManagement = (this.signinUIState_ == - SIGNIN_UI_STATE.CONSUMER_MANAGEMENT_ENROLLMENT); var isPasswordChangedUI = (this.signinUIState_ == SIGNIN_UI_STATE.PASSWORD_CHANGED); var isMultiProfilesUI = @@ -340,8 +325,6 @@ $('apps-header-bar-item').hidden = !this.hasApps_ || (!gaiaIsActive && !accountPickerIsActive); $('cancel-multiple-sign-in-item').hidden = !isMultiProfilesUI; - $('cancel-consumer-management-enrollment').hidden = - !isEnrollingConsumerManagement; if (!Oobe.getInstance().newKioskUI) { if (!$('apps-header-bar-item').hidden)
diff --git a/chrome/browser/resources/chromeos/login/screen_gaia_signin.js b/chrome/browser/resources/chromeos/login/screen_gaia_signin.js index 7abcaf4..1c7d517 100644 --- a/chrome/browser/resources/chromeos/login/screen_gaia_signin.js +++ b/chrome/browser/resources/chromeos/login/screen_gaia_signin.js
@@ -57,13 +57,6 @@ email: '', /** - * Whether consumer management enrollment is in progress. - * @type {boolean} - * @private - */ - isEnrollingConsumerManagement_: false, - - /** * Timer id of pending load. * @type {number} * @private @@ -438,10 +431,7 @@ onBeforeShow: function(data) { chrome.send('loginUIStateChanged', ['gaia-signin', true]); $('progress-dots').hidden = true; - $('login-header-bar').signinUIState = - this.isEnrollingConsumerManagement_ ? - SIGNIN_UI_STATE.CONSUMER_MANAGEMENT_ENROLLMENT : - SIGNIN_UI_STATE.GAIA_SIGNIN; + $('login-header-bar').signinUIState = SIGNIN_UI_STATE.GAIA_SIGNIN; // Ensure that GAIA signin (or loading UI) is actually visible. window.requestAnimationFrame(function() { @@ -545,8 +535,6 @@ this.isShowUsers_ = data.isShowUsers; this.updateControlsState(); - this.isEnrollingConsumerManagement_ = data.isEnrollingConsumerManagement; - this.classList.toggle('full-width', false); if (Oobe.getInstance().currentScreen === this) Oobe.getInstance().updateScreenSize(this);
diff --git a/chrome/browser/resources/md_extensions/compiled_resources.gyp b/chrome/browser/resources/md_extensions/compiled_resources.gyp index 50f7a41f..868cae3 100644 --- a/chrome/browser/resources/md_extensions/compiled_resources.gyp +++ b/chrome/browser/resources/md_extensions/compiled_resources.gyp
@@ -13,6 +13,7 @@ '../../../../ui/webui/resources/js/cr.js', '../../../../ui/webui/resources/js/i18n_behavior.js', 'item.js', + 'item_list.js', 'manager.js', 'service.js', 'sidebar.js',
diff --git a/chrome/browser/resources/md_extensions/item.js b/chrome/browser/resources/md_extensions/item.js index 547b074..6b9652d 100644 --- a/chrome/browser/resources/md_extensions/item.js +++ b/chrome/browser/resources/md_extensions/item.js
@@ -25,9 +25,6 @@ */ setItemAllowedIncognito: assertNotReached, - /** @return {boolean} */ - isInDevMode: assertNotReached, - /** * @param {string} id, * @param {chrome.developerPrivate.ExtensionView} view @@ -72,17 +69,6 @@ 'observeIdVisibility_(inDevMode, showingDetails_, data.id)', ], - /** - * @param {!chrome.developerPrivate.ExtensionInfo} data - * @param {!extensions.ItemDelegate} delegate - */ - factoryImpl: function(data, delegate) { - this.data = data; - this.id = data.id; - this.delegate_ = delegate; - this.inDevMode = delegate.isInDevMode(); - }, - /** @private */ observeIdVisibility_: function(inDevMode, showingDetails, id) { Polymer.dom.flush(); @@ -91,6 +77,7 @@ assert(this.data); idElement.innerHTML = this.i18n('itemId', this.data.id); } + this.fire('extension-item-size-changed', {item: this.data}); }, /** @private */ @@ -100,22 +87,22 @@ /** @private */ onDeleteTap_: function() { - this.delegate_.deleteItem(this.data.id); + this.delegate.deleteItem(this.data.id); }, /** @private */ onEnableChange_: function() { - this.delegate_.setItemEnabled(this.data.id, this.$.enabled.checked); + this.delegate.setItemEnabled(this.data.id, this.$.enabled.checked); }, /** @private */ onDetailsTap_: function() { - this.delegate_.showItemDetails(this.data.id); + this.delegate.showItemDetails(this.data.id); }, /** @private */ onAllowIncognitoChange_: function() { - this.delegate_.setItemAllowedIncognito( + this.delegate.setItemAllowedIncognito( this.data.id, this.$$('#allow-incognito').checked); }, @@ -124,7 +111,7 @@ * @private */ onInspectTap_: function(e) { - this.delegate_.inspectItemView(this.data.id, e.model.item); + this.delegate.inspectItemView(this.data.id, e.model.item); }, /**
diff --git a/chrome/browser/resources/md_extensions/item_list.css b/chrome/browser/resources/md_extensions/item_list.css new file mode 100644 index 0000000..9163291 --- /dev/null +++ b/chrome/browser/resources/md_extensions/item_list.css
@@ -0,0 +1,15 @@ +/* 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. */ + +h2 { + color: #5a5a5a; + font-size: 1.1em; + font-weight: normal; + margin-bottom: 0; + margin-top: 30px; +} + +.wrapper { + padding: 10px 0; +}
diff --git a/chrome/browser/resources/md_extensions/item_list.html b/chrome/browser/resources/md_extensions/item_list.html new file mode 100644 index 0000000..1d8958a --- /dev/null +++ b/chrome/browser/resources/md_extensions/item_list.html
@@ -0,0 +1,21 @@ +<link rel="import" href="chrome://resources/html/cr.html"> +<link rel="import" href="chrome://resources/polymer/v1_0/polymer/polymer.html"> +<link rel="import" href="chrome://resources/polymer/v1_0/iron-list/iron-list.html"> +<link rel="import" href="chrome://extensions/item.html"> + +<dom-module id="extensions-item-list"> + <template> + <h2>[[header]]</h2> + <iron-list id="list" items="[[items]]" as="item"> + <template> + <div class="wrapper"> + <extensions-item data="[[item]]" delegate="[[delegate]]" + id="[[item.id]]" in-dev-mode="[[inDevMode]]"> + </extensions-item> + </div> + </template> + </iron-list> + </template> + <link rel="import" type="css" href="chrome://extensions/item_list.css"> + <script src="chrome://extensions/item_list.js"></script> +</dom-module>
diff --git a/chrome/browser/resources/md_extensions/item_list.js b/chrome/browser/resources/md_extensions/item_list.js new file mode 100644 index 0000000..f94f885 --- /dev/null +++ b/chrome/browser/resources/md_extensions/item_list.js
@@ -0,0 +1,42 @@ +// 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. + +cr.define('extensions', function() { + var ItemList = Polymer({ + is: 'extensions-item-list', + + properties: { + /** @type {Array<!chrome.developerPrivate.ExtensionInfo>} */ + items: Array, + + /** @type {extensions.ItemDelegate} */ + delegate: Object, + + header: String, + + inDevMode: { + type: Boolean, + value: false, + }, + }, + + listeners: { + 'list.extension-item-size-changed': 'itemSizeChanged_', + }, + + /** + * Updates the size for a given item. + * @param {CustomEvent} e + * @private + * @suppress {checkTypes} Closure doesn't know $.list is an IronList. + */ + itemSizeChanged_: function(e) { + this.$.list.updateSizeForItem(e.detail.item); + }, + }); + + return { + ItemList: ItemList, + }; +});
diff --git a/chrome/browser/resources/md_extensions/manager.css b/chrome/browser/resources/md_extensions/manager.css index a5f689f7..d49f69c 100644 --- a/chrome/browser/resources/md_extensions/manager.css +++ b/chrome/browser/resources/md_extensions/manager.css
@@ -14,19 +14,12 @@ #items { -webkit-margin-start: 30px; + height: 100%; overflow-y: auto; padding-bottom: 30px; -} - -#items h2 { - color: #5a5a5a; - font-size: 1.1em; - font-weight: normal; - margin-bottom: 0; - margin-top: 30px; + width: 100%; } extensions-item { display: inline-block; - margin-top: 20px; }
diff --git a/chrome/browser/resources/md_extensions/manager.html b/chrome/browser/resources/md_extensions/manager.html index bfcb918..2dd99ba 100644 --- a/chrome/browser/resources/md_extensions/manager.html +++ b/chrome/browser/resources/md_extensions/manager.html
@@ -1,7 +1,8 @@ <link rel="import" href="chrome://resources/html/cr.html"> +<link rel="import" href="chrome://resources/html/i18n_behavior.html"> <link rel="import" href="chrome://resources/polymer/v1_0/polymer/polymer.html"> <link rel="import" href="chrome://resources/polymer/v1_0/paper-header-panel/paper-header-panel.html"> -<link rel="import" href="chrome://extensions/item.html"> +<link rel="import" href="chrome://extensions/item_list.html"> <link rel="import" href="chrome://extensions/service.html"> <link rel="import" href="chrome://extensions/sidebar.html"> <link rel="import" href="chrome://extensions/toolbar.html"> @@ -11,14 +12,20 @@ <paper-header-panel id="panel"> <extensions-toolbar class="paper-header" id="toolbar"> </extensions-toolbar> - <extensions-sidebar></extensions-sidebar> + <extensions-sidebar in-dev-mode="[[inDevMode]]"></extensions-sidebar> <div id="items"> - <h2 id="extensions-header" i18n-content="sidebarExtensions"></h2> - <div id="extensions-list"></div> - <h2 id="apps-header" i18n-content="sidebarApps"></h2> - <div id="apps-list"></div> - <h2 id="websites-header" i18n-content="sidebarWebsites"></h2> - <div id="websites-list"></div> + <extensions-item-list id="extensions-list" items="[[extensions]]" + delegate="[[service]]" header="[[i18n('sidebarExtensions')]]" + in-dev-mode="[[inDevMode]]"> + </extensions-item-list> + <extensions-item-list id="apps-list" items="[[apps]]" + delegate="[[service]]" header="[[i18n('sidebarApps')]]" + in-dev-mode="[[inDevMode]]"> + </extensions-item-list> + <extensions-item-list id="websites-list" items="[[websites]]" + delegate="[[service]]" header="[[i18n('sidebarWebsites')]]" + in-dev-mode="[[inDevMode]]"> + </extensions-item-list> </div> </paper-header-panel> </template>
diff --git a/chrome/browser/resources/md_extensions/manager.js b/chrome/browser/resources/md_extensions/manager.js index 0c5a2c3..417b5aa3 100644 --- a/chrome/browser/resources/md_extensions/manager.js +++ b/chrome/browser/resources/md_extensions/manager.js
@@ -34,39 +34,66 @@ properties: { /** @type {extensions.Sidebar} */ - sidebar: { - type: Object, - } + sidebar: Object, + + /** @type {extensions.Service} */ + service: Object, + + inDevMode: { + type: Boolean, + value: false, + }, + + /** @type {!Array<!chrome.developerPrivate.ExtensionInfo>} */ + extensions: { + type: Array, + value: function() { return []; }, + }, + + /** @type {!Array<!chrome.developerPrivate.ExtensionInfo>} */ + apps: { + type: Array, + value: function() { return []; }, + }, + + /** @type {!Array<!chrome.developerPrivate.ExtensionInfo>} */ + websites: { + type: Array, + value: function() { return []; }, + }, }, + behaviors: [ + I18nBehavior, + ], + ready: function() { /** @type {extensions.Sidebar} */ this.sidebar = this.$$('extensions-sidebar'); - extensions.Service.getInstance().managerReady(this); + this.service = extensions.Service.getInstance(); + this.service.managerReady(this); this.sidebar.setScrollDelegate(new ScrollHelper(this)); }, /** - * Creates and adds a new extensions-item element to the list, inserting it - * into its sorted position in the relevant section. - * @param {!chrome.developerPrivate.ExtensionInfo} extension The extension - * the item is representing. - * @param {!extensions.ItemDelegate} delegate The delegate for the item. + * @param {chrome.developerPrivate.ExtensionType} type The type of item. + * @return {string} The ID of the list that the item belongs in. + * @private */ - addItem: function(extension, delegate) { + getListId_: function(type) { var listId; var ExtensionType = chrome.developerPrivate.ExtensionType; - switch (extension.type) { + switch (type) { case ExtensionType.HOSTED_APP: case ExtensionType.LEGACY_PACKAGED_APP: - listId = 'websites-list'; + listId = 'websites'; break; case ExtensionType.PLATFORM_APP: - listId = 'apps-list'; + listId = 'apps'; break; case ExtensionType.EXTENSION: case ExtensionType.SHARED_MODULE: - listId = 'extensions-list'; + listId = 'extensions'; break; case ExtensionType.THEME: assertNotReached( @@ -74,41 +101,62 @@ break; } assert(listId); - var extensionItem = new extensions.Item(extension, delegate); - var itemList = this.$[listId]; + return listId; + }, - var insertBeforeChild = Array.prototype.find.call(itemList.children, - function(item) { - return compareExtensions(item.data, extension) > 0; + /** + * @param {string} listId The list to look for the item in. + * @param {string} itemId The id of the item to look for. + * @return {number} The index of the item in the list, or -1 if not found. + * @private + */ + getIndexInList_: function(listId, itemId) { + return this[listId].findIndex(function(item) { + return item.id == itemId; }); - itemList.insertBefore(extensionItem, insertBeforeChild); }, /** - * @param {string} id The id of the extension to get the item for. - * @return {?extensions.Item} + * Creates and adds a new extensions-item element to the list, inserting it + * into its sorted position in the relevant section. + * @param {!chrome.developerPrivate.ExtensionInfo} item The extension + * the new element is representing. */ - getItem: function(id) { - return this.$$('#' + id); - }, - - /** @param {string} id The id of the item to remove. */ - removeItem: function(id) { - var item = this.getItem(id); - if (item) - item.parentNode.removeChild(item); + addItem: function(item) { + var listId = this.getListId_(item.type); + // We should never try and add an existing item. + assert(this.getIndexInList_(listId, item.id) == -1); + var insertBeforeChild = this[listId].findIndex(function(listEl) { + return compareExtensions(listEl, item) > 0; + }); + if (insertBeforeChild == -1) + insertBeforeChild = this[listId].length; + this.splice(listId, insertBeforeChild, 0, item); }, /** - * Applies a function to each item present in the DOM. - * @param {!function(extensions.Item):void} callback The function to apply. + * @param {!chrome.developerPrivate.ExtensionInfo} item The data for the + * item to update. */ - forEachItem: function(callback) { - Array.prototype.forEach.call( - /** @type {Array<extensions.Item>} */( - Polymer.dom(this.root).querySelectorAll('extensions-item')), - callback); - }, + updateItem: function(item) { + var listId = this.getListId_(item.type); + var index = this.getIndexInList_(listId, item.id); + // We should never try and update a non-existent item. + assert(index >= 0); + this.set([listId, index], item); + }, + + /** + * @param {!chrome.developerPrivate.ExtensionInfo} item The data for the + * item to remove. + */ + removeItem: function(item) { + var listId = this.getListId_(item.type); + var index = this.getIndexInList_(listId, item.id); + // We should never try and remove a non-existent item. + assert(index >= 0); + this.splice(listId, index, 1); + }, }); /**
diff --git a/chrome/browser/resources/md_extensions/service.js b/chrome/browser/resources/md_extensions/service.js index cc4d824..a083720 100644 --- a/chrome/browser/resources/md_extensions/service.js +++ b/chrome/browser/resources/md_extensions/service.js
@@ -33,7 +33,7 @@ /** @private {Array<chrome.developerPrivate.ExtensionInfo>} */ this.extensions_ = extensions; for (let extension of extensions) - this.manager_.addItem(extension, this); + this.manager_.addItem(extension); }.bind(this)); chrome.developerPrivate.getProfileConfiguration( this.onProfileStateChanged_.bind(this)); @@ -46,10 +46,7 @@ onProfileStateChanged_: function(profileInfo) { /** @private {chrome.developerPrivate.ProfileInfo} */ this.profileInfo_ = profileInfo; - this.sidebar_.inDevMode = profileInfo.inDeveloperMode; - this.manager_.forEachItem(function(item) { - item.inDevMode = profileInfo.inDeveloperMode; - }); + this.manager_.set('inDevMode', profileInfo.inDeveloperMode); }, /** @@ -57,6 +54,10 @@ * @private */ onItemStateChanged_: function(eventData) { + var currentIndex = this.extensions_.findIndex(function(extension) { + return extension.id == eventData.item_id; + }); + var EventType = chrome.developerPrivate.EventType; switch (eventData.event_type) { case EventType.VIEW_REGISTERED: @@ -73,27 +74,17 @@ if (!eventData.extensionInfo) break; - var existing = this.manager_.getItem(eventData.extensionInfo.id); - if (existing) { - existing.data = eventData.extensionInfo; + if (currentIndex >= 0) { + this.extensions_[currentIndex] = eventData.extensionInfo; + this.manager_.updateItem(eventData.extensionInfo); } else { - // If there's no existing item in the list, there shouldn't be an - // extension with the same id in the data. - var currentIndex = this.extensions_.findIndex(function(extension) { - return extension.id == eventData.extensionInfo.id; - }); - assert(currentIndex == -1); - this.extensions_.push(eventData.extensionInfo); - this.manager_.addItem(eventData.extensionInfo, this); + this.manager_.addItem(eventData.extensionInfo); } break; case EventType.UNINSTALLED: - var currentIndex = this.extensions_.findIndex(function(extension) { - return extension.id == eventData.item_id; - }); + this.manager_.removeItem(this.extensions_[currentIndex]); this.extensions_.splice(currentIndex, 1); - this.manager_.removeItem(eventData.item_id); break; default: assertNotReached(); @@ -131,13 +122,6 @@ }, /** @override */ - isInDevMode: function() { - // It's possible this could be called before the profileInfo is - // initialized; that's fine, because we'll update the items when it is. - return !!this.profileInfo_ && this.profileInfo_.inDeveloperMode; - }, - - /** @override */ inspectItemView: function(id, view) { chrome.developerPrivate.openDevTools({ extensionId: id,
diff --git a/chrome/browser/resources/media_router/elements/media_router_container/media_router_container.css b/chrome/browser/resources/media_router/elements/media_router_container/media_router_container.css index 6bf24425..5a5f09f 100644 --- a/chrome/browser/resources/media_router/elements/media_router_container/media_router_container.css +++ b/chrome/browser/resources/media_router/elements/media_router_container/media_router_container.css
@@ -77,11 +77,6 @@ padding-top: 4px; } -.route { - color: rgb(150, 150, 150); - padding-top: 8px; -} - #searching-devices-spinner { height: 30px; width: 30px; @@ -100,6 +95,11 @@ font-weight: normal; } +.sink-subtext { + color: rgb(150, 150, 150); + padding-top: 8px; +} + .sink-text { -webkit-padding-end: 26px; line-height: normal; @@ -111,4 +111,4 @@ #route-details { margin-top: var(--container-header-height); -} \ No newline at end of file +}
diff --git a/chrome/browser/resources/media_router/elements/media_router_container/media_router_container.html b/chrome/browser/resources/media_router/elements/media_router_container/media_router_container.html index f3c93a3c..3fc7746b 100644 --- a/chrome/browser/resources/media_router/elements/media_router_container/media_router_container.html +++ b/chrome/browser/resources/media_router/elements/media_router_container/media_router_container.html
@@ -89,10 +89,12 @@ <div class="sink-text"> <span>[[item.name]]</span> </div> - <div class="sink-text route" - hidden$="[[computeRouteInSinkListHidden_(item.id, sinkToRouteMap_)]]"> - <span>[[computeRouteInSinkListValue_(item.id, sinkToRouteMap_)]]</span> - </div> + <template is="dom-if" + if="[[!computeSinkSubtextHidden_(item, sinkToRouteMap_)]]"> + <div class="sink-text sink-subtext"> + <span>[[computeSinkSubtext_(item, sinkToRouteMap_)]]</span> + </div> + </template> </div> </div> </paper-item>
diff --git a/chrome/browser/resources/media_router/elements/media_router_container/media_router_container.js b/chrome/browser/resources/media_router/elements/media_router_container/media_router_container.js index 9424143..f88b92f 100644 --- a/chrome/browser/resources/media_router/elements/media_router_container/media_router_container.js +++ b/chrome/browser/resources/media_router/elements/media_router_container/media_router_container.js
@@ -390,27 +390,6 @@ }, /** - * @param {!string} sinkId A sink ID. - * @return {boolean} Whether or not to hide the route info in the sink list - * that is associated with |sinkId|. - * @private - */ - computeRouteInSinkListHidden_: function(sinkId, sinkToRouteMap) { - return !sinkToRouteMap[sinkId]; - }, - - /** - * @param {!string} sinkId A sink ID. - * @return {string} The description value of the route associated with - * |sinkId|. - * @private - */ - computeRouteInSinkListValue_: function(sinkId, sinkToRouteMap) { - var route = sinkToRouteMap[sinkId]; - return route ? route.description : ''; - }, - - /** * @param {!Array<!media_router.CastMode>} castModeList The current list of * cast modes. * @return {boolean} Whether or not to hide the share screen subheading text. @@ -487,6 +466,38 @@ }, /** + * Returns the subtext to be shown for |sink|. Only called if + * |computeSinkSubtextHidden_| returns false for the same |sink| and + * |sinkToRouteMap|. + * @param {!media_router.Sink} sink + * @param {!Object<!string, ?media_router.Route>} sinkToRouteMap + * @return {string} The subtext to be shown. + * @private + */ + computeSinkSubtext_: function(sink, sinkToRouteMap) { + var route = sinkToRouteMap[sink.id]; + if (route && !this.isEmptyOrWhitespace_(route.description)) + return route.description; + + return sink.description; + }, + + /** + * Returns whether the sink subtext for |sink| should be hidden. + * @param {!media_router.Sink} sink + * @param {!Object<!string, ?media_router.Route>} sinkToRouteMap + * @return {boolean} |true| if the subtext should be hidden. + * @private + */ + computeSinkSubtextHidden_: function(sink, sinkToRouteMap) { + if (!this.isEmptyOrWhitespace_(sink.description)) + return false; + + var route = sinkToRouteMap[sink.id]; + return !route || this.isEmptyOrWhitespace_(route.description); + }, + + /** * @param {boolean} justOpened Whether the MR UI was just opened. * @return {boolean} Whether or not to hide the spinner. * @private @@ -527,6 +538,16 @@ }, /** + * Returns whether given string is null, empty, or whitespaces only. + * @param {?string} str String to be tested. + * @return {boolean} |true| if the string is null, empty, or whitespaces. + * @private + */ + isEmptyOrWhitespace_: function(str) { + return str === null || (/^\s*$/).test(str); + }, + + /** * Updates |currentView_| if the dialog had just opened and there's * only one local route. *
diff --git a/chrome/browser/resources/media_router/media_router_data.js b/chrome/browser/resources/media_router/media_router_data.js index aec528c..4568566 100644 --- a/chrome/browser/resources/media_router/media_router_data.js +++ b/chrome/browser/resources/media_router/media_router_data.js
@@ -150,19 +150,23 @@ /** * @param {string} id The ID of the media sink. * @param {string} name The name of the sink. + * @param {?string} description Optional description of the sink. * @param {media_router.SinkIconType} iconType the type of icon for the sink. * @param {media_router.SinkStatus} status The readiness state of the sink. * @param {!Array<number>} castModes Cast modes compatible with the sink. * @constructor * @struct */ - var Sink = function(id, name, iconType, status, castModes) { + var Sink = function(id, name, description, iconType, status, castModes) { /** @type {string} */ this.id = id; /** @type {string} */ this.name = name; + /** @type {?string} */ + this.description = description; + /** @type {SinkIconType} */ this.iconType = iconType;
diff --git a/chrome/browser/resources/pdf/elements/viewer-zoom-toolbar/viewer-zoom-button.css b/chrome/browser/resources/pdf/elements/viewer-zoom-toolbar/viewer-zoom-button.css index c9bb1896..02454185 100644 --- a/chrome/browser/resources/pdf/elements/viewer-zoom-toolbar/viewer-zoom-button.css +++ b/chrome/browser/resources/pdf/elements/viewer-zoom-toolbar/viewer-zoom-button.css
@@ -8,12 +8,14 @@ } :host([closed]) #wrapper { - transform: translateX(100%); + /* 132px roughly flips the location of the button across the right edge of the + * page. */ + transform: translateX(132px); transition-timing-function: cubic-bezier(0.4, 0, 1, 1); } :host-context([dir=rtl]):host([closed]) #wrapper { - transform: translateX(-100%); + transform: translateX(-132px); } paper-fab { @@ -26,6 +28,5 @@ @apply(--shadow-elevation-4dp); background-color: rgb(242, 242, 242); color: rgb(96, 96, 96); - margin: 0 48px; overflow: visible; }
diff --git a/chrome/browser/resources/pdf/elements/viewer-zoom-toolbar/viewer-zoom-toolbar.css b/chrome/browser/resources/pdf/elements/viewer-zoom-toolbar/viewer-zoom-toolbar.css index 4756c8b..c7577ef 100644 --- a/chrome/browser/resources/pdf/elements/viewer-zoom-toolbar/viewer-zoom-toolbar.css +++ b/chrome/browser/resources/pdf/elements/viewer-zoom-toolbar/viewer-zoom-toolbar.css
@@ -16,6 +16,16 @@ right: auto; } +#zoom-buttons { + position: relative; + right: 48px; +} + +:host-context([dir=rtl]) #zoom-buttons { + left: 48px; + right: auto; +} + viewer-zoom-button { display: block; }
diff --git a/chrome/browser/resources/pdf/elements/viewer-zoom-toolbar/viewer-zoom-toolbar.html b/chrome/browser/resources/pdf/elements/viewer-zoom-toolbar/viewer-zoom-toolbar.html index a2e3b372..b1ee0d99 100644 --- a/chrome/browser/resources/pdf/elements/viewer-zoom-toolbar/viewer-zoom-toolbar.html +++ b/chrome/browser/resources/pdf/elements/viewer-zoom-toolbar/viewer-zoom-toolbar.html
@@ -7,15 +7,13 @@ <template> <div id="zoom-buttons"> - <div id="buttons"> - <viewer-zoom-button id="fit-button" icons="fullscreen-exit fullscreen" - on-fabclick="fitToggle" delay="100"> - </viewer-zoom-button> - <viewer-zoom-button id="zoom-in-button" icons="add" - on-fabclick="zoomIn" delay="50"></viewer-zoom-button> - <viewer-zoom-button id="zoom-out-button" icons="remove" - on-fabclick="zoomOut" delay="0"></viewer-zoom-button> - </div> + <viewer-zoom-button id="fit-button" icons="fullscreen-exit fullscreen" + on-fabclick="fitToggle" delay="100"> + </viewer-zoom-button> + <viewer-zoom-button id="zoom-in-button" icons="add" + on-fabclick="zoomIn" delay="50"></viewer-zoom-button> + <viewer-zoom-button id="zoom-out-button" icons="remove" + on-fabclick="zoomOut" delay="0"></viewer-zoom-button> </div> </template> </dom-module>
diff --git a/chrome/browser/resources/settings/a11y_page/a11y_page.html b/chrome/browser/resources/settings/a11y_page/a11y_page.html index 66688cf..deeec10 100644 --- a/chrome/browser/resources/settings/a11y_page/a11y_page.html +++ b/chrome/browser/resources/settings/a11y_page/a11y_page.html
@@ -3,7 +3,7 @@ <link rel="import" href="chrome://md-settings/controls/settings_checkbox.html"> <dom-module id="settings-a11y-page"> - <link rel="import" type="css" href="chrome://md-settings/settings_page/settings_page.css"> + <link rel="import" type="css" href="chrome://md-settings/settings_shared.css"> <link rel="import" type="css" href="a11y_page.css"> <template> <div class="settings-box">
diff --git a/chrome/browser/resources/settings/appearance_page/appearance_fonts_page.html b/chrome/browser/resources/settings/appearance_page/appearance_fonts_page.html index d3f09a6..4d8d6045 100644 --- a/chrome/browser/resources/settings/appearance_page/appearance_fonts_page.html +++ b/chrome/browser/resources/settings/appearance_page/appearance_fonts_page.html
@@ -4,7 +4,7 @@ <dom-module id="settings-appearance-fonts-page"> <link rel="import" type="css" - href="chrome://md-settings/settings_page/settings_page.css"> + href="chrome://md-settings/settings_shared.css"> <link rel="import" type="css" href="chrome://md-settings/appearance_page/appearance_shared.css"> <template>
diff --git a/chrome/browser/resources/settings/appearance_page/appearance_page.html b/chrome/browser/resources/settings/appearance_page/appearance_page.html index 75effa7..04a5f5a 100644 --- a/chrome/browser/resources/settings/appearance_page/appearance_page.html +++ b/chrome/browser/resources/settings/appearance_page/appearance_page.html
@@ -15,7 +15,7 @@ <dom-module id="settings-appearance-page"> <link rel="import" type="css" - href="chrome://md-settings/settings_page/settings_page.css"> + href="chrome://md-settings/settings_shared.css"> <link rel="import" type="css" href="chrome://md-settings/appearance_page/appearance_shared.css"> <link rel="import" type="css" href="chrome://resources/css/widgets.css">
diff --git a/chrome/browser/resources/settings/bluetooth_page/bluetooth_page.html b/chrome/browser/resources/settings/bluetooth_page/bluetooth_page.html index 966ba25..0a5a725 100644 --- a/chrome/browser/resources/settings/bluetooth_page/bluetooth_page.html +++ b/chrome/browser/resources/settings/bluetooth_page/bluetooth_page.html
@@ -11,7 +11,7 @@ <link rel="import" href="chrome://md-settings/settings_page/settings_animated_pages.html"> <dom-module id="settings-bluetooth-page"> - <link rel="import" type="css" href="chrome://md-settings/settings_page/settings_page.css"> + <link rel="import" type="css" href="chrome://md-settings/settings_shared.css"> <link rel="import" type="css" href="bluetooth_page.css"> <template> <settings-animated-pages id="pages" current-route="{{currentRoute}}"
diff --git a/chrome/browser/resources/settings/clear_browsing_data_page/clear_browsing_data_page.html b/chrome/browser/resources/settings/clear_browsing_data_page/clear_browsing_data_page.html index 3ecec290..3edd6ddd 100644 --- a/chrome/browser/resources/settings/clear_browsing_data_page/clear_browsing_data_page.html +++ b/chrome/browser/resources/settings/clear_browsing_data_page/clear_browsing_data_page.html
@@ -8,7 +8,7 @@ <dom-module id="settings-clear-browsing-data-page"> <link rel="import" type="css" - href="chrome://md-settings/settings_page/settings_page.css"> + href="chrome://md-settings/settings_shared.css"> <link rel="import" type="css" href="clear_browsing_data_page.css"> <template> <div class="settings-box">
diff --git a/chrome/browser/resources/settings/controls/settings_dropdown_menu.html b/chrome/browser/resources/settings/controls/settings_dropdown_menu.html index 4e771932..a7b2caa 100644 --- a/chrome/browser/resources/settings/controls/settings_dropdown_menu.html +++ b/chrome/browser/resources/settings/controls/settings_dropdown_menu.html
@@ -7,7 +7,7 @@ <dom-module id="settings-dropdown-menu"> <link rel="import" type="css" - href="chrome://md-settings/settings_page/settings_page.css"> + href="chrome://md-settings/settings_shared.css"> <template> <paper-dropdown-menu id="dropdownMenu" label="[[menuLabel_]]" on-iron-select="onSelect_"
diff --git a/chrome/browser/resources/settings/date_time_page/date_time_page.html b/chrome/browser/resources/settings/date_time_page/date_time_page.html index 6363c3f32..0a298433 100644 --- a/chrome/browser/resources/settings/date_time_page/date_time_page.html +++ b/chrome/browser/resources/settings/date_time_page/date_time_page.html
@@ -4,7 +4,7 @@ <dom-module id="settings-date-time-page"> <link rel="import" type="css" - href="chrome://md-settings/settings_page/settings_page.css"> + href="chrome://md-settings/settings_shared.css"> <link rel="import" type="css" href="date_time_page.css"> <template> <div class="horizontal layout center">
diff --git a/chrome/browser/resources/settings/default_browser_page/default_browser_page.html b/chrome/browser/resources/settings/default_browser_page/default_browser_page.html index ae5c6857..fc63516 100644 --- a/chrome/browser/resources/settings/default_browser_page/default_browser_page.html +++ b/chrome/browser/resources/settings/default_browser_page/default_browser_page.html
@@ -5,7 +5,7 @@ <dom-module id="settings-default-browser-page"> <link rel="import" type="css" - href="chrome://md-settings/settings_page/settings_page.css"> + href="chrome://md-settings/settings_shared.css"> <link rel="import" type="css" href="default_browser_page.css"> <template> <div class="settings-box">[[message_]]</div>
diff --git a/chrome/browser/resources/settings/downloads_page/downloads_page.html b/chrome/browser/resources/settings/downloads_page/downloads_page.html index bb3fb94..0f81e676 100644 --- a/chrome/browser/resources/settings/downloads_page/downloads_page.html +++ b/chrome/browser/resources/settings/downloads_page/downloads_page.html
@@ -6,7 +6,7 @@ <dom-module id="settings-downloads-page"> <link rel="import" type="css" - href="chrome://md-settings/settings_page/settings_page.css"> + href="chrome://md-settings/settings_shared.css"> <link rel="import" type="css" href="downloads_page.css"> <template> <div class="settings-box split">
diff --git a/chrome/browser/resources/settings/internet_page/internet_detail_page.html b/chrome/browser/resources/settings/internet_page/internet_detail_page.html index 9e11b21..46eaa61 100644 --- a/chrome/browser/resources/settings/internet_page/internet_detail_page.html +++ b/chrome/browser/resources/settings/internet_page/internet_detail_page.html
@@ -18,7 +18,7 @@ <link rel="import" href="network_siminfo.html"> <dom-module id="settings-internet-detail-page"> - <link rel="import" type="css" href="chrome://md-settings/settings_page/settings_page.css"> + <link rel="import" type="css" href="chrome://md-settings/settings_shared.css"> <link rel="import" type="css" href="internet_detail_page.css"> <template> <div class="layout vertical">
diff --git a/chrome/browser/resources/settings/internet_page/internet_known_networks_page.html b/chrome/browser/resources/settings/internet_page/internet_known_networks_page.html index c6d1f50..6dd5f1e 100644 --- a/chrome/browser/resources/settings/internet_page/internet_known_networks_page.html +++ b/chrome/browser/resources/settings/internet_page/internet_known_networks_page.html
@@ -5,7 +5,7 @@ <link rel="import" href="chrome://resources/cr_elements/network/cr_network_list.html"> <dom-module id="settings-internet-known-networks-page"> - <link rel="import" type="css" href="chrome://md-settings/settings_page/settings_page.css"> + <link rel="import" type="css" href="chrome://md-settings/settings_shared.css"> <link rel="import" type="css" href="internet_known_networks_page.css"> <template> <div class="layout vertical">
diff --git a/chrome/browser/resources/settings/internet_page/internet_page.html b/chrome/browser/resources/settings/internet_page/internet_page.html index 995abea..543de58 100644 --- a/chrome/browser/resources/settings/internet_page/internet_page.html +++ b/chrome/browser/resources/settings/internet_page/internet_page.html
@@ -9,7 +9,7 @@ <dom-module id="settings-internet-page"> <link rel="import" type="css" - href="chrome://md-settings/settings_page/settings_page.css"> + href="chrome://md-settings/settings_shared.css"> <template> <settings-animated-pages id="pages" current-route="{{currentRoute}}" section="internet">
diff --git a/chrome/browser/resources/settings/languages_page/compiled_resources.gyp b/chrome/browser/resources/settings/languages_page/compiled_resources.gyp index 3726ded..67b25d33 100644 --- a/chrome/browser/resources/settings/languages_page/compiled_resources.gyp +++ b/chrome/browser/resources/settings/languages_page/compiled_resources.gyp
@@ -11,6 +11,7 @@ '../prefs/compiled_resources.gyp:prefs', '../../../../../ui/webui/resources/js/compiled_resources.gyp:assert', '../../../../../ui/webui/resources/js/compiled_resources.gyp:cr', + 'languages_types.js', ], 'externs': [ '<(EXTERNS_DIR)/chrome_send.js', @@ -27,6 +28,7 @@ '../../../../../ui/webui/resources/js/chromeos/compiled_resources.gyp:ui_account_tweaks', '../../../../../ui/webui/resources/js/compiled_resources.gyp:load_time_data', '../prefs/compiled_resources.gyp:prefs', + 'languages_types.js', 'languages.js', ], 'externs': [ @@ -45,6 +47,7 @@ '../settings_page/settings_animated_pages.js', '../prefs/prefs_types.js', '../prefs/compiled_resources.gyp:prefs', + 'languages_types.js', 'languages.js', ], 'externs': [ @@ -59,10 +62,11 @@ 'depends': [ '../../../../../ui/webui/resources/js/compiled_resources.gyp:assert', '../prefs/compiled_resources.gyp:prefs', + 'languages_types.js', 'languages.js', ], 'externs': [ - '../../../../../third_party/closure_compiler/externs/language_settings_private.js', + '<(EXTERNS_DIR)/language_settings_private.js', ], }, 'includes': ['../../../../../third_party/closure_compiler/compile_js.gypi'],
diff --git a/chrome/browser/resources/settings/languages_page/edit_dictionary_page.html b/chrome/browser/resources/settings/languages_page/edit_dictionary_page.html index 3d1dc31..6788df9 100644 --- a/chrome/browser/resources/settings/languages_page/edit_dictionary_page.html +++ b/chrome/browser/resources/settings/languages_page/edit_dictionary_page.html
@@ -8,7 +8,7 @@ <link rel="import" href="chrome://resources/polymer/v1_0/paper-item/paper-item.html"> <dom-module id="settings-edit-dictionary-page"> - <link rel="import" type="css" href="chrome://md-settings/settings_page/settings_page.css"> + <link rel="import" type="css" href="chrome://md-settings/settings_shared.css"> <link rel="import" type="css" href="edit_dictionary_page.css"> <template> <div class="settings-box">
diff --git a/chrome/browser/resources/settings/languages_page/language_detail_page.html b/chrome/browser/resources/settings/languages_page/language_detail_page.html index 1de5209..28bc6d6 100644 --- a/chrome/browser/resources/settings/languages_page/language_detail_page.html +++ b/chrome/browser/resources/settings/languages_page/language_detail_page.html
@@ -11,11 +11,10 @@ </if> <dom-module id="settings-language-detail-page"> - <link rel="import" type="css" href="chrome://md-settings/settings_page/settings_page.css"> + <link rel="import" type="css" href="chrome://md-settings/settings_shared.css"> <link rel="import" type="css" href="language_detail_page.css"> <template> - <settings-languages id="languages" languages="{{languages}}"> - </settings-languages> + <settings-languages languages="{{languages}}"></settings-languages> <if expr="chromeos or is_win"> <div id="languageSettings"> <label hidden$="[[!detail.language.supportsUI]]">
diff --git a/chrome/browser/resources/settings/languages_page/language_detail_page.js b/chrome/browser/resources/settings/languages_page/language_detail_page.js index b3b9166..8f89226 100644 --- a/chrome/browser/resources/settings/languages_page/language_detail_page.js +++ b/chrome/browser/resources/settings/languages_page/language_detail_page.js
@@ -35,6 +35,9 @@ detail: Object, }, + /** @private {!LanguageHelper} */ + languageHelper_: LanguageHelperImpl.getInstance(), + ready: function() { // In a CrOS multi-user session, the primary user controls the UI language. if (this.isSecondaryUser_()) { @@ -51,15 +54,19 @@ } }, +<if expr="chromeos or is_win"> /** + * Checks whether the prospective UI language (the pref that indicates what + * language to use in Chrome) matches the current language. This pref is only + * on Chrome OS and Windows; we don't control the UI language elsewhere. * @param {string} languageCode The language code identifying a language. - * @param {string} prospectiveUILanguage The chosen UI language. - * @return {boolean} True if the given language matches the chosen UI language - * (which may be different from the actual UI language). + * @param {string} prospectiveUILanguage The prospective UI language. + * @return {boolean} True if the given language matches the prospective UI + * pref (which may be different from the actual UI language). * @private */ isProspectiveUILanguage_: function(languageCode, prospectiveUILanguage) { - return languageCode == this.$.languages.getProspectiveUILanguage(); + return languageCode == this.languageHelper_.getProspectiveUILanguage(); }, /** @@ -73,6 +80,7 @@ return languageCode == prospectiveUILanguage && languageCode == navigator.language; }, +</if> /** * @param {string} languageCode The language code identifying a language. @@ -81,7 +89,7 @@ * @private */ isTranslateDisabled_: function(languageCode, targetLanguageCode) { - return this.$.languages.convertLanguageCodeForTranslate(languageCode) == + return this.languageHelper_.convertLanguageCodeForTranslate(languageCode) == targetLanguageCode; }, @@ -140,9 +148,9 @@ */ onTranslateEnabledChange_: function(e) { if (e.target.checked) - this.$.languages.enableTranslateLanguage(this.detail.language.code); + this.languageHelper_.enableTranslateLanguage(this.detail.language.code); else - this.$.languages.disableTranslateLanguage(this.detail.language.code); + this.languageHelper_.disableTranslateLanguage(this.detail.language.code); }, /** @@ -152,10 +160,10 @@ */ onUILanguageChange_: function(e) { if (e.target.checked) { - this.$.languages.setUILanguage(this.detail.language.code); + this.languageHelper_.setUILanguage(this.detail.language.code); } else { // Reset the chosen UI language to the actual UI language. - this.$.languages.resetUILanguage(); + this.languageHelper_.resetUILanguage(); } },
diff --git a/chrome/browser/resources/settings/languages_page/languages.js b/chrome/browser/resources/settings/languages_page/languages.js index bedacd7..a892542 100644 --- a/chrome/browser/resources/settings/languages_page/languages.js +++ b/chrome/browser/resources/settings/languages_page/languages.js
@@ -9,9 +9,9 @@ * Instances of this element have a 'languages' property, which reflects the * current language settings. The 'languages' property is read-only, meaning * hosts using this element cannot change it directly. Instead, changes to - * language settings should be made using this element's public functions. + * language settings should be made using the LanguageHelperImpl singleton. * - * Use two-way binding syntax to propagate changes from child to host, so that + * Use upward binding syntax to propagate changes from child to host, so that * changes made internally to 'languages' propagate to your host element: * * <template> @@ -24,26 +24,7 @@ * @element settings-languages */ -/** @typedef {{spellCheckEnabled: boolean, translateEnabled: boolean}} */ -var LanguageState; - -/** - * @typedef {{language: !chrome.languageSettingsPrivate.Language, - * state: !LanguageState}} - */ -var LanguageInfo; - -/** - * supportedLanguages: an array of languages, ordered alphabetically. - * enabledLanguages: an array of enabled language info and state, ordered by - * preference. - * @typedef {{ - * supportedLanguages: !Array<!chrome.languageSettingsPrivate.Language>, - * enabledLanguages: !Array<!LanguageInfo>, - * translateTarget: string - * }} - */ -var LanguagesModel; +var SettingsLanguagesSingletonElement; (function() { 'use strict'; @@ -66,130 +47,17 @@ 'jv': 'jw', }; -/** - * This element has a reference to the singleton, exposing the singleton's - * language model to the host of this element as the 'languages' property. - */ -Polymer({ - is: 'settings-languages', - - properties: { - /** - * Singleton element created at startup which provides the languages model. - * @type {!Element} - */ - singleton_: { - type: Object, - value: document.createElement('settings-languages-singleton'), - }, - - /** - * A reference to the languages model from the singleton, exposed as a - * read-only property so hosts can bind to it, but not change it. - * @type {LanguagesModel|undefined} - */ - languages: { - type: Object, - notify: true, - readOnly: true, - }, - }, - - ready: function() { - // Set the 'languages' property to reference the singleton's model. - this._setLanguages(this.singleton_.languages); - // Listen for changes to the singleton's languages property, so we know - // when to notify hosts of changes to (our reference to) the property. - this.listen( - this.singleton_, 'languages-changed', 'singletonLanguagesChanged_'); - }, - - /** - * Takes changes reported by the singleton and forwards them to the host, - * manually sending a change notification for our 'languages' property (since - * it's the same object as the singleton's property, but isn't bound by - * Polymer). - * @private - */ - singletonLanguagesChanged_: function(e) { - // Forward the change notification to the host. - this.fire(e.type, e.detail, {bubbles: false}); - }, - - // Forward public methods to the singleton. - - /** @param {string} languageCode */ - setUILanguage: function(languageCode) { - if (cr.isWindows || cr.isChromeOS) - this.singleton_.setUILanguage(languageCode); - }, - - resetUILanguage: function() { - if (cr.isWindows || cr.isChromeOS) - this.singleton_.resetUILanguage(); - }, - - /** @return {string} */ - getProspectiveUILanguage: function() { - return this.singleton_.getProspectiveUILanguage(); - }, - - /** @param {string} languageCode */ - enableLanguage: function(languageCode) { - this.singleton_.enableLanguage(languageCode); - }, - - /** @param {string} languageCode */ - disableLanguage: function(languageCode) { - this.singleton_.disableLanguage(languageCode); - }, - - /** @param {string} languageCode */ - enableTranslateLanguage: function(languageCode) { - this.singleton_.enableTranslateLanguage(languageCode); - }, - - /** @param {string} languageCode */ - disableTranslateLanguage: function(languageCode) { - this.singleton_.disableTranslateLanguage(languageCode); - }, - - /** - * @param {string} languageCode - * @return {boolean} - */ - isEnabled: function(languageCode) { - return this.singleton_.isEnabled(languageCode); - }, - - /** - * @param {string} languageCode - * @param {boolean} enable - */ - toggleSpellCheck: function(languageCode, enable) { - this.singleton_.toggleSpellCheck(languageCode, enable); - }, - - /** - * @param {string} languageCode - * @return {string} - */ - convertLanguageCodeForTranslate: function(languageCode) { - return this.singleton_.convertLanguageCodeForTranslate(languageCode); - }, -}); - var preferredLanguagesPrefName = cr.isChromeOS ? 'settings.language.preferred_languages' : 'intl.accept_languages'; /** - * Singleton element created when settings-languages is registered. - * Generates the languages model on start-up, and updates it whenever Chrome's - * pref store and other settings change. These updates propagate to each - * <settings-language> instance so that their 'languages' property updates - * like any other Polymer property. + * Singleton element that generates the languages model on start-up and + * updates it whenever Chrome's pref store and other settings change. These + * updates propagate to each <settings-language> instance so that their + * 'languages' property updates like any other Polymer property. + * @implements {LanguageHelper} */ -Polymer({ +SettingsLanguagesSingletonElement = Polymer({ is: 'settings-languages-singleton', behaviors: [PrefsBehavior], @@ -267,11 +135,68 @@ }, /** + * Updates the list of enabled languages from the preferred languages pref. + * @private + */ + preferredLanguagesPrefChanged_: function() { + if (!this.initialized_) + return; + + var enabledLanguages = + this.getEnabledLanguages_(this.languages.translateTarget); + + // Reset the enabled language map before updating + // languages.enabledLanguages. + this.enabledLanguageMap_ = {}; + for (var i = 0; i < enabledLanguages.length; i++) { + var languageInfo = enabledLanguages[i]; + this.enabledLanguageMap_[languageInfo.language.code] = languageInfo; + } + this.set('languages.enabledLanguages', enabledLanguages); + }, + + /** + * Updates the spellCheckEnabled state of each enabled language. + * @private + */ + spellCheckDictionariesPrefChanged_: function() { + if (!this.initialized_) + return; + + var spellCheckMap = this.makeMapFromArray_(/** @type {!Array<string>} */( + this.getPref('spellcheck.dictionaries').value)); + for (var i = 0; i < this.languages.enabledLanguages.length; i++) { + var languageCode = this.languages.enabledLanguages[i].language.code; + this.set('languages.enabledLanguages.' + i + '.state.spellCheckEnabled', + !!spellCheckMap[languageCode]); + } + }, + + /** @private */ + translateLanguagesPrefChanged_: function() { + if (!this.initialized_) + return; + + var translateBlockedPref = this.getPref('translate_blocked_languages'); + var translateBlockedMap = this.makeMapFromArray_( + /** @type {!Array<string>} */(translateBlockedPref.value)); + + for (var i = 0; i < this.languages.enabledLanguages.length; i++) { + var translateCode = this.convertLanguageCodeForTranslate( + this.languages.enabledLanguages[i].language.code); + this.set( + 'languages.enabledLanguages.' + i + '.state.translateEnabled', + !translateBlockedMap[translateCode]); + } + }, + + /** * Constructs the languages model. * @param {!Array<!chrome.languageSettingsPrivate.Language>} * supportedLanguages * @param {string} translateTarget Language code of the default translate * target language. + * @private */ createModel_: function(supportedLanguages, translateTarget) { // Populate the hash map of supported languages. @@ -325,17 +250,19 @@ for (var i = 0; i < enabledLanguageCodes.length; i++) { var code = enabledLanguageCodes[i]; var language = this.supportedLanguageMap_[code]; + // Skip unsupported languages. if (!language) continue; - var state = {}; + var state = /** @type {LanguageState} */({}); state.spellCheckEnabled = !!spellCheckMap[code]; // Translate is considered disabled if this language maps to any translate // language that is blocked. var translateCode = this.convertLanguageCodeForTranslate(code); - state.translateEnabled = language.supportsTranslate && + state.translateEnabled = !!language.supportsTranslate && !translateBlockedMap[translateCode] && translateCode != translateTarget; - enabledLanguages.push({language: language, state: state}); + enabledLanguages.push(/** @type {LanguageInfo} */( + {language: language, state: state})); } return enabledLanguages; }, @@ -344,6 +271,7 @@ * Creates an object whose keys are the elements of the list. * @param {!Array<string>} list * @return {!Object<boolean>} + * @private */ makeMapFromArray_: function(list) { var map = {}; @@ -352,84 +280,21 @@ return map; }, + // LanguageHelper implementation. + // TODO(michaelpg): replace duplicate docs with @override once b/24294625 + // is fixed. + +<if expr="chromeos or is_win"> /** - * Updates the list of enabled languages from the preferred languages pref. - * @private - * */ - preferredLanguagesPrefChanged_: function() { - if (!this.initialized_) - return; - - var enabledLanguages = - this.getEnabledLanguages_(this.languages.translateTarget); - // Reset the enabled language map. Do this before notifying of the change - // via languages.enabledLanguages. - this.enabledLanguageMap_ = {}; - for (var i = 0; i < enabledLanguages.length; i++) { - var languageInfo = enabledLanguages[i]; - this.enabledLanguageMap_[languageInfo.language.code] = languageInfo; - } - this.set('languages.enabledLanguages', enabledLanguages); - }, - - /** - * Updates the spellCheckEnabled state of each enabled language. - * @private - */ - spellCheckDictionariesPrefChanged_: function() { - if (!this.initialized_) - return; - - var spellCheckMap = this.makeMapFromArray_(/** @type {!Array<string>} */( - this.getPref('spellcheck.dictionaries').value)); - for (var i = 0; i < this.languages.enabledLanguages.length; i++) { - var languageCode = this.languages.enabledLanguages[i].language.code; - this.set('languages.enabledLanguages.' + i + '.state.spellCheckEnabled', - !!spellCheckMap[languageCode]); - } - }, - - translateLanguagesPrefChanged_: function() { - if (!this.initialized_) - return; - - var translateBlockedPref = this.getPref('translate_blocked_languages'); - var translateBlockedMap = this.makeMapFromArray_( - /** @type {!Array<string>} */(translateBlockedPref.value)); - - for (var i = 0; i < this.languages.enabledLanguages.length; i++) { - var translateCode = this.convertLanguageCodeForTranslate( - this.languages.enabledLanguages[i].language.code); - this.set( - 'languages.enabledLanguages.' + i + '.state.translateEnabled', - !translateBlockedMap[translateCode]); - } - }, - - /** - * Deletes the given item from the pref at the given key if the item is found. - * Asserts if the pref itself is not found or is not an Array type. - * @param {string} key - * @param {*} item - */ - deletePrefItem_: function(key, item) { - assert(this.getPref(key).type == chrome.settingsPrivate.PrefType.LIST); - this.arrayDelete('prefs.' + key + '.value', item); - }, - - /** - * Windows and Chrome OS only: Sets the prospective UI language to the chosen - * language. This dosen't affect the actual UI language until a restart. + * Sets the prospective UI language to the chosen language. This won't affect + * the actual UI language until a restart. * @param {string} languageCode */ setUILanguage: function(languageCode) { chrome.send('setUILanguage', [languageCode]); }, - /** - * Windows and Chrome OS only: Resets the prospective UI language back to the - * actual UI language. - */ + /** Resets the prospective UI language back to the actual UI language. */ resetUILanguage: function() { chrome.send('setUILanguage', [navigator.language]); }, @@ -439,12 +304,20 @@ * restart. If the pref is not set, the current UI language is also the * "prospective" language. * @return {string} Language code of the prospective UI language. - * @private */ getProspectiveUILanguage: function() { return /** @type {string} */(this.getPref('intl.app_locale').value) || navigator.language; }, +</if> + + /** + * @param {string} languageCode + * @return {boolean} True if the language is enabled. + */ + isLanguageEnabled: function(languageCode) { + return !!this.enabledLanguageMap_[languageCode]; + }, /** * Enables the language, making it available for spell check and input. @@ -471,17 +344,14 @@ if (!CrSettingsPrefs.isInitialized) return; - // Cannot disable the UI language. - assert(languageCode != this.getProspectiveUILanguage()); - - // Cannot disable the only enabled language. - var languageCodes = - this.getPref(preferredLanguagesPrefName).value.split(','); - assert(languageCodes.length > 1); + assert(this.canDisableLanguage(languageCode)); // Remove the language from spell check. - this.deletePrefItem_('spellcheck.dictionaries', languageCode); + this.deletePrefListItem('spellcheck.dictionaries', languageCode); + // Remove the language from preferred languages. + var languageCodes = + this.getPref(preferredLanguagesPrefName).value.split(','); var languageIndex = languageCodes.indexOf(languageCode); if (languageIndex == -1) return; @@ -491,11 +361,21 @@ }, /** - * @param {string} languageCode - * @return {boolean} True if the language is enabled. + * @param {string} languageCode Language code for an enabled language. + * @return {boolean} */ - isEnabled: function(languageCode) { - return !!this.enabledLanguageMap_[languageCode]; + canDisableLanguage: function(languageCode) { + // Cannot disable the prospective UI language. + if ((cr.isChromeOS || cr.isWindows) && + languageCode == this.getProspectiveUILanguage()) { + return false; + } + + // Cannot disable the only enabled language. + if (this.languages.enabledLanguages.length == 1) + return false; + + return true; }, /** @@ -505,7 +385,7 @@ */ enableTranslateLanguage: function(languageCode) { languageCode = this.convertLanguageCodeForTranslate(languageCode); - this.arrayDelete('prefs.translate_blocked_languages.value', languageCode); + this.deletePrefListItem('translate_blocked_languages', languageCode); }, /** @@ -514,11 +394,8 @@ * @param {string} languageCode */ disableTranslateLanguage: function(languageCode) { - languageCode = this.convertLanguageCodeForTranslate(languageCode); - if (this.getPref('translate_blocked_languages').value - .indexOf(languageCode) == -1) { - this.push('prefs.translate_blocked_languages.value', languageCode); - } + this.appendPrefListItem('translate_blocked_languages', + this.convertLanguageCodeForTranslate(languageCode)); }, /** @@ -532,10 +409,9 @@ if (enable) { var spellCheckPref = this.getPref('spellcheck.dictionaries'); - if (spellCheckPref.value.indexOf(languageCode) == -1) - this.push('prefs.spellcheck.dictionaries.value', languageCode); + this.appendPrefListItem('spellcheck.dictionaries', languageCode); } else { - this.arrayDelete('prefs.spellcheck.dictionaries.value', languageCode); + this.deletePrefListItem('spellcheck.dictionaries', languageCode); } }, @@ -545,7 +421,6 @@ * Accept-Language. * @param {string} languageCode * @return {string} The converted language code. - * @private */ convertLanguageCodeForTranslate: function(languageCode) { if (languageCode in kLanguageCodeToTranslateCode) @@ -562,5 +437,72 @@ return main; }, + + /** + * @param {string} languageCode + * @return {!chrome.languageSettingsPrivate.Language|undefined} + */ + getLanguage: function(languageCode) { + return this.supportedLanguageMap_[languageCode]; + }, }); })(); + +/** + * A reference to the singleton under the guise of a LanguageHelper + * implementation. This provides a limited API but implies the singleton + * should not be used directly for data binding. + */ +var LanguageHelperImpl = SettingsLanguagesSingletonElement; +cr.addSingletonGetter(LanguageHelperImpl); + +/** + * This element has a reference to the singleton, exposing the singleton's + * |languages| model to the host of this element. + */ +Polymer({ + is: 'settings-languages', + + properties: { + /** + * Singleton element created at startup which provides the languages model. + * @type {!SettingsLanguagesSingletonElement} + */ + singleton_: { + type: Object, + value: LanguageHelperImpl.getInstance(), + }, + + /** + * A reference to the languages model from the singleton, exposed as a + * read-only property so hosts can bind to it, but not change it. + * @type {LanguagesModel|undefined} + */ + languages: { + type: Object, + notify: true, + readOnly: true, + }, + }, + + ready: function() { + // Set the 'languages' property to reference the singleton's model. + this._setLanguages(this.singleton_.languages); + // Listen for changes to the singleton's languages property, so we know + // when to notify hosts of changes to (our reference to) the property. + this.listen( + this.singleton_, 'languages-changed', 'singletonLanguagesChanged_'); + }, + + /** + * Takes changes reported by the singleton and forwards them to the host, + * manually sending a change notification for our 'languages' property (since + * it's the same object as the singleton's property, but isn't bound by + * Polymer). + * @private + */ + singletonLanguagesChanged_: function(e) { + // Forward the change notification to the host. + this.fire(e.type, e.detail, {bubbles: false}); + }, +});
diff --git a/chrome/browser/resources/settings/languages_page/languages_page.html b/chrome/browser/resources/settings/languages_page/languages_page.html index 38fd7aa..882342c7 100644 --- a/chrome/browser/resources/settings/languages_page/languages_page.html +++ b/chrome/browser/resources/settings/languages_page/languages_page.html
@@ -20,11 +20,10 @@ <dom-module id="settings-languages-page"> <link rel="import" type="css" - href="chrome://md-settings/settings_page/settings_page.css"> + href="chrome://md-settings/settings_shared.css"> <link rel="import" type="css" href="languages_page.css"> <template> - <settings-languages id="languages" languages="{{languages}}"> - </settings-languages> + <settings-languages languages="{{languages}}"></settings-languages> <settings-animated-pages id="pages" current-route="{{currentRoute}}" section="languages"> <neon-animatable id="main"> @@ -37,9 +36,11 @@ <paper-item class="split" on-tap="onLanguageTap_"> <div class="flex" title="[[item.language.nativeDisplayName]]" >[[item.language.displayName]]</div> +<if expr="chromeos or is_win"> <iron-icon icon="done" - hidden$="[[!isUILanguage_(item.language.code, prefs.intl.app_locale.value)]]"> + hidden$="[[!isProspectiveUILanguage_(item.language.code, prefs.intl.app_locale.value)]]"> </iron-icon> +</if> <paper-icon-button icon="settings" on-tap="onShowLanguageDetailTap_"></paper-icon-button> </paper-item>
diff --git a/chrome/browser/resources/settings/languages_page/languages_page.js b/chrome/browser/resources/settings/languages_page/languages_page.js index dd43e36..12c83e3a 100644 --- a/chrome/browser/resources/settings/languages_page/languages_page.js +++ b/chrome/browser/resources/settings/languages_page/languages_page.js
@@ -43,19 +43,26 @@ }, }, + /** @private {!LanguageHelper} */ + languageHelper_: LanguageHelperImpl.getInstance(), + /** * Handler for clicking a language on the main page, which selects the * language as the prospective UI language on Chrome OS and Windows. * @param {!{model: !{item: !LanguageInfo}}} e */ onLanguageTap_: function(e) { + // Only change the UI language on platforms that allow it. + if (!cr.isChromeOS && !cr.isWindows) + return; + // Taps on the paper-icon-button are handled in onShowLanguageDetailTap_. if (e.target.tagName == 'PAPER-ICON-BUTTON') return; // Set the prospective UI language. This won't take effect until a restart. if (e.model.item.language.supportsUI) - this.$.languages.setUILanguage(e.model.item.language.code); + this.languageHelper_.setUILanguage(e.model.item.language.code); }, /** @@ -63,8 +70,8 @@ * @param {!{target: Element, model: !{item: !LanguageInfo}}} e */ onSpellCheckChange_: function(e) { - this.$.languages.toggleSpellCheck(e.model.item.language.code, - e.target.checked); + this.languageHelper_.toggleSpellCheck(e.model.item.language.code, + e.target.checked); }, /** @private */ @@ -102,16 +109,21 @@ }, </if> +<if expr="chromeos or is_win"> /** + * Checks whether the prospective UI language (the pref that indicates what + * language to use in Chrome) matches the current language. This pref is only + * on Chrome OS and Windows; we don't control the UI language elsewhere. * @param {string} languageCode The language code identifying a language. * @param {string} prospectiveUILanguage The prospective UI language. * @return {boolean} True if the given language matches the prospective UI * pref (which may be different from the actual UI language). * @private */ - isUILanguage_: function(languageCode, prospectiveUILanguage) { - return languageCode == this.$.languages.getProspectiveUILanguage(); + isProspectiveUILanguage_: function(languageCode, prospectiveUILanguage) { + return languageCode == this.languageHelper_.getProspectiveUILanguage(); }, +</if> /** * @param {string} id The input method ID.
diff --git a/chrome/browser/resources/settings/languages_page/languages_types.js b/chrome/browser/resources/settings/languages_page/languages_types.js new file mode 100644 index 0000000..895d3469b --- /dev/null +++ b/chrome/browser/resources/settings/languages_page/languages_types.js
@@ -0,0 +1,127 @@ +// 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. + +/** + * @fileoverview Closure typedefs for dictionaries and interfaces used by + * language settings. + */ + +/** + * Current properties of a language. + * @typedef {{spellCheckEnabled: boolean, translateEnabled: boolean, + * removable: boolean}} */ +var LanguageState; + +/** + * Information about a language including intrinsic information (|language|) + * and the |state| of the language. + * @typedef {{language: !chrome.languageSettingsPrivate.Language, + * state: !LanguageState}} + */ +var LanguageInfo; + +/** + * Languages data to expose to consumers. + * supportedLanguages: an array of languages, ordered alphabetically. + * enabledLanguages: an array of enabled language info, ordered by preference. + * translateTarget: the default language to translate into. + * @typedef {{ + * supportedLanguages: !Array<!chrome.languageSettingsPrivate.Language>, + * enabledLanguages: !Array<!LanguageInfo>, + * translateTarget: string + * }} + */ +var LanguagesModel; + +/** + * Helper methods implemented by settings-languages-singleton. The nature of + * the interaction between the singleton Polymer element and the |languages| + * properties kept in sync is hidden from the consumer, which can just treat + * these methods as a handy interface. + * @interface + */ +var LanguageHelper = function() {}; + +LanguageHelper.prototype = { + +<if expr="chromeos or is_win"> + /** + * Sets the prospective UI language to the chosen language. This won't affect + * the actual UI language until a restart. + * @param {string} languageCode + */ + setUILanguage: assertNotReached, + + /** Resets the prospective UI language back to the actual UI language. */ + resetUILanguage: assertNotReached, + + /** + * Returns the "prospective" UI language, i.e. the one to be used on next + * restart. If the pref is not set, the current UI language is also the + * "prospective" language. + * @return {string} Language code of the prospective UI language. + */ + getProspectiveUILanguage: assertNotReached, +</if> + + /** + * @param {string} languageCode + * @return {boolean} + */ + isLanguageEnabled: assertNotReached, + + /** + * Enables the language, making it available for spell check and input. + * @param {string} languageCode + */ + enableLanguage: assertNotReached, + + /** + * Disables the language. + * @param {string} languageCode + */ + disableLanguage: assertNotReached, + + /** + * @param {string} languageCode Language code for an enabled language. + * @return {boolean} + */ + canDisableLanguage: assertNotReached, + + /** + * Enables translate for the given language by removing the translate + * language from the blocked languages preference. + * @param {string} languageCode + */ + enableTranslateLanguage: assertNotReached, + + /** + * Disables translate for the given language by adding the translate + * language to the blocked languages preference. + * @param {string} languageCode + */ + disableTranslateLanguage: assertNotReached, + + /** + * Enables or disables spell check for the given language. + * @param {string} languageCode + * @param {boolean} enable + */ + toggleSpellCheck: assertNotReached, + + /** + * Converts the language code for translate. There are some differences + * between the language set the Translate server uses and that for + * Accept-Language. + * @param {string} languageCode + * @return {string} The converted language code. + */ + convertLanguageCodeForTranslate: assertNotReached, + + /** + * @param {string} languageCode + * @return {!chrome.languageSettingsPrivate.Language|undefined} + */ + getLanguage: assertNotReached, +};
diff --git a/chrome/browser/resources/settings/languages_page/manage_languages_page.html b/chrome/browser/resources/settings/languages_page/manage_languages_page.html index 5051ce5..393585f5 100644 --- a/chrome/browser/resources/settings/languages_page/manage_languages_page.html +++ b/chrome/browser/resources/settings/languages_page/manage_languages_page.html
@@ -11,11 +11,10 @@ <dom-module id="settings-manage-languages-page"> <link rel="import" type="css" - href="chrome://md-settings/settings_page/settings_page.css"> + href="chrome://md-settings/settings_shared.css"> <link rel="import" type="css" href="manage_languages_page.css"> <template> - <settings-languages id="languages" languages="{{languages}}"> - </settings-languages> + <settings-languages languages="{{languages}}"></settings-languages> <div class="settings-box content"> <h2 i18n-content="enabledLanguages"></h2> <div>
diff --git a/chrome/browser/resources/settings/languages_page/manage_languages_page.js b/chrome/browser/resources/settings/languages_page/manage_languages_page.js index 9dda84c1..36a8cc4 100644 --- a/chrome/browser/resources/settings/languages_page/manage_languages_page.js +++ b/chrome/browser/resources/settings/languages_page/manage_languages_page.js
@@ -37,6 +37,9 @@ availableLanguages_: Array, }, + /** @private {!LanguageHelper} */ + languageHelper_: LanguageHelperImpl.getInstance(), + observers: [ 'enabledLanguagesChanged_(languages.enabledLanguages.*)', ], @@ -47,7 +50,7 @@ * @private */ onRemoveLanguageTap_: function(e) { - this.$.languages.disableLanguage(e.model.item.language.code); + this.languageHelper_.disableLanguage(e.model.item.language.code); }, /** @@ -56,19 +59,19 @@ * @private */ onAddLanguageTap_: function(e) { - this.$.languages.enableLanguage(e.model.item.code); + this.languageHelper_.enableLanguage(e.model.item.code); }, /** * True if a language is not the current or prospective UI language. * @param {string} languageCode - * @param {!Array<!LanguageInfo>} prospectiveUILanguage + * @param {string} prospectiveUILanguageCode * @return {boolean} * @private */ - canRemoveLanguage_: function(languageCode, prospectiveUILanguage) { + canRemoveLanguage_: function(languageCode, prospectiveUILanguageCode) { if (languageCode == navigator.language || - languageCode == prospectiveUILanguage) { + languageCode == prospectiveUILanguageCode) { return false; } assert(this.languages.enabledLanguages.length > 1); @@ -88,7 +91,7 @@ code: language.code, displayName: language.displayName, nativeDisplayName: language.nativeDisplayName, - enabled: this.$.languages.isEnabled(language.code) + enabled: this.languageHelper_.isLanguageEnabled(language.code), }); } // Set the Polymer property after building the full array. @@ -97,7 +100,8 @@ // Update the available languages in place. for (var i = 0; i < this.availableLanguages_.length; i++) { this.set('availableLanguages_.' + i + '.enabled', - this.$.languages.isEnabled(this.availableLanguages_[i].code)); + this.languageHelper_.isLanguageEnabled( + this.availableLanguages_[i].code)); } } },
diff --git a/chrome/browser/resources/settings/on_startup_page/on_startup_page.html b/chrome/browser/resources/settings/on_startup_page/on_startup_page.html index 1d823303..53d082c 100644 --- a/chrome/browser/resources/settings/on_startup_page/on_startup_page.html +++ b/chrome/browser/resources/settings/on_startup_page/on_startup_page.html
@@ -9,7 +9,7 @@ <dom-module id="settings-on-startup-page"> <link rel="import" type="css" - href="chrome://md-settings/settings_page/settings_page.css"> + href="chrome://md-settings/settings_shared.css"> <link rel="import" type="css" href="on_startup_shared.css"> <template> <settings-animated-pages id="pages" current-route="{{currentRoute}}"
diff --git a/chrome/browser/resources/settings/on_startup_page/startup_urls_page.html b/chrome/browser/resources/settings/on_startup_page/startup_urls_page.html index a4e3a771..f68e8da 100644 --- a/chrome/browser/resources/settings/on_startup_page/startup_urls_page.html +++ b/chrome/browser/resources/settings/on_startup_page/startup_urls_page.html
@@ -3,7 +3,7 @@ <link rel="import" href="chrome://resources/polymer/v1_0/paper-item/paper-icon-item.html"> <dom-module id="settings-startup-urls-page"> - <link rel="import" type="css" href="chrome://md-settings/settings_page/settings_page.css"> + <link rel="import" type="css" href="chrome://md-settings/settings_shared.css"> <link rel="import" type="css" href="on_startup_shared.css"> <template> <div class="settings-box">
diff --git a/chrome/browser/resources/settings/passwords_and_forms_page/passwords_and_forms_page.html b/chrome/browser/resources/settings/passwords_and_forms_page/passwords_and_forms_page.html index 6041ca6..8a733ff 100644 --- a/chrome/browser/resources/settings/passwords_and_forms_page/passwords_and_forms_page.html +++ b/chrome/browser/resources/settings/passwords_and_forms_page/passwords_and_forms_page.html
@@ -6,7 +6,7 @@ <dom-module id="settings-passwords-and-forms-page"> <link rel="import" type="css" - href="chrome://md-settings/settings_page/settings_page.css"> + href="chrome://md-settings/settings_shared.css"> <template> <div class="settings-box"> <paper-item>
diff --git a/chrome/browser/resources/settings/prefs/prefs_behavior.js b/chrome/browser/resources/settings/prefs/prefs_behavior.js index 5a4c15d..8c94460 100644 --- a/chrome/browser/resources/settings/prefs/prefs_behavior.js +++ b/chrome/browser/resources/settings/prefs/prefs_behavior.js
@@ -32,4 +32,31 @@ this.getPref(prefPath); // Ensures we throw if the pref is not found. this.set('prefs.' + prefPath + '.value', value); }, + + /** + * Appends the item to the pref list at the given key if the item is not + * already in the list. Asserts if the pref itself is not found or is not an + * Array type. + * @param {string} key + * @param {*} item + * @protected + */ + appendPrefListItem: function(key, item) { + var pref = this.getPref(key); + assert(pref && pref.type == chrome.settingsPrivate.PrefType.LIST); + if (pref.value.indexOf(item) == -1) + this.push('prefs.' + key + '.value', item); + }, + + /** + * Deletes the given item from the pref at the given key if the item is found. + * Asserts if the pref itself is not found or is not an Array type. + * @param {string} key + * @param {*} item + * @protected + */ + deletePrefListItem: function(key, item) { + assert(this.getPref(key).type == chrome.settingsPrivate.PrefType.LIST); + this.arrayDelete('prefs.' + key + '.value', item); + }, };
diff --git a/chrome/browser/resources/settings/privacy_page/privacy_page.html b/chrome/browser/resources/settings/privacy_page/privacy_page.html index 410da507..008ede1 100644 --- a/chrome/browser/resources/settings/privacy_page/privacy_page.html +++ b/chrome/browser/resources/settings/privacy_page/privacy_page.html
@@ -13,7 +13,7 @@ <dom-module id="settings-privacy-page"> <link rel="import" type="css" - href="chrome://md-settings/settings_page/settings_page.css"> + href="chrome://md-settings/settings_shared.css"> <link rel="import" type="css" href="privacy_page.css"> <template> <settings-animated-pages id="pages" current-route="{{currentRoute}}"
diff --git a/chrome/browser/resources/settings/reset_page/powerwash_dialog.html b/chrome/browser/resources/settings/reset_page/powerwash_dialog.html index fa650541..824b52d 100644 --- a/chrome/browser/resources/settings/reset_page/powerwash_dialog.html +++ b/chrome/browser/resources/settings/reset_page/powerwash_dialog.html
@@ -3,20 +3,31 @@ <link rel="import" href="chrome://resources/polymer/v1_0/paper-button/paper-button.html"> <link rel="import" href="chrome://resources/polymer/v1_0/paper-checkbox/paper-checkbox.html"> <link rel="import" href="chrome://resources/polymer/v1_0/paper-dialog/paper-dialog.html"> +<link rel="import" href="chrome://resources/polymer/v1_0/paper-icon-button/paper-icon-button.html"> <dom-module id="settings-powerwash-dialog"> + <link rel="import" type="css" href="reset_page_dialog.css"> <template> <paper-dialog modal id="dialog"> - <h2 i18n-content="powerwashDialogTitle"></h2> - <div i18n-content="powerwashDialogBody"></div> - <div class="layout center horizontal" id="buttonContainer"> - <paper-button i18n-content="learnMore" - on-tap="onLearnMoreTap_" id="learnMore"></paper-button> - <div class="layout center buttons flex-1"> - <paper-button on-tap="onCancelTap_" id="cancel" - i18n-content="cancel"></paper-button> - <paper-button on-tap="onRestartTap_" id="powerwash" - i18n-content="powerwashDialogButton"></paper-button> + <div id="dialog-content"> + <div class="dialog-top-row"> + <span class="dialog-title" i18n-content="powerwashDialogTitle"></span> + <paper-icon-button icon="clear" on-tap="onCancelTap_" id="close"> + </paper-icon-button> + </div> + <div class="dialog-body"> + <div class="explanation"> + <span i18n-content="powerwashDialogExplanation"></span> + <a i18n-values="href:powerwashLearnMoreUrl" + i18n-content="learnMore" target="_blank"></a> + </div> + <div class="button-container"> + <paper-button class="cancel-button" on-tap="onCancelTap_" + id="cancel" i18n-content="cancel"></paper-button> + <paper-button class="action-button" id="powerwash" + on-tap="onRestartTap_" i18n-content="powerwashDialogButton"> + </paper-button> + </div> </div> </div> </paper-dialog>
diff --git a/chrome/browser/resources/settings/reset_page/powerwash_dialog.js b/chrome/browser/resources/settings/reset_page/powerwash_dialog.js index cd8ebca5..b55bd9e 100644 --- a/chrome/browser/resources/settings/reset_page/powerwash_dialog.js +++ b/chrome/browser/resources/settings/reset_page/powerwash_dialog.js
@@ -27,9 +27,4 @@ onRestartTap_: function() { chrome.send('requestFactoryResetRestart'); }, - - /** @private */ - onLearnMoreTap_: function() { - window.open(loadTimeData.getString('powerwashLearnMoreUrl')); - }, });
diff --git a/chrome/browser/resources/settings/reset_page/reset_page.html b/chrome/browser/resources/settings/reset_page/reset_page.html index e4eaa234..ac6b8147 100644 --- a/chrome/browser/resources/settings/reset_page/reset_page.html +++ b/chrome/browser/resources/settings/reset_page/reset_page.html
@@ -7,7 +7,7 @@ <dom-module id="settings-reset-page"> <link rel="import" type="css" - href="chrome://md-settings/settings_page/settings_page.css"> + href="chrome://md-settings/settings_shared.css"> <template> <div class="settings-box" id="resetProfile" on-tap="onShowResetProfileDialog_">
diff --git a/chrome/browser/resources/settings/reset_page/reset_page_dialog.css b/chrome/browser/resources/settings/reset_page/reset_page_dialog.css new file mode 100644 index 0000000..9bdac00e --- /dev/null +++ b/chrome/browser/resources/settings/reset_page/reset_page_dialog.css
@@ -0,0 +1,64 @@ +/* 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. */ + +#dialog-content { + -webkit-padding-end: 0; + -webkit-padding-start: 0; + margin-top: 0; +} + +.dialog-top-row { + align-items: center; + border-bottom: 1px solid gainsboro; + display: flex; + padding-bottom: 5px; + padding-top: 5px; +} + +.dialog-title { + flex: 1; + font-size: 1.13em; +} + +.dialog-body { + font-size: 1em; + margin: 20px 0; +} + +.dialog-title, +.dialog-body { + -webkit-padding-end: 24px; + -webkit-padding-start: 24px; +} + +.action-button { + -webkit-margin-start: 10px; + background-color: rgb(66, 133, 244); + color: white; + font-weight: 500; +} + +.cancel-button { + color: rgb(109, 109, 109); + font-weight: 500; +} + +paper-button { + margin: 0; +} + +a { + color: rgb(66, 133, 244); + text-decoration: none; +} + +.explanation { + margin-bottom: 35px; +} + +.button-container { + display: flex; + flex: 1; + justify-content: flex-end; +}
diff --git a/chrome/browser/resources/settings/reset_page/reset_profile_dialog.css b/chrome/browser/resources/settings/reset_page/reset_profile_dialog.css index 665657934..805be9c 100644 --- a/chrome/browser/resources/settings/reset_page/reset_profile_dialog.css +++ b/chrome/browser/resources/settings/reset_page/reset_profile_dialog.css
@@ -7,27 +7,6 @@ width: 500px; } -#reset { - -webkit-margin-start: 10px; - -webkit-padding-end: 15px; - -webkit-padding-start: 15px; - background-color: rgb(120, 120, 120); - color: white; -} - -#learnMore, -#cancel { - color: rgb(94, 94, 94); -} - -#explanation { - margin: 10px 0; -} - -#buttonContainer { - margin: 15px 0; -} - #feedbackBar { background-color: rgb(236, 236, 236); margin: 0;
diff --git a/chrome/browser/resources/settings/reset_page/reset_profile_dialog.html b/chrome/browser/resources/settings/reset_page/reset_profile_dialog.html index 2a1a57a..6d164ac 100644 --- a/chrome/browser/resources/settings/reset_page/reset_profile_dialog.html +++ b/chrome/browser/resources/settings/reset_page/reset_profile_dialog.html
@@ -3,24 +3,32 @@ <link rel="import" href="chrome://resources/polymer/v1_0/paper-button/paper-button.html"> <link rel="import" href="chrome://resources/polymer/v1_0/paper-checkbox/paper-checkbox.html"> <link rel="import" href="chrome://resources/polymer/v1_0/paper-dialog/paper-dialog.html"> +<link rel="import" href="chrome://resources/polymer/v1_0/paper-icon-button/paper-icon-button.html"> <link rel="import" href="chrome://resources/polymer/v1_0/paper-spinner/paper-spinner.html"> <dom-module id="settings-reset-profile-dialog"> + <link rel="import" type="css" href="reset_page_dialog.css"> <link rel="import" type="css" href="reset_profile_dialog.css"> <template> <paper-dialog modal id="dialog"> - <div> - <h2 i18n-content="resetPageTitle"></h2> - <div i18n-content="resetPageExplanation" id="explanation"></div> - <div class="layout center horizontal" id="buttonContainer"> - <paper-button on-tap="onLearnMoreTap_" id="learnMore" - i18n-content="learnMore"></paper-button> - <div class="layout center buttons flex-1"> + <div id="dialog-content"> + <div class="dialog-top-row"> + <span class="dialog-title" i18n-content="resetPageTitle"></span> + <paper-icon-button icon="clear" on-tap="onCancelTap_" id="close"> + </paper-icon-button> + </div> + <div class="dialog-body"> + <div class="explanation"> + <span i18n-content="resetPageExplanation"></span> + <a i18n-values="href:resetPageLearnMoreUrl" + i18n-content="learnMore" target="_blank"></a> + </div> + <div class="button-container"> <paper-spinner id="resetSpinner"></paper-spinner> - <paper-button on-tap="onCancelTap_" id="cancel" - i18n-content="cancel"></paper-button> - <paper-button i18n-content="resetPageCommit" on-tap="onResetTap_" - id="reset"></paper-button> + <paper-button class="cancel-button" on-tap="onCancelTap_" + id="cancel" i18n-content="cancel"></paper-button> + <paper-button class="action-button" i18n-content="resetPageCommit" + on-tap="onResetTap_" id="reset"></paper-button> </div> </div> </div>
diff --git a/chrome/browser/resources/settings/reset_page/reset_profile_dialog.js b/chrome/browser/resources/settings/reset_page/reset_profile_dialog.js index 3fe767d..9ba069b 100644 --- a/chrome/browser/resources/settings/reset_page/reset_profile_dialog.js +++ b/chrome/browser/resources/settings/reset_page/reset_profile_dialog.js
@@ -53,11 +53,6 @@ }, /** @private */ - onLearnMoreTap_: function() { - window.open(loadTimeData.getString('resetPageLearnMoreUrl')); - }, - - /** @private */ onSendSettingsChange_: function() { // TODO(dpapad): Update how settings info is surfaced when final mocks // exist.
diff --git a/chrome/browser/resources/settings/search_engines_page/search_engines_page.html b/chrome/browser/resources/settings/search_engines_page/search_engines_page.html index f457aab2..184dd5b 100644 --- a/chrome/browser/resources/settings/search_engines_page/search_engines_page.html +++ b/chrome/browser/resources/settings/search_engines_page/search_engines_page.html
@@ -3,7 +3,7 @@ <link rel="import" href="search_engines_list.html"> <dom-module id="settings-search-engines-page"> - <link rel="import" type="css" href="chrome://md-settings/settings_page/settings_page.css"> + <link rel="import" type="css" href="chrome://md-settings/settings_shared.css"> <template> <div class="settings-box"> <cr-search-engine-adder></cr-search-engine-adder>
diff --git a/chrome/browser/resources/settings/search_page/search_page.html b/chrome/browser/resources/settings/search_page/search_page.html index dc879f55..3891b40 100644 --- a/chrome/browser/resources/settings/search_page/search_page.html +++ b/chrome/browser/resources/settings/search_page/search_page.html
@@ -8,7 +8,7 @@ <dom-module id="settings-search-page"> <link rel="import" type="css" - href="chrome://md-settings/settings_page/settings_page.css"> + href="chrome://md-settings/settings_shared.css"> <link rel="import" type="css" href="search_page.css"> <template> <settings-animated-pages id="pages" current-route="{{currentRoute}}"
diff --git a/chrome/browser/resources/settings/settings_resources.grd b/chrome/browser/resources/settings/settings_resources.grd index 7723bac2..27e2192 100644 --- a/chrome/browser/resources/settings/settings_resources.grd +++ b/chrome/browser/resources/settings/settings_resources.grd
@@ -127,8 +127,8 @@ <structure name="IDR_SETTINGS_CR_SETTINGS_SUBHEADER_JS" file="settings_page/settings_subheader.js" type="chrome_html" /> - <structure name="IDR_SETTINGS_CR_SETTINGS_PAGE_CSS" - file="settings_page/settings_page.css" + <structure name="IDR_SETTINGS_CR_SETTINGS_SHARED_CSS" + file="settings_shared.css" type="chrome_html" /> <structure name="IDR_SETTINGS_BREADCRUMB_CSS" file="settings_ui/breadcrumb.css" @@ -232,6 +232,9 @@ <structure name="IDR_SETTINGS_POWERWASH_DIALOG_JS" file="reset_page/powerwash_dialog.js" type="chrome_html" /> + <structure name="IDR_SETTINGS_RESET_PAGE_DIALOG_CSS" + file="reset_page/reset_page_dialog.css" + type="chrome_html" /> <structure name="IDR_SETTINGS_RESET_PAGE_HTML" file="reset_page/reset_page.html" type="chrome_html" @@ -253,7 +256,9 @@ type="chrome_html" /> <structure name="IDR_SETTINGS_LANGUAGES_JS" file="languages_page/languages.js" - type="chrome_html" /> + type="chrome_html" + flattenhtml="true" + allowexternalscript="true" /> <structure name="IDR_SETTINGS_LANGUAGES_PAGE_CSS" file="languages_page/languages_page.css" type="chrome_html" /> @@ -286,7 +291,9 @@ allowexternalscript="true" /> <structure name="IDR_SETTINGS_LANGUAGES_LANGUAGE_DETAIL_PAGE_JS" file="languages_page/language_detail_page.js" - type="chrome_html" /> + type="chrome_html" + flattenhtml="true" + allowexternalscript="true" /> <if expr="not is_macosx"> <structure name="IDR_SETTINGS_LANGUAGES_EDIT_DICTIONARY_PAGE_CSS" file="languages_page/edit_dictionary_page.css"
diff --git a/chrome/browser/resources/settings/settings_page/settings_page.css b/chrome/browser/resources/settings/settings_shared.css similarity index 65% rename from chrome/browser/resources/settings/settings_page/settings_page.css rename to chrome/browser/resources/settings/settings_shared.css index c4db693d..1ea45da 100644 --- a/chrome/browser/resources/settings/settings_page/settings_page.css +++ b/chrome/browser/resources/settings/settings_shared.css
@@ -4,31 +4,8 @@ /** * @fileoverview - * Common styles for Settings pages. + * Common styles for Material Design settings. */ -:host > paper-material { - -webkit-padding-start: 80px; - background-color: white; - display: flex; - flex-direction: column; - padding: 40px; -} - -.soft-border { - border: 1px solid #c4c4c4; - border-radius: 2px; -} - -.page-content { - width: 760px; -} - -settings-checkbox { - -webkit-margin-end: 10px; - -webkit-margin-start: 0; - margin-bottom: 10px; - margin-top: 10px; -} paper-button { margin: 0; @@ -36,7 +13,7 @@ } paper-button[toggles][active] { - background-color: lightgrey; + background-color: LightGray; } h2 { @@ -52,6 +29,10 @@ margin-top: 25px; } +.button-strip { + text-align: end; +} + .settings-box { @apply(--layout-center); border-top: 1px solid #e0e0e0; @@ -76,7 +57,3 @@ /* Same padding as paper-icon-button. */ padding: 8px; } - -.button-strip { - text-align: end; -}
diff --git a/chrome/browser/resources/settings/signin_page/signin_page.html b/chrome/browser/resources/settings/signin_page/signin_page.html index 42bb0124..e74f5c4 100644 --- a/chrome/browser/resources/settings/signin_page/signin_page.html +++ b/chrome/browser/resources/settings/signin_page/signin_page.html
@@ -11,40 +11,57 @@ <dom-module id="settings-signin-page"> <link rel="import" type="css" - href="chrome://md-settings/settings_page/settings_page.css"> + href="chrome://md-settings/settings_shared.css"> <template> <settings-animated-pages id="pages" current-route="{{currentRoute}}" section="people"> <neon-animatable id="main"> - <div class="settings-box split" hidden="[[!isStatusTextSet_(syncStatus)]]"> + <div class="settings-box"> + <div class="split"> + <span class="start"> + <!-- TODO(tommycli): Show current profile icon and name here. + To be done by December 2015. --> + </span> + <span> + <template is="dom-if" if="[[!syncStatus.signedIn]]"> + <paper-button on-tap="onSigninTap_" raised + disabled="[[syncStatus.setupInProgress]]"> + [[i18n('syncSignin')]] + </paper-button> + </template> + <template is="dom-if" if="[[syncStatus.signedIn]]"> + <paper-button on-tap="onDisconnectTap_" + disabled="[[syncStatus.setupInProgress]]"> + [[i18n('syncDisconnect')]] + </paper-button> + </template> + </span> + </div> + <div hidden="[[syncStatus.signedIn]]">[[i18n('syncOverview')]]</div> + </div> + + <div class="settings-box split" + hidden="[[!isStatusTextSet_(syncStatus)]]"> <span id="syncStatusText"></span> <paper-button on-tap="onActionLinkTap_"> [[syncStatus.actionLinkText]] </paper-button> </div> - <template is="dom-if" if="[[!syncStatus.signedIn]]"> - <div class="settings-box">[[i18n('syncOverview')]]</div> - <div class="settings-box button-strip"> - <paper-button on-tap="onSigninTap_" raised - disabled="[[syncStatus.setupInProgress]]"> - [[i18n('syncSignin')]] - </paper-button> - </div> - </template> - <template is="dom-if" if="[[syncStatus.signedIn]]"> - <paper-button on-tap="onDisconnectTap_" raised - disabled="[[syncStatus.setupInProgress]]"> - [[i18n('syncDisconnect')]] - </paper-button> - - <template is="dom-if" - if="[[isAdvancedSyncSettingsVisible_(syncStatus)]]"> + <template is="dom-if" + if="[[isAdvancedSyncSettingsVisible_(syncStatus)]]"> + <div class="settings-box"> <paper-button on-tap="onSyncTap_" raised> [[i18n('syncPageTitle')]] </paper-button> - </template> + </div> </template> + + <div class="settings-box"> + <paper-button i18n-content="manageOtherPeople" + on-tap="onManageOtherPeople_"> + </paper-button> + </div> </neon-animatable> <neon-animatable id="sync"> <settings-subheader i18n-values="page-title:syncPageTitle">
diff --git a/chrome/browser/resources/settings/signin_page/signin_page.js b/chrome/browser/resources/settings/signin_page/signin_page.js index c4ea9f7..5be01225 100644 --- a/chrome/browser/resources/settings/signin_page/signin_page.js +++ b/chrome/browser/resources/settings/signin_page/signin_page.js
@@ -84,21 +84,25 @@ this.$.pages.setSubpageChain(['sync']); }, - /** - * @private - * @return {boolean} - */ - isStatusTextSet_: function() { - return this.syncStatus && this.syncStatus.statusText.length > 0; + /** @private */ + onManageOtherPeople_: function() { + settings.SyncPrivateApi.manageOtherPeople(); }, /** * @private * @return {boolean} */ - isAdvancedSyncSettingsVisible_: function() { - var status = this.syncStatus; - return status && status.signedIn && !status.managed && - status.syncSystemEnabled; + isStatusTextSet_: function(syncStatus) { + return syncStatus && syncStatus.statusText.length > 0; + }, + + /** + * @private + * @return {boolean} + */ + isAdvancedSyncSettingsVisible_: function(syncStatus) { + return syncStatus && syncStatus.signedIn && !syncStatus.managed && + syncStatus.syncSystemEnabled; }, });
diff --git a/chrome/browser/resources/settings/site_settings/site_details.html b/chrome/browser/resources/settings/site_settings/site_details.html index 0c50fcdc..33d96f7 100644 --- a/chrome/browser/resources/settings/site_settings/site_details.html +++ b/chrome/browser/resources/settings/site_settings/site_details.html
@@ -6,7 +6,7 @@ <dom-module id="site-details"> <link rel="import" type="css" - href="chrome://md-settings/settings_page/settings_page.css"> + href="chrome://md-settings/settings_shared.css"> <link rel="import" type="css" href="site_details.css"> <template> <div class="settings-box">
diff --git a/chrome/browser/resources/settings/site_settings/site_details_permission.html b/chrome/browser/resources/settings/site_settings/site_details_permission.html index d99e49a0..ba54d4eb 100644 --- a/chrome/browser/resources/settings/site_settings/site_details_permission.html +++ b/chrome/browser/resources/settings/site_settings/site_details_permission.html
@@ -12,7 +12,7 @@ <dom-module id="site-details-permission"> <link rel="import" type="css" - href="chrome://md-settings/settings_page/settings_page.css"> + href="chrome://md-settings/settings_shared.css"> <link rel="import" type="css" href="site_details_permission.css"> <template> <div id="details" class="horizontal layout top" hidden>
diff --git a/chrome/browser/resources/settings/site_settings/site_list.html b/chrome/browser/resources/settings/site_settings/site_list.html index 2c0ae8337..51414d1 100644 --- a/chrome/browser/resources/settings/site_settings/site_list.html +++ b/chrome/browser/resources/settings/site_settings/site_list.html
@@ -13,7 +13,7 @@ <link rel="import" href="chrome://md-settings/site_settings/site_settings_behavior.html"> <dom-module id="settings-site-list"> - <link rel="import" type="css" href="../settings_page/settings_page.css"> + <link rel="import" type="css" href="../settings_shared.css"> <link rel="import" type="css" href="site_list.css"> <template> <paper-submenu id="category" hidden on-paper-submenu-open="onToggle_"
diff --git a/chrome/browser/resources/settings/site_settings/site_settings_category.html b/chrome/browser/resources/settings/site_settings/site_settings_category.html index 829ba97..268d93db 100644 --- a/chrome/browser/resources/settings/site_settings/site_settings_category.html +++ b/chrome/browser/resources/settings/site_settings/site_settings_category.html
@@ -16,7 +16,7 @@ <dom-module id="site-settings-category"> <link rel="import" type="css" - href="chrome://md-settings/settings_page/settings_page.css"> + href="chrome://md-settings/settings_shared.css"> <link rel="import" type="css" href="site_settings_category.css"> <template> <settings-animated-pages id="pages" current-route="{{currentRoute}}"
diff --git a/chrome/browser/resources/settings/sync_page/sync_page.css b/chrome/browser/resources/settings/sync_page/sync_page.css index 1e47219e..3b2eda89 100644 --- a/chrome/browser/resources/settings/sync_page/sync_page.css +++ b/chrome/browser/resources/settings/sync_page/sync_page.css
@@ -2,21 +2,18 @@ * Use of this source code is governed by a BSD-style license that can be * found in the LICENSE file. */ +paper-checkbox { + margin-bottom: 10px; +} + paper-radio-button { display: block; } -.checkbox-container { - display: flex; - flex-flow: column; +#sync-item-list { + margin-left: 32px; } -.checkbox-container-row { - display: flex; -} - -.checkbox-container-row > paper-checkbox { - display: flex; - flex-basis: 0; - flex-grow: 1; +#sync-item-list paper-checkbox { + display: block; }
diff --git a/chrome/browser/resources/settings/sync_page/sync_page.html b/chrome/browser/resources/settings/sync_page/sync_page.html index e01921a..ca62faed 100644 --- a/chrome/browser/resources/settings/sync_page/sync_page.html +++ b/chrome/browser/resources/settings/sync_page/sync_page.html
@@ -12,72 +12,60 @@ <dom-module id="settings-sync-page"> <link rel="import" type="css" - href="chrome://md-settings/settings_page/settings_page.css"> + href="chrome://md-settings/settings_shared.css"> <link rel="import" type="css" href="sync_page.css"> <template> <iron-pages id="pages" selected="loading" attr-for-selected="id"> <div id="loading" i18n-content="syncLoading"></div> <div id="timeout" i18n-content="syncTimeout"></div> <div id="main"> - <paper-dropdown-menu> - <paper-menu id="syncSelector" class="dropdown-content" - selected="[[selectedSyncSelectorIndex_(syncPrefs.syncAllDataTypes)]]" - on-iron-select="onSyncSelectorChanged_"> - <paper-item name="sync-everything" - i18n-content="syncEverythingMenuOption"> - </paper-item> - <paper-item name="choose-what-to-sync" - i18n-content="chooseWhatToSyncMenuOption"> - </paper-item> - </paper-menu> - </paper-dropdown-menu> + <div class="settings-box"> + <paper-checkbox checked="{{syncPrefs.syncAllDataTypes}}" + on-change="onSyncAllDataTypesChanged_"> + <span i18n-content="syncEverythingCheckboxLabel"> + </paper-checkbox> - <div class="checkbox-container"> - <div class="checkbox-container-row"> + <div id="sync-item-list"> <paper-checkbox checked="{{syncPrefs.appsSynced}}" hidden="[[!syncPrefs.appsRegistered]]" disabled="[[shouldSyncCheckboxBeDisabled_(syncPrefs.syncAllDataTypes, syncPrefs.appsEnforced)]]"> <span i18n-content="appCheckboxLabel"></span> </paper-checkbox> + <paper-checkbox checked="{{syncPrefs.autofillSynced}}" + hidden="[[!syncPrefs.autofillRegistered]]" + disabled="[[shouldSyncCheckboxBeDisabled_(syncPrefs.syncAllDataTypes, syncPrefs.autofillEnforced)]]"> + <span i18n-content="autofillCheckboxLabel"></span> + </paper-checkbox> + <paper-checkbox checked="{{syncPrefs.bookmarksSynced}}" + hidden="[[!syncPrefs.bookmarksRegistered]]" + disabled="[[shouldSyncCheckboxBeDisabled_(syncPrefs.syncAllDataTypes, syncPrefs.bookmarksEnforced)]]"> + <span i18n-content="bookmarksCheckboxLabel"></span> + </paper-checkbox> <paper-checkbox checked="{{syncPrefs.extensionsSynced}}" hidden="[[!syncPrefs.extensionsRegistered]]" disabled="[[shouldSyncCheckboxBeDisabled_(syncPrefs.syncAllDataTypes, syncPrefs.extensionsEnforced)]]"> <span i18n-content="extensionsCheckboxLabel"></span> </paper-checkbox> - <paper-checkbox checked="{{syncPrefs.preferencesSynced}}" - hidden="[[!syncPrefs.preferencesRegistered]]" - disabled="[[shouldSyncCheckboxBeDisabled_(syncPrefs.syncAllDataTypes, syncPrefs.preferencesEnforced)]]"> - <span i18n-content="settingsCheckboxLabel"></span> - </paper-checkbox> - </div> - <div class="checkbox-container-row"> - <paper-checkbox checked="{{syncPrefs.autofillSynced}}" - hidden="[[!syncPrefs.autofillRegistered]]" - disabled="[[shouldSyncCheckboxBeDisabled_(syncPrefs.syncAllDataTypes, syncPrefs.autofillEnforced)]]"> - <span i18n-content="autofillCheckboxLabel"></span> - </paper-checkbox> <paper-checkbox checked="{{syncPrefs.typedUrlsSynced}}" hidden="[[!syncPrefs.typedUrlsRegistered]]" disabled="[[shouldSyncCheckboxBeDisabled_(syncPrefs.syncAllDataTypes, syncPrefs.typedUrlsEnforced)]]"> <span i18n-content="historyCheckboxLabel"></span> </paper-checkbox> - <paper-checkbox checked="{{syncPrefs.themesSynced}}" - hidden="[[!syncPrefs.themesRegistered]]" - disabled="[[shouldSyncCheckboxBeDisabled_(syncPrefs.syncAllDataTypes, syncPrefs.themesEnforced)]]"> - <span i18n-content="themesAndWallpapersCheckboxLabel"></span> - </paper-checkbox> - </div> - <div class="checkbox-container-row"> - <paper-checkbox checked="{{syncPrefs.bookmarksSynced}}" - hidden="[[!syncPrefs.bookmarksRegistered]]" - disabled="[[shouldSyncCheckboxBeDisabled_(syncPrefs.syncAllDataTypes, syncPrefs.bookmarksEnforced)]]"> - <span i18n-content="bookmarksCheckboxLabel"></span> - </paper-checkbox> <paper-checkbox checked="{{syncPrefs.passwordsSynced}}" hidden="[[!syncPrefs.passwordsRegistered]]" disabled="[[shouldSyncCheckboxBeDisabled_(syncPrefs.syncAllDataTypes, syncPrefs.passwordsEnforced)]]"> <span i18n-content="passwordsCheckboxLabel"></span> </paper-checkbox> + <paper-checkbox checked="{{syncPrefs.preferencesSynced}}" + hidden="[[!syncPrefs.preferencesRegistered]]" + disabled="[[shouldSyncCheckboxBeDisabled_(syncPrefs.syncAllDataTypes, syncPrefs.preferencesEnforced)]]"> + <span i18n-content="settingsCheckboxLabel"></span> + </paper-checkbox> + <paper-checkbox checked="{{syncPrefs.themesSynced}}" + hidden="[[!syncPrefs.themesRegistered]]" + disabled="[[shouldSyncCheckboxBeDisabled_(syncPrefs.syncAllDataTypes, syncPrefs.themesEnforced)]]"> + <span i18n-content="themesAndWallpapersCheckboxLabel"></span> + </paper-checkbox> <paper-checkbox checked="{{syncPrefs.tabsSynced}}" hidden="[[!syncPrefs.tabsRegistered]]" disabled="[[shouldSyncCheckboxBeDisabled_(syncPrefs.syncAllDataTypes, syncPrefs.tabsEnforced)]]"> @@ -86,54 +74,50 @@ </div> </div> - <h2 i18n-content="encryptionOptionsTitle"></h2> - <p i18n-content="syncDataEncryptedText"></p> + <div class="settings-box"> + <h2 i18n-content="encryptionOptionsTitle"></h2> + <p i18n-content="syncDataEncryptedText"></p> - <template is="dom-if" if="[[!syncPrefs.showPassphrase]]"> - <paper-radio-group id="encryptRadioGroup" - selected="[[selectedEncryptionRadio_(syncPrefs.usePassphrase, syncPrefs.encryptAllData)]]" - on-paper-radio-group-changed="onEncryptionRadioSelectionChanged_"> - <paper-radio-button name="encrypt-with-google" - disabled="[[encryptionRadiosDisabled_(syncPrefs.usePassphrase, syncPrefs.encryptAllData)]]"> - <span>[[i18n('encryptWithGoogleCredentialsLabel')]]</span> - </paper-radio-button> - <paper-radio-button name="encrypt-with-passphrase" - disabled="[[encryptionRadiosDisabled_(syncPrefs.usePassphrase, syncPrefs.encryptAllData)]]"> - <span>[[encryptWithPassphraseBody_(syncPrefs.fullEncryptionBody)]]</span> - </paper-radio-button> - </paper-radio-group> - </template> + <template is="dom-if" if="[[!syncPrefs.showPassphrase]]"> + <paper-radio-group id="encryptRadioGroup" + selected="[[selectedEncryptionRadio_(syncPrefs.usePassphrase, syncPrefs.encryptAllData)]]" + on-paper-radio-group-changed="onEncryptionRadioSelectionChanged_"> + <paper-radio-button name="encrypt-with-google" + disabled="[[encryptionRadiosDisabled_(syncPrefs.usePassphrase, syncPrefs.encryptAllData)]]"> + <span>[[i18n('encryptWithGoogleCredentialsLabel')]]</span> + </paper-radio-button> + <paper-radio-button name="encrypt-with-passphrase" + disabled="[[encryptionRadiosDisabled_(syncPrefs.usePassphrase, syncPrefs.encryptAllData)]]"> + <span>[[encryptWithPassphraseBody_(syncPrefs.fullEncryptionBody)]]</span> + </paper-radio-button> + </paper-radio-group> + </template> - <template is="dom-if" if="[[creatingNewPassphrase]]"> - <div>[[i18n('passphraseExplanationText')]]</div> - <paper-input id="passphraseInput" type="password" - placeholder="[[i18n('passphrasePlaceholder')]]"> - </paper-input> - <paper-input id="passphraseConfirmationInput" type="password" - placeholder="[[i18n('passphraseConfirmationPlaceholder')]]"> - </paper-input> - <div id="emptyPassphraseError" hidden>[[i18n('emptyPassphraseError')]]</div> - <div id="mismatchedPassphraseError" hidden>[[i18n('mismatchedPassphraseError')]]</div> - </template> + <template is="dom-if" if="[[creatingNewPassphrase]]"> + <div>[[i18n('passphraseExplanationText')]]</div> + <paper-input id="passphraseInput" type="password" + placeholder="[[i18n('passphrasePlaceholder')]]"> + </paper-input> + <paper-input id="passphraseConfirmationInput" type="password" + placeholder="[[i18n('passphraseConfirmationPlaceholder')]]"> + </paper-input> + <div id="emptyPassphraseError" hidden>[[i18n('emptyPassphraseError')]]</div> + <div id="mismatchedPassphraseError" hidden>[[i18n('mismatchedPassphraseError')]]</div> + </template> - <template is="dom-if" if="[[syncPrefs.showPassphrase]]"> - <div id="askCustomPassphraseMessage" - hidden="[[askOldGooglePassphrase]]">[[syncPrefs.enterPassphraseBody]]</div> - <div id="askOldGooglePassphraseMessage" - hidden="[[!askOldGooglePassphrase]]">[[syncPrefs.enterGooglePassphraseBody]]</div> - <paper-input id="existingPassphraseInput" type="password" - placeholder="[[i18n('passphrasePlaceholder')]]"> - </paper-input> - <div id="incorrectPassphraseError" hidden>[[i18n('incorrectPassphraseError')]]</div> - </template> + <template is="dom-if" if="[[syncPrefs.showPassphrase]]"> + <div id="askCustomPassphraseMessage" + hidden="[[askOldGooglePassphrase]]">[[syncPrefs.enterPassphraseBody]]</div> + <div id="askOldGooglePassphraseMessage" + hidden="[[!askOldGooglePassphrase]]">[[syncPrefs.enterGooglePassphraseBody]]</div> + <paper-input id="existingPassphraseInput" type="password" + placeholder="[[i18n('passphrasePlaceholder')]]"> + </paper-input> + <div id="incorrectPassphraseError" hidden>[[i18n('incorrectPassphraseError')]]</div> + </template> + </div> - <div class="button-row"> - <div class="flex"> - <paper-button i18n-content="useDefaultSettingsButton" - on-tap="onUseDefaultsTap_" - hidden="[[syncPrefs.showPassphrase]]"> - </paper-button> - </div> + <div class="settings-box"> <paper-button i18n-content="cancelButton" on-tap="onCancelTap_"> </paper-button> <paper-button i18n-content="okButton" on-tap="onOkTap_" raised>
diff --git a/chrome/browser/resources/settings/sync_page/sync_page.js b/chrome/browser/resources/settings/sync_page/sync_page.js index c50064e..f8f436f 100644 --- a/chrome/browser/resources/settings/sync_page/sync_page.js +++ b/chrome/browser/resources/settings/sync_page/sync_page.js
@@ -5,15 +5,6 @@ (function() { /** - * Indices of the options in the sync selector menu. - * @enum {number} - */ -var SyncSelectorIndices = { - SYNC_EVERYTHING: 0, - CHOOSE_WHAT_TO_SYNC: 1, -}; - -/** * Names of the radio buttons which allow the user to choose his encryption * mechanism. * @enum {string} @@ -125,6 +116,26 @@ this.$.pages.selected = 'main'; }, + /** + * Handler for when the sync all data types checkbox is changed. + * @param {Event} event + * @private + */ + onSyncAllDataTypesChanged_: function(event) { + if (event.target.checked) { + this.set('syncPrefs.syncAllDataTypes', true); + this.set('syncPrefs.appsSynced', true); + this.set('syncPrefs.extensionsSynced', true); + this.set('syncPrefs.preferencesSynced', true); + this.set('syncPrefs.autofillSynced', true); + this.set('syncPrefs.typedUrlsSynced', true); + this.set('syncPrefs.themesSynced', true); + this.set('syncPrefs.bookmarksSynced', true); + this.set('syncPrefs.passwordsSynced', true); + this.set('syncPrefs.tabsSynced', true); + } + }, + /** @private */ onCancelTap_: function() { // Event is caught by settings-animated-pages. @@ -161,23 +172,6 @@ }, /** - * Applies the default settings (i.e., sync everything). - * @private - */ - onUseDefaultsTap_: function() { - this.set('syncPrefs.syncAllDataTypes', true); - this.set('syncPrefs.appsSynced', true); - this.set('syncPrefs.extensionsSynced', true); - this.set('syncPrefs.preferencesSynced', true); - this.set('syncPrefs.autofillSynced', true); - this.set('syncPrefs.typedUrlsSynced', true); - this.set('syncPrefs.themesSynced', true); - this.set('syncPrefs.bookmarksSynced', true); - this.set('syncPrefs.passwordsSynced', true); - this.set('syncPrefs.tabsSynced', true); - }, - - /** * Callback invoked from calling settings.SyncPrivateApi.setSyncPrefs(). * @param {!settings.PageStatus} callbackState * @private @@ -203,16 +197,6 @@ }, /** - * Computed binding returning the selected index for the sync dropdown. - * @private - */ - selectedSyncSelectorIndex_: function() { - return this.syncPrefs.syncAllDataTypes ? - SyncSelectorIndices.SYNC_EVERYTHING : - SyncSelectorIndices.CHOOSE_WHAT_TO_SYNC; - }, - - /** * Computed binding returning the selected encryption radio button. * @private */ @@ -242,17 +226,6 @@ }, /** - * Handler for when the sync selector menu has changed its active option. - * @private - */ - onSyncSelectorChanged_: function(event) { - if (event.target.selected == SyncSelectorIndices.SYNC_EVERYTHING) - this.onUseDefaultsTap_(); - else - this.set('syncPrefs.syncAllDataTypes', false); - }, - - /** * @param {boolean} syncAllDataTypes * @param {boolean} enforced * @return {boolean} Whether the sync checkbox should be disabled.
diff --git a/chrome/browser/resources/settings/sync_page/sync_private_api.js b/chrome/browser/resources/settings/sync_page/sync_private_api.js index e9e9433..35a330f 100644 --- a/chrome/browser/resources/settings/sync_page/sync_private_api.js +++ b/chrome/browser/resources/settings/sync_page/sync_private_api.js
@@ -202,6 +202,13 @@ }; /** + * Sends a request from JS to C++ to open the multi-profile User Manager. + */ + SyncPrivateApi.manageOtherPeople = function() { + chrome.send('SyncSetupManageOtherPeople'); + }; + + /** * This function encapsulates the logic that maps from the legacy * SyncSettingsHandler to an API natural to the new Polymer implementation. * @param {!settings.PageStatus} status
diff --git a/chrome/browser/resources/settings/users_page/user_list.css b/chrome/browser/resources/settings/users_page/user_list.css index bd4ee80..0db441cd 100644 --- a/chrome/browser/resources/settings/users_page/user_list.css +++ b/chrome/browser/resources/settings/users_page/user_list.css
@@ -11,6 +11,11 @@ width: 18px; } +.soft-border { + border: 1px solid #c4c4c4; + border-radius: 2px; +} + .user { -webkit-padding-end: 8px; -webkit-padding-start: 20px;
diff --git a/chrome/browser/resources/settings/users_page/user_list.html b/chrome/browser/resources/settings/users_page/user_list.html index 88f1bf52..579424d 100644 --- a/chrome/browser/resources/settings/users_page/user_list.html +++ b/chrome/browser/resources/settings/users_page/user_list.html
@@ -4,7 +4,7 @@ <dom-module id="settings-user-list"> <link rel="import" type="css" - href="chrome://md-settings/settings_page/settings_page.css"> + href="chrome://md-settings/settings_shared.css"> <link rel="import" type="css" href="user_list.css"> <template> <div class="user-list soft-border">
diff --git a/chrome/browser/resources/settings/users_page/users_page.html b/chrome/browser/resources/settings/users_page/users_page.html index 2f33ad1..86343c7 100644 --- a/chrome/browser/resources/settings/users_page/users_page.html +++ b/chrome/browser/resources/settings/users_page/users_page.html
@@ -9,7 +9,7 @@ <dom-module id="settings-users-page"> <link rel="import" type="css" - href="chrome://md-settings/settings_page/settings_page.css"> + href="chrome://md-settings/settings_shared.css"> <link rel="import" type="css" href="users_page.css"> <template> <div class="page-content">
diff --git a/chrome/browser/safe_browsing/client_side_detection_host.cc b/chrome/browser/safe_browsing/client_side_detection_host.cc index 414c55b..ef73fb4 100644 --- a/chrome/browser/safe_browsing/client_side_detection_host.cc +++ b/chrome/browser/safe_browsing/client_side_detection_host.cc
@@ -45,8 +45,6 @@ const size_t ClientSideDetectionHost::kMaxUrlsPerIP = 20; const size_t ClientSideDetectionHost::kMaxIPsPerBrowse = 200; -const char kSafeBrowsingMatchKey[] = "safe_browsing_match"; - typedef base::Callback<void(bool)> ShouldClassifyUrlCallback; // This class is instantiated each time a new toplevel URL loads, and @@ -432,48 +430,11 @@ unsafe_resource_->callback.Reset(); // Don't do anything stupid. } -void ClientSideDetectionHost::OnSafeBrowsingMatch( - const SafeBrowsingUIManager::UnsafeResource& resource) { - if (!web_contents() || !web_contents()->GetController().GetActiveEntry()) - return; - - // Check that this notification is really for us. - content::RenderViewHost* hit_rvh = content::RenderViewHost::FromID( - resource.render_process_host_id, resource.render_view_id); - if (!hit_rvh || - web_contents() != content::WebContents::FromRenderViewHost(hit_rvh)) - return; - - web_contents()->GetController().GetActiveEntry()->SetExtraData( - kSafeBrowsingMatchKey, base::ASCIIToUTF16("1")); -} - scoped_refptr<SafeBrowsingDatabaseManager> ClientSideDetectionHost::database_manager() { return database_manager_; } -bool ClientSideDetectionHost::DidPageReceiveSafeBrowsingMatch() const { - if (!web_contents() || !web_contents()->GetController().GetVisibleEntry()) - return false; - - // If an interstitial page is showing, GetVisibleEntry will return the - // transient NavigationEntry for the interstitial. The transient entry - // will not have the flag set, so use the pending entry instead if there - // is one. - NavigationEntry* entry = web_contents()->GetController().GetPendingEntry(); - if (!entry) { - entry = web_contents()->GetController().GetVisibleEntry(); - if (entry->GetPageType() == content::PAGE_TYPE_INTERSTITIAL) - entry = web_contents()->GetController().GetLastCommittedEntry(); - if (!entry) - return false; - } - - base::string16 value; - return entry->GetExtraData(kSafeBrowsingMatchKey, &value); -} - void ClientSideDetectionHost::WebContentsDestroyed() { // Tell any pending classification request that it is being canceled. if (classification_request_.get()) {
diff --git a/chrome/browser/safe_browsing/client_side_detection_host.h b/chrome/browser/safe_browsing/client_side_detection_host.h index d5673a2..ab26a38 100644 --- a/chrome/browser/safe_browsing/client_side_detection_host.h +++ b/chrome/browser/safe_browsing/client_side_detection_host.h
@@ -52,17 +52,8 @@ void OnSafeBrowsingHit( const SafeBrowsingUIManager::UnsafeResource& resource) override; - // Called when the SafeBrowsingService finds a match on the SB lists. - // Called on the UI thread. Called even if the resource is whitelisted. - void OnSafeBrowsingMatch( - const SafeBrowsingUIManager::UnsafeResource& resource) override; - virtual scoped_refptr<SafeBrowsingDatabaseManager> database_manager(); - // Returns whether the current page contains a malware or phishing safe - // browsing match. - bool DidPageReceiveSafeBrowsingMatch() const; - protected: explicit ClientSideDetectionHost(content::WebContents* tab);
diff --git a/chrome/browser/safe_browsing/client_side_detection_host_unittest.cc b/chrome/browser/safe_browsing/client_side_detection_host_unittest.cc index b3037a62..9d9fc09 100644 --- a/chrome/browser/safe_browsing/client_side_detection_host_unittest.cc +++ b/chrome/browser/safe_browsing/client_side_detection_host_unittest.cc
@@ -364,11 +364,7 @@ GetID(); resource.render_view_id = web_contents()->GetRenderViewHost()->GetRoutingID(); - ASSERT_FALSE(csd_host_->DidPageReceiveSafeBrowsingMatch()); - csd_host_->OnSafeBrowsingMatch(resource); - ASSERT_TRUE(csd_host_->DidPageReceiveSafeBrowsingMatch()); csd_host_->OnSafeBrowsingHit(resource); - ASSERT_TRUE(csd_host_->DidPageReceiveSafeBrowsingMatch()); resource.callback.Reset(); ASSERT_TRUE(csd_host_->DidShowSBInterstitial()); TestUnsafeResourceCopied(resource); @@ -397,17 +393,13 @@ BrowserThread::GetMessageLoopProxyForThread(BrowserThread::IO); resource.render_process_host_id = pending_rvh()->GetProcess()->GetID(); resource.render_view_id = pending_rvh()->GetRoutingID(); - csd_host_->OnSafeBrowsingMatch(resource); csd_host_->OnSafeBrowsingHit(resource); resource.callback.Reset(); - ASSERT_TRUE(csd_host_->DidPageReceiveSafeBrowsingMatch()); - // LoadURL created a navigation entry, now simulate the RenderView sending // a notification that it actually navigated. content::WebContentsTester::For(web_contents())->CommitPendingNavigation(); - ASSERT_TRUE(csd_host_->DidPageReceiveSafeBrowsingMatch()); ASSERT_TRUE(csd_host_->DidShowSBInterstitial()); TestUnsafeResourceCopied(resource); } @@ -423,11 +415,9 @@ EXPECT_NE(web_contents()->GetRenderViewHost()->GetRoutingID(), pending_rvh()->GetRoutingID()); } - ASSERT_FALSE(csd_host_->DidPageReceiveSafeBrowsingMatch()); ASSERT_FALSE(csd_host_->DidShowSBInterstitial()); content::WebContentsTester::For(web_contents())->CommitPendingNavigation(); - ASSERT_FALSE(csd_host_->DidPageReceiveSafeBrowsingMatch()); ASSERT_FALSE(csd_host_->DidShowSBInterstitial()); }
diff --git a/chrome/browser/safe_browsing/download_protection_service.cc b/chrome/browser/safe_browsing/download_protection_service.cc index caf06c2..b6674564 100644 --- a/chrome/browser/safe_browsing/download_protection_service.cc +++ b/chrome/browser/safe_browsing/download_protection_service.cc
@@ -707,19 +707,12 @@ return; } -// Currently, the UI is enabled on Windows, OSX and chrome OS. we don't ping -// the server if we're not on one of those platforms. -// TODO(noelutz): change this code once the UI is done for Linux. -#if defined(OS_WIN) || defined(OS_MACOSX) || defined(OS_CHROMEOS) - // The URLFetcher is owned by the UI thread, so post a message to - // start the pingback. - BrowserThread::PostTask( - BrowserThread::UI, - FROM_HERE, - base::Bind(&CheckClientDownloadRequest::GetTabRedirects, this)); -#else - PostFinishTask(UNKNOWN, REASON_OS_NOT_SUPPORTED); -#endif + // The URLFetcher is owned by the UI thread, so post a message to + // start the pingback. + BrowserThread::PostTask( + BrowserThread::UI, + FROM_HERE, + base::Bind(&CheckClientDownloadRequest::GetTabRedirects, this)); } void GetTabRedirects() { @@ -1111,19 +1104,12 @@ bool DownloadProtectionService::IsSupportedDownload( const content::DownloadItem& item, const base::FilePath& target_path) const { -// Currently, the UI is only enabled on Windows, OSX and Chrome OS. On -// Linux we still want to show the dangerous file type warning if the file -// is possibly dangerous which means we have to always return false here. -#if defined(OS_WIN) || defined(OS_MACOSX) || defined(OS_CHROMEOS) DownloadCheckResultReason reason = REASON_MAX; ClientDownloadRequest::DownloadType type = ClientDownloadRequest::WIN_EXECUTABLE; return (CheckClientDownloadRequest::IsSupportedDownload( item, target_path, &reason, &type) && (ClientDownloadRequest::CHROME_EXTENSION != type)); -#else - return false; -#endif } DownloadProtectionService::ClientDownloadRequestSubscription
diff --git a/chrome/browser/safe_browsing/download_protection_service_unittest.cc b/chrome/browser/safe_browsing/download_protection_service_unittest.cc index 3ec5c7b..e4116d0 100644 --- a/chrome/browser/safe_browsing/download_protection_service_unittest.cc +++ b/chrome/browser/safe_browsing/download_protection_service_unittest.cc
@@ -488,13 +488,7 @@ base::Unretained(this))); MessageLoop::current()->Run(); -#if defined(OS_WIN) || defined(OS_MACOSX) || defined(OS_CHROMEOS) const bool expect_request = is_extended_reporting && !is_incognito; -#else - // For !(OS_WIN || OS_MACOSX || OS_CHROMEOS), - // no file types are currently supported. - const bool expect_request = false; -#endif if (expect_request) { ASSERT_TRUE(HasClientDownloadRequest()); @@ -635,14 +629,9 @@ base::Unretained(this))); MessageLoop::current()->Run(); -#if defined(OS_WIN) || defined(OS_MACOSX) || defined(OS_CHROMEOS) EXPECT_TRUE(IsResult(DownloadProtectionService::DANGEROUS)); EXPECT_TRUE(HasClientDownloadRequest()); ClearClientDownloadRequest(); -#else - EXPECT_TRUE(IsResult(DownloadProtectionService::UNKNOWN)); - EXPECT_FALSE(HasClientDownloadRequest()); -#endif // Check that the referrer is not matched against the whitelist. referrer = GURL("http://www.google.com/"); @@ -652,14 +641,9 @@ base::Unretained(this))); MessageLoop::current()->Run(); -#if defined(OS_WIN) || defined(OS_MACOSX) || defined(OS_CHROMEOS) EXPECT_TRUE(IsResult(DownloadProtectionService::DANGEROUS)); EXPECT_TRUE(HasClientDownloadRequest()); ClearClientDownloadRequest(); -#else - EXPECT_TRUE(IsResult(DownloadProtectionService::UNKNOWN)); - EXPECT_FALSE(HasClientDownloadRequest()); -#endif // Redirect from a site shouldn't be checked either. url_chain.insert(url_chain.begin(), GURL("http://www.google.com/redirect")); @@ -669,14 +653,9 @@ base::Unretained(this))); MessageLoop::current()->Run(); -#if defined(OS_WIN) || defined(OS_MACOSX) || defined(OS_CHROMEOS) EXPECT_TRUE(IsResult(DownloadProtectionService::DANGEROUS)); EXPECT_TRUE(HasClientDownloadRequest()); ClearClientDownloadRequest(); -#else - EXPECT_TRUE(IsResult(DownloadProtectionService::UNKNOWN)); - EXPECT_FALSE(HasClientDownloadRequest()); -#endif // Only if the final url is whitelisted should it be SAFE. url_chain.push_back(GURL("http://www.google.com/a.exe")); @@ -781,17 +760,9 @@ base::Unretained(this))); MessageLoop::current()->Run(); -#if defined(OS_WIN) || defined(OS_MACOSX) || defined(OS_CHROMEOS) EXPECT_TRUE(IsResult(DownloadProtectionService::SAFE)); EXPECT_TRUE(HasClientDownloadRequest()); ClearClientDownloadRequest(); -#else - // On !(OS_WIN || OS_MACOSX || OS_CHROMEOS), - // no file types are currently supported. Hence all - // requests to CheckClientDownload() result in a verdict of UNKNOWN. - EXPECT_TRUE(IsResult(DownloadProtectionService::UNKNOWN)); - EXPECT_FALSE(HasClientDownloadRequest()); -#endif // Invalid response should result in UNKNOWN. response.Clear(); @@ -806,12 +777,8 @@ base::Unretained(this))); MessageLoop::current()->Run(); EXPECT_TRUE(IsResult(DownloadProtectionService::UNKNOWN)); -#if defined(OS_WIN) || defined(OS_MACOSX) || defined(OS_CHROMEOS) EXPECT_TRUE(HasClientDownloadRequest()); ClearClientDownloadRequest(); -#else - EXPECT_FALSE(HasClientDownloadRequest()); -#endif std::string feedback_ping; std::string feedback_response; EXPECT_FALSE(DownloadFeedbackService::GetPingsForDownloadForTesting( @@ -832,14 +799,9 @@ EXPECT_FALSE(DownloadFeedbackService::GetPingsForDownloadForTesting( item, &feedback_ping, &feedback_response)); -#if defined(OS_WIN) || defined(OS_MACOSX) || defined(OS_CHROMEOS) EXPECT_TRUE(IsResult(DownloadProtectionService::DANGEROUS)); EXPECT_TRUE(HasClientDownloadRequest()); ClearClientDownloadRequest(); -#else - EXPECT_TRUE(IsResult(DownloadProtectionService::UNKNOWN)); - EXPECT_FALSE(HasClientDownloadRequest()); -#endif // If the response is uncommon the result should also be marked as uncommon. response.set_verdict(ClientDownloadResponse::UNCOMMON); @@ -853,7 +815,6 @@ base::Bind(&DownloadProtectionServiceTest::CheckDoneCallback, base::Unretained(this))); MessageLoop::current()->Run(); -#if defined(OS_WIN) || defined(OS_MACOSX) || defined(OS_CHROMEOS) EXPECT_TRUE(IsResult(DownloadProtectionService::UNCOMMON)); EXPECT_TRUE(DownloadFeedbackService::GetPingsForDownloadForTesting( item, &feedback_ping, &feedback_response)); @@ -863,9 +824,6 @@ EXPECT_EQ(response.SerializeAsString(), feedback_response); EXPECT_TRUE(HasClientDownloadRequest()); ClearClientDownloadRequest(); -#else - EXPECT_TRUE(IsResult(DownloadProtectionService::UNKNOWN)); -#endif // If the response is dangerous_host the result should also be marked as // dangerous_host. @@ -880,16 +838,12 @@ base::Bind(&DownloadProtectionServiceTest::CheckDoneCallback, base::Unretained(this))); MessageLoop::current()->Run(); -#if defined(OS_WIN) || defined(OS_MACOSX) || defined(OS_CHROMEOS) EXPECT_TRUE(IsResult(DownloadProtectionService::DANGEROUS_HOST)); EXPECT_TRUE(DownloadFeedbackService::GetPingsForDownloadForTesting( item, &feedback_ping, &feedback_response)); EXPECT_EQ(response.SerializeAsString(), feedback_response); EXPECT_TRUE(HasClientDownloadRequest()); ClearClientDownloadRequest(); -#else - EXPECT_TRUE(IsResult(DownloadProtectionService::UNKNOWN)); -#endif // If the response is POTENTIALLY_UNWANTED the result should also be marked as // POTENTIALLY_UNWANTED. @@ -905,14 +859,9 @@ base::Unretained(this))); MessageLoop::current()->Run(); -#if defined(OS_WIN) || defined(OS_MACOSX) || defined(OS_CHROMEOS) EXPECT_TRUE(IsResult(DownloadProtectionService::POTENTIALLY_UNWANTED)); EXPECT_TRUE(HasClientDownloadRequest()); ClearClientDownloadRequest(); -#else - EXPECT_TRUE(IsResult(DownloadProtectionService::UNKNOWN)); - EXPECT_FALSE(HasClientDownloadRequest()); -#endif } TEST_F(DownloadProtectionServiceTest, CheckClientDownloadHTTPS) { @@ -960,14 +909,9 @@ base::Unretained(this))); MessageLoop::current()->Run(); -#if defined(OS_WIN) || defined(OS_MACOSX) || defined(OS_CHROMEOS) EXPECT_TRUE(IsResult(DownloadProtectionService::DANGEROUS)); EXPECT_TRUE(HasClientDownloadRequest()); ClearClientDownloadRequest(); -#else - EXPECT_TRUE(IsResult(DownloadProtectionService::UNKNOWN)); - EXPECT_FALSE(HasClientDownloadRequest()); -#endif } TEST_F(DownloadProtectionServiceTest, CheckClientDownloadBlob) { @@ -1014,14 +958,9 @@ base::Unretained(this))); MessageLoop::current()->Run(); -#if defined(OS_WIN) || defined(OS_MACOSX) || defined(OS_CHROMEOS) EXPECT_TRUE(IsResult(DownloadProtectionService::DANGEROUS)); EXPECT_TRUE(HasClientDownloadRequest()); ClearClientDownloadRequest(); -#else - EXPECT_TRUE(IsResult(DownloadProtectionService::UNKNOWN)); - EXPECT_FALSE(HasClientDownloadRequest()); -#endif } TEST_F(DownloadProtectionServiceTest, CheckClientDownloadData) { @@ -1072,7 +1011,6 @@ base::Unretained(this))); MessageLoop::current()->Run(); -#if defined(OS_WIN) || defined(OS_MACOSX) || defined(OS_CHROMEOS) EXPECT_TRUE(IsResult(DownloadProtectionService::DANGEROUS)); ASSERT_TRUE(HasClientDownloadRequest()); const ClientDownloadRequest& request = *GetClientDownloadRequest(); @@ -1099,10 +1037,6 @@ ClientDownloadRequest::DOWNLOAD_URL, kExpectedUrl, kExpectedReferrer)); ClearClientDownloadRequest(); -#else - EXPECT_TRUE(IsResult(DownloadProtectionService::UNKNOWN)); - EXPECT_FALSE(HasClientDownloadRequest()); -#endif } TEST_F(DownloadProtectionServiceTest, CheckClientDownloadZip) { @@ -1174,7 +1108,6 @@ base::Unretained(this))); MessageLoop::current()->Run(); -#if defined(OS_WIN) || defined(OS_MACOSX) || defined(OS_CHROMEOS) EXPECT_TRUE(IsResult(DownloadProtectionService::SAFE)); EXPECT_TRUE(HasClientDownloadRequest()); const ClientDownloadRequest& request = *GetClientDownloadRequest(); @@ -1190,13 +1123,6 @@ EXPECT_EQ(static_cast<int64_t>(file_contents.size()), archived_binary->length()); ClearClientDownloadRequest(); -#else - // For !(OS_WIN || OS_MACOSX || OS_CHROMEOS), - // no file types are currently supported. Hence - // the resulting verdict is UNKNOWN. - EXPECT_TRUE(IsResult(DownloadProtectionService::UNKNOWN)); - EXPECT_FALSE(HasClientDownloadRequest()); -#endif Mock::VerifyAndClearExpectations(binary_feature_extractor_.get()); // If the response is dangerous the result should also be marked as @@ -1213,14 +1139,9 @@ base::Unretained(this))); MessageLoop::current()->Run(); -#if defined(OS_WIN) || defined(OS_MACOSX) || defined(OS_CHROMEOS) EXPECT_TRUE(IsResult(DownloadProtectionService::DANGEROUS)); EXPECT_TRUE(HasClientDownloadRequest()); ClearClientDownloadRequest(); -#else - EXPECT_TRUE(IsResult(DownloadProtectionService::UNKNOWN)); - EXPECT_FALSE(HasClientDownloadRequest()); -#endif Mock::VerifyAndClearExpectations(binary_feature_extractor_.get()); // Repeat the test with an archive inside the zip file in addition to the @@ -1236,20 +1157,12 @@ base::Unretained(this))); MessageLoop::current()->Run(); -#if defined(OS_WIN) || defined(OS_MACOSX) || defined(OS_CHROMEOS) ASSERT_TRUE(HasClientDownloadRequest()); EXPECT_EQ(1, GetClientDownloadRequest()->archived_binary_size()); EXPECT_TRUE(GetClientDownloadRequest()->has_download_type()); EXPECT_EQ(ClientDownloadRequest_DownloadType_ZIPPED_EXECUTABLE, GetClientDownloadRequest()->download_type()); ClearClientDownloadRequest(); -#else - // For !(OS_WIN || OS_MACOSX || OS_CHROMEOS), - // no file types are currently supported. Hence - // the resulting verdict is UNKNOWN. - EXPECT_TRUE(IsResult(DownloadProtectionService::UNKNOWN)); - EXPECT_FALSE(HasClientDownloadRequest()); -#endif Mock::VerifyAndClearExpectations(binary_feature_extractor_.get()); // Repeat the test with just the archive inside the zip file. @@ -1262,20 +1175,12 @@ base::Unretained(this))); MessageLoop::current()->Run(); -#if defined(OS_WIN) || defined(OS_MACOSX) || defined(OS_CHROMEOS) ASSERT_TRUE(HasClientDownloadRequest()); EXPECT_EQ(0, GetClientDownloadRequest()->archived_binary_size()); EXPECT_TRUE(GetClientDownloadRequest()->has_download_type()); EXPECT_EQ(ClientDownloadRequest_DownloadType_ZIPPED_ARCHIVE, GetClientDownloadRequest()->download_type()); ClearClientDownloadRequest(); -#else - // For !(OS_WIN || OS_MACOSX || OS_CHROMEOS), - // no file types are currently supported. Hence - // the resulting verdict is UNKNOWN. - EXPECT_TRUE(IsResult(DownloadProtectionService::UNKNOWN)); - EXPECT_FALSE(HasClientDownloadRequest()); -#endif Mock::VerifyAndClearExpectations(binary_feature_extractor_.get()); } @@ -1389,13 +1294,6 @@ base::Bind(&DownloadProtectionServiceTest::CheckDoneCallback, base::Unretained(this))); -#if !defined(OS_WIN) && !defined(OS_MACOSX) && !defined(OS_CHROMEOS) - // SendRequest is not called. Wait for FinishRequest to call our callback. - MessageLoop::current()->Run(); - net::TestURLFetcher* fetcher = factory.GetFetcherByID(0); - EXPECT_EQ(NULL, fetcher); - EXPECT_FALSE(HasClientDownloadRequest()); -#else // Run the message loop(s) until SendRequest is called. FlushThreadMessageLoops(); EXPECT_TRUE(HasClientDownloadRequest()); @@ -1436,7 +1334,6 @@ base::Bind(&DownloadProtectionServiceTest::SendURLFetchComplete, base::Unretained(this), fetcher)); MessageLoop::current()->Run(); -#endif } // Similar to above, but with an unsigned binary. @@ -1479,13 +1376,6 @@ base::Bind(&DownloadProtectionServiceTest::CheckDoneCallback, base::Unretained(this))); -#if !defined(OS_WIN) && !defined(OS_MACOSX) && !defined(OS_CHROMEOS) - // SendRequest is not called. Wait for FinishRequest to call our callback. - MessageLoop::current()->Run(); - net::TestURLFetcher* fetcher = factory.GetFetcherByID(0); - EXPECT_EQ(NULL, fetcher); - EXPECT_FALSE(HasClientDownloadRequest()); -#else // Run the message loop(s) until SendRequest is called. FlushThreadMessageLoops(); EXPECT_TRUE(HasClientDownloadRequest()); @@ -1515,7 +1405,6 @@ base::Bind(&DownloadProtectionServiceTest::SendURLFetchComplete, base::Unretained(this), fetcher)); MessageLoop::current()->Run(); -#endif } // Similar to above, but with tab history. @@ -1566,13 +1455,6 @@ base::Bind(&DownloadProtectionServiceTest::CheckDoneCallback, base::Unretained(this))); -#if !defined(OS_WIN) && !defined(OS_MACOSX) && !defined(OS_CHROMEOS) - // SendRequest is not called. Wait for FinishRequest to call our callback. - MessageLoop::current()->Run(); - net::TestURLFetcher* fetcher = factory.GetFetcherByID(0); - EXPECT_EQ(NULL, fetcher); - EXPECT_FALSE(HasClientDownloadRequest()); -#else EXPECT_EQ(0, fetcher_watcher.WaitForRequest()); EXPECT_TRUE(HasClientDownloadRequest()); ClearClientDownloadRequest(); @@ -1619,7 +1501,6 @@ base::Unretained(this), fetcher)); MessageLoop::current()->Run(); -#endif } // Now try with a history match. @@ -1645,13 +1526,6 @@ &item, base::Bind(&DownloadProtectionServiceTest::CheckDoneCallback, base::Unretained(this))); -#if !defined(OS_WIN) && !defined(OS_MACOSX) && !defined(OS_CHROMEOS) - // SendRequest is not called. Wait for FinishRequest to call our callback. - MessageLoop::current()->Run(); - net::TestURLFetcher* fetcher = factory.GetFetcherByID(0); - EXPECT_EQ(NULL, fetcher); - EXPECT_FALSE(HasClientDownloadRequest()); -#else EXPECT_EQ(0, fetcher_watcher.WaitForRequest()); EXPECT_TRUE(HasClientDownloadRequest()); ClearClientDownloadRequest(); @@ -1700,7 +1574,6 @@ base::Unretained(this), fetcher)); MessageLoop::current()->Run(); -#endif } } @@ -1811,12 +1684,8 @@ // anything yet. MessageLoop::current()->Run(); EXPECT_TRUE(IsResult(DownloadProtectionService::UNKNOWN)); -#if defined(OS_WIN) || defined(OS_MACOSX) || defined(OS_CHROMEOS) EXPECT_TRUE(HasClientDownloadRequest()); ClearClientDownloadRequest(); -#else - EXPECT_FALSE(HasClientDownloadRequest()); -#endif } TEST_F(DownloadProtectionServiceTest, TestDownloadItemDestroyed) { @@ -2092,15 +1961,8 @@ MessageLoop::current()->Run(); EXPECT_FALSE(HasClientDownloadRequest()); -#if defined(OS_WIN) || defined(OS_MACOSX) || defined(OS_CHROMEOS) // Overriden by flag: EXPECT_TRUE(IsResult(DownloadProtectionService::DANGEROUS)); -#else - // On !(OS_WIN || OS_MACOSX || OS_CHROMEOS), - // no file types are currently supported. Hence all - // requests to CheckClientDownload() result in a verdict of UNKNOWN. - EXPECT_TRUE(IsResult(DownloadProtectionService::UNKNOWN)); -#endif } // Test a real .zip with a real .exe in it, where the .exe is manually @@ -2139,15 +2001,8 @@ MessageLoop::current()->Run(); EXPECT_FALSE(HasClientDownloadRequest()); -#if defined(OS_WIN) || defined(OS_MACOSX) || defined(OS_CHROMEOS) // Overriden by flag: EXPECT_TRUE(IsResult(DownloadProtectionService::DANGEROUS)); -#else - // On !(OS_WIN || OS_MACOSX || OS_CHROMEOS), - // no file types are currently supported. Hence all - // requests to CheckClientDownload() result in a verdict of UNKNOWN. - EXPECT_TRUE(IsResult(DownloadProtectionService::UNKNOWN)); -#endif } } // namespace safe_browsing
diff --git a/chrome/browser/safe_browsing/remote_database_manager.cc b/chrome/browser/safe_browsing/remote_database_manager.cc index b834b856..9eb0d7e 100644 --- a/chrome/browser/safe_browsing/remote_database_manager.cc +++ b/chrome/browser/safe_browsing/remote_database_manager.cc
@@ -18,10 +18,8 @@ namespace { -// Android field trial +// Android field trial for controlling types_to_check. const char kAndroidFieldExperiment[] = "SafeBrowsingAndroid"; -const char kAndroidFieldParam[] = "enabled"; -const char kAndroidFieldParamEnabledValue[] = "true"; const char kAndroidTypesToCheckParam[] = "types_to_check"; } // namespace @@ -94,27 +92,41 @@ // TODO(nparker): Add more tests for this class RemoteSafeBrowsingDatabaseManager::RemoteSafeBrowsingDatabaseManager() : enabled_(false) { - - // Check if the field trial is enabled. - const std::string enabled_param = variations::GetVariationParamValue( - kAndroidFieldExperiment, kAndroidFieldParam); - is_android_field_trial_enabled_ = - (enabled_param == kAndroidFieldParamEnabledValue); - // Decide which resource types to check. These two are the minimum. resource_types_to_check_.insert(content::RESOURCE_TYPE_MAIN_FRAME); resource_types_to_check_.insert(content::RESOURCE_TYPE_SUB_FRAME); // The param is expected to be a comma-separated list of ints - // corresponding to the enum types. + // corresponding to the enum types. We're keeping this finch + // control around so we can add back types if they later become dangerous. const std::string ints_str = variations::GetVariationParamValue( kAndroidFieldExperiment, kAndroidTypesToCheckParam); - for (const std::string& val_str : base::SplitString( - ints_str, ",", base::TRIM_WHITESPACE, base::SPLIT_WANT_ALL)) { - int i; - if (base::StringToInt(val_str, &i) && i >= 0 && - i < content::RESOURCE_TYPE_LAST_TYPE) { - resource_types_to_check_.insert(static_cast<content::ResourceType>(i)); + if (ints_str.empty()) { + // By default, we check all types except a few. + static_assert(content::RESOURCE_TYPE_LAST_TYPE == + content::RESOURCE_TYPE_SERVICE_WORKER + 1, + "Decide if new resource type should be skipped on mobile."); + for (int t_int = 0; t_int < content::RESOURCE_TYPE_LAST_TYPE; t_int++) { + content::ResourceType t = static_cast<content::ResourceType>(t_int); + switch (t) { + case content::RESOURCE_TYPE_STYLESHEET: + case content::RESOURCE_TYPE_IMAGE: + case content::RESOURCE_TYPE_FONT_RESOURCE: + case content::RESOURCE_TYPE_FAVICON: + break; + default: + resource_types_to_check_.insert(t); + } + } + } else { + // Use the finch param. + for (const std::string& val_str : base::SplitString( + ints_str, ",", base::TRIM_WHITESPACE, base::SPLIT_WANT_ALL)) { + int i; + if (base::StringToInt(val_str, &i) && i >= 0 && + i < content::RESOURCE_TYPE_LAST_TYPE) { + resource_types_to_check_.insert(static_cast<content::ResourceType>(i)); + } } } } @@ -124,8 +136,7 @@ } bool RemoteSafeBrowsingDatabaseManager::IsSupported() const { - return SafeBrowsingApiHandler::GetInstance() != nullptr && - is_android_field_trial_enabled_; + return SafeBrowsingApiHandler::GetInstance() != nullptr; } safe_browsing::ThreatSource RemoteSafeBrowsingDatabaseManager::GetThreatSource()
diff --git a/chrome/browser/safe_browsing/remote_database_manager.h b/chrome/browser/safe_browsing/remote_database_manager.h index b630a8a..c3c5de8 100644 --- a/chrome/browser/safe_browsing/remote_database_manager.h +++ b/chrome/browser/safe_browsing/remote_database_manager.h
@@ -69,7 +69,6 @@ bool enabled_; std::set<content::ResourceType> resource_types_to_check_; - bool is_android_field_trial_enabled_; friend class base::RefCountedThreadSafe<RemoteSafeBrowsingDatabaseManager>; DISALLOW_COPY_AND_ASSIGN(RemoteSafeBrowsingDatabaseManager);
diff --git a/chrome/browser/safe_browsing/remote_database_manager_unittest.cc b/chrome/browser/safe_browsing/remote_database_manager_unittest.cc index 0726720..e584118 100644 --- a/chrome/browser/safe_browsing/remote_database_manager_unittest.cc +++ b/chrome/browser/safe_browsing/remote_database_manager_unittest.cc
@@ -35,8 +35,7 @@ } // Setup the two field trial params. These are read in db_'s ctor. - void SetFieldTrialParams(const std::string enabled_val, - const std::string types_to_check_val) { + void SetFieldTrialParams(const std::string types_to_check_val) { // Destroy the existing FieldTrialList before creating a new one to avoid // a DCHECK. field_trials_.reset(); @@ -50,8 +49,6 @@ base::FieldTrialList::CreateFieldTrial(experiment_name, group_name)); std::map<std::string, std::string> params; - if (!enabled_val.empty()) - params["enabled"] = enabled_val; if (!types_to_check_val.empty()) params["types_to_check"] = types_to_check_val; @@ -64,11 +61,7 @@ scoped_refptr<RemoteSafeBrowsingDatabaseManager> db_; }; -TEST_F(RemoteDatabaseManagerTest, DisabledViaNullOrTrial) { - EXPECT_FALSE(db_->IsSupported()); - - SetFieldTrialParams("true", ""); - db_ = new RemoteSafeBrowsingDatabaseManager(); +TEST_F(RemoteDatabaseManagerTest, DisabledViaNull) { EXPECT_TRUE(db_->IsSupported()); SafeBrowsingApiHandler::SetInstance(nullptr); @@ -76,17 +69,25 @@ } TEST_F(RemoteDatabaseManagerTest, TypesToCheckDefault) { - EXPECT_TRUE(db_->CanCheckResourceType(content::RESOURCE_TYPE_MAIN_FRAME)); - EXPECT_TRUE(db_->CanCheckResourceType(content::RESOURCE_TYPE_SUB_FRAME)); - // The rest are false. - for (int t = content::RESOURCE_TYPE_SUB_FRAME + 1; - t < content::RESOURCE_TYPE_LAST_TYPE; t++) { - EXPECT_FALSE( - db_->CanCheckResourceType(static_cast<content::ResourceType>(t))); + // Most are true, a few are false. + for (int t_int = 0; t_int < content::RESOURCE_TYPE_LAST_TYPE; t_int++) { + content::ResourceType t = static_cast<content::ResourceType>(t_int); + switch (t) { + case content::RESOURCE_TYPE_STYLESHEET: + case content::RESOURCE_TYPE_IMAGE: + case content::RESOURCE_TYPE_FONT_RESOURCE: + case content::RESOURCE_TYPE_FAVICON: + EXPECT_FALSE(db_->CanCheckResourceType(t)); + break; + default: + EXPECT_TRUE(db_->CanCheckResourceType(t)); + break; + } } } + TEST_F(RemoteDatabaseManagerTest, TypesToCheckFromTrial) { - SetFieldTrialParams("true", "1,2,blah, 9"); + SetFieldTrialParams("1,2,blah, 9"); db_ = new RemoteSafeBrowsingDatabaseManager(); EXPECT_TRUE(db_->CanCheckResourceType( content::RESOURCE_TYPE_MAIN_FRAME)); // defaulted
diff --git a/chrome/browser/safe_browsing/safe_browsing_blocking_page.cc b/chrome/browser/safe_browsing/safe_browsing_blocking_page.cc index 5ebc8d3..e4f71f16 100644 --- a/chrome/browser/safe_browsing/safe_browsing_blocking_page.cc +++ b/chrome/browser/safe_browsing/safe_browsing_blocking_page.cc
@@ -514,15 +514,10 @@ // static bool SafeBrowsingBlockingPage::IsMainPageLoadBlocked( const UnsafeResourceList& unsafe_resources) { - // Client-side phishing detection interstitials never block the main frame - // load, since they happen after the page is finished loading. - if (unsafe_resources[0].threat_type == - SB_THREAT_TYPE_CLIENT_SIDE_PHISHING_URL) { - return false; - } - - // Otherwise, check the threat type. - return unsafe_resources.size() == 1 && !unsafe_resources[0].is_subresource; + // If there is more than one unsafe resource, the main page load must not be + // blocked. Otherwise, check if the one resource is. + return unsafe_resources.size() == 1 && + unsafe_resources[0].IsMainPageLoadBlocked(); } std::string SafeBrowsingBlockingPage::GetMetricPrefix() const {
diff --git a/chrome/browser/safe_browsing/safe_browsing_blocking_page_test.cc b/chrome/browser/safe_browsing/safe_browsing_blocking_page_test.cc index e88dfe1b..9ec2fca 100644 --- a/chrome/browser/safe_browsing/safe_browsing_blocking_page_test.cc +++ b/chrome/browser/safe_browsing/safe_browsing_blocking_page_test.cc
@@ -6,6 +6,8 @@ // threat urls. It then uses a real browser to go to these urls, and sends // "goback" or "proceed" commands and verifies they work. +#include <algorithm> + #include "base/bind.h" #include "base/command_line.h" #include "base/prefs/pref_service.h" @@ -59,6 +61,7 @@ const char kEmptyPage[] = "empty.html"; const char kMalwarePage[] = "safe_browsing/malware.html"; +const char kMalwarePage2[] = "safe_browsing/malware2.html"; const char kMalwareIframe[] = "safe_browsing/malware_iframe.html"; const char kUnrelatedUrl[] = "https://www.google.com"; @@ -420,7 +423,7 @@ // navigates to a page with an iframe containing the threat site, and returns // the url of the parent page. GURL SetupThreatIframeWarningAndNavigate() { - GURL url = net::URLRequestMockHTTPJob::GetMockUrl(kMalwarePage); + GURL url = net::URLRequestMockHTTPJob::GetMockUrl(kMalwarePage2); GURL iframe_url = net::URLRequestMockHTTPJob::GetMockUrl(kMalwareIframe); SetURLThreatType(iframe_url, GetParam()); @@ -448,24 +451,6 @@ interstitial_page->CommandReceived(base::IntToString(command)); } - void DontProceedThroughInterstitial() { - WebContents* contents = - browser()->tab_strip_model()->GetActiveWebContents(); - InterstitialPage* interstitial_page = InterstitialPage::GetInterstitialPage( - contents); - ASSERT_TRUE(interstitial_page); - interstitial_page->DontProceed(); - } - - void ProceedThroughInterstitial() { - WebContents* contents = - browser()->tab_strip_model()->GetActiveWebContents(); - InterstitialPage* interstitial_page = InterstitialPage::GetInterstitialPage( - contents); - ASSERT_TRUE(interstitial_page); - interstitial_page->Proceed(); - } - void AssertNoInterstitial(bool wait_for_delete) { WebContents* contents = browser()->tab_strip_model()->GetActiveWebContents(); @@ -756,6 +741,120 @@ ASSERT_TRUE(report.ParseFromString(serialized)); // Verify the report is complete. EXPECT_TRUE(report.complete()); + // Do some basic verification of report contents. + EXPECT_EQ(url.spec(), report.page_url()); + EXPECT_EQ(net::URLRequestMockHTTPJob::GetMockUrl(kMalwareIframe).spec(), + report.url()); + std::vector<std::string> report_urls; + for (int i = 0; i < report.resources_size(); ++i) + report_urls.push_back(report.resources(i).url()); + ASSERT_EQ(3U, report_urls.size()); + std::sort(report_urls.begin(), report_urls.end()); + EXPECT_EQ("http://example.com/cross_site_iframe.html", report_urls[0]); + EXPECT_EQ(url.spec(), report_urls[1]); + EXPECT_EQ(net::URLRequestMockHTTPJob::GetMockUrl(kMalwareIframe).spec(), + report_urls[2]); + } +} + +IN_PROC_BROWSER_TEST_P(SafeBrowsingBlockingPageBrowserTest, + MainFrameBlockedShouldHaveNoDOMDetailsWhenDontProceed) { + const bool expect_threat_details = + SafeBrowsingBlockingPage::ShouldReportThreatDetails(GetParam()); + + scoped_refptr<content::MessageLoopRunner> threat_report_sent_runner( + new content::MessageLoopRunner); + if (expect_threat_details) + SetReportSentCallback(threat_report_sent_runner->QuitClosure()); + + // Navigate to a safe page which contains multiple potential DOM details. + // (Despite the name, kMalwarePage is not the page flagged as malware in this + // test.) + GURL safe_url(net::URLRequestMockHTTPJob::GetMockUrl(kMalwarePage)); + ui_test_utils::NavigateToURL(browser(), safe_url); + + EXPECT_EQ(nullptr, details_factory_.get_details()); + + // Start navigation to bad page (kEmptyPage), which will be blocked before it + // is committed. + GURL url = SetupWarningAndNavigate(); + + FakeThreatDetails* fake_threat_details = details_factory_.get_details(); + EXPECT_EQ(expect_threat_details, fake_threat_details != nullptr); + + // Go back. + EXPECT_EQ(VISIBLE, GetVisibility("extended-reporting-opt-in")); + EXPECT_TRUE(Click("opt-in-checkbox")); + EXPECT_TRUE(ClickAndWaitForDetach("primary-button")); + AssertNoInterstitial(true); // Assert the interstitial is gone + + EXPECT_TRUE(browser()->profile()->GetPrefs()->GetBoolean( + prefs::kSafeBrowsingExtendedReportingEnabled)); + EXPECT_EQ(safe_url, + browser()->tab_strip_model()->GetActiveWebContents()->GetURL()); + + if (expect_threat_details) { + threat_report_sent_runner->Run(); + std::string serialized = GetReportSent(); + ClientSafeBrowsingReportRequest report; + ASSERT_TRUE(report.ParseFromString(serialized)); + // Verify the report is complete. + EXPECT_TRUE(report.complete()); + EXPECT_EQ(url.spec(), report.page_url()); + EXPECT_EQ(url.spec(), report.url()); + ASSERT_EQ(1, report.resources_size()); + EXPECT_EQ(url.spec(), report.resources(0).url()); + } +} + +IN_PROC_BROWSER_TEST_P( + SafeBrowsingBlockingPageBrowserTest, + MainFrameBlockedShouldHaveNoDOMDetailsWhenProceeding) { + const bool expect_threat_details = + SafeBrowsingBlockingPage::ShouldReportThreatDetails(GetParam()); + + scoped_refptr<content::MessageLoopRunner> threat_report_sent_runner( + new content::MessageLoopRunner); + if (expect_threat_details) + SetReportSentCallback(threat_report_sent_runner->QuitClosure()); + + // Navigate to a safe page which contains multiple potential DOM details. + // (Despite the name, kMalwarePage is not the page flagged as malware in this + // test.) + ui_test_utils::NavigateToURL( + browser(), net::URLRequestMockHTTPJob::GetMockUrl(kMalwarePage)); + + EXPECT_EQ(nullptr, details_factory_.get_details()); + + // Start navigation to bad page (kEmptyPage), which will be blocked before it + // is committed. + GURL url = SetupWarningAndNavigate(); + + FakeThreatDetails* fake_threat_details = details_factory_.get_details(); + EXPECT_EQ(expect_threat_details, fake_threat_details != nullptr); + + // Proceed through the warning. + EXPECT_EQ(VISIBLE, GetVisibility("extended-reporting-opt-in")); + EXPECT_TRUE(Click("opt-in-checkbox")); + EXPECT_TRUE(ClickAndWaitForDetach("proceed-link")); + AssertNoInterstitial(true); // Assert the interstitial is gone + + EXPECT_TRUE(browser()->profile()->GetPrefs()->GetBoolean( + prefs::kSafeBrowsingExtendedReportingEnabled)); + EXPECT_EQ(url, + browser()->tab_strip_model()->GetActiveWebContents()->GetURL()); + + if (expect_threat_details) { + threat_report_sent_runner->Run(); + std::string serialized = GetReportSent(); + ClientSafeBrowsingReportRequest report; + ASSERT_TRUE(report.ParseFromString(serialized)); + // Verify the report is complete. + EXPECT_TRUE(report.complete()); + EXPECT_EQ(url.spec(), report.page_url()); + EXPECT_EQ(url.spec(), report.url()); + ASSERT_EQ(1, report.resources_size()); + EXPECT_EQ(url.spec(), report.resources(0).url()); } }
diff --git a/chrome/browser/safe_browsing/safe_browsing_service_browsertest.cc b/chrome/browser/safe_browsing/safe_browsing_service_browsertest.cc index 72c6f77..91547a2 100644 --- a/chrome/browser/safe_browsing/safe_browsing_service_browsertest.cc +++ b/chrome/browser/safe_browsing/safe_browsing_service_browsertest.cc
@@ -366,8 +366,6 @@ virtual ~MockObserver() {} MOCK_METHOD1(OnSafeBrowsingHit, void(const SafeBrowsingUIManager::UnsafeResource&)); - MOCK_METHOD1(OnSafeBrowsingMatch, - void(const SafeBrowsingUIManager::UnsafeResource&)); }; MATCHER_P(IsUnsafeResourceFor, url, "") { @@ -631,8 +629,6 @@ // we should see the interstitial page. SBFullHashResult malware_full_hash; GenUrlFullhashResultWithMetadata(url, &malware_full_hash); - EXPECT_CALL(observer_, - OnSafeBrowsingMatch(IsUnsafeResourceFor(url))).Times(1); EXPECT_CALL(observer_, OnSafeBrowsingHit(IsUnsafeResourceFor(url))).Times(1); SetupResponseForUrl(url, malware_full_hash); ui_test_utils::NavigateToURL(browser(), url); @@ -648,8 +644,6 @@ SBFullHashResult malware_full_hash; GenUrlFullhashResultWithMetadata(iframe_url, &malware_full_hash); EXPECT_CALL(observer_, - OnSafeBrowsingMatch(IsUnsafeResourceFor(iframe_url))).Times(1); - EXPECT_CALL(observer_, OnSafeBrowsingHit(IsUnsafeResourceFor(iframe_url))).Times(1); SetupResponseForUrl(iframe_url, malware_full_hash); ui_test_utils::NavigateToURL(browser(), main_url); @@ -667,8 +661,6 @@ switch (GetParam()) { case METADATA_NONE: // Falls through. case METADATA_DISTRIBUTION: - EXPECT_CALL(observer_, OnSafeBrowsingMatch(IsUnsafeResourceFor(img_url))) - .Times(1); EXPECT_CALL(observer_, OnSafeBrowsingHit(IsUnsafeResourceFor(img_url))) .Times(1); break; @@ -719,8 +711,6 @@ // we should see the interstitial page. SBFullHashResult malware_full_hash; GenUrlFullhashResult(url, MALWARE, &malware_full_hash); - EXPECT_CALL(observer_, - OnSafeBrowsingMatch(IsUnsafeResourceFor(url))).Times(1); EXPECT_CALL(observer_, OnSafeBrowsingHit(IsUnsafeResourceFor(url))) .Times(1) .WillOnce(testing::Invoke( @@ -733,10 +723,7 @@ EXPECT_FALSE(ShowingInterstitialPage()); Mock::VerifyAndClearExpectations(&observer_); - // Navigate back to kEmptyPage -- should hit the whitelist, and send a match - // call, but no hit call. - EXPECT_CALL(observer_, - OnSafeBrowsingMatch(IsUnsafeResourceFor(url))).Times(1); + // Navigate back to kEmptyPage -- should hit the whitelist. EXPECT_CALL(observer_, OnSafeBrowsingHit(IsUnsafeResourceFor(url))).Times(0); ui_test_utils::NavigateToURL(browser(), url); EXPECT_FALSE(ShowingInterstitialPage()); @@ -781,8 +768,6 @@ // However, when we navigate to the malware page, we should still get // the interstitial. - EXPECT_CALL(observer_, OnSafeBrowsingMatch(IsUnsafeResourceFor(malware_url))) - .Times(1); EXPECT_CALL(observer_, OnSafeBrowsingHit(IsUnsafeResourceFor(malware_url))) .Times(1); ui_test_utils::NavigateToURL(browser(), malware_url);
diff --git a/chrome/browser/safe_browsing/safe_browsing_tab_observer.cc b/chrome/browser/safe_browsing/safe_browsing_tab_observer.cc index 00df92e..7fe047c 100644 --- a/chrome/browser/safe_browsing/safe_browsing_tab_observer.cc +++ b/chrome/browser/safe_browsing/safe_browsing_tab_observer.cc
@@ -81,13 +81,4 @@ #endif } -bool SafeBrowsingTabObserver::DidPageReceiveSafeBrowsingMatch() const { -#if defined(SAFE_BROWSING_CSD) - return safebrowsing_detection_host_ && - safebrowsing_detection_host_->DidPageReceiveSafeBrowsingMatch(); -#else - return false; -#endif -} - } // namespace safe_browsing
diff --git a/chrome/browser/safe_browsing/safe_browsing_tab_observer.h b/chrome/browser/safe_browsing/safe_browsing_tab_observer.h index 8047189..d32a02ac 100644 --- a/chrome/browser/safe_browsing/safe_browsing_tab_observer.h +++ b/chrome/browser/safe_browsing/safe_browsing_tab_observer.h
@@ -23,9 +23,6 @@ public: ~SafeBrowsingTabObserver() override; - // Forward to detection host, if safe-browsing is enabled. - bool DidPageReceiveSafeBrowsingMatch() const; - private: explicit SafeBrowsingTabObserver(content::WebContents* web_contents); friend class content::WebContentsUserData<SafeBrowsingTabObserver>;
diff --git a/chrome/browser/safe_browsing/threat_details.cc b/chrome/browser/safe_browsing/threat_details.cc index aa361e3..af89c5c 100644 --- a/chrome/browser/safe_browsing/threat_details.cc +++ b/chrome/browser/safe_browsing/threat_details.cc
@@ -227,10 +227,14 @@ if (nav_entry && !referrer_url.is_empty()) AddUrl(referrer_url, GURL(), std::string(), NULL); - // Get URLs of frames, scripts etc from the DOM. - // OnReceivedThreatDOMDetails will be called when the renderer replies. - content::RenderViewHost* view = web_contents()->GetRenderViewHost(); - view->Send(new SafeBrowsingMsg_GetThreatDOMDetails(view->GetRoutingID())); + if (!resource_.IsMainPageLoadBlocked()) { + // Get URLs of frames, scripts etc from the DOM. + // OnReceivedThreatDOMDetails will be called when the renderer replies. + // TODO(mattm): In theory, if the user proceeds through the warning DOM + // detail collection could be started once the page loads. + content::RenderViewHost* view = web_contents()->GetRenderViewHost(); + view->Send(new SafeBrowsingMsg_GetThreatDOMDetails(view->GetRoutingID())); + } } // When the renderer is done, this is called.
diff --git a/chrome/browser/safe_browsing/ui_manager.cc b/chrome/browser/safe_browsing/ui_manager.cc index ac8fb0d3..c6bb6d0 100644 --- a/chrome/browser/safe_browsing/ui_manager.cc +++ b/chrome/browser/safe_browsing/ui_manager.cc
@@ -73,6 +73,21 @@ SafeBrowsingUIManager::UnsafeResource::~UnsafeResource() { } +bool SafeBrowsingUIManager::UnsafeResource::IsMainPageLoadBlocked() const { + // Subresource hits cannot happen until after main page load is committed. + if (is_subresource) + return false; + + // Client-side phishing detection interstitials never block the main frame + // load, since they happen after the page is finished loading. + if (threat_type == SB_THREAT_TYPE_CLIENT_SIDE_PHISHING_URL || + threat_type == SB_THREAT_TYPE_CLIENT_SIDE_MALWARE_URL) { + return false; + } + + return true; +} + // SafeBrowsingUIManager ------------------------------------------------------- SafeBrowsingUIManager::SafeBrowsingUIManager( @@ -133,12 +148,6 @@ } } - // Indicate to interested observers that the resource in question matched the - // SB filters. - if (resource.threat_type != SB_THREAT_TYPE_SAFE) { - FOR_EACH_OBSERVER(Observer, observer_list_, OnSafeBrowsingMatch(resource)); - } - // The tab might have been closed. If it was closed, just act as if "Don't // Proceed" had been chosen. WebContents* web_contents =
diff --git a/chrome/browser/safe_browsing/ui_manager.h b/chrome/browser/safe_browsing/ui_manager.h index 74d6e2d9..191dccc 100644 --- a/chrome/browser/safe_browsing/ui_manager.h +++ b/chrome/browser/safe_browsing/ui_manager.h
@@ -47,6 +47,8 @@ UnsafeResource(); ~UnsafeResource(); + bool IsMainPageLoadBlocked() const; + GURL url; GURL original_url; std::vector<GURL> redirect_urls; @@ -65,13 +67,6 @@ // was found. class Observer { public: - // The |resource| was classified as unsafe by SafeBrowsing. - // This method will be called every time an unsafe resource is - // loaded, even if it has already been whitelisted by the user. - // The |resource| must not be accessed after OnSafeBrowsingHit returns. - // This method will be called on the UI thread. - virtual void OnSafeBrowsingMatch(const UnsafeResource& resource) = 0; - // The |resource| was classified as unsafe by SafeBrowsing, and is // not whitelisted. // The |resource| must not be accessed after OnSafeBrowsingHit returns.
diff --git a/chrome/browser/search_engines/template_url_service_factory.cc b/chrome/browser/search_engines/template_url_service_factory.cc index f67a212..228b323 100644 --- a/chrome/browser/search_engines/template_url_service_factory.cc +++ b/chrome/browser/search_engines/template_url_service_factory.cc
@@ -22,6 +22,10 @@ #include "components/search_engines/search_engines_pref_names.h" #include "components/search_engines/template_url_service.h" +#if defined(OS_WIN) +#include "components/search_engines/desktop_search_win.h" +#endif // defined(OS_WIN) + #if defined(ENABLE_RLZ) #include "components/rlz/rlz_tracker.h" #endif @@ -79,6 +83,9 @@ user_prefs::PrefRegistrySyncable* registry) { DefaultSearchManager::RegisterProfilePrefs(registry); TemplateURLService::RegisterProfilePrefs(registry); +#if defined(OS_WIN) + RegisterWindowsDesktopSearchRedirectionPref(registry); +#endif } content::BrowserContext* TemplateURLServiceFactory::GetBrowserContextToUse(
diff --git a/chrome/browser/signin/chrome_signin_helper.cc b/chrome/browser/signin/chrome_signin_helper.cc index 0179bf3..4914aef 100644 --- a/chrome/browser/signin/chrome_signin_helper.cc +++ b/chrome/browser/signin/chrome_signin_helper.cc
@@ -11,6 +11,7 @@ #include "chrome/browser/signin/chrome_signin_client.h" #include "chrome/browser/tab_contents/tab_util.h" #include "chrome/browser/ui/browser_window.h" +#include "chrome/common/features.h" #include "chrome/common/url_constants.h" #include "components/signin/core/browser/account_reconcilor.h" #include "components/signin/core/browser/signin_header_helper.h" @@ -20,13 +21,13 @@ #include "google_apis/gaia/gaia_auth_util.h" #include "net/url_request/url_request.h" -#if defined(OS_ANDROID) +#if BUILDFLAG(ANDROID_JAVA_UI) #include "chrome/browser/android/signin/account_management_screen_helper.h" #else #include "chrome/browser/ui/browser_commands.h" #include "chrome/browser/ui/browser_finder.h" #include "extensions/browser/guest_view/web_view/web_view_renderer_state.h" -#endif // defined(OS_ANDROID) +#endif // BUILDFLAG(ANDROID_JAVA_UI) namespace signin { @@ -54,7 +55,7 @@ AccountReconcilorFactory::GetForProfile(profile); account_reconcilor->OnReceivedManageAccountsResponse( manage_accounts_params.service_type); -#if !defined(OS_ANDROID) +#if !BUILDFLAG(ANDROID_JAVA_UI) Browser* browser = chrome::FindBrowserWithWebContents(web_contents); if (browser) { BrowserWindow::AvatarBubbleMode bubble_mode; @@ -76,7 +77,7 @@ browser->window()->ShowAvatarBubbleFromAvatarButton(bubble_mode, manage_accounts_params); } -#else // defined(OS_ANDROID) +#else // BUILDFLAG(ANDROID_JAVA_UI) if (service_type == signin::GAIA_SERVICE_TYPE_INCOGNITO) { GURL url(manage_accounts_params.continue_url.empty() ? chrome::kChromeUINativeNewTabURL @@ -90,7 +91,7 @@ AccountManagementScreenHelper::OpenAccountManagementScreen(profile, service_type); } -#endif // !defined(OS_ANDROID) +#endif // !BUILDFLAG(ANDROID_JAVA_UI) } // Returns the parameters contained in the X-Chrome-Manage-Accounts response
diff --git a/chrome/browser/signin/profile_oauth2_token_service_factory.cc b/chrome/browser/signin/profile_oauth2_token_service_factory.cc index a8b65af..41e074f 100644 --- a/chrome/browser/signin/profile_oauth2_token_service_factory.cc +++ b/chrome/browser/signin/profile_oauth2_token_service_factory.cc
@@ -9,10 +9,11 @@ #include "chrome/browser/signin/chrome_signin_client_factory.h" #include "chrome/browser/signin/signin_error_controller_factory.h" #include "chrome/browser/web_data_service_factory.h" +#include "chrome/common/features.h" #include "components/keyed_service/content/browser_context_dependency_manager.h" #include "components/signin/core/browser/profile_oauth2_token_service.h" -#if defined(OS_ANDROID) +#if BUILDFLAG(ANDROID_JAVA_UI) #include "chrome/browser/signin/oauth2_token_service_delegate_android.h" #else #include "chrome/browser/signin/mutable_profile_oauth2_token_service_delegate.h" @@ -50,7 +51,7 @@ KeyedService* ProfileOAuth2TokenServiceFactory::BuildServiceInstanceFor( content::BrowserContext* context) const { Profile* profile = static_cast<Profile*>(context); -#if defined(OS_ANDROID) +#if BUILDFLAG(ANDROID_JAVA_UI) OAuth2TokenServiceDelegateAndroid* delegate = new OAuth2TokenServiceDelegateAndroid( AccountTrackerServiceFactory::GetInstance()->GetForProfile(profile));
diff --git a/chrome/browser/site_details.cc b/chrome/browser/site_details.cc index 4a4f3ae..4a326a83 100644 --- a/chrome/browser/site_details.cc +++ b/chrome/browser/site_details.cc
@@ -8,6 +8,7 @@ #include "content/public/browser/browser_thread.h" #include "content/public/browser/render_frame_host.h" #include "content/public/browser/render_process_host.h" +#include "url/origin.h" #if defined(ENABLE_EXTENSIONS) #include "extensions/browser/extension_registry.h" @@ -65,18 +66,15 @@ RenderFrameHost* frame) { BrowserContext* context = primary->GetBrowserContext(); - GURL url = frame->GetLastCommittedURL(); + // Determine the site from the frame's origin, with a fallback to the + // frame's URL. In cases like <iframe sandbox>, we can wind up with an http + // URL but a unique origin. The origin of the resource will still determine + // process placement. + url::Origin origin = frame->GetLastCommittedOrigin(); + GURL site = SiteInstance::GetSiteForURL( + context, origin.unique() ? frame->GetLastCommittedURL() + : GURL(origin.Serialize())); - // Treat about:blank url specially: use the URL on the SiteInstance if it is - // assigned. The rest of this computation must not depend on the - // SiteInstance's URL, since its value reflects the current process model, and - // this computation is simulating other process models. - if (url == GURL(url::kAboutBlankURL) && - !frame->GetSiteInstance()->GetSiteURL().is_empty()) { - url = frame->GetSiteInstance()->GetSiteURL(); - } - - GURL site = SiteInstance::GetSiteForURL(context, url); bool should_isolate = ShouldIsolate(context, scenario, site); // Treat a subframe as part of its parent site if neither needs isolation.
diff --git a/chrome/browser/site_details_browsertest.cc b/chrome/browser/site_details_browsertest.cc index 8686a4e..bc202c654 100644 --- a/chrome/browser/site_details_browsertest.cc +++ b/chrome/browser/site_details_browsertest.cc
@@ -1135,8 +1135,8 @@ const Extension* extension1 = CreateExtension("Extension One", false); // Navigate the tab's first iframe to a resource of the extension. The - // extension iframe will be put in a separate BrowsingInstance (see - // https://crbug.com/522302) unless in the default process model. + // extension iframe will be put in the same BrowsingInstance as it is part + // of the frame tree. content::NavigateIframeToURL( tab, "child-0", extension1->GetResourceURL("/blank_iframe.html")); details = new TestMemoryDetails(); @@ -1144,7 +1144,7 @@ if (content::AreAllSitesIsolatedForTesting()) { EXPECT_THAT(details->uma()->GetAllSamples( "SiteIsolation.SiteInstancesPerBrowsingInstance"), - ElementsAre(Bucket(1, 1), Bucket(4, 1))); + ElementsAre(Bucket(5, 1))); } else if (extensions::IsIsolateExtensionsEnabled()) { EXPECT_THAT(details->uma()->GetAllSamples( "SiteIsolation.SiteInstancesPerBrowsingInstance"), @@ -1163,7 +1163,7 @@ if (content::AreAllSitesIsolatedForTesting()) { EXPECT_THAT(details->uma()->GetAllSamples( "SiteIsolation.SiteInstancesPerBrowsingInstance"), - ElementsAre(Bucket(1, 2), Bucket(4, 1))); + ElementsAre(Bucket(1, 1), Bucket(5, 1))); } else if (extensions::IsIsolateExtensionsEnabled()) { EXPECT_THAT(details->uma()->GetAllSamples( "SiteIsolation.SiteInstancesPerBrowsingInstance"), @@ -1174,9 +1174,8 @@ ElementsAre(Bucket(1, 2))); } - // Navigate the second iframe of the tab to the second extension. This will - // create a new BrowsingInstance again due to https://crbug.com/522302 for - // --site-per-process and --isolate-extensions. + // Navigate the second iframe of the tab to the second extension. It should + // stay in the same BrowsingInstance as the page. content::NavigateIframeToURL( tab, "child-1", extension2->GetResourceURL("/blank_iframe.html")); details = new TestMemoryDetails(); @@ -1184,7 +1183,7 @@ if (content::AreAllSitesIsolatedForTesting()) { EXPECT_THAT(details->uma()->GetAllSamples( "SiteIsolation.SiteInstancesPerBrowsingInstance"), - ElementsAre(Bucket(1, 3), Bucket(3, 1))); + ElementsAre(Bucket(1, 1), Bucket(5, 1))); } else if (extensions::IsIsolateExtensionsEnabled()) { EXPECT_THAT(details->uma()->GetAllSamples( "SiteIsolation.SiteInstancesPerBrowsingInstance"),
diff --git a/chrome/browser/speech/tts_android.cc b/chrome/browser/speech/tts_android.cc index dbec2f8..e8ec307e 100644 --- a/chrome/browser/speech/tts_android.cc +++ b/chrome/browser/speech/tts_android.cc
@@ -11,6 +11,7 @@ #include "base/memory/singleton.h" #include "base/strings/utf_string_conversions.h" #include "chrome/browser/speech/tts_controller.h" +#include "chrome/common/features.h" #include "jni/TtsPlatformImpl_jni.h" using base::android::AttachCurrentThread;
diff --git a/chrome/browser/speech/tts_android.h b/chrome/browser/speech/tts_android.h index f6ce3b2..f38d674 100644 --- a/chrome/browser/speech/tts_android.h +++ b/chrome/browser/speech/tts_android.h
@@ -8,6 +8,7 @@ #include "base/android/jni_android.h" #include "base/android/scoped_java_ref.h" #include "chrome/browser/speech/tts_platform.h" +#include "chrome/common/features.h" class TtsPlatformImplAndroid : public TtsPlatformImpl { public: @@ -32,7 +33,9 @@ // Static functions. static TtsPlatformImplAndroid* GetInstance(); +#if BUILDFLAG(ANDROID_JAVA_UI) static bool Register(JNIEnv* env); +#endif private: friend struct base::DefaultSingletonTraits<TtsPlatformImplAndroid>;
diff --git a/chrome/browser/supervised_user/supervised_user_interstitial.cc b/chrome/browser/supervised_user/supervised_user_interstitial.cc index 3810abd..510c783de 100644 --- a/chrome/browser/supervised_user/supervised_user_interstitial.cc +++ b/chrome/browser/supervised_user/supervised_user_interstitial.cc
@@ -16,6 +16,7 @@ #include "chrome/browser/profiles/profile.h" #include "chrome/browser/supervised_user/supervised_user_service.h" #include "chrome/browser/supervised_user/supervised_user_service_factory.h" +#include "chrome/common/features.h" #include "chrome/common/pref_names.h" #include "chrome/grit/generated_resources.h" #include "components/infobars/core/infobar.h" @@ -36,9 +37,9 @@ #include "ui/base/webui/jstemplate_builder.h" #include "ui/base/webui/web_ui_util.h" -#if defined(OS_ANDROID) +#if BUILDFLAG(ANDROID_JAVA_UI) #include "chrome/browser/supervised_user/child_accounts/child_account_feedback_reporter_android.h" -#else +#elif !defined(OS_ANDROID) #include "chrome/browser/ui/browser_finder.h" #include "chrome/browser/ui/chrome_pages.h" #include "chrome/browser/ui/tabs/tab_strip_model.h" @@ -340,7 +341,7 @@ SupervisedUserURLFilter::GetBlockMessageID(reason_)); std::string message = l10n_util::GetStringFUTF8( IDS_BLOCK_INTERSTITIAL_DEFAULT_FEEDBACK_TEXT, reason); -#if defined(OS_ANDROID) +#if BUILDFLAG(ANDROID_JAVA_UI) ReportChildAccountFeedback(web_contents_, message, url_); #else chrome::ShowFeedbackPage(chrome::FindBrowserWithWebContents(web_contents_),
diff --git a/chrome/browser/sync/chrome_sync_client.cc b/chrome/browser/sync/chrome_sync_client.cc index 7c5e70d2..7e389f9 100644 --- a/chrome/browser/sync/chrome_sync_client.cc +++ b/chrome/browser/sync/chrome_sync_client.cc
@@ -29,6 +29,7 @@ #include "chrome/browser/undo/bookmark_undo_service_factory.h" #include "chrome/browser/web_data_service_factory.h" #include "chrome/common/channel_info.h" +#include "chrome/common/features.h" #include "chrome/common/pref_names.h" #include "chrome/common/url_constants.h" #include "components/autofill/core/browser/webdata/autocomplete_syncable_service.h" @@ -90,7 +91,7 @@ #include "chrome/browser/spellchecker/spellcheck_service.h" #endif -#if defined(OS_ANDROID) +#if BUILDFLAG(ANDROID_JAVA_UI) #include "chrome/browser/sync/glue/synced_window_delegates_getter_android.h" #endif @@ -116,7 +117,7 @@ public: explicit SyncSessionsClientImpl(Profile* profile) : profile_(profile) { window_delegates_getter_.reset( -#if defined(OS_ANDROID) +#if BUILDFLAG(ANDROID_JAVA_UI) // Android doesn't have multi-profile support, so no need to pass the // profile in. new browser_sync::SyncedWindowDelegatesGetterAndroid()); @@ -262,11 +263,11 @@ sync_driver::SyncApiComponentFactory::RegisterDataTypesMethod ChromeSyncClient::GetRegisterPlatformTypesCallback() { return base::Bind( -#ifdef OS_ANDROID +#if BUILDFLAG(ANDROID_JAVA_UI) &ChromeSyncClient::RegisterAndroidDataTypes, #else &ChromeSyncClient::RegisterDesktopDataTypes, -#endif // OS_ANDROID +#endif // BUILDFLAG(ANDROID_JAVA_UI) weak_ptr_factory_.GetWeakPtr()); }
diff --git a/chrome/browser/sync/sessions/notification_service_sessions_router.cc b/chrome/browser/sync/sessions/notification_service_sessions_router.cc index f66ec51..780ff29 100644 --- a/chrome/browser/sync/sessions/notification_service_sessions_router.cc +++ b/chrome/browser/sync/sessions/notification_service_sessions_router.cc
@@ -12,6 +12,7 @@ #include "chrome/browser/ui/browser.h" #include "chrome/browser/ui/sync/browser_synced_window_delegates_getter.h" #include "chrome/browser/ui/sync/tab_contents_synced_tab_delegate.h" +#include "chrome/common/features.h" #include "components/history/core/browser/history_service.h" #include "components/sync_sessions/sync_sessions_client.h" #include "components/sync_sessions/synced_tab_delegate.h" @@ -22,7 +23,7 @@ #include "content/public/browser/notification_source.h" #include "content/public/browser/web_contents.h" -#if defined(OS_ANDROID) +#if BUILDFLAG(ANDROID_JAVA_UI) #include "chrome/browser/android/tab_android.h" #endif @@ -44,14 +45,14 @@ SyncedTabDelegate* GetSyncedTabDelegateFromWebContents( content::WebContents* web_contents) { -#if defined(OS_ANDROID) +#if BUILDFLAG(ANDROID_JAVA_UI) TabAndroid* tab = TabAndroid::FromWebContents(web_contents); return tab ? tab->GetSyncedTabDelegate() : nullptr; -#else // !OS_ANDROID +#else SyncedTabDelegate* delegate = TabContentsSyncedTabDelegate::FromWebContents(web_contents); return delegate; -#endif // OS_ANDROID +#endif } } // namespace
diff --git a/chrome/browser/translate/translate_manager_browsertest.cc b/chrome/browser/translate/translate_manager_browsertest.cc index e30b1bce..4a7a6d9 100644 --- a/chrome/browser/translate/translate_manager_browsertest.cc +++ b/chrome/browser/translate/translate_manager_browsertest.cc
@@ -61,7 +61,7 @@ // Tests that the CLD (Compact Language Detection) works properly. IN_PROC_BROWSER_TEST_F(TranslateManagerBrowserTest, PageLanguageDetection) { - ASSERT_TRUE(test_server()->Start()); + ASSERT_TRUE(embedded_test_server()->Start()); // The InProcessBrowserTest opens a new tab, let's wait for that first. WaitUntilLanguageDetected(); @@ -73,7 +73,7 @@ EXPECT_EQ("und", adopted_language); // Open a new tab with a page in English. - AddTabAtIndex(0, GURL(test_server()->GetURL("files/english_page.html")), + AddTabAtIndex(0, GURL(embedded_test_server()->GetURL("/english_page.html")), ui::PAGE_TRANSITION_TYPED); ResetObserver(); @@ -92,7 +92,7 @@ // Now navigate to a page in French. ui_test_utils::NavigateToURL( - browser(), GURL(test_server()->GetURL("files/french_page.html"))); + browser(), GURL(embedded_test_server()->GetURL("/french_page.html"))); WaitUntilLanguageDetected(); adopted_language = GetLanguageFor(current_web_contents);
diff --git a/chrome/browser/ui/BUILD.gn b/chrome/browser/ui/BUILD.gn index 349a53d..91825ea9 100644 --- a/chrome/browser/ui/BUILD.gn +++ b/chrome/browser/ui/BUILD.gn
@@ -46,6 +46,7 @@ deps = [ # NOTE: New dependencies should generally be added in the OS!="ios" # dependencies block below, rather than here. + "//base/debug:debugging_flags", "//chrome:extra_resources", "//chrome:resources", "//chrome:strings", @@ -331,19 +332,19 @@ } if (is_android) { - deps += [ - "//chrome/browser:jni_headers", - "//crypto:platform", - ] + deps += [ "//crypto:platform" ] defines += [ "CHROME_BUILD_ID=\"$android_chrome_build_id\"" ] - if (!use_aura) { + if (android_java_ui) { sources += - rebase_path(gypi_values.chrome_browser_ui_android_non_aura_sources, + rebase_path(gypi_values.chrome_browser_ui_android_java_ui_sources, ".", "//chrome") - deps += [ "//components/web_contents_delegate_android" ] + deps += [ + "//chrome/browser:jni_headers", + "//components/web_contents_delegate_android", + ] deps -= [ "//ui/events" ] } } @@ -456,6 +457,11 @@ sources += rebase_path(gypi_values.chrome_browser_ui_app_list_sources, ".", "//chrome") + if (is_chromeos) { + sources += rebase_path(gypi_values.chrome_browser_ui_chromeos_arc_sources, + ".", + "//chrome") + } deps += [ "//ui/app_list" ] } else { sources += rebase_path(gypi_values.chrome_browser_ui_non_app_list_sources,
diff --git a/chrome/browser/ui/android/context_menu_helper.cc b/chrome/browser/ui/android/context_menu_helper.cc index 87a6f39..68893d3 100644 --- a/chrome/browser/ui/android/context_menu_helper.cc +++ b/chrome/browser/ui/android/context_menu_helper.cc
@@ -44,26 +44,24 @@ Java_ContextMenuHelper_destroy(env, java_obj_.obj()); } -void ContextMenuHelper::ShowContextMenu( +bool ContextMenuHelper::ShowContextMenu( const content::ContextMenuParams& params) { content::ContentViewCore* content_view_core = content::ContentViewCore::FromWebContents(web_contents_); if (!content_view_core) - return; + return false; base::android::ScopedJavaLocalRef<jobject> jcontent_view_core( content_view_core->GetJavaObject()); if (jcontent_view_core.is_null()) - return; + return false; JNIEnv* env = base::android::AttachCurrentThread(); context_menu_params_ = params; - Java_ContextMenuHelper_showContextMenu( - env, - java_obj_.obj(), - jcontent_view_core.obj(), + return Java_ContextMenuHelper_showContextMenu( + env, java_obj_.obj(), jcontent_view_core.obj(), ContextMenuHelper::CreateJavaContextMenuParams(params).obj()); }
diff --git a/chrome/browser/ui/android/context_menu_helper.h b/chrome/browser/ui/android/context_menu_helper.h index 499eaad..3fa25b94 100644 --- a/chrome/browser/ui/android/context_menu_helper.h +++ b/chrome/browser/ui/android/context_menu_helper.h
@@ -24,7 +24,7 @@ public: ~ContextMenuHelper() override; - void ShowContextMenu(const content::ContextMenuParams& params); + bool ShowContextMenu(const content::ContextMenuParams& params); void SetPopulator(jobject jpopulator);
diff --git a/chrome/browser/ui/android/tab_contents/chrome_web_contents_view_delegate_android.cc b/chrome/browser/ui/android/tab_contents/chrome_web_contents_view_delegate_android.cc index cc97dcc..473bc75 100644 --- a/chrome/browser/ui/android/tab_contents/chrome_web_contents_view_delegate_android.cc +++ b/chrome/browser/ui/android/tab_contents/chrome_web_contents_view_delegate_android.cc
@@ -34,18 +34,19 @@ if (params.is_editable && params.selection_text.empty()) { content::ContentViewCore* content_view_core = content::ContentViewCore::FromWebContents(web_contents_); - if (content_view_core) { - content_view_core->ShowPastePopup(params.selection_start.x(), - params.selection_start.y()); + if (content_view_core && + content_view_core->ShowPastePopup(params.selection_start.x(), + params.selection_start.y())) return; - } + } else { + // TODO(dtrainor, kouhei): Give WebView a Populator/delegate so it can use + // the same context menu code. + ContextMenuHelper* helper = + ContextMenuHelper::FromWebContents(web_contents_); + if (helper && helper->ShowContextMenu(params)) + return; } - - // TODO(dtrainor, kouhei): Give WebView a Populator/delegate so it can use the - // same context menu code. - ContextMenuHelper* helper = ContextMenuHelper::FromWebContents(web_contents_); - if (helper) - helper->ShowContextMenu(params); + web_contents_->NotifyContextMenuClosed(content::CustomContextMenuContext()); } namespace chrome {
diff --git a/chrome/browser/ui/app_list/app_list_model_builder.cc b/chrome/browser/ui/app_list/app_list_model_builder.cc new file mode 100644 index 0000000..9712158 --- /dev/null +++ b/chrome/browser/ui/app_list/app_list_model_builder.cc
@@ -0,0 +1,64 @@ +// 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. + +#include "chrome/browser/ui/app_list/app_list_model_builder.h" + +#include "chrome/browser/ui/app_list/app_list_syncable_service.h" +#include "ui/app_list/app_list_item.h" +#include "ui/app_list/app_list_model.h" + +AppListModelBuilder::AppListModelBuilder(AppListControllerDelegate* controller, + const char* item_type) + : controller_(controller), + item_type_(item_type) { +} + +AppListModelBuilder::~AppListModelBuilder() { + if (!service_) + model_->top_level_item_list()->RemoveObserver(this); +} + +void AppListModelBuilder::InitializeWithService( + app_list::AppListSyncableService* service, + app_list::AppListModel* model) { + DCHECK(!service_ && !profile_); + model_ = model; + service_ = service; + profile_ = service->profile(); + + BuildModel(); +} + +void AppListModelBuilder::InitializeWithProfile(Profile* profile, + app_list::AppListModel* model) { + DCHECK(!service_ && !profile_); + model_ = model; + model_->top_level_item_list()->AddObserver(this); + profile_ = profile; + + BuildModel(); +} + +void AppListModelBuilder::InsertApp(scoped_ptr<app_list::AppListItem> app) { + if (service_) { + service_->AddItem(app.Pass()); + return; + } + model_->AddItem(app.Pass()); +} + +const app_list::AppListSyncableService::SyncItem* + AppListModelBuilder::GetSyncItem(const std::string& id) { + return service_ ? service_->GetSyncItem(id) : nullptr; +} + +app_list::AppListItem* AppListModelBuilder::GetAppItem(const std::string& id) { + app_list::AppListItem* item = model_->FindItem(id); + if (item && item->GetItemType() != item_type_) { + VLOG(2) << "App Item matching id: " << id + << " has incorrect type: '" << item->GetItemType() << "'"; + return nullptr; + } + return item; +}
diff --git a/chrome/browser/ui/app_list/app_list_model_builder.h b/chrome/browser/ui/app_list/app_list_model_builder.h new file mode 100644 index 0000000..0b53ea1 --- /dev/null +++ b/chrome/browser/ui/app_list/app_list_model_builder.h
@@ -0,0 +1,75 @@ +// 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. + +#ifndef CHROME_BROWSER_UI_APP_LIST_APP_LIST_MODEL_BUILDER_H_ +#define CHROME_BROWSER_UI_APP_LIST_APP_LIST_MODEL_BUILDER_H_ + +#include <string> + +#include "base/macros.h" +#include "chrome/browser/ui/app_list/app_list_syncable_service.h" +#include "ui/app_list/app_list_item_list_observer.h" +#include "ui/app_list/app_list_model.h" + +class AppListControllerDelegate; +class Profile; + +// This abstract class populates and maintains the given |model| with +// information from |profile| for the specific item type. +class AppListModelBuilder : public app_list::AppListItemListObserver { + public: + // |controller| is owned by implementation of AppListService. + AppListModelBuilder(AppListControllerDelegate* controller, + const char* item_type); + ~AppListModelBuilder() override; + + // Initialize to use app-list sync and sets |service_| to |service|. + // |service| is the owner of this instance and |model|. + void InitializeWithService(app_list::AppListSyncableService* service, + app_list::AppListModel* model); + + // Initialize to use extension sync and sets |service_| to nullptr. Used in + // tests and when AppList sync is not enabled. + // app_list::AppListSyncableService is the owner of |model| + void InitializeWithProfile(Profile* profile, app_list::AppListModel* model); + + protected: + // Builds the model with the current profile. + virtual void BuildModel() = 0; + + app_list::AppListSyncableService* service() { return service_; } + + Profile* profile() { return profile_; } + + AppListControllerDelegate* controller() { return controller_; } + + app_list::AppListModel* model() { return model_; } + + // Inserts an app based on app ordinal prefs. + void InsertApp(scoped_ptr<app_list::AppListItem> app); + + const app_list::AppListSyncableService::SyncItem* GetSyncItem( + const std::string& id); + + // Returns app instance matching |id| or nullptr. + app_list::AppListItem* GetAppItem(const std::string& id); + + private: + // Unowned pointers to the service that owns this and associated profile. + app_list::AppListSyncableService* service_ = nullptr; + Profile* profile_ = nullptr; + + // Unowned pointer to the app list model. + app_list::AppListModel* model_ = nullptr; + + // Unowned pointer to the app list controller. + AppListControllerDelegate* controller_; + + // Global constant defined for each item type. + const char* item_type_; + + DISALLOW_COPY_AND_ASSIGN(AppListModelBuilder); +}; + +#endif // CHROME_BROWSER_UI_APP_LIST_APP_LIST_MODEL_BUILDER_H_
diff --git a/chrome/browser/ui/app_list/app_list_syncable_service.cc b/chrome/browser/ui/app_list/app_list_syncable_service.cc index 7ab733b..909a17b 100644 --- a/chrome/browser/ui/app_list/app_list_syncable_service.cc +++ b/chrome/browser/ui/app_list/app_list_syncable_service.cc
@@ -36,6 +36,8 @@ #if defined(OS_CHROMEOS) #include "chrome/browser/chromeos/file_manager/app_id.h" #include "chrome/browser/chromeos/genius_app/app_id.h" +#include "chrome/browser/ui/app_list/arc/arc_app_item.h" +#include "chrome/browser/ui/app_list/arc/arc_app_model_builder.h" #endif using syncer::SyncChange; @@ -132,6 +134,10 @@ const char* item_type = item->GetItemType(); if (item_type == ExtensionAppItem::kItemType) { *type = sync_pb::AppListSpecifics::TYPE_APP; +#if defined(OS_CHROMEOS) + } else if (item_type == ArcAppItem::kItemType) { + *type = sync_pb::AppListSpecifics::TYPE_APP; +#endif } else if (item_type == AppListFolderItem::kItemType) { *type = sync_pb::AppListSpecifics::TYPE_FOLDER; } else { @@ -265,14 +271,23 @@ if (service) controller = service->GetControllerDelegate(); apps_builder_.reset(new ExtensionAppModelBuilder(controller)); +#if defined(OS_CHROMEOS) + arc_apps_builder_.reset(new ArcAppModelBuilder(controller)); +#endif DCHECK(profile_); if (app_list::switches::IsAppListSyncEnabled()) { VLOG(1) << this << ": AppListSyncableService: InitializeWithService."; SyncStarted(); apps_builder_->InitializeWithService(this, model_.get()); +#if defined(OS_CHROMEOS) + arc_apps_builder_->InitializeWithService(this, model_.get()); +#endif } else { VLOG(1) << this << ": AppListSyncableService: InitializeWithProfile."; apps_builder_->InitializeWithProfile(profile_, model_.get()); +#if defined(OS_CHROMEOS) + arc_apps_builder_->InitializeWithProfile(profile_, model_.get()); +#endif } model_pref_updater_.reset(
diff --git a/chrome/browser/ui/app_list/app_list_syncable_service.h b/chrome/browser/ui/app_list/app_list_syncable_service.h index 3407616..c4258051 100644 --- a/chrome/browser/ui/app_list/app_list_syncable_service.h +++ b/chrome/browser/ui/app_list/app_list_syncable_service.h
@@ -18,6 +18,10 @@ #include "sync/api/syncable_service.h" #include "sync/protocol/app_list_specifics.pb.h" +#if defined(OS_CHROMEOS) +class ArcAppModelBuilder; +#endif + class DriveAppProvider; class ExtensionAppModelBuilder; class Profile; @@ -200,6 +204,9 @@ scoped_ptr<ModelObserver> model_observer_; scoped_ptr<ModelPrefUpdater> model_pref_updater_; scoped_ptr<ExtensionAppModelBuilder> apps_builder_; +#if defined(OS_CHROMEOS) + scoped_ptr<ArcAppModelBuilder> arc_apps_builder_; +#endif scoped_ptr<syncer::SyncChangeProcessor> sync_processor_; scoped_ptr<syncer::SyncErrorFactory> sync_error_handler_; SyncItemMap sync_items_;
diff --git a/chrome/browser/ui/app_list/app_list_syncable_service_factory.cc b/chrome/browser/ui/app_list/app_list_syncable_service_factory.cc index 2c96dc22..c2e2eb1 100644 --- a/chrome/browser/ui/app_list/app_list_syncable_service_factory.cc +++ b/chrome/browser/ui/app_list/app_list_syncable_service_factory.cc
@@ -18,6 +18,7 @@ #if defined(OS_CHROMEOS) #include "chrome/browser/chromeos/profiles/profile_helper.h" +#include "chrome/browser/ui/app_list/arc/arc_app_list_prefs_factory.h" #endif namespace app_list { @@ -57,6 +58,9 @@ FactorySet dependent_factories; dependent_factories.insert( extensions::ExtensionsBrowserClient::Get()->GetExtensionSystemFactory()); +#if defined(OS_CHROMEOS) + dependent_factories.insert(ArcAppListPrefsFactory::GetInstance()); +#endif DriveAppProvider::AppendDependsOnFactories(&dependent_factories); for (FactorySet::iterator it = dependent_factories.begin(); it != dependent_factories.end();
diff --git a/chrome/browser/ui/app_list/arc/arc_app_icon.cc b/chrome/browser/ui/app_list/arc/arc_app_icon.cc new file mode 100644 index 0000000..26adfab --- /dev/null +++ b/chrome/browser/ui/app_list/arc/arc_app_icon.cc
@@ -0,0 +1,284 @@ +// 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. + +#include "chrome/browser/ui/app_list/arc/arc_app_icon.h" + +#include <algorithm> + +#include "base/bind.h" +#include "base/files/file_path.h" +#include "base/files/file_util.h" +#include "base/task_runner_util.h" +#include "chrome/browser/image_decoder.h" +#include "chrome/browser/ui/app_list/arc/arc_app_list_prefs.h" +#include "content/public/browser/browser_thread.h" +#include "extensions/grit/extensions_browser_resources.h" +#include "ui/base/resource/resource_bundle.h" +#include "ui/gfx/geometry/size.h" +#include "ui/gfx/image/image_skia_source.h" + +namespace { + +bool g_disable_decoding = false; + +} // namespace + +//////////////////////////////////////////////////////////////////////////////// +// ArcAppIcon::ReadResult + +struct ArcAppIcon::ReadResult { + enum class Status { + OK, + FAIL, + REQUEST_TO_INSTALL, + }; + + // Used for fail results or for the requests to install an icon. + ReadResult(Status status, ui::ScaleFactor scale_factor) + : status(status), scale_factor(scale_factor) { + DCHECK(status == Status::FAIL || status == Status::REQUEST_TO_INSTALL); + } + + // Used for successful results. + ReadResult(ui::ScaleFactor scale_factor, + const std::string& unsafe_icon_data) + : status(Status::OK), + scale_factor(scale_factor), + unsafe_icon_data(unsafe_icon_data) { + } + + Status status; + ui::ScaleFactor scale_factor; + std::string unsafe_icon_data; +}; + +//////////////////////////////////////////////////////////////////////////////// +// ArcAppIcon::Source + +class ArcAppIcon::Source : public gfx::ImageSkiaSource { + public: + explicit Source(const base::WeakPtr<ArcAppIcon>& host); + ~Source() override; + + private: + // gfx::ImageSkiaSource overrides: + gfx::ImageSkiaRep GetImageForScale(float scale) override; + + // Used to load images asynchronously. NULLed out when the ArcAppIcon is + // destroyed. + base::WeakPtr<ArcAppIcon> host_; + + DISALLOW_COPY_AND_ASSIGN(Source); +}; + +ArcAppIcon::Source::Source(const base::WeakPtr<ArcAppIcon>& host) + : host_(host) { +} + +ArcAppIcon::Source::~Source() { +} + +gfx::ImageSkiaRep ArcAppIcon::Source::GetImageForScale(float scale) { + if (host_) + host_->LoadForScaleFactor(ui::GetSupportedScaleFactor(scale)); + + // Host loads icon asynchronously, so use default icon so far. + const gfx::ImageSkia* default_image = ResourceBundle::GetSharedInstance(). + GetImageSkiaNamed(IDR_APP_DEFAULT_ICON); + CHECK(default_image); + + return default_image->GetRepresentation(scale); +} + +class ArcAppIcon::DecodeRequest : public ImageDecoder::ImageRequest { + public: + DecodeRequest(const base::WeakPtr<ArcAppIcon>& host, + int dimension, + ui::ScaleFactor scale_factor); + ~DecodeRequest() override; + + // ImageDecoder::ImageRequest + void OnImageDecoded(const SkBitmap& bitmap) override; + void OnDecodeImageFailed() override; + private: + base::WeakPtr<ArcAppIcon> host_; + int dimension_; + ui::ScaleFactor scale_factor_; + + DISALLOW_COPY_AND_ASSIGN(DecodeRequest); +}; + +//////////////////////////////////////////////////////////////////////////////// +// ArcAppIcon::DecodeRequest + +ArcAppIcon::DecodeRequest::DecodeRequest(const base::WeakPtr<ArcAppIcon>& host, + int dimension, + ui::ScaleFactor scale_factor) + : host_(host), + dimension_(dimension), + scale_factor_(scale_factor) { +} + +ArcAppIcon::DecodeRequest::~DecodeRequest() { +} + +void ArcAppIcon::DecodeRequest::OnImageDecoded(const SkBitmap& bitmap) { + DCHECK(!bitmap.isNull() && !bitmap.empty()); + + if (!host_) + return; + + int expected_dim = static_cast<int>( + ui::GetScaleForScaleFactor(scale_factor_) * dimension_ + 0.5f); + if (bitmap.width() != expected_dim || bitmap.height() != expected_dim) { + VLOG(2) << "Decoded ARC icon has unexpected dimension " + << bitmap.width() << "x" << bitmap.height() << ". Expected " + << expected_dim << "x" << "."; + host_->DiscardDecodeRequest(this); + return; + } + + gfx::ImageSkia image_skia; + image_skia.AddRepresentation(gfx::ImageSkiaRep( + bitmap, + ui::GetScaleForScaleFactor(scale_factor_))); + + host_->Update(&image_skia); + host_->DiscardDecodeRequest(this); +} + +void ArcAppIcon::DecodeRequest::OnDecodeImageFailed() { + VLOG(2) << "Failed to decode ARC icon."; + + if (!host_) + return; + + host_->DiscardDecodeRequest(this); +} + +//////////////////////////////////////////////////////////////////////////////// +// ArcAppIcon + +// static +void ArcAppIcon::DisableDecodingForTesting() { + g_disable_decoding = true; +} + +ArcAppIcon::ArcAppIcon(content::BrowserContext* context, + const std::string& app_id, + int resource_size_in_dip, + Observer* observer) + : context_(context), + app_id_(app_id), + resource_size_in_dip_(resource_size_in_dip), + observer_(observer), + weak_ptr_factory_(this) { + CHECK(observer_ != nullptr); + source_ = new Source(weak_ptr_factory_.GetWeakPtr()); + gfx::Size resource_size(resource_size_in_dip, resource_size_in_dip); + image_skia_ = gfx::ImageSkia(source_, resource_size); +} + +ArcAppIcon::~ArcAppIcon() { +} + +void ArcAppIcon::LoadForScaleFactor(ui::ScaleFactor scale_factor) { + ArcAppListPrefs* prefs = ArcAppListPrefs::Get(context_); + + base::FilePath path = prefs->GetIconPath(app_id_, scale_factor); + if (path.empty()) + return; + + base::PostTaskAndReplyWithResult(content::BrowserThread::GetBlockingPool(), + FROM_HERE, + base::Bind(&ArcAppIcon::ReadOnFileThread, + scale_factor, + path), + base::Bind(&ArcAppIcon::OnIconRead, + weak_ptr_factory_.GetWeakPtr())); +} + +void ArcAppIcon::RequestIcon(ui::ScaleFactor scale_factor) { + DCHECK_CURRENTLY_ON(content::BrowserThread::UI); + ArcAppListPrefs* prefs = ArcAppListPrefs::Get(context_); + + // ArcAppListPrefs notifies ArcAppModelBuilder via Observer when icon is ready + // and ArcAppModelBuilder refreshes the icon of the corresponding item by + // calling LoadScaleFactor. + prefs->RequestIcon(app_id_, scale_factor); +} + +// static +scoped_ptr<ArcAppIcon::ReadResult> ArcAppIcon::ReadOnFileThread( + ui::ScaleFactor scale_factor, + const base::FilePath& path) { + DCHECK(content::BrowserThread::GetBlockingPool()->RunsTasksOnCurrentThread()); + DCHECK(!path.empty()); + + if (!base::PathExists(path)) + return make_scoped_ptr(new ArcAppIcon::ReadResult( + ArcAppIcon::ReadResult::Status::REQUEST_TO_INSTALL, scale_factor)); + + // Read the file from disk. + std::string unsafe_icon_data; + if (!base::ReadFileToString(path, &unsafe_icon_data)) { + VLOG(2) << "Failed to read an ARC icon from file " << path.MaybeAsASCII(); + return make_scoped_ptr(new ArcAppIcon::ReadResult( + ArcAppIcon::ReadResult::Status::FAIL, scale_factor)); + } + + return make_scoped_ptr(new ArcAppIcon::ReadResult(scale_factor, + unsafe_icon_data)); +} + +void ArcAppIcon::OnIconRead(scoped_ptr<ArcAppIcon::ReadResult> read_result) { + DCHECK_CURRENTLY_ON(content::BrowserThread::UI); + + switch (read_result->status) { + case ReadResult::Status::OK: + if (!g_disable_decoding) { + decode_requests_.push_back( + new DecodeRequest(weak_ptr_factory_.GetWeakPtr(), + resource_size_in_dip_, + read_result->scale_factor)); + ImageDecoder::Start(decode_requests_.back(), + read_result->unsafe_icon_data); + } + break; + case ReadResult::Status::FAIL: + break; + case ReadResult::Status::REQUEST_TO_INSTALL: + RequestIcon(read_result->scale_factor); + break; + default: + NOTREACHED(); + } +} + +void ArcAppIcon::Update(const gfx::ImageSkia* image) { + DCHECK_CURRENTLY_ON(content::BrowserThread::UI); + CHECK(image && !image->isNull()); + + std::vector<gfx::ImageSkiaRep> reps = image->image_reps(); + for (const auto& image_rep : reps) { + if (ui::IsSupportedScale(image_rep.scale())) { + image_skia_.RemoveRepresentation(image_rep.scale()); + image_skia_.AddRepresentation(image_rep); + } + } + + image_ = gfx::Image(image_skia_); + + observer_->OnIconUpdated(); +} + +void ArcAppIcon::DiscardDecodeRequest(DecodeRequest* request) { + DCHECK_CURRENTLY_ON(content::BrowserThread::UI); + + ScopedVector<DecodeRequest>::iterator it = std::find(decode_requests_.begin(), + decode_requests_.end(), + request); + CHECK(it != decode_requests_.end()); + decode_requests_.erase(it); +}
diff --git a/chrome/browser/ui/app_list/arc/arc_app_icon.h b/chrome/browser/ui/app_list/arc/arc_app_icon.h new file mode 100644 index 0000000..e3f09b82 --- /dev/null +++ b/chrome/browser/ui/app_list/arc/arc_app_icon.h
@@ -0,0 +1,111 @@ +// 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. + +#ifndef CHROME_BROWSER_UI_APP_LIST_ARC_ARC_APP_ICON_H_ +#define CHROME_BROWSER_UI_APP_LIST_ARC_ARC_APP_ICON_H_ + +#include <string> + +#include "base/macros.h" +#include "base/memory/scoped_vector.h" +#include "base/memory/weak_ptr.h" +#include "ui/base/layout.h" +#include "ui/gfx/image/image.h" +#include "ui/gfx/image/image_skia.h" + +namespace base { +class FilePath; +} + +namespace content { +class BrowserContext; +} + +// A class that provides an ImageSkia for UI code to use. It handles ARC app +// icon resource loading, screen scale factor change etc. UI code that uses +// ARC app icon should host this class. +class ArcAppIcon { + public: + class Observer { + public: + // Invoked when a new image rep for an additional scale factor + // is loaded and added to |image|. + virtual void OnIconUpdated() = 0; + + protected: + virtual ~Observer() {} + }; + + ArcAppIcon(content::BrowserContext* context, + const std::string& app_id, + int resource_size_in_dip, + Observer* observer); + ~ArcAppIcon(); + + gfx::Image image() const { return image_; } + const gfx::ImageSkia& image_skia() const { return image_skia_; } + + // Icon loading is performed in several steps. It is initiated by + // LoadImageForScaleFactor request that specifies a required scale factor. + // ArcAppListPrefs is used to resolve a path to resource. Content of file is + // asynchronously read in context of browser file thread. On successful read, + // an icon data is decoded to an image in the special utility process. + // DecodeRequest is used to interact with the utility process, and each + // active request is stored at |decode_requests_| vector. When decoding is + // complete, results are returned in context of UI thread, and corresponding + // request is removed from |decode_requests_|. In case of some requests are + // not completed by the time of deleting this icon, they are automatically + // canceled. + // In case of the icon file is not available this requests ArcAppListPrefs to + // install required resource from ARC side. ArcAppListPrefs notifies UI items + // that new icon is available and corresponding item should invoke + // LoadImageForScaleFactor again. + void LoadForScaleFactor(ui::ScaleFactor scale_factor); + + // Disables decoding requests when unit tests are executed. This is done to + // avoid two problems. Problems come because icons are decoded at a separate + // process created by ImageDecoder. ImageDecoder has 5 seconds delay to stop + // since the last request (see its kBatchModeTimeoutSeconds for more details). + // This is unacceptably long for unit tests because the test framework waits + // until external process is finished. Another problem happens when we issue + // a decoding request, but the process has not started its processing yet by + // the time when a test exits. This might cause situation when + // g_one_utility_thread_lock from in_process_utility_thread.cc gets released + // in an acquired state which is crash condition in debug builds. + static void DisableDecodingForTesting(); + + private: + class Source; + class DecodeRequest; + struct ReadResult; + + void RequestIcon(ui::ScaleFactor scale_factor); + static scoped_ptr<ArcAppIcon::ReadResult> ReadOnFileThread( + ui::ScaleFactor scale_factor, + const base::FilePath& path); + void OnIconRead(scoped_ptr<ArcAppIcon::ReadResult> read_result); + void Update(const gfx::ImageSkia* image); + void DiscardDecodeRequest(DecodeRequest* request); + + content::BrowserContext* context_; + std::string app_id_; + const int resource_size_in_dip_; + Observer* observer_; + + Source* source_ = nullptr; // Owned by ImageSkia storage. + gfx::ImageSkia image_skia_; + + // The image wrapper around |image_skia_|. + // Note: this is reset each time a new representation is loaded. + gfx::Image image_; + + // Contains pending image decode requests. + ScopedVector<DecodeRequest> decode_requests_; + + base::WeakPtrFactory<ArcAppIcon> weak_ptr_factory_; + + DISALLOW_COPY_AND_ASSIGN(ArcAppIcon); +}; + +#endif // CHROME_BROWSER_UI_APP_LIST_ARC_ARC_APP_ICON_H_
diff --git a/chrome/browser/ui/app_list/arc/arc_app_item.cc b/chrome/browser/ui/app_list/arc/arc_app_item.cc new file mode 100644 index 0000000..2e1a312 --- /dev/null +++ b/chrome/browser/ui/app_list/arc/arc_app_item.cc
@@ -0,0 +1,120 @@ +// 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. + +#include "chrome/browser/ui/app_list/arc/arc_app_item.h" + +#include "chrome/browser/ui/app_list/arc/arc_app_list_prefs.h" +#include "components/arc/arc_bridge_service.h" +#include "content/public/browser/browser_thread.h" +#include "extensions/browser/app_sorting.h" +#include "extensions/browser/extension_prefs.h" +#include "ui/app_list/app_list_constants.h" +#include "ui/gfx/color_utils.h" +#include "ui/gfx/image/image_skia_operations.h" + +namespace { + +gfx::ImageSkia CreateDisabledIcon(const gfx::ImageSkia& icon) { + const color_utils::HSL shift = {-1, 0, 0.6}; + return gfx::ImageSkiaOperations::CreateHSLShiftedImage(icon, shift); +} + +extensions::AppSorting* GetAppSorting(content::BrowserContext* context) { + return extensions::ExtensionPrefs::Get(context)->app_sorting(); +} + +} // namespace + +// static +const char ArcAppItem::kItemType[] = "ArcAppItem"; + +ArcAppItem::ArcAppItem( + content::BrowserContext* context, + const app_list::AppListSyncableService::SyncItem* sync_item, + const std::string& id, + const std::string& name, + bool ready) + : app_list::AppListItem(id), + context_(context), + ready_(ready) { + DCHECK_CURRENTLY_ON(content::BrowserThread::UI); + + arc_app_icon_.reset(new ArcAppIcon(context_, + id, + app_list::kGridIconDimension, + this)); + + SetName(name); + UpdateIcon(); + + if (sync_item && sync_item->item_ordinal.IsValid()) { + // An existing synced position exists, use that. + set_position(sync_item->item_ordinal); + } else { + // There is an ExtensionAppItem that uses extension::AppSorting to order + // its element. There is no commonly available sorting mechanism for app + // ordering so use the only one available from extension subsystem. + // Page is is the earliest non-full page. + const syncer::StringOrdinal& page = + GetAppSorting(context_)->GetNaturalAppPageOrdinal(); + // And get next available pos in this page. + const syncer::StringOrdinal& pos = + GetAppSorting(context_)->CreateNextAppLaunchOrdinal(page); + set_position(pos); + } +} + +ArcAppItem::~ArcAppItem() { +} + +const char* ArcAppItem::GetItemType() const { + return ArcAppItem::kItemType; +} + +void ArcAppItem::Activate(int event_flags) { + DCHECK(ready_); + + ArcAppListPrefs* prefs = ArcAppListPrefs::Get(context_); + scoped_ptr<ArcAppListPrefs::AppInfo> app_info = prefs->GetApp(id()); + if (!app_info) { + VLOG(2) << "Cannot launch unavailable app:" << id() << "."; + return; + } + + arc::ArcBridgeService* bridge_service = arc::ArcBridgeService::Get(); + if (!bridge_service || + bridge_service->state() != arc::ArcBridgeService::State::READY) { + VLOG(2) << "Cannot launch app: " << app_info->package + << ". Bridge service is not ready."; + return; + } + + bridge_service->LaunchApp(app_info->package, app_info->activity); +} + +void ArcAppItem::SetReady(bool ready) { + if (ready_ == ready) + return; + + ready_ = ready; + UpdateIcon(); +} + +void ArcAppItem::SetName(const std::string& name) { + SetNameAndShortName(name, name); +} + +void ArcAppItem::UpdateIcon() { + DCHECK_CURRENTLY_ON(content::BrowserThread::UI); + + gfx::ImageSkia icon = arc_app_icon_->image_skia(); + if (!ready_) + icon = CreateDisabledIcon(icon); + + SetIcon(icon); +} + +void ArcAppItem::OnIconUpdated() { + UpdateIcon(); +}
diff --git a/chrome/browser/ui/app_list/arc/arc_app_item.h b/chrome/browser/ui/app_list/arc/arc_app_item.h new file mode 100644 index 0000000..22342bd --- /dev/null +++ b/chrome/browser/ui/app_list/arc/arc_app_item.h
@@ -0,0 +1,57 @@ +// 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. + +#ifndef CHROME_BROWSER_UI_APP_LIST_ARC_ARC_APP_ITEM_H_ +#define CHROME_BROWSER_UI_APP_LIST_ARC_ARC_APP_ITEM_H_ + +#include <string> + +#include "base/macros.h" +#include "chrome/browser/ui/app_list/app_list_syncable_service.h" +#include "chrome/browser/ui/app_list/arc/arc_app_icon.h" +#include "ui/app_list/app_list_item.h" + +namespace content { +class BrowserContext; +} // content + +// ArcAppItem represents an ARC app in app list. +class ArcAppItem : public app_list::AppListItem, + public ArcAppIcon::Observer { + public: + static const char kItemType[]; + + ArcAppItem(content::BrowserContext* context, + const app_list::AppListSyncableService::SyncItem* sync_item, + const std::string& id, + const std::string& name, + bool ready); + ~ArcAppItem() override; + + void SetName(const std::string& name); + + void Activate(int event_flags) override; + const char* GetItemType() const override; + + ArcAppIcon* arc_app_icon() { return arc_app_icon_.get(); } + + bool ready() const { return ready_; } + + void SetReady(bool ready); + + // ArcAppIcon::Observer + void OnIconUpdated() override; + + private: + // Updates the app item's icon, if necessary making it gray. + void UpdateIcon(); + + content::BrowserContext* context_; + bool ready_; + scoped_ptr<ArcAppIcon> arc_app_icon_; + + DISALLOW_COPY_AND_ASSIGN(ArcAppItem); +}; + +#endif // CHROME_BROWSER_UI_APP_LIST_ARC_ARC_APP_ITEM_H_
diff --git a/chrome/browser/ui/app_list/arc/arc_app_list_prefs.cc b/chrome/browser/ui/app_list/arc/arc_app_list_prefs.cc new file mode 100644 index 0000000..157ec45 --- /dev/null +++ b/chrome/browser/ui/app_list/arc/arc_app_list_prefs.cc
@@ -0,0 +1,376 @@ +// 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. + +#include "chrome/browser/ui/app_list/arc/arc_app_list_prefs.h" + +#include "base/files/file_util.h" +#include "base/prefs/scoped_user_pref_update.h" +#include "base/task_runner_util.h" +#include "chrome/browser/profiles/profile.h" +#include "chrome/browser/ui/app_list/arc/arc_app_list_prefs_factory.h" +#include "chrome/common/pref_names.h" +#include "components/crx_file/id_util.h" +#include "components/pref_registry/pref_registry_syncable.h" +#include "content/public/browser/browser_thread.h" + +namespace { + +const char kName[] = "name"; +const char kPackage[] = "package"; +const char kActivity[] = "activity"; + +// Provider of write access to a dictionary storing ARC app prefs. +class ScopedArcAppListPrefUpdate : public DictionaryPrefUpdate { + public: + ScopedArcAppListPrefUpdate(PrefService* service, const std::string& id) + : DictionaryPrefUpdate(service, prefs::kArcApps), + id_(id) {} + + ~ScopedArcAppListPrefUpdate() override {} + + // DictionaryPrefUpdate overrides: + base::DictionaryValue* Get() override { + base::DictionaryValue* dict = DictionaryPrefUpdate::Get(); + base::DictionaryValue* app = nullptr; + if (!dict->GetDictionary(id_, &app)) { + app = new base::DictionaryValue(); + dict->SetWithoutPathExpansion(id_, app); + } + return app; + } + + private: + const std::string id_; + + DISALLOW_COPY_AND_ASSIGN(ScopedArcAppListPrefUpdate); +}; + +bool InstallIconFromFileThread(const std::string& app_id, + ui::ScaleFactor scale_factor, + const base::FilePath& icon_path, + const std::vector<uint8>& content_png) { + DCHECK(content::BrowserThread::GetBlockingPool()->RunsTasksOnCurrentThread()); + DCHECK(!content_png.empty()); + + base::CreateDirectory(icon_path.DirName()); + + int wrote = base::WriteFile(icon_path, + reinterpret_cast<const char*>(&content_png[0]), + content_png.size()); + if (wrote != static_cast<int>(content_png.size())) { + VLOG(2) << "Failed to write ARC icon file: " << icon_path.MaybeAsASCII() + << "."; + if (!base::DeleteFile(icon_path, false)) + VLOG(2) << "Couldn't delete broken icon file" << icon_path.MaybeAsASCII() + << "."; + return false; + } + + return true; +} + +} // namespace + +// static +ArcAppListPrefs* ArcAppListPrefs::Create(const base::FilePath& base_path, + PrefService* prefs) { + return new ArcAppListPrefs(base_path, prefs); +} + +// static +void ArcAppListPrefs::RegisterProfilePrefs( + user_prefs::PrefRegistrySyncable* registry) { + registry->RegisterDictionaryPref( + prefs::kArcApps, + user_prefs::PrefRegistrySyncable::SYNCABLE_PREF); +} + +// static +ArcAppListPrefs* ArcAppListPrefs::Get(content::BrowserContext* context) { + return ArcAppListPrefsFactory::GetInstance()->GetForBrowserContext(context); +} + +// static +std::string ArcAppListPrefs::GetAppId(const std::string& package, + const std::string& activity) { + std::string input = package + "#" + activity; + return crx_file::id_util::GenerateId(input); +} + +ArcAppListPrefs::ArcAppListPrefs(const base::FilePath& base_path, + PrefService* prefs) + : prefs_(prefs), + weak_ptr_factory_(this) { + base_path_ = base_path.AppendASCII(prefs::kArcApps); + + arc::ArcBridgeService* bridge_service = arc::ArcBridgeService::Get(); + if (!bridge_service) { + VLOG(2) << "Bridge service is not available. Cannot init."; + return; + } + + bridge_service->AddObserver(this); + bridge_service->AddAppObserver(this); + OnStateChanged(bridge_service->state()); +} + +ArcAppListPrefs::~ArcAppListPrefs() { + arc::ArcBridgeService* bridge_service = arc::ArcBridgeService::Get(); + if (bridge_service) { + bridge_service->RemoveAppObserver(this); + bridge_service->RemoveObserver(this); + } +} + +base::FilePath ArcAppListPrefs::GetIconPath( + const std::string& app_id, + ui::ScaleFactor scale_factor) const { + base::FilePath app_path = base_path_.AppendASCII(app_id); + switch (scale_factor) { + case ui::SCALE_FACTOR_100P: + return app_path.AppendASCII("icon_100p.png"); + case ui::SCALE_FACTOR_125P: + return app_path.AppendASCII("icon_125p.png"); + case ui::SCALE_FACTOR_133P: + return app_path.AppendASCII("icon_133p.png"); + case ui::SCALE_FACTOR_140P: + return app_path.AppendASCII("icon_140p.png"); + case ui::SCALE_FACTOR_150P: + return app_path.AppendASCII("icon_150p.png"); + case ui::SCALE_FACTOR_180P: + return app_path.AppendASCII("icon_180p.png"); + case ui::SCALE_FACTOR_200P: + return app_path.AppendASCII("icon_200p.png"); + case ui::SCALE_FACTOR_250P: + return app_path.AppendASCII("icon_250p.png"); + case ui::SCALE_FACTOR_300P: + return app_path.AppendASCII("icon_300p.png"); + default: + NOTREACHED(); + return base::FilePath(); + } +} + +void ArcAppListPrefs::RequestIcon(const std::string& app_id, + ui::ScaleFactor scale_factor) { + if (!IsRegistered(app_id)) { + VLOG(2) << "Request to load icon for non-registered app: " + << app_id << "."; + return; + } + + // In case app is not ready, defer this request. + if (!ready_apps_.count(app_id)) { + request_icon_deferred_[app_id] = + request_icon_deferred_[app_id] | 1 << scale_factor; + return; + } + + arc::ArcBridgeService* bridge_service = arc::ArcBridgeService::Get(); + if (!bridge_service || + bridge_service->state() != arc::ArcBridgeService::State::READY) { + VLOG(2) << "Request to load icon when bridge service is not ready: " + << app_id << "."; + return; + } + + scoped_ptr<AppInfo> app_info = GetApp(app_id); + if (!app_info) { + VLOG(2) << "Failed to get app info: " << app_id << "."; + return; + } + + bridge_service->RequestAppIcon(app_info->package, + app_info->activity, + static_cast<arc::ScaleFactor>(scale_factor)); +} + +void ArcAppListPrefs::AddObserver(Observer* observer) { + observer_list_.AddObserver(observer); +} + +void ArcAppListPrefs::RemoveObserver(Observer* observer) { + observer_list_.RemoveObserver(observer); +} + +std::vector<std::string> ArcAppListPrefs::GetAppIds() const { + std::vector<std::string> ids; + + // crx_file::id_util is de-factor utility for id generation. + const base::DictionaryValue* apps = prefs_->GetDictionary(prefs::kArcApps); + for (base::DictionaryValue::Iterator app_id(*apps); + !app_id.IsAtEnd(); app_id.Advance()) { + if (!crx_file::id_util::IdIsValid(app_id.key())) + continue; + ids.push_back(app_id.key()); + } + + return ids; +} + +scoped_ptr<ArcAppListPrefs::AppInfo> ArcAppListPrefs::GetApp( + const std::string& app_id) const { + const base::DictionaryValue* app = nullptr; + const base::DictionaryValue* apps = prefs_->GetDictionary(prefs::kArcApps); + if (!apps || !apps->GetDictionaryWithoutPathExpansion(app_id, &app)) + return scoped_ptr<AppInfo>(); + + std::string name; + std::string package; + std::string activity; + app->GetString(kName, &name); + app->GetString(kPackage, &package); + app->GetString(kActivity, &activity); + scoped_ptr<AppInfo> app_info(new AppInfo(name, + package, + activity, + ready_apps_.count(app_id) > 0)); + + return app_info.Pass(); +} + +bool ArcAppListPrefs::IsRegistered(const std::string& app_id) { + const base::DictionaryValue* app = nullptr; + const base::DictionaryValue* apps = prefs_->GetDictionary(prefs::kArcApps); + if (!apps || !apps->GetDictionary(app_id, &app)) + return false; + + return true; +} + +void ArcAppListPrefs::DisableAllApps() { + for (auto& app_id : ready_apps_) + FOR_EACH_OBSERVER(Observer, + observer_list_, + OnAppReadyChanged(app_id, false)); + + ready_apps_.clear(); +} + +void ArcAppListPrefs::OnStateChanged(arc::ArcBridgeService::State state) { + if (state == arc::ArcBridgeService::State::READY) + arc::ArcBridgeService::Get()->RefreshAppList(); + else + DisableAllApps(); +} + +void ArcAppListPrefs::OnAppReady(const arc::AppInfo& app) { + if (app.name.empty() || app.package.empty() || app.activity.empty()) { + VLOG(2) << "Name, package and activity cannot be empty."; + return; + } + std::string app_id = GetAppId(app.package, app.activity); + bool was_registered = IsRegistered(app_id); + + ScopedArcAppListPrefUpdate update(prefs_, app_id); + base::DictionaryValue* app_dict = update.Get(); + app_dict->SetString(kName, app.name); + app_dict->SetString(kPackage, app.package); + app_dict->SetString(kActivity, app.activity); + + // From now, app is ready. + if (!ready_apps_.count(app_id)) + ready_apps_.insert(app_id); + + if (was_registered) { + FOR_EACH_OBSERVER(Observer, + observer_list_, + OnAppReadyChanged(app_id, true)); + } else { + AppInfo app_info(app.name, app.package, app.activity, true); + FOR_EACH_OBSERVER(Observer, + observer_list_, + OnAppRegistered(app_id, app_info)); + } + + std::map<std::string, uint32>::iterator deferred_icons = + request_icon_deferred_.find(app_id); + if (deferred_icons != request_icon_deferred_.end()) { + for (uint32 i = ui::SCALE_FACTOR_100P; i < ui::NUM_SCALE_FACTORS; ++i) { + if (deferred_icons->second & (1 << i)) { + RequestIcon(app_id, static_cast<ui::ScaleFactor>(i)); + } + } + request_icon_deferred_.erase(deferred_icons); + } +} + +void ArcAppListPrefs::OnAppListRefreshed( + const std::vector<arc::AppInfo>& apps) { + std::set<std::string> old_ready_apps; + old_ready_apps.swap(ready_apps_); + + for (auto& app : apps) + OnAppReady(app); + + // Detect unavailable apps after current refresh. + for (auto& app_id : old_ready_apps) { + if (!ready_apps_.count(app_id)) { + FOR_EACH_OBSERVER(Observer, + observer_list_, + OnAppReadyChanged(app_id, false)); + } + } +} + +void ArcAppListPrefs::OnAppIcon(const std::string& package, + const std::string& activity, + arc::ScaleFactor scale_factor, + const std::vector<uint8_t>& icon_png_data) { + DCHECK_CURRENTLY_ON(content::BrowserThread::UI); + DCHECK(!icon_png_data.empty()); + DCHECK(scale_factor >= arc::SCALE_FACTOR_100P && + scale_factor < arc::NUM_SCALE_FACTORS); + + std::string app_id = GetAppId(package, activity); + if (!IsRegistered(app_id)) { + VLOG(2) << "Request to update icon for non-registered app: " << app_id; + return; + } + + InstallIcon(app_id, + static_cast<ui::ScaleFactor>(scale_factor), + icon_png_data); +} + + +void ArcAppListPrefs::InstallIcon(const std::string& app_id, + ui::ScaleFactor scale_factor, + const std::vector<uint8>& content_png) { + + base::FilePath icon_path = GetIconPath(app_id, scale_factor); + base::PostTaskAndReplyWithResult(content::BrowserThread::GetBlockingPool(), + FROM_HERE, + base::Bind(&InstallIconFromFileThread, + app_id, + scale_factor, + icon_path, + content_png), + base::Bind(&ArcAppListPrefs::OnIconInstalled, + weak_ptr_factory_.GetWeakPtr(), + app_id, + scale_factor)); +} + +void ArcAppListPrefs::OnIconInstalled(const std::string& app_id, + ui::ScaleFactor scale_factor, + bool install_succeed) { + DCHECK_CURRENTLY_ON(content::BrowserThread::UI); + if (!install_succeed) + return; + + FOR_EACH_OBSERVER(Observer, + observer_list_, + OnAppIconUpdated(app_id, scale_factor)); +} + +ArcAppListPrefs::AppInfo::AppInfo(const std::string& name, + const std::string& package, + const std::string& activity, + bool ready) + : name(name), + package(package), + activity(activity), + ready(ready) { +}
diff --git a/chrome/browser/ui/app_list/arc/arc_app_list_prefs.h b/chrome/browser/ui/app_list/arc/arc_app_list_prefs.h new file mode 100644 index 0000000..a8e7bba --- /dev/null +++ b/chrome/browser/ui/app_list/arc/arc_app_list_prefs.h
@@ -0,0 +1,148 @@ +// 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. + +#ifndef CHROME_BROWSER_UI_APP_LIST_ARC_ARC_APP_LIST_PREFS_H_ +#define CHROME_BROWSER_UI_APP_LIST_ARC_ARC_APP_LIST_PREFS_H_ + +#include <map> +#include <set> +#include <vector> + +#include "base/files/file_path.h" +#include "base/macros.h" +#include "base/memory/scoped_ptr.h" +#include "base/memory/weak_ptr.h" +#include "base/observer_list.h" +#include "components/arc/arc_bridge_service.h" +#include "components/keyed_service/core/keyed_service.h" +#include "ui/base/layout.h" + +class PrefService; + +namespace content { +class BrowserContext; +} + +namespace user_prefs { +class PrefRegistrySyncable; +} + +// Declares shareable ARC app specific preferences, that keep information +// about app attributes (name, package, activity) and its state. This +// information is used to pre-create non-ready app items while ARC bridge +// service is not ready to provide information about available ARC apps. +class ArcAppListPrefs : public KeyedService, + public arc::ArcBridgeService::Observer, + public arc::ArcBridgeService::AppObserver { + public: + struct AppInfo { + AppInfo(const std::string& name, + const std::string& package, + const std::string& activity, + bool ready); + + std::string name; + std::string package; + std::string activity; + bool ready; + }; + + class Observer { + public: + // Notifies an observer that new app is registered. + virtual void OnAppRegistered(const std::string& app_id, + const AppInfo& app_info) = 0; + // Notifies an observer that app ready state has been changed. + virtual void OnAppReadyChanged(const std::string& id, bool ready) = 0; + // Notifies an observer that app icon has been installed or updated. + virtual void OnAppIconUpdated(const std::string& id, + ui::ScaleFactor scale_factor) = 0; + protected: + virtual ~Observer() {} + }; + + static ArcAppListPrefs* Create(const base::FilePath& base_path, + PrefService* prefs); + + // Convenience function to get the ArcAppListPrefs for a BrowserContext. + static ArcAppListPrefs* Get(content::BrowserContext* context); + + // Constructs unique id based on package and activity information. This id + // is safe to use at file paths and as preference keys. + static std::string GetAppId(const std::string& package, + const std::string& activity); + + // It is called from chrome/browser/prefs/browser_prefs.cc. + static void RegisterProfilePrefs(user_prefs::PrefRegistrySyncable* registry); + + ~ArcAppListPrefs() override; + + // Returns a list of all app ids, including ready and non-ready apps. + std::vector<std::string> GetAppIds() const; + + // Extracts attributes of an app based on its id. Returns NULL if the app is + // not found. + scoped_ptr<AppInfo> GetApp(const std::string& app_id) const; + + // Constructs path to app icon for specific scale factor. + base::FilePath GetIconPath(const std::string& app_id, + ui::ScaleFactor scale_factor) const; + + // Requests to load an app icon for specific scale factor. If the app or Arc + // bridge service is not ready, then defer this request until the app gets + // available. Once new icon is installed notifies an observer + // OnAppIconUpdated. + void RequestIcon(const std::string& app_id, ui::ScaleFactor scale_factor); + + // Returns true if app is registered. + bool IsRegistered(const std::string& app_id); + + void AddObserver(Observer* observer); + void RemoveObserver(Observer* observer); + + // arc::ArcBridgeService::Observer + void OnStateChanged(arc::ArcBridgeService::State state) override; + void OnAppListRefreshed(const std::vector<arc::AppInfo>& apps) override; + void OnAppIcon(const std::string& package, + const std::string& activity, + arc::ScaleFactor scale_factor, + const std::vector<uint8_t>& icon_png_data) override; + + private: + // See the Create methods. + ArcAppListPrefs(const base::FilePath& base_path, PrefService* prefs); + + void OnAppReady(const arc::AppInfo& app); + void DisableAllApps(); + + // Installs an icon to file system in the special folder of the profile + // directory. + void InstallIcon(const std::string& app_id, + ui::ScaleFactor scale_factor, + const std::vector<uint8>& contentPng); + void OnIconInstalled(const std::string& app_id, + ui::ScaleFactor scale_factor, + bool install_succeed); + + // Owned by the BrowserContext. + PrefService* prefs_; + + // List of observers. + base::ObserverList<Observer> observer_list_; + // Keeps root folder where ARC app icons for different scale factor are + // stored. + base::FilePath base_path_; + // Contains set of ARC apps that are currently ready. + std::set<std::string> ready_apps_; + // Keeps deferred icon load requests. Each app may contain several requests + // for different scale factor. Scale factor is defined by specific bit + // position. + std::map<std::string, uint32> request_icon_deferred_; + + base::WeakPtrFactory<ArcAppListPrefs> weak_ptr_factory_; + + DISALLOW_COPY_AND_ASSIGN(ArcAppListPrefs); +}; + +#endif // CHROME_BROWSER_UI_APP_LIST_ARC_ARC_APP_LIST_PREFS_H_
diff --git a/chrome/browser/ui/app_list/arc/arc_app_list_prefs_factory.cc b/chrome/browser/ui/app_list/arc/arc_app_list_prefs_factory.cc new file mode 100644 index 0000000..e6051ca3 --- /dev/null +++ b/chrome/browser/ui/app_list/arc/arc_app_list_prefs_factory.cc
@@ -0,0 +1,45 @@ +// 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. + +#include "chrome/browser/ui/app_list/arc/arc_app_list_prefs_factory.h" + +#include "chrome/browser/profiles/incognito_helpers.h" +#include "chrome/browser/profiles/profile.h" +#include "chrome/browser/ui/app_list/arc/arc_app_list_prefs.h" +#include "components/keyed_service/content/browser_context_dependency_manager.h" +#include "content/public/browser/browser_context.h" + +// static +ArcAppListPrefs* ArcAppListPrefsFactory::GetForBrowserContext( + content::BrowserContext* context) { + return static_cast<ArcAppListPrefs*>( + GetInstance()->GetServiceForBrowserContext(context, true)); +} + +// static +ArcAppListPrefsFactory* ArcAppListPrefsFactory::GetInstance() { + return base::Singleton<ArcAppListPrefsFactory>::get(); +} + +ArcAppListPrefsFactory::ArcAppListPrefsFactory() + : BrowserContextKeyedServiceFactory( + "ArcAppListPrefs", + BrowserContextDependencyManager::GetInstance()) { +} + +ArcAppListPrefsFactory::~ArcAppListPrefsFactory() { +} + +KeyedService* ArcAppListPrefsFactory::BuildServiceInstanceFor( + content::BrowserContext* context) const { + Profile* profile = static_cast<Profile*>(context); + return ArcAppListPrefs::Create(profile->GetPath(), profile->GetPrefs()); +} + +content::BrowserContext* ArcAppListPrefsFactory::GetBrowserContextToUse( + content::BrowserContext* context) const { + // This matches the logic in ExtensionSyncServiceFactory, which uses the + // orginal browser context. + return chrome::GetBrowserContextRedirectedInIncognito(context); +}
diff --git a/chrome/browser/ui/app_list/arc/arc_app_list_prefs_factory.h b/chrome/browser/ui/app_list/arc/arc_app_list_prefs_factory.h new file mode 100644 index 0000000..e70773b --- /dev/null +++ b/chrome/browser/ui/app_list/arc/arc_app_list_prefs_factory.h
@@ -0,0 +1,36 @@ +// 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. + +#ifndef CHROME_BROWSER_UI_APP_LIST_ARC_ARC_APP_LIST_PREFS_FACTORY_H_ +#define CHROME_BROWSER_UI_APP_LIST_ARC_ARC_APP_LIST_PREFS_FACTORY_H_ + +#include "base/macros.h" +#include "base/memory/scoped_ptr.h" +#include "base/memory/singleton.h" +#include "components/keyed_service/content/browser_context_keyed_service_factory.h" + +class ArcAppListPrefs; + +class ArcAppListPrefsFactory : public BrowserContextKeyedServiceFactory { + public: + static ArcAppListPrefs* GetForBrowserContext( + content::BrowserContext* context); + + static ArcAppListPrefsFactory* GetInstance(); + + private: + friend struct base::DefaultSingletonTraits<ArcAppListPrefsFactory>; + + ArcAppListPrefsFactory(); + ~ArcAppListPrefsFactory() override; + + KeyedService* BuildServiceInstanceFor( + content::BrowserContext* context) const override; + content::BrowserContext* GetBrowserContextToUse( + content::BrowserContext* context) const override; + + DISALLOW_COPY_AND_ASSIGN(ArcAppListPrefsFactory); +}; + +#endif // CHROME_BROWSER_UI_APP_LIST_ARC_ARC_APP_LIST_PREFS_FACTORY_H_
diff --git a/chrome/browser/ui/app_list/arc/arc_app_model_builder.cc b/chrome/browser/ui/app_list/arc/arc_app_model_builder.cc new file mode 100644 index 0000000..445f935 --- /dev/null +++ b/chrome/browser/ui/app_list/arc/arc_app_model_builder.cc
@@ -0,0 +1,84 @@ +// 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. + +#include "chrome/browser/ui/app_list/arc/arc_app_model_builder.h" + +#include "chrome/browser/profiles/profile.h" +#include "chrome/browser/ui/app_list/arc/arc_app_item.h" + +ArcAppModelBuilder::ArcAppModelBuilder(AppListControllerDelegate* controller) + : AppListModelBuilder(controller, ArcAppItem::kItemType) { +} + +ArcAppModelBuilder::~ArcAppModelBuilder() { + prefs_->RemoveObserver(this); +} + +void ArcAppModelBuilder::BuildModel() { + prefs_ = ArcAppListPrefs::Get(profile()); + + std::vector<std::string> app_ids = prefs_->GetAppIds(); + for (auto& app_id : app_ids) { + scoped_ptr<ArcAppListPrefs::AppInfo> app_info = prefs_->GetApp(app_id); + if (!app_info) + continue; + + InsertApp(CreateApp(app_id, *app_info)); + } + + prefs_->AddObserver(this); +} + +ArcAppItem* ArcAppModelBuilder::GetArcAppItem(const std::string& app_id) { + return static_cast<ArcAppItem*>(GetAppItem(app_id)); +} + +scoped_ptr<ArcAppItem> ArcAppModelBuilder::CreateApp( + const std::string& app_id, + const ArcAppListPrefs::AppInfo& app_info) { + return make_scoped_ptr(new ArcAppItem(profile(), + GetSyncItem(app_id), + app_id, + app_info.name, + app_info.ready)); +} + +void ArcAppModelBuilder::OnAppRegistered( + const std::string& app_id, + const ArcAppListPrefs::AppInfo& app_info) { + InsertApp(CreateApp(app_id, app_info)); +} + +void ArcAppModelBuilder::OnAppReadyChanged(const std::string& app_id, + bool ready) { + ArcAppItem* app_item = GetArcAppItem(app_id); + if (!app_item) { + VLOG(2) << "Could not update the state of ARC app(" << app_id + << ") because it was not found."; + return; + } + + app_item->SetReady(ready); +} + +void ArcAppModelBuilder::OnAppIconUpdated(const std::string& app_id, + ui::ScaleFactor scale_factor) { + ArcAppItem* app_item = GetArcAppItem(app_id); + if (!app_item) { + VLOG(2) << "Could not update the icon of ARC app(" << app_id + << ") because it was not found."; + return; + } + + // Initiate async icon reloading. + app_item->arc_app_icon()->LoadForScaleFactor(scale_factor); +} + +void ArcAppModelBuilder::OnListItemMoved(size_t from_index, + size_t to_index, + app_list::AppListItem* item) { + // On ChromeOS we expect that ArcAppModelBuilder is initialized with + // AppListSyncableService and in this case this observer is not used. + NOTREACHED(); +}
diff --git a/chrome/browser/ui/app_list/arc/arc_app_model_builder.h b/chrome/browser/ui/app_list/arc/arc_app_model_builder.h new file mode 100644 index 0000000..04439c7 --- /dev/null +++ b/chrome/browser/ui/app_list/arc/arc_app_model_builder.h
@@ -0,0 +1,51 @@ +// 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. + +#ifndef CHROME_BROWSER_UI_APP_LIST_ARC_ARC_APP_MODEL_BUILDER_H_ +#define CHROME_BROWSER_UI_APP_LIST_ARC_ARC_APP_MODEL_BUILDER_H_ + +#include <string> + +#include "base/macros.h" +#include "base/memory/scoped_ptr.h" +#include "chrome/browser/ui/app_list/app_list_model_builder.h" +#include "chrome/browser/ui/app_list/arc/arc_app_list_prefs.h" + +class AppListControllerDelegate; +class ArcAppItem; + +// This class populates and maintains ARC apps. +class ArcAppModelBuilder : public AppListModelBuilder, + public ArcAppListPrefs::Observer { + public: + explicit ArcAppModelBuilder(AppListControllerDelegate* controller); + ~ArcAppModelBuilder() override; + + private: + // AppListModelBuilder + void BuildModel() override; + + // ArcAppListPrefs::Observer + void OnAppRegistered(const std::string& app_id, + const ArcAppListPrefs::AppInfo& app_info) override; + void OnAppReadyChanged(const std::string& app_id, bool ready) override; + void OnAppIconUpdated(const std::string& app_id, + ui::ScaleFactor scale_factor) override; + + // AppListItemListObserver. + void OnListItemMoved(size_t from_index, + size_t to_index, + app_list::AppListItem* item) override; + + scoped_ptr<ArcAppItem> CreateApp(const std::string& app_id, + const ArcAppListPrefs::AppInfo& info); + + ArcAppItem* GetArcAppItem(const std::string& app_id); + + ArcAppListPrefs* prefs_ = nullptr; + + DISALLOW_COPY_AND_ASSIGN(ArcAppModelBuilder); +}; + +#endif // CHROME_BROWSER_UI_APP_LIST_ARC_ARC_APP_MODEL_BUILDER_H_
diff --git a/chrome/browser/ui/app_list/arc/arc_app_unittest.cc b/chrome/browser/ui/app_list/arc/arc_app_unittest.cc new file mode 100644 index 0000000..df39fe6 --- /dev/null +++ b/chrome/browser/ui/app_list/arc/arc_app_unittest.cc
@@ -0,0 +1,399 @@ +// 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. + +#include <algorithm> +#include <map> +#include <string> +#include <vector> + +#include "base/files/file_path.h" +#include "base/files/file_util.h" +#include "base/memory/scoped_vector.h" +#include "base/run_loop.h" +#include "base/strings/string_util.h" +#include "base/task_runner_util.h" +#include "chrome/browser/ui/app_list/app_list_test_util.h" +#include "chrome/browser/ui/app_list/arc/arc_app_icon.h" +#include "chrome/browser/ui/app_list/arc/arc_app_item.h" +#include "chrome/browser/ui/app_list/arc/arc_app_list_prefs.h" +#include "chrome/browser/ui/app_list/arc/arc_app_model_builder.h" +#include "chrome/browser/ui/app_list/test/test_app_list_controller_delegate.h" +#include "chrome/test/base/testing_profile.h" +#include "components/arc/arc_bridge_service.h" +#include "components/arc/test/fake_arc_bridge_service.h" +#include "content/public/browser/browser_thread.h" +#include "testing/gtest/include/gtest/gtest.h" +#include "ui/app_list/app_list_model.h" +#include "ui/gfx/image/image_skia.h" + +namespace { + +std::string GetAppId(const arc::AppInfo& app_info) { + return ArcAppListPrefs::GetAppId(app_info.package, app_info.activity); +} + +} // namespace + +class ArcAppModelBuilderTest : public AppListTestBase { + public: + ArcAppModelBuilderTest() {} + ~ArcAppModelBuilderTest() override { + // Release profile file in order to keep right sequence. + profile_.reset(); + } + + void SetUp() override { + AppListTestBase::SetUp(); + + // Make sure we have enough data for test. + for (int i = 0; i < 3; ++i) { + arc::AppInfo app; + char buffer[16]; + base::snprintf(buffer, arraysize(buffer), "Fake App %d", i); + app.name = buffer; + base::snprintf(buffer, arraysize(buffer), "fake.app.%d", i); + app.package = buffer; + base::snprintf(buffer, arraysize(buffer), "fake.app.%d.activity", i); + app.activity = buffer; + fake_apps_.push_back(app); + } + + bridge_service_.reset(new arc::FakeArcBridgeService()); + + // Check initial conditions. + EXPECT_EQ(bridge_service_.get(), arc::ArcBridgeService::Get()); + EXPECT_EQ(true, !arc::ArcBridgeService::Get()->available()); + EXPECT_EQ(arc::ArcBridgeService::State::STOPPED, + arc::ArcBridgeService::Get()->state()); + + CreateBuilder(); + + // At this point we should have ArcAppListPrefs as observer of service. + EXPECT_EQ( + true, + bridge_service()->HasObserver(ArcAppListPrefs::Get(profile_.get()))); + } + + void TearDown() override { ResetBuilder(); } + + protected: + // Creates a new builder, destroying any existing one. + void CreateBuilder() { + ResetBuilder(); // Destroy any existing builder in the correct order. + + model_.reset(new app_list::AppListModel); + controller_.reset(new test::TestAppListControllerDelegate); + builder_.reset(new ArcAppModelBuilder(controller_.get())); + builder_->InitializeWithProfile(profile_.get(), model_.get()); + } + + void ResetBuilder() { + builder_.reset(); + controller_.reset(); + model_.reset(); + } + + size_t GetArcItemCount() const { + size_t arc_count = 0; + const size_t count = model_->top_level_item_list()->item_count(); + for (size_t i = 0; i < count; ++i) { + app_list::AppListItem* item = model_->top_level_item_list()->item_at(i); + if (item->GetItemType() == ArcAppItem::kItemType) + ++arc_count; + } + return arc_count; + } + + ArcAppItem* GetArcItem(size_t index) const { + size_t arc_count = 0; + const size_t count = model_->top_level_item_list()->item_count(); + ArcAppItem* arc_item = nullptr; + for (size_t i = 0; i < count; ++i) { + app_list::AppListItem* item = model_->top_level_item_list()->item_at(i); + if (item->GetItemType() == ArcAppItem::kItemType) { + if (arc_count++ == index) { + arc_item = reinterpret_cast<ArcAppItem*>(item); + break; + } + } + } + EXPECT_NE(nullptr, arc_item); + return arc_item; + } + + ArcAppItem* FindArcItem(const std::string& id) const { + const size_t count = GetArcItemCount(); + for (size_t i = 0; i < count; ++i) { + ArcAppItem* item = GetArcItem(i); + if (item && item->id() == id) + return item; + } + return nullptr; + } + + // Validate that prefs and model have right content. + void ValidateHaveApps(const std::vector<arc::AppInfo> apps) { + ArcAppListPrefs* prefs = ArcAppListPrefs::Get(profile_.get()); + const std::vector<std::string> ids = prefs->GetAppIds(); + ASSERT_EQ(apps.size(), ids.size()); + ASSERT_EQ(apps.size(), GetArcItemCount()); + // In principle, order of items is not defined. + for (auto& app : apps) { + const std::string id = GetAppId(app); + EXPECT_NE(std::find(ids.begin(), ids.end(), id), ids.end()); + scoped_ptr<ArcAppListPrefs::AppInfo> app_info = prefs->GetApp(id); + ASSERT_NE(nullptr, app_info.get()); + EXPECT_EQ(app.name, app_info->name); + EXPECT_EQ(app.package, app_info->package); + EXPECT_EQ(app.activity, app_info->activity); + + const ArcAppItem* app_item = FindArcItem(id); + ASSERT_NE(nullptr, app_item); + EXPECT_EQ(app.name, app_item->GetDisplayName()); + } + } + + // Validate that requested apps have required ready state and other apps have + // opposite state. + void ValidateAppReadyState(const std::vector<arc::AppInfo> apps, bool ready) { + ArcAppListPrefs* prefs = ArcAppListPrefs::Get(profile_.get()); + ASSERT_NE(nullptr, prefs); + + std::vector<std::string> ids = prefs->GetAppIds(); + EXPECT_EQ(ids.size(), GetArcItemCount()); + + // Process requested apps. + for (auto& app : apps) { + const std::string id = GetAppId(app); + std::vector<std::string>::iterator it_id = std::find(ids.begin(), + ids.end(), + id); + ASSERT_NE(it_id, ids.end()); + ids.erase(it_id); + + scoped_ptr<ArcAppListPrefs::AppInfo> app_info = prefs->GetApp(id); + ASSERT_NE(nullptr, app_info.get()); + EXPECT_EQ(ready, app_info->ready); + const ArcAppItem* app_item = FindArcItem(id); + ASSERT_NE(nullptr, app_item); + EXPECT_EQ(ready, app_item->ready()); + } + + // Process the rest of the apps. + for (auto& id : ids) { + scoped_ptr<ArcAppListPrefs::AppInfo> app_info = prefs->GetApp(id); + ASSERT_NE(nullptr, app_info.get()); + EXPECT_NE(ready, app_info->ready); + const ArcAppItem* app_item = FindArcItem(id); + ASSERT_NE(nullptr, app_item); + EXPECT_NE(ready, app_item->ready()); + } + + } + + arc::FakeArcBridgeService* bridge_service() { return bridge_service_.get(); } + + const std::vector<arc::AppInfo>& fake_apps() const { return fake_apps_; } + + private: + scoped_ptr<app_list::AppListModel> model_; + scoped_ptr<test::TestAppListControllerDelegate> controller_; + scoped_ptr<ArcAppModelBuilder> builder_; + scoped_ptr<arc::FakeArcBridgeService> bridge_service_; + std::vector<arc::AppInfo> fake_apps_; + + DISALLOW_COPY_AND_ASSIGN(ArcAppModelBuilderTest); +}; + +TEST_F(ArcAppModelBuilderTest, RefreshAllOnReady) { + EXPECT_EQ(0, bridge_service()->refresh_app_list_count()); + bridge_service()->SetReady(); + EXPECT_EQ(1, bridge_service()->refresh_app_list_count()); +} + +TEST_F(ArcAppModelBuilderTest, RefreshAllFillsContent) { + ValidateHaveApps(std::vector<arc::AppInfo>()); + bridge_service()->SetReady(); + bridge_service()->SendRefreshAppList(fake_apps()); + ValidateHaveApps(fake_apps()); +} + +TEST_F(ArcAppModelBuilderTest, MultipleRefreshAll) { + ValidateHaveApps(std::vector<arc::AppInfo>()); + bridge_service()->SetReady(); + // Send info about all fake apps except last. + std::vector<arc::AppInfo> apps1(fake_apps().begin(), fake_apps().end() - 1); + bridge_service()->SendRefreshAppList(apps1); + // At this point all apps (except last) should exist and be ready. + ValidateHaveApps(apps1); + ValidateAppReadyState(apps1, true); + + // Send info about all fake apps except first. + std::vector<arc::AppInfo> apps2(fake_apps().begin() + 1, fake_apps().end()); + bridge_service()->SendRefreshAppList(apps2); + // At this point all apps should exist but first one should be non-ready. + ValidateHaveApps(fake_apps()); + ValidateAppReadyState(apps2, true); + + // Send info about all fake apps. + bridge_service()->SendRefreshAppList(fake_apps()); + // At this point all apps should exist and be ready. + ValidateHaveApps(fake_apps()); + ValidateAppReadyState(fake_apps(), true); + + // Send info no app available. + bridge_service()->SendRefreshAppList(std::vector<arc::AppInfo>()); + // At this point all apps should exist and be non-ready. + ValidateHaveApps(fake_apps()); + ValidateAppReadyState(fake_apps(), false); +} + +TEST_F(ArcAppModelBuilderTest, StopServiceDisablesApps) { + ArcAppListPrefs* prefs = ArcAppListPrefs::Get(profile_.get()); + ASSERT_NE(nullptr, prefs); + + bridge_service()->SetReady(); + EXPECT_EQ(static_cast<size_t>(0), GetArcItemCount()); + EXPECT_EQ(static_cast<size_t>(0), prefs->GetAppIds().size()); + + bridge_service()->SendRefreshAppList(fake_apps()); + std::vector<std::string> ids = prefs->GetAppIds(); + EXPECT_EQ(fake_apps().size(), ids.size()); + ValidateAppReadyState(fake_apps(), true); + + // Stopping service does not delete items. It makes them non-ready. + bridge_service()->SetStopped(); + // Ids should be the same. + EXPECT_EQ(ids, prefs->GetAppIds()); + ValidateAppReadyState(fake_apps(), false); +} + +TEST_F(ArcAppModelBuilderTest, LaunchApps) { + bridge_service()->SetReady(); + bridge_service()->SendRefreshAppList(fake_apps()); + + // Simulate item activate. + const arc::AppInfo& app_first = fake_apps()[0]; + const arc::AppInfo& app_last = fake_apps()[0]; + ArcAppItem* item_first = FindArcItem(GetAppId(app_first)); + ArcAppItem* item_last = FindArcItem(GetAppId(app_last)); + ASSERT_NE(nullptr, item_first); + ASSERT_NE(nullptr, item_last); + item_first->Activate(0); + item_last->Activate(0); + item_first->Activate(0); + + const ScopedVector<arc::FakeArcBridgeService::Request>& launch_requests = + bridge_service()->launch_requests(); + EXPECT_EQ(static_cast<size_t>(3), launch_requests.size()); + EXPECT_EQ(true, launch_requests[0]->IsForApp(app_first)); + EXPECT_EQ(true, launch_requests[1]->IsForApp(app_last)); + EXPECT_EQ(true, launch_requests[2]->IsForApp(app_first)); +} + +TEST_F(ArcAppModelBuilderTest, RequestIcons) { + // Make sure we are on UI thread. + ASSERT_EQ(true, + content::BrowserThread::CurrentlyOn(content::BrowserThread::UI)); + + bridge_service()->SetReady(); + bridge_service()->SendRefreshAppList(fake_apps()); + + // Validate that no icon exists at the beginning and request icon for + // each supported scale factor. This will start asynchronous loading. + uint32_t expected_mask = 0; + const std::vector<ui::ScaleFactor>& scale_factors = + ui::GetSupportedScaleFactors(); + for (auto& scale_factor : scale_factors) { + expected_mask |= 1 << scale_factor; + for (auto& app : fake_apps()) { + ArcAppItem* app_item = FindArcItem(GetAppId(app)); + ASSERT_NE(nullptr, app_item); + const float scale = ui::GetScaleForScaleFactor(scale_factor); + app_item->icon().GetRepresentation(scale); + } + } + + // Process pending tasks. + content::BrowserThread::GetBlockingPool()->FlushForTesting(); + base::RunLoop().RunUntilIdle(); + + // At this moment we should receive all requests for icon loading. + const ScopedVector<arc::FakeArcBridgeService::IconRequest>& icon_requests = + bridge_service()->icon_requests(); + EXPECT_EQ(scale_factors.size() * fake_apps().size(), icon_requests.size()); + std::map<std::string, uint32_t> app_masks; + for (size_t i = 0; i < icon_requests.size(); ++i) { + const arc::FakeArcBridgeService::IconRequest* icon_request = + icon_requests[i]; + const std::string id = ArcAppListPrefs::GetAppId(icon_request->package(), + icon_request->activity()); + // Make sure no double requests. + EXPECT_NE(app_masks[id], + app_masks[id] | (1 << icon_request->scale_factor())); + app_masks[id] |= (1 << icon_request->scale_factor()); + } + + // Validate that we have a request for each icon for each supported scale + // factor. + EXPECT_EQ(fake_apps().size(), app_masks.size()); + for (auto& app : fake_apps()) { + const std::string id = GetAppId(app); + ASSERT_NE(app_masks.find(id), app_masks.end()); + EXPECT_EQ(app_masks[id], expected_mask); + } +} + +TEST_F(ArcAppModelBuilderTest, InstallIcon) { + // Make sure we are on UI thread. + ASSERT_EQ(true, + content::BrowserThread::CurrentlyOn(content::BrowserThread::UI)); + + + bridge_service()->SetReady(); + bridge_service()->SendRefreshAppList(std::vector<arc::AppInfo>( + fake_apps().begin(), fake_apps().begin() + 1)); + const arc::AppInfo& app = fake_apps()[0]; + + ArcAppListPrefs* prefs = ArcAppListPrefs::Get(profile_.get()); + ASSERT_NE(nullptr, prefs); + + const ui::ScaleFactor scale_factor = ui::GetSupportedScaleFactors()[0]; + const float scale = ui::GetScaleForScaleFactor(scale_factor); + const base::FilePath icon_path = prefs->GetIconPath(GetAppId(app), + scale_factor); + EXPECT_EQ(true, !base::PathExists(icon_path)); + + const ArcAppItem* app_item = FindArcItem(GetAppId(app)); + EXPECT_NE(nullptr, app_item); + // This initiates async loading. + app_item->icon().GetRepresentation(scale); + + // Process pending tasks. + content::BrowserThread::GetBlockingPool()->FlushForTesting(); + base::RunLoop().RunUntilIdle(); + + // Validating decoded content does not fit well for unit tests. + ArcAppIcon::DisableDecodingForTesting(); + + // Now send generated icon for the app. + std::string png_data; + EXPECT_EQ(true, bridge_service()->GenerateAndSendIcon( + app, + static_cast<arc::ScaleFactor>(scale_factor), + &png_data)); + + // Process pending tasks. + content::BrowserThread::GetBlockingPool()->FlushForTesting(); + base::RunLoop().RunUntilIdle(); + + // Validate that icons are installed, have right content and icon is + // refreshed for ARC app item. + EXPECT_EQ(true, base::PathExists(icon_path)); + + std::string icon_data; + // Read the file from disk and compare with reference data. + EXPECT_EQ(true, base::ReadFileToString(icon_path, &icon_data)); + ASSERT_EQ(icon_data, png_data); +}
diff --git a/chrome/browser/ui/app_list/extension_app_model_builder.cc b/chrome/browser/ui/app_list/extension_app_model_builder.cc index ec4c287..2956f97 100644 --- a/chrome/browser/ui/app_list/extension_app_model_builder.cc +++ b/chrome/browser/ui/app_list/extension_app_model_builder.cc
@@ -12,11 +12,9 @@ #include "chrome/browser/extensions/extension_ui_util.h" #include "chrome/browser/extensions/extension_util.h" #include "chrome/browser/extensions/install_tracker.h" -#include "chrome/browser/extensions/install_tracker_factory.h" #include "chrome/browser/profiles/profile.h" #include "chrome/browser/ui/app_list/app_list_controller_delegate.h" #include "chrome/browser/ui/app_list/app_list_syncable_service.h" -#include "chrome/browser/ui/app_list/app_list_syncable_service_factory.h" #include "chrome/browser/ui/app_list/extension_app_item.h" #include "chrome/common/pref_names.h" #include "extensions/browser/extension_prefs.h" @@ -34,47 +32,16 @@ ExtensionAppModelBuilder::ExtensionAppModelBuilder( AppListControllerDelegate* controller) - : service_(NULL), - profile_(NULL), - controller_(controller), - model_(NULL), - tracker_(NULL), - extension_registry_(NULL) { + : AppListModelBuilder(controller, ExtensionAppItem::kItemType) { } ExtensionAppModelBuilder::~ExtensionAppModelBuilder() { OnShutdown(); OnShutdown(extension_registry_); - if (!service_) - model_->top_level_item_list()->RemoveObserver(this); -} - -void ExtensionAppModelBuilder::InitializeWithService( - app_list::AppListSyncableService* service, - app_list::AppListModel* model) { - DCHECK(!service_ && !profile_); - model_ = model; - service_ = service; - profile_ = service->profile(); - InitializePrefChangeRegistrars(); - - BuildModel(); -} - -void ExtensionAppModelBuilder::InitializeWithProfile( - Profile* profile, - app_list::AppListModel* model) { - DCHECK(!service_ && !profile_); - model_ = model; - model_->top_level_item_list()->AddObserver(this); - profile_ = profile; - InitializePrefChangeRegistrars(); - - BuildModel(); } void ExtensionAppModelBuilder::InitializePrefChangeRegistrars() { - profile_pref_change_registrar_.Init(profile_->GetPrefs()); + profile_pref_change_registrar_.Init(profile()->GetPrefs()); profile_pref_change_registrar_.Add( prefs::kHideWebStoreIcon, base::Bind(&ExtensionAppModelBuilder::OnProfilePreferenceChanged, @@ -88,7 +55,7 @@ extensions::ExtensionsBrowserClient* client = extensions::ExtensionsBrowserClient::Get(); extension_pref_change_registrar_.Init( - client->GetPrefServiceForContext(profile_)); + client->GetPrefServiceForContext(profile())); extension_pref_change_registrar_.Add( extensions::pref_names::kExtensions, base::Bind(&ExtensionAppModelBuilder::OnExtensionPreferenceChanged, @@ -97,13 +64,13 @@ void ExtensionAppModelBuilder::OnProfilePreferenceChanged() { extensions::ExtensionSet extensions; - controller_->GetApps(profile_, &extensions); + controller()->GetApps(profile(), &extensions); for (extensions::ExtensionSet::const_iterator app = extensions.begin(); app != extensions.end(); ++app) { bool should_display = - extensions::ui_util::ShouldDisplayInAppLauncher(app->get(), profile_); - bool does_display = GetExtensionAppItem((*app)->id()) != NULL; + extensions::ui_util::ShouldDisplayInAppLauncher(app->get(), profile()); + bool does_display = GetExtensionAppItem((*app)->id()) != nullptr; if (should_display == does_display) continue; @@ -114,16 +81,16 @@ gfx::ImageSkia(), (*app)->is_platform_app())); } else { - if (service_) - service_->RemoveItem((*app)->id()); + if (service()) + service()->RemoveItem((*app)->id()); else - model_->DeleteItem((*app)->id()); + model()->DeleteItem((*app)->id()); } } } void ExtensionAppModelBuilder::OnExtensionPreferenceChanged() { - model_->NotifyExtensionPreferenceChanged(); + model()->NotifyExtensionPreferenceChanged(); } void ExtensionAppModelBuilder::OnBeginExtensionInstall( @@ -131,7 +98,7 @@ if (!params.is_app) return; - DVLOG(2) << service_ << ": OnBeginExtensionInstall: " + DVLOG(2) << service() << ": OnBeginExtensionInstall: " << params.extension_id.substr(0, 8); ExtensionAppItem* existing_item = GetExtensionAppItem(params.extension_id); if (existing_item) { @@ -164,22 +131,22 @@ void ExtensionAppModelBuilder::OnInstallFailure( const std::string& extension_id) { - model_->DeleteItem(extension_id); + model()->DeleteItem(extension_id); } void ExtensionAppModelBuilder::OnExtensionLoaded( content::BrowserContext* browser_context, const extensions::Extension* extension) { - if (!extensions::ui_util::ShouldDisplayInAppLauncher(extension, profile_)) + if (!extensions::ui_util::ShouldDisplayInAppLauncher(extension, profile())) return; - DVLOG(2) << service_ << ": OnExtensionLoaded: " + DVLOG(2) << service() << ": OnExtensionLoaded: " << extension->id().substr(0, 8); ExtensionAppItem* existing_item = GetExtensionAppItem(extension->id()); if (existing_item) { existing_item->Reload(); - if (service_) - service_->UpdateItem(existing_item); + if (service()) + service()->UpdateItem(existing_item); return; } @@ -203,18 +170,18 @@ content::BrowserContext* browser_context, const extensions::Extension* extension, extensions::UninstallReason reason) { - if (service_) { - DVLOG(2) << service_ << ": OnExtensionUninstalled: " + if (service()) { + DVLOG(2) << service() << ": OnExtensionUninstalled: " << extension->id().substr(0, 8); - service_->RemoveUninstalledItem(extension->id()); + service()->RemoveUninstalledItem(extension->id()); return; } - model_->DeleteUninstalledItem(extension->id()); + model()->DeleteUninstalledItem(extension->id()); } void ExtensionAppModelBuilder::OnDisabledExtensionUpdated( const Extension* extension) { - if (!extensions::ui_util::ShouldDisplayInAppLauncher(extension, profile_)) + if (!extensions::ui_util::ShouldDisplayInAppLauncher(extension, profile())) return; ExtensionAppItem* existing_item = GetExtensionAppItem(extension->id()); @@ -225,7 +192,7 @@ void ExtensionAppModelBuilder::OnShutdown() { if (tracker_) { tracker_->RemoveObserver(this); - tracker_ = NULL; + tracker_ = nullptr; } } @@ -236,7 +203,7 @@ DCHECK_EQ(extension_registry_, registry); extension_registry_->RemoveObserver(this); - extension_registry_ = NULL; + extension_registry_ = nullptr; } scoped_ptr<ExtensionAppItem> ExtensionAppModelBuilder::CreateAppItem( @@ -244,10 +211,8 @@ const std::string& extension_name, const gfx::ImageSkia& installing_icon, bool is_platform_app) { - const app_list::AppListSyncableService::SyncItem* sync_item = - service_ ? service_->GetSyncItem(extension_id) : NULL; - return make_scoped_ptr(new ExtensionAppItem(profile_, - sync_item, + return make_scoped_ptr(new ExtensionAppItem(profile(), + GetSyncItem(extension_id), extension_id, extension_name, installing_icon, @@ -256,8 +221,11 @@ void ExtensionAppModelBuilder::BuildModel() { DCHECK(!tracker_); - tracker_ = controller_->GetInstallTrackerFor(profile_); - extension_registry_ = extensions::ExtensionRegistry::Get(profile_); + + InitializePrefChangeRegistrars(); + + tracker_ = controller()->GetInstallTrackerFor(profile()); + extension_registry_ = extensions::ExtensionRegistry::Get(profile()); PopulateApps(); @@ -271,11 +239,11 @@ void ExtensionAppModelBuilder::PopulateApps() { extensions::ExtensionSet extensions; - controller_->GetApps(profile_, &extensions); + controller()->GetApps(profile(), &extensions); for (extensions::ExtensionSet::const_iterator app = extensions.begin(); app != extensions.end(); ++app) { - if (!extensions::ui_util::ShouldDisplayInAppLauncher(app->get(), profile_)) + if (!extensions::ui_util::ShouldDisplayInAppLauncher(app->get(), profile())) continue; InsertApp(CreateAppItem((*app)->id(), "", @@ -284,36 +252,23 @@ } } -void ExtensionAppModelBuilder::InsertApp(scoped_ptr<ExtensionAppItem> app) { - if (service_) { - service_->AddItem(app.Pass()); - return; - } - model_->AddItem(app.Pass()); -} - ExtensionAppItem* ExtensionAppModelBuilder::GetExtensionAppItem( const std::string& extension_id) { - app_list::AppListItem* item = model_->FindItem(extension_id); - LOG_IF(ERROR, item && - item->GetItemType() != ExtensionAppItem::kItemType) - << "App Item matching id: " << extension_id - << " has incorrect type: '" << item->GetItemType() << "'"; - return static_cast<ExtensionAppItem*>(item); + return static_cast<ExtensionAppItem*>(GetAppItem(extension_id)); } void ExtensionAppModelBuilder::OnListItemMoved(size_t from_index, size_t to_index, app_list::AppListItem* item) { - DCHECK(!service_); + DCHECK(!service()); // This will get called from AppListItemList::ListItemMoved after // set_position is called for the item. if (item->GetItemType() != ExtensionAppItem::kItemType) return; - app_list::AppListItemList* item_list = model_->top_level_item_list(); - ExtensionAppItem* prev = NULL; + app_list::AppListItemList* item_list = model()->top_level_item_list(); + ExtensionAppItem* prev = nullptr; for (size_t idx = to_index; idx > 0; --idx) { app_list::AppListItem* item = item_list->item_at(idx - 1); if (item->GetItemType() == ExtensionAppItem::kItemType) { @@ -321,7 +276,7 @@ break; } } - ExtensionAppItem* next = NULL; + ExtensionAppItem* next = nullptr; for (size_t idx = to_index; idx < item_list->item_count() - 1; ++idx) { app_list::AppListItem* item = item_list->item_at(idx + 1); if (item->GetItemType() == ExtensionAppItem::kItemType) {
diff --git a/chrome/browser/ui/app_list/extension_app_model_builder.h b/chrome/browser/ui/app_list/extension_app_model_builder.h index 8b327e2..9303e38 100644 --- a/chrome/browser/ui/app_list/extension_app_model_builder.h +++ b/chrome/browser/ui/app_list/extension_app_model_builder.h
@@ -1,4 +1,4 @@ -// Copyright (c) 2012 The Chromium Authors. All rights reserved. +// Copyright 2012 The Chromium Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. @@ -9,19 +9,13 @@ #include <vector> #include "base/prefs/pref_change_registrar.h" -#include "base/scoped_observer.h" #include "chrome/browser/extensions/install_observer.h" +#include "chrome/browser/ui/app_list/app_list_model_builder.h" #include "extensions/browser/extension_registry_observer.h" -#include "ui/app_list/app_list_model.h" #include "ui/base/models/list_model_observer.h" class AppListControllerDelegate; class ExtensionAppItem; -class Profile; - -namespace app_list { -class AppListSyncableService; -} namespace extensions { class Extension; @@ -34,28 +28,20 @@ class ImageSkia; } -// This class populates and maintains the given |model| with information from -// |profile|. -class ExtensionAppModelBuilder : public extensions::InstallObserver, - public extensions::ExtensionRegistryObserver, - public app_list::AppListItemListObserver { +// This class populates and maintains the given |model| for extension items +// with information from |profile|. +class ExtensionAppModelBuilder : public AppListModelBuilder, + public extensions::InstallObserver, + public extensions::ExtensionRegistryObserver { public: explicit ExtensionAppModelBuilder(AppListControllerDelegate* controller); ~ExtensionAppModelBuilder() override; - // Initialize to use app-list sync and sets |service_| to |service|. - void InitializeWithService(app_list::AppListSyncableService* service, - app_list::AppListModel* model); - - // Initialize to use extension sync and sets |service_| to NULL. Used in - // tests and when AppList sync is not enabled. - void InitializeWithProfile(Profile* profile, app_list::AppListModel* model); - private: typedef std::vector<ExtensionAppItem*> ExtensionAppList; - // Builds the model with the current profile. - void BuildModel(); + // AppListModelBuilder + void BuildModel() override; // extensions::InstallObserver. void OnBeginExtensionInstall(const ExtensionInstallParams& params) override; @@ -92,9 +78,6 @@ // Populates the model with apps. void PopulateApps(); - // Inserts an app based on app ordinal prefs. - void InsertApp(scoped_ptr<ExtensionAppItem> app); - // Returns app instance matching |extension_id| or NULL. ExtensionAppItem* GetExtensionAppItem(const std::string& extension_id); @@ -110,27 +93,17 @@ // Handles extension prefs changes. void OnExtensionPreferenceChanged(); - // Unowned pointers to the service that owns this and associated profile. - app_list::AppListSyncableService* service_; - Profile* profile_; - // Registrar used to monitor the profile prefs. PrefChangeRegistrar profile_pref_change_registrar_; // Registrar used to monitor the extension prefs. PrefChangeRegistrar extension_pref_change_registrar_; - // Unowned pointer to the app list controller. - AppListControllerDelegate* controller_; - - // Unowned pointer to the app list model. - app_list::AppListModel* model_; - // We listen to this to show app installing progress. - extensions::InstallTracker* tracker_; + extensions::InstallTracker* tracker_ = nullptr; // Listen extension's load, unload, uninstalled. - extensions::ExtensionRegistry* extension_registry_; + extensions::ExtensionRegistry* extension_registry_ = nullptr; DISALLOW_COPY_AND_ASSIGN(ExtensionAppModelBuilder); };
diff --git a/chrome/browser/ui/autofill/chrome_autofill_client.cc b/chrome/browser/ui/autofill/chrome_autofill_client.cc index 0646736..35c9573 100644 --- a/chrome/browser/ui/autofill/chrome_autofill_client.cc +++ b/chrome/browser/ui/autofill/chrome_autofill_client.cc
@@ -26,6 +26,7 @@ #include "chrome/browser/ui/chrome_pages.h" #include "chrome/browser/ui/tabs/tab_strip_model_observer.h" #include "chrome/browser/web_data_service_factory.h" +#include "chrome/common/features.h" #include "chrome/common/url_constants.h" #include "components/autofill/content/browser/content_autofill_driver.h" #include "components/autofill/content/common/autofill_messages.h" @@ -39,7 +40,7 @@ #include "content/public/browser/render_frame_host.h" #include "ui/gfx/geometry/rect.h" -#if defined(OS_ANDROID) +#if BUILDFLAG(ANDROID_JAVA_UI) #include "chrome/browser/android/chrome_application.h" #include "chrome/browser/ui/android/autofill/autofill_logger_android.h" #else @@ -60,7 +61,7 @@ last_rfh_to_rac_(nullptr) { DCHECK(web_contents); -#if !defined(OS_ANDROID) +#if !BUILDFLAG(ANDROID_JAVA_UI) // Since ZoomController is also a WebContentsObserver, we need to be careful // about disconnecting from it since the relative order of destruction of // WebContentsObservers is not guaranteed. ZoomController silently clears @@ -112,7 +113,7 @@ Profile::FromBrowserContext(web_contents()->GetBrowserContext()) ->GetOriginalProfile(); base::Closure login_callback; -#if !defined(OS_ANDROID) +#if !BUILDFLAG(ANDROID_JAVA_UI) login_callback = LoginUIServiceFactory::GetShowLoginPopupCallbackForProfile(profile); #endif @@ -130,13 +131,13 @@ } void ChromeAutofillClient::ShowAutofillSettings() { -#if defined(OS_ANDROID) +#if BUILDFLAG(ANDROID_JAVA_UI) chrome::android::ChromeApplication::ShowAutofillSettings(); #else Browser* browser = chrome::FindBrowserWithWebContents(web_contents()); if (browser) chrome::ShowSettingsSubPage(browser, chrome::kAutofillSubPage); -#endif // #if defined(OS_ANDROID) +#endif // #if BUILDFLAG(ANDROID_JAVA_UI) } void ChromeAutofillClient::ShowUnmaskPrompt( @@ -279,7 +280,7 @@ } void ChromeAutofillClient::MainFrameWasResized(bool width_changed) { -#if defined(OS_ANDROID) +#if BUILDFLAG(ANDROID_JAVA_UI) // Ignore virtual keyboard showing and hiding a strip of suggestions. if (!width_changed) return; @@ -312,10 +313,10 @@ void ChromeAutofillClient::DidFillOrPreviewField( const base::string16& autofilled_value, const base::string16& profile_full_name) { -#if defined(OS_ANDROID) +#if BUILDFLAG(ANDROID_JAVA_UI) AutofillLoggerAndroid::DidFillOrPreviewField(autofilled_value, profile_full_name); -#endif // defined(OS_ANDROID) +#endif // BUILDFLAG(ANDROID_JAVA_UI) } void ChromeAutofillClient::OnFirstUserGestureObserved() {
diff --git a/chrome/browser/ui/autofill/credit_card_scanner_view.cc b/chrome/browser/ui/autofill/credit_card_scanner_view.cc index 0f6e5b6..0d1bb08a 100644 --- a/chrome/browser/ui/autofill/credit_card_scanner_view.cc +++ b/chrome/browser/ui/autofill/credit_card_scanner_view.cc
@@ -3,11 +3,12 @@ // found in the LICENSE file. #include "chrome/browser/ui/autofill/credit_card_scanner_view.h" +#include "chrome/common/features.h" namespace autofill { // Not implemented on other platforms yet. -#if !defined(OS_ANDROID) +#if !BUILDFLAG(ANDROID_JAVA_UI) // static bool CreditCardScannerView::CanShow() { return false;
diff --git a/chrome/browser/ui/autofill/password_generation_popup_controller_impl.cc b/chrome/browser/ui/autofill/password_generation_popup_controller_impl.cc index bdc57b8..bc8b0ea 100644 --- a/chrome/browser/ui/autofill/password_generation_popup_controller_impl.cc +++ b/chrome/browser/ui/autofill/password_generation_popup_controller_impl.cc
@@ -18,6 +18,7 @@ #include "chrome/browser/ui/autofill/popup_constants.h" #include "chrome/browser/ui/browser_finder.h" #include "chrome/browser/ui/chrome_pages.h" +#include "chrome/common/features.h" #include "chrome/common/url_constants.h" #include "chrome/grit/chromium_strings.h" #include "chrome/grit/generated_resources.h" @@ -34,7 +35,7 @@ #include "ui/gfx/geometry/rect_conversions.h" #include "ui/gfx/text_utils.h" -#if defined(OS_ANDROID) +#if BUILDFLAG(ANDROID_JAVA_UI) #include "chrome/browser/android/chrome_application.h" #endif @@ -232,7 +233,7 @@ } void PasswordGenerationPopupControllerImpl::OnSavedPasswordsLinkClicked() { -#if defined(OS_ANDROID) +#if BUILDFLAG(ANDROID_JAVA_UI) chrome::android::ChromeApplication::ShowPasswordSettings(); #else chrome::ShowSettingsSubPage(
diff --git a/chrome/browser/ui/blocked_content/popup_blocker_tab_helper.cc b/chrome/browser/ui/blocked_content/popup_blocker_tab_helper.cc index ac28874..95f2a61 100644 --- a/chrome/browser/ui/blocked_content/popup_blocker_tab_helper.cc +++ b/chrome/browser/ui/blocked_content/popup_blocker_tab_helper.cc
@@ -12,6 +12,7 @@ #include "chrome/browser/ui/browser_navigator.h" #include "chrome/browser/ui/browser_navigator_params.h" #include "chrome/browser/ui/tabs/tab_strip_model.h" +#include "chrome/common/features.h" #include "chrome/common/render_messages.h" #include "components/content_settings/core/browser/host_content_settings_map.h" #include "content/public/browser/navigation_controller.h" @@ -22,7 +23,7 @@ #include "content/public/browser/web_contents_delegate.h" #include "third_party/WebKit/public/web/WebWindowFeatures.h" -#if defined(OS_ANDROID) +#if BUILDFLAG(ANDROID_JAVA_UI) #include "chrome/browser/ui/android/tab_model/tab_model_list.h" #endif @@ -120,7 +121,7 @@ return; // We set user_gesture to true here, so the new popup gets correctly focused. popup->params.user_gesture = true; -#if defined(OS_ANDROID) +#if BUILDFLAG(ANDROID_JAVA_UI) TabModelList::HandlePopupNavigation(&popup->params); #else chrome::Navigate(&popup->params);
diff --git a/chrome/browser/ui/browser_browsertest.cc b/chrome/browser/ui/browser_browsertest.cc index 5857df7..5226b856 100644 --- a/chrome/browser/ui/browser_browsertest.cc +++ b/chrome/browser/ui/browser_browsertest.cc
@@ -3126,9 +3126,7 @@ class BrowserTestNonsecureURLRequest : public BrowserTest { public: - // TODO(thakis): Add back the `: BrowserTest()` once - // http://llvm.org/PR25370 is fixed, http://crbug.com/549765 - BrowserTestNonsecureURLRequest() /* : BrowserTest() */ {} + BrowserTestNonsecureURLRequest() : BrowserTest() {} void SetUpOnMainThread() override { base::FilePath root_http; PathService::Get(chrome::DIR_TEST_DATA, &root_http);
diff --git a/chrome/browser/ui/browser_command_controller.cc b/chrome/browser/ui/browser_command_controller.cc index b6f7942..ac6ec7d 100644 --- a/chrome/browser/ui/browser_command_controller.cc +++ b/chrome/browser/ui/browser_command_controller.cc
@@ -7,6 +7,7 @@ #include <string> #include "base/command_line.h" +#include "base/debug/debugging_flags.h" #include "base/prefs/pref_service.h" #include "chrome/app/chrome_command_ids.h" #include "chrome/browser/browser_process.h" @@ -1279,7 +1280,7 @@ command_updater_.UpdateCommandEnabled(IDC_VIEW_PASSWORDS, show_main_ui); command_updater_.UpdateCommandEnabled(IDC_ABOUT, show_main_ui); command_updater_.UpdateCommandEnabled(IDC_SHOW_APP_MENU, show_main_ui); -#if defined (ENABLE_PROFILING) && !defined(NO_TCMALLOC) +#if BUILDFLAG(ENABLE_PROFILING) && !defined(NO_TCMALLOC) command_updater_.UpdateCommandEnabled(IDC_PROFILING_ENABLED, show_main_ui); #endif
diff --git a/chrome/browser/ui/cocoa/location_bar/page_action_decoration.mm b/chrome/browser/ui/cocoa/location_bar/page_action_decoration.mm index a911f4a..8a045c9 100644 --- a/chrome/browser/ui/cocoa/location_bar/page_action_decoration.mm +++ b/chrome/browser/ui/cocoa/location_bar/page_action_decoration.mm
@@ -50,10 +50,9 @@ PageActionDecoration::~PageActionDecoration() {} -// Always |kPageActionIconMaxSize| wide. |ImageDecoration| draws the -// image centered. +// Always |ActionIconSize| wide. |ImageDecoration| draws the image centered. CGFloat PageActionDecoration::GetWidthForSpace(CGFloat width) { - return ExtensionAction::kPageActionIconMaxSize; + return ExtensionAction::ActionIconSize(); } bool PageActionDecoration::AcceptsMousePress() { @@ -93,8 +92,8 @@ SetToolTip(viewController_->GetTooltip(contents)); // Set the image. - gfx::Size size(ExtensionAction::kPageActionIconMaxSize, - ExtensionAction::kPageActionIconMaxSize); + gfx::Size size(ExtensionAction::ActionIconSize(), + ExtensionAction::ActionIconSize()); gfx::Image icon = viewController_->GetIcon(contents, size); if (!icon.IsEmpty()) { SetImage(icon.ToNSImage()); @@ -120,7 +119,7 @@ // easier (the middle of the centered image is the middle of the // frame). const CGFloat delta_height = - NSHeight(frame) - ExtensionAction::kPageActionIconMaxSize; + NSHeight(frame) - ExtensionAction::ActionIconSize(); const CGFloat bottom_inset = std::ceil(delta_height / 2.0); // Return a point just below the bottom of the maximal drawing area.
diff --git a/chrome/browser/ui/exclusive_access/exclusive_access_bubble.cc b/chrome/browser/ui/exclusive_access/exclusive_access_bubble.cc index abf28c2..fe4de872 100644 --- a/chrome/browser/ui/exclusive_access/exclusive_access_bubble.cc +++ b/chrome/browser/ui/exclusive_access/exclusive_access_bubble.cc
@@ -31,6 +31,7 @@ const int ExclusiveAccessBubble::kSlideInDurationMs = 350; const int ExclusiveAccessBubble::kSlideOutDurationMs = 700; const int ExclusiveAccessBubble::kPopupTopPx = 45; +const int ExclusiveAccessBubble::kSimplifiedPopupTopPx = 16; ExclusiveAccessBubble::ExclusiveAccessBubble( ExclusiveAccessManager* manager, @@ -43,6 +44,27 @@ ExclusiveAccessBubble::~ExclusiveAccessBubble() { } +void ExclusiveAccessBubble::OnUserInput() { + if (!ExclusiveAccessManager::IsSimplifiedFullscreenUIEnabled()) + return; + + // We got some user input; reset the idle timer. + idle_timeout_.Stop(); // If the timer isn't running, this is a no-op. + idle_timeout_.Start(FROM_HERE, + base::TimeDelta::FromMilliseconds(kIdleTimeMs), this, + &ExclusiveAccessBubble::CheckMousePosition); + + // If the notification suppression timer has elapsed, re-show it. + if (!suppress_notify_timeout_.IsRunning()) { + ShowAndStartTimers(); + return; + } + + // The timer has not elapsed, but the user provided some input. Reset the + // timer. (We only want to re-show the message after a period of inactivity.) + suppress_notify_timeout_.Reset(); +} + void ExclusiveAccessBubble::StartWatchingMouse() { // Start the initial delay timer and begin watching the mouse. if (ExclusiveAccessManager::IsSimplifiedFullscreenUIEnabled()) { @@ -97,25 +119,16 @@ // Check to see whether the mouse is idle. if (cursor_pos != last_mouse_pos_) { - // The mouse moved; reset the idle timer. - idle_timeout_.Stop(); // If the timer isn't running, this is a no-op. - idle_timeout_.Start(FROM_HERE, - base::TimeDelta::FromMilliseconds(kIdleTimeMs), this, - &ExclusiveAccessBubble::CheckMousePosition); - - if (ExclusiveAccessManager::IsSimplifiedFullscreenUIEnabled()) { - // If the notification suppression timer has elapsed, show the - // notification regardless of where the mouse is on the screen. - if (!suppress_notify_timeout_.IsRunning()) { - ShowAndStartTimers(); - return; - } else { - // The timer has not elapsed, but the user moved the mouse. Reset the - // timer. (We only want to re-show the message after a period of - // inactivity.) - suppress_notify_timeout_.Reset(); - } + if (!ExclusiveAccessManager::IsSimplifiedFullscreenUIEnabled()) { + // OnUserInput() will reset the idle timer in simplified mode. In classic + // mode, we need to do this here. + idle_timeout_.Stop(); // If the timer isn't running, this is a no-op. + idle_timeout_.Start(FROM_HERE, + base::TimeDelta::FromMilliseconds(kIdleTimeMs), this, + &ExclusiveAccessBubble::CheckMousePosition); } + + OnUserInput(); } last_mouse_pos_ = cursor_pos;
diff --git a/chrome/browser/ui/exclusive_access/exclusive_access_bubble.h b/chrome/browser/ui/exclusive_access/exclusive_access_bubble.h index de663813..049df29 100644 --- a/chrome/browser/ui/exclusive_access/exclusive_access_bubble.h +++ b/chrome/browser/ui/exclusive_access/exclusive_access_bubble.h
@@ -34,6 +34,10 @@ ExclusiveAccessBubbleType bubble_type); ~ExclusiveAccessBubble() override; + // Informs the ExclusiveAccessBubble of some user input, which may update + // internal timers and/or re-display the bubble. + void OnUserInput(); + protected: static const int kPaddingPx; // Amount of padding around the link static const int kInitialDelayMs; // Initial time bubble remains onscreen @@ -46,6 +50,8 @@ static const int kSlideOutDurationMs; // Duration of slide-out animation // Space between the popup and the top of the screen (excluding shadow). static const int kPopupTopPx; + // Space between top of screen and popup, in simplified UI. + static const int kSimplifiedPopupTopPx; // Returns the current desirable rect for the popup window. If // |ignore_animation_state| is true this returns the rect assuming the popup @@ -113,7 +119,7 @@ // the user moving the mouse to the top of the screen and holding it there). base::OneShotTimer hide_timeout_; - // Timer to see how long the mouse has been idle. + // Timer to see how long the user has been idle (from all input sources). base::OneShotTimer idle_timeout_; // When this timer has elapsed, on the next mouse input, we will notify the
diff --git a/chrome/browser/ui/extensions/extension_action_view_controller.cc b/chrome/browser/ui/extensions/extension_action_view_controller.cc index 20937975..fbb8ebb 100644 --- a/chrome/browser/ui/extensions/extension_action_view_controller.cc +++ b/chrome/browser/ui/extensions/extension_action_view_controller.cc
@@ -27,7 +27,6 @@ #include "extensions/common/extension.h" #include "extensions/common/feature_switch.h" #include "extensions/common/manifest_constants.h" -#include "ui/base/resource/material_design/material_design_controller.h" #include "ui/gfx/image/image_skia.h" #include "ui/gfx/image/image_skia_operations.h" @@ -366,16 +365,7 @@ scoped_ptr<IconWithBadgeImageSource> image_source( new IconWithBadgeImageSource(size)); - gfx::Image icon(icon_factory_.GetIcon(tab_id)); - if (ui::MaterialDesignController::IsModeMaterial()) { - // TODO(tdanderson): Use a 16x16 icon if it exists instead of resizing. - icon = gfx::Image(gfx::ImageSkiaOperations::CreateResizedImage( - *icon.ToImageSkia(), - skia::ImageOperations::RESIZE_BEST, - gfx::Size(extension_misc::EXTENSION_ICON_BITTY, - extension_misc::EXTENSION_ICON_BITTY))); - } - image_source->SetIcon(icon); + image_source->SetIcon(icon_factory_.GetIcon(tab_id)); scoped_ptr<IconWithBadgeImageSource::Badge> badge; std::string badge_text = extension_action_->GetBadgeText(tab_id);
diff --git a/chrome/browser/ui/login/login_prompt_browsertest.cc b/chrome/browser/ui/login/login_prompt_browsertest.cc index c4a7738c..e768b42e 100644 --- a/chrome/browser/ui/login/login_prompt_browsertest.cc +++ b/chrome/browser/ui/login/login_prompt_browsertest.cc
@@ -1433,10 +1433,10 @@ https_server.SetSSLConfig(net::EmbeddedTestServer::CERT_EXPIRED); ASSERT_TRUE(https_server.Start()); - const char* kTestPage = "files/login/load_iframe_from_b.html"; + const char* kTestPage = "/login/load_iframe_from_b.html"; host_resolver()->AddRule("www.b.com", "127.0.0.1"); - ASSERT_TRUE(test_server()->Start()); + ASSERT_TRUE(embedded_test_server()->Start()); content::WebContents* contents = browser()->tab_strip_model()->GetActiveWebContents(); @@ -1446,7 +1446,7 @@ // Load a page that has a cross-domain iframe authentication. This should // trigger a login prompt but no login interstitial. - GURL test_page = test_server()->GetURL(kTestPage); + GURL test_page = embedded_test_server()->GetURL(kTestPage); GURL broken_ssl_page = https_server.GetURL("/"); ASSERT_EQ("127.0.0.1", test_page.host()); WindowedAuthNeededObserver auth_needed_waiter(controller);
diff --git a/chrome/browser/ui/passwords/manage_passwords_ui_controller.cc b/chrome/browser/ui/passwords/manage_passwords_ui_controller.cc index 8548f343..83ce991 100644 --- a/chrome/browser/ui/passwords/manage_passwords_ui_controller.cc +++ b/chrome/browser/ui/passwords/manage_passwords_ui_controller.cc
@@ -27,7 +27,7 @@ #include "content/public/browser/navigation_details.h" #include "ui/base/l10n/l10n_util.h" -#if defined(OS_ANDROID) +#if BUILDFLAG(ANDROID_JAVA_UI) #include "chrome/browser/android/chrome_application.h" #else #include "chrome/browser/ui/passwords/manage_passwords_icon_view.h" @@ -149,7 +149,7 @@ UpdateBubbleAndIconVisibility(); } -#if !defined(OS_ANDROID) +#if !BUILDFLAG(ANDROID_JAVA_UI) void ManagePasswordsUIController::UpdateIconAndBubbleState( ManagePasswordsIconView* icon) { if (should_pop_up_bubble_) { @@ -271,7 +271,7 @@ } void ManagePasswordsUIController::NavigateToExternalPasswordManager() { -#if defined(OS_ANDROID) +#if BUILDFLAG(ANDROID_JAVA_UI) NOTREACHED(); #else chrome::NavigateParams params( @@ -284,7 +284,7 @@ } void ManagePasswordsUIController::NavigateToSmartLockHelpPage() { -#if defined(OS_ANDROID) +#if BUILDFLAG(ANDROID_JAVA_UI) NOTREACHED(); #else chrome::NavigateParams params( @@ -296,7 +296,7 @@ } void ManagePasswordsUIController::NavigateToPasswordManagerSettingsPage() { -#if defined(OS_ANDROID) +#if BUILDFLAG(ANDROID_JAVA_UI) chrome::android::ChromeApplication::ShowPasswordSettings(); #else chrome::ShowSettingsSubPage( @@ -340,7 +340,7 @@ passwords_data_.OnInactive(); } -#if !defined(OS_ANDROID) +#if !BUILDFLAG(ANDROID_JAVA_UI) Browser* browser = chrome::FindBrowserWithWebContents(web_contents()); if (!browser) return; @@ -375,14 +375,14 @@ } void ManagePasswordsUIController::WasHidden() { -#if !defined(OS_ANDROID) +#if !BUILDFLAG(ANDROID_JAVA_UI) TabDialogs::FromWebContents(web_contents())->HideManagePasswordsBubble(); #endif } void ManagePasswordsUIController::ShowBubbleWithoutUserInteraction() { DCHECK(should_pop_up_bubble_); -#if !defined(OS_ANDROID) +#if !BUILDFLAG(ANDROID_JAVA_UI) Browser* browser = chrome::FindBrowserWithWebContents(web_contents()); if (!browser || browser->toolbar_model()->input_in_progress()) return;
diff --git a/chrome/browser/ui/passwords/manage_passwords_ui_controller.h b/chrome/browser/ui/passwords/manage_passwords_ui_controller.h index 19bebd25..dd745998 100644 --- a/chrome/browser/ui/passwords/manage_passwords_ui_controller.h +++ b/chrome/browser/ui/passwords/manage_passwords_ui_controller.h
@@ -9,6 +9,7 @@ #include "chrome/browser/ui/passwords/manage_passwords_state.h" #include "chrome/browser/ui/passwords/passwords_client_ui_delegate.h" #include "chrome/browser/ui/passwords/passwords_model_delegate.h" +#include "chrome/common/features.h" #include "components/password_manager/core/browser/password_store.h" #include "content/public/browser/web_contents_observer.h" #include "content/public/browser/web_contents_user_data.h" @@ -57,7 +58,7 @@ void OnLoginsChanged( const password_manager::PasswordStoreChangeList& changes) override; -#if !defined(OS_ANDROID) +#if !BUILDFLAG(ANDROID_JAVA_UI) // Set the state of the Omnibox icon, and possibly show the associated bubble // without user interaction. virtual void UpdateIconAndBubbleState(ManagePasswordsIconView* icon);
diff --git a/chrome/browser/ui/startup/startup_browser_creator.cc b/chrome/browser/ui/startup/startup_browser_creator.cc index 9e9daf6..51b9dd33 100644 --- a/chrome/browser/ui/startup/startup_browser_creator.cc +++ b/chrome/browser/ui/startup/startup_browser_creator.cc
@@ -92,8 +92,7 @@ #if defined(OS_WIN) #include "chrome/browser/metrics/jumplist_metrics_win.h" -#include "components/search_engines/detect_desktop_search_win.h" -#include "components/search_engines/search_engines_switches.h" +#include "components/search_engines/desktop_search_win.h" #endif #if defined(ENABLE_PRINT_PREVIEW) @@ -553,16 +552,16 @@ GURL url = GURL(param.MaybeAsASCII()); #if defined(OS_WIN) - if (command_line.HasSwitch( - switches::kUseDefaultSearchProviderForDesktopSearch)) { + if (ShouldRedirectWindowsDesktopSearchToDefaultSearchEngine( + profile->GetPrefs())) { TemplateURLService* template_url_service = TemplateURLServiceFactory::GetForProfile(profile); DCHECK(template_url_service); base::string16 search_terms; if (DetectWindowsDesktopSearch( url, template_url_service->search_terms_data(), &search_terms)) { - GURL search_url(GetDefaultSearchURLForSearchTerms(template_url_service, - search_terms)); + const GURL search_url(GetDefaultSearchURLForSearchTerms( + template_url_service, search_terms)); if (search_url.is_valid()) { urls.push_back(search_url); continue;
diff --git a/chrome/browser/ui/startup/startup_browser_creator.h b/chrome/browser/ui/startup/startup_browser_creator.h index 6ee80670..663285a 100644 --- a/chrome/browser/ui/startup/startup_browser_creator.h +++ b/chrome/browser/ui/startup/startup_browser_creator.h
@@ -132,6 +132,8 @@ ReadingWasRestartedAfterRestart); FRIEND_TEST_ALL_PREFIXES(StartupBrowserCreatorTest, UpdateWithTwoProfiles); FRIEND_TEST_ALL_PREFIXES(StartupBrowserCreatorTest, LastUsedProfileActivated); + FRIEND_TEST_ALL_PREFIXES(StartupBrowserCreatorWinTest, + GetURLsFromCommandLineWithDesktopSearchURL); // Returns the list of URLs to open from the command line. The returned // vector is empty if the user didn't specify any URLs on the command line.
diff --git a/chrome/browser/ui/startup/startup_browser_creator_triggered_reset_browsertest_win.cc b/chrome/browser/ui/startup/startup_browser_creator_triggered_reset_browsertest_win.cc index c9b8c2b..6ebb1b9b 100644 --- a/chrome/browser/ui/startup/startup_browser_creator_triggered_reset_browsertest_win.cc +++ b/chrome/browser/ui/startup/startup_browser_creator_triggered_reset_browsertest_win.cc
@@ -220,10 +220,10 @@ profile_manager->RegisterTestingProfile(other_profile, true, false); // Use a couple same-site HTTP URLs. - ASSERT_TRUE(test_server()->Start()); + ASSERT_TRUE(embedded_test_server()->Start()); std::vector<GURL> urls; - urls.push_back(test_server()->GetURL("files/title1.html")); - urls.push_back(test_server()->GetURL("files/title2.html")); + urls.push_back(embedded_test_server()->GetURL("/title1.html")); + urls.push_back(embedded_test_server()->GetURL("/title2.html")); // Set the startup preference to open these URLs. SessionStartupPref other_prefs(SessionStartupPref::URLS);
diff --git a/chrome/browser/ui/startup/startup_browser_creator_win_unittest.cc b/chrome/browser/ui/startup/startup_browser_creator_win_unittest.cc new file mode 100644 index 0000000..1821487 --- /dev/null +++ b/chrome/browser/ui/startup/startup_browser_creator_win_unittest.cc
@@ -0,0 +1,90 @@ +// 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. + +#include "chrome/browser/ui/startup/startup_browser_creator.h" + +#include <vector> + +#include "base/command_line.h" +#include "base/feature_list.h" +#include "base/macros.h" +#include "base/prefs/pref_service.h" +#include "chrome/browser/search_engines/template_url_service_factory.h" +#include "chrome/browser/search_engines/template_url_service_factory_test_util.h" +#include "chrome/test/base/testing_profile.h" +#include "components/search_engines/desktop_search_win.h" +#include "components/search_engines/util.h" +#include "content/public/test/test_browser_thread_bundle.h" +#include "testing/gtest/include/gtest/gtest.h" +#include "url/gurl.h" + +class StartupBrowserCreatorWinTest : public testing::Test { + public: + StartupBrowserCreatorWinTest() {} + + protected: + void SetWindowsDesktopSearchFeatureEnabled(bool enabled) { + base::FeatureList::ClearInstanceForTesting(); + scoped_ptr<base::FeatureList> feature_list(new base::FeatureList); + if (enabled) { + feature_list->InitializeFromCommandLine( + kWindowsDesktopSearchRedirectionFeature.name, std::string()); + } + base::FeatureList::SetInstance(std::move(feature_list)); + } + + private: + content::TestBrowserThreadBundle thread_bundle_; + + DISALLOW_COPY_AND_ASSIGN(StartupBrowserCreatorWinTest); +}; + +TEST_F(StartupBrowserCreatorWinTest, + GetURLsFromCommandLineWithDesktopSearchURL) { + const char kDesktopSearchURL[] = + "https://www.bing.com/search?q=keyword&form=WNSGPH"; + + TestingProfile profile; + TemplateURLServiceFactoryTestUtil template_url_service_factory_test_util( + &profile); + + base::CommandLine command_line(base::CommandLine::NO_PROGRAM); + command_line.AppendArg(kDesktopSearchURL); + + // Expected vectors of URLs. + const std::vector<GURL> desktop_search_url_vector({GURL(kDesktopSearchURL)}); + const std::vector<GURL> default_search_url_vector( + {GetDefaultSearchURLForSearchTerms( + TemplateURLServiceFactory::GetForProfile(&profile), L"keyword")}); + + // Preference unset, feature enabled. + SetWindowsDesktopSearchFeatureEnabled(true); + EXPECT_EQ(desktop_search_url_vector, + StartupBrowserCreator::GetURLsFromCommandLine( + command_line, base::FilePath(), &profile)); + + // Preference set to disabled, feature enabled. + profile.GetPrefs()->SetBoolean(prefs::kWindowsDesktopSearchRedirectionPref, + false); + SetWindowsDesktopSearchFeatureEnabled(true); + EXPECT_EQ(desktop_search_url_vector, + StartupBrowserCreator::GetURLsFromCommandLine( + command_line, base::FilePath(), &profile)); + + // Preference set to enabled, feature enabled. + profile.GetPrefs()->SetBoolean(prefs::kWindowsDesktopSearchRedirectionPref, + true); + SetWindowsDesktopSearchFeatureEnabled(true); + EXPECT_EQ(default_search_url_vector, + StartupBrowserCreator::GetURLsFromCommandLine( + command_line, base::FilePath(), &profile)); + + // Preference set to enabled, feature disabled. + profile.GetPrefs()->SetBoolean(prefs::kWindowsDesktopSearchRedirectionPref, + true); + SetWindowsDesktopSearchFeatureEnabled(false); + EXPECT_EQ(desktop_search_url_vector, + StartupBrowserCreator::GetURLsFromCommandLine( + command_line, base::FilePath(), &profile)); +}
diff --git a/chrome/browser/ui/tab_helpers.cc b/chrome/browser/ui/tab_helpers.cc index b9947de..5bfbf050 100644 --- a/chrome/browser/ui/tab_helpers.cc +++ b/chrome/browser/ui/tab_helpers.cc
@@ -39,6 +39,7 @@ #include "chrome/browser/ui/tab_contents/core_tab_helper.h" #include "chrome/browser/ui/tab_dialogs.h" #include "chrome/common/chrome_switches.h" +#include "chrome/common/features.h" #include "components/autofill/content/browser/content_autofill_driver_factory.h" #include "components/autofill/core/browser/autofill_manager.h" #include "components/dom_distiller/content/browser/web_contents_main_frame_observer.h" @@ -49,7 +50,7 @@ #include "components/tracing/tracing_switches.h" #include "content/public/browser/web_contents.h" -#if defined(OS_ANDROID) +#if BUILDFLAG(ANDROID_JAVA_UI) #include "chrome/browser/android/data_usage/data_use_tab_helper.h" #include "chrome/browser/android/voice_search_tab_helper.h" #include "chrome/browser/android/webapps/single_tab_mode_tab_helper.h" @@ -69,7 +70,7 @@ #include "components/pdf/browser/pdf_web_contents_helper.h" #include "components/ui/zoom/zoom_controller.h" #include "components/web_modal/web_contents_modal_dialog_manager.h" -#endif // defined(OS_ANDROID) +#endif // BUILDFLAG(ANDROID_JAVA_UI) #if defined(OS_WIN) #include "chrome/browser/ui/metro_pin_tab_helper_win.h" @@ -131,7 +132,7 @@ // SessionTabHelper comes first because it sets up the tab ID, and other // helpers may rely on that. SessionTabHelper::CreateForWebContents(web_contents); -#if !defined(OS_ANDROID) +#if !BUILDFLAG(ANDROID_JAVA_UI) // ZoomController comes before common tab helpers since ChromeAutofillClient // may want to register as a ZoomObserver with it. ui_zoom::ZoomController::CreateForWebContents(web_contents); @@ -179,7 +180,7 @@ // --- Platform-specific tab helpers --- -#if defined(OS_ANDROID) +#if BUILDFLAG(ANDROID_JAVA_UI) ContextMenuHelper::CreateForWebContents(web_contents); DataUseTabHelper::CreateForWebContents(web_contents); SingleTabModeTabHelper::CreateForWebContents(web_contents); @@ -228,14 +229,14 @@ SupervisedUserNavigationObserver::CreateForWebContents(web_contents); #endif -#if defined(ENABLE_PRINTING) && !defined(OS_ANDROID) +#if defined(ENABLE_PRINTING) && !BUILDFLAG(ANDROID_JAVA_UI) #if defined(ENABLE_PRINT_PREVIEW) printing::PrintViewManager::CreateForWebContents(web_contents); printing::PrintPreviewMessageHandler::CreateForWebContents(web_contents); #else printing::PrintViewManagerBasic::CreateForWebContents(web_contents); #endif // defined(ENABLE_PRINT_PREVIEW) -#endif // defined(ENABLE_PRINTING) && !defined(OS_ANDROID) +#endif // defined(ENABLE_PRINTING) && !BUILDFLAG(ANDROID_JAVA_UI) bool enabled_distiller = base::CommandLine::ForCurrentProcess()->HasSwitch( switches::kEnableDomDistiller);
diff --git a/chrome/browser/ui/toolbar/app_menu_model.cc b/chrome/browser/ui/toolbar/app_menu_model.cc index 93f8704f2..f25c0fd7 100644 --- a/chrome/browser/ui/toolbar/app_menu_model.cc +++ b/chrome/browser/ui/toolbar/app_menu_model.cc
@@ -8,6 +8,7 @@ #include <cmath> #include "base/command_line.h" +#include "base/debug/debugging_flags.h" #include "base/metrics/histogram.h" #include "base/prefs/pref_service.h" #include "base/strings/string_number_conversions.h" @@ -322,7 +323,7 @@ AddSeparator(ui::NORMAL_SEPARATOR); AddItemWithStringId(IDC_DEV_TOOLS, IDS_DEV_TOOLS); -#if defined(ENABLE_PROFILING) && !defined(NO_TCMALLOC) +#if BUILDFLAG(ENABLE_PROFILING) && !defined(NO_TCMALLOC) AddSeparator(ui::NORMAL_SEPARATOR); AddCheckItemWithStringId(IDC_PROFILING_ENABLED, IDS_PROFILING_ENABLED); #endif
diff --git a/chrome/browser/ui/toolbar/component_toolbar_actions_browsertest.cc b/chrome/browser/ui/toolbar/component_toolbar_actions_browsertest.cc index b5550c84..ddf66be 100644 --- a/chrome/browser/ui/toolbar/component_toolbar_actions_browsertest.cc +++ b/chrome/browser/ui/toolbar/component_toolbar_actions_browsertest.cc
@@ -54,7 +54,7 @@ // There should only have been one created component action. EXPECT_EQ(1u, ComponentToolbarActionsFactory::GetInstance() - ->GetComponentIds(browser()->profile()) + ->GetInitialComponentIds(browser()->profile()) .size()); const std::vector<ToolbarActionViewController*>& actions =
diff --git a/chrome/browser/ui/toolbar/component_toolbar_actions_factory.cc b/chrome/browser/ui/toolbar/component_toolbar_actions_factory.cc index 0c45060..956c3cb7 100644 --- a/chrome/browser/ui/toolbar/component_toolbar_actions_factory.cc +++ b/chrome/browser/ui/toolbar/component_toolbar_actions_factory.cc
@@ -37,7 +37,7 @@ return testing_factory_ ? testing_factory_ : &lazy_factory.Get(); } -std::set<std::string> ComponentToolbarActionsFactory::GetComponentIds( +std::set<std::string> ComponentToolbarActionsFactory::GetInitialComponentIds( Profile* profile) { std::set<std::string> component_ids; @@ -59,7 +59,7 @@ // This is currently behind the extension-action-redesign flag, as it is // designed for the new toolbar. DCHECK(extensions::FeatureSwitch::extension_action_redesign()->IsEnabled()); - DCHECK(GetComponentIds(browser->profile()).count(id)); + DCHECK(GetInitialComponentIds(browser->profile()).count(id)); // Add component toolbar actions here. // This current design means that the ComponentToolbarActionsFactory is aware
diff --git a/chrome/browser/ui/toolbar/component_toolbar_actions_factory.h b/chrome/browser/ui/toolbar/component_toolbar_actions_factory.h index ffdc126a4..f8fa607 100644 --- a/chrome/browser/ui/toolbar/component_toolbar_actions_factory.h +++ b/chrome/browser/ui/toolbar/component_toolbar_actions_factory.h
@@ -29,7 +29,7 @@ static ComponentToolbarActionsFactory* GetInstance(); // Returns a vector of IDs of the component actions. - virtual std::set<std::string> GetComponentIds(Profile* profile); + virtual std::set<std::string> GetInitialComponentIds(Profile* profile); // Returns a collection of controllers for component actions. Declared // virtual for testing.
diff --git a/chrome/browser/ui/toolbar/mock_component_toolbar_actions_factory.cc b/chrome/browser/ui/toolbar/mock_component_toolbar_actions_factory.cc index 05ecd87..01fdd05f 100644 --- a/chrome/browser/ui/toolbar/mock_component_toolbar_actions_factory.cc +++ b/chrome/browser/ui/toolbar/mock_component_toolbar_actions_factory.cc
@@ -21,8 +21,8 @@ ComponentToolbarActionsFactory::SetTestingFactory(nullptr); } -std::set<std::string> MockComponentToolbarActionsFactory::GetComponentIds( - Profile* profile) { +std::set<std::string> +MockComponentToolbarActionsFactory::GetInitialComponentIds(Profile* profile) { std::set<std::string> ids; ids.insert(kActionIdForTesting); return ids;
diff --git a/chrome/browser/ui/toolbar/mock_component_toolbar_actions_factory.h b/chrome/browser/ui/toolbar/mock_component_toolbar_actions_factory.h index 6770013..675cc28 100644 --- a/chrome/browser/ui/toolbar/mock_component_toolbar_actions_factory.h +++ b/chrome/browser/ui/toolbar/mock_component_toolbar_actions_factory.h
@@ -20,7 +20,7 @@ ~MockComponentToolbarActionsFactory() override; // ComponentToolbarActionsFactory: - std::set<std::string> GetComponentIds(Profile* profile) override; + std::set<std::string> GetInitialComponentIds(Profile* profile) override; scoped_ptr<ToolbarActionViewController> GetComponentToolbarActionForId( const std::string& id, Browser* browser) override;
diff --git a/chrome/browser/ui/toolbar/toolbar_action_view_controller.h b/chrome/browser/ui/toolbar/toolbar_action_view_controller.h index 4702922..d9f3ae6 100644 --- a/chrome/browser/ui/toolbar/toolbar_action_view_controller.h +++ b/chrome/browser/ui/toolbar/toolbar_action_view_controller.h
@@ -24,7 +24,7 @@ // The basic controller class for an action that is shown on the toolbar - // an extension action (like browser actions) or a component action (like -// chromecast). +// Media Router). class ToolbarActionViewController { public: virtual ~ToolbarActionViewController() {}
diff --git a/chrome/browser/ui/toolbar/toolbar_actions_bar.cc b/chrome/browser/ui/toolbar/toolbar_actions_bar.cc index e88db9dc..442119b 100644 --- a/chrome/browser/ui/toolbar/toolbar_actions_bar.cc +++ b/chrome/browser/ui/toolbar/toolbar_actions_bar.cc
@@ -9,7 +9,6 @@ #include "base/profiler/scoped_tracker.h" #include "base/single_thread_task_runner.h" #include "base/thread_task_runner_handle.h" -#include "chrome/browser/extensions/extension_action_manager.h" #include "chrome/browser/extensions/extension_message_bubble_controller.h" #include "chrome/browser/extensions/extension_util.h" #include "chrome/browser/profiles/profile.h" @@ -26,7 +25,6 @@ #include "chrome/common/pref_names.h" #include "components/crx_file/id_util.h" #include "components/pref_registry/pref_registry_syncable.h" -#include "extensions/browser/extension_registry.h" #include "extensions/browser/extension_system.h" #include "extensions/browser/runtime_data.h" #include "extensions/common/extension.h" @@ -597,30 +595,15 @@ } } -void ToolbarActionsBar::OnToolbarActionAdded(const std::string& action_id, - int index) { - DCHECK(GetActionForId(action_id) == nullptr) - << "Asked to add a toolbar action view for an extension that already " +void ToolbarActionsBar::OnToolbarActionAdded( + const ToolbarActionsModel::ToolbarItem& item, + int index) { + DCHECK(GetActionForId(item.id) == nullptr) + << "Asked to add a toolbar action view for an action that already " "exists"; - // TODO(devlin): This is a minor layering violation and the model should pass - // in an action directly. - const extensions::Extension* extension = - extensions::ExtensionRegistry::Get(browser_->profile()) - ->enabled_extensions() - .GetByID(action_id); - // Only extensions should be added after initialization. - DCHECK(extension); - - toolbar_actions_.insert( - toolbar_actions_.begin() + index, - new ExtensionActionViewController( - extension, - browser_, - extensions::ExtensionActionManager::Get(browser_->profile())-> - GetExtensionAction(*extension), - this)); - + toolbar_actions_.insert(toolbar_actions_.begin() + index, + model_->CreateActionForItem(browser_, this, item)); delegate_->AddViewForAction(toolbar_actions_[index], index); // If we are still initializing the container, don't bother animating. @@ -628,7 +611,7 @@ return; // We may need to resize (e.g. to show the new icon, or the chevron). We don't - // need to check if the extension is upgrading here, because ResizeDelegate() + // need to check if an extension is upgrading here, because ResizeDelegate() // checks to see if the container is already the proper size, and because // if the action is newly incognito enabled, even though it's a reload, it's // a new extension to this toolbar.
diff --git a/chrome/browser/ui/toolbar/toolbar_actions_bar.h b/chrome/browser/ui/toolbar/toolbar_actions_bar.h index b8757d6..6d3bf93 100644 --- a/chrome/browser/ui/toolbar/toolbar_actions_bar.h +++ b/chrome/browser/ui/toolbar/toolbar_actions_bar.h
@@ -244,7 +244,8 @@ using ToolbarActions = ScopedVector<ToolbarActionViewController>; // ToolbarActionsModel::Observer: - void OnToolbarActionAdded(const std::string& action_id, int index) override; + void OnToolbarActionAdded(const ToolbarActionsModel::ToolbarItem& item, + int index) override; void OnToolbarActionRemoved(const std::string& action_id) override; void OnToolbarActionMoved(const std::string& action_id, int index) override; void OnToolbarActionUpdated(const std::string& action_id) override;
diff --git a/chrome/browser/ui/toolbar/toolbar_actions_model.cc b/chrome/browser/ui/toolbar/toolbar_actions_model.cc index 23f6dba..2d2d479 100644 --- a/chrome/browser/ui/toolbar/toolbar_actions_model.cc +++ b/chrome/browser/ui/toolbar/toolbar_actions_model.cc
@@ -145,9 +145,8 @@ content::WebContents* web_contents, content::BrowserContext* browser_context) { // Notify observers if the extension exists and is in the model. - if (std::find(toolbar_items_.begin(), toolbar_items_.end(), - ToolbarItem(extension_action->extension_id(), - EXTENSION_ACTION)) != toolbar_items_.end()) { + if (HasItem( + ToolbarItem(extension_action->extension_id(), EXTENSION_ACTION))) { FOR_EACH_OBSERVER(Observer, observers_, OnToolbarActionUpdated(extension_action->extension_id())); } @@ -217,12 +216,8 @@ // We don't want to add the same extension twice. It may have already been // added by EXTENSION_BROWSER_ACTION_VISIBILITY_CHANGED below, if the user // hides the browser action and then disables and enables the extension. - if (std::find(toolbar_items_.begin(), toolbar_items_.end(), - ToolbarItem(extension->id(), EXTENSION_ACTION)) != - toolbar_items_.end()) - return; - - AddExtension(extension); + if (!HasItem(ToolbarItem(extension->id(), EXTENSION_ACTION))) + AddExtension(extension); } void ToolbarActionsModel::OnExtensionUnloaded( @@ -238,9 +233,12 @@ extensions::UninstallReason reason) { // Remove the extension id from the ordered list, if it exists (the extension // might not be represented in the list because it might not have an icon). - std::vector<std::string>::iterator pos = - std::find(last_known_positions_.begin(), last_known_positions_.end(), - extension->id()); + RemovePref(ToolbarItem(extension->id(), EXTENSION_ACTION)); +} + +void ToolbarActionsModel::RemovePref(const ToolbarItem& item) { + std::vector<std::string>::iterator pos = std::find( + last_known_positions_.begin(), last_known_positions_.end(), item.id); if (pos != last_known_positions_.end()) { last_known_positions_.erase(pos); @@ -309,23 +307,27 @@ } void ToolbarActionsModel::AddExtension(const extensions::Extension* extension) { - // We only use AddExtension() once the system is initialized. - DCHECK(actions_initialized_); if (!ShouldAddExtension(extension)) return; + AddItem(ToolbarItem(extension->id(), EXTENSION_ACTION), + extensions::Manifest::IsComponentLocation(extension->location())); +} + +void ToolbarActionsModel::AddItem(const ToolbarItem& item, bool is_component) { + // We only use AddItem() once the system is initialized. + DCHECK(actions_initialized_); + // See if we have a last known good position for this extension. bool is_new_extension = std::find(last_known_positions_.begin(), last_known_positions_.end(), - extension->id()) == last_known_positions_.end(); + item.id) == last_known_positions_.end(); // New extensions go at the right (end) of the visible extensions. Other // extensions go at their previous position. size_t new_index = 0; if (is_new_extension) { - new_index = extensions::Manifest::IsComponentLocation(extension->location()) - ? 0 - : visible_icon_count(); + new_index = is_component ? 0 : visible_icon_count(); // For the last-known position, we use the index of the extension that is // just before this extension, plus one. (Note that this isn't the same // as new_index + 1, because last_known_positions_ can include disabled @@ -342,22 +344,20 @@ new_last_known_index = std::min<int>(new_last_known_index, last_known_positions_.size()); last_known_positions_.insert( - last_known_positions_.begin() + new_last_known_index, extension->id()); + last_known_positions_.begin() + new_last_known_index, item.id); UpdatePrefs(); } else { - new_index = FindNewPositionFromLastKnownGood( - ToolbarItem(extension->id(), EXTENSION_ACTION)); + new_index = FindNewPositionFromLastKnownGood(item); } - toolbar_items_.insert(toolbar_items_.begin() + new_index, - ToolbarItem(extension->id(), EXTENSION_ACTION)); + toolbar_items_.insert(toolbar_items_.begin() + new_index, item); // If we're currently highlighting, then even though we add a browser action // to the full list (|toolbar_items_|, there won't be another *visible* // browser action, which was what the observers care about. if (!is_highlighting()) { FOR_EACH_OBSERVER(Observer, observers_, - OnToolbarActionAdded(extension->id(), new_index)); + OnToolbarActionAdded(item, new_index)); int visible_count_delta = 0; if (is_new_extension && !all_icons_visible()) { @@ -372,8 +372,7 @@ // Find what the index will be in the main bar. Because Observer calls are // nondeterministic, we can't just assume the main bar will have the // extension and look it up. - size_t main_index = main_model->FindNewPositionFromLastKnownGood( - ToolbarItem(extension->id(), EXTENSION_ACTION)); + size_t main_index = main_model->FindNewPositionFromLastKnownGood(item); bool visible = main_index < main_model->visible_icon_count(); // We may need to adjust the visible count if the incognito bar isn't // showing all icons and this one is visible, or if it is showing all @@ -389,11 +388,9 @@ } } -void ToolbarActionsModel::RemoveExtension( - const extensions::Extension* extension) { +void ToolbarActionsModel::RemoveItem(const ToolbarItem& item) { std::vector<ToolbarItem>::iterator pos = - std::find(toolbar_items_.begin(), toolbar_items_.end(), - ToolbarItem(extension->id(), EXTENSION_ACTION)); + std::find(toolbar_items_.begin(), toolbar_items_.end(), item); if (pos == toolbar_items_.end()) return; @@ -404,27 +401,29 @@ toolbar_items_.erase(pos); - // If we're in highlight mode, we also have to remove the extension from + // If we're in highlight mode, we also have to remove the action from // the highlighted list. if (is_highlighting()) { - pos = std::find(highlighted_items_.begin(), highlighted_items_.end(), - ToolbarItem(extension->id(), EXTENSION_ACTION)); + pos = std::find(highlighted_items_.begin(), highlighted_items_.end(), item); if (pos != highlighted_items_.end()) { highlighted_items_.erase(pos); - FOR_EACH_OBSERVER(Observer, observers_, - OnToolbarActionRemoved(extension->id())); + FOR_EACH_OBSERVER(Observer, observers_, OnToolbarActionRemoved(item.id)); // If the highlighted list is now empty, we stop highlighting. if (highlighted_items_.empty()) StopHighlighting(); } } else { - FOR_EACH_OBSERVER(Observer, observers_, - OnToolbarActionRemoved(extension->id())); + FOR_EACH_OBSERVER(Observer, observers_, OnToolbarActionRemoved(item.id)); } UpdatePrefs(); } +void ToolbarActionsModel::RemoveExtension( + const extensions::Extension* extension) { + RemoveItem(ToolbarItem(extension->id(), EXTENSION_ACTION)); +} + // Combine the currently enabled extensions that have browser actions (which // we get from the ExtensionRegistry) and component actions (which we get from // ComponentToolbarActionsFactory) with the ordering we get from the pref @@ -473,7 +472,8 @@ // Next, add the component action ids. std::set<std::string> component_ids = - ComponentToolbarActionsFactory::GetInstance()->GetComponentIds(profile_); + ComponentToolbarActionsFactory::GetInstance()->GetInitialComponentIds( + profile_); for (const std::string& id : component_ids) all_actions.push_back(ToolbarItem(id, COMPONENT_ACTION)); @@ -563,6 +563,26 @@ } } +bool ToolbarActionsModel::HasItem(const ToolbarItem& item) const { + return std::find(toolbar_items_.begin(), toolbar_items_.end(), item) != + toolbar_items_.end(); +} + +void ToolbarActionsModel::AddComponentAction(const std::string& action_id) { + DCHECK(use_redesign_); + ToolbarItem component_item(action_id, COMPONENT_ACTION); + DCHECK(!HasItem(component_item)); + AddItem(component_item, true); +} + +void ToolbarActionsModel::RemoveComponentAction(const std::string& action_id) { + DCHECK(use_redesign_); + ToolbarItem component_item(action_id, COMPONENT_ACTION); + DCHECK(HasItem(component_item)); + RemoveItem(component_item); + RemovePref(component_item); +} + void ToolbarActionsModel::IncognitoPopulate() { DCHECK(profile_->IsOffTheRecord()); const ToolbarActionsModel* original_model = @@ -577,7 +597,8 @@ visible_icon_count_ = 0; std::set<std::string> component_ids = - ComponentToolbarActionsFactory::GetInstance()->GetComponentIds(profile_); + ComponentToolbarActionsFactory::GetInstance()->GetInitialComponentIds( + profile_); for (std::vector<ToolbarItem>::const_iterator iter = original_model->toolbar_items_.begin(); iter != original_model->toolbar_items_.end(); ++iter) { @@ -621,9 +642,7 @@ bool is_now_visible) { // Hiding works differently with the new and old toolbars. if (use_redesign_) { - DCHECK(std::find(toolbar_items_.begin(), toolbar_items_.end(), - ToolbarItem(action_id, EXTENSION_ACTION)) != - toolbar_items_.end()); + DCHECK(HasItem(ToolbarItem(action_id, EXTENSION_ACTION))); int new_size = 0; int new_index = 0;
diff --git a/chrome/browser/ui/toolbar/toolbar_actions_model.h b/chrome/browser/ui/toolbar/toolbar_actions_model.h index e94938d..cfde0a68 100644 --- a/chrome/browser/ui/toolbar/toolbar_actions_model.h +++ b/chrome/browser/ui/toolbar/toolbar_actions_model.h
@@ -60,7 +60,7 @@ ToolbarItem(const std::string& action_id, ActionType action_type) : id(action_id), type(action_type) {} - bool operator==(const ToolbarItem& other) { return other.id == id; } + bool operator==(const ToolbarItem& other) const { return other.id == id; } std::string id; ActionType type; @@ -76,10 +76,9 @@ // delegate. class Observer { public: - // Signals that an action with |id| has been added to the toolbar at - // |index|. This will *only* be called after the toolbar model has been - // initialized. - virtual void OnToolbarActionAdded(const std::string& id, int index) = 0; + // Signals that |item| has been added to the toolbar at |index|. This will + // *only* be called after the toolbar model has been initialized. + virtual void OnToolbarActionAdded(const ToolbarItem& item, int index) = 0; // Signals that the given action with |id| has been removed from the // toolbar. @@ -183,6 +182,11 @@ // showing new icons as a result. bool RedesignIsShowingNewIcons() const; + // Adds or removes the component action labeled by |action_id| from the + // toolbar model. The caller must not add the same action twice. + void AddComponentAction(const std::string& action_id); + void RemoveComponentAction(const std::string& action_id); + private: // Callback when actions are ready. void OnReady(); @@ -207,10 +211,11 @@ bool is_now_visible) override; // To be called after the extension service is ready; gets loaded extensions - // from the ExtensionRegistry and their saved order from the pref service - // and constructs |toolbar_items_| from these data. IncognitoPopulate() - // takes the shortcut - looking at the regular model's content and modifying - // it. + // from the ExtensionRegistry, their saved order from the pref service, and + // the initial set of component actions from the + // ComponentToolbarActionsFactory, and constructs |toolbar_items_| from these + // data. IncognitoPopulate() takes the shortcut - looking at the regular + // model's content and modifying it. void InitializeActionList(); void Populate(); void IncognitoPopulate(); @@ -218,6 +223,9 @@ // Save the model to prefs. void UpdatePrefs(); + // Removes any preference for |item| and saves the model to prefs. + void RemovePref(const ToolbarItem& item); + // Finds the last known visible position of the icon for |action|. The value // returned is a zero-based index into the vector of visible items. size_t FindNewPositionFromLastKnownGood(const ToolbarItem& action); @@ -229,6 +237,21 @@ void AddExtension(const extensions::Extension* extension); void RemoveExtension(const extensions::Extension* extension); + // Returns true if |item| is in the toolbar model. + bool HasItem(const ToolbarItem& item) const; + + // Adds |item| to the toolbar. If the item has an existing preference for + // toolbar position, that will be used to determine its location. If + // |is_component| is true, the item will be given a default postion of 0, + // otherwise the default is at the end of the visible items. If the toolbar is + // in highlighting mode, the item will not be visible until highlighting mode + // is exited. + void AddItem(const ToolbarItem& item, bool is_component); + + // Removes |item| from the toolbar. If the toolbar is in highlighting mode, + // the item is also removed from the highlighted list (if present). + void RemoveItem(const ToolbarItem& item); + // Looks up and returns the extension with the given |id| in the set of // enabled extensions. const extensions::Extension* GetExtensionById(const std::string& id) const;
diff --git a/chrome/browser/ui/toolbar/toolbar_actions_model_unittest.cc b/chrome/browser/ui/toolbar/toolbar_actions_model_unittest.cc index c0e7d26..bdf48e8 100644 --- a/chrome/browser/ui/toolbar/toolbar_actions_model_unittest.cc +++ b/chrome/browser/ui/toolbar/toolbar_actions_model_unittest.cc
@@ -53,7 +53,8 @@ private: // ToolbarActionsModel::Observer: - void OnToolbarActionAdded(const std::string& id, int index) override { + void OnToolbarActionAdded(const ToolbarActionsModel::ToolbarItem& item, + int index) override { ++inserted_count_; } @@ -1334,11 +1335,24 @@ EXPECT_EQ(1u, num_toolbar_items()); EXPECT_EQ(component_action_id(), GetActionIdAtIndex(0u)); + // Just MCA is visible. Remove MCA. + toolbar_model()->RemoveComponentAction(component_action_id()); + EXPECT_EQ(4u, observer()->removed_count()); + EXPECT_EQ(0u, num_toolbar_items()); + + // Add MCA again. + toolbar_model()->AddComponentAction(component_action_id()); + EXPECT_EQ(1u, num_toolbar_items()); + EXPECT_EQ(4u, observer()->inserted_count()); + // Newly added component actions get put at the end of the visible area. + EXPECT_EQ(component_action_id(), GetActionIdAtIndex(0u)); + EXPECT_EQ(1u, toolbar_model()->visible_icon_count()); + EXPECT_TRUE(toolbar_model()->all_icons_visible()); + // Load extension C again. ASSERT_TRUE(AddExtension(browser_action_c())); - EXPECT_EQ(4u, observer()->inserted_count()); + EXPECT_EQ(5u, observer()->inserted_count()); EXPECT_EQ(2u, num_toolbar_items()); - // Make sure it gets its old spot in the list (at the beginning). - EXPECT_EQ(browser_action_c()->id(), GetActionIdAtIndex(0u)); - EXPECT_EQ(component_action_id(), GetActionIdAtIndex(1u)); + EXPECT_EQ(component_action_id(), GetActionIdAtIndex(0u)); + EXPECT_EQ(browser_action_c()->id(), GetActionIdAtIndex(1u)); }
diff --git a/chrome/browser/ui/views/exclusive_access_bubble_views.cc b/chrome/browser/ui/views/exclusive_access_bubble_views.cc index d6018160..67636b2 100644 --- a/chrome/browser/ui/views/exclusive_access_bubble_views.cc +++ b/chrome/browser/ui/views/exclusive_access_bubble_views.cc
@@ -4,7 +4,6 @@ #include "chrome/browser/ui/views/exclusive_access_bubble_views.h" -#include "base/i18n/case_conversion.h" #include "base/message_loop/message_loop.h" #include "base/strings/string_split.h" #include "base/strings/utf_string_conversions.h" @@ -45,9 +44,12 @@ // Space between the site info label and the buttons / link. const int kMiddlePaddingPx = 30; -// Opacity of the background (out of 255). Only used with +const int kOuterPaddingHorizPx = 24; +const int kOuterPaddingVertPx = 8; + +// Partially-transparent background color. Only used with // IsSimplifiedFullscreenUIEnabled. -const unsigned char kBackgroundOpacity = 180; +const SkColor kBackgroundColor = SkColorSetARGB(0xcc, 0x28, 0x2c, 0x32); class ButtonView : public views::View { public: @@ -113,9 +115,9 @@ // Spacing around the escape key name. const int kKeyNameMarginHorizPx = 7; - const int kKeyNameBorderPx = 2; + const int kKeyNameBorderPx = 1; const int kKeyNameCornerRadius = 2; - const int kKeyNamePaddingPx = 7; + const int kKeyNamePaddingPx = 5; // The |between_child_spacing| is the horizontal margin of the key name. views::BoxLayout* layout = new views::BoxLayout(views::BoxLayout::kHorizontal, @@ -130,8 +132,7 @@ if (segments.size() < 3) return; - base::string16 key = base::i18n::ToUpper(segments[1]); - views::Label* key_name_label = new views::Label(key, font_list); + views::Label* key_name_label = new views::Label(segments[1], font_list); key_name_label->SetEnabledColor(foreground_color); key_name_label->SetBackgroundColor(background_color); @@ -217,7 +218,7 @@ ui::NativeTheme* theme = ui::NativeTheme::GetInstanceForWeb(); SkColor background_color = ExclusiveAccessManager::IsSimplifiedFullscreenUIEnabled() - ? SkColorSetA(SK_ColorBLACK, kBackgroundOpacity) + ? kBackgroundColor : theme->GetSystemColor(ui::NativeTheme::kColorId_BubbleBackground); SkColor foreground_color = ExclusiveAccessManager::IsSimplifiedFullscreenUIEnabled() @@ -231,17 +232,20 @@ SetFocusable(false); ui::ResourceBundle& rb = ui::ResourceBundle::GetSharedInstance(); - const gfx::FontList& medium_font_list = - rb.GetFontList(ui::ResourceBundle::MediumFont); + ui::ResourceBundle::FontStyle font_style = + ExclusiveAccessManager::IsSimplifiedFullscreenUIEnabled() + ? ui::ResourceBundle::SmallFont + : ui::ResourceBundle::MediumFont; + const gfx::FontList& font_list = rb.GetFontList(font_style); if (!ExclusiveAccessManager::IsSimplifiedFullscreenUIEnabled()) { - message_label_ = new views::Label(base::string16(), medium_font_list); + message_label_ = new views::Label(base::string16(), font_list); message_label_->SetEnabledColor(foreground_color); message_label_->SetBackgroundColor(background_color); } exit_instruction_ = - new InstructionView(bubble_->GetInstructionText(), medium_font_list, + new InstructionView(bubble_->GetInstructionText(), font_list, foreground_color, background_color); link_ = new views::Link(); @@ -251,7 +255,7 @@ link_->SetText(l10n_util::GetStringUTF16(IDS_EXIT_FULLSCREEN_MODE)); #endif link_->set_listener(this); - link_->SetFontList(medium_font_list); + link_->SetFontList(font_list); link_->SetPressedColor(foreground_color); link_->SetEnabledColor(foreground_color); link_->SetBackgroundColor(background_color); @@ -259,16 +263,22 @@ button_view_ = new ButtonView(this, kPaddingPx); + int outer_padding_horiz = kOuterPaddingHorizPx; + int outer_padding_vert = kOuterPaddingVertPx; if (!ExclusiveAccessManager::IsSimplifiedFullscreenUIEnabled()) { DCHECK(message_label_); AddChildView(message_label_); + + outer_padding_horiz = kPaddingPx; + outer_padding_vert = kPaddingPx; } AddChildView(button_view_); AddChildView(exit_instruction_); AddChildView(link_); - views::BoxLayout* layout = new views::BoxLayout( - views::BoxLayout::kHorizontal, kPaddingPx, kPaddingPx, kMiddlePaddingPx); + views::BoxLayout* layout = + new views::BoxLayout(views::BoxLayout::kHorizontal, outer_padding_horiz, + outer_padding_vert, kMiddlePaddingPx); SetLayoutManager(layout); UpdateContent(url, bubble_type); @@ -562,7 +572,10 @@ bubble_view_context_->GetTopContainerBoundsInScreen().bottom(); } // |desired_top| is the top of the bubble area including the shadow. - int desired_top = kPopupTopPx - view_->border()->GetInsets().top(); + int popup_top = ExclusiveAccessManager::IsSimplifiedFullscreenUIEnabled() + ? kSimplifiedPopupTopPx + : kPopupTopPx; + int desired_top = popup_top - view_->border()->GetInsets().top(); int y = top_container_bottom + desired_top; if (!ignore_animation_state &&
diff --git a/chrome/browser/ui/views/frame/browser_frame.cc b/chrome/browser/ui/views/frame/browser_frame.cc index b7283a5..0b3ed94ee 100644 --- a/chrome/browser/ui/views/frame/browser_frame.cc +++ b/chrome/browser/ui/views/frame/browser_frame.cc
@@ -153,6 +153,10 @@ return native_browser_frame_->GetWindowPlacement(bounds, show_state); } +void BrowserFrame::OnBrowserViewInitViewsComplete() { + browser_frame_view_->OnBrowserViewInitViewsComplete(); +} + /////////////////////////////////////////////////////////////////////////////// // BrowserFrame, views::Widget overrides:
diff --git a/chrome/browser/ui/views/frame/browser_frame.h b/chrome/browser/ui/views/frame/browser_frame.h index 1ef4802..92bab93 100644 --- a/chrome/browser/ui/views/frame/browser_frame.h +++ b/chrome/browser/ui/views/frame/browser_frame.h
@@ -96,6 +96,9 @@ void GetWindowPlacement(gfx::Rect* bounds, ui::WindowShowState* show_state) const; + // Called when BrowserView creates all it's child views. + void OnBrowserViewInitViewsComplete(); + // Overridden from views::Widget: views::internal::RootView* CreateRootView() override; views::NonClientFrameView* CreateNonClientFrameView() override;
diff --git a/chrome/browser/ui/views/frame/browser_frame_mus.cc b/chrome/browser/ui/views/frame/browser_frame_mus.cc index 6177d1a1..d0ec71f 100644 --- a/chrome/browser/ui/views/frame/browser_frame_mus.cc +++ b/chrome/browser/ui/views/frame/browser_frame_mus.cc
@@ -64,6 +64,6 @@ } void BrowserFrameMus::UpdateClientArea() { - window()->SetClientArea( - views::WindowManagerFrameValues::instance().normal_insets); + // BrowserNonClientFrameViewMus::OnBoundsChanged() takes care of updating + // the insets. }
diff --git a/chrome/browser/ui/views/frame/browser_frame_mus.h b/chrome/browser/ui/views/frame/browser_frame_mus.h index db389bc9..4feb827 100644 --- a/chrome/browser/ui/views/frame/browser_frame_mus.h +++ b/chrome/browser/ui/views/frame/browser_frame_mus.h
@@ -15,6 +15,8 @@ BrowserFrameMus(BrowserFrame* browser_frame, BrowserView* browser_view); ~BrowserFrameMus() override; + mus::Window* mus_window(); + private: // Overridden from NativeBrowserFrame: views::Widget::InitParams GetWidgetParams() override;
diff --git a/chrome/browser/ui/views/frame/browser_non_client_frame_view.cc b/chrome/browser/ui/views/frame/browser_non_client_frame_view.cc index b99b8af..adb429ea 100644 --- a/chrome/browser/ui/views/frame/browser_non_client_frame_view.cc +++ b/chrome/browser/ui/views/frame/browser_non_client_frame_view.cc
@@ -61,6 +61,8 @@ } } +void BrowserNonClientFrameView::OnBrowserViewInitViewsComplete() {} + void BrowserNonClientFrameView::UpdateToolbar() { }
diff --git a/chrome/browser/ui/views/frame/browser_non_client_frame_view.h b/chrome/browser/ui/views/frame/browser_non_client_frame_view.h index 30abb5938..81344a88 100644 --- a/chrome/browser/ui/views/frame/browser_non_client_frame_view.h +++ b/chrome/browser/ui/views/frame/browser_non_client_frame_view.h
@@ -41,6 +41,9 @@ void OnThemeChanged() override; #endif + // Called when BrowserView creates all it's child views. + virtual void OnBrowserViewInitViewsComplete(); + // Retrieves the bounds, in non-client view coordinates within which the // TabStrip should be laid out. virtual gfx::Rect GetBoundsForTabStrip(views::View* tabstrip) const = 0;
diff --git a/chrome/browser/ui/views/frame/browser_non_client_frame_view_mus.cc b/chrome/browser/ui/views/frame/browser_non_client_frame_view_mus.cc index bac7c90..d030b6c1 100644 --- a/chrome/browser/ui/views/frame/browser_non_client_frame_view_mus.cc +++ b/chrome/browser/ui/views/frame/browser_non_client_frame_view_mus.cc
@@ -14,6 +14,7 @@ #include "chrome/browser/ui/browser.h" #include "chrome/browser/ui/browser_commands.h" #include "chrome/browser/ui/views/frame/browser_frame.h" +#include "chrome/browser/ui/views/frame/browser_frame_mus.h" #include "chrome/browser/ui/views/frame/browser_header_painter_ash.h" #include "chrome/browser/ui/views/frame/browser_view.h" #include "chrome/browser/ui/views/frame/immersive_mode_controller.h" @@ -23,6 +24,7 @@ #include "chrome/browser/ui/views/tab_icon_view.h" #include "chrome/browser/ui/views/tabs/tab_strip.h" #include "chrome/browser/web_applications/web_app.h" +#include "components/mus/public/cpp/window.h" #include "components/signin/core/common/profile_management_switches.h" #include "content/public/browser/web_contents.h" #include "extensions/browser/extension_registry.h" @@ -100,9 +102,15 @@ BrowserView* browser_view) : BrowserNonClientFrameView(frame, browser_view), web_app_left_header_view_(nullptr), - window_icon_(nullptr) {} + window_icon_(nullptr), + tab_strip_(nullptr) {} -BrowserNonClientFrameViewMus::~BrowserNonClientFrameViewMus() {} +BrowserNonClientFrameViewMus::~BrowserNonClientFrameViewMus() { + if (tab_strip_) { + tab_strip_->RemoveObserver(this); + tab_strip_ = nullptr; + } +} void BrowserNonClientFrameViewMus::Init() { // Initializing the TabIconView is expensive, so only do it if we need to. @@ -119,6 +127,13 @@ /////////////////////////////////////////////////////////////////////////////// // BrowserNonClientFrameView: +void BrowserNonClientFrameViewMus::OnBrowserViewInitViewsComplete() { + DCHECK(browser_view()->tabstrip()); + DCHECK(!tab_strip_); + tab_strip_ = browser_view()->tabstrip(); + tab_strip_->AddObserver(this); +} + gfx::Rect BrowserNonClientFrameViewMus::GetBoundsForTabStrip( views::View* tabstrip) const { if (!tabstrip) @@ -283,6 +298,8 @@ #endif BrowserNonClientFrameView::Layout(); + + UpdateClientArea(); } const char* BrowserNonClientFrameViewMus::GetClassName() const { @@ -377,7 +394,33 @@ /////////////////////////////////////////////////////////////////////////////// // BrowserNonClientFrameViewMus, private: -// views::NonClientFrameView: +mus::Window* BrowserNonClientFrameViewMus::mus_window() { + return static_cast<BrowserFrameMus*>(frame()->native_widget())->window(); +} + +void BrowserNonClientFrameViewMus::UpdateClientArea() { + std::vector<gfx::Rect> additional_client_area; + if (tab_strip_) { + gfx::Rect tab_strip_bounds(GetBoundsForTabStrip(tab_strip_)); + if (!tab_strip_bounds.IsEmpty() && tab_strip_->max_x()) { + tab_strip_bounds.set_width(tab_strip_->max_x()); + additional_client_area.push_back(tab_strip_bounds); + } + } + mus_window()->SetClientArea( + views::WindowManagerFrameValues::instance().normal_insets, + additional_client_area); +} + +void BrowserNonClientFrameViewMus::TabStripMaxXChanged(TabStrip* tab_strip) { + UpdateClientArea(); +} + +void BrowserNonClientFrameViewMus::TabStripDeleted(TabStrip* tab_strip) { + tab_strip_->RemoveObserver(this); + tab_strip_ = nullptr; +} + bool BrowserNonClientFrameViewMus::DoesIntersectRect( const views::View* target, const gfx::Rect& rect) const {
diff --git a/chrome/browser/ui/views/frame/browser_non_client_frame_view_mus.h b/chrome/browser/ui/views/frame/browser_non_client_frame_view_mus.h index d4a3fd2..774a4b3 100644 --- a/chrome/browser/ui/views/frame/browser_non_client_frame_view_mus.h +++ b/chrome/browser/ui/views/frame/browser_non_client_frame_view_mus.h
@@ -9,11 +9,16 @@ #include "base/memory/scoped_ptr.h" #include "chrome/browser/ui/views/frame/browser_non_client_frame_view.h" #include "chrome/browser/ui/views/tab_icon_view_model.h" +#include "chrome/browser/ui/views/tabs/tab_strip_observer.h" #include "ui/views/controls/button/button.h" class TabIconView; class WebAppLeftHeaderView; +namespace mus { +class Window; +} + namespace views { class ImageButton; class ToggleImageButton; @@ -21,7 +26,8 @@ class BrowserNonClientFrameViewMus : public BrowserNonClientFrameView, public TabIconViewModel, - public views::ButtonListener { + public views::ButtonListener, + public TabStripObserver { public: static const char kViewClassName[]; @@ -31,6 +37,7 @@ void Init(); // BrowserNonClientFrameView: + void OnBrowserViewInitViewsComplete() override; gfx::Rect GetBoundsForTabStrip(views::View* tabstrip) const override; int GetTopInset(bool restored) const override; int GetThemeBackgroundXInset() const override; @@ -69,6 +76,15 @@ void UpdateNewAvatarButtonImpl() override; private: + mus::Window* mus_window(); + + // Resets the client area on the mus::Window. + void UpdateClientArea(); + + // TabStripObserver: + void TabStripMaxXChanged(TabStrip* tab_strip) override; + void TabStripDeleted(TabStrip* tab_strip) override; + // views::NonClientFrameView: bool DoesIntersectRect(const views::View* target, const gfx::Rect& rect) const override; @@ -122,6 +138,8 @@ // For popups, the window icon. TabIconView* window_icon_; + TabStrip* tab_strip_; + DISALLOW_COPY_AND_ASSIGN(BrowserNonClientFrameViewMus); };
diff --git a/chrome/browser/ui/views/frame/browser_view.cc b/chrome/browser/ui/views/frame/browser_view.cc index 08d9722..9769133 100644 --- a/chrome/browser/ui/views/frame/browser_view.cc +++ b/chrome/browser/ui/views/frame/browser_view.cc
@@ -2164,6 +2164,8 @@ #endif GetLocationBar()->GetOmniboxView()->model()->popup_model()->AddObserver(this); + + frame_->OnBrowserViewInitViewsComplete(); } void BrowserView::LoadingAnimationCallback() {
diff --git a/chrome/browser/ui/views/infobars/infobar_view.cc b/chrome/browser/ui/views/infobars/infobar_view.cc index a1ad2e5..c454d42 100644 --- a/chrome/browser/ui/views/infobars/infobar_view.cc +++ b/chrome/browser/ui/views/infobars/infobar_view.cc
@@ -276,7 +276,7 @@ // canvas->sk_canvas()->clipPath(fill_path_); DCHECK_EQ(total_height(), height()) << "Infobar piecewise heights do not match overall height"; - ui::ClipRecorder clip_recorder(context, size()); + ui::ClipRecorder clip_recorder(context); clip_recorder.ClipRect(gfx::Rect(0, arrow_height(), width(), bar_height())); views::View::PaintChildren(context); }
diff --git a/chrome/browser/ui/views/location_bar/page_action_with_badge_view.cc b/chrome/browser/ui/views/location_bar/page_action_with_badge_view.cc index 5fee7a65..c0be1c9 100644 --- a/chrome/browser/ui/views/location_bar/page_action_with_badge_view.cc +++ b/chrome/browser/ui/views/location_bar/page_action_with_badge_view.cc
@@ -21,8 +21,8 @@ } gfx::Size PageActionWithBadgeView::GetPreferredSize() const { - return gfx::Size(ExtensionAction::kPageActionIconMaxSize, - ExtensionAction::kPageActionIconMaxSize); + return gfx::Size(ExtensionAction::ActionIconSize(), + ExtensionAction::ActionIconSize()); } void PageActionWithBadgeView::UpdateVisibility(content::WebContents* contents) {
diff --git a/chrome/browser/ui/views/omnibox/omnibox_popup_contents_view.cc b/chrome/browser/ui/views/omnibox/omnibox_popup_contents_view.cc index 276ce89..0d1f683a 100644 --- a/chrome/browser/ui/views/omnibox/omnibox_popup_contents_view.cc +++ b/chrome/browser/ui/views/omnibox/omnibox_popup_contents_view.cc
@@ -465,7 +465,7 @@ contents_bounds.Inset(0, views::NonClientFrameView::kClientEdgeThickness, 0, bottom_shadow_->height() - interior); - ui::ClipRecorder clip_recorder(context, size()); + ui::ClipRecorder clip_recorder(context); clip_recorder.ClipRect(contents_bounds); { ui::PaintRecorder recorder(context, size());
diff --git a/chrome/browser/ui/views/profiles/profile_chooser_view.cc b/chrome/browser/ui/views/profiles/profile_chooser_view.cc index 27d9686b..e7a061ea 100644 --- a/chrome/browser/ui/views/profiles/profile_chooser_view.cc +++ b/chrome/browser/ui/views/profiles/profile_chooser_view.cc
@@ -327,7 +327,7 @@ void PaintChildren(const ui::PaintContext& context) override { // Display any children (the "change photo" overlay) as a circle. - ui::ClipRecorder clip_recorder(context, size()); + ui::ClipRecorder clip_recorder(context); clip_recorder.ClipPathWithAntiAliasing(circular_mask_); View::PaintChildren(context); }
diff --git a/chrome/browser/ui/views/tabs/tab_strip.cc b/chrome/browser/ui/views/tabs/tab_strip.cc index 52a3e73..3343a38c 100644 --- a/chrome/browser/ui/views/tabs/tab_strip.cc +++ b/chrome/browser/ui/views/tabs/tab_strip.cc
@@ -2314,7 +2314,10 @@ const int new_tab_x = tabs_.ideal_bounds(tabs_.view_size() - 1).right() - GetLayoutConstant(TABSTRIP_NEW_TAB_BUTTON_OVERLAP); + const int old_max_x = newtab_button_bounds_.right(); newtab_button_bounds_.set_origin(gfx::Point(new_tab_x, 0)); + if (newtab_button_bounds_.right() != old_max_x) + FOR_EACH_OBSERVER(TabStripObserver, observers_, TabStripMaxXChanged(this)); } int TabStrip::GenerateIdealBoundsForPinnedTabs(int* first_non_pinned_index) {
diff --git a/chrome/browser/ui/views/tabs/tab_strip.h b/chrome/browser/ui/views/tabs/tab_strip.h index ec44b678..143a414a 100644 --- a/chrome/browser/ui/views/tabs/tab_strip.h +++ b/chrome/browser/ui/views/tabs/tab_strip.h
@@ -136,6 +136,10 @@ return tabs_.ideal_bounds(tab_data_index); } + // Max x-coordinate the tabstrip draws at, which is the right edge of the new + // tab button. + int max_x() const { return newtab_button_bounds_.right(); } + // Returns the Tab at |index|. Tab* tab_at(int index) const { return tabs_.view_at(index); }
diff --git a/chrome/browser/ui/views/tabs/tab_strip_observer.cc b/chrome/browser/ui/views/tabs/tab_strip_observer.cc index 03baafc9..cafb722 100644 --- a/chrome/browser/ui/views/tabs/tab_strip_observer.cc +++ b/chrome/browser/ui/views/tabs/tab_strip_observer.cc
@@ -17,3 +17,5 @@ void TabStripObserver::TabStripDeleted(TabStrip* tab_strip) { } + +void TabStripObserver::TabStripMaxXChanged(TabStrip* tab_strip) {}
diff --git a/chrome/browser/ui/views/tabs/tab_strip_observer.h b/chrome/browser/ui/views/tabs/tab_strip_observer.h index b9dea2e..f36a8461 100644 --- a/chrome/browser/ui/views/tabs/tab_strip_observer.h +++ b/chrome/browser/ui/views/tabs/tab_strip_observer.h
@@ -37,6 +37,9 @@ // be dropped. virtual void TabStripDeleted(TabStrip* tab_strip); + // tab_strip->max_x() has changed. + virtual void TabStripMaxXChanged(TabStrip* tab_strip); + protected: virtual ~TabStripObserver() {} };
diff --git a/chrome/browser/ui/views/tabs/window_finder_win.cc b/chrome/browser/ui/views/tabs/window_finder_win.cc index 63d2f48..79897ff3 100644 --- a/chrome/browser/ui/views/tabs/window_finder_win.cc +++ b/chrome/browser/ui/views/tabs/window_finder_win.cc
@@ -4,6 +4,8 @@ #include "chrome/browser/ui/views/tabs/window_finder.h" +#include <shobjidl.h> + #include "base/win/scoped_gdi_object.h" #include "base/win/windows_version.h" #include "ui/aura/window.h" @@ -150,29 +152,6 @@ // LocalProcessWindowFinder --------------------------------------------------- -// Copied from ShObjIdl.h in 10.0.10240.0 SDK. This can be removed once we -// update to the newer SDK. -#if NTDDI_VERSION < 0x0A000000 -class DECLSPEC_UUID("aa509086-5ca9-4c25-8f95-589d3c07b48a") - VirtualDesktopManager; - -MIDL_INTERFACE("a5cd92ff-29be-454c-8d04-d82879fb3f1b") -IVirtualDesktopManager : public IUnknown { - public: - virtual HRESULT STDMETHODCALLTYPE IsWindowOnCurrentVirtualDesktop( - /* [in] */ __RPC__in HWND topLevelWindow, - /* [out] */ __RPC__out BOOL * onCurrentDesktop) = 0; - - virtual HRESULT STDMETHODCALLTYPE GetWindowDesktopId( - /* [in] */ __RPC__in HWND topLevelWindow, - /* [out] */ __RPC__out GUID * desktopId) = 0; - - virtual HRESULT STDMETHODCALLTYPE MoveWindowToDesktop( - /* [in] */ __RPC__in HWND topLevelWindow, - /* [in] */ __RPC__in REFGUID desktopId) = 0; -}; -#endif // NTDDI_VERSION < 0x0A000000 - // Helper class to determine if a particular point contains a window from our // process. class LocalProcessWindowFinder : public BaseWindowFinder {
diff --git a/chrome/browser/ui/website_settings/website_settings.cc b/chrome/browser/ui/website_settings/website_settings.cc index a82135a..c717aac 100644 --- a/chrome/browser/ui/website_settings/website_settings.cc +++ b/chrome/browser/ui/website_settings/website_settings.cc
@@ -30,6 +30,7 @@ #include "chrome/browser/ssl/chrome_ssl_host_state_delegate_factory.h" #include "chrome/browser/ui/website_settings/website_settings_ui.h" #include "chrome/common/chrome_switches.h" +#include "chrome/common/features.h" #include "chrome/common/pref_names.h" #include "chrome/common/url_constants.h" #include "chrome/grit/chromium_strings.h" @@ -313,7 +314,7 @@ const GURL& url, const SecurityStateModel::SecurityInfo& security_info) { bool isChromeUINativeScheme = false; -#if defined(OS_ANDROID) +#if BUILDFLAG(ANDROID_JAVA_UI) isChromeUINativeScheme = url.SchemeIs(chrome::kChromeUINativeScheme); #endif
diff --git a/chrome/browser/ui/webui/browsing_history_handler.cc b/chrome/browser/ui/webui/browsing_history_handler.cc index 1ba3f77..86b83ff 100644 --- a/chrome/browser/ui/webui/browsing_history_handler.cc +++ b/chrome/browser/ui/webui/browsing_history_handler.cc
@@ -28,6 +28,7 @@ #include "chrome/browser/ui/browser_finder.h" #include "chrome/browser/ui/chrome_pages.h" #include "chrome/browser/ui/webui/favicon_source.h" +#include "chrome/common/features.h" #include "chrome/common/pref_names.h" #include "chrome/grit/generated_resources.h" #include "components/bookmarks/browser/bookmark_model.h" @@ -59,7 +60,7 @@ #include "chrome/browser/supervised_user/supervised_user_url_filter.h" #endif -#if defined(OS_ANDROID) +#if BUILDFLAG(ANDROID_JAVA_UI) #include "chrome/browser/android/chrome_application.h" #endif @@ -544,7 +545,7 @@ void BrowsingHistoryHandler::HandleClearBrowsingData( const base::ListValue* args) { -#if defined(OS_ANDROID) +#if BUILDFLAG(ANDROID_JAVA_UI) chrome::android::ChromeApplication::OpenClearBrowsingData( web_ui()->GetWebContents()); #else
diff --git a/chrome/browser/ui/webui/chromeos/login/gaia_screen_handler.cc b/chrome/browser/ui/webui/chromeos/login/gaia_screen_handler.cc index ef288e4a..75446090 100644 --- a/chrome/browser/ui/webui/chromeos/login/gaia_screen_handler.cc +++ b/chrome/browser/ui/webui/chromeos/login/gaia_screen_handler.cc
@@ -21,8 +21,6 @@ #include "chrome/browser/chromeos/login/users/chrome_user_manager.h" #include "chrome/browser/chromeos/net/network_portal_detector_impl.h" #include "chrome/browser/chromeos/policy/browser_policy_connector_chromeos.h" -#include "chrome/browser/chromeos/policy/consumer_management_service.h" -#include "chrome/browser/chromeos/policy/consumer_management_stage.h" #include "chrome/browser/chromeos/profiles/profile_helper.h" #include "chrome/browser/chromeos/settings/cros_settings.h" #include "chrome/browser/io_thread.h" @@ -79,7 +77,6 @@ } void UpdateAuthParams(base::DictionaryValue* params, - bool is_enrolling_consumer_management, bool is_restrictive_proxy) { CrosSettings* cros_settings = CrosSettings::Get(); bool allow_new_user = true; @@ -105,10 +102,7 @@ // Now check whether we're in multi-profiles user adding scenario and // disable GAIA right panel features if that's the case. - // For consumer management enrollment, we also hide all right panel components - // and show only an enrollment message. - if (UserAddingScreen::Get()->IsRunning() || - is_enrolling_consumer_management) { + if (UserAddingScreen::Get()->IsRunning()) { params->SetBoolean("createAccount", false); params->SetBoolean("guestSignin", false); params->SetBoolean("supervisedUsersCanCreate", false); @@ -166,20 +160,15 @@ // GAPS cookie. std::string gaps_cookie; - - // Whether consumer management enrollment is in progress. - bool is_enrolling_consumer_management = false; }; GaiaScreenHandler::GaiaContext::GaiaContext() {} GaiaScreenHandler::GaiaScreenHandler( CoreOobeActor* core_oobe_actor, - const scoped_refptr<NetworkStateInformer>& network_state_informer, - policy::ConsumerManagementService* consumer_management) + const scoped_refptr<NetworkStateInformer>& network_state_informer) : BaseScreenHandler(kJsScreenPath), network_state_informer_(network_state_informer), - consumer_management_(consumer_management), core_oobe_actor_(core_oobe_actor), weak_factory_(this) { DCHECK(network_state_informer_.get()); @@ -202,8 +191,6 @@ const GaiaContext& context, const std::string& platform_version) { base::DictionaryValue params; - const bool is_enrolling_consumer_management = - context.is_enrolling_consumer_management; params.SetBoolean("forceReload", context.force_reload); params.SetBoolean("isShowUsers", context.show_users); @@ -211,12 +198,9 @@ params.SetString("gaiaId", context.gaia_id); params.SetBoolean("readOnlyEmail", true); params.SetString("email", context.email); - params.SetBoolean("isEnrollingConsumerManagement", - is_enrolling_consumer_management); params.SetString("gapsCookie", context.gaps_cookie); - UpdateAuthParams(¶ms, is_enrolling_consumer_management, - IsRestrictiveProxy()); + UpdateAuthParams(¶ms, IsRestrictiveProxy()); if (!context.use_offline) { const std::string app_locale = g_browser_process->GetApplicationLocale(); @@ -502,30 +486,7 @@ const std::string& typed_email, const std::string& password, bool using_saml) { - if (!is_enrolling_consumer_management_) { - DoCompleteLogin(gaia_id, typed_email, password, using_saml); - return; - } - - // Consumer management enrollment is in progress. - const std::string owner_email = - user_manager::UserManager::Get()->GetOwnerAccountId().GetUserEmail(); - if (typed_email != owner_email) { - // Show Gaia sign-in screen again, since we only allow the owner to sign - // in. - populated_email_ = owner_email; - ShowGaiaAsync(is_enrolling_consumer_management_); - return; - } - - CHECK(consumer_management_); - consumer_management_->SetOwner(owner_email, - base::Bind(&GaiaScreenHandler::OnSetOwnerDone, - weak_factory_.GetWeakPtr(), - gaia_id, - typed_email, - password, - using_saml)); + DoCompleteLogin(gaia_id, typed_email, password, using_saml); } void GaiaScreenHandler::HandleUsingSAMLAPI() { @@ -569,25 +530,6 @@ SubmitLoginFormForTest(); } -void GaiaScreenHandler::OnSetOwnerDone(const std::string& gaia_id, - const std::string& typed_email, - const std::string& password, - bool using_saml, - bool success) { - CHECK(consumer_management_); - if (success) { - consumer_management_->SetStage( - policy::ConsumerManagementStage::EnrollmentOwnerStored()); - } else { - LOG(ERROR) << "Failed to write owner e-mail to boot lockbox."; - consumer_management_->SetStage( - policy::ConsumerManagementStage::EnrollmentBootLockboxFailed()); - // We should continue logging in the user, as there's not much we can do - // here. - } - DoCompleteLogin(gaia_id, typed_email, password, using_saml); -} - void GaiaScreenHandler::DoCompleteLogin(const std::string& gaia_id, const std::string& typed_email, const std::string& password, @@ -706,8 +648,7 @@ UMA_HISTOGRAM_BOOLEAN("ChromeOS.SAML.APIUsed", api_used); } -void GaiaScreenHandler::ShowGaiaAsync(bool is_enrolling_consumer_management) { - is_enrolling_consumer_management_ = is_enrolling_consumer_management; +void GaiaScreenHandler::ShowGaiaAsync() { show_when_dns_and_cookies_cleared_ = true; if (gaia_silent_load_ && populated_email_.empty()) { dns_cleared_ = true; @@ -841,7 +782,6 @@ context.force_reload = force; context.use_offline = offline; context.email = populated_email_; - context.is_enrolling_consumer_management = is_enrolling_consumer_management_; std::string gaia_id; if (!context.email.empty() &&
diff --git a/chrome/browser/ui/webui/chromeos/login/gaia_screen_handler.h b/chrome/browser/ui/webui/chromeos/login/gaia_screen_handler.h index d404ac51..2e82d52e 100644 --- a/chrome/browser/ui/webui/chromeos/login/gaia_screen_handler.h +++ b/chrome/browser/ui/webui/chromeos/login/gaia_screen_handler.h
@@ -19,10 +19,6 @@ class AccountId; -namespace policy { -class ConsumerManagementService; -} - namespace chromeos { class SigninScreenHandler; @@ -41,8 +37,7 @@ GaiaScreenHandler( CoreOobeActor* core_oobe_actor, - const scoped_refptr<NetworkStateInformer>& network_state_informer, - policy::ConsumerManagementService* consumer_management); + const scoped_refptr<NetworkStateInformer>& network_state_informer); ~GaiaScreenHandler() override; // Decides whether an auth extension should be pre-loaded. If it should, @@ -112,13 +107,6 @@ void HandleIdentifierEntered(const std::string& account_identifier); - // This is called when ConsumerManagementService::SetOwner() returns. - void OnSetOwnerDone(const std::string& gaia_id, - const std::string& typed_email, - const std::string& password, - bool using_saml, - bool success); - // Really handles the complete login message. void DoCompleteLogin(const std::string& gaia_id, const std::string& typed_email, @@ -153,7 +141,7 @@ // cleans DNS cache and cookies. In the latter case, the request to show the // screen can be canceled by calling CancelShowGaiaAsync() while the clean-up // is in progress. - void ShowGaiaAsync(bool is_enrolling_consumer_management); + void ShowGaiaAsync(); // Cancels the request to show the sign-in screen while the asynchronous // clean-up process that precedes the screen showing is in progress. @@ -211,9 +199,6 @@ // Network state informer used to keep signin screen up. scoped_refptr<NetworkStateInformer> network_state_informer_; - // Consumer management service for checking if enrollment is in progress. - policy::ConsumerManagementService* consumer_management_ = nullptr; - CoreOobeActor* core_oobe_actor_ = nullptr; // Email to pre-populate with. @@ -242,9 +227,6 @@ // API was used. bool using_saml_api_ = false; - // Whether consumer management enrollment is in progress. - bool is_enrolling_consumer_management_ = false; - // Test credentials. std::string test_user_; std::string test_pass_;
diff --git a/chrome/browser/ui/webui/chromeos/login/oobe_ui.cc b/chrome/browser/ui/webui/chromeos/login/oobe_ui.cc index 5bf9916..287a357 100644 --- a/chrome/browser/ui/webui/chromeos/login/oobe_ui.cc +++ b/chrome/browser/ui/webui/chromeos/login/oobe_ui.cc
@@ -21,7 +21,6 @@ #include "chrome/browser/chromeos/login/ui/login_display_host_impl.h" #include "chrome/browser/chromeos/login/wizard_controller.h" #include "chrome/browser/chromeos/policy/browser_policy_connector_chromeos.h" -#include "chrome/browser/chromeos/policy/consumer_management_service.h" #include "chrome/browser/chromeos/settings/shutdown_policy_handler.h" #include "chrome/browser/chromeos/system/input_device_settings.h" #include "chrome/browser/extensions/signin/gaia_auth_extension_loader.h" @@ -307,16 +306,11 @@ user_image_view_ = user_image_screen_handler; AddScreenHandler(user_image_screen_handler); - policy::ConsumerManagementService* consumer_management = - g_browser_process->platform_part()->browser_policy_connector_chromeos()-> - GetConsumerManagementService(); - user_board_screen_handler_ = new UserBoardScreenHandler(); AddScreenHandler(user_board_screen_handler_); gaia_screen_handler_ = - new GaiaScreenHandler( - core_handler_, network_state_informer_, consumer_management); + new GaiaScreenHandler(core_handler_, network_state_informer_); AddScreenHandler(gaia_screen_handler_); signin_screen_handler_ =
diff --git a/chrome/browser/ui/webui/chromeos/login/signin_screen_handler.cc b/chrome/browser/ui/webui/chromeos/login/signin_screen_handler.cc index a1f1a722..4d25dca 100644 --- a/chrome/browser/ui/webui/chromeos/login/signin_screen_handler.cc +++ b/chrome/browser/ui/webui/chromeos/login/signin_screen_handler.cc
@@ -43,8 +43,6 @@ #include "chrome/browser/chromeos/login/users/wallpaper/wallpaper_manager.h" #include "chrome/browser/chromeos/login/wizard_controller.h" #include "chrome/browser/chromeos/policy/browser_policy_connector_chromeos.h" -#include "chrome/browser/chromeos/policy/consumer_management_service.h" -#include "chrome/browser/chromeos/policy/consumer_management_stage.h" #include "chrome/browser/chromeos/policy/device_local_account.h" #include "chrome/browser/chromeos/profiles/profile_helper.h" #include "chrome/browser/chromeos/settings/cros_settings.h" @@ -270,13 +268,6 @@ max_mode_delegate_.reset(new TouchViewControllerDelegate()); max_mode_delegate_->AddObserver(this); - - policy::ConsumerManagementService* consumer_management = - g_browser_process->platform_part()->browser_policy_connector_chromeos()-> - GetConsumerManagementService(); - is_enrolling_consumer_management_ = - consumer_management && - consumer_management->GetStage().IsEnrollmentRequested(); } SigninScreenHandler::~SigninScreenHandler() { @@ -495,8 +486,6 @@ AddCallback("focusPod", &SigninScreenHandler::HandleFocusPod); AddCallback("getPublicSessionKeyboardLayouts", &SigninScreenHandler::HandleGetPublicSessionKeyboardLayouts); - AddCallback("cancelConsumerManagementEnrollment", - &SigninScreenHandler::HandleCancelConsumerManagementEnrollment); AddCallback("getTouchViewState", &SigninScreenHandler::HandleGetTouchViewState); AddCallback("logRemoveUserWarningShown", @@ -518,14 +507,7 @@ oobe_ui_ = context.oobe_ui(); std::string email; - if (is_enrolling_consumer_management_) { - // We don't check if the value of the owner e-mail is trusted because it is - // only used to pre-fill the e-mail field in Gaia sign-in page and a cached - // value is sufficient. - CrosSettings::Get()->GetString(kDeviceOwner, &email); - } else { - email = context.email(); - } + email = context.email(); gaia_screen_handler_->set_populated_email(email); ShowImpl(); histogram_helper_->OnScreenShow(); @@ -579,7 +561,7 @@ GetOobeUI()->AddObserver(this); } - if (oobe_ui_ || is_enrolling_consumer_management_) { + if (oobe_ui_) { // Shows new user sign-in for OOBE. OnShowAddUser(); } else { @@ -1285,17 +1267,6 @@ delegate_->Login(context, specifics); } -void SigninScreenHandler::HandleCancelConsumerManagementEnrollment() { - policy::ConsumerManagementService* consumer_management = - g_browser_process->platform_part()->browser_policy_connector_chromeos()-> - GetConsumerManagementService(); - CHECK(consumer_management); - consumer_management->SetStage( - policy::ConsumerManagementStage::EnrollmentCanceled()); - is_enrolling_consumer_management_ = false; - ShowImpl(); -} - void SigninScreenHandler::HandleGetTouchViewState() { if (max_mode_delegate_) { CallJS("login.AccountPickerScreen.setTouchViewState", @@ -1404,7 +1375,7 @@ void SigninScreenHandler::OnShowAddUser() { is_account_picker_showing_first_time_ = false; - gaia_screen_handler_->ShowGaiaAsync(is_enrolling_consumer_management_); + gaia_screen_handler_->ShowGaiaAsync(); } net::Error SigninScreenHandler::FrameError() const {
diff --git a/chrome/browser/ui/webui/chromeos/login/signin_screen_handler.h b/chrome/browser/ui/webui/chromeos/login/signin_screen_handler.h index 853fb564..3954a310 100644 --- a/chrome/browser/ui/webui/chromeos/login/signin_screen_handler.h +++ b/chrome/browser/ui/webui/chromeos/login/signin_screen_handler.h
@@ -358,7 +358,6 @@ bool diagnostic_mode); void HandleGetPublicSessionKeyboardLayouts(const AccountId& account_id, const std::string& locale); - void HandleCancelConsumerManagementEnrollment(); void HandleGetTouchViewState(); void HandleLogRemoveUserWarningShown(); void HandleFirstIncorrectPasswordAttempt(const AccountId& account_id); @@ -472,9 +471,6 @@ // Maximized mode controller delegate. scoped_ptr<TouchViewControllerDelegate> max_mode_delegate_; - // Whether consumer management enrollment is in progress. - bool is_enrolling_consumer_management_ = false; - // Input Method Engine state used at signin screen. scoped_refptr<input_method::InputMethodManager::State> ime_state_;
diff --git a/chrome/browser/ui/webui/extensions/extensions_ui.cc b/chrome/browser/ui/webui/extensions/extensions_ui.cc index 2ea97b1..77716c4 100644 --- a/chrome/browser/ui/webui/extensions/extensions_ui.cc +++ b/chrome/browser/ui/webui/extensions/extensions_ui.cc
@@ -77,6 +77,9 @@ source->AddResourcePath("item.css", IDR_MD_EXTENSIONS_ITEM_CSS); source->AddResourcePath("item.html", IDR_MD_EXTENSIONS_ITEM_HTML); source->AddResourcePath("item.js", IDR_MD_EXTENSIONS_ITEM_JS); + source->AddResourcePath("item_list.css", IDR_MD_EXTENSIONS_ITEM_LIST_CSS); + source->AddResourcePath("item_list.html", IDR_MD_EXTENSIONS_ITEM_LIST_HTML); + source->AddResourcePath("item_list.js", IDR_MD_EXTENSIONS_ITEM_LIST_JS); source->AddResourcePath("service.html", IDR_MD_EXTENSIONS_SERVICE_HTML); source->AddResourcePath("service.js", IDR_MD_EXTENSIONS_SERVICE_JS); source->AddResourcePath("sidebar.css", IDR_MD_EXTENSIONS_SIDEBAR_CSS);
diff --git a/chrome/browser/ui/webui/inspect_ui_browsertest.cc b/chrome/browser/ui/webui/inspect_ui_browsertest.cc index 60458d4..1286acb 100644 --- a/chrome/browser/ui/webui/inspect_ui_browsertest.cc +++ b/chrome/browser/ui/webui/inspect_ui_browsertest.cc
@@ -68,7 +68,8 @@ new base::StringValue(kSharedWorkerTestPage))); } -IN_PROC_BROWSER_TEST_F(InspectUITest, AndroidTargets) { +// Flaky due to failure to bind a hardcoded port. crbug.com/566057 +IN_PROC_BROWSER_TEST_F(InspectUITest, DISABLED_AndroidTargets) { DevToolsAndroidBridge* android_bridge = DevToolsAndroidBridge::Factory::GetForProfile(browser()->profile()); AndroidDeviceManager::DeviceProviders providers;
diff --git a/chrome/browser/ui/webui/md_downloads/downloads_list_tracker.cc b/chrome/browser/ui/webui/md_downloads/downloads_list_tracker.cc index b163644..f67a1cb 100644 --- a/chrome/browser/ui/webui/md_downloads/downloads_list_tracker.cc +++ b/chrome/browser/ui/webui/md_downloads/downloads_list_tracker.cc
@@ -235,14 +235,7 @@ file_value->SetBoolean("file_externally_removed", download_item->GetFileExternallyRemoved()); file_value->SetBoolean("resume", download_item->CanResume()); - - bool incognito = false; - auto* original_manager = GetOriginalNotifierManager(); - if (original_manager) { - incognito = - original_manager->GetDownload(download_item->GetId()) == download_item; - } - file_value->SetBoolean("otr", incognito); + file_value->SetBoolean("otr", IsIncognito(*download_item)); const char* danger_type = ""; base::string16 last_reason_text; @@ -307,6 +300,11 @@ return file_value.Pass(); } +bool DownloadsListTracker::IsIncognito(const DownloadItem& item) const { + return GetOriginalNotifierManager() && GetMainNotifierManager() && + GetMainNotifierManager()->GetDownload(item.GetId()) == &item; +} + const DownloadItem* DownloadsListTracker::GetItemForTesting(size_t index) const { if (index >= sorted_visible_items_.size()) @@ -335,9 +333,9 @@ Profile* profile = Profile::FromBrowserContext( GetMainNotifierManager()->GetBrowserContext()); if (profile->IsOffTheRecord()) { + Profile* original_profile = profile->GetOriginalProfile(); original_notifier_.reset(new AllDownloadItemNotifier( - BrowserContext::GetDownloadManager(profile->GetOriginalProfile()), - this)); + BrowserContext::GetDownloadManager(original_profile), this)); } RebuildSortedSet();
diff --git a/chrome/browser/ui/webui/md_downloads/downloads_list_tracker.h b/chrome/browser/ui/webui/md_downloads/downloads_list_tracker.h index 05399b3..00c8374 100644 --- a/chrome/browser/ui/webui/md_downloads/downloads_list_tracker.h +++ b/chrome/browser/ui/webui/md_downloads/downloads_list_tracker.h
@@ -68,6 +68,9 @@ virtual scoped_ptr<base::DictionaryValue> CreateDownloadItemValue( content::DownloadItem* item) const; + // Exposed for testing. + bool IsIncognito(const content::DownloadItem& item) const; + const content::DownloadItem* GetItemForTesting(size_t index) const; private:
diff --git a/chrome/browser/ui/webui/md_downloads/downloads_list_tracker_unittest.cc b/chrome/browser/ui/webui/md_downloads/downloads_list_tracker_unittest.cc index 9d279e4..ced1f8f5 100644 --- a/chrome/browser/ui/webui/md_downloads/downloads_list_tracker_unittest.cc +++ b/chrome/browser/ui/webui/md_downloads/downloads_list_tracker_unittest.cc
@@ -77,6 +77,7 @@ : DownloadsListTracker(manager, web_ui, base::Bind(&ShouldShowItem)) {} ~TestDownloadsListTracker() override {} + using DownloadsListTracker::IsIncognito; using DownloadsListTracker::GetItemForTesting; protected: @@ -125,6 +126,7 @@ tracker_.reset(new TestDownloadsListTracker(manager(), web_ui())); } + TestingProfile* profile() { return &profile_; } content::DownloadManager* manager() { return &manager_; } content::TestWebUI* web_ui() { return &web_ui_; } TestDownloadsListTracker* tracker() { return tracker_.get(); } @@ -271,3 +273,17 @@ web_ui()->call_data()[0]->function_name()); EXPECT_TRUE(GetIds(web_ui()->call_data()[0]->arg2()).empty()); } + +TEST_F(DownloadsListTrackerTest, Incognito) { + testing::NiceMock<content::MockDownloadManager> incognito_manager; + ON_CALL(incognito_manager, GetBrowserContext()).WillByDefault(Return( + TestingProfile::Builder().BuildIncognito(profile()))); + + MockDownloadItem item; + EXPECT_CALL(item, GetId()).WillRepeatedly(Return(0)); + + ON_CALL(incognito_manager, GetDownload(0)).WillByDefault(Return(&item)); + + TestDownloadsListTracker tracker(&incognito_manager, web_ui()); + EXPECT_TRUE(tracker.IsIncognito(item)); +}
diff --git a/chrome/browser/ui/webui/media_router/media_router_webui_message_handler.cc b/chrome/browser/ui/webui/media_router/media_router_webui_message_handler.cc index 4c911f9..ce1da635 100644 --- a/chrome/browser/ui/webui/media_router/media_router_webui_message_handler.cc +++ b/chrome/browser/ui/webui/media_router/media_router_webui_message_handler.cc
@@ -53,12 +53,14 @@ sink_val->SetString("id", sink.id()); sink_val->SetString("name", sink.name()); sink_val->SetInteger("iconType", sink.icon_type()); + if (!sink.description().empty()) + sink_val->SetString("description", sink.description()); scoped_ptr<base::ListValue> cast_modes_val(new base::ListValue); for (MediaCastMode cast_mode : sink_with_cast_modes.cast_modes) cast_modes_val->AppendInteger(cast_mode); - sink_val->Set("castModes", cast_modes_val.Pass()); + sink_val->Set("castModes", cast_modes_val.Pass()); value->Append(sink_val.release()); } @@ -68,14 +70,12 @@ scoped_ptr<base::DictionaryValue> RouteToValue( const MediaRoute& route, const std::string& extension_id) { scoped_ptr<base::DictionaryValue> dictionary(new base::DictionaryValue); - dictionary->SetString("id", route.media_route_id()); dictionary->SetString("sinkId", route.media_sink_id()); dictionary->SetString("description", route.description()); dictionary->SetBoolean("isLocal", route.is_local()); const std::string& custom_path = route.custom_controller_path(); - if (!custom_path.empty()) { std::string full_custom_controller_path = base::StringPrintf("%s://%s/%s", extensions::kExtensionScheme, extension_id.c_str(),
diff --git a/chrome/browser/ui/webui/memory_internals/memory_internals_proxy.cc b/chrome/browser/ui/webui/memory_internals/memory_internals_proxy.cc index dd80abee..5ce9a26e 100644 --- a/chrome/browser/ui/webui/memory_internals/memory_internals_proxy.cc +++ b/chrome/browser/ui/webui/memory_internals/memory_internals_proxy.cc
@@ -31,6 +31,7 @@ #include "chrome/browser/ui/browser_iterator.h" #include "chrome/browser/ui/tab_contents/tab_contents_iterator.h" #include "chrome/browser/ui/webui/memory_internals/memory_internals_handler.h" +#include "chrome/common/features.h" #include "content/public/browser/navigation_controller.h" #include "content/public/browser/navigation_entry.h" #include "content/public/browser/render_process_host.h" @@ -82,7 +83,7 @@ void GetAllWebContents(std::set<content::WebContents*>* web_contents) { // Add all the existing WebContentses. -#if defined(OS_ANDROID) +#if BUILDFLAG(ANDROID_JAVA_UI) for (TabModelList::const_iterator iter = TabModelList::begin(); iter != TabModelList::end(); ++iter) { TabModel* model = *iter; @@ -223,7 +224,7 @@ void MemoryInternalsProxy::RequestRendererDetails() { renderer_details_->Clear(); -#if defined(OS_ANDROID) +#if BUILDFLAG(ANDROID_JAVA_UI) for (TabModelList::const_iterator iter = TabModelList::begin(); iter != TabModelList::end(); ++iter) { TabModel* model = *iter;
diff --git a/chrome/browser/ui/webui/net_export_ui.cc b/chrome/browser/ui/webui/net_export_ui.cc index e5f96ea..f5de774 100644 --- a/chrome/browser/ui/webui/net_export_ui.cc +++ b/chrome/browser/ui/webui/net_export_ui.cc
@@ -13,6 +13,7 @@ #include "base/values.h" #include "chrome/browser/browser_process.h" #include "chrome/browser/profiles/profile.h" +#include "chrome/common/features.h" #include "chrome/common/url_constants.h" #include "components/grit/components_resources.h" #include "components/net_log/chrome_net_log.h" @@ -25,7 +26,7 @@ #include "content/public/browser/web_ui_data_source.h" #include "content/public/browser/web_ui_message_handler.h" -#if defined(OS_ANDROID) +#if BUILDFLAG(ANDROID_JAVA_UI) #include "chrome/browser/android/intent_helper.h" #endif @@ -225,7 +226,7 @@ return; DCHECK_CURRENTLY_ON(BrowserThread::UI); -#if defined(OS_ANDROID) +#if BUILDFLAG(ANDROID_JAVA_UI) std::string email; std::string subject = "net_internals_log"; std::string title = "Issue number: ";
diff --git a/chrome/browser/ui/webui/settings/md_settings_localized_strings_provider.cc b/chrome/browser/ui/webui/settings/md_settings_localized_strings_provider.cc index fbb0ea8..f2ac65f 100644 --- a/chrome/browser/ui/webui/settings/md_settings_localized_strings_provider.cc +++ b/chrome/browser/ui/webui/settings/md_settings_localized_strings_provider.cc
@@ -272,7 +272,7 @@ html_source->AddLocalizedString( "powerwashDialogTitle", IDS_OPTIONS_FACTORY_RESET_HEADING); html_source->AddLocalizedString( - "powerwashDialogBody", IDS_OPTIONS_FACTORY_RESET_WARNING); + "powerwashDialogExplanation", IDS_OPTIONS_FACTORY_RESET_WARNING); html_source->AddLocalizedString( "powerwashDialogButton", IDS_RELAUNCH_BUTTON); html_source->AddLocalizedString( @@ -607,14 +607,14 @@ IDS_SETTINGS_SYNC_DISCONNECT_DELETE_PROFILE); html_source->AddLocalizedString("syncDisconnectConfirm", IDS_SETTINGS_SYNC_DISCONNECT_CONFIRM); + html_source->AddLocalizedString("manageOtherPeople", + IDS_SETTINGS_SYNC_MANAGE_OTHER_PEOPLE); html_source->AddLocalizedString("syncPageTitle", IDS_SETTINGS_SYNC); html_source->AddLocalizedString("syncLoading", IDS_SETTINGS_SYNC_LOADING); html_source->AddLocalizedString("syncTimeout", IDS_SETTINGS_SYNC_TIMEOUT); - html_source->AddLocalizedString("syncEverythingMenuOption", - IDS_SETTINGS_SYNC_EVERYTHING_MENU_OPTION); - html_source->AddLocalizedString("chooseWhatToSyncMenuOption", - IDS_SETTINGS_CHOOSE_WHAT_TO_SYNC_MENU_OPTION); + html_source->AddLocalizedString("syncEverythingCheckboxLabel", + IDS_SETTINGS_SYNC_EVERYTHING_CHECKBOX_LABEL); html_source->AddLocalizedString("appCheckboxLabel", IDS_SETTINGS_APPS_CHECKBOX_LABEL); html_source->AddLocalizedString("extensionsCheckboxLabel",
diff --git a/chrome/browser/ui/webui/settings/md_settings_ui.cc b/chrome/browser/ui/webui/settings/md_settings_ui.cc index 8417b5ae..88faceb 100644 --- a/chrome/browser/ui/webui/settings/md_settings_ui.cc +++ b/chrome/browser/ui/webui/settings/md_settings_ui.cc
@@ -46,7 +46,8 @@ content::WebUIDataSource* html_source = content::WebUIDataSource::Create(chrome::kChromeUIMdSettingsHost); - AddSettingsPageUIHandler(new ResetSettingsHandler(html_source, web_ui)); + AddSettingsPageUIHandler(ResetSettingsHandler::Create( + html_source, Profile::FromWebUI(web_ui))); // Add all settings resources. for (size_t i = 0; i < kSettingsResourcesSize; ++i) {
diff --git a/chrome/browser/ui/webui/settings/reset_settings_handler.cc b/chrome/browser/ui/webui/settings/reset_settings_handler.cc index 3cc4661..df5b272 100644 --- a/chrome/browser/ui/webui/settings/reset_settings_handler.cc +++ b/chrome/browser/ui/webui/settings/reset_settings_handler.cc
@@ -43,23 +43,31 @@ namespace settings { ResetSettingsHandler::ResetSettingsHandler( - content::WebUIDataSource* html_source, content::WebUI* web_ui) { - google_brand::GetBrand(&brandcode_); - Profile* profile = Profile::FromWebUI(web_ui); - resetter_.reset(new ProfileResetter(profile)); - + Profile* profile, bool allow_powerwash) : profile_(profile) { #if defined(OS_CHROMEOS) - policy::BrowserPolicyConnectorChromeOS* connector = - g_browser_process->platform_part()->browser_policy_connector_chromeos(); - allow_powerwash_ = !connector->IsEnterpriseManaged() && - !user_manager::UserManager::Get()->IsLoggedInAsGuest() && - !user_manager::UserManager::Get()->IsLoggedInAsSupervisedUser(); - html_source->AddBoolean("allowPowerwash", allow_powerwash_); + allow_powerwash_ = allow_powerwash; #endif // defined(OS_CHROMEOS) + google_brand::GetBrand(&brandcode_); } ResetSettingsHandler::~ResetSettingsHandler() {} +ResetSettingsHandler* ResetSettingsHandler::Create( + content::WebUIDataSource* html_source, Profile* profile) { + bool allow_powerwash = false; +#if defined(OS_CHROMEOS) + policy::BrowserPolicyConnectorChromeOS* connector = + g_browser_process->platform_part()->browser_policy_connector_chromeos(); + allow_powerwash = !connector->IsEnterpriseManaged() && + !user_manager::UserManager::Get()->IsLoggedInAsGuest() && + !user_manager::UserManager::Get()->IsLoggedInAsSupervisedUser(); + html_source->AddBoolean("allowPowerwash", allow_powerwash); +#endif // defined(OS_CHROMEOS) + + // Inject |allow_powerwash| for testing. + return new ResetSettingsHandler(profile, allow_powerwash); +} + void ResetSettingsHandler::RegisterMessages() { web_ui()->RegisterMessageCallback("performResetProfileSettings", base::Bind(&ResetSettingsHandler::HandleResetProfileSettings, @@ -104,14 +112,13 @@ bool send_feedback) { web_ui()->CallJavascriptFunction("SettingsResetPage.doneResetting"); if (send_feedback && setting_snapshot_) { - Profile* profile = Profile::FromWebUI(web_ui()); - ResettableSettingsSnapshot current_snapshot(profile); + ResettableSettingsSnapshot current_snapshot(profile_); int difference = setting_snapshot_->FindDifferentFields(current_snapshot); if (difference) { setting_snapshot_->Subtract(current_snapshot); std::string report = SerializeSettingsReport(*setting_snapshot_, difference); - SendSettingsFeedback(report, profile); + SendSettingsFeedback(report, profile_); } } setting_snapshot_.reset(); @@ -119,9 +126,8 @@ void ResetSettingsHandler::OnShowResetProfileDialog( const base::ListValue* value) { - if (!resetter_->IsActive()) { - setting_snapshot_.reset( - new ResettableSettingsSnapshot(Profile::FromWebUI(web_ui()))); + if (!GetResetter()->IsActive()) { + setting_snapshot_.reset(new ResettableSettingsSnapshot(profile_)); setting_snapshot_->RequestShortcuts(base::Bind( &ResetSettingsHandler::UpdateFeedbackUI, AsWeakPtr())); UpdateFeedbackUI(); @@ -138,7 +144,7 @@ void ResetSettingsHandler::OnHideResetProfileDialog( const base::ListValue* value) { - if (!resetter_->IsActive()) + if (!GetResetter()->IsActive()) setting_snapshot_.reset(); } @@ -149,8 +155,7 @@ } void ResetSettingsHandler::ResetProfile(bool send_settings) { - DCHECK(resetter_); - DCHECK(!resetter_->IsActive()); + DCHECK(!GetResetter()->IsActive()); scoped_ptr<BrandcodedDefaultSettings> default_settings; if (config_fetcher_) { @@ -165,7 +170,8 @@ // installation, use default settings. if (!default_settings) default_settings.reset(new BrandcodedDefaultSettings); - resetter_->Reset( + + GetResetter()->Reset( ProfileResetter::ALL, default_settings.Pass(), base::Bind(&ResetSettingsHandler::OnResetProfileSettingsDone, @@ -179,14 +185,19 @@ if (!setting_snapshot_) return; scoped_ptr<base::ListValue> list = GetReadableFeedbackForSnapshot( - Profile::FromWebUI(web_ui()), - *setting_snapshot_); + profile_, *setting_snapshot_); base::DictionaryValue feedback_info; feedback_info.Set("feedbackInfo", list.release()); web_ui()->CallJavascriptFunction( "SettingsResetPage.setFeedbackInfo", feedback_info); } +ProfileResetter* ResetSettingsHandler::GetResetter() { + if (!resetter_) + resetter_.reset(new ProfileResetter(profile_)); + return resetter_.get(); +} + #if defined(OS_CHROMEOS) void ResetSettingsHandler::OnShowPowerwashDialog( const base::ListValue* args) {
diff --git a/chrome/browser/ui/webui/settings/reset_settings_handler.h b/chrome/browser/ui/webui/settings/reset_settings_handler.h index 0407947..6238dec 100644 --- a/chrome/browser/ui/webui/settings/reset_settings_handler.h +++ b/chrome/browser/ui/webui/settings/reset_settings_handler.h
@@ -23,6 +23,7 @@ } class BrandcodeConfigFetcher; +class Profile; class ProfileResetter; class ResettableSettingsSnapshot; @@ -35,17 +36,24 @@ : public SettingsPageUIHandler, public base::SupportsWeakPtr<ResetSettingsHandler> { public: - explicit ResetSettingsHandler( - content::WebUIDataSource* html_source, content::WebUI* web_ui); ~ResetSettingsHandler() override; + static ResetSettingsHandler* Create( + content::WebUIDataSource* html_source, Profile* profile); + // WebUIMessageHandler implementation. void RegisterMessages() override; - private: + protected: + ResetSettingsHandler(Profile* profile, bool allow_powerwash); + + // Overriden in tests to substitute with a test version of ProfileResetter. + virtual ProfileResetter* GetResetter(); + // Javascript callback to start clearing data. void HandleResetProfileSettings(const base::ListValue* value); + private: // Closes the dialog once all requested settings has been reset. void OnResetProfileSettingsDone(bool send_feedback); @@ -77,6 +85,8 @@ bool allow_powerwash_ = false; #endif // defined(OS_CHROMEOS) + Profile* const profile_; + scoped_ptr<ProfileResetter> resetter_; scoped_ptr<BrandcodeConfigFetcher> config_fetcher_;
diff --git a/chrome/browser/ui/webui/settings/reset_settings_handler_unittest.cc b/chrome/browser/ui/webui/settings/reset_settings_handler_unittest.cc new file mode 100644 index 0000000..ea3ee74 --- /dev/null +++ b/chrome/browser/ui/webui/settings/reset_settings_handler_unittest.cc
@@ -0,0 +1,95 @@ +// 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. + +#include "base/values.h" +#include "chrome/browser/profile_resetter/profile_resetter.h" +#include "chrome/browser/ui/webui/settings/reset_settings_handler.h" +#include "chrome/test/base/testing_profile.h" +#include "content/public/browser/web_ui_data_source.h" +#include "content/public/test/test_browser_thread_bundle.h" +#include "content/public/test/test_web_ui.h" +#include "testing/gtest/include/gtest/gtest.h" + +using settings::ResetSettingsHandler; + +namespace { + +// Mock version of ProfileResetter to be used in tests. +class MockProfileResetter : public ProfileResetter { + public: + explicit MockProfileResetter(TestingProfile* profile) + : ProfileResetter(profile) { + } + + bool IsActive() const override { + return false; + } + + void Reset(ResettableFlags resettable_flags, + scoped_ptr<BrandcodedDefaultSettings> master_settings, + const base::Closure& callback) override { + resets_++; + callback.Run(); + } + + size_t resets() const { + return resets_; + } + + private: + size_t resets_ = 0; +}; + +class TestingResetSettingsHandler : public ResetSettingsHandler { + public: + TestingResetSettingsHandler( + TestingProfile* profile, bool allow_powerwash, content::WebUI* web_ui) + : ResetSettingsHandler(profile, allow_powerwash), + resetter_(profile) { + set_web_ui(web_ui); + } + + size_t resets() const { return resetter_.resets(); } + + using settings::ResetSettingsHandler::HandleResetProfileSettings; + + protected: + ProfileResetter* GetResetter() override { + return &resetter_; + } + +private: + MockProfileResetter resetter_; + + DISALLOW_COPY_AND_ASSIGN(TestingResetSettingsHandler); +}; + +class ResetSettingsHandlerTest : public testing::Test { + public: + ResetSettingsHandlerTest() : handler_(&profile_, false, &web_ui_) { + } + + TestingResetSettingsHandler* handler() { return &handler_; } + content::TestWebUI* web_ui() { return &web_ui_; } + + private: + // The order here matters. + content::TestBrowserThreadBundle thread_bundle_; + TestingProfile profile_; + content::TestWebUI web_ui_; + TestingResetSettingsHandler handler_; +}; + +TEST_F(ResetSettingsHandlerTest, HandleResetProfileSettings) { + base::ListValue list; + list.AppendBoolean(false); + handler()->HandleResetProfileSettings(&list); + // Check that the delegate ProfileResetter was called. + EXPECT_EQ(1u, handler()->resets()); + // Check that Javascript side is notified after resetting is done. + EXPECT_EQ("SettingsResetPage.doneResetting", + web_ui()->call_data()[0]->function_name()); +} + +} // namespace
diff --git a/chrome/browser/ui/webui/settings/settings_startup_pages_handler.cc b/chrome/browser/ui/webui/settings/settings_startup_pages_handler.cc index 316316f..a1a7a67 100644 --- a/chrome/browser/ui/webui/settings/settings_startup_pages_handler.cc +++ b/chrome/browser/ui/webui/settings/settings_startup_pages_handler.cc
@@ -18,7 +18,8 @@ } void StartupPagesHandler::RegisterMessages() { - DCHECK(!Profile::FromWebUI(web_ui())->IsOffTheRecord()); + if (Profile::FromWebUI(web_ui())->IsOffTheRecord()) + return; web_ui()->RegisterMessageCallback("setStartupPagesToCurrentPages", base::Bind(&StartupPagesHandler::SetStartupPagesToCurrentPages,
diff --git a/chrome/browser/ui/webui/settings/sync_handler.cc b/chrome/browser/ui/webui/settings/sync_handler.cc index 2292260e..3928f18 100644 --- a/chrome/browser/ui/webui/settings/sync_handler.cc +++ b/chrome/browser/ui/webui/settings/sync_handler.cc
@@ -19,6 +19,7 @@ #include "chrome/browser/profiles/profile.h" #include "chrome/browser/profiles/profile_info_cache.h" #include "chrome/browser/profiles/profile_metrics.h" +#include "chrome/browser/profiles/profile_window.h" #include "chrome/browser/signin/chrome_signin_helper.h" #include "chrome/browser/signin/signin_error_controller_factory.h" #include "chrome/browser/signin/signin_manager_factory.h" @@ -28,6 +29,7 @@ #include "chrome/browser/ui/browser_finder.h" #include "chrome/browser/ui/browser_window.h" #include "chrome/browser/ui/singleton_tabs.h" +#include "chrome/browser/ui/user_manager.h" #include "chrome/browser/ui/webui/options/options_handlers_helper.h" #include "chrome/browser/ui/webui/signin/login_ui_service.h" #include "chrome/browser/ui/webui/signin/login_ui_service_factory.h" @@ -222,6 +224,10 @@ web_ui()->RegisterMessageCallback( "SyncSetupGetSyncStatus", base::Bind(&SyncHandler::HandleGetSyncStatus, base::Unretained(this))); + web_ui()->RegisterMessageCallback( + "SyncSetupManageOtherPeople", + base::Bind(&SyncHandler::HandleManageOtherPeople, + base::Unretained(this))); #if defined(OS_CHROMEOS) web_ui()->RegisterMessageCallback( "SyncSetupDoSignOutOnAuthError", @@ -566,6 +572,11 @@ UpdateSyncState(); } +void SyncHandler::HandleManageOtherPeople(const base::ListValue* /* args */) { + UserManager::Show(base::FilePath(), profiles::USER_MANAGER_NO_TUTORIAL, + profiles::USER_MANAGER_SELECT_PROFILE_NO_ACTION); +} + void SyncHandler::CloseSyncSetup() { // Stop a timer to handle timeout in waiting for checking network connection. backend_start_timer_.reset();
diff --git a/chrome/browser/ui/webui/settings/sync_handler.h b/chrome/browser/ui/webui/settings/sync_handler.h index 9ac84ba..ec67f44 100644 --- a/chrome/browser/ui/webui/settings/sync_handler.h +++ b/chrome/browser/ui/webui/settings/sync_handler.h
@@ -123,6 +123,7 @@ void HandleStopSyncing(const base::ListValue* args); void HandleCloseTimeout(const base::ListValue* args); void HandleGetSyncStatus(const base::ListValue* args); + void HandleManageOtherPeople(const base::ListValue* args); #if !defined(OS_CHROMEOS) // Displays the GAIA login form.
diff --git a/chrome/browser_tests.isolate b/chrome/browser_tests.isolate index 66fbba0c..d90c90aa 100644 --- a/chrome/browser_tests.isolate +++ b/chrome/browser_tests.isolate
@@ -205,6 +205,7 @@ '<(PRODUCT_DIR)/chrome_elf.dll', '<(PRODUCT_DIR)/clearkeycdm.dll', '<(PRODUCT_DIR)/clearkeycdmadapter.dll', + '<(PRODUCT_DIR)/crashpad_handler.exe', '<(PRODUCT_DIR)/plugins/', '<(PRODUCT_DIR)/power_saver_test_plugin.dll', '<(PRODUCT_DIR)/ppapi_tests.dll',
diff --git a/chrome/chrome_browser.gypi b/chrome/chrome_browser.gypi index e76071b8..df433200 100644 --- a/chrome/chrome_browser.gypi +++ b/chrome/chrome_browser.gypi
@@ -22,8 +22,600 @@ 'browser/about_flags.h', 'browser/after_startup_task_utils.cc', 'browser/after_startup_task_utils.h', + 'browser/app_controller_mac.h', + 'browser/app_controller_mac.mm', + 'browser/app_icon_win.cc', + 'browser/app_icon_win.h', + 'browser/app_mode/app_mode_utils.cc', + 'browser/app_mode/app_mode_utils.h', + 'browser/autofill/options_util.cc', + 'browser/autofill/options_util.h', + 'browser/autofill/personal_data_manager_factory.cc', + 'browser/autofill/personal_data_manager_factory.h', + 'browser/autofill/risk_util.cc', + 'browser/autofill/risk_util.h', + 'browser/autofill/validation_rules_storage_factory.cc', + 'browser/autofill/validation_rules_storage_factory.h', + 'browser/background_sync/background_sync_controller_factory.cc', + 'browser/background_sync/background_sync_controller_factory.h', + 'browser/background_sync/background_sync_controller_impl.cc', + 'browser/background_sync/background_sync_controller_impl.h', + 'browser/bad_message.cc', + 'browser/bad_message.h', + 'browser/banners/app_banner_data_fetcher.cc', + 'browser/banners/app_banner_data_fetcher.h', + 'browser/banners/app_banner_debug_log.cc', + 'browser/banners/app_banner_debug_log.h', + 'browser/banners/app_banner_manager.cc', + 'browser/banners/app_banner_manager.h', + 'browser/banners/app_banner_metrics.cc', + 'browser/banners/app_banner_metrics.h', + 'browser/banners/app_banner_settings_helper.cc', + 'browser/banners/app_banner_settings_helper.h', + 'browser/bitmap_fetcher/bitmap_fetcher.cc', + 'browser/bitmap_fetcher/bitmap_fetcher.h', + 'browser/bitmap_fetcher/bitmap_fetcher_delegate.h', + 'browser/bitmap_fetcher/bitmap_fetcher_service.cc', + 'browser/bitmap_fetcher/bitmap_fetcher_service.h', + 'browser/bitmap_fetcher/bitmap_fetcher_service_factory.cc', + 'browser/bitmap_fetcher/bitmap_fetcher_service_factory.h', + 'browser/browser_about_handler.cc', + 'browser/browser_about_handler.h', + 'browser/browser_shutdown.cc', + 'browser/browser_shutdown.h', + 'browser/browser_util_win.cc', + 'browser/browser_util_win.h', + 'browser/browsing_data/autofill_counter.cc', + 'browser/browsing_data/autofill_counter.h', + 'browser/browsing_data/browsing_data_appcache_helper.cc', + 'browser/browsing_data/browsing_data_appcache_helper.h', + 'browser/browsing_data/browsing_data_cache_storage_helper.cc', + 'browser/browsing_data/browsing_data_cache_storage_helper.h', + 'browser/browsing_data/browsing_data_channel_id_helper.cc', + 'browser/browsing_data/browsing_data_channel_id_helper.h', + 'browser/browsing_data/browsing_data_cookie_helper.cc', + 'browser/browsing_data/browsing_data_cookie_helper.h', + 'browser/browsing_data/browsing_data_counter.cc', + 'browser/browsing_data/browsing_data_counter.h', + 'browser/browsing_data/browsing_data_database_helper.cc', + 'browser/browsing_data/browsing_data_database_helper.h', + 'browser/browsing_data/browsing_data_file_system_helper.cc', + 'browser/browsing_data/browsing_data_file_system_helper.h', + 'browser/browsing_data/browsing_data_helper.cc', + 'browser/browsing_data/browsing_data_helper.h', + 'browser/browsing_data/browsing_data_indexed_db_helper.cc', + 'browser/browsing_data/browsing_data_indexed_db_helper.h', + 'browser/browsing_data/browsing_data_local_storage_helper.cc', + 'browser/browsing_data/browsing_data_local_storage_helper.h', + 'browser/browsing_data/browsing_data_quota_helper.cc', + 'browser/browsing_data/browsing_data_quota_helper.h', + 'browser/browsing_data/browsing_data_quota_helper_impl.cc', + 'browser/browsing_data/browsing_data_quota_helper_impl.h', + 'browser/browsing_data/browsing_data_remover.cc', + 'browser/browsing_data/browsing_data_remover.h', + 'browser/browsing_data/browsing_data_service_worker_helper.cc', + 'browser/browsing_data/browsing_data_service_worker_helper.h', + 'browser/browsing_data/cache_counter.cc', + 'browser/browsing_data/cache_counter.h', + 'browser/browsing_data/canonical_cookie_hash.cc', + 'browser/browsing_data/canonical_cookie_hash.h', + 'browser/browsing_data/cookies_tree_model.cc', + 'browser/browsing_data/cookies_tree_model.h', + 'browser/browsing_data/history_counter.cc', + 'browser/browsing_data/history_counter.h', + 'browser/browsing_data/local_data_container.cc', + 'browser/browsing_data/local_data_container.h', + 'browser/browsing_data/passwords_counter.cc', + 'browser/browsing_data/passwords_counter.h', + 'browser/character_encoding.cc', + 'browser/character_encoding.h', + 'browser/chrome_browser_application_mac.h', + 'browser/chrome_browser_application_mac.mm', + 'browser/chrome_browser_field_trials.cc', + 'browser/chrome_browser_field_trials.h', + 'browser/chrome_browser_main.cc', + 'browser/chrome_browser_main.h', + 'browser/chrome_browser_main_android.cc', + 'browser/chrome_browser_main_android.h', + 'browser/chrome_browser_main_extra_parts.h', + 'browser/chrome_browser_main_linux.cc', + 'browser/chrome_browser_main_linux.h', + 'browser/chrome_browser_main_mac.h', + 'browser/chrome_browser_main_mac.mm', + 'browser/chrome_browser_main_win.cc', + 'browser/chrome_browser_main_win.h', + 'browser/chrome_child_process_watcher.cc', + 'browser/chrome_child_process_watcher.h', + 'browser/chrome_content_browser_client.cc', + 'browser/chrome_content_browser_client.h', + 'browser/chrome_content_browser_client_parts.h', + 'browser/chrome_device_client.cc', + 'browser/chrome_device_client.h', + 'browser/chrome_elf_init_win.cc', + 'browser/chrome_elf_init_win.h', + 'browser/chrome_net_benchmarking_message_filter.cc', + 'browser/chrome_net_benchmarking_message_filter.h', + 'browser/chrome_notification_types.h', + 'browser/chrome_quota_permission_context.cc', + 'browser/chrome_quota_permission_context.h', + 'browser/chrome_select_file_dialog_factory_win.cc', + 'browser/chrome_select_file_dialog_factory_win.h', + 'browser/command_observer.h', + 'browser/command_updater.cc', + 'browser/command_updater.h', + 'browser/command_updater_delegate.h', + 'browser/component_updater/caps_installer_win.cc', + 'browser/component_updater/caps_installer_win.h', + 'browser/component_updater/chrome_component_updater_configurator.cc', + 'browser/component_updater/chrome_component_updater_configurator.h', + 'browser/component_updater/cld_component_installer.cc', + 'browser/component_updater/cld_component_installer.h', + 'browser/component_updater/component_patcher_operation_out_of_process.cc', + 'browser/component_updater/component_patcher_operation_out_of_process.h', + 'browser/component_updater/component_updater_resource_throttle.cc', + 'browser/component_updater/component_updater_resource_throttle.h', + 'browser/component_updater/ev_whitelist_component_installer.cc', + 'browser/component_updater/ev_whitelist_component_installer.h', + 'browser/component_updater/pnacl_component_installer.cc', + 'browser/component_updater/pnacl_component_installer.h', + 'browser/component_updater/recovery_component_installer.cc', + 'browser/component_updater/recovery_component_installer.h', + 'browser/component_updater/supervised_user_whitelist_installer.cc', + 'browser/component_updater/supervised_user_whitelist_installer.h', + 'browser/component_updater/sw_reporter_installer_win.cc', + 'browser/component_updater/sw_reporter_installer_win.h', + 'browser/component_updater/swiftshader_component_installer.cc', + 'browser/component_updater/swiftshader_component_installer.h', + 'browser/crash_upload_list.cc', + 'browser/crash_upload_list.h', + 'browser/custom_handlers/protocol_handler_registry.cc', + 'browser/custom_handlers/protocol_handler_registry.h', + 'browser/custom_handlers/protocol_handler_registry_factory.cc', + 'browser/custom_handlers/protocol_handler_registry_factory.h', + 'browser/defaults.cc', + 'browser/defaults.h', + 'browser/dom_distiller/dom_distiller_service_factory.cc', + 'browser/dom_distiller/dom_distiller_service_factory.h', + 'browser/dom_distiller/lazy_dom_distiller_service.cc', + 'browser/dom_distiller/lazy_dom_distiller_service.h', + 'browser/dom_distiller/profile_utils.cc', + 'browser/dom_distiller/profile_utils.h', + 'browser/dom_distiller/tab_utils.cc', + 'browser/dom_distiller/tab_utils.h', + 'browser/domain_reliability/service_factory.cc', + 'browser/domain_reliability/service_factory.h', + 'browser/download/all_download_item_notifier.cc', + 'browser/download/all_download_item_notifier.h', + 'browser/download/chrome_download_manager_delegate.cc', + 'browser/download/chrome_download_manager_delegate.h', + 'browser/download/download_crx_util_android.cc', + 'browser/download/download_extensions.cc', + 'browser/download/download_extensions.h', + 'browser/download/download_file_picker.cc', + 'browser/download/download_file_picker.h', + 'browser/download/download_history.cc', + 'browser/download/download_history.h', + 'browser/download/download_item_model.cc', + 'browser/download/download_item_model.h', + 'browser/download/download_path_reservation_tracker.cc', + 'browser/download/download_path_reservation_tracker.h', + 'browser/download/download_prefs.cc', + 'browser/download/download_prefs.h', + 'browser/download/download_query.cc', + 'browser/download/download_query.h', + 'browser/download/download_request_limiter.cc', + 'browser/download/download_request_limiter.h', + 'browser/download/download_resource_throttle.cc', + 'browser/download/download_resource_throttle.h', + 'browser/download/download_service.cc', + 'browser/download/download_service.h', + 'browser/download/download_service_factory.cc', + 'browser/download/download_service_factory.h', + 'browser/download/download_service_impl.cc', + 'browser/download/download_service_impl.h', + 'browser/download/download_started_animation.h', + 'browser/download/download_stats.cc', + 'browser/download/download_stats.h', + 'browser/download/download_status_updater.cc', + 'browser/download/download_status_updater.h', + 'browser/download/download_status_updater_mac.mm', + 'browser/download/download_status_updater_win.cc', + 'browser/download/download_target_determiner.cc', + 'browser/download/download_target_determiner.h', + 'browser/download/download_target_determiner_delegate.h', + 'browser/download/download_target_info.h', + 'browser/download/download_ui_controller.cc', + 'browser/download/download_ui_controller.h', + 'browser/download/drag_download_item.h', + 'browser/download/save_package_file_picker.cc', + 'browser/download/save_package_file_picker.h', + 'browser/enumerate_modules_model_win.cc', + 'browser/enumerate_modules_model_win.h', + # Oh hey, all the cool browser/extensions files are hanging out in + # chrome/chrome_browser_extensions.gypi. + 'browser/external_protocol/external_protocol_handler.cc', + 'browser/external_protocol/external_protocol_handler.h', + 'browser/external_protocol/external_protocol_observer.cc', + 'browser/external_protocol/external_protocol_observer.h', + 'browser/file_select_helper.cc', + 'browser/file_select_helper.h', + 'browser/file_select_helper_mac.mm', + 'browser/fullscreen.h', + 'browser/fullscreen_chromeos.cc', + 'browser/fullscreen_mac.mm', + 'browser/fullscreen_win.cc', + 'browser/geolocation/chrome_access_token_store.cc', + 'browser/geolocation/chrome_access_token_store.h', + 'browser/geolocation/geolocation_permission_context.cc', + 'browser/geolocation/geolocation_permission_context.h', + 'browser/geolocation/geolocation_permission_context_android.cc', + 'browser/geolocation/geolocation_permission_context_android.h', + 'browser/geolocation/geolocation_permission_context_extensions.cc', + 'browser/geolocation/geolocation_permission_context_extensions.h', + 'browser/geolocation/geolocation_permission_context_factory.cc', + 'browser/geolocation/geolocation_permission_context_factory.h', + 'browser/geolocation/geolocation_prefs.cc', + 'browser/geolocation/geolocation_prefs.h', + 'browser/global_keyboard_shortcuts_mac.h', + 'browser/global_keyboard_shortcuts_mac.mm', + 'browser/gpu/gl_string_manager.cc', + 'browser/gpu/gl_string_manager.h', + 'browser/gpu/gpu_feature_checker.cc', + 'browser/gpu/gpu_feature_checker.h', + 'browser/gpu/gpu_mode_manager.cc', + 'browser/gpu/gpu_mode_manager.h', + 'browser/gpu/three_d_api_observer.cc', + 'browser/gpu/three_d_api_observer.h', + 'browser/icon_loader.cc', + 'browser/icon_loader.h', + 'browser/icon_loader_android.cc', + 'browser/icon_loader_chromeos.cc', + 'browser/icon_loader_mac.mm', + 'browser/icon_loader_win.cc', + 'browser/icon_manager.cc', + 'browser/icon_manager.h', + 'browser/image_decoder.cc', + 'browser/image_decoder.h', + 'browser/image_holder.cc', + 'browser/image_holder.h', + 'browser/infobars/infobar_responder.cc', + 'browser/infobars/infobar_responder.h', + 'browser/infobars/infobar_service.cc', + 'browser/infobars/infobar_service.h', + 'browser/infobars/insecure_content_infobar_delegate.cc', + 'browser/infobars/insecure_content_infobar_delegate.h', + 'browser/install_verification/win/imported_module_verification.cc', + 'browser/install_verification/win/imported_module_verification.h', + 'browser/install_verification/win/install_verification.cc', + 'browser/install_verification/win/install_verification.h', + 'browser/install_verification/win/loaded_module_verification.cc', + 'browser/install_verification/win/loaded_module_verification.h', + 'browser/install_verification/win/loaded_modules_snapshot.cc', + 'browser/install_verification/win/loaded_modules_snapshot.h', + 'browser/install_verification/win/module_ids.cc', + 'browser/install_verification/win/module_ids.h', + 'browser/install_verification/win/module_info.h', + 'browser/install_verification/win/module_list.cc', + 'browser/install_verification/win/module_list.h', + 'browser/install_verification/win/module_verification_common.cc', + 'browser/install_verification/win/module_verification_common.h', + 'browser/interests/interests_fetcher.cc', + 'browser/interests/interests_fetcher.h', + 'browser/internal_auth.cc', + 'browser/internal_auth.h', + 'browser/interstitials/chrome_controller_client.cc', + 'browser/interstitials/chrome_controller_client.h', + 'browser/interstitials/chrome_metrics_helper.cc', + 'browser/interstitials/chrome_metrics_helper.h', + 'browser/interstitials/security_interstitial_page.cc', + 'browser/interstitials/security_interstitial_page.h', + 'browser/intranet_redirect_detector.cc', + 'browser/intranet_redirect_detector.h', + 'browser/invalidation/profile_invalidation_provider_factory.cc', + 'browser/invalidation/profile_invalidation_provider_factory.h', + 'browser/io_thread.cc', + 'browser/io_thread.h', + 'browser/jumplist_updater_win.cc', + 'browser/jumplist_updater_win.h', + 'browser/jumplist_win.cc', + 'browser/jumplist_win.h', + 'browser/lifetime/application_lifetime.cc', + 'browser/lifetime/application_lifetime.h', + 'browser/lifetime/application_lifetime_mac.mm', + 'browser/lifetime/application_lifetime_win.cc', + 'browser/mac/bluetooth_utility.h', + 'browser/mac/bluetooth_utility.mm', + 'browser/mac/dock.h', + 'browser/mac/dock.mm', + 'browser/mac/install_from_dmg.h', + 'browser/mac/install_from_dmg.mm', + 'browser/mac/keystone_glue.h', + 'browser/mac/keystone_glue.mm', + 'browser/mac/keystone_registration.h', + 'browser/mac/keystone_registration.mm', + 'browser/mac/mac_startup_profiler.cc', + 'browser/mac/mac_startup_profiler.h', + 'browser/mac/master_prefs.h', + 'browser/mac/master_prefs.mm', + 'browser/mac/relauncher.cc', + 'browser/mac/relauncher.h', + 'browser/mac/security_wrappers.cc', + 'browser/mac/security_wrappers.h', + 'browser/manifest/manifest_icon_downloader.cc', + 'browser/manifest/manifest_icon_downloader.h', + 'browser/manifest/manifest_icon_selector.cc', + 'browser/manifest/manifest_icon_selector.h', + 'browser/media/desktop_media_list.h', + 'browser/media/desktop_media_picker.h', + 'browser/media/desktop_streams_registry.cc', + 'browser/media/desktop_streams_registry.h', + 'browser/media/media_access_handler.h', + 'browser/media/media_capture_devices_dispatcher.cc', + 'browser/media/media_capture_devices_dispatcher.h', + 'browser/media/media_device_id_salt.cc', + 'browser/media/media_device_id_salt.h', + 'browser/media/media_permission.cc', + 'browser/media/media_permission.h', + 'browser/media/media_stream_camera_permission_context_factory.cc', + 'browser/media/media_stream_camera_permission_context_factory.h', + 'browser/media/media_stream_capture_indicator.cc', + 'browser/media/media_stream_capture_indicator.h', + 'browser/media/media_stream_device_permission_context.cc', + 'browser/media/media_stream_device_permission_context.h', + 'browser/media/media_stream_device_permissions.cc', + 'browser/media/media_stream_device_permissions.h', + 'browser/media/media_stream_devices_controller.cc', + 'browser/media/media_stream_devices_controller.h', + 'browser/media/media_stream_mic_permission_context_factory.cc', + 'browser/media/media_stream_mic_permission_context_factory.h', + 'browser/media/media_url_constants.cc', + 'browser/media/media_url_constants.h', + 'browser/media/midi_permission_context.cc', + 'browser/media/midi_permission_context.h', + 'browser/media/midi_permission_context_factory.cc', + 'browser/media/midi_permission_context_factory.h', + 'browser/media/native_desktop_media_list.cc', + 'browser/media/native_desktop_media_list.h', + 'browser/media/permission_bubble_media_access_handler.cc', + 'browser/media/permission_bubble_media_access_handler.h', + 'browser/media/router/media_router_feature.cc', + 'browser/media/router/media_router_feature.h', + # TODO(brettw) should this go with the webrtc sources? + 'browser/media/webrtc_log_list.cc', + 'browser/media/webrtc_log_list.h', + 'browser/memory_details.cc', + 'browser/memory_details.h', + 'browser/memory_details_android.cc', + 'browser/memory_details_linux.cc', + 'browser/memory_details_mac.cc', + 'browser/memory_details_win.cc', + 'browser/mod_pagespeed/mod_pagespeed_metrics.cc', + 'browser/mod_pagespeed/mod_pagespeed_metrics.h', + 'browser/native_window_notification_source.h', + 'browser/net/predictor_tab_helper.cc', + 'browser/net/predictor_tab_helper.h', + 'browser/ntp_snippets/ntp_snippets_service_factory.cc', + 'browser/ntp_snippets/ntp_snippets_service_factory.h', + 'browser/page_load_metrics/observers/from_gws_page_load_metrics_observer.cc', + 'browser/page_load_metrics/observers/from_gws_page_load_metrics_observer.h', + 'browser/page_load_metrics/observers/google_captcha_observer.cc', + 'browser/page_load_metrics/observers/google_captcha_observer.h', + 'browser/page_load_metrics/observers/stale_while_revalidate_metrics_observer.cc', + 'browser/page_load_metrics/observers/stale_while_revalidate_metrics_observer.h', + 'browser/page_load_metrics/page_load_metrics_initialize.cc', + 'browser/page_load_metrics/page_load_metrics_initialize.h', + 'browser/performance_monitor/performance_monitor.cc', + 'browser/performance_monitor/performance_monitor.h', + 'browser/performance_monitor/process_metrics_history.cc', + 'browser/performance_monitor/process_metrics_history.h', + 'browser/platform_util.h', + 'browser/platform_util_chromeos.cc', + 'browser/platform_util_internal.h', + 'browser/platform_util_mac.mm', + 'browser/platform_util_win.cc', + 'browser/prefetch/prefetch.cc', + 'browser/prefetch/prefetch.h', + 'browser/prefetch/prefetch_field_trial.cc', + 'browser/prefetch/prefetch_field_trial.h', + 'browser/prerender/prerender_config.cc', + 'browser/prerender/prerender_config.h', + 'browser/prerender/prerender_contents.cc', + 'browser/prerender/prerender_contents.h', + 'browser/prerender/prerender_field_trial.cc', + 'browser/prerender/prerender_field_trial.h', + 'browser/prerender/prerender_final_status.cc', + 'browser/prerender/prerender_final_status.h', + 'browser/prerender/prerender_handle.cc', + 'browser/prerender/prerender_handle.h', + 'browser/prerender/prerender_histograms.cc', + 'browser/prerender/prerender_histograms.h', + 'browser/prerender/prerender_history.cc', + 'browser/prerender/prerender_history.h', + 'browser/prerender/prerender_link_manager.cc', + 'browser/prerender/prerender_link_manager.h', + 'browser/prerender/prerender_link_manager_factory.cc', + 'browser/prerender/prerender_link_manager_factory.h', + 'browser/prerender/prerender_manager.cc', + 'browser/prerender/prerender_manager.h', + 'browser/prerender/prerender_manager_factory.cc', + 'browser/prerender/prerender_manager_factory.h', + 'browser/prerender/prerender_message_filter.cc', + 'browser/prerender/prerender_message_filter.h', + 'browser/prerender/prerender_origin.cc', + 'browser/prerender/prerender_origin.h', + 'browser/prerender/prerender_resource_throttle.cc', + 'browser/prerender/prerender_resource_throttle.h', + 'browser/prerender/prerender_tab_helper.cc', + 'browser/prerender/prerender_tab_helper.h', + 'browser/prerender/prerender_util.cc', + 'browser/prerender/prerender_util.h', + 'browser/private_working_set_snapshot.h', + 'browser/private_working_set_snapshot_win.cc', + 'browser/process_info_snapshot.h', + 'browser/process_info_snapshot_mac.cc', + 'browser/process_resource_usage.cc', + 'browser/process_resource_usage.h', + 'browser/process_singleton.h', + 'browser/process_singleton_win.cc', + 'browser/push_messaging/push_messaging_app_identifier.cc', + 'browser/push_messaging/push_messaging_app_identifier.h', + 'browser/push_messaging/push_messaging_constants.cc', + 'browser/push_messaging/push_messaging_constants.h', + 'browser/push_messaging/push_messaging_permission_context.cc', + 'browser/push_messaging/push_messaging_permission_context.h', + 'browser/push_messaging/push_messaging_permission_context_factory.cc', + 'browser/push_messaging/push_messaging_permission_context_factory.h', + 'browser/push_messaging/push_messaging_service_factory.cc', + 'browser/push_messaging/push_messaging_service_factory.h', + 'browser/push_messaging/push_messaging_service_impl.cc', + 'browser/push_messaging/push_messaging_service_impl.h', + 'browser/renderer_context_menu/context_menu_content_type_factory.cc', + 'browser/renderer_context_menu/context_menu_content_type_factory.h', + 'browser/renderer_context_menu/context_menu_content_type_panel.cc', + 'browser/renderer_context_menu/context_menu_content_type_panel.h', + 'browser/renderer_host/chrome_render_message_filter.cc', + 'browser/renderer_host/chrome_render_message_filter.h', + 'browser/renderer_host/chrome_render_widget_host_view_mac_delegate.h', + 'browser/renderer_host/chrome_render_widget_host_view_mac_delegate.mm', + 'browser/renderer_host/chrome_render_widget_host_view_mac_history_swiper.h', + 'browser/renderer_host/chrome_render_widget_host_view_mac_history_swiper.mm', + 'browser/renderer_host/chrome_resource_dispatcher_host_delegate.cc', + 'browser/renderer_host/chrome_resource_dispatcher_host_delegate.h', + 'browser/renderer_host/thread_hop_resource_throttle.cc', + 'browser/renderer_host/thread_hop_resource_throttle.h', + 'browser/renderer_preferences_util.cc', + 'browser/renderer_preferences_util.h', + 'browser/resources_util.cc', + 'browser/resources_util.h', + 'browser/safe_browsing/safe_browsing_tab_observer.cc', + 'browser/safe_browsing/safe_browsing_tab_observer.h', + 'browser/safe_browsing/srt_fetcher_win.cc', + 'browser/safe_browsing/srt_fetcher_win.h', + 'browser/safe_browsing/srt_field_trial_win.cc', + 'browser/safe_browsing/srt_field_trial_win.h', + 'browser/safe_browsing/srt_global_error_win.cc', + 'browser/safe_browsing/srt_global_error_win.h', + 'browser/search/iframe_source.cc', + 'browser/search/iframe_source.h', + 'browser/search/instant_io_context.cc', + 'browser/search/instant_io_context.h', + 'browser/search/instant_service.cc', + 'browser/search/instant_service.h', + 'browser/search/instant_service_factory.cc', + 'browser/search/instant_service_factory.h', + 'browser/search/instant_service_observer.cc', + 'browser/search/instant_service_observer.h', + 'browser/search/most_visited_iframe_source.cc', + 'browser/search/most_visited_iframe_source.h', + 'browser/search/search.cc', + 'browser/search/search.h', + 'browser/search/suggestions/image_fetcher_impl.cc', + 'browser/search/suggestions/image_fetcher_impl.h', + 'browser/search/suggestions/suggestions_service_factory.cc', + 'browser/search/suggestions/suggestions_service_factory.h', + 'browser/search/suggestions/suggestions_source.cc', + 'browser/search/suggestions/suggestions_source.h', + 'browser/search/thumbnail_source.cc', + 'browser/search/thumbnail_source.h', + 'browser/shell_integration.cc', + 'browser/shell_integration.h', + 'browser/shell_integration_android.cc', + 'browser/shell_integration_chromeos.cc', + 'browser/shell_integration_mac.mm', + 'browser/shell_integration_win.cc', + 'browser/site_details.cc', + 'browser/site_details.h', + 'browser/speech/chrome_speech_recognition_manager_delegate.cc', + 'browser/speech/chrome_speech_recognition_manager_delegate.h', + 'browser/speech/tts_android.cc', + 'browser/speech/tts_android.h', + 'browser/speech/tts_chromeos.cc', + 'browser/speech/tts_controller.h', + 'browser/speech/tts_controller_impl.cc', + 'browser/speech/tts_controller_impl.h', + 'browser/speech/tts_mac.mm', + 'browser/speech/tts_message_filter.cc', + 'browser/speech/tts_message_filter.h', + 'browser/speech/tts_platform.cc', + 'browser/speech/tts_platform.h', + 'browser/speech/tts_win.cc', + 'browser/stack_sampling_configuration.cc', + 'browser/stack_sampling_configuration.h', + 'browser/status_icons/status_icon.cc', + 'browser/status_icons/status_icon.h', + 'browser/status_icons/status_icon_menu_model.cc', + 'browser/status_icons/status_icon_menu_model.h', + 'browser/status_icons/status_icon_observer.h', + 'browser/status_icons/status_tray.cc', + 'browser/status_icons/status_tray.h', + 'browser/storage/durable_storage_permission_context.cc', + 'browser/storage/durable_storage_permission_context.h', + 'browser/storage/durable_storage_permission_context_factory.cc', + 'browser/storage/durable_storage_permission_context_factory.h', + 'browser/tab_contents/navigation_metrics_recorder.cc', + 'browser/tab_contents/navigation_metrics_recorder.h', + 'browser/tab_contents/retargeting_details.h', + 'browser/tab_contents/tab_util.cc', + 'browser/tab_contents/tab_util.h', + 'browser/task_management/web_contents_tags.cc', + 'browser/task_management/web_contents_tags.h', + 'browser/task_profiler/task_profiler_data_serializer.cc', + 'browser/task_profiler/task_profiler_data_serializer.h', + 'browser/thumbnails/content_analysis.cc', + 'browser/thumbnails/content_analysis.h', + 'browser/thumbnails/content_based_thumbnailing_algorithm.cc', + 'browser/thumbnails/content_based_thumbnailing_algorithm.h', + 'browser/thumbnails/simple_thumbnail_crop.cc', + 'browser/thumbnails/simple_thumbnail_crop.h', + 'browser/thumbnails/thumbnail_list_source.cc', + 'browser/thumbnails/thumbnail_list_source.h', + 'browser/thumbnails/thumbnail_service.h', + 'browser/thumbnails/thumbnail_service_factory.cc', + 'browser/thumbnails/thumbnail_service_factory.h', + 'browser/thumbnails/thumbnail_service_impl.cc', + 'browser/thumbnails/thumbnail_service_impl.h', + 'browser/thumbnails/thumbnail_tab_helper.cc', + 'browser/thumbnails/thumbnail_tab_helper.h', + 'browser/thumbnails/thumbnailing_algorithm.h', + 'browser/thumbnails/thumbnailing_context.cc', + 'browser/thumbnails/thumbnailing_context.h', + 'browser/tracing/background_tracing_field_trial.cc', + 'browser/tracing/background_tracing_field_trial.h', + 'browser/tracing/crash_service_uploader.cc', + 'browser/tracing/crash_service_uploader.h', + 'browser/tracing/navigation_tracing.cc', + 'browser/tracing/navigation_tracing.h', + 'browser/translate/chrome_translate_client.cc', + 'browser/translate/chrome_translate_client.h', + 'browser/translate/translate_accept_languages_factory.cc', + 'browser/translate/translate_accept_languages_factory.h', + 'browser/translate/translate_service.cc', + 'browser/translate/translate_service.h', + 'browser/update_client/chrome_update_query_params_delegate.cc', + 'browser/update_client/chrome_update_query_params_delegate.h', + 'browser/usb/usb_chooser_context.cc', + 'browser/usb/usb_chooser_context.h', + 'browser/usb/usb_chooser_context_factory.cc', + 'browser/usb/usb_chooser_context_factory.h', + 'browser/usb/usb_tab_helper.cc', + 'browser/usb/usb_tab_helper.h', + 'browser/usb/web_usb_permission_provider.cc', + 'browser/usb/web_usb_permission_provider.h', + 'browser/web_data_service_factory.cc', + 'browser/web_data_service_factory.h', + ], + # Android sources included regardless of android_java_ui. + 'chrome_browser_android_sources': [ + 'browser/media/protected_media_identifier_permission_context.cc', + 'browser/media/protected_media_identifier_permission_context.h', + 'browser/media/protected_media_identifier_permission_context_factory.cc', + 'browser/media/protected_media_identifier_permission_context_factory.h', + ], + # Browser sources used when android_java_ui is enabled. + 'chrome_browser_android_java_ui_sources': [ 'browser/after_startup_task_utils_android.cc', 'browser/after_startup_task_utils_android.h', + 'browser/platform_util_android.cc', 'browser/android/accessibility/font_size_prefs_android.cc', 'browser/android/accessibility/font_size_prefs_android.h', 'browser/android/accessibility_util.cc', @@ -33,6 +625,8 @@ 'browser/android/android_theme_resources.h', 'browser/android/appmenu/app_menu_drag_helper.cc', 'browser/android/appmenu/app_menu_drag_helper.h', + 'browser/android/background_sync_launcher_android.cc', + 'browser/android/background_sync_launcher_android.h', 'browser/android/banners/app_banner_data_fetcher_android.cc', 'browser/android/banners/app_banner_data_fetcher_android.h', 'browser/android/banners/app_banner_infobar_delegate_android.cc', @@ -106,6 +700,8 @@ 'browser/android/data_usage/data_use_tab_helper.h', 'browser/android/data_usage/data_use_tab_model.cc', 'browser/android/data_usage/data_use_tab_model.h', + 'browser/android/data_usage/data_use_tab_ui_manager_android.cc', + 'browser/android/data_usage/data_use_tab_ui_manager_android.h', 'browser/android/data_usage/data_use_ui_tab_model.cc', 'browser/android/data_usage/data_use_ui_tab_model.h', 'browser/android/data_usage/data_use_ui_tab_model_factory.cc', @@ -278,341 +874,22 @@ 'browser/android/webapps/single_tab_mode_tab_helper.h', 'browser/android/webapps/webapp_registry.cc', 'browser/android/webapps/webapp_registry.h', - 'browser/app_controller_mac.h', - 'browser/app_controller_mac.mm', - 'browser/app_icon_win.cc', - 'browser/app_icon_win.h', - 'browser/app_mode/app_mode_utils.cc', - 'browser/app_mode/app_mode_utils.h', 'browser/autofill/android/personal_data_manager_android.cc', 'browser/autofill/android/personal_data_manager_android.h', - 'browser/autofill/options_util.cc', - 'browser/autofill/options_util.h', - 'browser/autofill/personal_data_manager_factory.cc', - 'browser/autofill/personal_data_manager_factory.h', - 'browser/autofill/risk_util.cc', - 'browser/autofill/risk_util.h', - 'browser/autofill/validation_rules_storage_factory.cc', - 'browser/autofill/validation_rules_storage_factory.h', - 'browser/background_sync/background_sync_controller_factory.cc', - 'browser/background_sync/background_sync_controller_factory.h', - 'browser/background_sync/background_sync_controller_impl.cc', - 'browser/background_sync/background_sync_controller_impl.h', - 'browser/bad_message.cc', - 'browser/bad_message.h', - 'browser/banners/app_banner_data_fetcher.cc', - 'browser/banners/app_banner_data_fetcher.h', - 'browser/banners/app_banner_debug_log.cc', - 'browser/banners/app_banner_debug_log.h', - 'browser/banners/app_banner_manager.cc', - 'browser/banners/app_banner_manager.h', - 'browser/banners/app_banner_metrics.cc', - 'browser/banners/app_banner_metrics.h', - 'browser/banners/app_banner_settings_helper.cc', - 'browser/banners/app_banner_settings_helper.h', - 'browser/bitmap_fetcher/bitmap_fetcher.cc', - 'browser/bitmap_fetcher/bitmap_fetcher.h', - 'browser/bitmap_fetcher/bitmap_fetcher_delegate.h', - 'browser/bitmap_fetcher/bitmap_fetcher_service.cc', - 'browser/bitmap_fetcher/bitmap_fetcher_service.h', - 'browser/bitmap_fetcher/bitmap_fetcher_service_factory.cc', - 'browser/bitmap_fetcher/bitmap_fetcher_service_factory.h', - 'browser/browser_about_handler.cc', - 'browser/browser_about_handler.h', - 'browser/browser_shutdown.cc', - 'browser/browser_shutdown.h', - 'browser/browser_util_win.cc', - 'browser/browser_util_win.h', - 'browser/browsing_data/autofill_counter.cc', - 'browser/browsing_data/autofill_counter.h', - 'browser/browsing_data/browsing_data_appcache_helper.cc', - 'browser/browsing_data/browsing_data_appcache_helper.h', - 'browser/browsing_data/browsing_data_cache_storage_helper.cc', - 'browser/browsing_data/browsing_data_cache_storage_helper.h', - 'browser/browsing_data/browsing_data_channel_id_helper.cc', - 'browser/browsing_data/browsing_data_channel_id_helper.h', - 'browser/browsing_data/browsing_data_cookie_helper.cc', - 'browser/browsing_data/browsing_data_cookie_helper.h', - 'browser/browsing_data/browsing_data_counter.cc', - 'browser/browsing_data/browsing_data_counter.h', - 'browser/browsing_data/browsing_data_database_helper.cc', - 'browser/browsing_data/browsing_data_database_helper.h', - 'browser/browsing_data/browsing_data_file_system_helper.cc', - 'browser/browsing_data/browsing_data_file_system_helper.h', - 'browser/browsing_data/browsing_data_helper.cc', - 'browser/browsing_data/browsing_data_helper.h', - 'browser/browsing_data/browsing_data_indexed_db_helper.cc', - 'browser/browsing_data/browsing_data_indexed_db_helper.h', - 'browser/browsing_data/browsing_data_local_storage_helper.cc', - 'browser/browsing_data/browsing_data_local_storage_helper.h', - 'browser/browsing_data/browsing_data_quota_helper.cc', - 'browser/browsing_data/browsing_data_quota_helper.h', - 'browser/browsing_data/browsing_data_quota_helper_impl.cc', - 'browser/browsing_data/browsing_data_quota_helper_impl.h', - 'browser/browsing_data/browsing_data_remover.cc', - 'browser/browsing_data/browsing_data_remover.h', - 'browser/browsing_data/browsing_data_service_worker_helper.cc', - 'browser/browsing_data/browsing_data_service_worker_helper.h', - 'browser/browsing_data/cache_counter.cc', - 'browser/browsing_data/cache_counter.h', - 'browser/browsing_data/canonical_cookie_hash.cc', - 'browser/browsing_data/canonical_cookie_hash.h', - 'browser/browsing_data/cookies_tree_model.cc', - 'browser/browsing_data/cookies_tree_model.h', - 'browser/browsing_data/history_counter.cc', - 'browser/browsing_data/history_counter.h', - 'browser/browsing_data/local_data_container.cc', - 'browser/browsing_data/local_data_container.h', - 'browser/browsing_data/passwords_counter.cc', - 'browser/browsing_data/passwords_counter.h', - 'browser/character_encoding.cc', - 'browser/character_encoding.h', - 'browser/chrome_browser_application_mac.h', - 'browser/chrome_browser_application_mac.mm', - 'browser/chrome_browser_field_trials.cc', - 'browser/chrome_browser_field_trials.h', - 'browser/chrome_browser_main.cc', - 'browser/chrome_browser_main.h', - 'browser/chrome_browser_main_android.cc', - 'browser/chrome_browser_main_android.h', - 'browser/chrome_browser_main_extra_parts.h', - 'browser/chrome_browser_main_linux.cc', - 'browser/chrome_browser_main_linux.h', - 'browser/chrome_browser_main_mac.h', - 'browser/chrome_browser_main_mac.mm', - 'browser/chrome_browser_main_win.cc', - 'browser/chrome_browser_main_win.h', - 'browser/chrome_child_process_watcher.cc', - 'browser/chrome_child_process_watcher.h', - 'browser/chrome_content_browser_client.cc', - 'browser/chrome_content_browser_client.h', - 'browser/chrome_content_browser_client_parts.h', - 'browser/chrome_device_client.cc', - 'browser/chrome_device_client.h', - 'browser/chrome_elf_init_win.cc', - 'browser/chrome_elf_init_win.h', - 'browser/chrome_net_benchmarking_message_filter.cc', - 'browser/chrome_net_benchmarking_message_filter.h', - 'browser/chrome_notification_types.h', - 'browser/chrome_quota_permission_context.cc', - 'browser/chrome_quota_permission_context.h', - 'browser/chrome_select_file_dialog_factory_win.cc', - 'browser/chrome_select_file_dialog_factory_win.h', - 'browser/command_observer.h', - 'browser/command_updater.cc', - 'browser/command_updater.h', - 'browser/command_updater_delegate.h', - 'browser/component_updater/caps_installer_win.cc', - 'browser/component_updater/caps_installer_win.h', - 'browser/component_updater/chrome_component_updater_configurator.cc', - 'browser/component_updater/chrome_component_updater_configurator.h', - 'browser/component_updater/cld_component_installer.cc', - 'browser/component_updater/cld_component_installer.h', - 'browser/component_updater/component_patcher_operation_out_of_process.cc', - 'browser/component_updater/component_patcher_operation_out_of_process.h', - 'browser/component_updater/component_updater_resource_throttle.cc', - 'browser/component_updater/component_updater_resource_throttle.h', - 'browser/component_updater/ev_whitelist_component_installer.cc', - 'browser/component_updater/ev_whitelist_component_installer.h', - 'browser/component_updater/pnacl_component_installer.cc', - 'browser/component_updater/pnacl_component_installer.h', - 'browser/component_updater/recovery_component_installer.cc', - 'browser/component_updater/recovery_component_installer.h', - 'browser/component_updater/supervised_user_whitelist_installer.cc', - 'browser/component_updater/supervised_user_whitelist_installer.h', - 'browser/component_updater/sw_reporter_installer_win.cc', - 'browser/component_updater/sw_reporter_installer_win.h', - 'browser/component_updater/swiftshader_component_installer.cc', - 'browser/component_updater/swiftshader_component_installer.h', - 'browser/crash_upload_list.cc', - 'browser/crash_upload_list.h', - 'browser/custom_handlers/protocol_handler_registry.cc', - 'browser/custom_handlers/protocol_handler_registry.h', - 'browser/custom_handlers/protocol_handler_registry_factory.cc', - 'browser/custom_handlers/protocol_handler_registry_factory.h', - 'browser/defaults.cc', - 'browser/defaults.h', - 'browser/dom_distiller/dom_distiller_service_factory.cc', - 'browser/dom_distiller/dom_distiller_service_factory.h', 'browser/dom_distiller/dom_distiller_service_factory_android.cc', 'browser/dom_distiller/dom_distiller_service_factory_android.h', - 'browser/dom_distiller/lazy_dom_distiller_service.cc', - 'browser/dom_distiller/lazy_dom_distiller_service.h', - 'browser/dom_distiller/profile_utils.cc', - 'browser/dom_distiller/profile_utils.h', - 'browser/dom_distiller/tab_utils.cc', - 'browser/dom_distiller/tab_utils.h', 'browser/dom_distiller/tab_utils_android.cc', 'browser/dom_distiller/tab_utils_android.h', - 'browser/domain_reliability/service_factory.cc', - 'browser/domain_reliability/service_factory.h', - 'browser/download/all_download_item_notifier.cc', - 'browser/download/all_download_item_notifier.h', - 'browser/download/chrome_download_manager_delegate.cc', - 'browser/download/chrome_download_manager_delegate.h', - 'browser/download/download_crx_util_android.cc', - 'browser/download/download_extensions.cc', - 'browser/download/download_extensions.h', - 'browser/download/download_file_picker.cc', - 'browser/download/download_file_picker.h', - 'browser/download/download_history.cc', - 'browser/download/download_history.h', - 'browser/download/download_item_model.cc', - 'browser/download/download_item_model.h', - 'browser/download/download_path_reservation_tracker.cc', - 'browser/download/download_path_reservation_tracker.h', - 'browser/download/download_prefs.cc', - 'browser/download/download_prefs.h', - 'browser/download/download_query.cc', - 'browser/download/download_query.h', - 'browser/download/download_request_limiter.cc', - 'browser/download/download_request_limiter.h', - 'browser/download/download_resource_throttle.cc', - 'browser/download/download_resource_throttle.h', - 'browser/download/download_service.cc', - 'browser/download/download_service.h', - 'browser/download/download_service_factory.cc', - 'browser/download/download_service_factory.h', - 'browser/download/download_service_impl.cc', - 'browser/download/download_service_impl.h', - 'browser/download/download_started_animation.h', - 'browser/download/download_stats.cc', - 'browser/download/download_stats.h', - 'browser/download/download_status_updater.cc', - 'browser/download/download_status_updater.h', - 'browser/download/download_status_updater_mac.mm', - 'browser/download/download_status_updater_win.cc', - 'browser/download/download_target_determiner.cc', - 'browser/download/download_target_determiner.h', - 'browser/download/download_target_determiner_delegate.h', - 'browser/download/download_target_info.h', - 'browser/download/download_ui_controller.cc', - 'browser/download/download_ui_controller.h', - 'browser/download/drag_download_item.h', - 'browser/download/save_package_file_picker.cc', - 'browser/download/save_package_file_picker.h', - 'browser/enumerate_modules_model_win.cc', - 'browser/enumerate_modules_model_win.h', - # Oh hey, all the cool browser/extensions files are hanging out in - # chrome/chrome_browser_extensions.gypi. - 'browser/external_protocol/external_protocol_handler.cc', - 'browser/external_protocol/external_protocol_handler.h', - 'browser/external_protocol/external_protocol_observer.cc', - 'browser/external_protocol/external_protocol_observer.h', - 'browser/file_select_helper.cc', - 'browser/file_select_helper.h', - 'browser/file_select_helper_mac.mm', - 'browser/fullscreen.h', - 'browser/fullscreen_chromeos.cc', - 'browser/fullscreen_mac.mm', - 'browser/fullscreen_win.cc', - 'browser/geolocation/chrome_access_token_store.cc', - 'browser/geolocation/chrome_access_token_store.h', - 'browser/geolocation/geolocation_permission_context.cc', - 'browser/geolocation/geolocation_permission_context.h', - 'browser/geolocation/geolocation_permission_context_android.cc', - 'browser/geolocation/geolocation_permission_context_android.h', - 'browser/geolocation/geolocation_permission_context_extensions.cc', - 'browser/geolocation/geolocation_permission_context_extensions.h', - 'browser/geolocation/geolocation_permission_context_factory.cc', - 'browser/geolocation/geolocation_permission_context_factory.h', - 'browser/geolocation/geolocation_prefs.cc', - 'browser/geolocation/geolocation_prefs.h', - 'browser/global_keyboard_shortcuts_mac.h', - 'browser/global_keyboard_shortcuts_mac.mm', - 'browser/gpu/gl_string_manager.cc', - 'browser/gpu/gl_string_manager.h', - 'browser/gpu/gpu_feature_checker.cc', - 'browser/gpu/gpu_feature_checker.h', - 'browser/gpu/gpu_mode_manager.cc', - 'browser/gpu/gpu_mode_manager.h', - 'browser/gpu/three_d_api_observer.cc', - 'browser/gpu/three_d_api_observer.h', - 'browser/icon_loader.cc', - 'browser/icon_loader.h', - 'browser/icon_loader_android.cc', - 'browser/icon_loader_chromeos.cc', - 'browser/icon_loader_mac.mm', - 'browser/icon_loader_win.cc', - 'browser/icon_manager.cc', - 'browser/icon_manager.h', - 'browser/image_decoder.cc', - 'browser/image_decoder.h', - 'browser/image_holder.cc', - 'browser/image_holder.h', - 'browser/infobars/infobar_responder.cc', - 'browser/infobars/infobar_responder.h', - 'browser/infobars/infobar_service.cc', - 'browser/infobars/infobar_service.h', - 'browser/infobars/insecure_content_infobar_delegate.cc', - 'browser/infobars/insecure_content_infobar_delegate.h', - 'browser/install_verification/win/imported_module_verification.cc', - 'browser/install_verification/win/imported_module_verification.h', - 'browser/install_verification/win/install_verification.cc', - 'browser/install_verification/win/install_verification.h', - 'browser/install_verification/win/loaded_module_verification.cc', - 'browser/install_verification/win/loaded_module_verification.h', - 'browser/install_verification/win/loaded_modules_snapshot.cc', - 'browser/install_verification/win/loaded_modules_snapshot.h', - 'browser/install_verification/win/module_ids.cc', - 'browser/install_verification/win/module_ids.h', - 'browser/install_verification/win/module_info.h', - 'browser/install_verification/win/module_list.cc', - 'browser/install_verification/win/module_list.h', - 'browser/install_verification/win/module_verification_common.cc', - 'browser/install_verification/win/module_verification_common.h', + 'browser/download/download_request_infobar_delegate_android.cc', + 'browser/download/download_request_infobar_delegate_android.h', + 'browser/geolocation/geolocation_infobar_delegate_android.cc', + 'browser/geolocation/geolocation_infobar_delegate_android.h', 'browser/interests/android/interests_service.cc', 'browser/interests/android/interests_service.h', - 'browser/interests/interests_fetcher.cc', - 'browser/interests/interests_fetcher.h', - 'browser/internal_auth.cc', - 'browser/internal_auth.h', - 'browser/interstitials/chrome_controller_client.cc', - 'browser/interstitials/chrome_controller_client.h', - 'browser/interstitials/chrome_metrics_helper.cc', - 'browser/interstitials/chrome_metrics_helper.h', - 'browser/interstitials/security_interstitial_page.cc', - 'browser/interstitials/security_interstitial_page.h', - 'browser/intranet_redirect_detector.cc', - 'browser/intranet_redirect_detector.h', 'browser/invalidation/invalidation_service_factory_android.cc', 'browser/invalidation/invalidation_service_factory_android.h', - 'browser/invalidation/profile_invalidation_provider_factory.cc', - 'browser/invalidation/profile_invalidation_provider_factory.h', - 'browser/io_thread.cc', - 'browser/io_thread.h', - 'browser/jumplist_updater_win.cc', - 'browser/jumplist_updater_win.h', - 'browser/jumplist_win.cc', - 'browser/jumplist_win.h', - 'browser/lifetime/application_lifetime.cc', - 'browser/lifetime/application_lifetime.h', 'browser/lifetime/application_lifetime_android.cc', 'browser/lifetime/application_lifetime_android.h', - 'browser/lifetime/application_lifetime_mac.mm', - 'browser/lifetime/application_lifetime_win.cc', - 'browser/mac/bluetooth_utility.h', - 'browser/mac/bluetooth_utility.mm', - 'browser/mac/dock.h', - 'browser/mac/dock.mm', - 'browser/mac/install_from_dmg.h', - 'browser/mac/install_from_dmg.mm', - 'browser/mac/keystone_glue.h', - 'browser/mac/keystone_glue.mm', - 'browser/mac/keystone_registration.h', - 'browser/mac/keystone_registration.mm', - 'browser/mac/mac_startup_profiler.cc', - 'browser/mac/mac_startup_profiler.h', - 'browser/mac/master_prefs.h', - 'browser/mac/master_prefs.mm', - 'browser/mac/relauncher.cc', - 'browser/mac/relauncher.h', - 'browser/mac/security_wrappers.cc', - 'browser/mac/security_wrappers.h', - 'browser/manifest/manifest_icon_downloader.cc', - 'browser/manifest/manifest_icon_downloader.h', - 'browser/manifest/manifest_icon_selector.cc', - 'browser/manifest/manifest_icon_selector.h', 'browser/media/android/cdm/media_drm_credential_manager.cc', 'browser/media/android/cdm/media_drm_credential_manager.h', 'browser/media/android/remote/record_cast_action.cc', @@ -625,293 +902,18 @@ 'browser/media/android/router/media_router_android.h', 'browser/media/android/router/media_router_dialog_controller_android.cc', 'browser/media/android/router/media_router_dialog_controller_android.h', - 'browser/media/desktop_media_list.h', - 'browser/media/desktop_media_picker.h', - 'browser/media/desktop_streams_registry.cc', - 'browser/media/desktop_streams_registry.h', - 'browser/media/media_access_handler.h', - 'browser/media/media_capture_devices_dispatcher.cc', - 'browser/media/media_capture_devices_dispatcher.h', - 'browser/media/media_device_id_salt.cc', - 'browser/media/media_device_id_salt.h', - 'browser/media/media_permission.cc', - 'browser/media/media_permission.h', - 'browser/media/media_stream_camera_permission_context_factory.cc', - 'browser/media/media_stream_camera_permission_context_factory.h', - 'browser/media/media_stream_capture_indicator.cc', - 'browser/media/media_stream_capture_indicator.h', - 'browser/media/media_stream_device_permission_context.cc', - 'browser/media/media_stream_device_permission_context.h', - 'browser/media/media_stream_device_permissions.cc', - 'browser/media/media_stream_device_permissions.h', - 'browser/media/media_stream_devices_controller.cc', - 'browser/media/media_stream_devices_controller.h', - 'browser/media/media_stream_mic_permission_context_factory.cc', - 'browser/media/media_stream_mic_permission_context_factory.h', - 'browser/media/media_url_constants.cc', - 'browser/media/media_url_constants.h', - 'browser/media/midi_permission_context.cc', - 'browser/media/midi_permission_context.h', - 'browser/media/midi_permission_context_factory.cc', - 'browser/media/midi_permission_context_factory.h', - 'browser/media/native_desktop_media_list.cc', - 'browser/media/native_desktop_media_list.h', - 'browser/media/permission_bubble_media_access_handler.cc', - 'browser/media/permission_bubble_media_access_handler.h', - 'browser/media/router/media_router_feature.cc', - 'browser/media/router/media_router_feature.h', - # TODO(brettw) should this go with the webrtc sources? - 'browser/media/webrtc_log_list.cc', - 'browser/media/webrtc_log_list.h', - 'browser/memory_details.cc', - 'browser/memory_details.h', - 'browser/memory_details_android.cc', - 'browser/memory_details_linux.cc', - 'browser/memory_details_mac.cc', - 'browser/memory_details_win.cc', - 'browser/mod_pagespeed/mod_pagespeed_metrics.cc', - 'browser/mod_pagespeed/mod_pagespeed_metrics.h', - 'browser/native_window_notification_source.h', - 'browser/net/predictor_tab_helper.cc', - 'browser/net/predictor_tab_helper.h', - 'browser/ntp_snippets/ntp_snippets_service_factory.cc', - 'browser/ntp_snippets/ntp_snippets_service_factory.h', - 'browser/page_load_metrics/observers/from_gws_page_load_metrics_observer.cc', - 'browser/page_load_metrics/observers/from_gws_page_load_metrics_observer.h', - 'browser/page_load_metrics/observers/google_captcha_observer.cc', - 'browser/page_load_metrics/observers/google_captcha_observer.h', - 'browser/page_load_metrics/observers/stale_while_revalidate_metrics_observer.cc', - 'browser/page_load_metrics/observers/stale_while_revalidate_metrics_observer.h', - 'browser/page_load_metrics/page_load_metrics_initialize.cc', - 'browser/page_load_metrics/page_load_metrics_initialize.h', - 'browser/performance_monitor/performance_monitor.cc', - 'browser/performance_monitor/performance_monitor.h', - 'browser/performance_monitor/process_metrics_history.cc', - 'browser/performance_monitor/process_metrics_history.h', - 'browser/platform_util.h', - 'browser/platform_util_android.cc', - 'browser/platform_util_chromeos.cc', - 'browser/platform_util_internal.h', - 'browser/platform_util_mac.mm', - 'browser/platform_util_win.cc', - 'browser/prefetch/prefetch.cc', - 'browser/prefetch/prefetch.h', - 'browser/prefetch/prefetch_field_trial.cc', - 'browser/prefetch/prefetch_field_trial.h', - 'browser/prerender/external_prerender_handler_android.cc', - 'browser/prerender/external_prerender_handler_android.h', - 'browser/prerender/prerender_config.cc', - 'browser/prerender/prerender_config.h', - 'browser/prerender/prerender_contents.cc', - 'browser/prerender/prerender_contents.h', - 'browser/prerender/prerender_field_trial.cc', - 'browser/prerender/prerender_field_trial.h', - 'browser/prerender/prerender_final_status.cc', - 'browser/prerender/prerender_final_status.h', - 'browser/prerender/prerender_handle.cc', - 'browser/prerender/prerender_handle.h', - 'browser/prerender/prerender_histograms.cc', - 'browser/prerender/prerender_histograms.h', - 'browser/prerender/prerender_history.cc', - 'browser/prerender/prerender_history.h', - 'browser/prerender/prerender_link_manager.cc', - 'browser/prerender/prerender_link_manager.h', - 'browser/prerender/prerender_link_manager_factory.cc', - 'browser/prerender/prerender_link_manager_factory.h', - 'browser/prerender/prerender_manager.cc', - 'browser/prerender/prerender_manager.h', - 'browser/prerender/prerender_manager_factory.cc', - 'browser/prerender/prerender_manager_factory.h', - 'browser/prerender/prerender_message_filter.cc', - 'browser/prerender/prerender_message_filter.h', - 'browser/prerender/prerender_origin.cc', - 'browser/prerender/prerender_origin.h', - 'browser/prerender/prerender_resource_throttle.cc', - 'browser/prerender/prerender_resource_throttle.h', - 'browser/prerender/prerender_tab_helper.cc', - 'browser/prerender/prerender_tab_helper.h', - 'browser/prerender/prerender_util.cc', - 'browser/prerender/prerender_util.h', - 'browser/private_working_set_snapshot.h', - 'browser/private_working_set_snapshot_win.cc', - 'browser/process_info_snapshot.h', - 'browser/process_info_snapshot_mac.cc', - 'browser/process_resource_usage.cc', - 'browser/process_resource_usage.h', - 'browser/process_singleton.h', - 'browser/process_singleton_win.cc', - 'browser/push_messaging/push_messaging_app_identifier.cc', - 'browser/push_messaging/push_messaging_app_identifier.h', - 'browser/push_messaging/push_messaging_constants.cc', - 'browser/push_messaging/push_messaging_constants.h', - 'browser/push_messaging/push_messaging_permission_context.cc', - 'browser/push_messaging/push_messaging_permission_context.h', - 'browser/push_messaging/push_messaging_permission_context_factory.cc', - 'browser/push_messaging/push_messaging_permission_context_factory.h', - 'browser/push_messaging/push_messaging_service_factory.cc', - 'browser/push_messaging/push_messaging_service_factory.h', - 'browser/push_messaging/push_messaging_service_impl.cc', - 'browser/push_messaging/push_messaging_service_impl.h', - 'browser/renderer_context_menu/context_menu_content_type_factory.cc', - 'browser/renderer_context_menu/context_menu_content_type_factory.h', - 'browser/renderer_context_menu/context_menu_content_type_panel.cc', - 'browser/renderer_context_menu/context_menu_content_type_panel.h', - 'browser/renderer_host/chrome_render_message_filter.cc', - 'browser/renderer_host/chrome_render_message_filter.h', - 'browser/renderer_host/chrome_render_widget_host_view_mac_delegate.h', - 'browser/renderer_host/chrome_render_widget_host_view_mac_delegate.mm', - 'browser/renderer_host/chrome_render_widget_host_view_mac_history_swiper.h', - 'browser/renderer_host/chrome_render_widget_host_view_mac_history_swiper.mm', - 'browser/renderer_host/chrome_resource_dispatcher_host_delegate.cc', - 'browser/renderer_host/chrome_resource_dispatcher_host_delegate.h', - 'browser/renderer_host/thread_hop_resource_throttle.cc', - 'browser/renderer_host/thread_hop_resource_throttle.h', - 'browser/renderer_preferences_util.cc', - 'browser/renderer_preferences_util.h', - 'browser/resources_util.cc', - 'browser/resources_util.h', - 'browser/safe_browsing/safe_browsing_tab_observer.cc', - 'browser/safe_browsing/safe_browsing_tab_observer.h', - 'browser/safe_browsing/srt_fetcher_win.cc', - 'browser/safe_browsing/srt_fetcher_win.h', - 'browser/safe_browsing/srt_field_trial_win.cc', - 'browser/safe_browsing/srt_field_trial_win.h', - 'browser/safe_browsing/srt_global_error_win.cc', - 'browser/safe_browsing/srt_global_error_win.h', - 'browser/search/contextual_search_policy_handler_android.cc', - 'browser/search/contextual_search_policy_handler_android.h', - 'browser/search/iframe_source.cc', - 'browser/search/iframe_source.h', - 'browser/search/instant_io_context.cc', - 'browser/search/instant_io_context.h', - 'browser/search/instant_service.cc', - 'browser/search/instant_service.h', - 'browser/search/instant_service_factory.cc', - 'browser/search/instant_service_factory.h', - 'browser/search/instant_service_observer.cc', - 'browser/search/instant_service_observer.h', - 'browser/search/most_visited_iframe_source.cc', - 'browser/search/most_visited_iframe_source.h', - 'browser/search/search.cc', - 'browser/search/search.h', - 'browser/search/suggestions/image_fetcher_impl.cc', - 'browser/search/suggestions/image_fetcher_impl.h', - 'browser/search/suggestions/suggestions_service_factory.cc', - 'browser/search/suggestions/suggestions_service_factory.h', - 'browser/search/suggestions/suggestions_source.cc', - 'browser/search/suggestions/suggestions_source.h', - 'browser/search/thumbnail_source.cc', - 'browser/search/thumbnail_source.h', - 'browser/shell_integration.cc', - 'browser/shell_integration.h', - 'browser/shell_integration_android.cc', - 'browser/shell_integration_chromeos.cc', - 'browser/shell_integration_mac.mm', - 'browser/shell_integration_win.cc', - 'browser/site_details.cc', - 'browser/site_details.h', - 'browser/speech/chrome_speech_recognition_manager_delegate.cc', - 'browser/speech/chrome_speech_recognition_manager_delegate.h', - 'browser/speech/tts_android.cc', - 'browser/speech/tts_android.h', - 'browser/speech/tts_chromeos.cc', - 'browser/speech/tts_controller.h', - 'browser/speech/tts_controller_impl.cc', - 'browser/speech/tts_controller_impl.h', - 'browser/speech/tts_mac.mm', - 'browser/speech/tts_message_filter.cc', - 'browser/speech/tts_message_filter.h', - 'browser/speech/tts_platform.cc', - 'browser/speech/tts_platform.h', - 'browser/speech/tts_win.cc', - 'browser/stack_sampling_configuration.cc', - 'browser/stack_sampling_configuration.h', - 'browser/status_icons/status_icon.cc', - 'browser/status_icons/status_icon.h', - 'browser/status_icons/status_icon_menu_model.cc', - 'browser/status_icons/status_icon_menu_model.h', - 'browser/status_icons/status_icon_observer.h', - 'browser/status_icons/status_tray.cc', - 'browser/status_icons/status_tray.h', - 'browser/storage/durable_storage_permission_context.cc', - 'browser/storage/durable_storage_permission_context.h', - 'browser/storage/durable_storage_permission_context_factory.cc', - 'browser/storage/durable_storage_permission_context_factory.h', - 'browser/tab_contents/navigation_metrics_recorder.cc', - 'browser/tab_contents/navigation_metrics_recorder.h', - 'browser/tab_contents/retargeting_details.h', - 'browser/tab_contents/tab_util.cc', - 'browser/tab_contents/tab_util.h', - 'browser/task_management/web_contents_tags.cc', - 'browser/task_management/web_contents_tags.h', - 'browser/task_profiler/task_profiler_data_serializer.cc', - 'browser/task_profiler/task_profiler_data_serializer.h', - 'browser/thumbnails/content_analysis.cc', - 'browser/thumbnails/content_analysis.h', - 'browser/thumbnails/content_based_thumbnailing_algorithm.cc', - 'browser/thumbnails/content_based_thumbnailing_algorithm.h', - 'browser/thumbnails/simple_thumbnail_crop.cc', - 'browser/thumbnails/simple_thumbnail_crop.h', - 'browser/thumbnails/thumbnail_list_source.cc', - 'browser/thumbnails/thumbnail_list_source.h', - 'browser/thumbnails/thumbnail_service.h', - 'browser/thumbnails/thumbnail_service_factory.cc', - 'browser/thumbnails/thumbnail_service_factory.h', - 'browser/thumbnails/thumbnail_service_impl.cc', - 'browser/thumbnails/thumbnail_service_impl.h', - 'browser/thumbnails/thumbnail_tab_helper.cc', - 'browser/thumbnails/thumbnail_tab_helper.h', - 'browser/thumbnails/thumbnailing_algorithm.h', - 'browser/thumbnails/thumbnailing_context.cc', - 'browser/thumbnails/thumbnailing_context.h', - 'browser/tracing/background_tracing_field_trial.cc', - 'browser/tracing/background_tracing_field_trial.h', - 'browser/tracing/crash_service_uploader.cc', - 'browser/tracing/crash_service_uploader.h', - 'browser/tracing/navigation_tracing.cc', - 'browser/tracing/navigation_tracing.h', - 'browser/translate/chrome_translate_client.cc', - 'browser/translate/chrome_translate_client.h', - 'browser/translate/translate_accept_languages_factory.cc', - 'browser/translate/translate_accept_languages_factory.h', - 'browser/translate/translate_service.cc', - 'browser/translate/translate_service.h', - 'browser/update_client/chrome_update_query_params_delegate.cc', - 'browser/update_client/chrome_update_query_params_delegate.h', - 'browser/usb/usb_chooser_context.cc', - 'browser/usb/usb_chooser_context.h', - 'browser/usb/usb_chooser_context_factory.cc', - 'browser/usb/usb_chooser_context_factory.h', - 'browser/usb/usb_tab_helper.cc', - 'browser/usb/usb_tab_helper.h', - 'browser/usb/web_usb_permission_provider.cc', - 'browser/usb/web_usb_permission_provider.h', - 'browser/web_data_service_factory.cc', - 'browser/web_data_service_factory.h', - ], - 'chrome_browser_android_sources': [ - 'browser/android/background_sync_launcher_android.cc', - 'browser/android/background_sync_launcher_android.h', - 'browser/android/data_usage/data_use_tab_ui_manager_android.cc', - 'browser/android/data_usage/data_use_tab_ui_manager_android.h', - 'browser/download/download_request_infobar_delegate_android.cc', - 'browser/download/download_request_infobar_delegate_android.h', - 'browser/geolocation/geolocation_infobar_delegate_android.cc', - 'browser/geolocation/geolocation_infobar_delegate_android.h', 'browser/media/media_stream_infobar_delegate_android.cc', 'browser/media/media_stream_infobar_delegate_android.h', 'browser/media/midi_permission_infobar_delegate_android.cc', 'browser/media/midi_permission_infobar_delegate_android.h', 'browser/media/protected_media_identifier_infobar_delegate_android.cc', 'browser/media/protected_media_identifier_infobar_delegate_android.h', - 'browser/media/protected_media_identifier_permission_context.cc', - 'browser/media/protected_media_identifier_permission_context.h', - 'browser/media/protected_media_identifier_permission_context_factory.cc', - 'browser/media/protected_media_identifier_permission_context_factory.h', 'browser/metrics/android_metrics_provider.cc', 'browser/metrics/android_metrics_provider.h', 'browser/net/spdyproxy/data_reduction_proxy_infobar_delegate_android.cc', 'browser/net/spdyproxy/data_reduction_proxy_infobar_delegate_android.h', + 'browser/net/spdyproxy/data_reduction_proxy_settings_android.cc', + 'browser/net/spdyproxy/data_reduction_proxy_settings_android.h', 'browser/password_manager/account_chooser_dialog_android.cc', 'browser/password_manager/account_chooser_dialog_android.h', 'browser/password_manager/auto_signin_first_run_infobar_delegate.cc', @@ -924,6 +926,12 @@ 'browser/permissions/permission_queue_controller.h', 'browser/precache/precache_manager_factory.cc', 'browser/precache/precache_manager_factory.h', + 'browser/prerender/external_prerender_handler_android.cc', + 'browser/prerender/external_prerender_handler_android.h', + 'browser/profiles/profile_android.cc', + 'browser/profiles/profile_android.h', + 'browser/search/contextual_search_policy_handler_android.cc', + 'browser/search/contextual_search_policy_handler_android.h', 'browser/signin/oauth2_token_service_delegate_android.cc', 'browser/signin/oauth2_token_service_delegate_android.h', 'browser/ssl/ssl_add_certificate_android.cc', @@ -1730,14 +1738,6 @@ 'browser/google/google_url_tracker_factory.h', ], 'chrome_browser_history_sources': [ - 'browser/history/android/android_history_provider_service.cc', - 'browser/history/android/android_history_provider_service.h', - 'browser/history/android/android_provider_backend.cc', - 'browser/history/android/android_provider_backend.h', - 'browser/history/android/bookmark_model_sql_handler.cc', - 'browser/history/android/bookmark_model_sql_handler.h', - 'browser/history/android/sqlite_cursor.cc', - 'browser/history/android/sqlite_cursor.h', 'browser/history/chrome_history_backend_client.cc', 'browser/history/chrome_history_backend_client.h', 'browser/history/chrome_history_client.cc', @@ -1753,6 +1753,17 @@ 'browser/history/web_history_service_factory.cc', 'browser/history/web_history_service_factory.h', ], + # History sources used when android_java_ui is enabled. + 'chrome_browser_history_android_java_ui_sources': [ + 'browser/history/android/android_history_provider_service.cc', + 'browser/history/android/android_history_provider_service.h', + 'browser/history/android/android_provider_backend.cc', + 'browser/history/android/android_provider_backend.h', + 'browser/history/android/bookmark_model_sql_handler.cc', + 'browser/history/android/bookmark_model_sql_handler.h', + 'browser/history/android/sqlite_cursor.cc', + 'browser/history/android/sqlite_cursor.h', + ], 'chrome_browser_jni_sources': [ 'android/java/src/org/chromium/chrome/browser/AfterStartupTaskUtils.java', 'android/java/src/org/chromium/chrome/browser/ApplicationLifetime.java', @@ -2006,8 +2017,6 @@ 'browser/net/spdyproxy/data_reduction_proxy_chrome_settings.h', 'browser/net/spdyproxy/data_reduction_proxy_chrome_settings_factory.cc', 'browser/net/spdyproxy/data_reduction_proxy_chrome_settings_factory.h', - 'browser/net/spdyproxy/data_reduction_proxy_settings_android.cc', - 'browser/net/spdyproxy/data_reduction_proxy_settings_android.h', 'browser/net/timed_cache.cc', 'browser/net/timed_cache.h', 'browser/net/url_info.cc', @@ -2029,8 +2038,6 @@ 'browser/notifications/notification_permission_context_factory.cc', 'browser/notifications/notification_permission_context_factory.h', 'browser/notifications/notification_ui_manager.h', - 'browser/notifications/notification_ui_manager_android.cc', - 'browser/notifications/notification_ui_manager_android.h', 'browser/notifications/notifier_state_tracker.cc', 'browser/notifications/notifier_state_tracker.h', 'browser/notifications/notifier_state_tracker_factory.cc', @@ -2044,8 +2051,10 @@ 'browser/push_messaging/push_messaging_notification_manager.cc', 'browser/push_messaging/push_messaging_notification_manager.h', ], - # Used on Android when notifications are enabled. - 'chrome_browser_notifications_android_sources': [ + # Used on Android when notifications and java_ui are enabled. + 'chrome_browser_notifications_android_java_ui_sources': [ + 'browser/notifications/notification_ui_manager_android.cc', + 'browser/notifications/notification_ui_manager_android.h', 'browser/notifications/notification_permission_infobar_delegate.cc', 'browser/notifications/notification_permission_infobar_delegate.h', ], @@ -2126,11 +2135,14 @@ 'browser/permissions/permission_request_id.h', 'browser/permissions/permission_uma_util.cc', 'browser/permissions/permission_uma_util.h', - 'browser/permissions/permission_update_infobar_delegate_android.cc', - 'browser/permissions/permission_update_infobar_delegate_android.h', 'browser/permissions/permission_util.cc', 'browser/permissions/permission_util.h', ], + # Permissions sources used when android_java_ui is enabled. + 'chrome_browser_permissions_android_java_ui_sources': [ + 'browser/permissions/permission_update_infobar_delegate_android.cc', + 'browser/permissions/permission_update_infobar_delegate_android.h', + ], # See also the plugin_installation_sources list below. 'chrome_browser_plugins_sources': [ 'browser/browsing_data/browsing_data_flash_lso_helper.cc', @@ -2407,8 +2419,6 @@ 'browser/profiles/off_the_record_profile_io_data.h', 'browser/profiles/profile.cc', 'browser/profiles/profile.h', - 'browser/profiles/profile_android.cc', - 'browser/profiles/profile_android.h', 'browser/profiles/profile_attributes_entry.cc', 'browser/profiles/profile_attributes_entry.h', 'browser/profiles/profile_attributes_storage.h', @@ -2606,8 +2616,6 @@ 'browser/search_engines/search_provider_install_state_message_filter.h', 'browser/search_engines/template_url_fetcher_factory.cc', 'browser/search_engines/template_url_fetcher_factory.h', - 'browser/search_engines/template_url_service_android.cc', - 'browser/search_engines/template_url_service_android.h', 'browser/search_engines/template_url_service_factory.cc', 'browser/search_engines/template_url_service_factory.h', 'browser/search_engines/ui_thread_search_terms_data.cc', @@ -2615,6 +2623,11 @@ 'browser/search_engines/ui_thread_search_terms_data_android.cc', 'browser/search_engines/ui_thread_search_terms_data_android.h', ], + # Search sources used when android_java_ui is enabled. + 'chrome_browser_search_engines_android_java_ui_sources': [ + 'browser/search_engines/template_url_service_android.cc', + 'browser/search_engines/template_url_service_android.h', + ], 'chrome_browser_service_discovery_sources': [ 'browser/local_discovery/cloud_device_list.cc', 'browser/local_discovery/cloud_device_list.h', @@ -2792,8 +2805,6 @@ 'browser/ssl/common_name_mismatch_handler.h', 'browser/ssl/security_state_model.cc', 'browser/ssl/security_state_model.h', - 'browser/ssl/security_state_model_android.cc', - 'browser/ssl/security_state_model_android.h', 'browser/ssl/security_state_model_client.h', 'browser/ssl/ssl_blocking_page.cc', 'browser/ssl/ssl_blocking_page.h', @@ -2802,15 +2813,16 @@ 'browser/ssl/ssl_error_handler.cc', 'browser/ssl/ssl_error_handler.h', ], + # SSL sources used when android_java_ui is enabled. + 'chrome_browser_ssl_android_java_ui_sources': [ + 'browser/ssl/security_state_model_android.cc', + 'browser/ssl/security_state_model_android.h', + ], 'chrome_browser_supervised_user_sources': [ 'browser/content_settings/content_settings_supervised_provider.cc', 'browser/content_settings/content_settings_supervised_provider.h', - 'browser/supervised_user/child_accounts/child_account_feedback_reporter_android.cc', - 'browser/supervised_user/child_accounts/child_account_feedback_reporter_android.h', 'browser/supervised_user/child_accounts/child_account_service.cc', 'browser/supervised_user/child_accounts/child_account_service.h', - 'browser/supervised_user/child_accounts/child_account_service_android.cc', - 'browser/supervised_user/child_accounts/child_account_service_android.h', 'browser/supervised_user/child_accounts/child_account_service_factory.cc', 'browser/supervised_user/child_accounts/child_account_service_factory.h', 'browser/supervised_user/child_accounts/family_info_fetcher.cc', @@ -2855,6 +2867,13 @@ 'browser/supervised_user/supervised_user_whitelist_service.h', 'browser/supervised_user/supervised_users.h', ], + # Child accounts sources used with android_java_ui enabled. + 'chrome_browser_supervised_user_android_java_ui_sources': [ + 'browser/supervised_user/child_accounts/child_account_feedback_reporter_android.cc', + 'browser/supervised_user/child_accounts/child_account_feedback_reporter_android.h', + 'browser/supervised_user/child_accounts/child_account_service_android.cc', + 'browser/supervised_user/child_accounts/child_account_service_android.h', + ], # TODO(bauerb): This code should be removed (on desktop) once child account # support has launched (https://crbug.com/505443). 'chrome_browser_supervised_user_legacy_sources': [ @@ -2897,14 +2916,6 @@ 'browser/sync/glue/extensions_activity_monitor.h', 'browser/sync/glue/sync_start_util.cc', 'browser/sync/glue/sync_start_util.h', - 'browser/sync/glue/synced_tab_delegate_android.cc', - 'browser/sync/glue/synced_tab_delegate_android.h', - 'browser/sync/glue/synced_window_delegate_android.cc', - 'browser/sync/glue/synced_window_delegate_android.h', - 'browser/sync/glue/synced_window_delegates_getter_android.cc', - 'browser/sync/glue/synced_window_delegates_getter_android.h', - 'browser/sync/profile_sync_service_android.cc', - 'browser/sync/profile_sync_service_android.h', 'browser/sync/profile_sync_service_factory.cc', 'browser/sync/profile_sync_service_factory.h', 'browser/sync/sessions/notification_service_sessions_router.cc', @@ -2914,6 +2925,17 @@ 'browser/sync/sync_startup_tracker.cc', 'browser/sync/sync_startup_tracker.h', ], + # Sync sources used when android_java_ui is enabled. + 'chrome_browser_sync_android_java_ui_sources': [ + 'browser/sync/glue/synced_tab_delegate_android.cc', + 'browser/sync/glue/synced_tab_delegate_android.h', + 'browser/sync/glue/synced_window_delegate_android.cc', + 'browser/sync/glue/synced_window_delegate_android.h', + 'browser/sync/profile_sync_service_android.cc', + 'browser/sync/profile_sync_service_android.h', + 'browser/sync/glue/synced_window_delegates_getter_android.cc', + 'browser/sync/glue/synced_window_delegates_getter_android.h', + ], 'chrome_browser_task_manager_sources': [ # Stats collection for CAPS (uses old task manager): 'browser/caps/generate_state_json.cc', @@ -3606,13 +3628,13 @@ ['notifications==1', { 'sources': [ '<@(chrome_browser_notifications_sources)' ], 'conditions': [ - ['OS!="android"', { + ['android_java_ui==0', { 'sources': [ '<@(chrome_browser_notifications_non_android_sources)', ], }, { 'sources': [ - '<@(chrome_browser_notifications_android_sources)', + '<@(chrome_browser_notifications_android_java_ui_sources)', ], }], ], @@ -3665,21 +3687,9 @@ 'dependencies': [ '../build/android/ndk.gyp:cpu_features', '../components/components.gyp:cdm_browser', - '../components/components.gyp:data_reduction_proxy_content', - '../components/components.gyp:data_usage_android', - '../components/components.gyp:enhanced_bookmarks', - '../components/components.gyp:offline_pages', - '../components/components.gyp:precache_content', - '../components/components.gyp:precache_core', - '../components/components.gyp:service_tab_launcher', - '../components/components.gyp:toolbar', - '../components/components.gyp:web_contents_delegate_android', '../components/components_resources.gyp:components_resources', '../third_party/android_opengl/etc1/etc1.gyp:etc1', '../third_party/libaddressinput/libaddressinput.gyp:libaddressinput_util', - 'chrome_browser_jni_headers', - 'client_discourse_context_proto', - 'delta_file_proto', ], 'dependencies!': [ '../components/components.gyp:storage_monitor', @@ -3688,10 +3698,35 @@ ], 'sources': [ '<@(chrome_browser_android_sources)', - '<@(chrome_browser_bookmark_android_sources)', ], - 'defines': [ 'ENABLE_DATA_REDUCTION_PROXY_DEBUGGING' ], 'conditions': [ + ['android_java_ui==1', { + 'dependencies': [ + '../components/components.gyp:data_reduction_proxy_content', + '../components/components.gyp:data_usage_android', + '../components/components.gyp:enhanced_bookmarks', + '../components/components.gyp:offline_pages', + '../components/components.gyp:precache_content', + '../components/components.gyp:precache_core', + '../components/components.gyp:service_tab_launcher', + '../components/components.gyp:toolbar', + '../components/components.gyp:web_contents_delegate_android', + 'chrome_browser_jni_headers', + 'client_discourse_context_proto', + 'delta_file_proto', + ], + 'sources': [ + '<@(chrome_browser_android_java_ui_sources)', + '<@(chrome_browser_bookmark_android_sources)', + '<@(chrome_browser_sync_android_java_ui_sources)', + '<@(chrome_browser_supervised_user_android_java_ui_sources)', + '<@(chrome_browser_ssl_android_java_ui_sources)', + '<@(chrome_browser_search_engines_android_java_ui_sources)', + '<@(chrome_browser_permissions_android_java_ui_sources)', + '<@(chrome_browser_history_android_java_ui_sources)', + ], + 'defines': [ 'ENABLE_DATA_REDUCTION_PROXY_DEBUGGING' ], + }], ['use_seccomp_bpf==1', { 'defines': ['USE_SECCOMP_BPF'], 'dependencies': [ @@ -3939,7 +3974,7 @@ }, ], 'conditions': [ - ['OS=="android"', { + ['android_java_ui == 1', { 'targets': [ { # GN: //chrome/browser:jni_headers
diff --git a/chrome/chrome_browser_ui.gypi b/chrome/chrome_browser_ui.gypi index 816ddb3..c3d58c9 100644 --- a/chrome/chrome_browser_ui.gypi +++ b/chrome/chrome_browser_ui.gypi
@@ -15,8 +15,6 @@ 'browser/ui/android/android_about_app_info.h', 'browser/ui/android/external_protocol_dialog_android.cc', 'browser/ui/android/status_tray_android.cc', - 'browser/ui/android/tab_model/tab_model_list.cc', - 'browser/ui/android/tab_model/tab_model_list.h', 'browser/ui/app_list/app_list_util.cc', 'browser/ui/app_list/app_list_util.h', # All other browser/ui/app_list files go in chrome_browser_ui_app_list_sources. @@ -425,7 +423,7 @@ 'browser/ui/zoom/chrome_zoom_level_prefs.cc', 'browser/ui/zoom/chrome_zoom_level_prefs.h', ], - 'chrome_browser_ui_android_non_aura_sources': [ + 'chrome_browser_ui_android_java_ui_sources': [ 'browser/ui/android/autofill/autofill_dialog_controller_android.cc', 'browser/ui/android/autofill/autofill_dialog_controller_android.h', 'browser/ui/android/autofill/autofill_dialog_result.cc', @@ -494,6 +492,10 @@ 'browser/ui/android/tab_model/tab_model.h', 'browser/ui/android/tab_model/tab_model_jni_bridge.cc', 'browser/ui/android/tab_model/tab_model_jni_bridge.h', + 'browser/ui/android/tab_model/tab_model_list.cc', + 'browser/ui/android/tab_model/tab_model_list.h', + 'browser/ui/android/toolbar/toolbar_model_android.cc', + 'browser/ui/android/toolbar/toolbar_model_android.h', 'browser/ui/android/website_settings_popup_android.cc', 'browser/ui/android/website_settings_popup_android.h', 'browser/ui/android/window_android_helper.cc', @@ -720,6 +722,19 @@ 'browser/ui/views/select_file_dialog_extension_factory.cc', 'browser/ui/views/select_file_dialog_extension_factory.h', ], + # ARC-only sources. + 'chrome_browser_ui_chromeos_arc_sources': [ + 'browser/ui/app_list/arc/arc_app_icon.cc', + 'browser/ui/app_list/arc/arc_app_icon.h', + 'browser/ui/app_list/arc/arc_app_item.cc', + 'browser/ui/app_list/arc/arc_app_item.h', + 'browser/ui/app_list/arc/arc_app_list_prefs_factory.cc', + 'browser/ui/app_list/arc/arc_app_list_prefs_factory.h', + 'browser/ui/app_list/arc/arc_app_list_prefs.cc', + 'browser/ui/app_list/arc/arc_app_list_prefs.h', + 'browser/ui/app_list/arc/arc_app_model_builder.cc', + 'browser/ui/app_list/arc/arc_app_model_builder.h', + ], # ChromeOS sources that should not be included in the official build. 'chrome_browser_ui_chromeos_non_official_sources': [ 'browser/ui/webui/chromeos/emulator/device_emulator_message_handler.cc', @@ -2541,6 +2556,8 @@ 'browser/ui/app_list/app_list_controller_delegate_impl.h', 'browser/ui/app_list/app_list_icon_win.cc', 'browser/ui/app_list/app_list_icon_win.h', + 'browser/ui/app_list/app_list_model_builder.cc', + 'browser/ui/app_list/app_list_model_builder.h', 'browser/ui/app_list/app_list_positioner.cc', 'browser/ui/app_list/app_list_positioner.h', 'browser/ui/app_list/app_list_prefs.cc', @@ -2770,8 +2787,6 @@ 'browser/ui/webui/local_discovery/local_discovery_ui_handler.h', ], 'chrome_browser_ui_toolbar_model_sources': [ - 'browser/ui/android/toolbar/toolbar_model_android.cc', - 'browser/ui/android/toolbar/toolbar_model_android.h', 'browser/ui/toolbar/chrome_toolbar_model.cc', 'browser/ui/toolbar/chrome_toolbar_model.h', 'browser/ui/toolbar/toolbar_model_delegate.h', @@ -2807,6 +2822,7 @@ 'chrome_resources.gyp:platform_locale_settings', 'chrome_resources.gyp:theme_resources', 'common', + '../base/base.gyp:base_debugging_flags', '../components/components.gyp:auto_login_parser', '../components/components.gyp:certificate_reporting', '../components/components.gyp:device_event_log_component', @@ -2957,6 +2973,9 @@ '../ui/chromeos/ui_chromeos.gyp:ui_chromeos_resources', ], }], + ['enable_app_list==1 and chromeos==1', { + 'sources': [ '<@(chrome_browser_ui_chromeos_arc_sources)' ], + }], ['use_cups==1', { 'dependencies': [ '../printing/printing.gyp:cups', @@ -3060,15 +3079,21 @@ }], ['OS=="android"', { 'dependencies': [ - '../components/components.gyp:web_contents_delegate_android', '../third_party/boringssl/boringssl.gyp:boringssl', - 'chrome_browser_jni_headers', ], - 'dependencies!': [ - '../ui/events/events.gyp:events', - 'chrome_browser_ui_views.gyp:browser_ui_views', + 'conditions': [ + ['android_java_ui == 1', { + 'sources': [ '<@(chrome_browser_ui_android_java_ui_sources)' ], + 'dependencies': [ + '../components/components.gyp:web_contents_delegate_android', + 'chrome_browser_jni_headers', + ], + 'dependencies!': [ + '../ui/events/events.gyp:events', + 'chrome_browser_ui_views.gyp:browser_ui_views', + ], + }] ], - 'sources': [ '<@(chrome_browser_ui_android_non_aura_sources)' ], }], ['OS=="mac"', { 'sources': [ '<@(chrome_browser_ui_mac_sources)' ],
diff --git a/chrome/chrome_dll.gypi b/chrome/chrome_dll.gypi index 52a7401a..c873e52 100644 --- a/chrome/chrome_dll.gypi +++ b/chrome/chrome_dll.gypi
@@ -123,9 +123,7 @@ ], 'dependencies': [ '<@(chromium_browser_dependencies)', - '../components/components.gyp:crash_component', '../content/content.gyp:content_app_browser', - '../third_party/crashpad/crashpad/handler/handler.gyp:crashpad_handler', ], 'conditions': [ ['OS=="win"', { @@ -165,8 +163,6 @@ ], 'sources': [ 'app/chrome_dll.rc', - 'app/chrome_crash_reporter_client.cc', - 'app/chrome_crash_reporter_client.h', # ETW Manifest. '<(SHARED_INTERMEDIATE_DIR)/base/trace_event/etw_manifest/chrome_events_win.rc', @@ -304,6 +300,7 @@ 'dependencies': [ '../components/components.gyp:crash_component', '../components/components.gyp:policy', + '../third_party/crashpad/crashpad/handler/handler.gyp:crashpad_handler', ], 'sources': [ 'app/chrome_crash_reporter_client.cc', @@ -355,7 +352,6 @@ 'dependencies': [ '<@(chromium_child_dependencies)', '../components/components.gyp:browser_watcher_client', - '../components/components.gyp:crash_component', '../content/content.gyp:content_app_child', 'chrome_version_resources', 'policy_path_parser', @@ -365,8 +361,6 @@ ], 'sources': [ '<(SHARED_INTERMEDIATE_DIR)/chrome_version/chrome_dll_version.rc', - 'app/chrome_crash_reporter_client.cc', - 'app/chrome_crash_reporter_client.h', 'app/chrome_main.cc', 'app/chrome_main_delegate.cc', 'app/chrome_main_delegate.h',
diff --git a/chrome/chrome_exe.gypi b/chrome/chrome_exe.gypi index 45274699..9117c87e6 100644 --- a/chrome/chrome_exe.gypi +++ b/chrome/chrome_exe.gypi
@@ -71,10 +71,10 @@ 'app/chrome_watcher_client_win.h', 'app/chrome_watcher_command_line_win.cc', 'app/chrome_watcher_command_line_win.h', - 'app/main_dll_loader_win.cc', - 'app/main_dll_loader_win.h', 'app/kasko_client.cc', 'app/kasko_client.h', + 'app/main_dll_loader_win.cc', + 'app/main_dll_loader_win.h', 'app/signature_validator_win.cc', 'app/signature_validator_win.h', ], @@ -105,8 +105,13 @@ 'chrome_watcher', 'chrome_watcher_client', '../components/components.gyp:browser_watcher_client', + '../components/components.gyp:crash_component', '../third_party/crashpad/crashpad/handler/handler.gyp:crashpad_handler_lib', ], + 'sources': [ + 'app/chrome_crash_reporter_client.cc', + 'app/chrome_crash_reporter_client.h', + ], 'conditions': [ ['kasko==1', { 'dependencies': [
diff --git a/chrome/chrome_features.gyp b/chrome/chrome_features.gyp index 0d29f18..6ff5d76 100644 --- a/chrome/chrome_features.gyp +++ b/chrome/chrome_features.gyp
@@ -15,6 +15,7 @@ 'buildflag_header_path': 'chrome/common/features.h', 'buildflag_flags': [ 'ENABLE_GOOGLE_NOW=<(enable_google_now)', + 'ANDROID_JAVA_UI=<(android_java_ui)', ], }, },
diff --git a/chrome/chrome_features.gypi b/chrome/chrome_features.gypi index a4d8756..06488b1e 100644 --- a/chrome/chrome_features.gypi +++ b/chrome/chrome_features.gypi
@@ -10,6 +10,11 @@ 'variables': { # Conditional variables. 'conditions': [ + ['OS=="android"', { + 'android_java_ui%': 1, + }, { + 'android_java_ui': 0, + }], ['OS=="android" or OS=="ios"', { 'enable_google_now%': 0, }, { @@ -21,6 +26,7 @@ # Anything in the conditions needs to be copied to the outer scope to be # accessible. 'enable_google_now%': '<(enable_google_now)', + 'android_java_ui%': '<(android_java_ui)', # Grit defines based on the feature flags. These must be manually added to # grit targets.
diff --git a/chrome/chrome_tests_unit.gypi b/chrome/chrome_tests_unit.gypi index 6ab5482..f569558 100644 --- a/chrome/chrome_tests_unit.gypi +++ b/chrome/chrome_tests_unit.gypi
@@ -468,6 +468,7 @@ 'browser/ui/webui/browsing_history_handler_unittest.cc', 'browser/ui/webui/fileicon_source_unittest.cc', 'browser/ui/webui/log_web_ui_url_unittest.cc', + 'browser/ui/startup/startup_browser_creator_win_unittest.cc', 'browser/update_client/chrome_update_query_params_delegate_unittest.cc', 'common/chrome_content_client_unittest.cc', 'common/chrome_paths_unittest.cc', @@ -1591,6 +1592,7 @@ 'browser/ui/webui/options/language_options_handler_unittest.cc', 'browser/ui/webui/options/pepper_flash_content_settings_utils_unittest.cc', 'browser/ui/webui/options/sync_setup_handler_unittest.cc', + 'browser/ui/webui/settings/reset_settings_handler_unittest.cc', 'browser/ui/webui/settings/sync_handler_unittest.cc', 'browser/ui/webui/signin/login_ui_service_unittest.cc', 'browser/ui/webui/sync_internals_message_handler_unittest.cc', @@ -1646,6 +1648,10 @@ 'chrome_unit_tests_app_list_chromeos_sources': [ 'browser/ui/app_list/search/launcher_search/launcher_search_icon_image_loader_unittest.cc', ], + # ARC only sources of app_list. + 'chrome_unit_tests_app_list_chromeos_arc_sources': [ + 'browser/ui/app_list/arc/arc_app_unittest.cc', + ], # Sources for Offline pages. For now only for Android. 'chrome_unit_tests_offline_pages_sources': [ 'browser/android/offline_pages/offline_page_mhtml_archiver_unittest.cc', @@ -2069,6 +2075,7 @@ ], 'dependencies': [ '../components/components.gyp:crash_component', + '../third_party/crashpad/crashpad/handler/handler.gyp:crashpad_handler', '../win8/win8.gyp:test_registrar_constants', '../win8/win8.gyp:test_support_win8', ], @@ -2764,6 +2771,12 @@ ['enable_app_list==1 and chromeos==1', { 'sources': [ '<@(chrome_unit_tests_app_list_chromeos_sources)' ], }], + ['enable_app_list==1 and chromeos==1', { + 'sources': [ '<@(chrome_unit_tests_app_list_chromeos_arc_sources)' ], + 'dependencies': [ + '../components/components.gyp:arc_test_support', + ], + }], ['enable_plugin_installation==0', { 'sources!': [ 'browser/plugins/plugin_installer_unittest.cc',
diff --git a/chrome/common/BUILD.gn b/chrome/common/BUILD.gn index 863cedd..1912a22 100644 --- a/chrome/common/BUILD.gn +++ b/chrome/common/BUILD.gn
@@ -40,7 +40,10 @@ buildflag_header("features") { header = "features.h" - flags = [ "ENABLE_GOOGLE_NOW=$enable_google_now" ] + flags = [ + "ENABLE_GOOGLE_NOW=$enable_google_now", + "ANDROID_JAVA_UI=$android_java_ui", + ] } # GYP version: chrome/chrome_common.gypi:common
diff --git a/chrome/common/chrome_paths.cc b/chrome/common/chrome_paths.cc index 66c7bf2a..4c19077 100644 --- a/chrome/common/chrome_paths.cc +++ b/chrome/common/chrome_paths.cc
@@ -207,6 +207,8 @@ // directory. This avoids the problem of having to re-initialize the // exception handler after parsing command line options, which may // override the location of the app's profile directory. + // TODO(scottmg): Consider supporting --user-data-dir. See + // https://crbug.com/565446. if (!GetDefaultUserDataDirectory(&cur)) return false; #endif
diff --git a/chrome/common/chrome_switches.cc b/chrome/common/chrome_switches.cc index 9443ec0..f71178a 100644 --- a/chrome/common/chrome_switches.cc +++ b/chrome/common/chrome_switches.cc
@@ -520,6 +520,12 @@ const char kDisableSimplifiedFullscreenUI[] = "disable-simplified-fullscreen-ui"; +// Enable the Site Engagement App Banner which triggers app install banners +// using the site engagement service rather than a navigation-based heuristic. +// Implicitly enables the site engagement service. +const char kEnableSiteEngagementAppBanner[] = + "enable-site-engagement-app-banner"; + // Enable the Site Engagement Eviction Policy which evicts temporary storage // using the site engagement service. Implicitly enables the site engagement // service.
diff --git a/chrome/common/chrome_switches.h b/chrome/common/chrome_switches.h index 6a4e48f..67908f2 100644 --- a/chrome/common/chrome_switches.h +++ b/chrome/common/chrome_switches.h
@@ -150,6 +150,7 @@ extern const char kDisableSettingsWindow[]; extern const char kEnableSimplifiedFullscreenUI[]; extern const char kDisableSimplifiedFullscreenUI[]; +extern const char kEnableSiteEngagementAppBanner[]; extern const char kEnableSiteEngagementEvictionPolicy[]; extern const char kEnableSiteEngagementService[]; extern const char kEnableSupervisedUserManagedBookmarksFolder[];
diff --git a/chrome/common/extensions/api/extension_action/action_info.cc b/chrome/common/extensions/api/extension_action/action_info.cc index 8cf0386..a3be61b 100644 --- a/chrome/common/extensions/api/extension_action/action_info.cc +++ b/chrome/common/extensions/api/extension_action/action_info.cc
@@ -91,25 +91,17 @@ const base::DictionaryValue* icons_value = NULL; std::string default_icon; if (dict->GetDictionary(keys::kPageActionDefaultIcon, &icons_value)) { - int icon_sizes[extension_misc::kNumExtensionActionIconSizes]; - for (size_t i = 0u; i < extension_misc::kNumExtensionActionIconSizes; ++i) - icon_sizes[i] = extension_misc::kExtensionActionIconSizes[i].size; - if (!manifest_handler_helpers::LoadIconsFromDictionary( - icons_value, - icon_sizes, - extension_misc::kNumExtensionActionIconSizes, - &result->default_icon, - error)) { + if (!manifest_handler_helpers::LoadAllIconsFromDictionary( + icons_value, &result->default_icon, error)) { return scoped_ptr<ActionInfo>(); } } else if (dict->GetString(keys::kPageActionDefaultIcon, &default_icon) && manifest_handler_helpers::NormalizeAndValidatePath( &default_icon)) { - // Choose the most optimistic (highest) icon density - e.g. 38 not 19 - - // regardless of the actual icon resolution, whatever that happens to be. - // Code elsewhere knows how to scale 38 down to 19. - result->default_icon.Add(extension_misc::EXTENSION_ICON_ACTION * - extension_misc::kNumExtensionActionIconSizes, + // Choose the most optimistic (highest) icon density regardless of the + // actual icon resolution, whatever that happens to be. Code elsewhere + // knows how to scale down to 19. + result->default_icon.Add(extension_misc::EXTENSION_ICON_GIGANTOR, default_icon); } else { *error = base::ASCIIToUTF16(errors::kInvalidPageActionIconPath);
diff --git a/chrome/common/extensions/api/extension_action/browser_action_manifest_unittest.cc b/chrome/common/extensions/api/extension_action/browser_action_manifest_unittest.cc index 4693a94..539477b6 100644 --- a/chrome/common/extensions/api/extension_action/browser_action_manifest_unittest.cc +++ b/chrome/common/extensions/api/extension_action/browser_action_manifest_unittest.cc
@@ -4,6 +4,7 @@ #include "chrome/common/extensions/api/extension_action/action_info.h" #include "chrome/common/extensions/manifest_tests/chrome_manifest_test.h" +#include "extensions/common/constants.h" #include "extensions/common/error_utils.h" #include "extensions/common/extension_builder.h" #include "extensions/common/extension_icon_set.h" @@ -60,23 +61,27 @@ const ExtensionIconSet& icons = browser_action_info->default_icon; EXPECT_EQ(1u, icons.map().size()); - EXPECT_EQ("icon.png", icons.Get(38, ExtensionIconSet::MATCH_EXACTLY)); + EXPECT_EQ("icon.png", icons.Get(extension_misc::EXTENSION_ICON_GIGANTOR, + ExtensionIconSet::MATCH_EXACTLY)); } TEST_F(BrowserActionManifestTest, BrowserActionManifestIcons_DictDefaultIcon) { + // Arbitrary sizes should be allowed (useful for various scale factors). scoped_refptr<const Extension> extension = ExtensionBuilder() - .SetManifest(DictionaryBuilder() - .Set("name", "Dictionary default icon") - .Set("version", "1.0.0") - .Set("manifest_version", 2) - .Set("browser_action", DictionaryBuilder() - .Set("default_icon", DictionaryBuilder() - .Set("19", "icon19.png") - .Set("24", "icon24.png") // Should be ignored. - .Set("38", "icon38.png")))) - .Build(); + .SetManifest( + DictionaryBuilder() + .Set("name", "Dictionary default icon") + .Set("version", "1.0.0") + .Set("manifest_version", 2) + .Set("browser_action", + DictionaryBuilder().Set("default_icon", + DictionaryBuilder() + .Set("19", "icon19.png") + .Set("24", "icon24.png") + .Set("38", "icon38.png")))) + .Build(); ASSERT_TRUE(extension.get()); const ActionInfo* browser_action_info = @@ -86,9 +91,10 @@ const ExtensionIconSet& icons = browser_action_info->default_icon; - // 24px icon should be ignored. - EXPECT_EQ(2u, icons.map().size()); + // 24px icon should be included. + EXPECT_EQ(3u, icons.map().size()); EXPECT_EQ("icon19.png", icons.Get(19, ExtensionIconSet::MATCH_EXACTLY)); + EXPECT_EQ("icon24.png", icons.Get(24, ExtensionIconSet::MATCH_EXACTLY)); EXPECT_EQ("icon38.png", icons.Get(38, ExtensionIconSet::MATCH_EXACTLY)); }
diff --git a/chrome/common/extensions/docs/examples/api/desktopCapture/app.js b/chrome/common/extensions/docs/examples/api/desktopCapture/app.js index 6445baf..65823af 100644 --- a/chrome/common/extensions/docs/examples/api/desktopCapture/app.js +++ b/chrome/common/extensions/docs/examples/api/desktopCapture/app.js
@@ -2,50 +2,121 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -function gotStream(stream) { - console.log("Received local stream"); - var video = document.querySelector("video"); - video.src = URL.createObjectURL(stream); - localstream = stream; - stream.onended = function() { console.log("Ended"); }; -} +'use strict'; -function getUserMediaError() { - console.log("getUserMedia() failed."); -} - -function onAccessApproved(id) { - if (!id) { - console.log("Access rejected."); - return; - } - - navigator.webkitGetUserMedia({ - audio:false, - video: { - mandatory: { - chromeMediaSource: "desktop", - chromeMediaSourceId: id, - maxWidth:screen.width, - maxHeight:screen.height} } - }, gotStream, getUserMediaError); -} +const DESKTOP_MEDIA = ['screen', 'window']; var pending_request_id = null; +var pc1 = null; +var pc2 = null; -document.querySelector('#start').addEventListener('click', function(e) { +// Launch the chooseDesktopMedia(). +document.querySelector('#start').addEventListener('click', function(event) { pending_request_id = chrome.desktopCapture.chooseDesktopMedia( - ["screen", "window"], onAccessApproved); + DESKTOP_MEDIA, onAccessApproved); }); -document.querySelector('#cancel').addEventListener('click', function(e) { +document.querySelector('#cancel').addEventListener('click', function(event) { if (pending_request_id != null) { chrome.desktopCapture.cancelChooseDesktopMedia(pending_request_id); } }); document.querySelector('#startFromBackgroundPage') - .addEventListener('click', function(e) { + .addEventListener('click', function(event) { chrome.runtime.sendMessage( {}, function(response) { console.log(response.farewell); }); }); + +// Launch webkitGetUserMedia() based on selected media id. +function onAccessApproved(id) { + if (!id) { + console.log('Access rejected.'); + return; + } + + navigator.webkitGetUserMedia({ + audio:{ + mandatory: { + chromeMediaSource: 'desktop', + chromeMediaSourceId: id} }, + video: { + mandatory: { + chromeMediaSource: 'desktop', + chromeMediaSourceId: id, + maxWidth:screen.width, + maxHeight:screen.height} } + }, gotStream, getUserMediaError); +} + +function getUserMediaError(error) { + console.log('navigator.webkitGetUserMedia() errot: ', error); +} + +// Capture video/audio of media and initialize RTC communication. +function gotStream(stream) { + console.log('Received local stream', stream); + var video = document.querySelector('video'); + video.src = URL.createObjectURL(stream); + stream.onended = function() { console.log('Ended'); }; + + var servers = null; + pc1 = new webkitRTCPeerConnection(servers); + pc1.onicecandidate = function(event) { + onIceCandidate(pc1, event); + }; + pc2 = new webkitRTCPeerConnection(servers); + pc2.onicecandidate = function(event) { + onIceCandidate(pc2, event); + }; + pc1.oniceconnectionstatechange = function(event) { + onIceStateChange(pc1, event); + }; + pc2.oniceconnectionstatechange = function(event) { + onIceStateChange(pc2, event); + }; + pc2.onaddstream = gotRemoteStream; + + pc1.addStream(stream); + + pc1.createOffer(onCreateOfferSuccess); +} + +function onCreateOfferSuccess(desc) { + pc1.setLocalDescription(desc); + pc2.setRemoteDescription(desc); + // Since the 'remote' side has no media stream we need + // to pass in the right constraints in order for it to + // accept the incoming offer of audio and video. + var sdpConstraints = { + 'mandatory': { + 'OfferToReceiveAudio': true, + 'OfferToReceiveVideo': true + } + }; + pc2.createAnswer(onCreateAnswerSuccess, function(){}, sdpConstraints); +} + +function gotRemoteStream(event) { + // Call the polyfill wrapper to attach the media stream to this element. + console.log('hitting this code'); + remoteVideo.src = URL.createObjectURL(event.stream); +} + +function onCreateAnswerSuccess(desc) { + pc2.setLocalDescription(desc); + pc1.setRemoteDescription(desc); +} + +function onIceCandidate(pc, event) { + if (event.candidate) { + var remotePC = (pc === pc1) ? pc2 : pc1; + remotePC.addIceCandidate(new RTCIceCandidate(event.candidate)); + } +} + +function onIceStateChange(pc, event) { + if (pc) { + console.log('ICE state change event: ', event); + } +}
diff --git a/chrome/common/extensions/docs/examples/api/desktopCapture/background.js b/chrome/common/extensions/docs/examples/api/desktopCapture/background.js index c1574a53..332b4515 100644 --- a/chrome/common/extensions/docs/examples/api/desktopCapture/background.js +++ b/chrome/common/extensions/docs/examples/api/desktopCapture/background.js
@@ -5,8 +5,8 @@ chrome.app.runtime.onLaunched.addListener(function() { chrome.app.window.create('index.html', { bounds: { - width: 700, - height: 600 + width: 1080, + height: 420 } }); });
diff --git a/chrome/common/extensions/docs/examples/api/desktopCapture/index.html b/chrome/common/extensions/docs/examples/api/desktopCapture/index.html index f8db183..fca9053 100644 --- a/chrome/common/extensions/docs/examples/api/desktopCapture/index.html +++ b/chrome/common/extensions/docs/examples/api/desktopCapture/index.html
@@ -9,15 +9,18 @@ -webkit-flex-direction: column; } video { - width: 640px; - height: 480px; + width: 480px; + height: 360px; border: 1px solid #e2e2e2; box-shadow: 0 1px 1px rgba(0,0,0,0.2); } </style> </head> <body> - <video id="video" autoplay></video> + <div> + <video id="video" autoplay></video> + <video id="remoteVideo" autoplay></video> + </div> <p> <button id="start">Start</button> <button id="cancel">Cancel</button>
diff --git a/chrome/common/features.gni b/chrome/common/features.gni index 2e92745c..3188c6c 100644 --- a/chrome/common/features.gni +++ b/chrome/common/features.gni
@@ -7,6 +7,12 @@ declare_args() { enable_google_now = !is_ios && !is_android + + # Whether the Java UI is being used (Java infobars and popups, Java native + # settings and first run experience, sign-in etc.). + # Default to true if compiling for android, but allow this being overriden + # through the environment. + android_java_ui = is_android } chrome_grit_defines = [ "enable_google_now=$enable_google_now" ]
diff --git a/chrome/common/localized_error.cc b/chrome/common/localized_error.cc index 4ce95ed..e36cfe1e 100644 --- a/chrome/common/localized_error.cc +++ b/chrome/common/localized_error.cc
@@ -25,7 +25,6 @@ #include "components/url_formatter/url_formatter.h" #include "net/base/escape.h" #include "net/base/net_errors.h" -#include "third_party/WebKit/public/platform/WebURLError.h" #include "ui/base/l10n/l10n_util.h" #include "ui/base/webui/web_ui_util.h" @@ -33,7 +32,6 @@ #include "base/win/windows_version.h" #endif -using blink::WebURLError; using error_page::OfflinePageStatus; // Some error pages have no details. @@ -774,7 +772,6 @@ base::string16 button_text = l10n_util::GetStringUTF16(IDS_ERRORPAGES_BUTTON_SHOW_OFFLINE_COPY); show_offline_copy_button->SetString("msg", button_text); - show_offline_copy_button->SetString("title", button_text); error_strings->Set("showOfflineCopyButton", show_offline_copy_button); } else if (offline_page_status == OfflinePageStatus::HAS_OTHER_OFFLINE_PAGES) { @@ -783,7 +780,6 @@ base::string16 button_text = l10n_util::GetStringUTF16(IDS_ERRORPAGES_BUTTON_SHOW_OFFLINE_PAGES); show_offline_pages_button->SetString("msg", button_text); - show_offline_pages_button->SetString("title", button_text); error_strings->Set("showOfflinePagesButton", show_offline_pages_button); } } @@ -925,10 +921,11 @@ } } -base::string16 LocalizedError::GetErrorDetails(const blink::WebURLError& error, +base::string16 LocalizedError::GetErrorDetails(const std::string& error_domain, + int error_code, bool is_post) { const LocalizedErrorMap* error_map = - LookupErrorMap(error.domain.utf8(), error.reason, is_post); + LookupErrorMap(error_domain, error_code, is_post); if (error_map) return l10n_util::GetStringUTF16(error_map->details_resource_id); else
diff --git a/chrome/common/localized_error.h b/chrome/common/localized_error.h index ed7ceb5..ed6009f 100644 --- a/chrome/common/localized_error.h +++ b/chrome/common/localized_error.h
@@ -17,10 +17,6 @@ class DictionaryValue; } -namespace blink { -struct WebURLError; -} - namespace error_page { struct ErrorPageParams; } @@ -42,7 +38,8 @@ base::DictionaryValue* strings); // Returns a description of the encountered error. - static base::string16 GetErrorDetails(const blink::WebURLError& error, + static base::string16 GetErrorDetails(const std::string& error_domain, + int error_code, bool is_post); // Returns true if an error page exists for the specified parameters.
diff --git a/chrome/common/pref_names.cc b/chrome/common/pref_names.cc index 79f0662..dd363714 100644 --- a/chrome/common/pref_names.cc +++ b/chrome/common/pref_names.cc
@@ -5,7 +5,6 @@ #include "chrome/common/pref_names.h" #include "base/basictypes.h" -#include "chrome/common/features.h" #include "chrome/common/pref_font_webkit_names.h" namespace prefs { @@ -13,6 +12,10 @@ // *************** PROFILE PREFS *************** // These are attached to the user profile +#if defined(OS_CHROMEOS) && defined(ENABLE_APP_LIST) +// A preference to keep list of ARC apps and its state. +const char kArcApps[] = "arc.apps"; +#endif // A bool pref that keeps whether the child status for this profile was already // successfully checked via ChildAccountService. @@ -367,7 +370,7 @@ // Boolean that is true when Suggest support is enabled. const char kSearchSuggestEnabled[] = "search.suggest_enabled"; -#if defined(OS_ANDROID) +#if BUILDFLAG(ANDROID_JAVA_UI) // String indicating the Contextual Search enabled state. // "false" - opt-out (disabled) // "" (empty string) - undecided @@ -991,7 +994,7 @@ const char kAutofillGeneratedCardBubbleTimesShown[] = "autofill.generated_card_bubble_times_shown"; -#if defined(OS_ANDROID) +#if BUILDFLAG(ANDROID_JAVA_UI) // A dictionary that tracks the defaults to be set on the next invocation // of the requestAutocomplete dialog. const char kAutofillDialogDefaults[] = "autofill.rac_dialog_defaults"; @@ -1256,7 +1259,7 @@ const char kStabilitySystemUncleanShutdownCount[] = "user_experience_metrics.stability.system_unclean_shutdowns"; -#if defined(OS_ANDROID) +#if BUILDFLAG(ANDROID_JAVA_UI) // Activity type that is currently in the foreground for the UMA session. // Uses the ActivityTypeIds::Type enum. const char kStabilityForegroundActivityType[] = @@ -1416,7 +1419,7 @@ // Customized app page names that appear on the New Tab Page. const char kNtpAppPageNames[] = "ntp.app_page_names"; -#if defined(OS_ANDROID) +#if BUILDFLAG(ANDROID_JAVA_UI) // Keeps track of currently open tabs collapsed state in the Other Devices menu. const char kNtpCollapsedCurrentlyOpenTabs[] = "ntp.collapsed_open_tabs"; #endif @@ -1424,7 +1427,7 @@ // Keeps track of which sessions are collapsed in the Other Devices menu. const char kNtpCollapsedForeignSessions[] = "ntp.collapsed_foreign_sessions"; -#if defined(OS_ANDROID) +#if BUILDFLAG(ANDROID_JAVA_UI) // Keeps track of recently closed tabs collapsed state in the Other Devices // menu. const char kNtpCollapsedRecentlyClosedTabs[] = @@ -1440,7 +1443,7 @@ // Which page should be visible on the new tab page v4 const char kNtpShownPage[] = "ntp.shown_page"; -#if defined(OS_ANDROID) +#if BUILDFLAG(ANDROID_JAVA_UI) // Ordered list of website suggestions shown on the new tab page that will allow // retaining the order even if the suggestions change over time. const char kNTPSuggestionsURL[] = "ntp.suggestions_url"; @@ -1542,7 +1545,7 @@ // corresponding access token. const char kGeolocationAccessToken[] = "geolocation.access_token"; -#if defined(OS_ANDROID) +#if BUILDFLAG(ANDROID_JAVA_UI) // Boolean that controls the enabled-state of Geolocation in content. const char kGeolocationEnabled[] = "geolocation.enabled"; #endif @@ -2113,7 +2116,7 @@ const char kWatchdogExtensionActive[] = "profile.extensions.activity_log.num_consumers_active"; -#if defined(OS_ANDROID) +#if BUILDFLAG(ANDROID_JAVA_UI) // A list of partner bookmark rename/remove mappings. // Each list item is a dictionary containing a "url", a "provider_title" and // "mapped_title" entries, detailing the bookmark target URL (if any), the title
diff --git a/chrome/common/pref_names.h b/chrome/common/pref_names.h index 7563ff6..1ead3de 100644 --- a/chrome/common/pref_names.h +++ b/chrome/common/pref_names.h
@@ -15,6 +15,9 @@ namespace prefs { // Profile prefs. Please add Local State prefs below instead. +#if defined(OS_CHROMEOS) && defined(ENABLE_APP_LIST) +extern const char kArcApps[]; +#endif extern const char kChildAccountStatusKnown[]; extern const char kDefaultApps[]; extern const char kDisableScreenshots[]; @@ -146,7 +149,7 @@ extern const char kSSLErrorOverrideAllowed[]; extern const char kIncognitoModeAvailability[]; extern const char kSearchSuggestEnabled[]; -#if defined(OS_ANDROID) +#if BUILDFLAG(ANDROID_JAVA_UI) extern const char kContextualSearchEnabled[]; #endif #if defined(OS_MACOSX) @@ -332,7 +335,7 @@ extern const char kAutofillDialogSaveData[]; extern const char kAutofillDialogWalletShippingSameAsBilling[]; extern const char kAutofillGeneratedCardBubbleTimesShown[]; -#if defined(OS_ANDROID) +#if BUILDFLAG(ANDROID_JAVA_UI) extern const char kAutofillDialogDefaults[]; #endif @@ -415,7 +418,7 @@ // Android has it's own metric / crash reporting implemented in Android // Java code so kMetricsReportingEnabled doesn't make sense. We use this // to inform crashes_ui that we have enabled crash reporting. -#if defined(OS_ANDROID) +#if BUILDFLAG(ANDROID_JAVA_UI) extern const char kCrashReportingEnabled[]; #endif @@ -430,7 +433,7 @@ extern const char kStabilityOtherUserCrashCount[]; extern const char kStabilityKernelCrashCount[]; extern const char kStabilitySystemUncleanShutdownCount[]; -#if defined(OS_ANDROID) +#if BUILDFLAG(ANDROID_JAVA_UI) extern const char kStabilityForegroundActivityType[]; extern const char kStabilityLaunchedActivityFlags[]; extern const char kStabilityLaunchedActivityCounts[]; @@ -500,17 +503,17 @@ extern const char kDisablePluginFinder[]; extern const char kNtpAppPageNames[]; -#if defined(OS_ANDROID) +#if BUILDFLAG(ANDROID_JAVA_UI) extern const char kNtpCollapsedCurrentlyOpenTabs[]; #endif extern const char kNtpCollapsedForeignSessions[]; -#if defined(OS_ANDROID) +#if BUILDFLAG(ANDROID_JAVA_UI) extern const char kNtpCollapsedRecentlyClosedTabs[]; extern const char kNtpCollapsedSnapshotDocument[]; extern const char kNtpCollapsedSyncPromo[]; #endif extern const char kNtpShownPage[]; -#if defined(OS_ANDROID) +#if BUILDFLAG(ANDROID_JAVA_UI) extern const char kNTPSuggestionsURL[]; extern const char kNTPSuggestionsIsPersonal[]; #endif @@ -551,7 +554,7 @@ extern const char kWebAppCreateInQuickLaunchBar[]; extern const char kGeolocationAccessToken[]; -#if defined(OS_ANDROID) +#if BUILDFLAG(ANDROID_JAVA_UI) extern const char kGeolocationEnabled[]; #endif @@ -766,7 +769,7 @@ extern const char kWatchdogExtensionActive[]; -#if defined(OS_ANDROID) +#if BUILDFLAG(ANDROID_JAVA_UI) extern const char kPartnerBookmarkMappings[]; #endif
diff --git a/chrome/common/url_constants.cc b/chrome/common/url_constants.cc index 70a108201..99a662e 100644 --- a/chrome/common/url_constants.cc +++ b/chrome/common/url_constants.cc
@@ -7,6 +7,7 @@ #include <algorithm> #include "base/basictypes.h" +#include "chrome/common/features.h" #include "content/public/common/url_constants.h" #include "url/url_util.h" @@ -87,7 +88,7 @@ const char kChromeUIUserActionsURL[] = "chrome://user-actions/"; const char kChromeUIVersionURL[] = "chrome://version/"; -#if defined(OS_ANDROID) +#if BUILDFLAG(ANDROID_JAVA_UI) const char kChromeUIContextualSearchPromoURL[] = "chrome://contextual-search-promo"; const char kChromeUINativeScheme[] = "chrome-native";
diff --git a/chrome/common/url_constants.h b/chrome/common/url_constants.h index 724b8c5f..7f471c8 100644 --- a/chrome/common/url_constants.h +++ b/chrome/common/url_constants.h
@@ -11,6 +11,7 @@ #include <vector> #include "build/build_config.h" +#include "chrome/common/features.h" #include "content/public/common/url_constants.h" namespace chrome { @@ -83,7 +84,7 @@ extern const char kChromeUIUserActionsURL[]; extern const char kChromeUIVersionURL[]; -#if defined(OS_ANDROID) +#if BUILDFLAG(ANDROID_JAVA_UI) extern const char kChromeUIContextualSearchPromoURL[]; extern const char kChromeUINativeScheme[]; extern const char kChromeUINativeNewTabURL[];
diff --git a/chrome/ct_dm.isolate b/chrome/ct_dm.isolate index 0a8c726..ee573c4 100644 --- a/chrome/ct_dm.isolate +++ b/chrome/ct_dm.isolate
@@ -10,7 +10,7 @@ '../../skia/resources/', '../../skia/out/Debug/dm', '../content/test/ct/run_ct_dm.py', - '../content/test/ct/slave<(SLAVE_NUM)/skps/', + '../../skps/slave<(SLAVE_NUM)/', ], 'command': [ 'python',
diff --git a/chrome/installer/mac/sign_versioned_dir.sh.in b/chrome/installer/mac/sign_versioned_dir.sh.in index f68b7aa..c47cb954 100644 --- a/chrome/installer/mac/sign_versioned_dir.sh.in +++ b/chrome/installer/mac/sign_versioned_dir.sh.in
@@ -43,6 +43,8 @@ framework="${versioned_dir}/@MAC_PRODUCT_NAME@ Framework.framework" crashpad_handler="${framework}/Helpers/crashpad_handler" helper_app="${versioned_dir}/@MAC_PRODUCT_NAME@ Helper.app" +app_mode_loader_app="${framework}/Resources/app_mode_loader.app" +app_mode_loader="${app_mode_loader_app}/Contents/MacOS/app_mode_loader" requirement_suffix="\ and certificate leaf = H\"85cee8254216185620ddc8851c7a9fc4dfe120ef\"\ @@ -54,17 +56,38 @@ "${crashpad_handler}" \ -r="designated => identifier \"crashpad_handler\" \ ${requirement_suffix}" --options "${enforcement_flags}" + +# The app mode loader bundle is modified dynamically at runtime. Just sign the +# executable, which shouldn't change. In order to do this, the executable needs +# to be copied out of the bundle, signed, and then copied back in. The resulting +# bundle's signature won't validate normally, but if the executable file is +# verified in isolation or with --ignore-resources, it will. Because the +# bundle's signature won't validate on its own, don't set any of the enforcement +# flags. +app_mode_loader_tmp="$(mktemp -t app_mode_loader)" +cp "${app_mode_loader}" "${app_mode_loader_tmp}" +codesign --sign "${codesign_id}" --keychain "${codesign_keychain}" \ + "${app_mode_loader_tmp}" \ + -r="designated => identifier \"app_mode_loader\" \ +${requirement_suffix}" +cp "${app_mode_loader_tmp}" "${app_mode_loader}" +rm -f "${app_mode_loader_tmp}" + codesign --sign "${codesign_id}" --keychain "${codesign_keychain}" \ "${framework}" \ -r="designated => identifier \"com.google.Chrome.framework\" \ ${requirement_suffix}" + codesign --sign "${codesign_id}" --keychain "${codesign_keychain}" \ "${helper_app}" \ -r="designated => identifier \"com.google.Chrome.helper\" \ ${requirement_suffix}" --options "${enforcement_flags}" # Verify everything. Don't use --deep on the framework because Keystone's -# signature is in a transitional state (radar 18474911). +# signature is in a transitional state (radar 18474911). Don't verify +# app_mode_loader independently because --ignore-resources is unrecognized +# before 10.11 (bug 565859). codesign --verify --deep "${crashpad_handler}" +# codesign --verify --ignore-resources "${app_mode_loader}" codesign --verify "${framework}" codesign --verify --deep "${helper_app}"
diff --git a/chrome/installer/util/l10n_string_util.cc b/chrome/installer/util/l10n_string_util.cc index 96f2ce7..5d93814 100644 --- a/chrome/installer/util/l10n_string_util.cc +++ b/chrome/installer/util/l10n_string_util.cc
@@ -7,8 +7,10 @@ #include "chrome/installer/util/l10n_string_util.h" #include <atlbase.h> +#include <stdint.h> #include <algorithm> +#include <limits> #include "base/logging.h" #include "base/memory/scoped_ptr.h" @@ -89,7 +91,7 @@ // The cast is safe because url_path has limited length // (see the definition of full_exe_path and resource). - DCHECK(kuint32max > (url_path.size() * 3)); + DCHECK(std::numeric_limits<uint32_t>::max() > (url_path.size() * 3)); DWORD count = static_cast<DWORD>(url_path.size() * 3); scoped_ptr<wchar_t[]> url_canon(new wchar_t[count]); HRESULT hr = ::UrlCanonicalizeW(url_path.c_str(), url_canon.get(),
diff --git a/chrome/renderer/autofill/form_autofill_browsertest.cc b/chrome/renderer/autofill/form_autofill_browsertest.cc index bc7a762..6e876015 100644 --- a/chrome/renderer/autofill/form_autofill_browsertest.cc +++ b/chrome/renderer/autofill/form_autofill_browsertest.cc
@@ -2068,6 +2068,67 @@ &field)); } +// Tests that the |should_autocomplete| is set to false for all the fields when +// an autocomplete='off' attribute is set for the form in HTML. +TEST_F(FormAutofillTest, WebFormElementToFormData_AutocompleteOff_OnForm) { + LoadHTML( + "<FORM name='TestForm' id='form' action='http://cnn.com' method='post' " + "autocomplete='off'>" + " <LABEL for='firstname'>First name:</LABEL>" + " <INPUT type='text' id='firstname' value='John'/>" + " <LABEL for='lastname'>Last name:</LABEL>" + " <INPUT type='text' id='lastname' value='Smith'/>" + " <LABEL for='street-address'>Address:</LABEL>" + " <INPUT type='text' id='addressline1' value='123 Test st.'/>" + "</FORM>"); + + WebFrame* frame = GetMainFrame(); + ASSERT_NE(nullptr, frame); + + WebFormElement web_form = + frame->document().getElementById("form").to<WebFormElement>(); + ASSERT_FALSE(web_form.isNull()); + + FormData form; + EXPECT_TRUE(WebFormElementToFormData(web_form, WebFormControlElement(), + EXTRACT_NONE, &form, nullptr)); + + for (const FormFieldData& field : form.fields) { + EXPECT_FALSE(field.should_autocomplete); + } +} + +// Tests that the |should_autocomplete| is set to false only for the field +// which has an autocomplete='off' attribute set for it in HTML. +TEST_F(FormAutofillTest, WebFormElementToFormData_AutocompleteOff_OnField) { + LoadHTML( + "<FORM name='TestForm' id='form' action='http://cnn.com' method='post'>" + " <LABEL for='firstname'>First name:</LABEL>" + " <INPUT type='text' id='firstname' value='John' autocomplete='off'/>" + " <LABEL for='lastname'>Last name:</LABEL>" + " <INPUT type='text' id='lastname' value='Smith'/>" + " <LABEL for='street-address'>Address:</LABEL>" + " <INPUT type='text' id='addressline1' value='123 Test st.'/>" + "</FORM>"); + + WebFrame* frame = GetMainFrame(); + ASSERT_NE(nullptr, frame); + + WebFormElement web_form = + frame->document().getElementById("form").to<WebFormElement>(); + ASSERT_FALSE(web_form.isNull()); + + FormData form; + EXPECT_TRUE(WebFormElementToFormData(web_form, WebFormControlElement(), + EXTRACT_NONE, &form, nullptr)); + + ASSERT_EQ(3U, form.fields.size()); + + EXPECT_FALSE(form.fields[0].should_autocomplete); + EXPECT_TRUE(form.fields[1].should_autocomplete); + EXPECT_TRUE(form.fields[2].should_autocomplete); +} + TEST_F(FormAutofillTest, ExtractForms) { ExpectJohnSmithLabels( "<FORM name='TestForm' action='http://cnn.com' method='post'>"
diff --git a/chrome/renderer/chrome_content_renderer_client.cc b/chrome/renderer/chrome_content_renderer_client.cc index 0db8e41..65f743f 100644 --- a/chrome/renderer/chrome_content_renderer_client.cc +++ b/chrome/renderer/chrome_content_renderer_client.cc
@@ -1122,7 +1122,8 @@ } if (error_description) - *error_description = LocalizedError::GetErrorDetails(error, is_post); + *error_description = LocalizedError::GetErrorDetails(error.domain.utf8(), + error.reason, is_post); } bool ChromeContentRendererClient::RunIdleHandlerWhenWidgetsHidden() {
diff --git a/chrome/renderer/chrome_render_process_observer.cc b/chrome/renderer/chrome_render_process_observer.cc index 543032b..72c985b 100644 --- a/chrome/renderer/chrome_render_process_observer.cc +++ b/chrome/renderer/chrome_render_process_observer.cc
@@ -318,7 +318,8 @@ base::FieldTrial* trial = base::FieldTrialList::CreateFieldTrial(field_trial_name, group_name); // TODO(mef): Remove this check after the investigation of 359406 is complete. - CHECK(trial) << field_trial_name << ":" << group_name; + CHECK(trial) << field_trial_name << ":" << group_name << "=>" + << base::FieldTrialList::FindFullName(field_trial_name); // Ensure the trial is marked as "used" by calling group() on it if it is // marked as activated. trial->group();
diff --git a/chrome/renderer/resources/neterror.html b/chrome/renderer/resources/neterror.html index f1fba59..f3807438 100644 --- a/chrome/renderer/resources/neterror.html +++ b/chrome/renderer/resources/neterror.html
@@ -41,13 +41,13 @@ class="gray-button text-button" onclick="showOfflinePagesButtonClick()" jsselect="showOfflinePagesButton" - jscontent="msg" jsvalues="title:title"> + jscontent="msg"> </button> <button id="show-offline-copy-button" class="blue-button text-button" onclick="showOfflineCopyButtonClick()" jsselect="showOfflineCopyButton" - jscontent="msg" jsvalues="title:title; .primary:primary"> + jscontent="msg" jsvalues=".primary:primary"> </button> </div> <button id="details-button" class="text-button small-link"
diff --git a/chrome/sync_integration_tests.isolate b/chrome/sync_integration_tests.isolate index 295da53..4bb4ad6 100644 --- a/chrome/sync_integration_tests.isolate +++ b/chrome/sync_integration_tests.isolate
@@ -76,6 +76,7 @@ 'variables': { 'files': [ '<(PRODUCT_DIR)/chrome_elf.dll', + '<(PRODUCT_DIR)/crashpad_handler.exe', ], }, }],
diff --git a/chrome/telemetry_unittests.isolate b/chrome/telemetry_unittests.isolate index fb8c401..14b5d8a 100644 --- a/chrome/telemetry_unittests.isolate +++ b/chrome/telemetry_unittests.isolate
@@ -15,10 +15,6 @@ '../testing/scripts/common.py', '../testing/scripts/run_telemetry_as_googletest.py', ], - } - }], - ['OS=="mac"', { - 'variables': { 'command': [ '../testing/scripts/run_telemetry_as_googletest.py', '../tools/telemetry/run_tests', @@ -28,20 +24,5 @@ ], }, }], - ['OS=="win"', { - 'variables': { - 'command': [ - '../testing/scripts/run_telemetry_as_googletest.py', - '../tools/telemetry/run_tests', - '-v', - '--chrome-root', - '..', - # crbug.com/559154 - # TODO(nednguyen): Remove --jobs=1 once the bug is fixed to speed up - # the test run. - '--job=1', - ], - }, - }], ] }
diff --git a/chrome/test/BUILD.gn b/chrome/test/BUILD.gn index 32a0caaa..3670d55 100644 --- a/chrome/test/BUILD.gn +++ b/chrome/test/BUILD.gn
@@ -197,7 +197,11 @@ ] } if (is_win) { - public_deps += [ "//third_party/wtl" ] + sources += [ "//chrome/app/chrome_crash_reporter_client.cc" ] + public_deps += [ + "//components/crash/content/app", + "//third_party/wtl", + ] if (use_aura) { public_deps += [ "//win8:test_registrar_constants", @@ -1667,12 +1671,14 @@ [ "../browser/download/download_request_infobar_delegate_unittest.cc" ] } - if (!is_android && !is_ios) { + if (!is_ios) { deps += [ ":unit_tests_js" ] - sources += rebase_path( - chrome_tests_unit_gypi_values.chrome_unit_tests_non_mobile_sources, - ".", - "//chrome") + if (!is_android) { + sources += rebase_path( + chrome_tests_unit_gypi_values.chrome_unit_tests_non_mobile_sources, + ".", + "//chrome") + } } if (is_ios || is_chromeos) { @@ -2110,6 +2116,11 @@ chrome_tests_unit_gypi_values.chrome_unit_tests_app_list_chromeos_sources, ".", "//chrome") + sources += rebase_path( + chrome_tests_unit_gypi_values.chrome_unit_tests_app_list_chromeos_arc_sources, + ".", + "//chrome") + deps += [ "//components/arc:arc_test_support" ] } if (enable_plugins && !enable_plugin_installation) { sources -= [ "../browser/plugins/plugin_installer_unittest.cc" ]
diff --git a/chrome/test/android/javatests/src/org/chromium/chrome/test/ChromeActivityTestCaseBase.java b/chrome/test/android/javatests/src/org/chromium/chrome/test/ChromeActivityTestCaseBase.java index 11ef462..006b0d5 100644 --- a/chrome/test/android/javatests/src/org/chromium/chrome/test/ChromeActivityTestCaseBase.java +++ b/chrome/test/android/javatests/src/org/chromium/chrome/test/ChromeActivityTestCaseBase.java
@@ -17,8 +17,6 @@ import android.view.View; import android.widget.ListView; -import junit.framework.Assert; - import org.chromium.base.PerfTraceEvent; import org.chromium.base.ThreadUtils; import org.chromium.base.annotations.SuppressFBWarnings; @@ -464,33 +462,26 @@ startActivityCompletely(intent); - assertTrue("Tab never selected/initialized.", - CriteriaHelper.pollForUIThreadCriteria(new Criteria() { - @Override - public boolean isSatisfied() { - return getActivity().getActivityTab() != null; - } - })); + CriteriaHelper.pollForUIThreadCriteria(new Criteria("Tab never selected/initialized.") { + @Override + public boolean isSatisfied() { + return getActivity().getActivityTab() != null; + } + }); Tab tab = getActivity().getActivityTab(); ChromeTabUtils.waitForTabPageLoaded(tab, (String) null); if (!isDocumentMode && tab != null && NewTabPage.isNTPUrl(tab.getUrl())) { - boolean ntpReady = NewTabPageTestUtils.waitForNtpLoaded(tab); - if (!ntpReady && tab.isShowingSadTab()) { - fail("Renderer crashed before NTP finished loading. " - + "Look at logcat for renderer stack dump."); - } - assertTrue("Initial NTP never fully loaded.", ntpReady); + NewTabPageTestUtils.waitForNtpLoaded(tab); } - assertTrue("Deferred startup never completed", - CriteriaHelper.pollForUIThreadCriteria(new Criteria() { - @Override - public boolean isSatisfied() { - return DeferredStartupHandler.getInstance().isDeferredStartupComplete(); - } - })); + CriteriaHelper.pollForUIThreadCriteria(new Criteria("Deferred startup never completed") { + @Override + public boolean isSatisfied() { + return DeferredStartupHandler.getInstance().isDeferredStartupComplete(); + } + }); assertNotNull(tab); assertNotNull(tab.getView()); @@ -588,8 +579,7 @@ } ChromeTabUtils.waitForTabPageLoaded(tab, (String) null); - Assert.assertTrue("NTP never fully loaded.", - NewTabPageTestUtils.waitForNtpLoaded(tab)); + NewTabPageTestUtils.waitForNtpLoaded(tab); getInstrumentation().waitForIdleSync(); Log.d(TAG, "newIncognitoTabFromMenu <<"); } @@ -702,13 +692,13 @@ } // Wait for suggestions to show up. - assertTrue(CriteriaHelper.pollForCriteria(new Criteria() { + CriteriaHelper.pollForCriteria(new Criteria() { @Override public boolean isSatisfied() { return ((LocationBarLayout) getActivity().findViewById( R.id.location_bar)).getSuggestionList() != null; } - }, 3000, 10)); + }, 3000, 10); final ListView suggestionListView = locationBar.getSuggestionList(); OmniboxResultItem popupItem = (OmniboxResultItem) suggestionListView .getItemAtPosition(0);
diff --git a/chrome/test/android/javatests/src/org/chromium/chrome/test/MultiActivityTestBase.java b/chrome/test/android/javatests/src/org/chromium/chrome/test/MultiActivityTestBase.java index ab5b3db..d71c9d8 100644 --- a/chrome/test/android/javatests/src/org/chromium/chrome/test/MultiActivityTestBase.java +++ b/chrome/test/android/javatests/src/org/chromium/chrome/test/MultiActivityTestBase.java
@@ -174,14 +174,14 @@ final Tab tab = activity.getActivityTab(); assert tab != null; - assertTrue(CriteriaHelper.pollForUIThreadCriteria(new Criteria() { + CriteriaHelper.pollForUIThreadCriteria(new Criteria() { @Override public boolean isSatisfied() { if (!tab.isLoadingAndRenderingDone()) return false; if (!TextUtils.equals(expectedTitle, tab.getTitle())) return false; return true; } - })); + }); } /**
diff --git a/chrome/test/android/javatests/src/org/chromium/chrome/test/util/ActivityUtils.java b/chrome/test/android/javatests/src/org/chromium/chrome/test/util/ActivityUtils.java index 825b1df..19eab5d 100644 --- a/chrome/test/android/javatests/src/org/chromium/chrome/test/util/ActivityUtils.java +++ b/chrome/test/android/javatests/src/org/chromium/chrome/test/util/ActivityUtils.java
@@ -26,12 +26,13 @@ /** * Waits for a particular fragment to be present on a given activity. */ - private static class FragmentPresentCriteria implements Criteria { + private static class FragmentPresentCriteria extends Criteria { private final Activity mActivity; private final String mFragmentTag; public FragmentPresentCriteria(Activity activity, String fragmentTag) { + super(String.format("Could not locate the fragment with tag '%s'", fragmentTag)); mActivity = activity; mFragmentTag = fragmentTag; } @@ -96,9 +97,8 @@ @SuppressWarnings({"unchecked", "TypeParameterUnusedInFormals"}) public static <T> T waitForFragment(Activity activity, String fragmentTag) throws InterruptedException { - Assert.assertTrue(String.format("Could not locate the fragment with tag '%s'", fragmentTag), - CriteriaHelper.pollForCriteria(new FragmentPresentCriteria(activity, fragmentTag), - ACTIVITY_START_TIMEOUT_MS, CONDITION_POLL_INTERVAL_MS)); + CriteriaHelper.pollForCriteria(new FragmentPresentCriteria(activity, fragmentTag), + ACTIVITY_START_TIMEOUT_MS, CONDITION_POLL_INTERVAL_MS); return (T) activity.getFragmentManager().findFragmentByTag(fragmentTag); } @@ -117,15 +117,12 @@ public static <T extends Fragment> T waitForFragmentToAttach( final Preferences activity, final Class<T> fragmentClass) throws InterruptedException { - boolean isFragmentAttached = CriteriaHelper.pollForCriteria( - new Criteria() { - @Override - public boolean isSatisfied() { - return fragmentClass.isInstance(activity.getFragmentForTest()); - } - }, - ACTIVITY_START_TIMEOUT_MS, CONDITION_POLL_INTERVAL_MS); - Assert.assertTrue("Could not find fragment " + fragmentClass, isFragmentAttached); + CriteriaHelper.pollForCriteria(new Criteria("Could not find fragment " + fragmentClass) { + @Override + public boolean isSatisfied() { + return fragmentClass.isInstance(activity.getFragmentForTest()); + } + }, ACTIVITY_START_TIMEOUT_MS, CONDITION_POLL_INTERVAL_MS); return (T) activity.getFragmentForTest(); } }
diff --git a/chrome/test/android/javatests/src/org/chromium/chrome/test/util/ApplicationData.java b/chrome/test/android/javatests/src/org/chromium/chrome/test/util/ApplicationData.java index d834291..2bbcb56 100644 --- a/chrome/test/android/javatests/src/org/chromium/chrome/test/util/ApplicationData.java +++ b/chrome/test/android/javatests/src/org/chromium/chrome/test/util/ApplicationData.java
@@ -36,12 +36,10 @@ * When this is invoked from tests, the target context from the instrumentation must be used. * * @param targetContext the target Context. - * - * @return Whether clearing the application data was successful. */ - public static boolean clearAppData(Context targetContext) throws InterruptedException { + public static void clearAppData(Context targetContext) throws InterruptedException { final String appDir = getAppDirFromTargetContext(targetContext); - return CriteriaHelper.pollForCriteria( + CriteriaHelper.pollForCriteria( new Criteria() { private boolean mDataRemoved = false;
diff --git a/chrome/test/android/javatests/src/org/chromium/chrome/test/util/ApplicationTestUtils.java b/chrome/test/android/javatests/src/org/chromium/chrome/test/util/ApplicationTestUtils.java index e3d2288..6ad36689 100644 --- a/chrome/test/android/javatests/src/org/chromium/chrome/test/util/ApplicationTestUtils.java +++ b/chrome/test/android/javatests/src/org/chromium/chrome/test/util/ApplicationTestUtils.java
@@ -36,7 +36,7 @@ throws Exception { if (clearAppData) { // Clear data and remove any tasks listed in Android's Overview menu between test runs. - Assert.assertTrue("Unable to clear the app data", clearAppData(context)); + clearAppData(context); if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) { finishAllChromeTasks(context); } @@ -70,10 +70,9 @@ * Clear all files and folders in the Chrome application directory except 'lib'. * The 'cache' directory is recreated as an empty directory. * @param context Target instrumentation context. - * @return Whether clearing the application data was successful. */ - public static boolean clearAppData(Context context) throws InterruptedException { - return ApplicationData.clearAppData(context); + public static void clearAppData(Context context) throws InterruptedException { + ApplicationData.clearAppData(context); } /** Send the user to the Android home screen. */ @@ -97,25 +96,25 @@ /** Waits until Chrome is in the background. */ public static void waitUntilChromeInBackground() throws Exception { - Assert.assertTrue(CriteriaHelper.pollForCriteria(new Criteria() { + CriteriaHelper.pollForCriteria(new Criteria() { @Override public boolean isSatisfied() { int state = ApplicationStatus.getStateForApplication(); return state == ApplicationState.HAS_STOPPED_ACTIVITIES || state == ApplicationState.HAS_DESTROYED_ACTIVITIES; } - })); + }); } /** Waits until Chrome is in the foreground. */ public static void waitUntilChromeInForeground() throws Exception { - Assert.assertTrue(CriteriaHelper.pollForCriteria(new Criteria() { + CriteriaHelper.pollForCriteria(new Criteria() { @Override public boolean isSatisfied() { int state = ApplicationStatus.getStateForApplication(); return state == ApplicationState.HAS_RUNNING_ACTIVITIES; } - })); + }); } /** Finishes all tasks Chrome has listed in Android's Overview. */ @@ -128,18 +127,17 @@ task.finishAndRemoveTask(); } - Assert.assertTrue(CriteriaHelper.pollForCriteria(new Criteria() { + CriteriaHelper.pollForCriteria(new Criteria() { @Override public boolean isSatisfied() { return getNumChromeTasks(context) == 0; } - })); + }); } /** Counts how many tasks Chrome has listed in Android's Overview. */ @TargetApi(Build.VERSION_CODES.LOLLIPOP) public static int getNumChromeTasks(Context context) { - int count = 0; ActivityManager activityManager = (ActivityManager) context.getSystemService(Context.ACTIVITY_SERVICE); return activityManager.getAppTasks().size(); @@ -163,16 +161,16 @@ public static void assertWaitForPageScaleFactorMatch(final ChromeActivity activity, final float expectedScale, boolean waitLongerForLoad) throws InterruptedException { long waitTimeInMs = waitLongerForLoad ? 10000 : CriteriaHelper.DEFAULT_MAX_TIME_TO_POLL; - boolean scaleFactorMatch = CriteriaHelper.pollForCriteria(new Criteria() { + CriteriaHelper.pollForCriteria(new Criteria() { @Override public boolean isSatisfied() { if (activity.getCurrentContentViewCore() == null) return false; + updateFailureReason("Expecting scale factor of: " + expectedScale + ", got: " + + activity.getCurrentContentViewCore().getScale()); return Math.abs(activity.getCurrentContentViewCore().getScale() - expectedScale) < FLOAT_EPSILON; } }, waitTimeInMs, CriteriaHelper.DEFAULT_POLLING_INTERVAL); - Assert.assertTrue("Expecting scale factor of: " + expectedScale + ", got: " - + activity.getCurrentContentViewCore().getScale(), scaleFactorMatch); } } \ No newline at end of file
diff --git a/chrome/test/android/javatests/src/org/chromium/chrome/test/util/BookmarkTestUtils.java b/chrome/test/android/javatests/src/org/chromium/chrome/test/util/BookmarkTestUtils.java index 6d44171b..82f0b550 100644 --- a/chrome/test/android/javatests/src/org/chromium/chrome/test/util/BookmarkTestUtils.java +++ b/chrome/test/android/javatests/src/org/chromium/chrome/test/util/BookmarkTestUtils.java
@@ -282,12 +282,12 @@ private static void checkCriteria(String message, final Callable<Boolean> criteria) throws InterruptedException { - Assert.assertTrue(message, CriteriaHelper.pollForCriteria(new Criteria() { + CriteriaHelper.pollForCriteria(new Criteria(message) { @Override public boolean isSatisfied() { return ThreadUtils.runOnUiThreadBlockingNoException(criteria); } - })); + }); } /**
diff --git a/chrome/test/android/javatests/src/org/chromium/chrome/test/util/ChromeTabUtils.java b/chrome/test/android/javatests/src/org/chromium/chrome/test/util/ChromeTabUtils.java index 5f1ee5c..3db694c 100644 --- a/chrome/test/android/javatests/src/org/chromium/chrome/test/util/ChromeTabUtils.java +++ b/chrome/test/android/javatests/src/org/chromium/chrome/test/util/ChromeTabUtils.java
@@ -256,8 +256,7 @@ Tab tab = activity.getActivityTab(); waitForTabPageLoaded(tab, (String) null); - Assert.assertTrue("NTP never fully loaded.", - NewTabPageTestUtils.waitForNtpLoaded(tab)); + NewTabPageTestUtils.waitForNtpLoaded(tab); instrumentation.waitForIdleSync(); Log.d(TAG, "newTabFromMenu <<"); }
diff --git a/chrome/test/android/javatests/src/org/chromium/chrome/test/util/NewTabPageTestUtils.java b/chrome/test/android/javatests/src/org/chromium/chrome/test/util/NewTabPageTestUtils.java index c76ba1a..de88ad0 100644 --- a/chrome/test/android/javatests/src/org/chromium/chrome/test/util/NewTabPageTestUtils.java +++ b/chrome/test/android/javatests/src/org/chromium/chrome/test/util/NewTabPageTestUtils.java
@@ -23,11 +23,10 @@ * Waits for the NTP owned by the passed in tab to be fully loaded. * * @param tab The tab to be monitored for NTP loading. - * @return Whether the NTP has fully loaded. */ @TargetApi(Build.VERSION_CODES.LOLLIPOP) - public static boolean waitForNtpLoaded(final Tab tab) throws InterruptedException { - return CriteriaHelper.pollForUIThreadCriteria(new Criteria() { + public static void waitForNtpLoaded(final Tab tab) throws InterruptedException { + CriteriaHelper.pollForUIThreadCriteria(new Criteria("NTP never fully loaded") { @Override public boolean isSatisfied() { if (!tab.isIncognito()) {
diff --git a/chrome/test/android/javatests/src/org/chromium/chrome/test/util/OmniboxTestUtils.java b/chrome/test/android/javatests/src/org/chromium/chrome/test/util/OmniboxTestUtils.java index 690d432d..0b3eec6 100644 --- a/chrome/test/android/javatests/src/org/chromium/chrome/test/util/OmniboxTestUtils.java +++ b/chrome/test/android/javatests/src/org/chromium/chrome/test/util/OmniboxTestUtils.java
@@ -229,9 +229,9 @@ throws InterruptedException { for (int i = 0; i < times; i++) { toggleUrlBarFocus(urlBar, true); - Assert.assertTrue(waitForFocusAndKeyboardActive(urlBar, true)); + waitForFocusAndKeyboardActive(urlBar, true); toggleUrlBarFocus(urlBar, false); - Assert.assertTrue(waitForFocusAndKeyboardActive(urlBar, false)); + waitForFocusAndKeyboardActive(urlBar, false); } } @@ -284,11 +284,10 @@ * * @param urlBar The UrlBar whose focus is being inspected. * @param active Whether the UrlBar is expected to have focus or not. - * @return Whether the UrlBar had the requested focus state. */ - public static boolean waitForFocusAndKeyboardActive(final UrlBar urlBar, final boolean active) + public static void waitForFocusAndKeyboardActive(final UrlBar urlBar, final boolean active) throws InterruptedException { - return CriteriaHelper.pollForCriteria(new Criteria() { + CriteriaHelper.pollForCriteria(new Criteria() { @Override public boolean isSatisfied() { return (doesUrlBarHaveFocus(urlBar) == active) @@ -301,11 +300,10 @@ * Waits for a non-empty list of omnibox suggestions is shown. * * @param locationBar The LocationBar who owns the suggestions. - * @return Whether the suggestions were shown. */ - public static boolean waitForOmniboxSuggestions(final LocationBarLayout locationBar) + public static void waitForOmniboxSuggestions(final LocationBarLayout locationBar) throws InterruptedException { - return CriteriaHelper.pollForUIThreadCriteria(new Criteria() { + CriteriaHelper.pollForUIThreadCriteria(new Criteria() { @Override public boolean isSatisfied() { LocationBarLayout.OmniboxSuggestionsList suggestionsList = @@ -321,12 +319,11 @@ * Waits for a suggestion list to be shown with a specified number of entries. * @param locationBar The LocationBar who owns the suggestions. * @param expectedCount The number of suggestions expected to be shown. - * @return Whether the suggestions were shown. */ - public static boolean waitForOmniboxSuggestions( + public static void waitForOmniboxSuggestions( final LocationBarLayout locationBar, final int expectedCount) throws InterruptedException { - return CriteriaHelper.pollForUIThreadCriteria(new Criteria() { + CriteriaHelper.pollForUIThreadCriteria(new Criteria() { @Override public boolean isSatisfied() { LocationBarLayout.OmniboxSuggestionsList suggestionsList =
diff --git a/chrome/test/android/javatests/src/org/chromium/chrome/test/util/OverviewModeBehaviorWatcher.java b/chrome/test/android/javatests/src/org/chromium/chrome/test/util/OverviewModeBehaviorWatcher.java index 9a8a2816..e537cd6 100644 --- a/chrome/test/android/javatests/src/org/chromium/chrome/test/util/OverviewModeBehaviorWatcher.java +++ b/chrome/test/android/javatests/src/org/chromium/chrome/test/util/OverviewModeBehaviorWatcher.java
@@ -4,8 +4,6 @@ package org.chromium.chrome.test.util; -import junit.framework.Assert; - import org.chromium.chrome.browser.compositor.layouts.OverviewModeBehavior; import org.chromium.chrome.browser.compositor.layouts.OverviewModeBehavior.OverviewModeObserver; import org.chromium.content.browser.test.util.Criteria; @@ -23,7 +21,17 @@ private final Criteria mCriteria = new Criteria() { @Override public boolean isSatisfied() { - return !mWaitingForShow && !mWaitingForHide; + if (mWaitingForShow) { + updateFailureReason( + "OverviewModeObserver#onOverviewModeFinishedShowing() not called."); + return false; + } + if (mWaitingForHide) { + updateFailureReason( + "OverviewModeObserver#onOverviewModeFinishedHiding() not called."); + return false; + } + return true; } }; @@ -67,14 +75,7 @@ */ public void waitForBehavior() throws InterruptedException { try { - if (!CriteriaHelper.pollForUIThreadCriteria(mCriteria)) { - Assert.assertFalse( - "OverviewModeObserver#onOverviewModeFinishedShowing() not called.", - mWaitingForShow); - Assert.assertFalse( - "OverviewModeObserver#onOverviewModeFinishedHiding() not called.", - mWaitingForHide); - } + CriteriaHelper.pollForUIThreadCriteria(mCriteria); } finally { mOverviewModeBehavior.removeOverviewModeObserver(this); }
diff --git a/chrome/test/android/javatests/src/org/chromium/chrome/test/util/PrerenderTestHelper.java b/chrome/test/android/javatests/src/org/chromium/chrome/test/util/PrerenderTestHelper.java index b3e822c..0361ece1 100644 --- a/chrome/test/android/javatests/src/org/chromium/chrome/test/util/PrerenderTestHelper.java +++ b/chrome/test/android/javatests/src/org/chromium/chrome/test/util/PrerenderTestHelper.java
@@ -48,12 +48,16 @@ */ public static boolean waitForPrerenderUrl(final Tab tab, final String url, boolean shortTimeout) throws InterruptedException { - CriteriaHelper.pollForCriteria(new Criteria() { - @Override - public boolean isSatisfied() { - return hasTabPrerenderedUrl(tab, url); - } - }, shortTimeout ? SHORT_TIMEOUT_MS : WAIT_FOR_RESPONSE_MS, UI_DELAY_MS); + try { + CriteriaHelper.pollForCriteria(new Criteria() { + @Override + public boolean isSatisfied() { + return hasTabPrerenderedUrl(tab, url); + } + }, shortTimeout ? SHORT_TIMEOUT_MS : WAIT_FOR_RESPONSE_MS, UI_DELAY_MS); + } catch (AssertionError e) { + // TODO(tedchoc): This is horrible and should never timeout to determine success. + } return hasTabPrerenderedUrl(tab, url); }
diff --git a/chrome/test/android/javatests/src/org/chromium/chrome/test/util/browser/TabLoadObserver.java b/chrome/test/android/javatests/src/org/chromium/chrome/test/util/browser/TabLoadObserver.java index 3b0be21..76a575d 100644 --- a/chrome/test/android/javatests/src/org/chromium/chrome/test/util/browser/TabLoadObserver.java +++ b/chrome/test/android/javatests/src/org/chromium/chrome/test/util/browser/TabLoadObserver.java
@@ -6,8 +6,6 @@ import android.text.TextUtils; -import junit.framework.Assert; - import org.chromium.base.ThreadUtils; import org.chromium.chrome.browser.tab.EmptyTabObserver; import org.chromium.chrome.browser.tab.Tab; @@ -16,7 +14,6 @@ import org.chromium.content_public.browser.LoadUrlParams; import java.util.Locale; -import java.util.concurrent.atomic.AtomicReference; /** * Monitors that a Tab starts loading and stops loading a URL. @@ -64,27 +61,25 @@ * @param maxAllowedTime The maximum time this will wait for the page to load. */ public void assertLoaded(long maxAllowedTime) throws InterruptedException { - final AtomicReference<String> failureReason = new AtomicReference<>(); - Criteria loadedCriteria = new Criteria() { @Override public boolean isSatisfied() { if (!mTabLoadStarted) { - failureReason.set("load started never called"); + updateFailureReason("load started never called"); return false; } if (!mTabLoadStopped) { - failureReason.set("load stopped never called"); + updateFailureReason("load stopped never called"); return false; } if (!mTab.isLoadingAndRenderingDone()) { - failureReason.set("load and rendering never completed"); + updateFailureReason("load and rendering never completed"); return false; } String title = mTab.getTitle(); if (mExpectedTitle != null && !TextUtils.equals(mExpectedTitle, title)) { - failureReason.set(String.format( + updateFailureReason(String.format( Locale.ENGLISH, "title did not match -- expected: \"%s\", actual \"%s\"", mExpectedTitle, title)); @@ -92,29 +87,26 @@ } if (mExpectedScale != null) { if (mTab.getContentViewCore() == null) { - failureReason.set("tab has no content view core"); + updateFailureReason("tab has no content view core"); return false; } float scale = mTab.getContentViewCore().getScale(); if (Math.abs(mExpectedScale - scale) >= FLOAT_EPSILON) { - failureReason.set(String.format( + updateFailureReason(String.format( Locale.ENGLISH, "scale did not match with allowed epsilon -- " + "expected: \"%f\", actual \"%f\"", mExpectedScale, scale)); return false; } } - failureReason.set(null); + updateFailureReason(null); return true; } }; - boolean result = CriteriaHelper.pollForUIThreadCriteria( + CriteriaHelper.pollForUIThreadCriteria( loadedCriteria, maxAllowedTime, CriteriaHelper.DEFAULT_POLLING_INTERVAL); - if (!result) { - Assert.fail("Tab not fully loaded because: " + failureReason.get()); - } } /**
diff --git a/chrome/test/android/javatests/src/org/chromium/chrome/test/util/browser/contextmenu/ContextMenuUtils.java b/chrome/test/android/javatests/src/org/chromium/chrome/test/util/browser/contextmenu/ContextMenuUtils.java index 438477d..e2afc11 100644 --- a/chrome/test/android/javatests/src/org/chromium/chrome/test/util/browser/contextmenu/ContextMenuUtils.java +++ b/chrome/test/android/javatests/src/org/chromium/chrome/test/util/browser/contextmenu/ContextMenuUtils.java
@@ -162,12 +162,11 @@ } }); - Assert.assertTrue("Activity did not regain focus.", - CriteriaHelper.pollForCriteria(new Criteria() { - @Override - public boolean isSatisfied() { - return testCase.getActivity().hasWindowFocus(); - } - })); + CriteriaHelper.pollForCriteria(new Criteria("Activity did not regain focus.") { + @Override + public boolean isSatisfied() { + return testCase.getActivity().hasWindowFocus(); + } + }); } }
diff --git a/chrome/test/android/javatests/src/org/chromium/chrome/test/util/browser/sync/SyncTestUtil.java b/chrome/test/android/javatests/src/org/chromium/chrome/test/util/browser/sync/SyncTestUtil.java index c31e302..bde367f 100644 --- a/chrome/test/android/javatests/src/org/chromium/chrome/test/util/browser/sync/SyncTestUtil.java +++ b/chrome/test/android/javatests/src/org/chromium/chrome/test/util/browser/sync/SyncTestUtil.java
@@ -67,13 +67,13 @@ public static void triggerSyncAndWaitForCompletion() throws InterruptedException { final long oldSyncTime = getCurrentSyncTime(); triggerSync(); - boolean syncCompleted = CriteriaHelper.pollForCriteria(new Criteria() { + CriteriaHelper.pollForCriteria(new Criteria( + "Timed out waiting for sync cycle to complete.") { @Override public boolean isSatisfied() { return getCurrentSyncTime() > oldSyncTime; } }, TIMEOUT_MS, INTERVAL_MS); - Assert.assertTrue("Timed out waiting for sync cycle to complete.", syncCompleted); } private static long getCurrentSyncTime() { @@ -89,13 +89,13 @@ * Waits for sync to become active. */ public static void waitForSyncActive() throws InterruptedException { - Assert.assertTrue("Timed out waiting for sync to become active.", - CriteriaHelper.pollForUIThreadCriteria(new Criteria() { - @Override - public boolean isSatisfied() { - return ProfileSyncService.get().isSyncActive(); - } - }, TIMEOUT_MS, INTERVAL_MS)); + CriteriaHelper.pollForUIThreadCriteria(new Criteria( + "Timed out waiting for sync to become active.") { + @Override + public boolean isSatisfied() { + return ProfileSyncService.get().isSyncActive(); + } + }, TIMEOUT_MS, INTERVAL_MS); } /**
diff --git a/chrome/test/android/javatests/src/org/chromium/chrome/test/util/browser/tabmodel/document/TestInitializationObserver.java b/chrome/test/android/javatests/src/org/chromium/chrome/test/util/browser/tabmodel/document/TestInitializationObserver.java index 7f20edc..7b511eb2 100644 --- a/chrome/test/android/javatests/src/org/chromium/chrome/test/util/browser/tabmodel/document/TestInitializationObserver.java +++ b/chrome/test/android/javatests/src/org/chromium/chrome/test/util/browser/tabmodel/document/TestInitializationObserver.java
@@ -4,8 +4,6 @@ package org.chromium.chrome.test.util.browser.tabmodel.document; -import static junit.framework.Assert.assertTrue; - import org.chromium.base.ThreadUtils; import org.chromium.chrome.browser.tabmodel.document.DocumentTabModel; import org.chromium.content.browser.test.util.Criteria; @@ -52,11 +50,11 @@ } }); - assertTrue(CriteriaHelper.pollForCriteria(new Criteria() { + CriteriaHelper.pollForCriteria(new Criteria() { @Override public boolean isSatisfied() { return observer.mIsReady; } - })); + }); } } \ No newline at end of file
diff --git a/chrome/test/base/chrome_test_launcher.cc b/chrome/test/base/chrome_test_launcher.cc index a1b317e..6e59b804 100644 --- a/chrome/test/base/chrome_test_launcher.cc +++ b/chrome/test/base/chrome_test_launcher.cc
@@ -19,7 +19,9 @@ #include "chrome/common/chrome_switches.h" #include "chrome/test/base/chrome_test_suite.h" #include "chrome/test/base/test_switches.h" +#include "components/crash/content/app/crashpad.h" #include "content/public/app/content_main.h" +#include "content/public/common/content_switches.h" #include "content/public/test/test_launcher.h" #include "content/public/test/test_utils.h" #include "ui/base/test/ui_controls.h" @@ -40,7 +42,7 @@ #include "ash/test/ui_controls_factory_ash.h" #endif -#if defined(OS_LINUX) || defined(OS_ANDROID) +#if defined(OS_LINUX) || defined(OS_ANDROID) || defined(OS_WIN) #include "chrome/app/chrome_crash_reporter_client.h" #endif @@ -112,14 +114,22 @@ chrome_browser_application_mac::RegisterBrowserCrApp(); #endif -#if defined(OS_LINUX) || defined(OS_ANDROID) - // We leak this pointer intentionally. The breakpad client needs to outlive +#if defined(OS_LINUX) || defined(OS_ANDROID) || defined(OS_WIN) + // We leak this pointer intentionally. The crash client needs to outlive // all other code. ChromeCrashReporterClient* crash_client = new ChromeCrashReporterClient(); ANNOTATE_LEAKING_OBJECT_PTR(crash_client); crash_reporter::SetCrashReporterClient(crash_client); #endif +#if defined(OS_WIN) + base::CommandLine::Init(0, nullptr); + std::string process_type = + base::CommandLine::ForCurrentProcess()->GetSwitchValueASCII( + switches::kProcessType); + crash_reporter::InitializeCrashpad(process_type.empty(), process_type); +#endif + ChromeTestLauncherDelegate launcher_delegate(runner); return content::LaunchTests(&launcher_delegate, default_jobs, argc, argv); }
diff --git a/chrome/test/base/chrome_test_suite.cc b/chrome/test/base/chrome_test_suite.cc index 6581d13..90e4331 100644 --- a/chrome/test/base/chrome_test_suite.cc +++ b/chrome/test/base/chrome_test_suite.cc
@@ -16,13 +16,14 @@ #include "chrome/browser/browser_process.h" #include "chrome/common/chrome_constants.h" #include "chrome/common/chrome_paths.h" +#include "chrome/common/features.h" #include "chrome/common/url_constants.h" #include "components/content_settings/core/common/content_settings_pattern.h" #include "content/public/test/test_launcher.h" #include "extensions/common/constants.h" #include "testing/gtest/include/gtest/gtest.h" -#if defined(OS_ANDROID) +#if BUILDFLAG(ANDROID_JAVA_UI) #include "base/android/jni_android.h" #include "chrome/browser/android/chrome_jni_registrar.h" #endif @@ -82,7 +83,7 @@ PathService::Override(base::DIR_MODULE, browser_dir_); } -#if defined(OS_ANDROID) +#if BUILDFLAG(ANDROID_JAVA_UI) ASSERT_TRUE(chrome::android::RegisterBrowserJNI( base::android::AttachCurrentThread())); #endif
diff --git a/chrome/test/data/chromeos/app_mode/multi_app_kiosk/src/primary_app/key.pem b/chrome/test/data/chromeos/app_mode/multi_app_kiosk/src/primary_app/key.pem new file mode 100644 index 0000000..fac381c --- /dev/null +++ b/chrome/test/data/chromeos/app_mode/multi_app_kiosk/src/primary_app/key.pem
@@ -0,0 +1,28 @@ +-----BEGIN PRIVATE KEY----- +MIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQDmJvQFpDnngGBy +iIEpjw4RfxRNS/keOHz54Qjh5M5PKAlZPHZmxhEsrg8FwAQWiZP6/zrtPFAVzalU +WJJjBz5TLUmGY8BLvg3nBEHtcQ6qTcJHRms96wi4gM76DIZVdjh5SW0c5XY41CPP +alfr8Xtdhg+Y2d+Em5jjS33JMXQgilR34cpKzj4KfPvzX4nQULc0DhdnRshrWzZq +Np3vjZYdt0D7WfJR52RUsQHZxIuY5oKxv/IRG43/NENx1QdtmkMdVZxcv59F+zg8 +qC7HxsLlSo4A0mdYR/9Qldqkxdl3j1FqEDF+XLZHntmpydCbt9GyddmIwSeiSob5 +5Yka4EwLAgMBAAECggEBAIMIKmYL2euzazXKAb9nctsDPsvDNVG/V2fsduIlIlBu +uuPTSJW6royBjIv5hlpOebGtHh9y9yVysbUTuEQpG5K/ddzNbe2xhri/88j7VR4g +pzttHCFkbtKcgzpZZyHA7OYgp76L5YL1RG4SXXw3P8U/TiH36QnWjHTbxgGF5lef +VZCM/f6p73JySbvgmkoUW2fi757bEz3Tb2CWiNbdutfFBnjm9Vh0Mp/aF3RJM7tZ +vQTU3yAcXKqhtqLXQ6uT+D7zZfgTImZnRLwOnIQRz0xEIIbjU4/CNZdMT3HbGsbC +kK+9Exru8j61epCwFUfiaixq71CqHggyIplBoTonMgECgYEA9PHUCj/VAFHPYqZZ +pUHX/6+A0Rl7QcmuQ5xP0QzQcE8OXLZEUtWmRUDs4Vx0qQRKFDU4s2mj1b/PETl4 +dl36tPNoZb74GbvGisb5ZU26d1II/+3axJ5AcMylHRyyQt2SxSFggSaLS4VWYClu +7uDDrG87dC7JNa66oj0P88Sf5C8CgYEA8Io1K4tbuVrqqTsrEJ0UyDrLBw9eSIvk +2BnTomt517fTt368Kq/IutKw3aV8ZkgdJIGswua67OSC08faw/piRgUuYxtpXvFU +b74Au0wQHUM0g3W9fe4iTjsJEIkaFpa2ITxL/eaDmr9gO4t6rRepl8Sewulh444E +ZxMXDF04MuUCgYBSySEHTcep0fyrtNl7lyNv0VtSULBt7cIuK7h2SURxkOajwx6Y +eIk3wtfM2zi6ny6CYfKGAOBUr/1GLwxdxSmk2tef+8lSuTpDUTidWoX5KgrMpRFZ +frr85M2xZy+Ale6zHbLGM8bEgY5N9fL+XY0EzJtliyKKOEHv739ivkPkFQKBgAJy +taXSzkUtqrO8OWz63EpJZuWUf3YnjlWwtZmylFPguBPnA00/6sAUAt7On1x/IWTM +uRBmvsJIdRhosU5LTxK9XMJ/dewUcrKMcX92f7d8hp1L5njQoqK/MRFtA8n1ELd3 +4KId5Xr+taEFg2MdmYlE5ATB0VA6ksrlw9dJX5gNAoGAGAo7B78o1f3BGuBqgYiM +irmpDiUbx9bSm1En1hs9/D7jeAMay+omroTaBnEaycFjOY3baeMNuDp8myGYzeKd +Z6CaDi9o0MJnbOX32DNNLyhrg67tlH/mwO1D6+vKnzIywuS4bWuW0CbDRCSsG9Mh +irtGu/xwo/nI8U2ZI8bDXyE= +-----END PRIVATE KEY-----
diff --git a/chrome/test/data/chromeos/app_mode/multi_app_kiosk/src/primary_app/v1/manifest.json b/chrome/test/data/chromeos/app_mode/multi_app_kiosk/src/primary_app/v1/manifest.json index 60e4b2c..47467ba 100644 --- a/chrome/test/data/chromeos/app_mode/multi_app_kiosk/src/primary_app/v1/manifest.json +++ b/chrome/test/data/chromeos/app_mode/multi_app_kiosk/src/primary_app/v1/manifest.json
@@ -15,8 +15,8 @@ "kiosk_enabled": true, "offline_enabled": true, "kiosk_secondary_apps": [ - {"id": "ihplaomghjbeafnpnjkhppmfpnmdihgd"}, - {"id": "fiehokkcgaojmbhfhlpiheggjhaedjoc"} + {"id": "emnbflhfbllbehnpjmjddklbkeeoaaeg"}, + {"id": "blmjgfbajihimkjmepbhgmjbopjchlda"} ], "permissions": [ "power"
diff --git a/chrome/test/data/chromeos/app_mode/multi_app_kiosk/src/primary_app/v2/manifest.json b/chrome/test/data/chromeos/app_mode/multi_app_kiosk/src/primary_app/v2/manifest.json index 55f7f6f..5712db1 100644 --- a/chrome/test/data/chromeos/app_mode/multi_app_kiosk/src/primary_app/v2/manifest.json +++ b/chrome/test/data/chromeos/app_mode/multi_app_kiosk/src/primary_app/v2/manifest.json
@@ -15,7 +15,7 @@ "kiosk_enabled": true, "offline_enabled": true, "kiosk_secondary_apps": [ - {"id": "fiehokkcgaojmbhfhlpiheggjhaedjoc"} + {"id": "blmjgfbajihimkjmepbhgmjbopjchlda"} ], "permissions": [ "power"
diff --git a/chrome/test/data/chromeos/app_mode/multi_app_kiosk/src/primary_app/v24/manifest.json b/chrome/test/data/chromeos/app_mode/multi_app_kiosk/src/primary_app/v24/manifest.json index cb698e6..36360a9 100644 --- a/chrome/test/data/chromeos/app_mode/multi_app_kiosk/src/primary_app/v24/manifest.json +++ b/chrome/test/data/chromeos/app_mode/multi_app_kiosk/src/primary_app/v24/manifest.json
@@ -15,6 +15,6 @@ "kiosk_enabled": true, "offline_enabled": true, "kiosk_secondary_apps": [ - {"id": "imlgadjgphbjkaceoiapiephhgeofhic"} + {"id": "gdmgkkoghcihimdfoabkefdkccllcfea"} ] }
diff --git a/chrome/test/data/chromeos/app_mode/multi_app_kiosk/src/primary_app/v3/manifest.json b/chrome/test/data/chromeos/app_mode/multi_app_kiosk/src/primary_app/v3/manifest.json index 0035ee3..adf341b5 100644 --- a/chrome/test/data/chromeos/app_mode/multi_app_kiosk/src/primary_app/v3/manifest.json +++ b/chrome/test/data/chromeos/app_mode/multi_app_kiosk/src/primary_app/v3/manifest.json
@@ -15,9 +15,9 @@ "kiosk_enabled": true, "offline_enabled": true, "kiosk_secondary_apps": [ - {"id": "ihplaomghjbeafnpnjkhppmfpnmdihgd"}, - {"id": "fiehokkcgaojmbhfhlpiheggjhaedjoc"}, - {"id": "aabnpdpieclcikafhdkkpldcaodmfoai"} + {"id": "emnbflhfbllbehnpjmjddklbkeeoaaeg"}, + {"id": "blmjgfbajihimkjmepbhgmjbopjchlda"}, + {"id": "jkofhenkpndpdflehcjpcekgecjkpggg"} ], "permissions": [ "power"
diff --git a/chrome/test/data/chromeos/app_mode/multi_app_kiosk/src/secondary_app_1/key.pem b/chrome/test/data/chromeos/app_mode/multi_app_kiosk/src/secondary_app_1/key.pem new file mode 100644 index 0000000..9a6f7423 --- /dev/null +++ b/chrome/test/data/chromeos/app_mode/multi_app_kiosk/src/secondary_app_1/key.pem
@@ -0,0 +1,28 @@ +-----BEGIN PRIVATE KEY----- +MIIEvwIBADANBgkqhkiG9w0BAQEFAASCBKkwggSlAgEAAoIBAQDzgLk3sBpIZygk +esyB/KqtrdK05IK4IK5JA3AWhRWMnJd5Go4u6F+TJldnP6eBA8gLrlqXgwLbFPI9 +0kPDjw+Lb/eydhN2icsVbAwBOrmce1S7B76Lh/PoAj3rqbGVudlIJTBuc/U9Zmkn +renpOqgv6pAUGw5Fpo++6GH0wUGJmB41tdoI5OrkiR51nwbeqe8ZG2kOKMWJVGN0 +z0uxQ4iq8XJPghrh2FgdpUyB4asq5j/A2Z0QHAcCs73iAGES00KLLsUhuv/RvUjp +M5YyK72RQk2G9JI1HnBoqwyI0oXiVr67AYzWw9Cw4PpObMBYWXMl7TF591DGFopp +LmnweQRTAgMBAAECggEBAMmdQD5aojhmqTcjMedCxDMPpFHAjndUH9o2bX1H7eLB +2S0djrJKFrBo45+Kde99qQn67+lZQWkSO8xyJ0dpUW6bY5Sw7UaNqsfu8TWnYP2u +pCZDsEIpbAsiqBBTLcWR3tU8bZBWlKyk+dYvymgg+BbMeUUcbcG/um9QS6LyzIfV +/V4LIq9Gf6WJJw0HB2muNCtzn1Bt55ZjGPK+QgGNYuteTNtcTLDPuEBTp8oQfBPw +X6eDbTFL6EIEHqSWGLCg5QhtOvgz/3QTIeMzJYJ6n5zZZ+1nIZmGtk1wY4+aDpIe +iQfjabak4fQ/hAnPSNMZvw8yjheWj4ENdCVzoCKOd2ECgYEA+7VW/wVGMIpiCW94 +TOXtoek74w74xz69OHcbLp3XzOvDtNfX5j7DORGOw/bukYp7qSH33/oui5mpQppD +O5MVTk8/KFZtXvHY/5ffJzwGJdz3SCnZCoJyE0jME33pYlN6t10mEPBrh/35DcHv +3vCqaLJN6F/lkQ8iIf/t1+7YxeMCgYEA96eRa/rJmnSH1zc8CNXK+quUHtokfv2W +sc+x6VxSlKzpE6OU8Ay3TH94hoZfQRCsZMX1ab9nRfLwe8u9Bvi9jfwJkCJkr40b +O/91JKAfXV3sxAwTMGW4ayBIa2ftjJfvm1ZYNs7QhwshcQ9OHqdnZWfaa93JkkZm +BSUnAu4MktECgYEAt+Ogngk1YSsIOop0YgGs3RfvB5Adkjq0tLbXZfQs/2nS/aCe ++3go2d2I5oPVgQCiHUtSsxAsxxJIxP68VZ679w0QQCD8IFwhw4Epp5lDiI/pHJBu +Hy5ztsD9TtQzGAGS6rkjoUZz2NNkC3f/DWnXpUt2fWjp51MeBabbFWFKfy8CgYB0 +CnxFUDluufN8kFD9AtAdLJA29JftOP2HS35djfjT2UFNBnUfFZY9rezXe9beMeXV +Qjx/1EObrv2nxAtKXPrUsKf6dWMgLsn4DvbgtnZ71Sq/objMEJ2c9H96dDQGkJqg ++pBS/g0PedOtmjJMgrwb89GQgVeVxo6/Em15HfmeQQKBgQCBq/966gD0SZ9cHTw8 +7tRVrDEIAygjJYjCy3psHbBiorynbQAiBrnHfb2Ty3M4y7tygVHzGalrTwUYhe23 +0pQsMfwcJCZC03tq6ujQgUUKfNtD+NxCU7QixrTIVqUUlcuzBcv31cuZx1hekoje +RJy//J+Smym4/T1gQNSpsqegiw== +-----END PRIVATE KEY-----
diff --git a/chrome/test/data/chromeos/app_mode/multi_app_kiosk/src/secondary_app_2/key.pem b/chrome/test/data/chromeos/app_mode/multi_app_kiosk/src/secondary_app_2/key.pem new file mode 100644 index 0000000..6ce94ca --- /dev/null +++ b/chrome/test/data/chromeos/app_mode/multi_app_kiosk/src/secondary_app_2/key.pem
@@ -0,0 +1,28 @@ +-----BEGIN PRIVATE KEY----- +MIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQC7lD52iGwy/N8P +AHbrUnI4fhOjmkXEPXAFW5xdnlIG+RS2TKUjqo5ufQwxBHeyWL/BmYtj4rekdke/ +jZ419EhTFwYUw6aLpLKQPTjeNylf4Zmr2xUchPaZSgSKemPZIrJY36QgBoXf+G+r +99gMYMJAecyzPoWsCvb+W64D48XrOQHaRf3T7CQpiyVemdfB/TrP4Qmd2U3tLzB3 +HbSfEQ7AkDpupdv2sovyuR1SAxY8JkgLUoDtU46xUGwFS9hs8YhcY8gHs8V9Gqvx +YPFxNCVP3v4Sz4FWRZvFzhrzTuE5c1JVDg2oXPSKLviXvw8aboRlkq1RlduTqQ7N +llJPnSppAgMBAAECggEAfZe8WtDs4Ra+ouTEurrxDzIbJCdfHw2ju3KjN2uRsGmF +nKmkyESiKQhA6XD8U8VoXs/XrIFYRB2N3IuNqsJsynVX9P8qu8UCaeET+nUklrYO +liqR8A52rhwI/k8EG5ZHo4nZ8jdr25IT8yh215LRfSoQDNOH3LFavuPTl3ciRWM4 +ZFLkGO8QrfoDAdoC6xYNFDWGHLz5tvOtZ+p2iEZ7z1WYwebqmi7wgVnjQEUkDwg2 +j9XlpAxM4x2rK5Wv5L6M3QRm7ct2qpA3v7D7Xt7wwyH8bs1fa25BB32DzdpcqDBh +k1wqzUOGsK9xDinuLCbNCkhEdzc1bZla/1jXF7EiIQKBgQDivV/JqNHk1kFw2jQz +PCMjNfRp9mPGXSUdBIrK9G19HyffjgQLQmiP17yZ7JHL+X+fd0tMhpuwlrnEPYNp +J24u6rwfHq/MHIz96I6/mRFMr9KFSc+LmG9IkdE/wxMG4Rl7fdAnliAOjt3cq/gv +RfS2F9Tm6PgEHOPfa0xKuyGvVwKBgQDTySYwjWB6/YjNC2Ray/7SmxNxG7PwpZIa +AegZfXoldK/baskKbpj8bjCer+4RV4kU/60YJyN9TtjY62Ol3U1LAFN8XyFaGDea +Dx4dB3LkX+eCcRrCrUguNGqQif8GEAaEoNWkfNkiuZzNVovysmwfsdLI+opyBBo4 +J4F8ZhacPwKBgB5uhFiwi9tG1mmrH65wt9aV+0Ptid6pyb1nSqmKvNc6Q0PB79ED +DL2hmvKdycOyrOpePID84BCHak9oYibO3/70CmOy3q1qd5HskJwukx/TyVGSYoS9 +5NG8oHUKXZdixuTIMhPeFldd3XEss5bEsN9vu2dyhTcoGX13DTpKe27pAoGABdvZ +r5wpoB1lbG61PwHHseHSXt2qU6zw5sFIv3PGLkUVHFfO6ff3SXxu4eTyDA7E3wzX +qARlKfFFdHLGle8SVVHT/WvQS2LCHwPuDFWJayHwEJ66Y8pRZd3TWN5IbM2CsKaW +Ym+Fvj0uRkvvoS4oaZQMxbyQmejdJNKK9XsJgxcCgYEAtJmoe7hiCTqKetX7N56P +uxOmf1KpRnqDgWyq+l8dTJ4rSPOGr8N1X7JGGoHaO/8ElWkPKJ2WNAB1HbRMFTNz ++3NhQLLEZUp64nLUtMSaN2XvQhSminbzPtLF+i0jijjfw4HYTb64kDAbFlz8zrJ3 +Oahu+bwAN5SyrQgIJI4BxDw= +-----END PRIVATE KEY-----
diff --git a/chrome/test/data/chromeos/app_mode/multi_app_kiosk/src/secondary_app_3/key.pem b/chrome/test/data/chromeos/app_mode/multi_app_kiosk/src/secondary_app_3/key.pem new file mode 100644 index 0000000..59503ea9 --- /dev/null +++ b/chrome/test/data/chromeos/app_mode/multi_app_kiosk/src/secondary_app_3/key.pem
@@ -0,0 +1,28 @@ +-----BEGIN PRIVATE KEY----- +MIIEvwIBADANBgkqhkiG9w0BAQEFAASCBKkwggSlAgEAAoIBAQC4BIDw3iHLPtZ4 +LBEEeojs5z4DsBdpN1wwNsPSV8PP5otZORAeYeB6KY5CrXOtogoiNwZGm1CbX/2E +2s4+qpN1ZmvuR49jKvYemNPPX5WO0mQHVRzJOU73V6FtSFvSnyj4oAnOSasuSGtb +CebJjQxYv0mWeMMfK9AFr6zyN4KEntnHjKWcqAcuxNRkcjNeFL3mVGFku5eo9i8M +XMffH8mwK4Jb4uH42ux9PJH/HMYC/n6Sn+gfEOGPh3/jKxUgPfCBkuoj58QqJ3Yt +jyDUGi6ilVMa0754xTkpQUwIVsHzR/86BzA+3/j8z76vxYGyq0PfKXD4EfoajNBT +poWFl1TBAgMBAAECggEBALJP4uYESXjZ5hbClKbjWeU92jDWpIjXFSS/HJepZdwC +SUtm6QCX1V5rACgKTYqV9v3aleE7RSuaI15ma+37ejIL0lAt1XrBuYZCjxRmSdUA +d99HEULHnoY8yvbLY/a/NYNeCMJ1TkPl9ulbud/aJnmkuljtoh2FZejsp0h6k6WP +ZWEMmIdpSIMNktIjeBTmuQWoGibX04WpKqbdt9QhGz0sRoojjA8foLje39oEW7a1 +8E0VJibfXUm7GgzdzLmVJTiViBzf2+4ZUdfZOzksl/9/QjT4okdI4g984+aTddet +gp37Nkf+m33ASCyFgKiU28Z0WSqS6nA/lT+M8X0pYwECgYEA7vOo1O3IfnS+xOz5 +6Z+PHADtOJRTozBqty/RqAfBp0nVVbnxpj8VHNxr/4kBrOaKvXMr0mMfKUTvrQEr +tZX0PNVYvdzMvEdf3b5QEvnZBjC/2zQAxiSj2mqTMFcW488NluWGHFuGm2N1MdcO +FzgiTrbSKC1+KEmBFaoIfPpOllECgYEAxSV/R352qMTmQkr+ImgP49pL6+lIVkLj +FKE/UsWVGRcz14pxuOg9yaC2KCv0nAcFEPTMOL2mv1RVuKwVzeiFcNAOrook6oG9 +eTAup606HFzkDvLxRXpH4Oj8zqu5riI3Faw+ViCo5AiK54t58qKpzWBsFjVZ1cdQ +gMpZhwF5i3ECgYEAobpvCfcKnXRc7iJKn/IrxVNnO8VAupH5mJUX/PeK/bP+XXBl ++xR1MLyLqD/Nz32WZ9V80n/eRmtvIRRKxjOBRG9OCetY8xIH86hsv/s1BXiXUkDn +STThZeJ+TtiTGIs6cmhVFfpop+FwH9Sjp9mJdudMZH8uBQyC/uu/pP8xk5ECgYBt +/Bdf+WuViBO1lETnSQrkYRrOCB11EmfBUJwVP2mIz+r6KqB7OgWOgPxeuPcEPN5U +sV1lolhukUwpdMfNUhVv9ILcWPFzauIbxAejP/8VZ7VLqbl0u11yWkj/u8ohHbGB +g9BbGGlgnmtv9d4YwSreCxcB5M2zeDivQTRlHyuB4QKBgQCmKoHvFapbJ6MgG1r8 +bFFdl6UXehN6q6KXS+T4jCUbbLJbyI6uj39QOB9BsbHB6qI30g0GfF6rq3Vrsx9n +B3RxvyoZhnvXn1gCubvcl+wNPMKSYumDBOzvk+zQxXp3UMT9q8E6sfG9YmwajPu3 +Tid+7nx+zm42NvmzVDi3jgyutQ== +-----END PRIVATE KEY-----
diff --git a/chrome/test/data/chromeos/app_mode/multi_app_kiosk/src/secondary_extension_1/key.pem b/chrome/test/data/chromeos/app_mode/multi_app_kiosk/src/secondary_extension_1/key.pem new file mode 100644 index 0000000..8597665b --- /dev/null +++ b/chrome/test/data/chromeos/app_mode/multi_app_kiosk/src/secondary_extension_1/key.pem
@@ -0,0 +1,28 @@ +-----BEGIN PRIVATE KEY----- +MIIEuwIBADANBgkqhkiG9w0BAQEFAASCBKUwggShAgEAAoIBAQC5Yqr1sdfY5Kr8 +OPq1tj1M31P9ICSFOhR5FUMP6WQ3uPr4TV1wpenG/WtUl68S/HQ6gj8qu7Shcq+E +AG8tJZ6ZgrV4I3NuFpq2xiI9OjCIDfHT+LpOohcagETtDTGVhJWwyEHUqC9rsQ0P +BWxyogwBGIFIJRz8IwZ08e8ntrrgV7OuUmeK7pgjw0SI7may7FWdTOoLNhvAtZDh +Q6TJOi2ZHRZ+ekAccQ1fUMCoeQoPmjtLb3faR+WV0hLb5JppEdtSl05j1X4LSGnr +9+67J3ZBZN87DjMkPu+BOdpR2EKOgFwnGNkXVvqbQz7oIy7tv/Ctj9JU1ilfPwMn +iioQhMOVAgMBAAECgf9EEfa0QJkBCvW9py5nioL3twkf6K2APdNGoof9T7V8wG9m +vQGSW1l7t5GxfgDK9+e1lB2dk06/+Vx5G6+25BlYRKZddqbrxWEJu7bWxIcNbhFd +w/ak6N+S24ZzhGSwgf506xNBAoBnCpvA6Dzp2paN0HGoC/iYnEPCrRMjgfUcaneS +7LWVy38+niCGy7WKdv5GBS/nALVx5CXRqeawXs8Awa49mfV63P3s3dIE5COK55xw +32SQVMuXCV9ZC2C+tbdFxKKAzgQVGS3oENa/ov3TP9FXlr0nlj9FAGigvhMl0qKB +gjXXxCL5/xpkw+9ZdD9lmlV8LlKvyKCEM5Oc3IECgYEA2zbBWiJUksyKqAalaO7Z +jgShtjRlGEv+gm2TxV2fGFoxDYK8s0Se/obyhCoDzRluRXS0u2wTZuYXRbFkL4PT +JsUvlOaNmfRJ9lfuiFdX3E3sg0Uzulr+7XN7tdUz1szA+Ft+ESQ2N0HlHxGMDk97 +wb7Wfp9F5M4PmvFJAn5/lPECgYEA2H6rg9mchTustKBz7II85kQ013RBu22iYPF6 +KrcfLL1iANIfDJ8dB0A+P4dp6hQCsM/3Go+jLTLpM5u/zYL2pEKOGssQAlrEjBNe +hNpYerxYpprfsq0g9NPfsxzpUNJd8IRnzymo/T3FZZWWO4okmY0Wp+Uuv3sbfS6N +KBONCOUCgYEAgZMCAxcbypHgu6UCDN5x9gJC3AJoZ040KEBBAn5uVeSp7gSDKau8 +F1MI8porGQaZKbDsS4R8i2wiAW3zfCp9mwMfNvJ4bLH7LgOX2TtXkb71uDolc1fq +K80BKN/W/naU8biS8ernqQ3oMs8abDMLQeBdxQa8N5ydmMZak4DWROECgYAL2/R9 +RoBidABj7J4tCH1Zh8b1PnMTV1Aby16L1HgqtT0XGmuE/3pRmV1PkZVlsy7qjJnW +pKOlqDJKF3AMS+5C1Tp/kTwRRPObULxOvr82Cfc5OSaj3QP/JVQNtbm6KavnrvkY +ygltxeJ4TBdsr4aNusLQ86b56j55PwGQfnGtWQKBgBvrYWZn9EY09HZGrmI5pK3P +08roc7qjU6sRKQUdST1qWaPo/Ct8N1t0cx9IjOx29vRm6LjaF8SNMAW9wQUliJkK +QCwO5RJGSh4H/ujUPVJaf7gWp/3hrsFvdFqLiweMbP21Us3j/drR0EdZK2Rt29hJ +zLxK87gXUSzJKDND1XQ3 +-----END PRIVATE KEY-----
diff --git a/chrome/test/data/chromeos/app_mode/multi_app_kiosk/src/secondary_extension_1/manifest.json b/chrome/test/data/chromeos/app_mode/multi_app_kiosk/src/secondary_extension_1/manifest.json index 93e183c..7a9aaf4 100644 --- a/chrome/test/data/chromeos/app_mode/multi_app_kiosk/src/secondary_extension_1/manifest.json +++ b/chrome/test/data/chromeos/app_mode/multi_app_kiosk/src/secondary_extension_1/manifest.json
@@ -10,6 +10,5 @@ "background": { "scripts": ["main.js"] }, - "kiosk_enabled": true, "offline_enabled": true }
diff --git a/chrome/test/data/chromeos/app_mode/multi_app_kiosk/src/shared_module/v2/manifest.json b/chrome/test/data/chromeos/app_mode/multi_app_kiosk/src/shared_module/v2/manifest.json new file mode 100644 index 0000000..f8f06db --- /dev/null +++ b/chrome/test/data/chromeos/app_mode/multi_app_kiosk/src/shared_module/v2/manifest.json
@@ -0,0 +1,6 @@ +{ + "export": {}, + "name": "Shared Module", + "manifest_version": 2, + "version": "2.0.0" +}
diff --git a/chrome/test/data/chromeos/app_mode/multi_app_kiosk/src/shared_module/v2/pass.js b/chrome/test/data/chromeos/app_mode/multi_app_kiosk/src/shared_module/v2/pass.js new file mode 100644 index 0000000..1e1d7e5 --- /dev/null +++ b/chrome/test/data/chromeos/app_mode/multi_app_kiosk/src/shared_module/v2/pass.js
@@ -0,0 +1,5 @@ +// Copyright (c) 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. + +var pass_shared_module = {};
diff --git a/chrome/test/data/chromeos/app_mode/webstore/downloads/aabnpdpieclcikafhdkkpldcaodmfoai-1.0.0.crx b/chrome/test/data/chromeos/app_mode/webstore/downloads/aabnpdpieclcikafhdkkpldcaodmfoai-1.0.0.crx deleted file mode 100644 index d77cb21..0000000 --- a/chrome/test/data/chromeos/app_mode/webstore/downloads/aabnpdpieclcikafhdkkpldcaodmfoai-1.0.0.crx +++ /dev/null Binary files differ
diff --git a/chrome/test/data/chromeos/app_mode/webstore/downloads/biebhpdepndljbnkadldcbjkiedldnmn-2.0.0.crx b/chrome/test/data/chromeos/app_mode/webstore/downloads/biebhpdepndljbnkadldcbjkiedldnmn-2.0.0.crx new file mode 100644 index 0000000..cd4d9b4 --- /dev/null +++ b/chrome/test/data/chromeos/app_mode/webstore/downloads/biebhpdepndljbnkadldcbjkiedldnmn-2.0.0.crx Binary files differ
diff --git a/chrome/test/data/chromeos/app_mode/webstore/downloads/blmjgfbajihimkjmepbhgmjbopjchlda-1.0.0.crx b/chrome/test/data/chromeos/app_mode/webstore/downloads/blmjgfbajihimkjmepbhgmjbopjchlda-1.0.0.crx new file mode 100644 index 0000000..85ccadde --- /dev/null +++ b/chrome/test/data/chromeos/app_mode/webstore/downloads/blmjgfbajihimkjmepbhgmjbopjchlda-1.0.0.crx Binary files differ
diff --git a/chrome/test/data/chromeos/app_mode/webstore/downloads/ceobkcclegcliomogfoeoheahogoecgl-1.0.0.crx b/chrome/test/data/chromeos/app_mode/webstore/downloads/ceobkcclegcliomogfoeoheahogoecgl-1.0.0.crx deleted file mode 100644 index cb5c5e0..0000000 --- a/chrome/test/data/chromeos/app_mode/webstore/downloads/ceobkcclegcliomogfoeoheahogoecgl-1.0.0.crx +++ /dev/null Binary files differ
diff --git a/chrome/test/data/chromeos/app_mode/webstore/downloads/ceobkcclegcliomogfoeoheahogoecgl-2.0.0-1app.crx b/chrome/test/data/chromeos/app_mode/webstore/downloads/ceobkcclegcliomogfoeoheahogoecgl-2.0.0-1app.crx deleted file mode 100644 index a7e8657..0000000 --- a/chrome/test/data/chromeos/app_mode/webstore/downloads/ceobkcclegcliomogfoeoheahogoecgl-2.0.0-1app.crx +++ /dev/null Binary files differ
diff --git a/chrome/test/data/chromeos/app_mode/webstore/downloads/ceobkcclegcliomogfoeoheahogoecgl-24.0.0.crx b/chrome/test/data/chromeos/app_mode/webstore/downloads/ceobkcclegcliomogfoeoheahogoecgl-24.0.0.crx deleted file mode 100644 index df8d87b..0000000 --- a/chrome/test/data/chromeos/app_mode/webstore/downloads/ceobkcclegcliomogfoeoheahogoecgl-24.0.0.crx +++ /dev/null Binary files differ
diff --git a/chrome/test/data/chromeos/app_mode/webstore/downloads/ceobkcclegcliomogfoeoheahogoecgl-3.0.0-3app.crx b/chrome/test/data/chromeos/app_mode/webstore/downloads/ceobkcclegcliomogfoeoheahogoecgl-3.0.0-3app.crx deleted file mode 100644 index 8768f88..0000000 --- a/chrome/test/data/chromeos/app_mode/webstore/downloads/ceobkcclegcliomogfoeoheahogoecgl-3.0.0-3app.crx +++ /dev/null Binary files differ
diff --git a/chrome/test/data/chromeos/app_mode/webstore/downloads/dpejijbnadgcgmabkmcoajkgongfgnii-1.0.0.crx b/chrome/test/data/chromeos/app_mode/webstore/downloads/dpejijbnadgcgmabkmcoajkgongfgnii-1.0.0.crx new file mode 100644 index 0000000..0a4d20a2 --- /dev/null +++ b/chrome/test/data/chromeos/app_mode/webstore/downloads/dpejijbnadgcgmabkmcoajkgongfgnii-1.0.0.crx Binary files differ
diff --git a/chrome/test/data/chromeos/app_mode/webstore/downloads/dpejijbnadgcgmabkmcoajkgongfgnii-2.0.0.crx b/chrome/test/data/chromeos/app_mode/webstore/downloads/dpejijbnadgcgmabkmcoajkgongfgnii-2.0.0.crx new file mode 100644 index 0000000..86100eb --- /dev/null +++ b/chrome/test/data/chromeos/app_mode/webstore/downloads/dpejijbnadgcgmabkmcoajkgongfgnii-2.0.0.crx Binary files differ
diff --git a/chrome/test/data/chromeos/app_mode/webstore/downloads/dpejijbnadgcgmabkmcoajkgongfgnii-24.0.0.crx b/chrome/test/data/chromeos/app_mode/webstore/downloads/dpejijbnadgcgmabkmcoajkgongfgnii-24.0.0.crx new file mode 100644 index 0000000..21e9b17 --- /dev/null +++ b/chrome/test/data/chromeos/app_mode/webstore/downloads/dpejijbnadgcgmabkmcoajkgongfgnii-24.0.0.crx Binary files differ
diff --git a/chrome/test/data/chromeos/app_mode/webstore/downloads/dpejijbnadgcgmabkmcoajkgongfgnii-3.0.0.crx b/chrome/test/data/chromeos/app_mode/webstore/downloads/dpejijbnadgcgmabkmcoajkgongfgnii-3.0.0.crx new file mode 100644 index 0000000..e6e689c1 --- /dev/null +++ b/chrome/test/data/chromeos/app_mode/webstore/downloads/dpejijbnadgcgmabkmcoajkgongfgnii-3.0.0.crx Binary files differ
diff --git a/chrome/test/data/chromeos/app_mode/webstore/downloads/emnbflhfbllbehnpjmjddklbkeeoaaeg-1.0.0.crx b/chrome/test/data/chromeos/app_mode/webstore/downloads/emnbflhfbllbehnpjmjddklbkeeoaaeg-1.0.0.crx new file mode 100644 index 0000000..72414cd --- /dev/null +++ b/chrome/test/data/chromeos/app_mode/webstore/downloads/emnbflhfbllbehnpjmjddklbkeeoaaeg-1.0.0.crx Binary files differ
diff --git a/chrome/test/data/chromeos/app_mode/webstore/downloads/fiehokkcgaojmbhfhlpiheggjhaedjoc-1.0.0.crx b/chrome/test/data/chromeos/app_mode/webstore/downloads/fiehokkcgaojmbhfhlpiheggjhaedjoc-1.0.0.crx deleted file mode 100644 index 4b90489..0000000 --- a/chrome/test/data/chromeos/app_mode/webstore/downloads/fiehokkcgaojmbhfhlpiheggjhaedjoc-1.0.0.crx +++ /dev/null Binary files differ
diff --git a/chrome/test/data/chromeos/app_mode/webstore/downloads/gdmgkkoghcihimdfoabkefdkccllcfea-1.0.0.crx b/chrome/test/data/chromeos/app_mode/webstore/downloads/gdmgkkoghcihimdfoabkefdkccllcfea-1.0.0.crx new file mode 100644 index 0000000..900823bb --- /dev/null +++ b/chrome/test/data/chromeos/app_mode/webstore/downloads/gdmgkkoghcihimdfoabkefdkccllcfea-1.0.0.crx Binary files differ
diff --git a/chrome/test/data/chromeos/app_mode/webstore/downloads/ihplaomghjbeafnpnjkhppmfpnmdihgd-1.0.0.crx b/chrome/test/data/chromeos/app_mode/webstore/downloads/ihplaomghjbeafnpnjkhppmfpnmdihgd-1.0.0.crx deleted file mode 100644 index 734efcc..0000000 --- a/chrome/test/data/chromeos/app_mode/webstore/downloads/ihplaomghjbeafnpnjkhppmfpnmdihgd-1.0.0.crx +++ /dev/null Binary files differ
diff --git a/chrome/test/data/chromeos/app_mode/webstore/downloads/imlgadjgphbjkaceoiapiephhgeofhic-1.0.0.crx b/chrome/test/data/chromeos/app_mode/webstore/downloads/imlgadjgphbjkaceoiapiephhgeofhic-1.0.0.crx deleted file mode 100644 index 23d0e6a3..0000000 --- a/chrome/test/data/chromeos/app_mode/webstore/downloads/imlgadjgphbjkaceoiapiephhgeofhic-1.0.0.crx +++ /dev/null Binary files differ
diff --git a/chrome/test/data/chromeos/app_mode/webstore/downloads/jkofhenkpndpdflehcjpcekgecjkpggg-1.0.0.crx b/chrome/test/data/chromeos/app_mode/webstore/downloads/jkofhenkpndpdflehcjpcekgecjkpggg-1.0.0.crx new file mode 100644 index 0000000..963703f --- /dev/null +++ b/chrome/test/data/chromeos/app_mode/webstore/downloads/jkofhenkpndpdflehcjpcekgecjkpggg-1.0.0.crx Binary files differ
diff --git a/chrome/test/data/extensions/platform_apps/web_view/shim/main.js b/chrome/test/data/extensions/platform_apps/web_view/shim/main.js index 553b54d2..9cc1005b 100644 --- a/chrome/test/data/extensions/platform_apps/web_view/shim/main.js +++ b/chrome/test/data/extensions/platform_apps/web_view/shim/main.js
@@ -1298,6 +1298,55 @@ document.body.appendChild(webview); } +// This test verifies that, in the case where the WebView is set up with a +// 'loadabort' handler that calls executeScript() with a script that sets +// the WebView's 'src' to an invalid URL, and the caller then calls +// executeScript() on that WebView with that same script (that sets 'src' +// to an invalid URL), that loadabort will get called in both cases (and +// that the browser does not crash during the second call to executeScript()). +function testExecuteScriptIsAbortedWhenWebViewSourceIsInvalid() { + var webview = document.createElement('webview'); + var abortCount = 0; + + webview.addEventListener('loadstop', loadDone); + webview.addEventListener('loadabort', loadAbort); + webview.addEventListener('exit', function(e) { + // We should not crash. + embedder.test.fail(); + }); + + function loadDone() { + window.console.log( + '2. WebView loaded \'about:blank\'. Now call \'executeScript()\''); + webview.executeScript( {code: '/* no op */'}, webviewStop); + } + + function webviewStop() { + window.console.log( + '3. Executing the script. Set webview.src to ' + + '\'http:\' (which is invalid and should cause an abort)'); + webview.src = 'http:'; + } + + function loadAbort() { + abortCount++; + if (abortCount == 1) { + window.console.log( + '4. In \'loadabort\' handler. Execute the script again, ' + + 'which should cause the \'loadabort\' handler to be called again ' + + '(the browser should NOT crash)'); + webview.executeScript( {code: '/* no op */'}, webviewStop); + } else { + window.console.log('5. In \'loadabort\' handler for 2nd time. Success!!'); + embedder.test.succeed(); + } + } + + window.console.log('1. Set webview.src to \'about:blank\''); + webview.src = 'about:blank'; + document.body.appendChild(webview); +} + // This test calls terminate() on guest after it has already been // terminated. This makes sure we ignore the call gracefully. function testTerminateAfterExit() { @@ -2951,6 +3000,8 @@ 'testExecuteScript': testExecuteScript, 'testExecuteScriptIsAbortedWhenWebViewSourceIsChanged': testExecuteScriptIsAbortedWhenWebViewSourceIsChanged, + 'testExecuteScriptIsAbortedWhenWebViewSourceIsInvalid': + testExecuteScriptIsAbortedWhenWebViewSourceIsInvalid, 'testTerminateAfterExit': testTerminateAfterExit, 'testAssignSrcAfterCrash': testAssignSrcAfterCrash, 'testNavOnConsecutiveSrcAttributeChanges':
diff --git a/chrome/test/data/password/password_autocomplete_off_test.html b/chrome/test/data/password/password_autocomplete_off_test.html index 902409ad..ae18625 100644 --- a/chrome/test/data/password/password_autocomplete_off_test.html +++ b/chrome/test/data/password/password_autocomplete_off_test.html
@@ -5,15 +5,10 @@ <title>Password Test Form</title> </head> <body> - <form id="loginform" action="google.com" method="post"> - <table cellspacing="3" cellpadding="5" border="0"> - <tbody> - <tr><td>Username:</td><td align="left"><input type="text" name="Email" id="Email" size="18" value=""></td></tr> - <tr><td>Password:</td><td align="left"><input autocomplete="off" type="password" name="Passwd" id="Passwd" size="18"></td></tr> - <tr><td></td><td align="left"><input type="submit" class="button" name="signIn" id="signIn" value="Sign in"></td></tr> - </tbody> - </table> + <form method="POST" action="done.html" id="loginform"> + <input type="text" id="username" autocomplete="off"> + <input type="password" id="password" autocomplete="off"> + <input type="submit" id="submit"> </form> </body> -</html> - +</html> \ No newline at end of file
diff --git a/chrome/test/data/safe_browsing/malware2.html b/chrome/test/data/safe_browsing/malware2.html new file mode 100644 index 0000000..27e22fd --- /dev/null +++ b/chrome/test/data/safe_browsing/malware2.html
@@ -0,0 +1,8 @@ +<html> +<body> +<iframe src="malware_iframe.html"></iframe> +<iframe src="http://example.com/cross_site_iframe.html"></iframe> +<img src="malware_image.png"> +<img src="http://example.com/image.png"> +</body> +</html>
diff --git a/chrome/test/data/webui/extensions/extension_item_test.js b/chrome/test/data/webui/extensions/extension_item_test.js index 2226972..d3b4f3ed 100644 --- a/chrome/test/data/webui/extensions/extension_item_test.js +++ b/chrome/test/data/webui/extensions/extension_item_test.js
@@ -137,7 +137,9 @@ setup(function() { PolymerTest.clearBody(); mockDelegate = new MockDelegate(); - item = new extensions.Item(extensionData, mockDelegate); + item = new extensions.Item(); + item.set('data', extensionData); + item.set('delegate', mockDelegate); document.body.appendChild(item); });
diff --git a/chrome/test/data/webui/extensions/extension_manager_test.js b/chrome/test/data/webui/extensions/extension_manager_test.js index aadf325d..06732593 100644 --- a/chrome/test/data/webui/extensions/extension_manager_test.js +++ b/chrome/test/data/webui/extensions/extension_manager_test.js
@@ -20,82 +20,62 @@ }); test(assert(TestNames.SplitSections), function() { - var testVisible = extension_test_util.testVisible.bind(null, manager); - // All sections and headers should be visible. - testVisible('#extensions-header', true); - testVisible('#extensions-list', true); - testVisible('#apps-header', true); - testVisible('#apps-list', true); - testVisible('#websites-header', true); - testVisible('#websites-list', true); + var testManagerElementVisible = + extension_test_util.testVisible.bind(null, manager); + // All sections should be visible. + testManagerElementVisible('#extensions-list', true); + testManagerElementVisible('#apps-list', true); + testManagerElementVisible('#websites-list', true); - var findItemWithName = function(name) { - var result; - manager.forEachItem(function(item) { - if (item.data.name == name) { - expectFalse(!!result, - 'Found two items with the same name: ' + name); - result = item; - } + var sectionHasItemWithName = function(section, name) { + return !!manager[section].find(function(el) { + return el.name == name; }); - expectTrue(!!result); - return result; }; - // Find each type of extension. Each should be present, visible, and - // sorted in the correct section. - var extension = findItemWithName('My extension 1'); - var selector = '#' + extension.data.id; - testVisible(selector, true) - expectTrue(!!manager.$$('#extensions-list').querySelector(selector)); + expectEquals(manager.extensions, manager.$['extensions-list'].items); + expectEquals(manager.apps, manager.$['apps-list'].items); + expectEquals(manager.websites, manager.$['websites-list'].items); - var platform_app = - findItemWithName('Platform App Test: minimal platform app'); - selector = '#' + platform_app.data.id - testVisible(selector, true) - expectTrue(!!manager.$$('#apps-list').querySelector(selector)); - - var hosted_app = findItemWithName('hosted_app'); - selector = '#' + hosted_app.data.id; - testVisible(selector, true) - expectTrue(!!manager.$$('#websites-list').querySelector(selector)); - - var packaged_app = findItemWithName('Packaged App Test'); - selector = '#' + packaged_app.data.id; - testVisible(selector, true) - expectTrue(!!manager.$$('#websites-list').querySelector(selector)); + // We really just have to test for existence of the items within the + // given subsection of the manager, since they are bound to the iron + // list with Polymer (and we kind of have to trust that Polymer works). + expectTrue(sectionHasItemWithName('extensions', 'My extension 1')); + expectTrue(sectionHasItemWithName( + 'apps', 'Platform App Test: minimal platform app')); + expectTrue(sectionHasItemWithName('websites', 'hosted_app')); + expectTrue(sectionHasItemWithName('websites', 'Packaged App Test')); }); test(assert(TestNames.ItemOrder), function() { - var extensionsSection = manager.$['extensions-list']; var service = extensions.Service.getInstance(); - expectEquals(0, extensionsSection.children.length); + expectEquals(0, manager.extensions.length); var alphaFromStore = extension_test_util.createExtensionInfo( {location: 'FROM_STORE', name: 'Alpha', id: 'a'.repeat(32)}); manager.addItem(alphaFromStore, service); - expectEquals(1, extensionsSection.children.length); - expectEquals(alphaFromStore.id, extensionsSection.children[0].id); + expectEquals(1, manager.extensions.length); + expectEquals(alphaFromStore.id, manager.extensions[0].id); // Unpacked extensions come first. var betaUnpacked = extension_test_util.createExtensionInfo( {location: 'UNPACKED', name: 'Beta', id: 'b'.repeat(32)}); manager.addItem(betaUnpacked, service); - expectEquals(2, extensionsSection.children.length); - expectEquals(betaUnpacked.id, extensionsSection.children[0].id); - expectEquals(alphaFromStore.id, extensionsSection.children[1].id); + expectEquals(2, manager.extensions.length); + expectEquals(betaUnpacked.id, manager.extensions[0].id); + expectEquals(alphaFromStore.id, manager.extensions[1].id); // Extensions from the same location are sorted by name. var gammaUnpacked = extension_test_util.createExtensionInfo( {location: 'UNPACKED', name: 'Gamma', id: 'c'.repeat(32)}); manager.addItem(gammaUnpacked, service); - expectEquals(3, extensionsSection.children.length); - expectEquals(betaUnpacked.id, extensionsSection.children[0].id); - expectEquals(gammaUnpacked.id, extensionsSection.children[1].id); - expectEquals(alphaFromStore.id, extensionsSection.children[2].id); + expectEquals(3, manager.extensions.length); + expectEquals(betaUnpacked.id, manager.extensions[0].id); + expectEquals(gammaUnpacked.id, manager.extensions[1].id); + expectEquals(alphaFromStore.id, manager.extensions[2].id); // The name-sort should be case-insensitive, and should fall back on // id. @@ -109,13 +89,13 @@ manager.addItem(AaFromStore, service); manager.addItem(aAFromStore, service); - expectEquals(6, extensionsSection.children.length); - expectEquals(betaUnpacked.id, extensionsSection.children[0].id); - expectEquals(gammaUnpacked.id, extensionsSection.children[1].id); - expectEquals(aaFromStore.id, extensionsSection.children[2].id); - expectEquals(AaFromStore.id, extensionsSection.children[3].id); - expectEquals(aAFromStore.id, extensionsSection.children[4].id); - expectEquals(alphaFromStore.id, extensionsSection.children[5].id); + expectEquals(6, manager.extensions.length); + expectEquals(betaUnpacked.id, manager.extensions[0].id); + expectEquals(gammaUnpacked.id, manager.extensions[1].id); + expectEquals(aaFromStore.id, manager.extensions[2].id); + expectEquals(AaFromStore.id, manager.extensions[3].id); + expectEquals(aAFromStore.id, manager.extensions[4].id); + expectEquals(alphaFromStore.id, manager.extensions[5].id); }); }); }
diff --git a/chrome/test/data/webui/extensions/extension_service_test.js b/chrome/test/data/webui/extensions/extension_service_test.js index db2a867..a578c07 100644 --- a/chrome/test/data/webui/extensions/extension_service_test.js +++ b/chrome/test/data/webui/extensions/extension_service_test.js
@@ -83,6 +83,13 @@ /** @type {extensions.Manager} */ var manager; + var getItemData = function(id) { + var elMatches = function(el) { return el.id == id; }; + return manager.extensions.find(elMatches) || + manager.apps.find(elMatches) || + manager.websites.find(elMatches); + }; + suiteSetup(function() { return PolymerTest.importHtml('chrome://extensions/service.html'); }); @@ -94,33 +101,39 @@ }); test(assert(TestNames.EnableAndDisable), function(done) { - var item = manager.getItem(kExtensionId); + var item = getItemData(kExtensionId); assertTrue(!!item); expectEquals(kExtensionId, item.id); - expectEquals('My extension 1', item.data.name); - expectEquals(ExtensionState.ENABLED, item.data.state); + expectEquals('My extension 1', item.name); + expectEquals(ExtensionState.ENABLED, item.state); var disabledListener = new ItemChangedListener(kExtensionId, EventType.UNLOADED); service.setItemEnabled(kExtensionId, false); disabledListener.onUpdate.then(function() { - expectEquals(ExtensionState.DISABLED, item.data.state); + // Note: we need to re-get the item since the object in the manager's + // collection was replaced, rather than updated. + var item = getItemData(kExtensionId); + assertTrue(!!item); + expectEquals(ExtensionState.DISABLED, item.state); enabledListener = new ItemChangedListener(kExtensionId, EventType.LOADED); service.setItemEnabled(kExtensionId, true); return enabledListener.onUpdate; }).then(function() { - expectEquals(ExtensionState.ENABLED, item.data.state); + var item = getItemData(kExtensionId); + assertTrue(!!item); + expectEquals(ExtensionState.ENABLED, item.state); done(); }); }); test(assert(TestNames.ToggleIncognitoMode), function(done) { - var item = manager.getItem(kExtensionId); + var item = getItemData(kExtensionId); assertTrue(!!item); - expectTrue(item.data.incognitoAccess.isEnabled); - expectFalse(item.data.incognitoAccess.isActive); + expectTrue(item.incognitoAccess.isEnabled); + expectFalse(item.incognitoAccess.isActive); var incognitoListener = new ItemChangedListener(kExtensionId, EventType.LOADED); @@ -128,7 +141,9 @@ service.setItemAllowedIncognito(kExtensionId, true); }); incognitoListener.onUpdate.then(function() { - expectTrue(item.data.incognitoAccess.isActive); + var item = getItemData(kExtensionId); + assertTrue(!!item); + expectTrue(item.incognitoAccess.isActive); var disabledIncognitoListener = new ItemChangedListener(kExtensionId, EventType.LOADED); @@ -137,13 +152,15 @@ }); return disabledIncognitoListener.onUpdate; }).then(function() { - expectFalse(item.data.incognitoAccess.isActive); + var item = getItemData(kExtensionId); + assertTrue(!!item); + expectFalse(item.incognitoAccess.isActive); done(); }); }); test(assert(TestNames.Uninstall), function(done) { - var item = manager.getItem(kExtensionId); + var item = getItemData(kExtensionId); assertTrue(!!item); var uninstallListener = new ItemChangedListener(kExtensionId, EventType.UNINSTALLED); @@ -151,27 +168,25 @@ service.deleteItem(kExtensionId); }); uninstallListener.onUpdate.then(function() { - expectFalse(!!manager.getItem(kExtensionId)); + expectFalse(!!getItemData(kExtensionId)); done(); }); }); test(assert(TestNames.ProfileSettings), function(done) { - var item = manager.getItem(kExtensionId); - assertTrue(!!item); - expectFalse(item.inDevMode); + expectFalse(manager.inDevMode); var profileListener = new ProfileChangedListener(); service.setProfileInDevMode(true); profileListener.onUpdate.then(function() { - expectTrue(item.inDevMode); + expectTrue(manager.inDevMode); var noDevModeProfileListener = new ProfileChangedListener(); service.setProfileInDevMode(false); return noDevModeProfileListener.onUpdate; }).then(function() { - expectFalse(item.inDevMode); + expectFalse(manager.inDevMode); done(); }); });
diff --git a/chrome/test/data/webui/media_router/media_router_container_tests.js b/chrome/test/data/webui/media_router/media_router_container_tests.js index ccdb963..abffbc9 100644 --- a/chrome/test/data/webui/media_router/media_router_container_tests.js +++ b/chrome/test/data/webui/media_router/media_router_container_tests.js
@@ -88,11 +88,6 @@ assertEquals(visible, elementVisible); }; - // Checks whether |element| is hidden. - var checkElementHidden = function(hidden, element) { - assertEquals(hidden, element.hidden); - }; - // Checks whether |expected| and the text in the |element| are equal. var checkElementText = function(expected, element) { assertEquals(expected.trim(), element.textContent.trim()); @@ -142,13 +137,13 @@ // Note: These need to be in-order by name to prevent shuffling. // Sorting of sinks by name is tested separately. fakeSinkList = [ - new media_router.Sink('sink id 1', 'Sink 1', + new media_router.Sink('sink id 1', 'Sink 1', null, media_router.SinkIconType.CAST, media_router.SinkStatus.ACTIVE, [1, 2, 3]), - new media_router.Sink('sink id 2', 'Sink 2', + new media_router.Sink('sink id 2', 'Sink 2', null, media_router.SinkIconType.CAST, media_router.SinkStatus.ACTIVE, [1, 2, 3]), - new media_router.Sink('sink id 3', 'Sink 3', + new media_router.Sink('sink id 3', 'Sink 3', null, media_router.SinkIconType.CAST, media_router.SinkStatus.PENDING, [1, 2, 3]), ]; @@ -313,32 +308,47 @@ // Tests the text shown for the sink list. test('initial sink list route text', function(done) { - container.allSinks = fakeSinkList; - container.routeList = fakeRouteList; + // Sink 1 - no sink description, no route -> no subtext + // Sink 2 - sink description, no route -> subtext = sink description + // Sink 3 - no sink description, route -> subtext = route description + // Sink 4 - sink description, route -> subtext = route description + container.allSinks = [ + new media_router.Sink('sink id 1', 'Sink 1', null, + media_router.SinkIconType.CAST, + media_router.SinkStatus.ACTIVE, [1, 2, 3]), + new media_router.Sink('sink id 2', 'Sink 2', 'Sink 2 description', + media_router.SinkIconType.CAST, + media_router.SinkStatus.ACTIVE, [1, 2, 3]), + new media_router.Sink('sink id 3', 'Sink 3', null, + media_router.SinkIconType.CAST, + media_router.SinkStatus.PENDING, [1, 2, 3]), + new media_router.Sink('sink id 4', 'Sink 4', 'Sink 4 description', + media_router.SinkIconType.CAST, + media_router.SinkStatus.PENDING, [1, 2, 3]) + ]; + + container.routeList = [ + new media_router.Route('id 3', 'sink id 3', 'Title 3', 0, true), + new media_router.Route('id 4', 'sink id 4', 'Title 4', 1, false), + ]; setTimeout(function() { - var routeList = - container.$['sink-list'].querySelectorAll('.route'); - assertEquals(fakeSinkList.length, routeList.length); - checkElementText(fakeRouteList[0].description, routeList[0]); - checkElementText(fakeRouteList[1].description, routeList[1]); - checkElementText('', routeList[2]); - done(); - }); - }); + var sinkSubtextList = + container.$['sink-list'].querySelectorAll('.sink-subtext'); - // Tests the visibility of routes in the sink list. - test('initial route visibility', function(done) { - container.allSinks = fakeSinkList; - container.routeList = fakeRouteList; + // There will only be 3 sink subtext entries, because Sink 1 does not + // have any subtext. + assertEquals(3, sinkSubtextList.length); - setTimeout(function() { - var routeList = - container.$['sink-list'].querySelectorAll('.route'); + checkElementText(container.allSinks[1].description, + sinkSubtextList[0]); - checkElementHidden(false, routeList[0]); - checkElementHidden(false, routeList[1]); - checkElementHidden(true, routeList[2]); + // Route description overrides sink description for subtext. + checkElementText(container.routeList[0].description, + sinkSubtextList[1]); + + checkElementText(container.routeList[1].description, + sinkSubtextList[2]); done(); }); }); @@ -498,13 +508,13 @@ // route. test('sink list filtering based on initial cast mode', function(done) { var newSinks = [ - new media_router.Sink('sink id 10', 'Sink 10', + new media_router.Sink('sink id 10', 'Sink 10', null, media_router.SinkIconType.CAST, media_router.SinkStatus.ACTIVE, [2, 3]), - new media_router.Sink('sink id 20', 'Sink 20', + new media_router.Sink('sink id 20', 'Sink 20', null, media_router.SinkIconType.CAST, media_router.SinkStatus.ACTIVE, [1, 2, 3]), - new media_router.Sink('sink id 30', 'Sink 30', + new media_router.Sink('sink id 30', 'Sink 30', null, media_router.SinkIconType.CAST, media_router.SinkStatus.PENDING, [2, 3]), ]; @@ -568,22 +578,22 @@ // when shown to the user. test('sinks are shown sorted by name', function(done) { var outOfOrderSinks = [ - new media_router.Sink('6543', 'Sleepy', + new media_router.Sink('6543', 'Sleepy', null, media_router.SinkIconType.CAST, media_router.SinkStatus.ACTIVE, [1]), - new media_router.Sink('543', 'Happy', + new media_router.Sink('543', 'Happy', null, media_router.SinkIconType.CAST, media_router.SinkStatus.ACTIVE, [1]), - new media_router.Sink('43', 'Bashful', + new media_router.Sink('43', 'Bashful', null, media_router.SinkIconType.CAST, media_router.SinkStatus.ACTIVE, [1]), - new media_router.Sink('2', 'George', + new media_router.Sink('2', 'George', null, media_router.SinkIconType.CAST_AUDIO, media_router.SinkStatus.ACTIVE, [1]), - new media_router.Sink('1', 'George', + new media_router.Sink('1', 'George', null, media_router.SinkIconType.CAST, media_router.SinkStatus.ACTIVE, [1]), - new media_router.Sink('3', 'George', + new media_router.Sink('3', 'George', null, media_router.SinkIconType.HANGOUT, media_router.SinkStatus.ACTIVE, [1]), ];
diff --git a/chrome/test/data/webui/settings/reset_page_test.js b/chrome/test/data/webui/settings/reset_page_test.js index d1a0695c..d2576638 100644 --- a/chrome/test/data/webui/settings/reset_page_test.js +++ b/chrome/test/data/webui/settings/reset_page_test.js
@@ -41,9 +41,13 @@ document.body.appendChild(resetPage); }); - // Tests that the reset profile dialog opens and closes correctly, and - // that chrome.send calls are propagated as expected. - test(TestNames.ResetProfileDialogOpenClose, function() { + + /** + * @param {string} closeButtonId The ID of the button that closes the + * dialog. + * @return {!Promise} + */ + function testOpenCloseResetProfileDialog(closeButtonId) { var onShowResetProfileDialogCalled = whenChromeSendCalled( 'onShowResetProfileDialog'); var onHideResetProfileDialogCalled = whenChromeSendCalled( @@ -57,13 +61,24 @@ dialog.addEventListener('iron-overlay-closed', resolve); }); - MockInteractions.tap(dialog.$.cancel); + MockInteractions.tap(dialog.$[closeButtonId]); return Promise.all([ onShowResetProfileDialogCalled, onHideResetProfileDialogCalled, onDialogClosed ]); + } + + // Tests that the reset profile dialog opens and closes correctly and that + // chrome.send calls are propagated as expected. + test(TestNames.ResetProfileDialogOpenClose, function() { + return Promise.all([ + // Test case where the 'cancel' button is clicked. + testOpenCloseResetProfileDialog('cancel'), + // Test case where the 'close' button is clicked. + testOpenCloseResetProfileDialog('close') + ]); }); // Tests that when resetting the profile is requested chrome.send calls @@ -78,9 +93,12 @@ }); if (cr.isChromeOS) { - // Tests that the powerwash dialog opens and closes correctly, and - // that chrome.send calls are propagated as expected. - test(TestNames.PowerwashDialogOpenClose, function() { + /** + * @param {string} closeButtonId The ID of the button that closes the + * dialog. + * @return {!Promise} + */ + function testOpenClosePowerwashDialog(closeButtonId) { var onPowerwashDialogShowCalled = whenChromeSendCalled( 'onPowerwashDialogShow'); @@ -92,8 +110,19 @@ dialog.addEventListener('iron-overlay-closed', resolve); }); - MockInteractions.tap(dialog.$.cancel); + MockInteractions.tap(dialog.$[closeButtonId]); return Promise.all([onPowerwashDialogShowCalled, onDialogClosed]); + } + + // Tests that the powerwash dialog opens and closes correctly, and + // that chrome.send calls are propagated as expected. + test(TestNames.PowerwashDialogOpenClose, function() { + return Promise.all([ + // Test case where the 'cancel' button is clicked. + testOpenClosePowerwashDialog('cancel'), + // Test case where the 'close' button is clicked. + testOpenClosePowerwashDialog('close') + ]); }); // Tests that when powerwash is requested chrome.send calls are
diff --git a/chrome/utility/importer/importer_creator.cc b/chrome/utility/importer/importer_creator.cc index f260f8c5..48c7c0c 100644 --- a/chrome/utility/importer/importer_creator.cc +++ b/chrome/utility/importer/importer_creator.cc
@@ -23,7 +23,7 @@ namespace importer { -Importer* CreateImporterByType(ImporterType type) { +scoped_refptr<Importer> CreateImporterByType(ImporterType type) { switch (type) { #if defined(OS_WIN) case TYPE_IE: @@ -44,7 +44,7 @@ #endif default: NOTREACHED(); - return NULL; + return nullptr; } }
diff --git a/chrome/utility/importer/importer_creator.h b/chrome/utility/importer/importer_creator.h index 40e0de5..dc61cd1 100644 --- a/chrome/utility/importer/importer_creator.h +++ b/chrome/utility/importer/importer_creator.h
@@ -5,6 +5,7 @@ #ifndef CHROME_UTILITY_IMPORTER_IMPORTER_CREATOR_H_ #define CHROME_UTILITY_IMPORTER_IMPORTER_CREATOR_H_ +#include "base/memory/ref_counted.h" #include "chrome/common/importer/importer_type.h" class Importer; @@ -12,7 +13,7 @@ namespace importer { // Creates an Importer of the specified |type|. -Importer* CreateImporterByType(ImporterType type); +scoped_refptr<Importer> CreateImporterByType(ImporterType type); } // namespace importer
diff --git a/chromeos/CHROMEOS_LKGM b/chromeos/CHROMEOS_LKGM index b98d630..8d7cfda 100644 --- a/chromeos/CHROMEOS_LKGM +++ b/chromeos/CHROMEOS_LKGM
@@ -1 +1 @@ -7692.0.0 \ No newline at end of file +7703.0.0 \ No newline at end of file
diff --git a/chromeos/dbus/power_policy_controller.cc b/chromeos/dbus/power_policy_controller.cc index e934275..336b72e 100644 --- a/chromeos/dbus/power_policy_controller.cc +++ b/chromeos/dbus/power_policy_controller.cc
@@ -246,6 +246,11 @@ return AddWakeLockInternal(WakeLock::TYPE_SCREEN, reason, description); } +int PowerPolicyController::AddDimWakeLock(WakeLockReason reason, + const std::string& description) { + return AddWakeLockInternal(WakeLock::TYPE_DIM, reason, description); +} + int PowerPolicyController::AddSystemWakeLock(WakeLockReason reason, const std::string& description) { return AddWakeLockInternal(WakeLock::TYPE_SYSTEM, reason, description); @@ -301,6 +306,7 @@ causes = kPrefsReason; bool have_screen_wake_locks = false; + bool have_dim_wake_locks = false; bool have_system_wake_locks = false; for (const auto& it : wake_locks_) { // Skip audio and video locks that should be ignored due to policy. @@ -312,6 +318,9 @@ case WakeLock::TYPE_SCREEN: have_screen_wake_locks = true; break; + case WakeLock::TYPE_DIM: + have_dim_wake_locks = true; + break; case WakeLock::TYPE_SYSTEM: have_system_wake_locks = true; break; @@ -328,7 +337,14 @@ policy.mutable_battery_delays()->set_screen_lock_ms(0); } - if (have_screen_wake_locks || have_system_wake_locks) { + if (honor_screen_wake_locks_ && have_dim_wake_locks) { + policy.mutable_ac_delays()->set_screen_off_ms(0); + policy.mutable_ac_delays()->set_screen_lock_ms(0); + policy.mutable_battery_delays()->set_screen_off_ms(0); + policy.mutable_battery_delays()->set_screen_lock_ms(0); + } + + if (have_screen_wake_locks || have_dim_wake_locks || have_system_wake_locks) { if (!policy.has_ac_idle_action() || policy.ac_idle_action() == power_manager::PowerManagementPolicy_Action_SUSPEND) { policy.set_ac_idle_action(
diff --git a/chromeos/dbus/power_policy_controller.h b/chromeos/dbus/power_policy_controller.h index 5437cd4..ec0ae2e2 100644 --- a/chromeos/dbus/power_policy_controller.h +++ b/chromeos/dbus/power_policy_controller.h
@@ -98,11 +98,13 @@ // and sends an updated policy. |description| is a human-readable description // of the reason the lock was created. Returns a unique ID that can be passed // to RemoveWakeLock() later. + // See the comment above WakeLock::Type for descriptions of the lock types. int AddScreenWakeLock(WakeLockReason reason, const std::string& description); + int AddDimWakeLock(WakeLockReason reason, const std::string& description); int AddSystemWakeLock(WakeLockReason reason, const std::string& description); - // Unregisters a request previously created via AddScreenWakeLock() or - // AddSystemWakeLock() and sends an updated policy. + // Unregisters a request previously created via an Add*WakeLock() call + // and sends an updated policy. void RemoveWakeLock(int id); // PowerManagerClient::Observer implementation: @@ -114,11 +116,14 @@ friend class PowerPrefsTest; - // Details about a wake lock added via AddScreenWakeLock() or - // AddSystemWakeLock(). + // Details about a wake lock added via Add*WakeLock(). + // SCREEN and DIM will keep the screen on and prevent it from locking. + // SCREEN will also prevent it from dimming. SYSTEM will prevent idle + // suspends, but the screen will turn off and lock normally. struct WakeLock { enum Type { TYPE_SCREEN, + TYPE_DIM, TYPE_SYSTEM, }; @@ -153,11 +158,11 @@ // to details about the request. WakeLockMap wake_locks_; - // Should TYPE_SCREEN entries in |wake_locks_| be honored? If false, screen - // wake locks are just treated as TYPE_SYSTEM instead. + // Should TYPE_SCREEN or TYPE_DIM entries in |wake_locks_| be honored? + // If false, screen wake locks are just treated as TYPE_SYSTEM instead. bool honor_screen_wake_locks_; - // Next ID to be used by AddScreenWakeLock() or AddSystemWakeLock(). + // Next ID to be used by an Add*WakeLock() request. int next_wake_lock_id_; DISALLOW_COPY_AND_ASSIGN(PowerPolicyController);
diff --git a/chromeos/dbus/power_policy_controller_unittest.cc b/chromeos/dbus/power_policy_controller_unittest.cc index 3352f21..7c6de2e 100644 --- a/chromeos/dbus/power_policy_controller_unittest.cc +++ b/chromeos/dbus/power_policy_controller_unittest.cc
@@ -163,43 +163,111 @@ } TEST_F(PowerPolicyControllerTest, WakeLocks) { + // If our highest lock type is system, we only worry about + // the idle action. const char kSystemWakeLockReason[] = "system"; + power_manager::PowerManagementPolicy expected_policy_system; + expected_policy_system.set_ac_idle_action( + power_manager::PowerManagementPolicy_Action_DO_NOTHING); + expected_policy_system.set_battery_idle_action( + power_manager::PowerManagementPolicy_Action_DO_NOTHING); + + // The dim lock type prevents the screen from turning off or + // locking, and we won't have an idle action. + const char kDimWakeLockReason[] = "dim"; + power_manager::PowerManagementPolicy expected_policy_dim; + expected_policy_dim.set_ac_idle_action( + power_manager::PowerManagementPolicy_Action_DO_NOTHING); + expected_policy_dim.set_battery_idle_action( + power_manager::PowerManagementPolicy_Action_DO_NOTHING); + expected_policy_dim.mutable_ac_delays()->set_screen_off_ms(0); + expected_policy_dim.mutable_ac_delays()->set_screen_lock_ms(0); + expected_policy_dim.mutable_battery_delays()->set_screen_off_ms(0); + expected_policy_dim.mutable_battery_delays()->set_screen_lock_ms(0); + + // The screen lock keeps the screen bright. We won't turn off, + // lock the screen or do anything for idle. + const char kScreenWakeLockReason[] = "screen"; + power_manager::PowerManagementPolicy expected_policy_screen; + expected_policy_screen.set_ac_idle_action( + power_manager::PowerManagementPolicy_Action_DO_NOTHING); + expected_policy_screen.set_battery_idle_action( + power_manager::PowerManagementPolicy_Action_DO_NOTHING); + expected_policy_screen.mutable_ac_delays()->set_screen_dim_ms(0); + expected_policy_screen.mutable_ac_delays()->set_screen_off_ms(0); + expected_policy_screen.mutable_ac_delays()->set_screen_lock_ms(0); + expected_policy_screen.mutable_battery_delays()->set_screen_dim_ms(0); + expected_policy_screen.mutable_battery_delays()->set_screen_off_ms(0); + expected_policy_screen.mutable_battery_delays()->set_screen_lock_ms(0); + + // With no locks our policy should be the default. + power_manager::PowerManagementPolicy expected_policy_none; + + // There are eight different possibilities for combinations of + // different locks, as there are three types. We will go through + // each possibility by adding or removing one lock. + + // System lock only. const int system_id = policy_controller_->AddSystemWakeLock( PowerPolicyController::REASON_OTHER, kSystemWakeLockReason); - power_manager::PowerManagementPolicy expected_policy; - expected_policy.set_ac_idle_action( - power_manager::PowerManagementPolicy_Action_DO_NOTHING); - expected_policy.set_battery_idle_action( - power_manager::PowerManagementPolicy_Action_DO_NOTHING); - expected_policy.set_reason(kSystemWakeLockReason); - EXPECT_EQ(PowerPolicyController::GetPolicyDebugString(expected_policy), + expected_policy_system.set_reason(kSystemWakeLockReason); + EXPECT_EQ(PowerPolicyController::GetPolicyDebugString(expected_policy_system), PowerPolicyController::GetPolicyDebugString( fake_power_client_->policy())); - const char kScreenWakeLockReason[] = "screen"; + // System and dim locks. + const int dim_id = policy_controller_->AddDimWakeLock( + PowerPolicyController::REASON_OTHER, kDimWakeLockReason); + expected_policy_dim.set_reason(std::string(kSystemWakeLockReason) + ", " + + kDimWakeLockReason); + EXPECT_EQ(PowerPolicyController::GetPolicyDebugString(expected_policy_dim), + PowerPolicyController::GetPolicyDebugString( + fake_power_client_->policy())); + + // Dim lock only. + policy_controller_->RemoveWakeLock(system_id); + expected_policy_dim.set_reason(kDimWakeLockReason); + EXPECT_EQ(PowerPolicyController::GetPolicyDebugString(expected_policy_dim), + PowerPolicyController::GetPolicyDebugString( + fake_power_client_->policy())); + + // Dim and screen locks. const int screen_id = policy_controller_->AddScreenWakeLock( PowerPolicyController::REASON_OTHER, kScreenWakeLockReason); - expected_policy.mutable_ac_delays()->set_screen_dim_ms(0); - expected_policy.mutable_ac_delays()->set_screen_off_ms(0); - expected_policy.mutable_ac_delays()->set_screen_lock_ms(0); - expected_policy.mutable_battery_delays()->set_screen_dim_ms(0); - expected_policy.mutable_battery_delays()->set_screen_off_ms(0); - expected_policy.mutable_battery_delays()->set_screen_lock_ms(0); - expected_policy.set_reason(std::string(kSystemWakeLockReason) + ", " + - kScreenWakeLockReason); - EXPECT_EQ(PowerPolicyController::GetPolicyDebugString(expected_policy), + expected_policy_screen.set_reason(std::string(kDimWakeLockReason) + ", " + + kScreenWakeLockReason); + EXPECT_EQ(PowerPolicyController::GetPolicyDebugString(expected_policy_screen), PowerPolicyController::GetPolicyDebugString( fake_power_client_->policy())); - policy_controller_->RemoveWakeLock(system_id); - expected_policy.set_reason(kScreenWakeLockReason); - EXPECT_EQ(PowerPolicyController::GetPolicyDebugString(expected_policy), + // System, dim and screen locks. + const int system_id_2 = policy_controller_->AddSystemWakeLock( + PowerPolicyController::REASON_OTHER, kSystemWakeLockReason); + expected_policy_screen.set_reason(std::string(kDimWakeLockReason) + ", " + + std::string(kScreenWakeLockReason) + ", " + + kSystemWakeLockReason); + EXPECT_EQ(PowerPolicyController::GetPolicyDebugString(expected_policy_screen), PowerPolicyController::GetPolicyDebugString( fake_power_client_->policy())); + // System and screen locks. + policy_controller_->RemoveWakeLock(dim_id); + expected_policy_screen.set_reason(std::string(kScreenWakeLockReason) + ", " + + kSystemWakeLockReason); + EXPECT_EQ(PowerPolicyController::GetPolicyDebugString(expected_policy_screen), + PowerPolicyController::GetPolicyDebugString( + fake_power_client_->policy())); + + // Screen lock only. + policy_controller_->RemoveWakeLock(system_id_2); + expected_policy_screen.set_reason(kScreenWakeLockReason); + EXPECT_EQ(PowerPolicyController::GetPolicyDebugString(expected_policy_screen), + PowerPolicyController::GetPolicyDebugString( + fake_power_client_->policy())); + + // No locks. policy_controller_->RemoveWakeLock(screen_id); - expected_policy.Clear(); - EXPECT_EQ(PowerPolicyController::GetPolicyDebugString(expected_policy), + EXPECT_EQ(PowerPolicyController::GetPolicyDebugString(expected_policy_none), PowerPolicyController::GetPolicyDebugString( fake_power_client_->policy())); }
diff --git a/components/arc.gypi b/components/arc.gypi index 7ad1264..7105b7b 100644 --- a/components/arc.gypi +++ b/components/arc.gypi
@@ -32,5 +32,21 @@ 'arc/common/arc_notification_types.cc', ], }, + { + # GN version: //components/arc_test_support + 'target_name': 'arc_test_support', + 'type': 'static_library', + 'include_dirs': [ + '..', + ], + 'dependencies': [ + '../base/base.gyp:base', + 'arc', + ], + 'sources': [ + 'arc/test/fake_arc_bridge_service.cc', + 'arc/test/fake_arc_bridge_service.h', + ], + }, ], }
diff --git a/components/arc/BUILD.gn b/components/arc/BUILD.gn index fe11655..6ab92706 100644 --- a/components/arc/BUILD.gn +++ b/components/arc/BUILD.gn
@@ -20,6 +20,19 @@ ] } +static_library("arc_test_support") { + testonly = true + sources = [ + "test/fake_arc_bridge_service.cc", + "test/fake_arc_bridge_service.h", + ] + + deps = [ + ":arc", + "//base", + ] +} + source_set("unit_tests") { testonly = true sources = [
diff --git a/components/arc/test/fake_arc_bridge_service.cc b/components/arc/test/fake_arc_bridge_service.cc new file mode 100644 index 0000000..ace3acf --- /dev/null +++ b/components/arc/test/fake_arc_bridge_service.cc
@@ -0,0 +1,145 @@ +// 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. + +#include "components/arc/test/fake_arc_bridge_service.h" + +#include "base/files/file_path.h" +#include "base/files/file_util.h" +#include "base/path_service.h" + +namespace arc { + +FakeArcBridgeService::FakeArcBridgeService() { +} + +FakeArcBridgeService::~FakeArcBridgeService() { + if (state() != State::STOPPED) { + SetState(State::STOPPED); + } +} + +void FakeArcBridgeService::DetectAvailability() { +} + +void FakeArcBridgeService::HandleStartup() { +} + +void FakeArcBridgeService::Shutdown() { +} + +bool FakeArcBridgeService::RegisterInputDevice(const std::string& name, + const std::string& device_type, + base::ScopedFD fd) { + return true; +} + +bool FakeArcBridgeService::SendNotificationEventToAndroid( + const std::string& key, + ArcNotificationEvent event) { + return true; +} + +bool FakeArcBridgeService::RefreshAppList() { + ++refresh_app_list_count_; + return true; +} + +bool FakeArcBridgeService::LaunchApp(const std::string& package, + const std::string& activity) { + launch_requests_.push_back(new Request(package, activity)); + return true; +} + +bool FakeArcBridgeService::RequestAppIcon(const std::string& package, + const std::string& activity, + ScaleFactor scale_factor) { + icon_requests_.push_back(new IconRequest(package, activity, scale_factor)); + return true; +} + +void FakeArcBridgeService::SetReady() { + SetState(State::READY); +} + +void FakeArcBridgeService::SetStopped() { + SetState(State::STOPPED); +} + +bool FakeArcBridgeService::HasObserver(const Observer* observer) { + return observer_list().HasObserver(observer); +} + +bool FakeArcBridgeService::HasAppObserver(const AppObserver* observer) { + return app_observer_list().HasObserver(observer); +} + +void FakeArcBridgeService::SendRefreshAppList( + const std::vector<AppInfo>& apps) { + FOR_EACH_OBSERVER(AppObserver, app_observer_list(), OnAppListRefreshed(apps)); +} + +bool FakeArcBridgeService::GenerateAndSendIcon( + const AppInfo& app, + ScaleFactor scale_factor, + std::string* png_data_as_string) { + CHECK(png_data_as_string != nullptr); + std::string icon_file_name; + switch(scale_factor) { + case SCALE_FACTOR_100P: + icon_file_name = "icon_100p.png"; + break; + case SCALE_FACTOR_125P: + icon_file_name = "icon_125p.png"; + break; + case SCALE_FACTOR_133P: + icon_file_name = "icon_133p.png"; + break; + case SCALE_FACTOR_140P: + icon_file_name = "icon_140p.png"; + break; + case SCALE_FACTOR_150P: + icon_file_name = "icon_150p.png"; + break; + case SCALE_FACTOR_180P: + icon_file_name = "icon_180p.png"; + break; + case SCALE_FACTOR_200P: + icon_file_name = "icon_200p.png"; + break; + case SCALE_FACTOR_250P: + icon_file_name = "icon_250p.png"; + break; + case SCALE_FACTOR_300P: + icon_file_name = "icon_300p.png"; + break; + default: + NOTREACHED(); + return false; + } + + base::FilePath base_path; + CHECK(PathService::Get(base::DIR_SOURCE_ROOT, &base_path)); + base::FilePath icon_file_path = base_path + .AppendASCII("components") + .AppendASCII("test") + .AppendASCII("data") + .AppendASCII("arc") + .AppendASCII(icon_file_name); + CHECK(base::PathExists(icon_file_path)); + CHECK(base::ReadFileToString(icon_file_path, png_data_as_string)); + + std::vector<uint8_t> png_data(png_data_as_string->begin(), + png_data_as_string->end()); + + FOR_EACH_OBSERVER(AppObserver, + app_observer_list(), + OnAppIcon(app.package, + app.activity, + scale_factor, + png_data)); + + return true; +} + +} // namespace arc
diff --git a/components/arc/test/fake_arc_bridge_service.h b/components/arc/test/fake_arc_bridge_service.h new file mode 100644 index 0000000..ef4e20d --- /dev/null +++ b/components/arc/test/fake_arc_bridge_service.h
@@ -0,0 +1,119 @@ +// 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. + +#ifndef COMPONENTS_ARC_TEST_FAKE_ARC_BRIDGE_SERVICE_H_ +#define COMPONENTS_ARC_TEST_FAKE_ARC_BRIDGE_SERVICE_H_ + +#include <string> +#include <vector> + +#include "base/macros.h" +#include "base/memory/scoped_vector.h" +#include "components/arc/arc_bridge_service.h" + +namespace arc { + +class FakeArcBridgeService : public ArcBridgeService { + public: + class Request { + public: + Request(const std::string& package, const std::string& activity) + : package_(package), + activity_(activity) { + } + + ~Request() { + } + + const std::string& package() const { return package_; } + + const std::string& activity() const { return activity_; } + + bool IsForApp(const AppInfo& app_info) const { + return package_ == app_info.package && activity_ == app_info.activity; + } + + private: + std::string package_; + std::string activity_; + + DISALLOW_COPY_AND_ASSIGN(Request); + }; + + class IconRequest : public Request { + public: + IconRequest(const std::string& package, + const std::string& activity, + ScaleFactor scale_factor) + : Request(package, activity), + scale_factor_(scale_factor) { + } + + ~IconRequest() { + } + + int scale_factor() const { return scale_factor_; } + + private: + int scale_factor_; + + DISALLOW_COPY_AND_ASSIGN(IconRequest); + }; + + FakeArcBridgeService(); + ~FakeArcBridgeService() override; + + // arc::ArcBridgeService + void DetectAvailability() override; + void HandleStartup() override; + void Shutdown() override; + bool RegisterInputDevice(const std::string& name, + const std::string& device_type, + base::ScopedFD fd) override; + bool RefreshAppList() override; + bool LaunchApp(const std::string& package, + const std::string& activity) override; + bool RequestAppIcon(const std::string& package, + const std::string& activity, + ScaleFactor scale_factor) override; + bool SendNotificationEventToAndroid(const std::string& key, + ArcNotificationEvent event) override; + + int refresh_app_list_count() const { return refresh_app_list_count_; } + + const ScopedVector<Request>& launch_requests() const { + return launch_requests_; + } + + const ScopedVector<IconRequest>& icon_requests() const { + return icon_requests_; + } + + void SetReady(); + + void SetStopped(); + + bool HasObserver(const Observer* observer); + bool HasAppObserver(const AppObserver* observer); + + void SendRefreshAppList(const std::vector<AppInfo>& apps); + + bool GenerateAndSendIcon(const AppInfo& app, + ScaleFactor scale_factor, + std::string* png_data); + + private: + // Number of RefreshAppList calls. + int refresh_app_list_count_ = 0; + // Keeps information about launch requests. + ScopedVector<Request> launch_requests_; + // Keeps information about icon load requests. + ScopedVector<IconRequest> icon_requests_; + + DISALLOW_COPY_AND_ASSIGN(FakeArcBridgeService); +}; + +} // namespace arc + +#endif // COMPONENTS_ARC_TEST_FAKE_ARC_BRIDGE_SERVICE_H_
diff --git a/components/autofill/content/renderer/autofill_agent.cc b/components/autofill/content/renderer/autofill_agent.cc index a1ceea41..afb8274 100644 --- a/components/autofill/content/renderer/autofill_agent.cc +++ b/components/autofill/content/renderer/autofill_agent.cc
@@ -386,10 +386,14 @@ void AutofillAgent::textFieldDidChange(const WebFormControlElement& element) { DCHECK(toWebInputElement(&element) || form_util::IsTextAreaElement(element)); + if (ignore_text_changes_) return; - if (!IsUserGesture()) + // Disregard text changes that aren't caused by user gestures or pastes. Note + // that pastes aren't necessarily user gestures because Blink's conception of + // user gestures is centered around creating new windows/tabs. + if (!IsUserGesture() && !render_frame()->IsPasting()) return; // We post a task for doing the Autofill as the caret position is not set @@ -731,9 +735,13 @@ data_list_values, data_list_labels)); + blink::WebRect bounding_box_in_window = element_.boundsInViewport(); + render_frame()->GetRenderView()->convertViewportToWindow( + &bounding_box_in_window); + Send(new AutofillHostMsg_QueryFormFieldAutofill( routing_id(), autofill_query_id_, form, field, - gfx::RectF(element_.boundsInViewport()))); + gfx::RectF(bounding_box_in_window))); } void AutofillAgent::FillFieldWithValue(const base::string16& value,
diff --git a/components/autofill/content/renderer/password_autofill_agent.cc b/components/autofill/content/renderer/password_autofill_agent.cc index a80fef1..4fe2a143 100644 --- a/components/autofill/content/renderer/password_autofill_agent.cc +++ b/components/autofill/content/renderer/password_autofill_agent.cc
@@ -1438,9 +1438,13 @@ username.isNull() ? base::string16() : static_cast<base::string16>(user_input.value())); + blink::WebRect bounding_box_in_window = selected_element.boundsInViewport(); + render_frame()->GetRenderView()->convertViewportToWindow( + &bounding_box_in_window); + Send(new AutofillHostMsg_ShowPasswordSuggestions( routing_id(), key_it->second, field.text_direction, username_string, - options, gfx::RectF(selected_element.boundsInViewport()))); + options, gfx::RectF(bounding_box_in_window))); username_query_prefix_ = username_string; return CanShowSuggestion(fill_data, username_string, show_all); }
diff --git a/components/autofill/content/renderer/password_generation_agent.cc b/components/autofill/content/renderer/password_generation_agent.cc index 4d1c8cc..6ad50b5 100644 --- a/components/autofill/content/renderer/password_generation_agent.cc +++ b/components/autofill/content/renderer/password_generation_agent.cc
@@ -411,18 +411,26 @@ } void PasswordGenerationAgent::ShowGenerationPopup() { + blink::WebRect bounding_box_in_window = + generation_element_.boundsInViewport(); + render_frame()->GetRenderView()->convertViewportToWindow( + &bounding_box_in_window); + Send(new AutofillHostMsg_ShowPasswordGenerationPopup( - routing_id(), gfx::RectF(generation_element_.boundsInViewport()), + routing_id(), gfx::RectF(bounding_box_in_window), generation_element_.maxLength(), *generation_form_data_->form)); generation_popup_shown_ = true; } void PasswordGenerationAgent::ShowEditingPopup() { + blink::WebRect bounding_box_in_window = + generation_element_.boundsInViewport(); + render_frame()->GetRenderView()->convertViewportToWindow( + &bounding_box_in_window); Send(new AutofillHostMsg_ShowPasswordEditingPopup( - routing_id(), gfx::RectF(generation_element_.boundsInViewport()), + routing_id(), gfx::RectF(bounding_box_in_window), *generation_form_data_->form)); - editing_popup_shown_ = true; }
diff --git a/components/autofill/core/browser/autofill_field.cc b/components/autofill/core/browser/autofill_field.cc index 5fd597d..41bc2fc0 100644 --- a/components/autofill/core/browser/autofill_field.cc +++ b/components/autofill/core/browser/autofill_field.cc
@@ -20,6 +20,7 @@ #include "components/autofill/core/browser/state_names.h" #include "components/autofill/core/common/autofill_l10n_util.h" #include "components/autofill/core/common/autofill_switches.h" +#include "components/autofill/core/common/autofill_util.h" #include "grit/components_strings.h" #include "third_party/libaddressinput/src/cpp/include/libaddressinput/address_data.h" #include "third_party/libaddressinput/src/cpp/include/libaddressinput/address_formatter.h" @@ -500,6 +501,13 @@ FormFieldData* field_data) { AutofillType type = field.Type(); + // Don't fill if autocomplete=off is set on |field| on desktop for non credit + // card related fields. + if (!field.should_autocomplete && IsDesktopPlatform() && + (type.group() != CREDIT_CARD)) { + return false; + } + if (type.GetStorableType() == PHONE_HOME_NUMBER) { FillPhoneNumberField(field, value, field_data); return true;
diff --git a/components/autofill/core/browser/autofill_field_unittest.cc b/components/autofill/core/browser/autofill_field_unittest.cc index c65daaa..46009a2 100644 --- a/components/autofill/core/browser/autofill_field_unittest.cc +++ b/components/autofill/core/browser/autofill_field_unittest.cc
@@ -9,6 +9,7 @@ #include "base/strings/utf_string_conversions.h" #include "components/autofill/core/browser/autofill_type.h" #include "components/autofill/core/browser/field_types.h" +#include "components/autofill/core/common/autofill_util.h" #include "testing/gtest/include/gtest/gtest.h" using base::ASCIIToUTF16; @@ -129,11 +130,45 @@ field.set_server_type(NAME_LAST); EXPECT_TRUE(field.IsFieldFillable()); - // Field has autocomplete="off" set. Chrome ignores the attribute. + // Field has autocomplete="off" set. Since autofill was able to make a + // prediction, it is still considered a fillable field. field.should_autocomplete = false; EXPECT_TRUE(field.IsFieldFillable()); } +// Verify that non credit card related fields with the autocomplete attribute +// set to off don't get filled on desktop. +TEST(AutofillFieldTest, FillFormField_AutocompleteOff_AddressField) { + AutofillField field; + field.should_autocomplete = false; + + // Non credit card related field. + AutofillField::FillFormField(field, ASCIIToUTF16("Test"), "en-US", "en-US", + &field); + + // Verifiy that the field is filled on mobile but not on desktop. + if (IsDesktopPlatform()) { + EXPECT_EQ(base::string16(), field.value); + } else { + EXPECT_EQ(ASCIIToUTF16("Test"), field.value); + } +} + +// Verify that credit card related fields with the autocomplete attribute +// set to off get filled. +TEST(AutofillFieldTest, FillFormField_AutocompleteOff_CreditCardField) { + AutofillField field; + field.should_autocomplete = false; + + // Credit card related field. + field.set_heuristic_type(CREDIT_CARD_NUMBER); + AutofillField::FillFormField(field, ASCIIToUTF16("4111111111111111"), "en-US", + "en-US", &field); + + // Verify that the field is filled. + EXPECT_EQ(ASCIIToUTF16("4111111111111111"), field.value); +} + TEST(AutofillFieldTest, FillPhoneNumber) { AutofillField field; field.SetHtmlType(HTML_TYPE_TEL_LOCAL_PREFIX, HtmlFieldMode());
diff --git a/components/autofill/core/browser/autofill_manager.cc b/components/autofill/core/browser/autofill_manager.cc index e3c5e3c6..c3c0776 100644 --- a/components/autofill/core/browser/autofill_manager.cc +++ b/components/autofill/core/browser/autofill_manager.cc
@@ -49,6 +49,7 @@ #include "components/autofill/core/common/autofill_data_validation.h" #include "components/autofill/core/common/autofill_pref_names.h" #include "components/autofill/core/common/autofill_switches.h" +#include "components/autofill/core/common/autofill_util.h" #include "components/autofill/core/common/form_data.h" #include "components/autofill/core/common/form_data_predictions.h" #include "components/autofill/core/common/form_field_data.h" @@ -347,6 +348,9 @@ if (!IsValidFormData(form) || !IsValidFormFieldData(field)) return; + if (test_delegate_) + test_delegate_->OnTextFieldChanged(); + FormStructure* form_structure = NULL; AutofillField* autofill_field = NULL; if (!GetCachedFormAndField(form, field, &form_structure, &autofill_field)) @@ -407,6 +411,12 @@ got_autofillable_form) { AutofillType type = autofill_field->Type(); bool is_filling_credit_card = (type.group() == CREDIT_CARD); + // On desktop, don't return non credit card related suggestions for forms or + // fields that have the "autocomplete" attribute set to off. + if (IsDesktopPlatform() && !is_filling_credit_card && + !field.should_autocomplete) { + return; + } if (is_filling_credit_card) { suggestions = GetCreditCardSuggestions(field, type); } else {
diff --git a/components/autofill/core/browser/autofill_manager_test_delegate.h b/components/autofill/core/browser/autofill_manager_test_delegate.h index 222a8df..3e2ad09f 100644 --- a/components/autofill/core/browser/autofill_manager_test_delegate.h +++ b/components/autofill/core/browser/autofill_manager_test_delegate.h
@@ -19,6 +19,9 @@ // Called when a popup with Autofill suggestions is shown. virtual void DidShowSuggestions() = 0; + + // Called when a text field change is detected. + virtual void OnTextFieldChanged() = 0; }; } // namespace autofill
diff --git a/components/autofill/core/browser/autofill_manager_unittest.cc b/components/autofill/core/browser/autofill_manager_unittest.cc index 487eb108..87dccd9 100644 --- a/components/autofill/core/browser/autofill_manager_unittest.cc +++ b/components/autofill/core/browser/autofill_manager_unittest.cc
@@ -35,6 +35,7 @@ #include "components/autofill/core/browser/webdata/autofill_webdata_service.h" #include "components/autofill/core/common/autofill_pref_names.h" #include "components/autofill/core/common/autofill_switches.h" +#include "components/autofill/core/common/autofill_util.h" #include "components/autofill/core/common/form_data.h" #include "components/autofill/core/common/form_field_data.h" #include "grit/components_strings.h" @@ -1895,6 +1896,89 @@ } } +// Test that non credit card related fields with the autocomplete attribute set +// to off are not filled on desktop. +TEST_F(AutofillManagerTest, FillAddressForm_AutocompleteOff) { + FormData address_form; + address_form.name = ASCIIToUTF16("MyForm"); + address_form.origin = GURL("https://myform.com/form.html"); + address_form.action = GURL("https://myform.com/submit.html"); + FormFieldData field; + test::CreateTestFormField("First name", "firstname", "", "text", &field); + address_form.fields.push_back(field); + test::CreateTestFormField("Middle name", "middle", "", "text", &field); + field.should_autocomplete = false; + address_form.fields.push_back(field); + test::CreateTestFormField("Last name", "lastname", "", "text", &field); + field.should_autocomplete = true; + address_form.fields.push_back(field); + test::CreateTestFormField("Address Line 1", "addr1", "", "text", &field); + field.should_autocomplete = false; + address_form.fields.push_back(field); + std::vector<FormData> address_forms(1, address_form); + FormsSeen(address_forms); + + // Fill the address form. + const char guid[] = "00000000-0000-0000-0000-000000000001"; + int response_page_id = 0; + FormData response_data; + FillAutofillFormDataAndSaveResults( + kDefaultPageID, address_form, address_form.fields[0], + MakeFrontendID(std::string(), guid), &response_page_id, &response_data); + + // The fist name should be filled. + ExpectFilledField("First name", "firstname", "Elvis", "text", + response_data.fields[0]); + + // The middle name should not be filled on desktop. + if (IsDesktopPlatform()) { + ExpectFilledField("Middle name", "middle", "", "text", + response_data.fields[1]); + } else { + ExpectFilledField("Middle name", "middle", "Aaron", "text", + response_data.fields[1]); + } + + // The last name should be filled. + ExpectFilledField("Last name", "lastname", "Presley", "text", + response_data.fields[2]); + + // The address line 1 should not be filled on desktop. + if (IsDesktopPlatform()) { + ExpectFilledField("Address Line 1", "addr1", "", "text", + response_data.fields[3]); + } else { + ExpectFilledField("Address Line 1", "addr1", "3734 Elvis Presley Blvd.", + "text", response_data.fields[3]); + } +} + +// Test that credit card fields are filled even if they have the autocomplete +// attribute set to off. +TEST_F(AutofillManagerTest, FillCreditCardForm_AutocompleteOff) { + // Set up our form data. + FormData form; + CreateTestCreditCardFormData(&form, true, false); + + // Set the autocomplete=off on all fields. + for (FormFieldData field : form.fields) + field.should_autocomplete = false; + + std::vector<FormData> forms(1, form); + FormsSeen(forms); + + const char guid[] = "00000000-0000-0000-0000-000000000004"; + int response_page_id = 0; + FormData response_data; + FillAutofillFormDataAndSaveResults(kDefaultPageID, form, *form.fields.begin(), + MakeFrontendID(guid, std::string()), + &response_page_id, &response_data); + + // All fields should be filled. + ExpectFilledCreditCardFormElvis(response_page_id, response_data, + kDefaultPageID, false); +} + // Test that non-focusable field is ignored while inferring boundaries between // sections: http://crbug.com/231160 TEST_F(AutofillManagerTest, FillFormWithNonFocusableFields) { @@ -3870,4 +3954,72 @@ EXPECT_FALSE(autofill_manager_->ShouldUploadForm(form_structure_3)); } +// Verify that no suggestions are shown on desktop for non credit card related +// fields if the initiating field has the "autocomplete" attribute set to off. +TEST_F(AutofillManagerTest, DisplaySuggestions_AutocompleteOff_AddressField) { + // Set up an address form. + FormData mixed_form; + mixed_form.name = ASCIIToUTF16("MyForm"); + mixed_form.origin = GURL("https://myform.com/form.html"); + mixed_form.action = GURL("https://myform.com/submit.html"); + FormFieldData field; + test::CreateTestFormField("First name", "firstname", "", "text", &field); + field.should_autocomplete = false; + mixed_form.fields.push_back(field); + test::CreateTestFormField("Last name", "lastname", "", "text", &field); + field.should_autocomplete = true; + mixed_form.fields.push_back(field); + test::CreateTestFormField("Address", "address", "", "text", &field); + field.should_autocomplete = true; + mixed_form.fields.push_back(field); + std::vector<FormData> mixed_forms(1, mixed_form); + FormsSeen(mixed_forms); + + // Suggestions should not be displayed on desktop for this field. + GetAutofillSuggestions(mixed_form, mixed_form.fields[0]); + if (IsDesktopPlatform()) { + EXPECT_FALSE(external_delegate_->on_suggestions_returned_seen()); + } else { + EXPECT_TRUE(external_delegate_->on_suggestions_returned_seen()); + } + + // Suggestions should always be displayed for all the other fields. + for (size_t i = 1U; i < mixed_form.fields.size(); ++i) { + GetAutofillSuggestions(mixed_form, mixed_form.fields[i]); + EXPECT_TRUE(external_delegate_->on_suggestions_returned_seen()); + } +} + +// Verify that suggestions are shown on desktop for credit card related fields +// even if the initiating field field has the "autocomplete" attribute set to +// off. +TEST_F(AutofillManagerTest, + DisplaySuggestions_AutocompleteOff_CreditCardField) { + // Set up a credit card form. + FormData mixed_form; + mixed_form.name = ASCIIToUTF16("MyForm"); + mixed_form.origin = GURL("https://myform.com/form.html"); + mixed_form.action = GURL("https://myform.com/submit.html"); + FormFieldData field; + test::CreateTestFormField("Name on Card", "nameoncard", "", "text", &field); + field.should_autocomplete = false; + mixed_form.fields.push_back(field); + test::CreateTestFormField("Card Number", "cardnumber", "", "text", &field); + field.should_autocomplete = true; + mixed_form.fields.push_back(field); + test::CreateTestFormField("Expiration Month", "ccexpiresmonth", "", "text", + &field); + field.should_autocomplete = false; + mixed_form.fields.push_back(field); + mixed_form.fields.push_back(field); + std::vector<FormData> mixed_forms(1, mixed_form); + FormsSeen(mixed_forms); + + // Suggestions should always be displayed. + for (const FormFieldData& field : mixed_form.fields) { + GetAutofillSuggestions(mixed_form, field); + EXPECT_TRUE(external_delegate_->on_suggestions_returned_seen()); + } +} + } // namespace autofill
diff --git a/components/autofill/core/common/autofill_util.cc b/components/autofill/core/common/autofill_util.cc index b2c3671..1359816 100644 --- a/components/autofill/core/common/autofill_util.cc +++ b/components/autofill/core/common/autofill_util.cc
@@ -96,4 +96,12 @@ return base::string16::npos; } +bool IsDesktopPlatform() { +#if defined(OS_ANDROID) || defined(OS_IOS) + return false; +#else + return true; +#endif +} + } // namespace autofill
diff --git a/components/autofill/core/common/autofill_util.h b/components/autofill/core/common/autofill_util.h index 81c3062..e29318d 100644 --- a/components/autofill/core/common/autofill_util.h +++ b/components/autofill/core/common/autofill_util.h
@@ -36,6 +36,10 @@ const base::string16& field_contents, bool case_sensitive); +// Returns true if running on a desktop platform. Any platform that is not +// Android or iOS is considered desktop. +bool IsDesktopPlatform(); + } // namespace autofill #endif // COMPONENTS_AUTOFILL_CORE_COMMON_AUTOFILL_UTIL_H_
diff --git a/components/autofill/ios/browser/resources/autofill_controller.js b/components/autofill/ios/browser/resources/autofill_controller.js index 16a4684..7c76203 100644 --- a/components/autofill/ios/browser/resources/autofill_controller.js +++ b/components/autofill/ios/browser/resources/autofill_controller.js
@@ -175,27 +175,40 @@ } /** - * To avoid overly expensive computation, we impose a minimum number of - * allowable fields. The corresponding maximum number of allowable fields - * is imposed by webFormElementToFormData(). + * Determines whether the form is interesting enough to send to the browser for + * further operations. * * Unlike the C++ version, this version takes a required field count param, * instead of using a hard coded value. * * It is based on the logic in - * bool ShouldIgnoreForm(size_t num_editable_elements, - * size_t num_control_elements); + * bool IsFormInteresting(const FormData& form, + * size_t num_editable_elements); * in chromium/src/components/autofill/content/renderer/form_cache.cc * + * @param {AutofillFormData} form Form to examine. * @param {number} numEditableElements number of editable elements. - * @param {number} numControlElements number of control elements. * @param {number} numFieldsRequired number of fields required. - * @return {boolean} Whether to ignore the form or not. + * @return {boolean} Whether the form is sufficiently interesting. */ -function shouldIgnoreForm_(numEditableElements, - numControlElements, - numFieldsRequired) { - return numEditableElements < numFieldsRequired && numControlElements > 0; +function isFormInteresting_(form, numEditableElements, numFieldsRequired) { + if (form.fields.length === 0) { + return false; + } + + // If the form has at least one field with an autocomplete attribute, it is a + // candidate for autofill. + for (var i = 0; i < form.fields.length; ++i) { + if (form.fields['autocomplete_attribute'] != null && + form.fields['autocomplete_attribute'].length > 0) { + return true; + } + } + + // If there are no autocomplete attributes, the form needs to have at least + // the required number of editable fields for the prediction routines to be a + // candidate for autofill. + return numEditableElements >= numFieldsRequired; } /** @@ -767,9 +780,8 @@ var controlElements = __gCrWeb.autofill.extractAutofillableElementsInForm(formElement); var numEditableElements = scanFormControlElements_(controlElements); - if (shouldIgnoreForm_(numEditableElements, - controlElements.length, - minimumRequiredFields)) { + + if (numEditableElements === 0) { continue; } @@ -778,12 +790,13 @@ frame, formElement, null, extractMask, form, null /* field */)) { continue; } + numFieldsSeen += form['fields'].length; if (numFieldsSeen > __gCrWeb.autofill.MAX_PARSEABLE_FIELDS) { break; } - if (form.fields.length >= minimumRequiredFields) { + if (isFormInteresting_(form, numEditableElements, minimumRequiredFields)) { forms.push(form); } } @@ -794,15 +807,16 @@ getUnownedAutofillableFormFieldElements_(doc.all, fieldsets); var numEditableUnownedElements = scanFormControlElements_(unownedControlElements); - if (!shouldIgnoreForm_(numEditableUnownedElements, - unownedControlElements.length, - minimumRequiredFields)) { + if (numEditableUnownedElements > 0) { var unownedForm = new __gCrWeb['common'].JSONSafeObject; - if (unownedFormElementsAndFieldSetsToFormData_( - frame, fieldsets, unownedControlElements, extractMask, unownedForm)) { + var hasUnownedForm = unownedFormElementsAndFieldSetsToFormData_( + frame, fieldsets, unownedControlElements, extractMask, unownedForm); + if (hasUnownedForm) { numFieldsSeen += unownedForm['fields'].length; if (numFieldsSeen <= __gCrWeb.autofill.MAX_PARSEABLE_FIELDS) { - if (unownedForm.fields.length >= minimumRequiredFields) { + var interesting = isFormInteresting_(unownedForm, + numEditableUnownedElements, minimumRequiredFields); + if (interesting) { forms.push(unownedForm); } }
diff --git a/components/component_updater/component_updater_service.cc b/components/component_updater/component_updater_service.cc index 1c49d26..490e5c4 100644 --- a/components/component_updater/component_updater_service.cc +++ b/components/component_updater/component_updater_service.cc
@@ -352,7 +352,7 @@ DCHECK(config); auto update_client = update_client::UpdateClientFactory(config); return scoped_ptr<ComponentUpdateService>( - new CrxUpdateService(config, update_client.Pass())); + new CrxUpdateService(config, std::move(update_client))); } } // namespace component_updater
diff --git a/components/components_tests.gyp b/components/components_tests.gyp index 1683204b..ce7d958 100644 --- a/components/components_tests.gyp +++ b/components/components_tests.gyp
@@ -601,12 +601,12 @@ 'scheduler/base/task_queue_manager_delegate_for_test.h', 'scheduler/base/task_queue_manager_unittest.cc', 'scheduler/base/task_queue_selector_unittest.cc', - 'scheduler/base/task_queue_sets_unittest.cc', 'scheduler/base/test_always_fail_time_source.cc', 'scheduler/base/test_always_fail_time_source.h', 'scheduler/base/test_time_source.cc', 'scheduler/base/test_time_source.h', 'scheduler/base/time_domain_unittest.cc', + 'scheduler/base/work_queue_sets_unittest.cc', 'scheduler/child/idle_helper_unittest.cc', 'scheduler/child/scheduler_helper_unittest.cc', 'scheduler/child/scheduler_tqm_delegate_for_test.cc', @@ -632,7 +632,7 @@ 'search_engines_unittest_sources': [ 'search_engines/default_search_manager_unittest.cc', 'search_engines/default_search_pref_migration_unittest.cc', - 'search_engines/detect_desktop_search_win_unittest.cc', + 'search_engines/desktop_search_win_unittest.cc', 'search_engines/keyword_table_unittest.cc', 'search_engines/search_host_to_urls_map_unittest.cc', 'search_engines/template_url_prepopulate_data_unittest.cc',
diff --git a/components/crash/content/app/crashpad_win.cc b/components/crash/content/app/crashpad_win.cc index 684366e..07c235e 100644 --- a/components/crash/content/app/crashpad_win.cc +++ b/components/crash/content/app/crashpad_win.cc
@@ -16,6 +16,7 @@ #include "components/crash/content/app/crash_reporter_client.h" #include "third_party/crashpad/crashpad/client/crashpad_client.h" #include "third_party/crashpad/crashpad/client/crashpad_info.h" +#include "third_party/crashpad/crashpad/client/simulate_crash_win.h" namespace crash_reporter { namespace internal { @@ -68,8 +69,7 @@ // In test binaries, use crashpad_handler directly. Otherwise, we launch // chrome.exe with --type=crashpad-handler. if (exe_file.BaseName().value() != FILE_PATH_LITERAL("chrome.exe")) { - base::FilePath exe_dir; - CHECK(PathService::Get(base::DIR_EXE, &exe_dir)); + base::FilePath exe_dir = exe_file.DirName(); exe_file = exe_dir.Append(FILE_PATH_LITERAL("crashpad_handler.exe")); } else { arguments.push_back("--type=crashpad-handler"); @@ -113,6 +113,60 @@ return EXCEPTION_CONTINUE_SEARCH; } +// TODO(scottmg): http://crbug.com/546288 These exported functions are for +// compatibility with how Breakpad worked, but it seems like there's no need to +// do the CreateRemoteThread() dance with a minor extension of the Crashpad API +// (to just pass the pid we want a dump for). We should add that and then modify +// hang_crash_dump_win.cc to work in a more direct manner. + +// Used for dumping a process state when there is no crash. +extern "C" void __declspec(dllexport) __cdecl DumpProcessWithoutCrash() { + CRASHPAD_SIMULATE_CRASH(); +} + +namespace { + +// We need to prevent ICF from folding DumpForHangDebuggingThread() and +// DumpProcessWithoutCrashThread() together, since that makes them +// indistinguishable in crash dumps. We do this by making the function +// bodies unique, and prevent optimization from shuffling things around. +MSVC_DISABLE_OPTIMIZE() +MSVC_PUSH_DISABLE_WARNING(4748) + +DWORD WINAPI DumpProcessWithoutCrashThread(void*) { + DumpProcessWithoutCrash(); + return 0; +} + +// The following two functions do exactly the same thing as the two above. But +// we want the signatures to be different so that we can easily track them in +// crash reports. +// TODO(yzshen): Remove when enough information is collected and the hang rate +// of pepper/renderer processes is reduced. +DWORD WINAPI DumpForHangDebuggingThread(void*) { + DumpProcessWithoutCrash(); + VLOG(1) << "dumped for hang debugging"; + return 0; +} + +MSVC_POP_WARNING() +MSVC_ENABLE_OPTIMIZE() + +} // namespace + +// Injects a thread into a remote process to dump state when there is no crash. +extern "C" HANDLE __declspec(dllexport) __cdecl InjectDumpProcessWithoutCrash( + HANDLE process) { + return CreateRemoteThread(process, NULL, 0, DumpProcessWithoutCrashThread, 0, + 0, NULL); +} + +extern "C" HANDLE __declspec(dllexport) __cdecl InjectDumpForHangDebugging( + HANDLE process) { + return CreateRemoteThread(process, NULL, 0, DumpForHangDebuggingThread, 0, 0, + NULL); +} + #if defined(ARCH_CPU_X86_64) static int CrashForExceptionInNonABICompliantCodeRange(
diff --git a/components/exo/shell_surface.cc b/components/exo/shell_surface.cc index 40bbd7f01..163b5588 100644 --- a/components/exo/shell_surface.cc +++ b/components/exo/shell_surface.cc
@@ -180,6 +180,18 @@ } } +void ShellSurface::SetGeometry(const gfx::Rect& geometry) { + TRACE_EVENT1("exo", "ShellSurface::SetGeometry", "geometry", + geometry.ToString()); + + if (geometry.IsEmpty()) { + DLOG(WARNING) << "Surface geometry must be non-empty"; + return; + } + + geometry_ = geometry; +} + scoped_refptr<base::trace_event::TracedValue> ShellSurface::AsTracedValue() const { scoped_refptr<base::trace_event::TracedValue> value = @@ -198,7 +210,8 @@ // Update surface bounds and widget size. gfx::Point origin; views::View::ConvertPointToWidget(this, &origin); - surface_->SetBounds(gfx::Rect(origin, surface_->layer()->size())); + surface_->SetBounds(gfx::Rect(origin - geometry_.OffsetFromOrigin(), + surface_->layer()->size())); widget_->SetSize(widget_->non_client_view()->GetPreferredSize()); // Show widget if not already visible. @@ -248,6 +261,9 @@ // views::Views overrides: gfx::Size ShellSurface::GetPreferredSize() const { + if (!geometry_.IsEmpty()) + return geometry_.size(); + return surface_ ? surface_->GetPreferredSize() : gfx::Size(); }
diff --git a/components/exo/shell_surface.h b/components/exo/shell_surface.h index 1c2bad32..541dd11d 100644 --- a/components/exo/shell_surface.h +++ b/components/exo/shell_surface.h
@@ -58,6 +58,10 @@ // Start an interactive move of surface. void Move(); + // Set geometry for surface. The geometry represents the "visible bounds" + // for the surface from the user's perspective. + void SetGeometry(const gfx::Rect& geometry); + // Returns a trace value representing the state of the surface. scoped_refptr<base::trace_event::TracedValue> AsTracedValue() const; @@ -84,6 +88,7 @@ Surface* surface_; base::string16 title_; std::string application_id_; + gfx::Rect geometry_; DISALLOW_COPY_AND_ASSIGN(ShellSurface); };
diff --git a/components/exo/shell_surface_unittest.cc b/components/exo/shell_surface_unittest.cc index 0f25a73..c8b6d46 100644 --- a/components/exo/shell_surface_unittest.cc +++ b/components/exo/shell_surface_unittest.cc
@@ -117,5 +117,25 @@ shell_surface->Move(); } +TEST_F(ShellSurfaceTest, SetGeometry) { + gfx::Size buffer_size(64, 64); + scoped_ptr<Buffer> buffer(new Buffer( + exo_test_helper()->CreateGpuMemoryBuffer(buffer_size), GL_TEXTURE_2D)); + scoped_ptr<Surface> surface(new Surface); + scoped_ptr<ShellSurface> shell_surface(new ShellSurface(surface.get())); + + shell_surface->SetToplevel(); + gfx::Rect geometry(16, 16, 32, 32); + shell_surface->SetGeometry(geometry); + surface->Attach(buffer.get()); + surface->Commit(); + EXPECT_EQ( + geometry.size().ToString(), + shell_surface->GetWidget()->GetWindowBoundsInScreen().size().ToString()); + EXPECT_EQ(gfx::Rect(gfx::Point() - geometry.OffsetFromOrigin(), buffer_size) + .ToString(), + surface->bounds().ToString()); +} + } // namespace } // namespace exo
diff --git a/components/exo/surface.cc b/components/exo/surface.cc index 717812c..7033b2a 100644 --- a/components/exo/surface.cc +++ b/components/exo/surface.cc
@@ -88,9 +88,9 @@ compositor_(nullptr), delegate_(nullptr) { SetType(ui::wm::WINDOW_TYPE_CONTROL); + SetName("ExoSurface"); Init(ui::LAYER_SOLID_COLOR); set_owned_by_parent(false); - SetName("ExoSurface"); } Surface::~Surface() {
diff --git a/components/exo/wayland/server.cc b/components/exo/wayland/server.cc index 13a568d..4e36150c 100644 --- a/components/exo/wayland/server.cc +++ b/components/exo/wayland/server.cc
@@ -758,7 +758,8 @@ int32_t y, int32_t width, int32_t height) { - NOTIMPLEMENTED(); + GetUserDataAs<ShellSurface>(resource) + ->SetGeometry(gfx::Rect(x, y, width, height)); } void xdg_surface_set_maximized(wl_client* client, wl_resource* resource) {
diff --git a/components/html_viewer/BUILD.gn b/components/html_viewer/BUILD.gn index 5f4a08a..820fc5a7 100644 --- a/components/html_viewer/BUILD.gn +++ b/components/html_viewer/BUILD.gn
@@ -10,7 +10,6 @@ if (is_android) { import("//build/config/android/rules.gni") - import("//mojo/generate_mojo_shell_assets_list.gni") } grit("html_viewer_resources_grit") { @@ -63,8 +62,6 @@ "blink_basic_type_converters.h", "blink_find_type_converters.cc", "blink_find_type_converters.h", - "blink_input_events_type_converters.cc", - "blink_input_events_type_converters.h", "blink_platform_impl.cc", "blink_platform_impl.h", "blink_resource_constants.h", @@ -177,6 +174,7 @@ "//mojo/application/public/cpp", "//mojo/application/public/interfaces", "//mojo/common", + "//mojo/converters/blink", "//mojo/converters/surfaces", "//mojo/gles2:headers", "//mojo/gpu:mojo_gles2_implementation", @@ -316,6 +314,7 @@ "//base/test:test_support", "//components/scheduler", "//gin", + "//mojo/converters/blink", "//mojo/converters/input_events", "//mojo/gles2", "//mojo/platform_handle:platform_handle_impl",
diff --git a/components/html_viewer/DEPS b/components/html_viewer/DEPS index 21d04e94..e1e5a2f 100644 --- a/components/html_viewer/DEPS +++ b/components/html_viewer/DEPS
@@ -24,6 +24,7 @@ "+mojo/application", "+mojo/cc", "+mojo/common", + "+mojo/converters/blink", "+mojo/converters/geometry", "+mojo/converters/input_events", "+mojo/converters/network",
diff --git a/components/html_viewer/blink_input_events_type_converters.h b/components/html_viewer/blink_input_events_type_converters.h deleted file mode 100644 index 9461bdc..0000000 --- a/components/html_viewer/blink_input_events_type_converters.h +++ /dev/null
@@ -1,25 +0,0 @@ -// Copyright 2014 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef COMPONENTS_HTML_VIEWER_BLINK_INPUT_EVENTS_TYPE_CONVERTERS_H_ -#define COMPONENTS_HTML_VIEWER_BLINK_INPUT_EVENTS_TYPE_CONVERTERS_H_ - -#include "base/memory/scoped_ptr.h" -#include "components/mus/public/interfaces/input_events.mojom.h" - -namespace blink { -class WebInputEvent; -} - -namespace mojo { - -template <> -struct TypeConverter<scoped_ptr<blink::WebInputEvent>, mus::mojom::EventPtr> { - static scoped_ptr<blink::WebInputEvent> Convert( - const mus::mojom::EventPtr& input); -}; - -} // namespace mojo - -#endif // COMPONENTS_HTML_VIEWER_BLINK_INPUT_EVENTS_TYPE_CONVERTERS_H_
diff --git a/components/html_viewer/blink_platform_impl.cc b/components/html_viewer/blink_platform_impl.cc index c50fb5e..443ba881 100644 --- a/components/html_viewer/blink_platform_impl.cc +++ b/components/html_viewer/blink_platform_impl.cc
@@ -50,11 +50,11 @@ bool initially_signaled = state == InitialState::Signaled; impl_.reset(new base::WaitableEvent(manual_reset, initially_signaled)); } - virtual ~WebWaitableEventImpl() {} + ~WebWaitableEventImpl() override {} - virtual void reset() { impl_->Reset(); } - virtual void wait() { impl_->Wait(); } - virtual void signal() { impl_->Signal(); } + void reset() override { impl_->Reset(); } + void wait() override { impl_->Wait(); } + void signal() override { impl_->Signal(); } base::WaitableEvent* impl() { return impl_.get();
diff --git a/components/html_viewer/blink_platform_impl.h b/components/html_viewer/blink_platform_impl.h index a0ceae4..25f078f 100644 --- a/components/html_viewer/blink_platform_impl.h +++ b/components/html_viewer/blink_platform_impl.h
@@ -40,61 +40,61 @@ BlinkPlatformImpl(GlobalState* global_state, mojo::ApplicationImpl* app, scheduler::RendererScheduler* renderer_scheduler); - virtual ~BlinkPlatformImpl(); + ~BlinkPlatformImpl() override; // blink::Platform methods: - virtual blink::WebCookieJar* cookieJar(); - virtual blink::WebClipboard* clipboard(); - virtual blink::WebMimeRegistry* mimeRegistry(); - virtual blink::WebThemeEngine* themeEngine(); - virtual blink::WebString defaultLocale(); - virtual blink::WebBlobRegistry* blobRegistry(); - virtual double currentTimeSeconds(); - virtual double monotonicallyIncreasingTimeSeconds(); - virtual void cryptographicallyRandomValues(unsigned char* buffer, - size_t length); - virtual bool isThreadedCompositingEnabled(); - virtual blink::WebCompositorSupport* compositorSupport(); + blink::WebCookieJar* cookieJar() override; + blink::WebClipboard* clipboard() override; + blink::WebMimeRegistry* mimeRegistry() override; + blink::WebThemeEngine* themeEngine() override; + blink::WebString defaultLocale() override; + blink::WebBlobRegistry* blobRegistry() override; + double currentTimeSeconds() override; + double monotonicallyIncreasingTimeSeconds() override; + void cryptographicallyRandomValues(unsigned char* buffer, + size_t length) override; + bool isThreadedCompositingEnabled() override; + blink::WebCompositorSupport* compositorSupport() override; uint32_t getUniqueIdForProcess() override; void createMessageChannel(blink::WebMessagePortChannel** channel1, blink::WebMessagePortChannel** channel2) override; - virtual blink::WebURLLoader* createURLLoader(); - virtual blink::WebSocketHandle* createWebSocketHandle(); - virtual blink::WebString userAgent(); - virtual blink::WebData parseDataURL( - const blink::WebURL& url, blink::WebString& mime_type, - blink::WebString& charset); - virtual bool isReservedIPAddress(const blink::WebString& host) const; - virtual blink::WebURLError cancelledError(const blink::WebURL& url) const; - virtual blink::WebThread* createThread(const char* name); - virtual blink::WebThread* currentThread(); - virtual void yieldCurrentThread(); - virtual blink::WebWaitableEvent* createWaitableEvent( + blink::WebURLLoader* createURLLoader() override; + blink::WebSocketHandle* createWebSocketHandle() override; + blink::WebString userAgent() override; + blink::WebData parseDataURL(const blink::WebURL& url, + blink::WebString& mime_type, + blink::WebString& charset) override; + bool isReservedIPAddress(const blink::WebString& host) const override; + blink::WebURLError cancelledError(const blink::WebURL& url) const override; + blink::WebThread* createThread(const char* name) override; + blink::WebThread* currentThread() override; + void yieldCurrentThread() override; + blink::WebWaitableEvent* createWaitableEvent( blink::WebWaitableEvent::ResetPolicy policy, - blink::WebWaitableEvent::InitialState state); - virtual blink::WebWaitableEvent* waitMultipleEvents( - const blink::WebVector<blink::WebWaitableEvent*>& events); - virtual blink::WebScrollbarBehavior* scrollbarBehavior(); - virtual const unsigned char* getTraceCategoryEnabledFlag( - const char* category_name); - virtual blink::WebGraphicsContext3D* createOffscreenGraphicsContext3D( + blink::WebWaitableEvent::InitialState state) override; + blink::WebWaitableEvent* waitMultipleEvents( + const blink::WebVector<blink::WebWaitableEvent*>& events) override; + blink::WebScrollbarBehavior* scrollbarBehavior() override; + const unsigned char* getTraceCategoryEnabledFlag( + const char* category_name) override; + blink::WebGraphicsContext3D* createOffscreenGraphicsContext3D( const blink::WebGraphicsContext3D::Attributes& attributes, - blink::WebGraphicsContext3D* share_context); - virtual blink::WebGraphicsContext3D* createOffscreenGraphicsContext3D( + blink::WebGraphicsContext3D* share_context) override; + blink::WebGraphicsContext3D* createOffscreenGraphicsContext3D( const blink::WebGraphicsContext3D::Attributes& attributes, blink::WebGraphicsContext3D* share_context, - blink::WebGraphicsContext3D::WebGraphicsInfo* gl_info); - virtual blink::WebGraphicsContext3D* createOffscreenGraphicsContext3D( - const blink::WebGraphicsContext3D::Attributes& attributes); - virtual blink::WebGraphicsContext3DProvider* - createSharedOffscreenGraphicsContext3DProvider(); - virtual blink::WebData loadResource(const char* name); - virtual blink::WebGestureCurve* createFlingAnimationCurve( + blink::WebGraphicsContext3D::WebGraphicsInfo* gl_info) override; + blink::WebGraphicsContext3D* createOffscreenGraphicsContext3D( + const blink::WebGraphicsContext3D::Attributes& attributes) override; + blink::WebGraphicsContext3DProvider* + createSharedOffscreenGraphicsContext3DProvider() override; + blink::WebData loadResource(const char* name) override; + blink::WebGestureCurve* createFlingAnimationCurve( blink::WebGestureDevice device_source, const blink::WebFloatPoint& velocity, - const blink::WebSize& cumulative_scroll); - virtual blink::WebCrypto* crypto(); - virtual blink::WebNotificationManager* notificationManager(); + const blink::WebSize& cumulative_scroll) override; + blink::WebCrypto* crypto() override; + blink::WebNotificationManager* notificationManager() override; private: void UpdateWebThreadTLS(blink::WebThread* thread);
diff --git a/components/html_viewer/blink_settings_impl.cc b/components/html_viewer/blink_settings_impl.cc index b6de9e3..a2b3180 100644 --- a/components/html_viewer/blink_settings_impl.cc +++ b/components/html_viewer/blink_settings_impl.cc
@@ -244,8 +244,6 @@ settings->setAccelerated2dCanvasMSAASampleCount( prefs.accelerated_2d_canvas_msaa_sample_count); - settings->setAsynchronousSpellCheckingEnabled( - prefs.asynchronous_spell_checking_enabled); settings->setUnifiedTextCheckerEnabled(prefs.unified_textchecker_enabled); // Tabs to link is not part of the settings. WebCore calls
diff --git a/components/html_viewer/devtools_agent_impl.h b/components/html_viewer/devtools_agent_impl.h index 8b942d4..bcb429c 100644 --- a/components/html_viewer/devtools_agent_impl.h +++ b/components/html_viewer/devtools_agent_impl.h
@@ -41,7 +41,7 @@ void sendProtocolMessage(int session_id, int call_id, const blink::WebString& response, - const blink::WebString& state); + const blink::WebString& state) override; void OnConnectionError();
diff --git a/components/html_viewer/global_state.cc b/components/html_viewer/global_state.cc index 4bbf4db..2a2261b 100644 --- a/components/html_viewer/global_state.cc +++ b/components/html_viewer/global_state.cc
@@ -9,6 +9,8 @@ #include "base/bind.h" #include "base/command_line.h" #include "base/logging.h" +#include "cc/blink/web_layer_impl.h" +#include "cc/layers/layer_settings.h" #include "components/html_viewer/blink_platform_impl.h" #include "components/html_viewer/blink_settings_impl.h" #include "components/html_viewer/media_factory.h" @@ -128,6 +130,12 @@ gpu_service_->GetGpuInfo(base::Bind(&GlobalState::GetGpuInfoCallback, base::Unretained(this))); + // Use new animation system (cc::AnimationHost). + cc::LayerSettings layer_settings; + layer_settings.use_compositor_animation_timelines = true; + cc_blink::WebLayerImpl::SetLayerSettings(layer_settings); + blink::WebRuntimeFeatures::enableCompositorAnimationTimelines(true); + renderer_scheduler_ = scheduler::RendererScheduler::Create(); blink_platform_.reset( new BlinkPlatformImpl(this, app_, renderer_scheduler_.get()));
diff --git a/components/html_viewer/html_frame.cc b/components/html_viewer/html_frame.cc index 8050f145..1ddb997 100644 --- a/components/html_viewer/html_frame.cc +++ b/components/html_viewer/html_frame.cc
@@ -17,7 +17,6 @@ #include "components/html_viewer/ax_provider_impl.h" #include "components/html_viewer/blink_basic_type_converters.h" #include "components/html_viewer/blink_find_type_converters.h" -#include "components/html_viewer/blink_input_events_type_converters.h" #include "components/html_viewer/blink_text_input_type_converters.h" #include "components/html_viewer/blink_url_request_type_converters.h" #include "components/html_viewer/devtools_agent_impl.h" @@ -42,6 +41,7 @@ #include "mojo/application/public/cpp/connect.h" #include "mojo/application/public/interfaces/shell.mojom.h" #include "mojo/common/common_type_converters.h" +#include "mojo/converters/blink/blink_input_events_type_converters.h" #include "mojo/converters/geometry/geometry_type_converters.h" #include "third_party/WebKit/public/platform/Platform.h" #include "third_party/WebKit/public/platform/WebHTTPHeaderVisitor.h"
diff --git a/components/html_viewer/html_frame.h b/components/html_viewer/html_frame.h index 34e33e3..9f108ac 100644 --- a/components/html_viewer/html_frame.h +++ b/components/html_viewer/html_frame.h
@@ -152,59 +152,59 @@ base::TimeTicks navigation_start_time); protected: - virtual ~HTMLFrame(); + ~HTMLFrame() override; // WebFrameClient methods: - virtual blink::WebMediaPlayer* createMediaPlayer( + blink::WebMediaPlayer* createMediaPlayer( blink::WebLocalFrame* frame, const blink::WebURL& url, blink::WebMediaPlayerClient* client, blink::WebMediaPlayerEncryptedMediaClient* encrypted_client, blink::WebContentDecryptionModule* initial_cdm, - const blink::WebString& sink_id); - virtual blink::WebFrame* createChildFrame( + const blink::WebString& sink_id) override; + blink::WebFrame* createChildFrame( blink::WebLocalFrame* parent, blink::WebTreeScopeType scope, const blink::WebString& frame_ame, blink::WebSandboxFlags sandbox_flags, - const blink::WebFrameOwnerProperties& frame_owner_properties); - virtual void frameDetached(blink::WebFrame* frame, - blink::WebFrameClient::DetachType type); - virtual blink::WebCookieJar* cookieJar(blink::WebLocalFrame* frame); - virtual blink::WebNavigationPolicy decidePolicyForNavigation( - const NavigationPolicyInfo& info); - virtual bool hasPendingNavigation(blink::WebLocalFrame* frame); - virtual void didHandleOnloadEvents(blink::WebLocalFrame* frame); - virtual void didAddMessageToConsole(const blink::WebConsoleMessage& message, - const blink::WebString& source_name, - unsigned source_line, - const blink::WebString& stack_trace); - virtual void didFinishLoad(blink::WebLocalFrame* frame); - virtual void didNavigateWithinPage(blink::WebLocalFrame* frame, - const blink::WebHistoryItem& history_item, - blink::WebHistoryCommitType commit_type); - virtual blink::WebGeolocationClient* geolocationClient(); - virtual blink::WebEncryptedMediaClient* encryptedMediaClient(); - virtual void didStartLoading(bool to_different_document); - virtual void didStopLoading(); - virtual void didChangeLoadProgress(double load_progress); - virtual void dispatchLoad(); - virtual void didChangeName(blink::WebLocalFrame* frame, - const blink::WebString& name); - virtual void didCommitProvisionalLoad( + const blink::WebFrameOwnerProperties& frame_owner_properties) override; + void frameDetached(blink::WebFrame* frame, + blink::WebFrameClient::DetachType type) override; + blink::WebCookieJar* cookieJar(blink::WebLocalFrame* frame) override; + blink::WebNavigationPolicy decidePolicyForNavigation( + const NavigationPolicyInfo& info) override; + bool hasPendingNavigation(blink::WebLocalFrame* frame) override; + void didHandleOnloadEvents(blink::WebLocalFrame* frame) override; + void didAddMessageToConsole(const blink::WebConsoleMessage& message, + const blink::WebString& source_name, + unsigned source_line, + const blink::WebString& stack_trace) override; + void didFinishLoad(blink::WebLocalFrame* frame) override; + void didNavigateWithinPage(blink::WebLocalFrame* frame, + const blink::WebHistoryItem& history_item, + blink::WebHistoryCommitType commit_type) override; + blink::WebGeolocationClient* geolocationClient() override; + blink::WebEncryptedMediaClient* encryptedMediaClient() override; + void didStartLoading(bool to_different_document) override; + void didStopLoading() override; + void didChangeLoadProgress(double load_progress) override; + void dispatchLoad() override; + void didChangeName(blink::WebLocalFrame* frame, + const blink::WebString& name) override; + void didCommitProvisionalLoad( blink::WebLocalFrame* frame, const blink::WebHistoryItem& item, - blink::WebHistoryCommitType commit_type); - virtual void didReceiveTitle(blink::WebLocalFrame* frame, - const blink::WebString& title, - blink::WebTextDirection direction); - virtual void reportFindInFrameMatchCount(int identifier, - int count, - bool finalUpdate); - virtual void reportFindInPageSelection(int identifier, - int activeMatchOrdinal, - const blink::WebRect& selection); - virtual bool shouldSearchSingleFrame(); + blink::WebHistoryCommitType commit_type) override; + void didReceiveTitle(blink::WebLocalFrame* frame, + const blink::WebString& title, + blink::WebTextDirection direction) override; + void reportFindInFrameMatchCount(int identifier, + int count, + bool finalUpdate) override; + void reportFindInPageSelection(int identifier, + int activeMatchOrdinal, + const blink::WebRect& selection) override; + bool shouldSearchSingleFrame() override; private: friend class HTMLFrameTreeManager; @@ -310,17 +310,17 @@ void StopHighlightingFindResults() override; // blink::WebRemoteFrameClient: - virtual void frameDetached(blink::WebRemoteFrameClient::DetachType type); - virtual void postMessageEvent(blink::WebLocalFrame* source_web_frame, - blink::WebRemoteFrame* target_web_frame, - blink::WebSecurityOrigin target_origin, - blink::WebDOMMessageEvent event); - virtual void initializeChildFrame(const blink::WebRect& frame_rect, - float scale_factor); - virtual void navigate(const blink::WebURLRequest& request, - bool should_replace_current_entry); - virtual void reload(bool ignore_cache, bool is_client_redirect); - virtual void frameRectsChanged(const blink::WebRect& frame_rect); + void frameDetached(blink::WebRemoteFrameClient::DetachType type) override; + void postMessageEvent(blink::WebLocalFrame* source_web_frame, + blink::WebRemoteFrame* target_web_frame, + blink::WebSecurityOrigin target_origin, + blink::WebDOMMessageEvent event) override; + void initializeChildFrame(const blink::WebRect& frame_rect, + float scale_factor) override; + void navigate(const blink::WebURLRequest& request, + bool should_replace_current_entry) override; + void reload(bool ignore_cache, bool is_client_redirect) override; + void frameRectsChanged(const blink::WebRect& frame_rect) override; HTMLFrameTreeManager* frame_tree_manager_; HTMLFrame* parent_;
diff --git a/components/html_viewer/html_widget.h b/components/html_viewer/html_widget.h index 7ae9f4c..03cd280 100644 --- a/components/html_viewer/html_widget.h +++ b/components/html_viewer/html_widget.h
@@ -45,8 +45,8 @@ private: // WebViewClient methods: - virtual blink::WebStorageNamespace* createSessionStorageNamespace(); - virtual bool allowsBrokenNullLayerTreeView() const; + blink::WebStorageNamespace* createSessionStorageNamespace() override; + bool allowsBrokenNullLayerTreeView() const override; // HTMLWidget: blink::WebWidget* GetWidget() override; @@ -79,15 +79,15 @@ protected: // WebViewClient methods: - virtual blink::WebStorageNamespace* createSessionStorageNamespace(); - virtual void initializeLayerTreeView(); - virtual blink::WebLayerTreeView* layerTreeView(); - virtual void didMeaningfulLayout(blink::WebMeaningfulLayout layout_type); - virtual void resetInputMethod(); - virtual void didHandleGestureEvent(const blink::WebGestureEvent& event, - bool event_cancelled); - virtual void didUpdateTextOfFocusedElementByNonUserInput(); - virtual void showImeIfNeeded(); + blink::WebStorageNamespace* createSessionStorageNamespace() override; + void initializeLayerTreeView() override; + blink::WebLayerTreeView* layerTreeView() override; + void didMeaningfulLayout(blink::WebMeaningfulLayout layout_type) override; + void resetInputMethod() override; + void didHandleGestureEvent(const blink::WebGestureEvent& event, + bool event_cancelled) override; + void didUpdateTextOfFocusedElementByNonUserInput() override; + void showImeIfNeeded() override; private: // HTMLWidget: @@ -119,13 +119,13 @@ void OnWindowBoundsChanged(mus::Window* window) override; // WebWidgetClient: - virtual void initializeLayerTreeView(); - virtual blink::WebLayerTreeView* layerTreeView(); - virtual void resetInputMethod(); - virtual void didHandleGestureEvent(const blink::WebGestureEvent& event, - bool event_cancelled); - virtual void didUpdateTextOfFocusedElementByNonUserInput(); - virtual void showImeIfNeeded(); + void initializeLayerTreeView() override; + blink::WebLayerTreeView* layerTreeView() override; + void resetInputMethod() override; + void didHandleGestureEvent(const blink::WebGestureEvent& event, + bool event_cancelled) override; + void didUpdateTextOfFocusedElementByNonUserInput() override; + void showImeIfNeeded() override; mojo::ApplicationImpl* app_; GlobalState* global_state_;
diff --git a/components/html_viewer/ime_controller.cc b/components/html_viewer/ime_controller.cc index 3b65a5a..da6e7b14 100644 --- a/components/html_viewer/ime_controller.cc +++ b/components/html_viewer/ime_controller.cc
@@ -4,9 +4,9 @@ #include "components/html_viewer/ime_controller.h" -#include "components/html_viewer/blink_input_events_type_converters.h" #include "components/html_viewer/blink_text_input_type_converters.h" #include "components/mus/public/cpp/window.h" +#include "mojo/converters/blink/blink_input_events_type_converters.h" #include "third_party/WebKit/public/web/WebInputEvent.h" #include "third_party/WebKit/public/web/WebWidget.h"
diff --git a/components/html_viewer/input_events_unittest.cc b/components/html_viewer/input_events_unittest.cc index afaf724..4a28bbec 100644 --- a/components/html_viewer/input_events_unittest.cc +++ b/components/html_viewer/input_events_unittest.cc
@@ -3,7 +3,7 @@ // found in the LICENSE file. #include "base/memory/scoped_ptr.h" -#include "components/html_viewer/blink_input_events_type_converters.h" +#include "mojo/converters/blink/blink_input_events_type_converters.h" #include "mojo/converters/input_events/input_events_type_converters.h" #include "testing/gtest/include/gtest/gtest.h" #include "third_party/WebKit/public/web/WebInputEvent.h"
diff --git a/components/html_viewer/mock_web_blob_registry_impl.h b/components/html_viewer/mock_web_blob_registry_impl.h index 1a8ee38..687e685 100644 --- a/components/html_viewer/mock_web_blob_registry_impl.h +++ b/components/html_viewer/mock_web_blob_registry_impl.h
@@ -22,28 +22,28 @@ class MockWebBlobRegistryImpl : public blink::WebBlobRegistry { public: MockWebBlobRegistryImpl(); - virtual ~MockWebBlobRegistryImpl(); + ~MockWebBlobRegistryImpl() override; - virtual void registerBlobData(const blink::WebString& uuid, - const blink::WebBlobData& data); - virtual void addBlobDataRef(const blink::WebString& uuid); - virtual void removeBlobDataRef(const blink::WebString& uuid); - virtual void registerPublicBlobURL(const blink::WebURL&, - const blink::WebString& uuid); - virtual void revokePublicBlobURL(const blink::WebURL&); + void registerBlobData(const blink::WebString& uuid, + const blink::WebBlobData& data) override; + void addBlobDataRef(const blink::WebString& uuid) override; + void removeBlobDataRef(const blink::WebString& uuid) override; + void registerPublicBlobURL(const blink::WebURL&, + const blink::WebString& uuid) override; + void revokePublicBlobURL(const blink::WebURL&) override; // Additional support for Streams. - virtual void registerStreamURL(const blink::WebURL& url, - const blink::WebString& content_type); - virtual void registerStreamURL(const blink::WebURL& url, - const blink::WebURL& src_url); - virtual void addDataToStream(const blink::WebURL& url, - const char* data, - size_t length); - virtual void flushStream(const blink::WebURL& url); - virtual void finalizeStream(const blink::WebURL& url); - virtual void abortStream(const blink::WebURL& url); - virtual void unregisterStreamURL(const blink::WebURL& url); + void registerStreamURL(const blink::WebURL& url, + const blink::WebString& content_type) override; + void registerStreamURL(const blink::WebURL& url, + const blink::WebURL& src_url) override; + void addDataToStream(const blink::WebURL& url, + const char* data, + size_t length) override; + void flushStream(const blink::WebURL& url) override; + void finalizeStream(const blink::WebURL& url) override; + void abortStream(const blink::WebURL& url) override; + void unregisterStreamURL(const blink::WebURL& url) override; bool GetUUIDForURL(const blink::WebURL& url, blink::WebString* uuid) const; bool GetBlobItems(const blink::WebString& uuid,
diff --git a/components/html_viewer/test_html_viewer_impl.cc b/components/html_viewer/test_html_viewer_impl.cc index b006255..b8f98ee 100644 --- a/components/html_viewer/test_html_viewer_impl.cc +++ b/components/html_viewer/test_html_viewer_impl.cc
@@ -42,11 +42,12 @@ ExecutionCallbackImpl(TestHTMLViewerImpl* host, const mojo::Callback<void(mojo::String)>& callback) : host_(host), callback_(callback) {} - virtual ~ExecutionCallbackImpl() {} + ~ExecutionCallbackImpl() override {} private: // blink::WebScriptExecutionCallback: - virtual void completed(const blink::WebVector<v8::Local<v8::Value>>& result) { + void completed( + const blink::WebVector<v8::Local<v8::Value>>& result) override { mojo::String callback_result; if (!result.isEmpty()) callback_result = V8ValueToJSONString(host_->web_frame_, result);
diff --git a/components/html_viewer/web_clipboard_impl.h b/components/html_viewer/web_clipboard_impl.h index 407ef81..fd1e18a 100644 --- a/components/html_viewer/web_clipboard_impl.h +++ b/components/html_viewer/web_clipboard_impl.h
@@ -16,24 +16,24 @@ virtual ~WebClipboardImpl(); // blink::WebClipboard methods: - virtual uint64_t sequenceNumber(Buffer); - virtual bool isFormatAvailable(Format, Buffer); - virtual blink::WebVector<blink::WebString> readAvailableTypes( + uint64_t sequenceNumber(Buffer) override; + bool isFormatAvailable(Format, Buffer) override; + blink::WebVector<blink::WebString> readAvailableTypes( Buffer buffer, - bool* contains_filenames); - virtual blink::WebString readPlainText(Buffer buffer); - virtual blink::WebString readHTML(Buffer buffer, - blink::WebURL* page_url, - unsigned* fragment_start, - unsigned* fragment_end); + bool* contains_filenames) override; + blink::WebString readPlainText(Buffer buffer) override; + blink::WebString readHTML(Buffer buffer, + blink::WebURL* page_url, + unsigned* fragment_start, + unsigned* fragment_end) override; // TODO(erg): readImage() - virtual blink::WebString readCustomData(Buffer buffer, - const blink::WebString& type); - virtual void writePlainText(const blink::WebString& plain_text); - virtual void writeHTML(const blink::WebString& html_text, - const blink::WebURL& source_url, - const blink::WebString& plain_text, - bool write_smart_paste); + blink::WebString readCustomData(Buffer buffer, + const blink::WebString& type) override; + void writePlainText(const blink::WebString& plain_text) override; + void writeHTML(const blink::WebString& html_text, + const blink::WebURL& source_url, + const blink::WebString& plain_text, + bool write_smart_paste) override; private: // Changes webkit buffers to mojo Clipboard::Types.
diff --git a/components/html_viewer/web_cookie_jar_impl.h b/components/html_viewer/web_cookie_jar_impl.h index bec897e..d8ae21ba 100644 --- a/components/html_viewer/web_cookie_jar_impl.h +++ b/components/html_viewer/web_cookie_jar_impl.h
@@ -16,15 +16,15 @@ virtual ~WebCookieJarImpl(); // blink::WebCookieJar methods: - virtual void setCookie(const blink::WebURL& url, - const blink::WebURL& first_party_for_cookies, - const blink::WebString& cookie); - virtual blink::WebString cookies( + void setCookie(const blink::WebURL& url, + const blink::WebURL& first_party_for_cookies, + const blink::WebString& cookie) override; + blink::WebString cookies( const blink::WebURL& url, - const blink::WebURL& first_party_for_cookies); - virtual blink::WebString cookieRequestHeaderFieldValue( + const blink::WebURL& first_party_for_cookies) override; + blink::WebString cookieRequestHeaderFieldValue( const blink::WebURL& url, - const blink::WebURL& first_party_for_cookies); + const blink::WebURL& first_party_for_cookies) override; private: mojo::CookieStorePtr store_;
diff --git a/components/html_viewer/web_graphics_context_3d_command_buffer_impl.h b/components/html_viewer/web_graphics_context_3d_command_buffer_impl.h index 37076df..adcd03db 100644 --- a/components/html_viewer/web_graphics_context_3d_command_buffer_impl.h +++ b/components/html_viewer/web_graphics_context_3d_command_buffer_impl.h
@@ -44,7 +44,7 @@ const GURL& active_url, const blink::WebGraphicsContext3D::Attributes& attributes, blink::WebGraphicsContext3D* share_context); - virtual ~WebGraphicsContext3DCommandBufferImpl(); + ~WebGraphicsContext3DCommandBufferImpl() override; static void ContextLostThunk(void* closure) { static_cast<WebGraphicsContext3DCommandBufferImpl*>(closure)->ContextLost();
diff --git a/components/html_viewer/web_layer_tree_view_impl.cc b/components/html_viewer/web_layer_tree_view_impl.cc index c379bc9b..2f793b8 100644 --- a/components/html_viewer/web_layer_tree_view_impl.cc +++ b/components/html_viewer/web_layer_tree_view_impl.cc
@@ -41,6 +41,9 @@ // to keep content always crisp when possible. settings.layer_transforms_should_scale_layer_contents = true; + // Use new animation system (cc::AnimationHost). + settings.use_compositor_animation_timelines = true; + // TODO(rjkroege): Not having a shared tile transport breaks // software compositing. Add bitmap transport support. cc::SharedBitmapManager* shared_bitmap_manager = nullptr;
diff --git a/components/html_viewer/web_layer_tree_view_impl.h b/components/html_viewer/web_layer_tree_view_impl.h index aa2ee3cb..bcd833b 100644 --- a/components/html_viewer/web_layer_tree_view_impl.h +++ b/components/html_viewer/web_layer_tree_view_impl.h
@@ -72,40 +72,40 @@ override {} // blink::WebLayerTreeView implementation. - virtual void setRootLayer(const blink::WebLayer& layer); - virtual void clearRootLayer(); - virtual void setViewportSize(const blink::WebSize& device_viewport_size); - virtual void setDeviceScaleFactor(float); + void setRootLayer(const blink::WebLayer& layer) override; + void clearRootLayer() override; + void setViewportSize(const blink::WebSize& device_viewport_size) override; + void setDeviceScaleFactor(float) override; virtual float deviceScaleFactor() const; - virtual void setBackgroundColor(blink::WebColor color); - virtual void setHasTransparentBackground(bool has_transparent_background); - virtual void setVisible(bool visible); - virtual void setPageScaleFactorAndLimits(float page_scale_factor, - float minimum, - float maximum); - virtual void startPageScaleAnimation(const blink::WebPoint& destination, - bool use_anchor, - float new_page_scale, - double duration_sec); - virtual void heuristicsForGpuRasterizationUpdated(bool matches_heuristic) {} - virtual void setNeedsAnimate(); - virtual void didStopFlinging() {} - virtual void compositeAndReadbackAsync( - blink::WebCompositeAndReadbackAsyncCallback* callback) {} - virtual void setDeferCommits(bool defer_commits) {} - virtual void registerForAnimations(blink::WebLayer* layer); - virtual void registerViewportLayers( + void setBackgroundColor(blink::WebColor color) override; + void setHasTransparentBackground(bool has_transparent_background) override; + void setVisible(bool visible) override; + void setPageScaleFactorAndLimits(float page_scale_factor, + float minimum, + float maximum) override; + void startPageScaleAnimation(const blink::WebPoint& destination, + bool use_anchor, + float new_page_scale, + double duration_sec) override; + void heuristicsForGpuRasterizationUpdated(bool matches_heuristic) override {} + void setNeedsAnimate() override; + void didStopFlinging() override {} + void compositeAndReadbackAsync( + blink::WebCompositeAndReadbackAsyncCallback* callback) override {} + void setDeferCommits(bool defer_commits) override {} + void registerForAnimations(blink::WebLayer* layer) override; + void registerViewportLayers( const blink::WebLayer* overscrollElasticityLayer, const blink::WebLayer* pageScaleLayerLayer, const blink::WebLayer* innerViewportScrollLayer, - const blink::WebLayer* outerViewportScrollLayer); - virtual void clearViewportLayers(); - virtual void registerSelection(const blink::WebSelection& selection) {} - virtual void clearSelection() {} - virtual void setShowFPSCounter(bool) {} - virtual void setShowPaintRects(bool) {} - virtual void setShowDebugBorders(bool) {} - virtual void setShowScrollBottleneckRects(bool) {} + const blink::WebLayer* outerViewportScrollLayer) override; + void clearViewportLayers() override; + void registerSelection(const blink::WebSelection& selection) override {} + void clearSelection() override {} + void setShowFPSCounter(bool) override {} + void setShowPaintRects(bool) override {} + void setShowDebugBorders(bool) override {} + void setShowScrollBottleneckRects(bool) override {} private: // widget_ and window_ will outlive us.
diff --git a/components/html_viewer/web_mime_registry_impl.h b/components/html_viewer/web_mime_registry_impl.h index 0440adcd..f0214880 100644 --- a/components/html_viewer/web_mime_registry_impl.h +++ b/components/html_viewer/web_mime_registry_impl.h
@@ -16,26 +16,26 @@ virtual ~WebMimeRegistryImpl() {} // WebMimeRegistry methods: - virtual blink::WebMimeRegistry::SupportsType supportsMIMEType( - const blink::WebString& mime_type); - virtual blink::WebMimeRegistry::SupportsType supportsImageMIMEType( - const blink::WebString& mime_type); - virtual blink::WebMimeRegistry::SupportsType supportsImagePrefixedMIMEType( - const blink::WebString& mime_type); - virtual blink::WebMimeRegistry::SupportsType supportsJavaScriptMIMEType( - const blink::WebString& mime_type); - virtual blink::WebMimeRegistry::SupportsType supportsMediaMIMEType( + blink::WebMimeRegistry::SupportsType supportsMIMEType( + const blink::WebString& mime_type) override; + blink::WebMimeRegistry::SupportsType supportsImageMIMEType( + const blink::WebString& mime_type) override; + blink::WebMimeRegistry::SupportsType supportsImagePrefixedMIMEType( + const blink::WebString& mime_type) override; + blink::WebMimeRegistry::SupportsType supportsJavaScriptMIMEType( + const blink::WebString& mime_type) override; + blink::WebMimeRegistry::SupportsType supportsMediaMIMEType( const blink::WebString& mime_type, const blink::WebString& codecs, - const blink::WebString& key_system); - virtual bool supportsMediaSourceMIMEType(const blink::WebString& mime_type, - const blink::WebString& codecs); - virtual blink::WebMimeRegistry::SupportsType supportsNonImageMIMEType( - const blink::WebString& mime_type); - virtual blink::WebString mimeTypeForExtension( - const blink::WebString& extension); - virtual blink::WebString wellKnownMimeTypeForExtension( - const blink::WebString& extension); + const blink::WebString& key_system) override; + bool supportsMediaSourceMIMEType(const blink::WebString& mime_type, + const blink::WebString& codecs) override; + blink::WebMimeRegistry::SupportsType supportsNonImageMIMEType( + const blink::WebString& mime_type) override; + blink::WebString mimeTypeForExtension( + const blink::WebString& extension) override; + blink::WebString wellKnownMimeTypeForExtension( + const blink::WebString& extension) override; }; } // namespace html_viewer
diff --git a/components/html_viewer/web_socket_handle_impl.h b/components/html_viewer/web_socket_handle_impl.h index 9537d3e..fda06b00 100644 --- a/components/html_viewer/web_socket_handle_impl.h +++ b/components/html_viewer/web_socket_handle_impl.h
@@ -28,16 +28,16 @@ private: friend class WebSocketClientImpl; - virtual ~WebSocketHandleImpl(); + ~WebSocketHandleImpl() override; // blink::WebSocketHandle methods: - virtual void connect(const blink::WebURL& url, - const blink::WebVector<blink::WebString>& protocols, - const blink::WebSecurityOrigin& origin, - blink::WebSocketHandleClient*); - virtual void send(bool fin, MessageType, const char* data, size_t size); - virtual void flowControl(int64_t quota); - virtual void close(unsigned short code, const blink::WebString& reason); + void connect(const blink::WebURL& url, + const blink::WebVector<blink::WebString>& protocols, + const blink::WebSecurityOrigin& origin, + blink::WebSocketHandleClient*) override; + void send(bool fin, MessageType, const char* data, size_t size) override; + void flowControl(int64_t quota) override; + void close(unsigned short code, const blink::WebString& reason) override; // Called when we finished writing to |send_stream_|. void DidWriteToSendStream(bool fin,
diff --git a/components/html_viewer/web_storage_namespace_impl.h b/components/html_viewer/web_storage_namespace_impl.h index 1c199aa..3ccb864 100644 --- a/components/html_viewer/web_storage_namespace_impl.h +++ b/components/html_viewer/web_storage_namespace_impl.h
@@ -15,12 +15,12 @@ WebStorageNamespaceImpl(); private: - virtual ~WebStorageNamespaceImpl(); + ~WebStorageNamespaceImpl() override; // blink::WebStorageNamespace methods: - virtual blink::WebStorageArea* createStorageArea( - const blink::WebString& origin); - virtual bool isSameNamespace(const blink::WebStorageNamespace&) const; + blink::WebStorageArea* createStorageArea( + const blink::WebString& origin) override; + bool isSameNamespace(const blink::WebStorageNamespace&) const override; DISALLOW_COPY_AND_ASSIGN(WebStorageNamespaceImpl); };
diff --git a/components/html_viewer/web_theme_engine_impl.h b/components/html_viewer/web_theme_engine_impl.h index e146e9d..bce5501 100644 --- a/components/html_viewer/web_theme_engine_impl.h +++ b/components/html_viewer/web_theme_engine_impl.h
@@ -12,12 +12,12 @@ class WebThemeEngineImpl : public blink::WebThemeEngine { public: // WebThemeEngine methods: - virtual blink::WebSize getSize(blink::WebThemeEngine::Part); - virtual void paint(blink::WebCanvas* canvas, - blink::WebThemeEngine::Part part, - blink::WebThemeEngine::State state, - const blink::WebRect& rect, - const blink::WebThemeEngine::ExtraParams* extra_params); + blink::WebSize getSize(blink::WebThemeEngine::Part) override; + void paint(blink::WebCanvas* canvas, + blink::WebThemeEngine::Part part, + blink::WebThemeEngine::State state, + const blink::WebRect& rect, + const blink::WebThemeEngine::ExtraParams* extra_params) override; virtual void paintStateTransition(blink::WebCanvas* canvas, blink::WebThemeEngine::Part part, blink::WebThemeEngine::State startState,
diff --git a/components/html_viewer/web_url_loader_impl.h b/components/html_viewer/web_url_loader_impl.h index a513efa..09dcf27 100644 --- a/components/html_viewer/web_url_loader_impl.h +++ b/components/html_viewer/web_url_loader_impl.h
@@ -25,7 +25,7 @@ class WebURLRequestExtraData : public blink::WebURLRequest::ExtraData { public: WebURLRequestExtraData(); - virtual ~WebURLRequestExtraData(); + ~WebURLRequestExtraData() override; mojo::URLResponsePtr synthetic_response; }; @@ -36,18 +36,18 @@ MockWebBlobRegistryImpl* web_blob_registry); private: - virtual ~WebURLLoaderImpl(); + ~WebURLLoaderImpl() override; // blink::WebURLLoader methods: - virtual void loadSynchronously(const blink::WebURLRequest& request, - blink::WebURLResponse& response, - blink::WebURLError& error, - blink::WebData& data); - virtual void loadAsynchronously(const blink::WebURLRequest&, - blink::WebURLLoaderClient* client); - virtual void cancel(); - virtual void setDefersLoading(bool defers_loading); - virtual void setLoadingTaskRunner(blink::WebTaskRunner* web_task_runner); + void loadSynchronously(const blink::WebURLRequest& request, + blink::WebURLResponse& response, + blink::WebURLError& error, + blink::WebData& data) override; + void loadAsynchronously(const blink::WebURLRequest&, + blink::WebURLLoaderClient* client) override; + void cancel() override; + void setDefersLoading(bool defers_loading) override; + void setLoadingTaskRunner(blink::WebTaskRunner* web_task_runner) override; void OnReceivedResponse(const blink::WebURLRequest& request, mojo::URLResponsePtr response);
diff --git a/components/mus/public/cpp/BUILD.gn b/components/mus/public/cpp/BUILD.gn index 926acb4..015040a 100644 --- a/components/mus/public/cpp/BUILD.gn +++ b/components/mus/public/cpp/BUILD.gn
@@ -34,6 +34,7 @@ "window_tracker.cc", "window_tracker.h", "window_tree_connection.h", + "window_tree_connection_observer.h", "window_tree_delegate.h", "window_tree_host_factory.h", ]
diff --git a/components/mus/public/cpp/lib/event_matcher.cc b/components/mus/public/cpp/lib/event_matcher.cc index 702ad53..b619adf 100644 --- a/components/mus/public/cpp/lib/event_matcher.cc +++ b/components/mus/public/cpp/lib/event_matcher.cc
@@ -11,6 +11,13 @@ mojom::EventMatcherPtr matcher(mojom::EventMatcher::New()); matcher->type_matcher = mojom::EventTypeMatcher::New(); matcher->flags_matcher = mojom::EventFlagsMatcher::New(); + matcher->ignore_flags_matcher = mojom::EventFlagsMatcher::New(); + // Ignoring these makes most accelerator scenarios more straight forward. Code + // that needs to check them can override this setting. + matcher->ignore_flags_matcher->flags = + static_cast<mojom::EventFlags>(mojom::EVENT_FLAGS_CAPS_LOCK_DOWN | + mojom::EVENT_FLAGS_SCROLL_LOCK_DOWN | + mojom::EVENT_FLAGS_NUM_LOCK_DOWN); matcher->key_matcher = mojom::KeyEventMatcher::New(); matcher->type_matcher->type = mus::mojom::EVENT_TYPE_KEY_PRESSED;
diff --git a/components/mus/public/cpp/lib/in_flight_change.cc b/components/mus/public/cpp/lib/in_flight_change.cc index 002ee3f..922ae13 100644 --- a/components/mus/public/cpp/lib/in_flight_change.cc +++ b/components/mus/public/cpp/lib/in_flight_change.cc
@@ -5,6 +5,7 @@ #include "components/mus/public/cpp/lib/in_flight_change.h" #include "components/mus/public/cpp/lib/window_private.h" +#include "components/mus/public/cpp/lib/window_tree_client_impl.h" #include "components/mus/public/cpp/window_tree_connection.h" namespace mus { @@ -58,6 +59,41 @@ CHECK(false); } +// InFlightFocusChange -------------------------------------------------------- + +InFlightFocusChange::InFlightFocusChange(WindowTreeClientImpl* connection, + Window* window) + : InFlightChange(nullptr, ChangeType::FOCUS), + connection_(connection), + revert_window_(nullptr) { + SetRevertWindow(window); +} + +InFlightFocusChange::~InFlightFocusChange() { + SetRevertWindow(nullptr); +} + +void InFlightFocusChange::SetRevertValueFrom(const InFlightChange& change) { + SetRevertWindow( + static_cast<const InFlightFocusChange&>(change).revert_window_); +} + +void InFlightFocusChange::Revert() { + connection_->LocalSetFocus(revert_window_); +} + +void InFlightFocusChange::SetRevertWindow(Window* window) { + if (revert_window_) + revert_window_->RemoveObserver(this); + revert_window_ = window; + if (revert_window_) + revert_window_->AddObserver(this); +} + +void InFlightFocusChange::OnWindowDestroying(Window* window) { + SetRevertWindow(nullptr); +} + // InFlightPropertyChange ----------------------------------------------------- InFlightPropertyChange::InFlightPropertyChange( @@ -85,6 +121,26 @@ .LocalSetSharedProperty(property_name_, revert_value_.Pass()); } +// InFlightPredefinedCursorChange --------------------------------------------- + +InFlightPredefinedCursorChange::InFlightPredefinedCursorChange( + Window* window, + mojom::Cursor revert_value) + : InFlightChange(window, ChangeType::PREDEFINED_CURSOR), + revert_cursor_(revert_value) {} + +InFlightPredefinedCursorChange::~InFlightPredefinedCursorChange() {} + +void InFlightPredefinedCursorChange::SetRevertValueFrom( + const InFlightChange& change) { + revert_cursor_ = + static_cast<const InFlightPredefinedCursorChange&>(change).revert_cursor_; +} + +void InFlightPredefinedCursorChange::Revert() { + WindowPrivate(window()).LocalSetPredefinedCursor(revert_cursor_); +} + // InFlightVisibleChange ------------------------------------------------------- InFlightVisibleChange::InFlightVisibleChange(Window* window,
diff --git a/components/mus/public/cpp/lib/in_flight_change.h b/components/mus/public/cpp/lib/in_flight_change.h index 33d0417..54aa779 100644 --- a/components/mus/public/cpp/lib/in_flight_change.h +++ b/components/mus/public/cpp/lib/in_flight_change.h
@@ -10,20 +10,31 @@ #include "base/macros.h" #include "base/memory/scoped_ptr.h" +#include "components/mus/public/cpp/window_observer.h" #include "mojo/public/cpp/bindings/array.h" #include "ui/gfx/geometry/rect.h" namespace mus { +namespace mojom { +enum Cursor : int32_t; +} + class Window; +class WindowTreeClientImpl; enum class ChangeType { + ADD_CHILD, ADD_TRANSIENT_WINDOW, BOUNDS, DELETE_WINDOW, + FOCUS, NEW_WINDOW, + PREDEFINED_CURSOR, PROPERTY, + REMOVE_CHILD, REMOVE_TRANSIENT_WINDOW_FROM_PARENT, + REORDER, VISIBLE, }; @@ -49,11 +60,41 @@ // InFlightChange for the same window outstanding, then ChangeFailed() is // invoked followed by Revert(). The expectation is Revert() sets the // appropriate value back on the Window. +// +// In general there are two classes of changes: +// 1. We are the only side allowed to make the change. +// 2. The change can also be applied by another client. For example, the +// window manager may change the bounds as well as the local client. +// +// For (1) use CrashInFlightChange. As the name implies this change CHECKs that +// the change succeeded. Use the following pattern for this. This code goes +// where the change is sent to the server (in WindowTreeClientImpl): +// const uint32_t change_id = +// ScheduleInFlightChange(make_scoped_ptr(new CrashInFlightChange( +// window, ChangeType::REORDER))); +// +// For (2) use the same pattern as (1), but in the on change callback from the +// server (e.g. OnWindowBoundsChanged()) add the following: +// // value_from_server is the value supplied from the server. It corresponds +// // to the value of the property at the time the server processed the +// // change. If the local change fails, this is the value reverted to. +// InFlightBoundsChange new_change(window, value_from_server); +// if (ApplyServerChangeToExistingInFlightChange(new_change)) { +// // There was an in flight change for the same property. The in flight +// // change takes the value to revert from |new_change|. +// return; +// } +// +// // else case is no flight in change and the new value can be applied +// // immediately. +// WindowPrivate(window).LocalSetValue(new_value_from_server); +// class InFlightChange { public: InFlightChange(Window* window, ChangeType type); virtual ~InFlightChange(); + // NOTE: for properties not associated with any window window is null. Window* window() { return window_; } const Window* window() const { return window_; } ChangeType change_type() const { return change_type_; } @@ -112,6 +153,31 @@ DISALLOW_COPY_AND_ASSIGN(CrashInFlightChange); }; +// Focus is really a property of the WindowTreeConnection and not the Window. +// As such, InFlightFocusChange is special in that it is not associated with +// a particular window (InFlightFocusChange::window() returns null). Internally +// InFlightFocusChange tracks a window to give focus to, but it may be null. +class InFlightFocusChange : public InFlightChange, public WindowObserver { + public: + InFlightFocusChange(WindowTreeClientImpl* connection, Window* revert_window); + ~InFlightFocusChange() override; + + // InFlightChange: + void SetRevertValueFrom(const InFlightChange& change) override; + void Revert() override; + + private: + void SetRevertWindow(Window* window); + + // WindowObserver: + void OnWindowDestroying(Window* window) override; + + WindowTreeClientImpl* connection_; + Window* revert_window_; + + DISALLOW_COPY_AND_ASSIGN(InFlightFocusChange); +}; + class InFlightPropertyChange : public InFlightChange { public: InFlightPropertyChange(Window* window, @@ -131,6 +197,21 @@ DISALLOW_COPY_AND_ASSIGN(InFlightPropertyChange); }; +class InFlightPredefinedCursorChange : public InFlightChange { + public: + InFlightPredefinedCursorChange(Window* window, mojom::Cursor revert_value); + ~InFlightPredefinedCursorChange() override; + + // InFlightChange: + void SetRevertValueFrom(const InFlightChange& change) override; + void Revert() override; + + private: + mojom::Cursor revert_cursor_; + + DISALLOW_COPY_AND_ASSIGN(InFlightPredefinedCursorChange); +}; + class InFlightVisibleChange : public InFlightChange { public: InFlightVisibleChange(Window* window, const bool revert_value);
diff --git a/components/mus/public/cpp/lib/window.cc b/components/mus/public/cpp/lib/window.cc index aa77867d..084bac5 100644 --- a/components/mus/public/cpp/lib/window.cc +++ b/components/mus/public/cpp/lib/window.cc
@@ -192,13 +192,15 @@ LocalSetBounds(bounds_, bounds); } -void Window::SetClientArea(const gfx::Insets& client_area) { +void Window::SetClientArea( + const gfx::Insets& client_area, + const std::vector<gfx::Rect>& additional_client_areas) { if (!OwnsWindowOrIsRoot(this)) return; if (connection_) - tree_client()->SetClientArea(id_, client_area); - LocalSetClientArea(client_area); + tree_client()->SetClientArea(id_, client_area, additional_client_areas); + LocalSetClientArea(client_area, additional_client_areas); } void Window::SetVisible(bool value) { @@ -210,6 +212,15 @@ LocalSetVisible(value); } +void Window::SetPredefinedCursor(mus::mojom::Cursor cursor_id) { + if (cursor_id_ == cursor_id) + return; + + if (connection_) + tree_client()->SetPredefinedCursor(id_, cursor_id); + LocalSetPredefinedCursor(cursor_id); +} + bool Window::IsDrawn() const { if (!visible_) return false; @@ -219,15 +230,15 @@ scoped_ptr<WindowSurface> Window::RequestSurface(mojom::SurfaceType type) { scoped_ptr<WindowSurfaceBinding> surface_binding; scoped_ptr<WindowSurface> surface = WindowSurface::Create(&surface_binding); - AttachSurface(type, surface_binding.Pass()); + AttachSurface(type, std::move(surface_binding)); return surface; } void Window::AttachSurface(mojom::SurfaceType type, scoped_ptr<WindowSurfaceBinding> surface_binding) { - tree_client()->AttachSurface(id_, type, - surface_binding->surface_request_.Pass(), - surface_binding->surface_client_.Pass()); + tree_client()->AttachSurface( + id_, type, std::move(surface_binding->surface_request_), + mojo::MakeProxy(std::move(surface_binding->surface_client_))); } void Window::ClearSharedProperty(const std::string& name) { @@ -260,7 +271,7 @@ CHECK_EQ(child->connection(), connection_); LocalAddChild(child); if (connection_) - tree_client()->AddChild(child->id(), id_); + tree_client()->AddChild(this, child->id()); } void Window::RemoveChild(Window* child) { @@ -270,14 +281,14 @@ CHECK_EQ(child->connection(), connection_); LocalRemoveChild(child); if (connection_) - tree_client()->RemoveChild(child->id(), id_); + tree_client()->RemoveChild(this, child->id()); } void Window::Reorder(Window* relative, mojom::OrderDirection direction) { if (!LocalReorder(relative, direction)) return; if (connection_) - tree_client()->Reorder(id_, relative->id(), direction); + tree_client()->Reorder(this, relative->id(), direction); } void Window::MoveToFront() { @@ -349,8 +360,8 @@ } void Window::SetFocus() { - if (connection_) - tree_client()->SetFocus(id_); + if (connection_ && IsDrawn()) + tree_client()->SetFocus(this); } bool Window::HasFocus() const { @@ -562,11 +573,17 @@ bounds_ = new_bounds; } -void Window::LocalSetClientArea(const gfx::Insets& new_client_area) { +void Window::LocalSetClientArea( + const gfx::Insets& new_client_area, + const std::vector<gfx::Rect>& additional_client_areas) { + const std::vector<gfx::Rect> old_additional_client_areas = + additional_client_areas_; const gfx::Insets old_client_area = client_area_; client_area_ = new_client_area; + additional_client_areas_ = additional_client_areas; FOR_EACH_OBSERVER(WindowObserver, observers_, - OnWindowClientAreaChanged(this, old_client_area)); + OnWindowClientAreaChanged(this, old_client_area, + old_additional_client_areas)); } void Window::LocalSetViewportMetrics( @@ -604,6 +621,15 @@ NotifyWindowVisibilityChanged(this); } +void Window::LocalSetPredefinedCursor(mojom::Cursor cursor_id) { + if (cursor_id_ == cursor_id) + return; + + cursor_id_ = cursor_id; + FOR_EACH_OBSERVER(WindowObserver, observers_, + OnWindowPredefinedCursorChanged(this, cursor_id)); +} + void Window::LocalSetSharedProperty(const std::string& name, const std::vector<uint8_t>* value) { std::vector<uint8_t> old_value;
diff --git a/components/mus/public/cpp/lib/window_private.h b/components/mus/public/cpp/lib/window_private.h index 930ffb3c..d1bec3f3 100644 --- a/components/mus/public/cpp/lib/window_private.h +++ b/components/mus/public/cpp/lib/window_private.h
@@ -5,6 +5,8 @@ #ifndef COMPONENTS_MUS_PUBLIC_CPP_LIB_WINDOW_PRIVATE_H_ #define COMPONENTS_MUS_PUBLIC_CPP_LIB_WINDOW_PRIVATE_H_ +#include <vector> + #include "components/mus/public/cpp/window.h" #include "mojo/public/cpp/bindings/array.h" @@ -63,11 +65,16 @@ const gfx::Rect& new_bounds) { window_->LocalSetBounds(old_bounds, new_bounds); } - void LocalSetClientArea(const gfx::Insets& new_client_area) { - window_->LocalSetClientArea(new_client_area); + void LocalSetClientArea( + const gfx::Insets& client_area, + const std::vector<gfx::Rect>& additional_client_areas) { + window_->LocalSetClientArea(client_area, additional_client_areas); } void LocalSetDrawn(bool drawn) { window_->LocalSetDrawn(drawn); } void LocalSetVisible(bool visible) { window_->LocalSetVisible(visible); } + void LocalSetPredefinedCursor(mojom::Cursor cursor) { + window_->LocalSetPredefinedCursor(cursor); + } void LocalSetSharedProperty(const std::string& name, mojo::Array<uint8_t> new_data); void LocalSetSharedProperty(const std::string& name,
diff --git a/components/mus/public/cpp/lib/window_surface.cc b/components/mus/public/cpp/lib/window_surface.cc index 076243c..746d31c 100644 --- a/components/mus/public/cpp/lib/window_surface.cc +++ b/components/mus/public/cpp/lib/window_surface.cc
@@ -17,10 +17,10 @@ mojo::InterfaceRequest<mojom::SurfaceClient> surface_client_request = GetProxy(&surface_client); - surface_binding->reset( - new WindowSurfaceBinding(GetProxy(&surface), surface_client.Pass())); + surface_binding->reset(new WindowSurfaceBinding( + GetProxy(&surface), surface_client.PassInterface())); return make_scoped_ptr(new WindowSurface(surface.PassInterface(), - surface_client_request.Pass())); + std::move(surface_client_request))); } WindowSurface::~WindowSurface() {} @@ -28,9 +28,9 @@ void WindowSurface::BindToThread() { DCHECK(!thread_checker_); thread_checker_.reset(new base::ThreadChecker()); - surface_.Bind(surface_info_.Pass()); - client_binding_.reset( - new mojo::Binding<mojom::SurfaceClient>(this, client_request_.Pass())); + surface_.Bind(std::move(surface_info_)); + client_binding_.reset(new mojo::Binding<mojom::SurfaceClient>( + this, std::move(client_request_))); } void WindowSurface::SubmitCompositorFrame(mojom::CompositorFramePtr frame, @@ -39,15 +39,15 @@ DCHECK(thread_checker_->CalledOnValidThread()); if (!surface_) return; - surface_->SubmitCompositorFrame(frame.Pass(), callback); + surface_->SubmitCompositorFrame(std::move(frame), callback); } WindowSurface::WindowSurface( mojo::InterfacePtrInfo<mojom::Surface> surface_info, mojo::InterfaceRequest<mojom::SurfaceClient> client_request) : client_(nullptr), - surface_info_(surface_info.Pass()), - client_request_(client_request.Pass()) {} + surface_info_(std::move(surface_info)), + client_request_(std::move(client_request)) {} void WindowSurface::ReturnResources( mojo::Array<mojom::ReturnedResourcePtr> resources) { @@ -55,15 +55,15 @@ DCHECK(thread_checker_->CalledOnValidThread()); if (!client_) return; - client_->OnResourcesReturned(this, resources.Pass()); + client_->OnResourcesReturned(this, std::move(resources)); } WindowSurfaceBinding::~WindowSurfaceBinding() {} WindowSurfaceBinding::WindowSurfaceBinding( mojo::InterfaceRequest<mojom::Surface> surface_request, - mojom::SurfaceClientPtr surface_client) - : surface_request_(surface_request.Pass()), - surface_client_(surface_client.Pass()) {} + mojo::InterfacePtrInfo<mojom::SurfaceClient> surface_client) + : surface_request_(std::move(surface_request)), + surface_client_(std::move(surface_client)) {} } // namespace mus
diff --git a/components/mus/public/cpp/lib/window_tree_client_impl.cc b/components/mus/public/cpp/lib/window_tree_client_impl.cc index 2b094e9..570c9b5b 100644 --- a/components/mus/public/cpp/lib/window_tree_client_impl.cc +++ b/components/mus/public/cpp/lib/window_tree_client_impl.cc
@@ -11,6 +11,7 @@ #include "components/mus/public/cpp/window_manager_delegate.h" #include "components/mus/public/cpp/window_observer.h" #include "components/mus/public/cpp/window_tree_connection.h" +#include "components/mus/public/cpp/window_tree_connection_observer.h" #include "components/mus/public/cpp/window_tree_delegate.h" #include "mojo/application/public/cpp/application_impl.h" #include "mojo/application/public/cpp/connect.h" @@ -157,14 +158,18 @@ tree_->DeleteWindow(change_id, window->id()); } -void WindowTreeClientImpl::AddChild(Id child_id, Id parent_id) { +void WindowTreeClientImpl::AddChild(Window* parent, Id child_id) { DCHECK(tree_); - tree_->AddWindow(parent_id, child_id, ActionCompletedCallback()); + const uint32_t change_id = ScheduleInFlightChange( + make_scoped_ptr(new CrashInFlightChange(parent, ChangeType::ADD_CHILD))); + tree_->AddWindow(change_id, parent->id(), child_id); } -void WindowTreeClientImpl::RemoveChild(Id child_id, Id parent_id) { +void WindowTreeClientImpl::RemoveChild(Window* parent, Id child_id) { DCHECK(tree_); - tree_->RemoveWindowFromParent(child_id, ActionCompletedCallback()); + const uint32_t change_id = ScheduleInFlightChange(make_scoped_ptr( + new CrashInFlightChange(parent, ChangeType::REMOVE_CHILD))); + tree_->RemoveWindowFromParent(change_id, child_id); } void WindowTreeClientImpl::AddTransientWindow(Window* window, @@ -183,12 +188,13 @@ tree_->RemoveTransientWindowFromParent(change_id, window->id()); } -void WindowTreeClientImpl::Reorder(Id window_id, +void WindowTreeClientImpl::Reorder(Window* window, Id relative_window_id, mojom::OrderDirection direction) { DCHECK(tree_); - tree_->ReorderWindow(window_id, relative_window_id, direction, - ActionCompletedCallback()); + const uint32_t change_id = ScheduleInFlightChange( + make_scoped_ptr(new CrashInFlightChange(window, ChangeType::REORDER))); + tree_->ReorderWindow(change_id, window->id(), relative_window_id, direction); } bool WindowTreeClientImpl::OwnsWindow(Id id) const { @@ -204,17 +210,24 @@ tree_->SetWindowBounds(change_id, window->id(), mojo::Rect::From(bounds)); } -void WindowTreeClientImpl::SetClientArea(Id window_id, - const gfx::Insets& client_area) { +void WindowTreeClientImpl::SetClientArea( + Id window_id, + const gfx::Insets& client_area, + const std::vector<gfx::Rect>& additional_client_areas) { DCHECK(tree_); - tree_->SetClientArea(window_id, mojo::Insets::From(client_area)); + tree_->SetClientArea( + window_id, mojo::Insets::From(client_area), + mojo::Array<mojo::RectPtr>::From(additional_client_areas)); } -void WindowTreeClientImpl::SetFocus(Id window_id) { +void WindowTreeClientImpl::SetFocus(Window* window) { // In order for us to get here we had to have exposed a window, which implies // we got a connection. DCHECK(tree_); - tree_->SetFocus(window_id); + const uint32_t change_id = ScheduleInFlightChange( + make_scoped_ptr(new InFlightFocusChange(this, focused_window_))); + tree_->SetFocus(change_id, window ? window->id() : 0); + LocalSetFocus(window); } void WindowTreeClientImpl::SetCanFocus(Id window_id, bool can_focus) { @@ -222,6 +235,20 @@ tree_->SetCanFocus(window_id, can_focus); } +void WindowTreeClientImpl::SetPredefinedCursor(Id window_id, + mus::mojom::Cursor cursor_id) { + DCHECK(tree_); + + Window* window = GetWindowById(window_id); + if (!window) + return; + + // We make an inflight change thing here. + const uint32_t change_id = ScheduleInFlightChange(make_scoped_ptr( + new InFlightPredefinedCursorChange(window, window->predefined_cursor()))); + tree_->SetPredefinedCursor(change_id, window_id, cursor_id); +} + void WindowTreeClientImpl::SetVisible(Window* window, bool visible) { DCHECK(tree_); const uint32_t change_id = ScheduleInFlightChange( @@ -276,14 +303,37 @@ tree_->AttachSurface(window_id, type, surface.Pass(), client.Pass()); } +void WindowTreeClientImpl::LocalSetFocus(Window* focused) { + Window* blurred = focused_window_; + // Update |focused_window_| before calling any of the observers, so that the + // observers get the correct result from calling |Window::HasFocus()|, + // |WindowTreeConnection::GetFocusedWindow()| etc. + focused_window_ = focused; + if (blurred) { + FOR_EACH_OBSERVER(WindowObserver, *WindowPrivate(blurred).observers(), + OnWindowFocusChanged(focused, blurred)); + } + if (focused) { + FOR_EACH_OBSERVER(WindowObserver, *WindowPrivate(focused).observers(), + OnWindowFocusChanged(focused, blurred)); + } + FOR_EACH_OBSERVER(WindowTreeConnectionObserver, observers_, + OnWindowTreeFocusChanged(focused, blurred)); +} + void WindowTreeClientImpl::AddWindow(Window* window) { DCHECK(windows_.find(window->id()) == windows_.end()); windows_[window->id()] = window; } void WindowTreeClientImpl::RemoveWindow(Id window_id) { - if (focused_window_ && focused_window_->id() == window_id) - OnWindowFocused(0); + if (focused_window_ && focused_window_->id() == window_id) { + // The focused window is being removed. When this happens the server + // advances focus. We don't want to randomly pick a Window to get focus, so + // we update local state only, and wait for the next focus change from the + // server. + LocalSetFocus(nullptr); + } IdToWindowMap::iterator it = windows_.find(window_id); if (it != windows_.end()) @@ -292,7 +342,7 @@ // Remove any InFlightChanges associated with the window. std::set<uint32_t> in_flight_change_ids; for (const auto& pair : in_flight_map_) { - if (pair.second->window()->id() == window_id) + if (pair.second->window() && pair.second->window()->id() == window_id) in_flight_change_ids.insert(pair.first); } for (auto change_id : in_flight_change_ids) @@ -353,6 +403,11 @@ focused_window_ = GetWindowById(focused_window_id); delegate_->OnEmbed(root_); + + if (focused_window_) { + FOR_EACH_OBSERVER(WindowTreeConnectionObserver, observers_, + OnWindowTreeFocusChanged(focused_window_, nullptr)); + } } //////////////////////////////////////////////////////////////////////////////// @@ -402,6 +457,15 @@ //////////////////////////////////////////////////////////////////////////////// // WindowTreeClientImpl, WindowTreeClient implementation: +void WindowTreeClientImpl::AddObserver(WindowTreeConnectionObserver* observer) { + observers_.AddObserver(observer); +} + +void WindowTreeClientImpl::RemoveObserver( + WindowTreeConnectionObserver* observer) { + observers_.RemoveObserver(observer); +} + void WindowTreeClientImpl::OnEmbed(ConnectionSpecificId connection_id, mojom::WindowDataPtr root_data, mojom::WindowTreePtr tree, @@ -445,11 +509,14 @@ void WindowTreeClientImpl::OnClientAreaChanged( uint32_t window_id, - mojo::InsetsPtr old_client_area, - mojo::InsetsPtr new_client_area) { + mojo::InsetsPtr new_client_area, + mojo::Array<mojo::RectPtr> new_additional_client_areas) { Window* window = GetWindowById(window_id); - if (window) - WindowPrivate(window).LocalSetClientArea(new_client_area.To<gfx::Insets>()); + if (window) { + WindowPrivate(window).LocalSetClientArea( + new_client_area.To<gfx::Insets>(), + new_additional_client_areas.To<std::vector<gfx::Rect>>()); + } } void WindowTreeClientImpl::OnTransientWindowAdded( @@ -581,20 +648,26 @@ } void WindowTreeClientImpl::OnWindowFocused(Id focused_window_id) { - Window* focused = GetWindowById(focused_window_id); - Window* blurred = focused_window_; - // Update |focused_window_| before calling any of the observers, so that the - // observers get the correct result from calling |Window::HasFocus()|, - // |WindowTreeConnection::GetFocusedWindow()| etc. - focused_window_ = focused; - if (blurred) { - FOR_EACH_OBSERVER(WindowObserver, *WindowPrivate(blurred).observers(), - OnWindowFocusChanged(focused, blurred)); - } - if (focused) { - FOR_EACH_OBSERVER(WindowObserver, *WindowPrivate(focused).observers(), - OnWindowFocusChanged(focused, blurred)); - } + Window* focused_window = GetWindowById(focused_window_id); + InFlightFocusChange new_change(this, focused_window); + if (ApplyServerChangeToExistingInFlightChange(new_change)) + return; + + LocalSetFocus(focused_window); +} + +void WindowTreeClientImpl::OnWindowPredefinedCursorChanged( + Id window_id, + mojom::Cursor cursor) { + Window* window = GetWindowById(window_id); + if (!window) + return; + + InFlightPredefinedCursorChange new_change(window, cursor); + if (ApplyServerChangeToExistingInFlightChange(new_change)) + return; + + WindowPrivate(window).LocalSetPredefinedCursor(cursor); } void WindowTreeClientImpl::OnChangeCompleted(uint32 change_id, bool success) {
diff --git a/components/mus/public/cpp/lib/window_tree_client_impl.h b/components/mus/public/cpp/lib/window_tree_client_impl.h index af224db..7e46a79a 100644 --- a/components/mus/public/cpp/lib/window_tree_client_impl.h +++ b/components/mus/public/cpp/lib/window_tree_client_impl.h
@@ -7,6 +7,7 @@ #include <map> +#include "base/observer_list.h" #include "components/mus/common/types.h" #include "components/mus/public/cpp/window.h" #include "components/mus/public/cpp/window_tree_connection.h" @@ -48,13 +49,13 @@ // These methods take TransportIds. For windows owned by the current // connection, the connection id high word can be zero. In all cases, the // TransportId 0x1 refers to the root window. - void AddChild(Id child_id, Id parent_id); - void RemoveChild(Id child_id, Id parent_id); + void AddChild(Window* parent, Id child_id); + void RemoveChild(Window* parent, Id child_id); void AddTransientWindow(Window* window, Id transient_window_id); void RemoveTransientWindowFromParent(Window* window); - void Reorder(Id window_id, + void Reorder(Window* window, Id relative_window_id, mojom::OrderDirection direction); @@ -64,9 +65,12 @@ void SetBounds(Window* window, const gfx::Rect& old_bounds, const gfx::Rect& bounds); - void SetClientArea(Id window_id, const gfx::Insets& client_area); - void SetFocus(Id window_id); + void SetClientArea(Id window_id, + const gfx::Insets& client_area, + const std::vector<gfx::Rect>& additional_client_areas); + void SetFocus(Window* window); void SetCanFocus(Id window_id, bool can_focus); + void SetPredefinedCursor(Id window_id, mus::mojom::Cursor cursor_id); void SetVisible(Window* window, bool visible); void SetProperty(Window* window, const std::string& name, @@ -86,6 +90,9 @@ mojo::InterfaceRequest<mojom::Surface> surface, mojom::SurfaceClientPtr client); + // Sets focus to |window| without notifying the server. + void LocalSetFocus(Window* window); + // Start/stop tracking windows. While tracked, they can be retrieved via // WindowTreeConnection::GetWindowById. void AddWindow(Window* window); @@ -108,11 +115,13 @@ // Returns the oldest InFlightChange that matches |change|. InFlightChange* GetOldestInFlightChangeMatching(const InFlightChange& change); + // See InFlightChange for details on how InFlightChanges are used. uint32_t ScheduleInFlightChange(scoped_ptr<InFlightChange> change); // Returns true if there is an InFlightChange that matches |change|. If there // is an existing change SetRevertValueFrom() is invoked on it. Returns false // if there is no InFlightChange matching |change|. + // See InFlightChange for details on how InFlightChanges are used. bool ApplyServerChangeToExistingInFlightChange(const InFlightChange& change); // OnEmbed() calls into this. Exposed as a separate function for testing. @@ -129,6 +138,8 @@ Window* NewWindow(const Window::SharedProperties* properties) override; bool IsEmbedRoot() override; ConnectionSpecificId GetConnectionId() override; + void AddObserver(WindowTreeConnectionObserver* observer) override; + void RemoveObserver(WindowTreeConnectionObserver* observer) override; // Overridden from WindowTreeClient: void OnEmbed(ConnectionSpecificId connection_id, @@ -141,9 +152,10 @@ void OnWindowBoundsChanged(Id window_id, mojo::RectPtr old_bounds, mojo::RectPtr new_bounds) override; - void OnClientAreaChanged(uint32_t window_id, - mojo::InsetsPtr old_client_area, - mojo::InsetsPtr new_client_area) override; + void OnClientAreaChanged( + uint32_t window_id, + mojo::InsetsPtr new_client_area, + mojo::Array<mojo::RectPtr> new_additional_client_areas) override; void OnTransientWindowAdded(uint32_t window_id, uint32_t transient_window_id) override; void OnTransientWindowRemoved(uint32_t window_id, @@ -169,6 +181,8 @@ Id window_id, mojom::EventPtr event) override; void OnWindowFocused(Id focused_window_id) override; + void OnWindowPredefinedCursorChanged(Id window_id, + mojom::Cursor cursor) override; void OnChangeCompleted(uint32_t change_id, bool success) override; void WmSetBounds(uint32_t change_id, Id window_id, @@ -211,6 +225,8 @@ bool in_destructor_; + base::ObserverList<WindowTreeConnectionObserver> observers_; + MOJO_DISALLOW_COPY_AND_ASSIGN(WindowTreeClientImpl); };
diff --git a/components/mus/public/cpp/tests/test_window_tree.cc b/components/mus/public/cpp/tests/test_window_tree.cc index 1eff074..1d70f32f 100644 --- a/components/mus/public/cpp/tests/test_window_tree.cc +++ b/components/mus/public/cpp/tests/test_window_tree.cc
@@ -34,8 +34,10 @@ change_id_ = change_id; } -void TestWindowTree::SetClientArea(uint32_t window_id, mojo::InsetsPtr insets) { -} +void TestWindowTree::SetClientArea( + uint32_t window_id, + mojo::InsetsPtr insets, + mojo::Array<mojo::RectPtr> additional_client_areas) {} void TestWindowTree::SetWindowVisibility(uint32_t change_id, uint32_t window_id, @@ -58,13 +60,12 @@ mojo::InterfaceRequest<mojom::Surface> surface, mojom::SurfaceClientPtr client) {} -void TestWindowTree::AddWindow(uint32_t parent, - uint32_t child, - const AddWindowCallback& callback) {} +void TestWindowTree::AddWindow(uint32_t change_id, + uint32_t parent, + uint32_t child) {} -void TestWindowTree::RemoveWindowFromParent( - uint32_t window_id, - const RemoveWindowFromParentCallback& callback) {} +void TestWindowTree::RemoveWindowFromParent(uint32_t change_id, + uint32_t window_id) {} void TestWindowTree::AddTransientWindow(uint32_t change_id, uint32_t window_id, @@ -74,10 +75,10 @@ uint32_t change_id, uint32_t transient_window_id) {} -void TestWindowTree::ReorderWindow(uint32_t window_id, +void TestWindowTree::ReorderWindow(uint32_t change_id, + uint32_t window_id, uint32_t relative_window_id, - mojom::OrderDirection direction, - const ReorderWindowCallback& callback) {} + mojom::OrderDirection direction) {} void TestWindowTree::GetWindowTree(uint32_t window_id, const GetWindowTreeCallback& callback) {} @@ -87,10 +88,17 @@ uint32_t policy_bitmask, const EmbedCallback& callback) {} -void TestWindowTree::SetFocus(uint32_t window_id) {} +void TestWindowTree::SetFocus(uint32_t change_id, uint32_t window_id) { + got_change_ = true; + change_id_ = change_id; +} void TestWindowTree::SetCanFocus(uint32_t window_id, bool can_focus) {} +void TestWindowTree::SetPredefinedCursor(uint32_t change_id, + uint32_t window_id, + mus::mojom::Cursor cursor_id) {} + void TestWindowTree::SetWindowTextInputState(uint32_t window_id, mojo::TextInputStatePtr state) {}
diff --git a/components/mus/public/cpp/tests/test_window_tree.h b/components/mus/public/cpp/tests/test_window_tree.h index 80bdec5..8a35699 100644 --- a/components/mus/public/cpp/tests/test_window_tree.h +++ b/components/mus/public/cpp/tests/test_window_tree.h
@@ -31,7 +31,10 @@ void SetWindowBounds(uint32_t change_id, uint32_t window_id, mojo::RectPtr bounds) override; - void SetClientArea(uint32_t window_id, mojo::InsetsPtr insets) override; + void SetClientArea( + uint32_t window_id, + mojo::InsetsPtr insets, + mojo::Array<mojo::RectPtr> additional_client_areas) override; void SetWindowVisibility(uint32_t change_id, uint32_t window_id, bool visible) override; @@ -43,29 +46,28 @@ mojom::SurfaceType type, mojo::InterfaceRequest<mojom::Surface> surface, mojom::SurfaceClientPtr client) override; - void AddWindow(uint32_t parent, - uint32_t child, - const AddWindowCallback& callback) override; - void RemoveWindowFromParent( - uint32_t window_id, - const RemoveWindowFromParentCallback& callback) override; + void AddWindow(uint32_t change_id, uint32_t parent, uint32_t child) override; + void RemoveWindowFromParent(uint32_t change_id, uint32_t window_id) override; void AddTransientWindow(uint32_t change_id, uint32_t window_id, uint32_t transient_window_id) override; void RemoveTransientWindowFromParent(uint32_t change_id, uint32_t window_id) override; - void ReorderWindow(uint32_t window_id, + void ReorderWindow(uint32_t change_id, + uint32_t window_id, uint32_t relative_window_id, - mojom::OrderDirection direction, - const ReorderWindowCallback& callback) override; + mojom::OrderDirection direction) override; void GetWindowTree(uint32_t window_id, const GetWindowTreeCallback& callback) override; void Embed(uint32_t window_id, mojom::WindowTreeClientPtr client, uint32_t policy_bitmask, const EmbedCallback& callback) override; - void SetFocus(uint32_t window_id) override; + void SetFocus(uint32_t change_id, uint32_t window_id) override; void SetCanFocus(uint32_t window_id, bool can_focus) override; + void SetPredefinedCursor(uint32_t change_id, + uint32_t window_id, + mus::mojom::Cursor cursor_id) override; void SetWindowTextInputState(uint32_t window_id, mojo::TextInputStatePtr state) override; void SetImeVisibility(uint32_t window_id,
diff --git a/components/mus/public/cpp/tests/window_tree_client_impl_unittest.cc b/components/mus/public/cpp/tests/window_tree_client_impl_unittest.cc index 11f54962..5c61a40 100644 --- a/components/mus/public/cpp/tests/window_tree_client_impl_unittest.cc +++ b/components/mus/public/cpp/tests/window_tree_client_impl_unittest.cc
@@ -276,4 +276,97 @@ EXPECT_EQ(original_visible, root->visible()); } +// Verifies focus is reverted if the server replied that the change failed. +TEST_F(WindowTreeClientImplTest, SetFocusFailed) { + WindowTreeSetup setup; + Window* root = setup.window_tree_connection()->GetRoot(); + ASSERT_TRUE(root); + root->SetVisible(true); + Window* child = setup.window_tree_connection()->NewWindow(); + child->SetVisible(true); + root->AddChild(child); + Window* original_focus = setup.window_tree_connection()->GetFocusedWindow(); + Window* new_focus = child; + ASSERT_NE(new_focus, original_focus); + new_focus->SetFocus(); + ASSERT_TRUE(new_focus->HasFocus()); + uint32_t change_id; + ASSERT_TRUE(setup.window_tree()->GetAndClearChangeId(&change_id)); + setup.window_tree_client()->OnChangeCompleted(change_id, false); + EXPECT_EQ(original_focus, setup.window_tree_connection()->GetFocusedWindow()); +} + +// Simulates a focus change, and while the focus change is in flight the server +// replies with a new focus and the original focus change fails. +TEST_F(WindowTreeClientImplTest, SetFocusFailedWithPendingChange) { + WindowTreeSetup setup; + Window* root = setup.window_tree_connection()->GetRoot(); + ASSERT_TRUE(root); + root->SetVisible(true); + Window* child1 = setup.window_tree_connection()->NewWindow(); + child1->SetVisible(true); + root->AddChild(child1); + Window* child2 = setup.window_tree_connection()->NewWindow(); + child2->SetVisible(true); + root->AddChild(child2); + Window* original_focus = setup.window_tree_connection()->GetFocusedWindow(); + Window* new_focus = child1; + ASSERT_NE(new_focus, original_focus); + new_focus->SetFocus(); + ASSERT_TRUE(new_focus->HasFocus()); + uint32_t change_id; + ASSERT_TRUE(setup.window_tree()->GetAndClearChangeId(&change_id)); + + // Simulate the server responding with a focus change. + setup.window_tree_client()->OnWindowFocused(child2->id()); + + // This shouldn't trigger focus changing yet. + EXPECT_TRUE(child1->HasFocus()); + + // Tell the client the change failed, which should trigger failing to the + // most recent focus from server. + setup.window_tree_client()->OnChangeCompleted(change_id, false); + EXPECT_FALSE(child1->HasFocus()); + EXPECT_TRUE(child2->HasFocus()); + EXPECT_EQ(child2, setup.window_tree_connection()->GetFocusedWindow()); + + // Simulate server changing focus to child1. Should take immediately. + setup.window_tree_client()->OnWindowFocused(child1->id()); + EXPECT_TRUE(child1->HasFocus()); +} + +TEST_F(WindowTreeClientImplTest, FocusOnRemovedWindowWithInFlightFocusChange) { + WindowTreeSetup setup; + Window* root = setup.window_tree_connection()->GetRoot(); + ASSERT_TRUE(root); + root->SetVisible(true); + Window* child1 = setup.window_tree_connection()->NewWindow(); + child1->SetVisible(true); + root->AddChild(child1); + Window* child2 = setup.window_tree_connection()->NewWindow(); + child2->SetVisible(true); + root->AddChild(child2); + + child1->SetFocus(); + uint32_t change_id; + ASSERT_TRUE(setup.window_tree()->GetAndClearChangeId(&change_id)); + + // Destroy child1, which should set focus to null. + child1->Destroy(); + EXPECT_EQ(nullptr, setup.window_tree_connection()->GetFocusedWindow()); + + // Server changes focus to 2. + setup.window_tree_client()->OnWindowFocused(child2->id()); + // Shouldn't take immediately. + EXPECT_FALSE(child2->HasFocus()); + + // Ack the change, focus should still be null. + setup.window_tree_client()->OnChangeCompleted(change_id, true); + EXPECT_EQ(nullptr, setup.window_tree_connection()->GetFocusedWindow()); + + // Change to 2 again, this time it should take. + setup.window_tree_client()->OnWindowFocused(child2->id()); + EXPECT_TRUE(child2->HasFocus()); +} + } // namespace mus
diff --git a/components/mus/public/cpp/window.h b/components/mus/public/cpp/window.h index 9da43ce..8005cf4 100644 --- a/components/mus/public/cpp/window.h +++ b/components/mus/public/cpp/window.h
@@ -72,12 +72,23 @@ void SetBounds(const gfx::Rect& bounds); const gfx::Insets& client_area() const { return client_area_; } - void SetClientArea(const gfx::Insets& new_client_area); + const std::vector<gfx::Rect>& additional_client_areas() { + return additional_client_areas_; + } + void SetClientArea(const gfx::Insets& new_client_area) { + SetClientArea(new_client_area, std::vector<gfx::Rect>()); + } + void SetClientArea(const gfx::Insets& new_client_area, + const std::vector<gfx::Rect>& additional_client_areas); // Visibility (also see IsDrawn()). When created windows are hidden. bool visible() const { return visible_; } void SetVisible(bool value); + // Cursors + mojom::Cursor predefined_cursor() const { return cursor_id_; } + void SetPredefinedCursor(mus::mojom::Cursor cursor_id); + // A Window is drawn if the Window and all its ancestors are visible and the // Window is attached to the root. bool IsDrawn() const; @@ -219,11 +230,14 @@ // Returns true if the order actually changed. bool LocalReorder(Window* relative, mojom::OrderDirection direction); void LocalSetBounds(const gfx::Rect& old_bounds, const gfx::Rect& new_bounds); - void LocalSetClientArea(const gfx::Insets& new_client_area); + void LocalSetClientArea( + const gfx::Insets& new_client_area, + const std::vector<gfx::Rect>& additional_client_areas); void LocalSetViewportMetrics(const mojom::ViewportMetrics& old_metrics, const mojom::ViewportMetrics& new_metrics); void LocalSetDrawn(bool drawn); void LocalSetVisible(bool visible); + void LocalSetPredefinedCursor(mojom::Cursor cursor_id); void LocalSetSharedProperty(const std::string& name, const std::vector<uint8_t>* data); @@ -271,11 +285,14 @@ gfx::Rect bounds_; gfx::Insets client_area_; + std::vector<gfx::Rect> additional_client_areas_; mojom::ViewportMetricsPtr viewport_metrics_; bool visible_; + mojom::Cursor cursor_id_; + SharedProperties properties_; // Drawn state is derived from the visible state and the parent's visible
diff --git a/components/mus/public/cpp/window_observer.h b/components/mus/public/cpp/window_observer.h index 979428ad..b0b3597 100644 --- a/components/mus/public/cpp/window_observer.h +++ b/components/mus/public/cpp/window_observer.h
@@ -22,8 +22,7 @@ // If the change originated from another connection to the window manager, it's // possible that the change has already been applied to the service-side model // prior to being called, so for example in the case of OnWindowDestroying(), -// it's -// possible the window has already been destroyed on the service side. +// it's possible the window has already been destroyed on the service side. class WindowObserver { public: @@ -54,8 +53,10 @@ virtual void OnWindowBoundsChanged(Window* window, const gfx::Rect& old_bounds, const gfx::Rect& new_bounds) {} - virtual void OnWindowClientAreaChanged(Window* window, - const gfx::Insets& old_client_area) {} + virtual void OnWindowClientAreaChanged( + Window* window, + const gfx::Insets& old_client_area, + const std::vector<gfx::Rect>& old_additional_client_areas) {} virtual void OnWindowViewportMetricsChanged( Window* window, @@ -64,6 +65,9 @@ virtual void OnWindowFocusChanged(Window* gained_focus, Window* lost_focus) {} + virtual void OnWindowPredefinedCursorChanged(Window* window, + mojom::Cursor cursor) {} + virtual void OnWindowInputEvent(Window* window, const mojom::EventPtr& event) {}
diff --git a/components/mus/public/cpp/window_surface.h b/components/mus/public/cpp/window_surface.h index 2a285259..ae15193a3 100644 --- a/components/mus/public/cpp/window_surface.h +++ b/components/mus/public/cpp/window_surface.h
@@ -69,11 +69,12 @@ friend class WindowSurface; friend class Window; - WindowSurfaceBinding(mojo::InterfaceRequest<mojom::Surface> surface_request, - mojom::SurfaceClientPtr surface_client); + WindowSurfaceBinding( + mojo::InterfaceRequest<mojom::Surface> surface_request, + mojo::InterfacePtrInfo<mojom::SurfaceClient> surface_client); mojo::InterfaceRequest<mojom::Surface> surface_request_; - mojom::SurfaceClientPtr surface_client_; + mojo::InterfacePtrInfo<mojom::SurfaceClient> surface_client_; DISALLOW_COPY_AND_ASSIGN(WindowSurfaceBinding); };
diff --git a/components/mus/public/cpp/window_tree_connection.h b/components/mus/public/cpp/window_tree_connection.h index fc5b7db..61897fa 100644 --- a/components/mus/public/cpp/window_tree_connection.h +++ b/components/mus/public/cpp/window_tree_connection.h
@@ -17,6 +17,7 @@ class Window; class WindowManagerDelegate; +class WindowTreeConnectionObserver; class WindowTreeDelegate; // Encapsulates a connection to a window tree. A unique connection is made @@ -67,6 +68,9 @@ // Returns the id for this connection. virtual ConnectionSpecificId GetConnectionId() = 0; + + virtual void AddObserver(WindowTreeConnectionObserver* observer) = 0; + virtual void RemoveObserver(WindowTreeConnectionObserver* observer) = 0; }; } // namespace mus
diff --git a/components/mus/public/cpp/window_tree_connection_observer.h b/components/mus/public/cpp/window_tree_connection_observer.h new file mode 100644 index 0000000..b29d71c --- /dev/null +++ b/components/mus/public/cpp/window_tree_connection_observer.h
@@ -0,0 +1,23 @@ +// 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. + +#ifndef COMPONENTS_MUS_PUBLIC_CPP_WINDOW_TREE_CONNECTION_OBSERVER_H_ +#define COMPONENTS_MUS_PUBLIC_CPP_WINDOW_TREE_CONNECTION_OBSERVER_H_ + +namespace mus { + +class Window; + +class WindowTreeConnectionObserver { + public: + virtual void OnWindowTreeFocusChanged(Window* gained_focus, + Window* lost_focus) {} + + protected: + virtual ~WindowTreeConnectionObserver() {} +}; + +} // namespace mus + +#endif // COMPONENTS_MUS_PUBLIC_CPP_WINDOW_TREE_CONNECTION_OBSERVER_H_
diff --git a/components/mus/public/interfaces/BUILD.gn b/components/mus/public/interfaces/BUILD.gn index cd27ea1..c20d0db 100644 --- a/components/mus/public/interfaces/BUILD.gn +++ b/components/mus/public/interfaces/BUILD.gn
@@ -9,6 +9,7 @@ "accelerator_registrar.mojom", "command_buffer.mojom", "compositor_frame.mojom", + "cursor.mojom", "gpu.mojom", "gpu_capabilities.mojom", "input_event_constants.mojom",
diff --git a/components/mus/public/interfaces/cursor.mojom b/components/mus/public/interfaces/cursor.mojom new file mode 100644 index 0000000..c92aef2 --- /dev/null +++ b/components/mus/public/interfaces/cursor.mojom
@@ -0,0 +1,57 @@ +// 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. + +module mus.mojom; + +// Standard Cursor numbers. These are the same as Chrome's ui::Cursor and +// blink's WebCursorInfo. +enum Cursor { + // NULL is kept for compatibility with chrome declarations. In chrome code, it + // is treated exactly like POINTER, the default pointer. + NULL = 0, + POINTER, + CROSS, + HAND, + IBEAM, + WAIT, + HELP, + EAST_RESIZE, + NORTH_RESIZE, + NORTH_EAST_RESIZE, + NORTH_WEST_RESIZE, + SOUTH_RESIZE, + SOUTH_EAST_RESIZE, + SOUTH_WEST_RESIZE, + WEST_RESIZE, + NORTH_SOUTH_RESIZE, + EAST_WEST_RESIZE, + NORTH_EAST_SOUTH_WEST_RESIZE, + NORTH_WEST_SOUTH_EAST_RESIZE, + COLUMN_RESIZE, + ROW_RESIZE, + MIDDLE_PANNING, + EAST_PANNING, + NORTH_PANNING, + NORTH_EAST_PANNING, + NORTH_WEST_PANNING, + SOUTH_PANNING, + SOUTH_EAST_PANNING, + SOUTH_WEST_PANNING, + WEST_PANNING, + MOVE, + VERTICAL_TEXT, + CELL, + CONTEXT_MENU, + ALIAS, + PROGRESS, + NO_DROP, + COPY, + NONE, + NOT_ALLOWED, + ZOOM_IN, + ZOOM_OUT, + GRAB, + GRABBING, + CUSTOM +};
diff --git a/components/mus/public/interfaces/input_event_constants.mojom b/components/mus/public/interfaces/input_event_constants.mojom index 587a17d..900fc24 100644 --- a/components/mus/public/interfaces/input_event_constants.mojom +++ b/components/mus/public/interfaces/input_event_constants.mojom
@@ -18,19 +18,23 @@ // This mirrors ui::EventFlags // TODO(morrita): Use shift operator once it is available. enum EventFlags { - NONE = 0, - CAPS_LOCK_DOWN = 1, - SHIFT_DOWN = 2, - CONTROL_DOWN = 4, - ALT_DOWN = 8, - LEFT_MOUSE_BUTTON = 16, - MIDDLE_MOUSE_BUTTON = 32, - RIGHT_MOUSE_BUTTON = 64, - COMMAND_DOWN = 128, - EXTENDED = 256, - IS_SYNTHESIZED = 512, - ALTGR_DOWN = 1024, - MOD3_DOWN = 2048 + NONE = 0, + CAPS_LOCK_DOWN = 1, + SHIFT_DOWN = 2, + CONTROL_DOWN = 4, + ALT_DOWN = 8, + LEFT_MOUSE_BUTTON = 16, + MIDDLE_MOUSE_BUTTON = 32, + RIGHT_MOUSE_BUTTON = 64, + COMMAND_DOWN = 128, + EXTENDED = 256, + IS_SYNTHESIZED = 512, + ALTGR_DOWN = 1024, + MOD3_DOWN = 2048, + BACK_MOUSE_BUTTON = 4096, + FORWARD_MOUSE_BUTTON = 8192, + NUM_LOCK_DOWN = 16384, + SCROLL_LOCK_DOWN = 32768, }; enum MouseEventFlags {
diff --git a/components/mus/public/interfaces/input_event_matcher.mojom b/components/mus/public/interfaces/input_event_matcher.mojom index 89c75c4..ec223e65 100644 --- a/components/mus/public/interfaces/input_event_matcher.mojom +++ b/components/mus/public/interfaces/input_event_matcher.mojom
@@ -42,6 +42,9 @@ struct EventMatcher { EventTypeMatcher? type_matcher; EventFlagsMatcher? flags_matcher; + // These flags will be stripped from incoming events' flags when comparing + // against |flags_matcher|. + EventFlagsMatcher? ignore_flags_matcher; KeyEventMatcher? key_matcher; PointerKindMatcher? pointer_kind_matcher; PointerLocationMatcher? pointer_location_matcher;
diff --git a/components/mus/public/interfaces/window_tree.mojom b/components/mus/public/interfaces/window_tree.mojom index 9c64bb8..cc75ee4 100644 --- a/components/mus/public/interfaces/window_tree.mojom +++ b/components/mus/public/interfaces/window_tree.mojom
@@ -5,6 +5,7 @@ module mus.mojom; import "components/mus/public/interfaces/compositor_frame.mojom"; +import "components/mus/public/interfaces/cursor.mojom"; import "components/mus/public/interfaces/input_events.mojom"; import "components/mus/public/interfaces/mus_constants.mojom"; import "components/mus/public/interfaces/surface_id.mojom"; @@ -100,8 +101,13 @@ // Sets the specified bounds of the specified window. SetWindowBounds(uint32 change_id, uint32 window_id, mojo.Rect bounds); - // Sets the insets of the client area of the specified window. - SetClientArea(uint32 window_id, mojo.Insets insets); + // Sets the client area of the specified window. The client area is specified + // by way of insets. Everything outside of the insets, and not in + // |additional_client_areas| is considered non-client area. + // TODO(sky): convert additional_client_areas to a path. + SetClientArea(uint32 window_id, + mojo.Insets insets, + array<mojo.Rect>? additional_client_areas); // Sets the visibility of the specified window to |visible|. Connections are // allowed to change the visibility of any window they have created, as well @@ -129,7 +135,7 @@ // // This may result in a connection getting OnWindowDeleted(). See // RemoveWindowFromParent for details. - AddWindow(uint32 parent, uint32 child) => (bool success); + AddWindow(uint32 change_id, uint32 parent, uint32 child); // Removes a window from its current parent. This fails if the window is not // valid or the window already has no parent. @@ -139,7 +145,7 @@ // a child of 1. Connection B has a root 1. If 2 is removed from 1 then B gets // OnWindowDeleted(). This is done as window 2 is effectively no longer // visible to connection B. - RemoveWindowFromParent(uint32 window_id) => (bool success); + RemoveWindowFromParent(uint32 change_id, uint32 window_id); // Ties the lifetime of |child| to the lifetime of |parent|. This also // places |child| always on top of |parent|. @@ -157,9 +163,10 @@ // Reorders a window in its parent, relative to |relative_window_id| according // to |direction|. Only the connection that created the window's parent can // reorder its children. - ReorderWindow(uint32 window_id, + ReorderWindow(uint32 change_id, + uint32 window_id, uint32 relative_window_id, - OrderDirection direction) => (bool success); + OrderDirection direction); // Returns the windows comprising the tree starting at |window_id|. // |window_id| is the first result in the return value, unless |window_id| is @@ -201,9 +208,16 @@ WindowTreeClient client, uint32 policy_bitmask) => (bool success, uint16 connection_id); - SetFocus(uint32 window_id); + SetFocus(uint32 change_id, uint32 window_id); SetCanFocus(uint32 window_id, bool can_focus); + // Sets the cursor when the pointer is inside |window_id| to a system standard + // cursor provided by the window manager. + SetPredefinedCursor(uint32 change_id, uint32 window_id, Cursor cursor_id); + + // TODO(erg): Additional cursor methods. Image based cursors, visibility, + // and cursor locking. + // Set text input state for the given window. SetWindowTextInputState(uint32 window_id, mojo.TextInputState state); @@ -254,8 +268,8 @@ mojo.Rect new_bounds); OnClientAreaChanged(uint32 window_id, - mojo.Insets old_client_area, - mojo.Insets new_client_area); + mojo.Insets new_client_area, + array<mojo.Rect> new_additional_client_areas); OnTransientWindowAdded(uint32 window_id, uint32 transient_window_id); @@ -316,6 +330,8 @@ OnWindowFocused(uint32 focused_window_id); + OnWindowPredefinedCursorChanged(uint32 window_id, Cursor cursor_id); + // A change initiated from the client has completed. See description of // change ids for details. OnChangeCompleted(uint32 change_id, bool success);
diff --git a/components/mus/ws/BUILD.gn b/components/mus/ws/BUILD.gn index 407b255..fd9918d 100644 --- a/components/mus/ws/BUILD.gn +++ b/components/mus/ws/BUILD.gn
@@ -76,6 +76,7 @@ "//mojo/converters/surfaces", "//mojo/public/cpp/bindings:callback", "//mojo/services/tracing/public/cpp", + "//ui/base", "//ui/events", "//ui/events/platform", "//ui/gfx",
diff --git a/components/mus/ws/access_policy.h b/components/mus/ws/access_policy.h index 9b382fe..16eff90 100644 --- a/components/mus/ws/access_policy.h +++ b/components/mus/ws/access_policy.h
@@ -50,6 +50,9 @@ virtual bool CanSetWindowTextInputState(const ServerWindow* window) const = 0; virtual bool CanSetFocus(const ServerWindow* window) const = 0; virtual bool CanSetClientArea(const ServerWindow* window) const = 0; + // Used for all cursor properties; which cursor should be displayed, + // visibility, locking, etc. + virtual bool CanSetCursorProperties(const ServerWindow* window) const = 0; // Returns whether the connection should notify on a hierarchy change. // |new_parent| and |old_parent| are initially set to the new and old parents
diff --git a/components/mus/ws/connection_manager.cc b/components/mus/ws/connection_manager.cc index 3c8bea5..b72b3f9 100644 --- a/components/mus/ws/connection_manager.cc +++ b/components/mus/ws/connection_manager.cc
@@ -286,11 +286,11 @@ void ConnectionManager::ProcessClientAreaChanged( const ServerWindow* window, - const gfx::Insets& old_client_area, - const gfx::Insets& new_client_area) { + const gfx::Insets& new_client_area, + const std::vector<gfx::Rect>& new_additional_client_areas) { for (auto& pair : connection_map_) { pair.second->service()->ProcessClientAreaChanged( - window, old_client_area, new_client_area, + window, new_client_area, new_additional_client_areas, IsOperationSource(pair.first)); } } @@ -338,6 +338,20 @@ } } +void ConnectionManager::ProcessWillChangeWindowPredefinedCursor( + ServerWindow* window, + int32_t cursor_id) { + for (auto& pair : connection_map_) { + pair.second->service()->ProcessCursorChanged(window, cursor_id, + IsOperationSource(pair.first)); + } + + // Pass the cursor change to the native window. + WindowTreeHostImpl* host = GetWindowTreeHostByWindow(window); + if (host) + host->OnCursorUpdated(window); +} + void ConnectionManager::ProcessViewportMetricsChanged( const mojom::ViewportMetrics& old_metrics, const mojom::ViewportMetrics& new_metrics) { @@ -434,12 +448,13 @@ void ConnectionManager::OnWindowClientAreaChanged( ServerWindow* window, - const gfx::Insets& old_client_area, - const gfx::Insets& new_client_area) { + const gfx::Insets& new_client_area, + const std::vector<gfx::Rect>& new_additional_client_areas) { if (in_destructor_) return; - ProcessClientAreaChanged(window, old_client_area, new_client_area); + ProcessClientAreaChanged(window, new_client_area, + new_additional_client_areas); } void ConnectionManager::OnWindowReordered(ServerWindow* window, @@ -468,6 +483,14 @@ } } +void ConnectionManager::OnWindowPredefinedCursorChanged(ServerWindow* window, + int32_t cursor_id) { + if (in_destructor_) + return; + + ProcessWillChangeWindowPredefinedCursor(window, cursor_id); +} + void ConnectionManager::OnWindowSharedPropertyChanged( ServerWindow* window, const std::string& name,
diff --git a/components/mus/ws/connection_manager.h b/components/mus/ws/connection_manager.h index c9cd68a..4ba4c93d 100644 --- a/components/mus/ws/connection_manager.h +++ b/components/mus/ws/connection_manager.h
@@ -143,9 +143,10 @@ void ProcessWindowBoundsChanged(const ServerWindow* window, const gfx::Rect& old_bounds, const gfx::Rect& new_bounds); - void ProcessClientAreaChanged(const ServerWindow* window, - const gfx::Insets& old_client_area, - const gfx::Insets& new_client_area); + void ProcessClientAreaChanged( + const ServerWindow* window, + const gfx::Insets& new_client_area, + const std::vector<gfx::Rect>& new_additional_client_areas); void ProcessViewportMetricsChanged(const mojom::ViewportMetrics& old_metrics, const mojom::ViewportMetrics& new_metrics); void ProcessWillChangeWindowHierarchy(const ServerWindow* window, @@ -158,6 +159,8 @@ const ServerWindow* relative_window, const mojom::OrderDirection direction); void ProcessWindowDeleted(const WindowId& window); + void ProcessWillChangeWindowPredefinedCursor(ServerWindow* window, + int32_t cursor_id); private: friend class Operation; @@ -214,9 +217,10 @@ void OnWindowBoundsChanged(ServerWindow* window, const gfx::Rect& old_bounds, const gfx::Rect& new_bounds) override; - void OnWindowClientAreaChanged(ServerWindow* window, - const gfx::Insets& old_client_area, - const gfx::Insets& new_client_area) override; + void OnWindowClientAreaChanged( + ServerWindow* window, + const gfx::Insets& new_client_area, + const std::vector<gfx::Rect>& new_additional_client_areas) override; void OnWindowReordered(ServerWindow* window, ServerWindow* relative, mojom::OrderDirection direction) override; @@ -225,6 +229,8 @@ ServerWindow* window, const std::string& name, const std::vector<uint8_t>* new_data) override; + void OnWindowPredefinedCursorChanged(ServerWindow* window, + int32_t cursor_id) override; void OnWindowTextInputStateChanged(ServerWindow* window, const ui::TextInputState& state) override; void OnTransientWindowAdded(ServerWindow* window,
diff --git a/components/mus/ws/default_access_policy.cc b/components/mus/ws/default_access_policy.cc index 0a9cb241..2c7a89a 100644 --- a/components/mus/ws/default_access_policy.cc +++ b/components/mus/ws/default_access_policy.cc
@@ -133,6 +133,12 @@ delegate_->IsRootForAccessPolicy(window->id()); } +bool DefaultAccessPolicy::CanSetCursorProperties( + const ServerWindow* window) const { + return WasCreatedByThisConnection(window) || + delegate_->IsRootForAccessPolicy(window->id()); +} + bool DefaultAccessPolicy::ShouldNotifyOnHierarchyChange( const ServerWindow* window, const ServerWindow** new_parent,
diff --git a/components/mus/ws/default_access_policy.h b/components/mus/ws/default_access_policy.h index f5b766d..f710f52 100644 --- a/components/mus/ws/default_access_policy.h +++ b/components/mus/ws/default_access_policy.h
@@ -46,6 +46,7 @@ bool CanSetWindowTextInputState(const ServerWindow* window) const override; bool CanSetFocus(const ServerWindow* window) const override; bool CanSetClientArea(const ServerWindow* window) const override; + bool CanSetCursorProperties(const ServerWindow* window) const override; bool ShouldNotifyOnHierarchyChange( const ServerWindow* window, const ServerWindow** new_parent,
diff --git a/components/mus/ws/display_manager.cc b/components/mus/ws/display_manager.cc index afbe6e9..334dd024 100644 --- a/components/mus/ws/display_manager.cc +++ b/components/mus/ws/display_manager.cc
@@ -29,6 +29,7 @@ #include "mojo/converters/surfaces/surfaces_utils.h" #include "mojo/converters/transform/transform_type_converters.h" #include "third_party/skia/include/core/SkXfermode.h" +#include "ui/base/cursor/cursor_loader.h" #include "ui/events/event.h" #include "ui/events/event_utils.h" #include "ui/gfx/display.h" @@ -170,6 +171,9 @@ delegate_(nullptr), draw_timer_(false, false), frame_pending_(false), +#if !defined(OS_ANDROID) + cursor_loader_(ui::CursorLoader::Create()), +#endif weak_factory_(this) { metrics_.size_in_pixels = mojo::Size::New(); metrics_.size_in_pixels->width = 1024; @@ -226,6 +230,19 @@ platform_window_->SetTitle(title); } +void DefaultDisplayManager::SetCursorById(int32_t cursor_id) { +#if !defined(OS_ANDROID) + // TODO(erg): This still isn't sufficient, and will only use native cursors + // that chrome would use, not custom image cursors. For that, we should + // delegate to the window manager to load images from resource packs. + // + // We probably also need to deal with different DPIs. + ui::Cursor cursor(cursor_id); + cursor_loader_->SetPlatformCursor(&cursor); + platform_window_->SetCursor(cursor.platform()); +#endif +} + const mojom::ViewportMetrics& DefaultDisplayManager::GetViewportMetrics() { return metrics_; }
diff --git a/components/mus/ws/display_manager.h b/components/mus/ws/display_manager.h index c8596b1..3705d96 100644 --- a/components/mus/ws/display_manager.h +++ b/components/mus/ws/display_manager.h
@@ -32,6 +32,7 @@ } // namespace mojo namespace ui { +class CursorLoader; class PlatformWindow; struct TextInputState; } // namespace ui @@ -68,6 +69,8 @@ virtual void SetTitle(const base::string16& title) = 0; + virtual void SetCursorById(int32_t cursor) = 0; + virtual const mojom::ViewportMetrics& GetViewportMetrics() = 0; virtual void UpdateTextInputState(const ui::TextInputState& state) = 0; @@ -103,6 +106,7 @@ const gfx::Rect& bounds) override; void SetViewportSize(const gfx::Size& size) override; void SetTitle(const base::string16& title) override; + void SetCursorById(int32_t cursor) override; const mojom::ViewportMetrics& GetViewportMetrics() override; void UpdateTextInputState(const ui::TextInputState& state) override; void SetImeVisibility(bool visible) override; @@ -149,6 +153,10 @@ scoped_ptr<TopLevelDisplayClient> top_level_display_client_; scoped_ptr<ui::PlatformWindow> platform_window_; +#if !defined(OS_ANDROID) + scoped_ptr<ui::CursorLoader> cursor_loader_; +#endif + base::WeakPtrFactory<DefaultDisplayManager> weak_factory_; DISALLOW_COPY_AND_ASSIGN(DefaultDisplayManager);
diff --git a/components/mus/ws/event_dispatcher.cc b/components/mus/ws/event_dispatcher.cc index 384f9ba8..5265368 100644 --- a/components/mus/ws/event_dispatcher.cc +++ b/components/mus/ws/event_dispatcher.cc
@@ -39,7 +39,15 @@ gfx::Rect client_area(target->bounds().size()); client_area.Inset(target->client_area()); - return !client_area.Contains(location); + if (client_area.Contains(location)) + return false; + + for (const auto& rect : target->additional_client_areas()) { + if (rect.Contains(location)) + return false; + } + + return true; } gfx::Point EventLocationToPoint(const mojom::Event& event) { @@ -55,6 +63,7 @@ : fields_to_match_(NONE), event_type_(mojom::EVENT_TYPE_UNKNOWN), event_flags_(mojom::EVENT_FLAGS_NONE), + ignore_event_flags_(mojom::EVENT_FLAGS_NONE), keyboard_code_(mojom::KEYBOARD_CODE_UNKNOWN), pointer_kind_(mojom::POINTER_KIND_MOUSE) { if (matcher.type_matcher) { @@ -64,6 +73,8 @@ if (matcher.flags_matcher) { fields_to_match_ |= FLAGS; event_flags_ = matcher.flags_matcher->flags; + if (matcher.ignore_flags_matcher) + ignore_event_flags_ = matcher.ignore_flags_matcher->flags; } if (matcher.key_matcher) { fields_to_match_ |= KEYBOARD_CODE; @@ -85,7 +96,9 @@ bool MatchesEvent(const mojom::Event& event) const { if ((fields_to_match_ & TYPE) && event.action != event_type_) return false; - if ((fields_to_match_ & FLAGS) && event.flags != event_flags_) + mojom::EventFlags flags = + static_cast<mojom::EventFlags>(event.flags & ~ignore_event_flags_); + if ((fields_to_match_ & FLAGS) && flags != event_flags_) return false; if (fields_to_match_ & KEYBOARD_CODE) { if (!event.key_data) @@ -113,6 +126,7 @@ return fields_to_match_ == matcher.fields_to_match_ && event_type_ == matcher.event_type_ && event_flags_ == matcher.event_flags_ && + ignore_event_flags_ == matcher.ignore_event_flags_ && keyboard_code_ == matcher.keyboard_code_ && pointer_kind_ == matcher.pointer_kind_ && pointer_region_ == matcher.pointer_region_; @@ -131,6 +145,7 @@ uint32_t fields_to_match_; mojom::EventType event_type_; mojom::EventFlags event_flags_; + mojom::EventFlags ignore_event_flags_; mojom::KeyboardCode keyboard_code_; mojom::PointerKind pointer_kind_; gfx::RectF pointer_region_; @@ -139,7 +154,10 @@ //////////////////////////////////////////////////////////////////////////////// EventDispatcher::EventDispatcher(EventDispatcherDelegate* delegate) - : delegate_(delegate), root_(nullptr) {} + : delegate_(delegate), + root_(nullptr), + mouse_button_down_(false), + mouse_cursor_source_window_(nullptr) {} EventDispatcher::~EventDispatcher() { std::set<ServerWindow*> pointer_targets; @@ -203,6 +221,10 @@ } void EventDispatcher::ProcessPointerEvent(mojom::EventPtr event) { + bool is_mouse_event = + event->pointer_data && + event->pointer_data->kind == mojom::PointerKind::POINTER_KIND_MOUSE; + const int32_t pointer_id = event->pointer_data->pointer_id; if (event->action == mojom::EVENT_TYPE_WHEEL || (event->action == mojom::EVENT_TYPE_POINTER_MOVE && @@ -215,6 +237,8 @@ pointer_target.window = FindDeepestVisibleWindowForEvents(root_, surface_id_, &location); } + if (is_mouse_event && !mouse_button_down_) + mouse_cursor_source_window_ = pointer_target.window; DispatchToPointerTarget(pointer_target, event.Pass()); return; } @@ -230,6 +254,11 @@ if (!IsObservingWindow(target)) target->AddObserver(this); + if (is_mouse_event) { + mouse_button_down_ = true; + mouse_cursor_source_window_ = target; + } + pointer_targets_[pointer_id].window = target; pointer_targets_[pointer_id].in_nonclient_area = IsLocationInNonclientArea(target, location); @@ -246,6 +275,18 @@ (event->pointer_data->kind != mojom::POINTER_KIND_MOUSE || IsOnlyOneMouseButtonDown(event->flags)); + if (should_reset_target && is_mouse_event) { + // When we release the mouse button, we want the cursor to be sourced from + // the window under the mouse pointer, even though we're sending the button + // up event to the window that had implicit capture. We have to set this + // before we perform dispatch because the Delegate is going to read this + // information from us. + mouse_button_down_ = false; + gfx::Point location(EventLocationToPoint(*event)); + mouse_cursor_source_window_ = + FindDeepestVisibleWindowForEvents(root_, surface_id_, &location); + } + DispatchToPointerTarget(pointer_targets_[pointer_id], event.Pass()); if (should_reset_target) { @@ -311,6 +352,9 @@ void EventDispatcher::OnWindowDestroyed(ServerWindow* window) { CancelPointerEventsToTarget(window); + + if (mouse_cursor_source_window_ == window) + mouse_cursor_source_window_ = nullptr; } } // namespace ws
diff --git a/components/mus/ws/event_dispatcher.h b/components/mus/ws/event_dispatcher.h index a6ffd62..505713c 100644 --- a/components/mus/ws/event_dispatcher.h +++ b/components/mus/ws/event_dispatcher.h
@@ -33,6 +33,11 @@ void set_surface_id(cc::SurfaceId surface_id) { surface_id_ = surface_id; } + // Retrieves the ServerWindow of the last mouse move. + ServerWindow* mouse_cursor_source_window() const { + return mouse_cursor_source_window_; + } + // Adds an accelerator with the given id and event-matcher. If an accelerator // already exists with the same id or the same matcher, then the accelerator // is not added. Returns whether adding the accelerator was successful or not. @@ -95,6 +100,9 @@ EventDispatcherDelegate* delegate_; ServerWindow* root_; + bool mouse_button_down_; + ServerWindow* mouse_cursor_source_window_; + cc::SurfaceId surface_id_; using Entry = std::pair<uint32_t, EventMatcher>;
diff --git a/components/mus/ws/event_dispatcher_unittest.cc b/components/mus/ws/event_dispatcher_unittest.cc index d837dbc..010a017b 100644 --- a/components/mus/ws/event_dispatcher_unittest.cc +++ b/components/mus/ws/event_dispatcher_unittest.cc
@@ -219,6 +219,14 @@ EXPECT_EQ(accelerator_1, event_dispatcher_delegate.GetAndClearLastAccelerator()); + // EF_NUM_LOCK_DOWN should be ignored since CreateKeyMatcher defaults to + // ignoring. + key = ui::KeyEvent(ui::ET_KEY_PRESSED, ui::VKEY_W, + ui::EF_CONTROL_DOWN | ui::EF_NUM_LOCK_DOWN); + dispatcher.OnEvent(mojom::Event::From(key)); + EXPECT_EQ(accelerator_1, + event_dispatcher_delegate.GetAndClearLastAccelerator()); + key = ui::KeyEvent(ui::ET_KEY_PRESSED, ui::VKEY_W, ui::EF_NONE); dispatcher.OnEvent(mojom::Event::From(key)); EXPECT_EQ(0u, event_dispatcher_delegate.GetAndClearLastAccelerator()); @@ -344,7 +352,7 @@ root.SetBounds(gfx::Rect(0, 0, 100, 100)); child.SetBounds(gfx::Rect(10, 10, 20, 20)); - child.SetClientArea(gfx::Insets(5, 5, 5, 5)); + child.SetClientArea(gfx::Insets(5, 5, 5, 5), std::vector<gfx::Rect>()); TestEventDispatcherDelegate event_dispatcher_delegate(&root); EventDispatcher dispatcher(&event_dispatcher_delegate); @@ -393,6 +401,40 @@ EXPECT_FALSE(event_dispatcher_delegate.GetAndClearLastInNonclientArea()); } +TEST(EventDispatcherTest, AdditionalClientArea) { + TestServerWindowDelegate window_delegate; + ServerWindow root(&window_delegate, WindowId(1, 2)); + window_delegate.set_root_window(&root); + root.SetVisible(true); + + ServerWindow child(&window_delegate, WindowId(1, 3)); + root.Add(&child); + child.SetVisible(true); + EnableHitTest(&child); + + root.SetBounds(gfx::Rect(0, 0, 100, 100)); + child.SetBounds(gfx::Rect(10, 10, 20, 20)); + + std::vector<gfx::Rect> additional_client_areas; + additional_client_areas.push_back(gfx::Rect(18, 0, 2, 2)); + child.SetClientArea(gfx::Insets(5, 5, 5, 5), additional_client_areas); + + TestEventDispatcherDelegate event_dispatcher_delegate(&root); + EventDispatcher dispatcher(&event_dispatcher_delegate); + dispatcher.set_root(&root); + + // Press in the additional client area, it should go to the child. + const ui::MouseEvent press_event( + ui::ET_MOUSE_PRESSED, gfx::Point(28, 11), gfx::Point(28, 11), + base::TimeDelta(), ui::EF_LEFT_MOUSE_BUTTON, ui::EF_LEFT_MOUSE_BUTTON); + dispatcher.OnEvent( + mojom::Event::From(static_cast<const ui::Event&>(press_event))); + + // Events should target child and be in the client area. + ASSERT_EQ(&child, event_dispatcher_delegate.last_target()); + EXPECT_FALSE(event_dispatcher_delegate.GetAndClearLastInNonclientArea()); +} + TEST(EventDispatcherTest, DontFocusOnSecondDown) { TestServerWindowDelegate window_delegate; ServerWindow root(&window_delegate, WindowId(1, 2));
diff --git a/components/mus/ws/operation.h b/components/mus/ws/operation.h index 27441a6..76b4111 100644 --- a/components/mus/ws/operation.h +++ b/components/mus/ws/operation.h
@@ -27,6 +27,7 @@ REORDER_WINDOW, SET_FOCUS, SET_WINDOW_BOUNDS, + SET_WINDOW_PREDEFINED_CURSOR, SET_WINDOW_PROPERTY, SET_WINDOW_VISIBILITY, };
diff --git a/components/mus/ws/server_window.cc b/components/mus/ws/server_window.cc index 29b8ec1..c0bcffaf 100644 --- a/components/mus/ws/server_window.cc +++ b/components/mus/ws/server_window.cc
@@ -29,6 +29,7 @@ stacking_target_(nullptr), transient_parent_(nullptr), visible_(false), + cursor_id_(mojom::CURSOR_NULL), opacity_(1), can_focus_(true), properties_(properties), @@ -159,14 +160,19 @@ OnWindowBoundsChanged(this, old_bounds, bounds)); } -void ServerWindow::SetClientArea(const gfx::Insets& insets) { - if (client_area_ == insets) +void ServerWindow::SetClientArea( + const gfx::Insets& insets, + const std::vector<gfx::Rect>& additional_client_areas) { + if (client_area_ == insets && + additional_client_areas == additional_client_areas_) { return; + } - const gfx::Insets old_client_area = client_area_; + additional_client_areas_ = additional_client_areas; client_area_ = insets; - FOR_EACH_OBSERVER(ServerWindowObserver, observers_, - OnWindowClientAreaChanged(this, old_client_area, insets)); + FOR_EACH_OBSERVER( + ServerWindowObserver, observers_, + OnWindowClientAreaChanged(this, insets, additional_client_areas)); } const ServerWindow* ServerWindow::GetRoot() const { @@ -261,6 +267,15 @@ delegate_->OnScheduleWindowPaint(this); } +void ServerWindow::SetPredefinedCursor(mus::mojom::Cursor value) { + if (value == cursor_id_) + return; + cursor_id_ = value; + FOR_EACH_OBSERVER( + ServerWindowObserver, observers_, + OnWindowPredefinedCursorChanged(this, static_cast<int32_t>(value))); +} + void ServerWindow::SetTransform(const gfx::Transform& transform) { if (transform_ == transform) return;
diff --git a/components/mus/ws/server_window.h b/components/mus/ws/server_window.h index 7cadc08..f20d785 100644 --- a/components/mus/ws/server_window.h +++ b/components/mus/ws/server_window.h
@@ -71,8 +71,14 @@ // area to fill the whole bounds. void SetBounds(const gfx::Rect& bounds); + const std::vector<gfx::Rect>& additional_client_areas() const { + return additional_client_areas_; + } const gfx::Insets& client_area() const { return client_area_; } - void SetClientArea(const gfx::Insets& insets); + void SetClientArea(const gfx::Insets& insets, + const std::vector<gfx::Rect>& additional_client_areas); + + int32_t cursor() const { return cursor_id_; } const ServerWindow* parent() const { return parent_; } ServerWindow* parent() { return parent_; } @@ -111,6 +117,8 @@ float opacity() const { return opacity_; } void SetOpacity(float value); + void SetPredefinedCursor(mus::mojom::Cursor cursor_id); + const gfx::Transform& transform() const { return transform_; } void SetTransform(const gfx::Transform& transform); @@ -190,7 +198,9 @@ bool visible_; gfx::Rect bounds_; gfx::Insets client_area_; + std::vector<gfx::Rect> additional_client_areas_; scoped_ptr<ServerWindowSurfaceManager> surface_manager_; + mojom::Cursor cursor_id_; float opacity_; bool can_focus_; gfx::Transform transform_;
diff --git a/components/mus/ws/server_window_observer.h b/components/mus/ws/server_window_observer.h index 61d5d16..04273b2e 100644 --- a/components/mus/ws/server_window_observer.h +++ b/components/mus/ws/server_window_observer.h
@@ -5,6 +5,8 @@ #ifndef COMPONENTS_MUS_WS_SERVER_WINDOW_OBSERVER_H_ #define COMPONENTS_MUS_WS_SERVER_WINDOW_OBSERVER_H_ +#include <vector> + #include "components/mus/public/interfaces/mus_constants.mojom.h" namespace gfx { @@ -45,9 +47,10 @@ const gfx::Rect& old_bounds, const gfx::Rect& new_bounds) {} - virtual void OnWindowClientAreaChanged(ServerWindow* window, - const gfx::Insets& old_client_area, - const gfx::Insets& new_client_area) {} + virtual void OnWindowClientAreaChanged( + ServerWindow* window, + const gfx::Insets& new_client_area, + const std::vector<gfx::Rect>& new_additional_client_areas) {} virtual void OnWindowReordered(ServerWindow* window, ServerWindow* relative, @@ -56,6 +59,9 @@ virtual void OnWillChangeWindowVisibility(ServerWindow* window) {} virtual void OnWindowVisibilityChanged(ServerWindow* window) {} + virtual void OnWindowPredefinedCursorChanged(ServerWindow* window, + int32_t cursor_id) {} + virtual void OnWindowTextInputStateChanged(ServerWindow* window, const ui::TextInputState& state) {}
diff --git a/components/mus/ws/test_change_tracker.cc b/components/mus/ws/test_change_tracker.cc index a128c017..7b5750d 100644 --- a/components/mus/ws/test_change_tracker.cc +++ b/components/mus/ws/test_change_tracker.cc
@@ -111,6 +111,11 @@ case CHANGE_TYPE_FOCUSED: return base::StringPrintf("Focused id=%s", WindowIdToString(change.window_id).c_str()); + + case CHANGE_TYPE_CURSOR_CHANGED: + return base::StringPrintf("CursorChanged id=%s cursor_id=%d", + WindowIdToString(change.window_id).c_str(), + change.cursor_id); } return std::string(); } @@ -327,6 +332,16 @@ AddChange(change); } +void TestChangeTracker::OnWindowPredefinedCursorChanged( + Id window_id, + mojom::Cursor cursor_id) { + Change change; + change.type = CHANGE_TYPE_CURSOR_CHANGED; + change.window_id = window_id; + change.cursor_id = cursor_id; + AddChange(change); +} + void TestChangeTracker::DelegateEmbed(const String& url) { Change change; change.type = CHANGE_TYPE_DELEGATE_EMBED;
diff --git a/components/mus/ws/test_change_tracker.h b/components/mus/ws/test_change_tracker.h index aa7a5a6..df9b6d6 100644 --- a/components/mus/ws/test_change_tracker.h +++ b/components/mus/ws/test_change_tracker.h
@@ -36,6 +36,7 @@ CHANGE_TYPE_PROPERTY_CHANGED, CHANGE_TYPE_DELEGATE_EMBED, CHANGE_TYPE_FOCUSED, + CHANGE_TYPE_CURSOR_CHANGED }; // TODO(sky): consider nuking and converting directly to WindowData. @@ -76,6 +77,7 @@ bool bool_value; std::string property_key; std::string property_value; + int32_t cursor_id; }; // Converts Changes to string descriptions. @@ -146,6 +148,7 @@ mojo::String name, mojo::Array<uint8_t> data); void OnWindowFocused(Id window_id); + void OnWindowPredefinedCursorChanged(Id window_id, mojom::Cursor cursor_id); void DelegateEmbed(const mojo::String& url); private:
diff --git a/components/mus/ws/window_manager_access_policy.cc b/components/mus/ws/window_manager_access_policy.cc index 69c17f1e..a3fa1700 100644 --- a/components/mus/ws/window_manager_access_policy.cc +++ b/components/mus/ws/window_manager_access_policy.cc
@@ -113,6 +113,12 @@ delegate_->IsRootForAccessPolicy(window->id()); } +bool WindowManagerAccessPolicy::CanSetCursorProperties( + const ServerWindow* window) const { + return window->id().connection_id == connection_id_ || + delegate_->IsRootForAccessPolicy(window->id()); +} + bool WindowManagerAccessPolicy::ShouldNotifyOnHierarchyChange( const ServerWindow* window, const ServerWindow** new_parent,
diff --git a/components/mus/ws/window_manager_access_policy.h b/components/mus/ws/window_manager_access_policy.h index ba1c6b47..8781cf5 100644 --- a/components/mus/ws/window_manager_access_policy.h +++ b/components/mus/ws/window_manager_access_policy.h
@@ -45,6 +45,7 @@ bool CanSetWindowTextInputState(const ServerWindow* window) const override; bool CanSetFocus(const ServerWindow* window) const override; bool CanSetClientArea(const ServerWindow* window) const override; + bool CanSetCursorProperties(const ServerWindow* window) const override; bool ShouldNotifyOnHierarchyChange( const ServerWindow* window, const ServerWindow** new_parent,
diff --git a/components/mus/ws/window_manager_client_apptest.cc b/components/mus/ws/window_manager_client_apptest.cc index b2ef3f5..db0be04 100644 --- a/components/mus/ws/window_manager_client_apptest.cc +++ b/components/mus/ws/window_manager_client_apptest.cc
@@ -9,6 +9,7 @@ #include "components/mus/public/cpp/tests/window_server_test_base.h" #include "components/mus/public/cpp/window_observer.h" #include "components/mus/public/cpp/window_tree_connection.h" +#include "components/mus/public/cpp/window_tree_connection_observer.h" #include "components/mus/public/cpp/window_tree_delegate.h" #include "mojo/application/public/cpp/application_connection.h" #include "mojo/application/public/cpp/application_impl.h" @@ -66,8 +67,10 @@ private: // Overridden from WindowObserver: - void OnWindowClientAreaChanged(Window* window, - const gfx::Insets& old_client_area) override { + void OnWindowClientAreaChanged( + Window* window, + const gfx::Insets& old_client_area, + const std::vector<gfx::Rect>& old_additional_client_areas) override { DCHECK_EQ(window, window_); EXPECT_TRUE(WindowServerTestBase::QuitRunLoop()); } @@ -608,11 +611,14 @@ explicit FocusChangeObserver(Window* window) : window_(window), last_gained_focus_(nullptr), - last_lost_focus_(nullptr) { + last_lost_focus_(nullptr), + quit_on_change_(true) { window_->AddObserver(this); } ~FocusChangeObserver() override { window_->RemoveObserver(this); } + void set_quit_on_change(bool value) { quit_on_change_ = value; } + Window* last_gained_focus() { return last_gained_focus_; } Window* last_lost_focus() { return last_lost_focus_; } @@ -624,16 +630,39 @@ EXPECT_FALSE(lost_focus && lost_focus->HasFocus()); last_gained_focus_ = gained_focus; last_lost_focus_ = lost_focus; - EXPECT_TRUE(WindowServerTestBase::QuitRunLoop()); + if (quit_on_change_) + EXPECT_TRUE(WindowServerTestBase::QuitRunLoop()); } Window* window_; Window* last_gained_focus_; Window* last_lost_focus_; + bool quit_on_change_; MOJO_DISALLOW_COPY_AND_ASSIGN(FocusChangeObserver); }; +class NullFocusChangeObserver : public WindowTreeConnectionObserver { + public: + explicit NullFocusChangeObserver(WindowTreeConnection* connection) + : connection_(connection) { + connection_->AddObserver(this); + } + ~NullFocusChangeObserver() override { connection_->RemoveObserver(this); } + + private: + // Overridden from WindowTreeConnectionObserver. + void OnWindowTreeFocusChanged(Window* gained_focus, + Window* lost_focus) override { + if (!gained_focus) + EXPECT_TRUE(WindowServerTestBase::QuitRunLoop()); + } + + WindowTreeConnection* connection_; + + MOJO_DISALLOW_COPY_AND_ASSIGN(NullFocusChangeObserver); +}; + bool WaitForWindowToHaveFocus(Window* window) { if (window->HasFocus()) return true; @@ -641,6 +670,13 @@ return WindowServerTestBase::DoRunLoopWithTimeout(); } +bool WaitForNoWindowToHaveFocus(WindowTreeConnection* connection) { + if (!connection->GetFocusedWindow()) + return true; + NullFocusChangeObserver observer(connection); + return WindowServerTestBase::DoRunLoopWithTimeout(); +} + } // namespace TEST_F(WindowServerTest, Focus) { @@ -654,31 +690,39 @@ window11->SetVisible(true); embedded->GetRoot()->AddChild(window11); - // TODO(alhaad): Figure out why switching focus between windows from different - // connections is causing the tests to crash and add tests for that. { + // Focus the embed root in |embedded|. Window* embedded_root = embedded->GetRoot(); FocusChangeObserver observer(embedded_root); + observer.set_quit_on_change(false); embedded_root->SetFocus(); - ASSERT_TRUE(DoRunLoopWithTimeout()); + ASSERT_TRUE(embedded_root->HasFocus()); ASSERT_NE(nullptr, observer.last_gained_focus()); EXPECT_EQ(embedded_root->id(), observer.last_gained_focus()->id()); + + // |embedded_root| is the same as |window1|, make sure |window1| got + // focus too. + ASSERT_TRUE(WaitForWindowToHaveFocus(window1)); } + + // Focus a child of embedded->GetRoot(). { FocusChangeObserver observer(window11); + observer.set_quit_on_change(false); window11->SetFocus(); - ASSERT_TRUE(DoRunLoopWithTimeout()); + ASSERT_TRUE(window11->HasFocus()); ASSERT_NE(nullptr, observer.last_gained_focus()); ASSERT_NE(nullptr, observer.last_lost_focus()); EXPECT_EQ(window11->id(), observer.last_gained_focus()->id()); EXPECT_EQ(embedded->GetRoot()->id(), observer.last_lost_focus()->id()); } + { // Add an observer on the Window that loses focus, and make sure the // observer sees the right values. FocusChangeObserver observer(window11); + observer.set_quit_on_change(false); embedded->GetRoot()->SetFocus(); - ASSERT_TRUE(DoRunLoopWithTimeout()); ASSERT_NE(nullptr, observer.last_gained_focus()); ASSERT_NE(nullptr, observer.last_lost_focus()); EXPECT_EQ(window11->id(), observer.last_lost_focus()->id()); @@ -737,6 +781,7 @@ WaitForWindowToHaveFocus(window_manager()->GetWindowById(child21->id()))); EXPECT_EQ(child21->id(), window_manager()->GetFocusedWindow()->id()); EXPECT_EQ(child21->id(), embedded2->GetFocusedWindow()->id()); + EXPECT_TRUE(WaitForNoWindowToHaveFocus(embedded1)); EXPECT_EQ(nullptr, embedded1->GetFocusedWindow()); EXPECT_GT(ValidIndexOf(parent->children(), child2), ValidIndexOf(parent->children(), child1));
diff --git a/components/mus/ws/window_tree_apptest.cc b/components/mus/ws/window_tree_apptest.cc index 3895571..cbf3c57d 100644 --- a/components/mus/ws/window_tree_apptest.cc +++ b/components/mus/ws/window_tree_apptest.cc
@@ -44,13 +44,6 @@ // Callback function from WindowTree functions. // ---------------------------------- -void BoolResultCallback(base::RunLoop* run_loop, - bool* result_cache, - bool result) { - *result_cache = result; - run_loop->Quit(); -} - void WindowTreeResultCallback(base::RunLoop* run_loop, std::vector<TestWindow>* windows, Array<WindowDataPtr> results) { @@ -95,36 +88,6 @@ return result; } -bool AddWindow(WindowTree* ws, Id parent, Id child) { - bool result = false; - base::RunLoop run_loop; - ws->AddWindow(parent, child, - base::Bind(&BoolResultCallback, &run_loop, &result)); - run_loop.Run(); - return result; -} - -bool RemoveWindowFromParent(WindowTree* ws, Id window_id) { - bool result = false; - base::RunLoop run_loop; - ws->RemoveWindowFromParent( - window_id, base::Bind(&BoolResultCallback, &run_loop, &result)); - run_loop.Run(); - return result; -} - -bool ReorderWindow(WindowTree* ws, - Id window_id, - Id relative_window_id, - mojom::OrderDirection direction) { - bool result = false; - base::RunLoop run_loop; - ws->ReorderWindow(window_id, relative_window_id, direction, - base::Bind(&BoolResultCallback, &run_loop, &result)); - run_loop.Run(); - return result; -} - void GetWindowTree(WindowTree* ws, Id window_id, std::vector<TestWindow>* windows) { @@ -214,6 +177,26 @@ return WaitForChangeCompleted(change_id); } + bool AddWindow(Id parent, Id child) { + const uint32_t change_id = GetAndAdvanceChangeId(); + tree()->AddWindow(change_id, parent, child); + return WaitForChangeCompleted(change_id); + } + + bool RemoveWindowFromParent(Id window_id) { + const uint32_t change_id = GetAndAdvanceChangeId(); + tree()->RemoveWindowFromParent(change_id, window_id); + return WaitForChangeCompleted(change_id); + } + + bool ReorderWindow(Id window_id, + Id relative_window_id, + mojom::OrderDirection direction) { + const uint32_t change_id = GetAndAdvanceChangeId(); + tree()->ReorderWindow(change_id, window_id, relative_window_id, direction); + return WaitForChangeCompleted(change_id); + } + // Waits for all messages to be received by |ws|. This is done by attempting // to create a bogus window. When we get the response we know all messages // have been processed. @@ -248,6 +231,12 @@ return WaitForChangeCompleted(change_id); } + bool SetPredefinedCursor(Id window_id, mojom::Cursor cursor) { + const uint32_t change_id = GetAndAdvanceChangeId(); + tree()->SetPredefinedCursor(change_id, window_id, cursor); + return WaitForChangeCompleted(change_id); + } + bool SetWindowVisibility(Id window_id, bool visible) { const uint32_t change_id = GetAndAdvanceChangeId(); tree()->SetWindowVisibility(change_id, window_id, visible); @@ -300,9 +289,10 @@ tracker()->OnWindowBoundsChanged(window_id, old_bounds.Pass(), new_bounds.Pass()); } - void OnClientAreaChanged(uint32_t window_id, - mojo::InsetsPtr old_client_area, - mojo::InsetsPtr new_client_area) override {} + void OnClientAreaChanged( + uint32_t window_id, + mojo::InsetsPtr new_client_area, + mojo::Array<mojo::RectPtr> new_additional_client_areas) override {} void OnTransientWindowAdded(uint32_t window_id, uint32_t transient_window_id) override { tracker()->OnTransientWindowAdded(window_id, transient_window_id); @@ -350,6 +340,10 @@ } // TODO(sky): add testing coverage. void OnWindowFocused(uint32_t focused_window_id) override {} + void OnWindowPredefinedCursorChanged(uint32 window_id, + mojom::Cursor cursor_id) override { + tracker_.OnWindowPredefinedCursorChanged(window_id, cursor_id); + } void OnChangeCompleted(uint32_t change_id, bool success) override { if (waiting_change_id_ == change_id && change_completed_run_loop_) { on_change_completed_result_ = success; @@ -592,11 +586,11 @@ // Two windows 1 and 2. 2 is parented to 1. Id window_1_1 = ws_client1()->NewWindow(1); ASSERT_TRUE(window_1_1); - ASSERT_TRUE(AddWindow(ws1(), root_window_id(), window_1_1)); + ASSERT_TRUE(ws_client1()->AddWindow(root_window_id(), window_1_1)); Id window_1_2 = ws_client1()->NewWindow(2); ASSERT_TRUE(window_1_2); - ASSERT_TRUE(AddWindow(ws1(), window_1_1, window_1_2)); + ASSERT_TRUE(ws_client1()->AddWindow(window_1_1, window_1_2)); ASSERT_NO_FATAL_FAILURE(EstablishSecondConnection(false)); ASSERT_EQ(1u, changes2()->size()); @@ -630,7 +624,7 @@ Id window_2_4 = ws_client2()->NewWindow(4); ASSERT_TRUE(window_2_3); ASSERT_TRUE(window_2_4); - ASSERT_TRUE(AddWindow(ws2(), window_2_3, window_2_4)); + ASSERT_TRUE(ws_client2()->AddWindow(window_2_3, window_2_4)); // Connection 3 rooted at 2. ASSERT_NO_FATAL_FAILURE(EstablishThirdConnection(ws2(), window_2_3)); @@ -665,13 +659,13 @@ Id window_1_1 = BuildWindowId(connection_id_1(), 1); Id window_2_2 = ws_client2()->NewWindow(2); ASSERT_TRUE(window_2_2); - ASSERT_TRUE(AddWindow(ws2(), window_1_1, window_2_2)); + ASSERT_TRUE(ws_client2()->AddWindow(window_1_1, window_2_2)); ASSERT_NO_FATAL_FAILURE(EstablishThirdConnection(ws2(), window_2_2)); Id window_3_3 = ws_client3()->NewWindow(3); ASSERT_TRUE(window_3_3); - ASSERT_TRUE(AddWindow(ws3(), window_2_2, window_3_3)); + ASSERT_TRUE(ws_client3()->AddWindow(window_2_2, window_3_3)); // Even though 3 is a child of 2 connection 2 can't see 3 as it's from a // different connection. @@ -710,22 +704,22 @@ Id window_1_1 = BuildWindowId(connection_id_1(), 1); Id window_2_2 = ws_client2()->NewWindow(2); ASSERT_TRUE(window_2_2); - ASSERT_TRUE(AddWindow(ws2(), window_1_1, window_2_2)); + ASSERT_TRUE(ws_client2()->AddWindow(window_1_1, window_2_2)); ASSERT_NO_FATAL_FAILURE(EstablishThirdConnection(ws2(), window_2_2)); Id window_2_3 = ws_client2()->NewWindow(3); ASSERT_TRUE(window_2_3); // Connection 2 shouldn't be able to add anything to the window anymore. - ASSERT_FALSE(AddWindow(ws2(), window_2_2, window_2_3)); + ASSERT_FALSE(ws_client2()->AddWindow(window_2_2, window_2_3)); // Create window 3 in connection 3 and add it to window 3. Id window_3_3 = ws_client3()->NewWindow(3); ASSERT_TRUE(window_3_3); - ASSERT_TRUE(AddWindow(ws3(), window_2_2, window_3_3)); + ASSERT_TRUE(ws_client3()->AddWindow(window_2_2, window_3_3)); // Connection 2 shouldn't be able to remove window 3. - ASSERT_FALSE(RemoveWindowFromParent(ws2(), window_3_3)); + ASSERT_FALSE(ws_client2()->RemoveWindowFromParent(window_3_3)); } // Verifies client gets a valid id. @@ -754,10 +748,10 @@ ASSERT_NO_FATAL_FAILURE(EstablishSecondConnection(true)); // Make 3 a child of 2. - ASSERT_TRUE(AddWindow(ws1(), window_1_2, window_1_3)); + ASSERT_TRUE(ws_client1()->AddWindow(window_1_2, window_1_3)); // Try again, this should fail. - EXPECT_FALSE(AddWindow(ws1(), window_1_2, window_1_3)); + EXPECT_FALSE(ws_client1()->AddWindow(window_1_2, window_1_3)); } // Verifies AddWindow fails when window is already in position. @@ -770,10 +764,10 @@ ASSERT_NO_FATAL_FAILURE(EstablishSecondConnection(true)); // Make 3 a child of 2. - ASSERT_TRUE(AddWindow(ws1(), window_1_2, window_1_3)); + ASSERT_TRUE(ws_client1()->AddWindow(window_1_2, window_1_3)); // Try to make 2 a child of 3, this should fail since 2 is an ancestor of 3. - EXPECT_FALSE(AddWindow(ws1(), window_1_3, window_1_2)); + EXPECT_FALSE(ws_client1()->AddWindow(window_1_3, window_1_2)); } // Verifies adding to root sends right notifications. @@ -788,10 +782,10 @@ changes2()->clear(); // Make 3 a child of 21. - ASSERT_TRUE(AddWindow(ws1(), window_1_21, window_1_3)); + ASSERT_TRUE(ws_client1()->AddWindow(window_1_21, window_1_3)); // Make 21 a child of 1. - ASSERT_TRUE(AddWindow(ws1(), window_1_1, window_1_21)); + ASSERT_TRUE(ws_client1()->AddWindow(window_1_1, window_1_21)); // Connection 2 should not be told anything (because the window is from a // different connection). Create a window to ensure we got a response from @@ -809,7 +803,7 @@ Id window_1_11 = ws_client1()->NewWindow(11); ASSERT_TRUE(window_1_11); ASSERT_TRUE(ws_client1()->SetWindowVisibility(window_1_11, true)); - ASSERT_TRUE(AddWindow(ws1(), window_1_2, window_1_11)); + ASSERT_TRUE(ws_client1()->AddWindow(window_1_2, window_1_11)); Id window_1_1 = BuildWindowId(connection_id_1(), 1); ASSERT_NO_FATAL_FAILURE(EstablishSecondConnection(true)); @@ -821,7 +815,7 @@ // 1,1->1,2->1,11 { // Client 2 should not get anything (1,2 is from another connection). - ASSERT_TRUE(AddWindow(ws1(), window_1_1, window_1_2)); + ASSERT_TRUE(ws_client1()->AddWindow(window_1_1, window_1_2)); ASSERT_TRUE(ws_client2()->WaitForAllMessages()); EXPECT_TRUE(changes2()->empty()); } @@ -830,7 +824,7 @@ { // Client 2 is now connected to the root, so it should have gotten a drawn // notification. - ASSERT_TRUE(AddWindow(ws1(), root_window_id(), window_1_1)); + ASSERT_TRUE(ws_client1()->AddWindow(root_window_id(), window_1_1)); ws_client2_->WaitForChangeCount(1u); EXPECT_EQ( "DrawnStateChanged window=" + IdToString(window_1_1) + " drawn=true", @@ -842,7 +836,7 @@ // Client 2 is no longer connected to the root, should get drawn state // changed. changes2()->clear(); - ASSERT_TRUE(RemoveWindowFromParent(ws1(), window_1_1)); + ASSERT_TRUE(ws_client1()->RemoveWindowFromParent(window_1_1)); ws_client2_->WaitForChangeCount(1); EXPECT_EQ( "DrawnStateChanged window=" + IdToString(window_1_1) + " drawn=false", @@ -855,7 +849,7 @@ ASSERT_TRUE(ws_client1()->SetWindowVisibility(window_1_111, true)); { changes2()->clear(); - ASSERT_TRUE(AddWindow(ws1(), window_1_11, window_1_111)); + ASSERT_TRUE(ws_client1()->AddWindow(window_1_11, window_1_111)); ASSERT_TRUE(ws_client2()->WaitForAllMessages()); EXPECT_TRUE(changes2()->empty()); } @@ -863,7 +857,7 @@ // 0,1->1,1->1,2->1,11->1,111 { changes2()->clear(); - ASSERT_TRUE(AddWindow(ws1(), root_window_id(), window_1_1)); + ASSERT_TRUE(ws_client1()->AddWindow(root_window_id(), window_1_1)); ws_client2_->WaitForChangeCount(1); EXPECT_EQ( "DrawnStateChanged window=" + IdToString(window_1_1) + " drawn=true", @@ -885,14 +879,14 @@ ASSERT_TRUE(window_2_21); // Set up the hierarchy. - ASSERT_TRUE(AddWindow(ws1(), root_window_id(), window_1_1)); - ASSERT_TRUE(AddWindow(ws2(), window_1_1, window_2_11)); - ASSERT_TRUE(AddWindow(ws2(), window_2_2, window_2_21)); + ASSERT_TRUE(ws_client1()->AddWindow(root_window_id(), window_1_1)); + ASSERT_TRUE(ws_client2()->AddWindow(window_1_1, window_2_11)); + ASSERT_TRUE(ws_client2()->AddWindow(window_2_2, window_2_21)); // Remove 11, should result in a hierarchy change for the root. { changes1()->clear(); - ASSERT_TRUE(RemoveWindowFromParent(ws2(), window_2_11)); + ASSERT_TRUE(ws_client2()->RemoveWindowFromParent(window_2_11)); ws_client1_->WaitForChangeCount(1); EXPECT_EQ("HierarchyChanged window=" + IdToString(window_2_11) + @@ -903,7 +897,7 @@ // Add 2 to 1. { changes1()->clear(); - ASSERT_TRUE(AddWindow(ws2(), window_1_1, window_2_2)); + ASSERT_TRUE(ws_client2()->AddWindow(window_1_1, window_2_2)); ws_client1_->WaitForChangeCount(1); EXPECT_EQ("HierarchyChanged window=" + IdToString(window_2_2) + " new_parent=" + IdToString(window_1_1) + " old_parent=null", @@ -934,17 +928,17 @@ ASSERT_TRUE(window_2_7); ASSERT_TRUE(window_2_8); - ASSERT_TRUE(AddWindow(ws2(), window_2_1, window_2_2)); - ASSERT_TRUE(AddWindow(ws2(), window_2_2, window_2_6)); - ASSERT_TRUE(AddWindow(ws2(), window_2_1, window_2_3)); - ASSERT_TRUE(AddWindow(ws1(), root_window_id(), window_1_4)); - ASSERT_TRUE(AddWindow(ws1(), root_window_id(), window_1_5)); - ASSERT_TRUE(AddWindow(ws1(), root_window_id(), window_2_1)); + ASSERT_TRUE(ws_client2()->AddWindow(window_2_1, window_2_2)); + ASSERT_TRUE(ws_client2()->AddWindow(window_2_2, window_2_6)); + ASSERT_TRUE(ws_client2()->AddWindow(window_2_1, window_2_3)); + ASSERT_TRUE(ws_client1()->AddWindow(root_window_id(), window_1_4)); + ASSERT_TRUE(ws_client1()->AddWindow(root_window_id(), window_1_5)); + ASSERT_TRUE(ws_client1()->AddWindow(root_window_id(), window_2_1)); { changes1()->clear(); - ASSERT_TRUE(ReorderWindow(ws2(), window_2_2, window_2_3, - mojom::ORDER_DIRECTION_ABOVE)); + ASSERT_TRUE(ws_client2()->ReorderWindow(window_2_2, window_2_3, + mojom::ORDER_DIRECTION_ABOVE)); ws_client1_->WaitForChangeCount(1); EXPECT_EQ("Reordered window=" + IdToString(window_2_2) + " relative=" + @@ -954,8 +948,8 @@ { changes1()->clear(); - ASSERT_TRUE(ReorderWindow(ws2(), window_2_2, window_2_3, - mojom::ORDER_DIRECTION_BELOW)); + ASSERT_TRUE(ws_client2()->ReorderWindow(window_2_2, window_2_3, + mojom::ORDER_DIRECTION_BELOW)); ws_client1_->WaitForChangeCount(1); EXPECT_EQ("Reordered window=" + IdToString(window_2_2) + " relative=" + @@ -964,25 +958,25 @@ } // view2 is already below view3. - EXPECT_FALSE(ReorderWindow(ws2(), window_2_2, window_2_3, - mojom::ORDER_DIRECTION_BELOW)); + EXPECT_FALSE(ws_client2()->ReorderWindow(window_2_2, window_2_3, + mojom::ORDER_DIRECTION_BELOW)); // view4 & 5 are unknown to connection2_. - EXPECT_FALSE(ReorderWindow(ws2(), window_1_4, window_1_5, - mojom::ORDER_DIRECTION_ABOVE)); + EXPECT_FALSE(ws_client2()->ReorderWindow(window_1_4, window_1_5, + mojom::ORDER_DIRECTION_ABOVE)); // view6 & view3 have different parents. - EXPECT_FALSE(ReorderWindow(ws1(), window_2_3, window_2_6, - mojom::ORDER_DIRECTION_ABOVE)); + EXPECT_FALSE(ws_client1()->ReorderWindow(window_2_3, window_2_6, + mojom::ORDER_DIRECTION_ABOVE)); // Non-existent window-ids - EXPECT_FALSE(ReorderWindow(ws1(), BuildWindowId(connection_id_1(), 27), - BuildWindowId(connection_id_1(), 28), - mojom::ORDER_DIRECTION_ABOVE)); + EXPECT_FALSE(ws_client1()->ReorderWindow(BuildWindowId(connection_id_1(), 27), + BuildWindowId(connection_id_1(), 28), + mojom::ORDER_DIRECTION_ABOVE)); // view7 & view8 are un-parented. - EXPECT_FALSE(ReorderWindow(ws1(), window_2_7, window_2_8, - mojom::ORDER_DIRECTION_ABOVE)); + EXPECT_FALSE(ws_client1()->ReorderWindow(window_2_7, window_2_8, + mojom::ORDER_DIRECTION_ABOVE)); } // Verifies DeleteWindow works. @@ -995,7 +989,7 @@ // Make 2 a child of 1. { changes1()->clear(); - ASSERT_TRUE(AddWindow(ws2(), window_1_1, window_2_2)); + ASSERT_TRUE(ws_client2()->AddWindow(window_1_1, window_2_2)); ws_client1_->WaitForChangeCount(1); EXPECT_EQ("HierarchyChanged window=" + IdToString(window_2_2) + " new_parent=" + IdToString(window_1_1) + " old_parent=null", @@ -1032,7 +1026,7 @@ // Add 2 to 1. { changes1()->clear(); - ASSERT_TRUE(AddWindow(ws2(), window_1_1, window_2_2)); + ASSERT_TRUE(ws_client2()->AddWindow(window_1_1, window_2_2)); ws_client1_->WaitForChangeCount(1); EXPECT_EQ("HierarchyChanged window=" + IdToString(window_2_2) + " new_parent=" + IdToString(window_1_1) + " old_parent=null", @@ -1056,7 +1050,7 @@ ASSERT_TRUE(window_2_2); { changes1()->clear(); - ASSERT_TRUE(AddWindow(ws2(), window_1_1, window_2_2)); + ASSERT_TRUE(ws_client2()->AddWindow(window_1_1, window_2_2)); ws_client1_->WaitForChangeCount(1); EXPECT_EQ("HierarchyChanged window=" + IdToString(window_2_2) + @@ -1075,16 +1069,16 @@ // Create 11 in first connection and make it a child of 1. Id window_1_11 = ws_client1()->NewWindow(11); ASSERT_TRUE(window_1_11); - ASSERT_TRUE(AddWindow(ws1(), root_window_id(), window_1_1)); - ASSERT_TRUE(AddWindow(ws1(), window_1_1, window_1_11)); + ASSERT_TRUE(ws_client1()->AddWindow(root_window_id(), window_1_1)); + ASSERT_TRUE(ws_client1()->AddWindow(window_1_1, window_1_11)); // Create two windows in second connection, 2 and 3, both children of 1. Id window_2_2 = ws_client2()->NewWindow(2); Id window_2_3 = ws_client2()->NewWindow(3); ASSERT_TRUE(window_2_2); ASSERT_TRUE(window_2_3); - ASSERT_TRUE(AddWindow(ws2(), window_1_1, window_2_2)); - ASSERT_TRUE(AddWindow(ws2(), window_1_1, window_2_3)); + ASSERT_TRUE(ws_client2()->AddWindow(window_1_1, window_2_2)); + ASSERT_TRUE(ws_client2()->AddWindow(window_1_1, window_2_3)); // Verifies GetWindowTree() on the root. The root connection sees all. { @@ -1129,7 +1123,7 @@ TEST_F(WindowTreeAppTest, SetWindowBounds) { Id window_1_1 = ws_client1()->NewWindow(1); ASSERT_TRUE(window_1_1); - ASSERT_TRUE(AddWindow(ws1(), root_window_id(), window_1_1)); + ASSERT_TRUE(ws_client1()->AddWindow(root_window_id(), window_1_1)); ASSERT_NO_FATAL_FAILURE(EstablishSecondConnection(false)); @@ -1163,11 +1157,11 @@ // Try to move 2 to be a child of 1 from connection 2. This should fail as 2 // should not be able to access 1. - ASSERT_FALSE(AddWindow(ws2(), window_1_1, window_1_2)); + ASSERT_FALSE(ws_client2()->AddWindow(window_1_1, window_1_2)); // Try to reparent 1 to the root. A connection is not allowed to reparent its // roots. - ASSERT_FALSE(AddWindow(ws2(), root_window_id(), window_1_1)); + ASSERT_FALSE(ws_client2()->AddWindow(root_window_id(), window_1_1)); } // Verify RemoveWindowFromParent fails for windows that are descendants of the @@ -1179,15 +1173,15 @@ ASSERT_TRUE(window_1_1); ASSERT_TRUE(window_1_2); - ASSERT_TRUE(AddWindow(ws1(), root_window_id(), window_1_1)); - ASSERT_TRUE(AddWindow(ws1(), root_window_id(), window_1_2)); + ASSERT_TRUE(ws_client1()->AddWindow(root_window_id(), window_1_1)); + ASSERT_TRUE(ws_client1()->AddWindow(root_window_id(), window_1_2)); // Establish the second connection and give it the root 1. ASSERT_NO_FATAL_FAILURE(EstablishSecondConnection(false)); // Connection 2 should not be able to remove window 2 or 1 from its parent. - ASSERT_FALSE(RemoveWindowFromParent(ws2(), window_1_2)); - ASSERT_FALSE(RemoveWindowFromParent(ws2(), window_1_1)); + ASSERT_FALSE(ws_client2()->RemoveWindowFromParent(window_1_2)); + ASSERT_FALSE(ws_client2()->RemoveWindowFromParent(window_1_1)); // Create windows 10 and 11 in 2. Id window_2_10 = ws_client2()->NewWindow(10); @@ -1196,9 +1190,9 @@ ASSERT_TRUE(window_2_11); // Parent 11 to 10. - ASSERT_TRUE(AddWindow(ws2(), window_2_10, window_2_11)); + ASSERT_TRUE(ws_client2()->AddWindow(window_2_10, window_2_11)); // Remove 11 from 10. - ASSERT_TRUE(RemoveWindowFromParent(ws2(), window_2_11)); + ASSERT_TRUE(ws_client2()->RemoveWindowFromParent(window_2_11)); // Verify nothing was actually removed. { @@ -1222,8 +1216,8 @@ ASSERT_TRUE(window_1_1); ASSERT_TRUE(window_1_2); - ASSERT_TRUE(AddWindow(ws1(), root_window_id(), window_1_1)); - ASSERT_TRUE(AddWindow(ws1(), root_window_id(), window_1_2)); + ASSERT_TRUE(ws_client1()->AddWindow(root_window_id(), window_1_1)); + ASSERT_TRUE(ws_client1()->AddWindow(root_window_id(), window_1_2)); ASSERT_NO_FATAL_FAILURE(EstablishSecondConnection(false)); @@ -1281,7 +1275,7 @@ // Create a window in the third connection and parent it to the root. Id window_3_1 = ws_client3()->NewWindow(1); ASSERT_TRUE(window_3_1); - ASSERT_TRUE(AddWindow(ws3(), window_1_1, window_3_1)); + ASSERT_TRUE(ws_client3()->AddWindow(window_1_1, window_3_1)); // Connection 1 should have been told about the add (it owns the window). { @@ -1344,7 +1338,7 @@ ASSERT_TRUE(window_1_1); ASSERT_TRUE(window_1_2); - ASSERT_TRUE(AddWindow(ws1(), root_window_id(), window_1_1)); + ASSERT_TRUE(ws_client1()->AddWindow(root_window_id(), window_1_1)); { std::vector<TestWindow> windows; GetWindowTree(ws1(), root_window_id(), &windows); @@ -1384,7 +1378,7 @@ } // Attach 2 to 1. - ASSERT_TRUE(AddWindow(ws1(), window_1_1, window_1_2)); + ASSERT_TRUE(ws_client1()->AddWindow(window_1_1, window_1_2)); { std::vector<TestWindow> windows; GetWindowTree(ws1(), window_1_1, &windows); @@ -1412,6 +1406,21 @@ } } +// Test that we hear the cursor change in other connections. +TEST_F(WindowTreeAppTest, SetCursor) { + // Get a second connection to listen in. + ASSERT_NO_FATAL_FAILURE(EstablishSecondConnection(true)); + Id window_1_1 = BuildWindowId(connection_id_1(), 1); + changes2()->clear(); + + ASSERT_TRUE(ws_client1()->SetPredefinedCursor(window_1_1, + mojom::Cursor::CURSOR_IBEAM)); + ws_client2_->WaitForChangeCount(1u); + + EXPECT_EQ("CursorChanged id=" + IdToString(window_1_1) + " cursor_id=4", + SingleChangeToDescription(*changes2())); +} + // Assertions for SetWindowVisibility sending notifications. TEST_F(WindowTreeAppTest, SetWindowVisibilityNotifications) { // Create 1,1 and 1,2. 1,2 is made a child of 1,1 and 1,1 a child of the root. @@ -1421,8 +1430,8 @@ Id window_1_2 = ws_client1()->NewWindow(2); ASSERT_TRUE(window_1_2); ASSERT_TRUE(ws_client1()->SetWindowVisibility(window_1_2, true)); - ASSERT_TRUE(AddWindow(ws1(), root_window_id(), window_1_1)); - ASSERT_TRUE(AddWindow(ws1(), window_1_1, window_1_2)); + ASSERT_TRUE(ws_client1()->AddWindow(root_window_id(), window_1_1)); + ASSERT_TRUE(ws_client1()->AddWindow(window_1_1, window_1_2)); // Establish the second connection at 1,2. ASSERT_NO_FATAL_FAILURE(EstablishSecondConnectionWithRoot(window_1_2)); @@ -1431,7 +1440,7 @@ Id window_2_3 = ws_client2()->NewWindow(3); ASSERT_TRUE(window_2_3); ASSERT_TRUE(ws_client2()->SetWindowVisibility(window_2_3, true)); - ASSERT_TRUE(AddWindow(ws2(), window_1_2, window_2_3)); + ASSERT_TRUE(ws_client2()->AddWindow(window_1_2, window_2_3)); ASSERT_TRUE(ws_client1()->WaitForAllMessages()); changes2()->clear(); @@ -1486,7 +1495,7 @@ changes2()->clear(); // Remove 1,1 from the root, connection 2 should see drawn state changed. - ASSERT_TRUE(RemoveWindowFromParent(ws1(), window_1_1)); + ASSERT_TRUE(ws_client1()->RemoveWindowFromParent(window_1_1)); { ws_client2_->WaitForChangeCount(1); EXPECT_EQ( @@ -1496,7 +1505,7 @@ changes2()->clear(); // Add 1,1 back to the root, connection 2 should see drawn state changed. - ASSERT_TRUE(AddWindow(ws1(), root_window_id(), window_1_1)); + ASSERT_TRUE(ws_client1()->AddWindow(root_window_id(), window_1_1)); { ws_client2_->WaitForChangeCount(1); EXPECT_EQ( @@ -1512,7 +1521,7 @@ ASSERT_NO_FATAL_FAILURE(EstablishSecondConnection(false)); changes2()->clear(); - ASSERT_TRUE(AddWindow(ws1(), root_window_id(), window_1_1)); + ASSERT_TRUE(ws_client1()->AddWindow(root_window_id(), window_1_1)); { std::vector<TestWindow> windows; GetWindowTree(ws1(), root_window_id(), &windows); @@ -1559,7 +1568,7 @@ Id window_1_1 = BuildWindowId(connection_id_1(), 1); Id window_2_2 = ws_client2()->NewWindow(2); ASSERT_TRUE(window_2_2); - ASSERT_TRUE(AddWindow(ws2(), window_1_1, window_2_2)); + ASSERT_TRUE(ws_client2()->AddWindow(window_1_1, window_2_2)); changes2()->clear(); ASSERT_NO_FATAL_FAILURE(EstablishThirdConnection(ws2(), window_2_2)); @@ -1585,13 +1594,13 @@ // Create connection 2 and 3. ASSERT_NO_FATAL_FAILURE(EstablishSecondConnection(true)); Id window_1_1 = BuildWindowId(connection_id_1(), 1); - ASSERT_TRUE(AddWindow(ws1(), root_window_id(), window_1_1)); + ASSERT_TRUE(ws_client1()->AddWindow(root_window_id(), window_1_1)); Id window_2_2 = ws_client2()->NewWindow(2); Id window_2_3 = ws_client2()->NewWindow(3); ASSERT_TRUE(window_2_2); ASSERT_TRUE(window_2_3); - ASSERT_TRUE(AddWindow(ws2(), window_1_1, window_2_2)); - ASSERT_TRUE(AddWindow(ws2(), window_2_2, window_2_3)); + ASSERT_TRUE(ws_client2()->AddWindow(window_1_1, window_2_2)); + ASSERT_TRUE(ws_client2()->AddWindow(window_2_2, window_2_3)); changes2()->clear(); ASSERT_NO_FATAL_FAILURE(EstablishThirdConnection(ws2(), window_2_3)); changes3()->clear(); @@ -1639,12 +1648,12 @@ Id window_1_1 = BuildWindowId(connection_id_1(), 1); Id window_2_2 = ws_client2()->NewWindow(2); ASSERT_TRUE(window_2_2); - ASSERT_TRUE(AddWindow(ws2(), window_1_1, window_2_2)); + ASSERT_TRUE(ws_client2()->AddWindow(window_1_1, window_2_2)); ASSERT_NO_FATAL_FAILURE(EstablishThirdConnection(ws2(), window_2_2)); Id window_3_3 = ws_client3()->NewWindow(3); ASSERT_TRUE(window_3_3); - ASSERT_TRUE(AddWindow(ws3(), window_2_2, window_3_3)); + ASSERT_TRUE(ws_client3()->AddWindow(window_2_2, window_3_3)); // 2 should not be able to embed in window_3_3 as window_3_3 was not created // by @@ -1660,7 +1669,7 @@ Id window_1_1 = BuildWindowId(connection_id_1(), 1); Id window_2_2 = ws_client2()->NewWindow(2); ASSERT_TRUE(window_2_2); - ASSERT_TRUE(AddWindow(ws2(), window_1_1, window_2_2)); + ASSERT_TRUE(ws_client2()->AddWindow(window_1_1, window_2_2)); changes2()->clear(); @@ -1692,7 +1701,7 @@ Id window_1_2 = ws_client1()->NewWindow(2); ASSERT_TRUE(window_1_2); ASSERT_TRUE( - AddWindow(ws1(), BuildWindowId(connection_id_1(), 1), window_1_2)); + ws_client1()->AddWindow(BuildWindowId(connection_id_1(), 1), window_1_2)); ASSERT_TRUE(ws_client3_.get() == nullptr); ws_client3_ = EstablishConnectionViaEmbedWithPolicyBitmask( ws1(), window_1_2, mojom::WindowTree::ACCESS_POLICY_EMBED_ROOT, nullptr); @@ -1718,10 +1727,10 @@ // root -> window_1_1 -> window_2_1 // root -> window_1_1 -> window_2_2 // root -> window_1_1 -> window_2_3 - ASSERT_TRUE(AddWindow(ws1(), root_window_id(), window_1_1)); - ASSERT_TRUE(AddWindow(ws2(), window_1_1, window_2_1)); - ASSERT_TRUE(AddWindow(ws2(), window_1_1, window_2_2)); - ASSERT_TRUE(AddWindow(ws2(), window_1_1, window_2_3)); + ASSERT_TRUE(ws_client1()->AddWindow(root_window_id(), window_1_1)); + ASSERT_TRUE(ws_client2()->AddWindow(window_1_1, window_2_1)); + ASSERT_TRUE(ws_client2()->AddWindow(window_1_1, window_2_2)); + ASSERT_TRUE(ws_client2()->AddWindow(window_1_1, window_2_3)); // window_2_2 and window_2_3 now track the lifetime of window_2_1. changes1()->clear();
diff --git a/components/mus/ws/window_tree_host_impl.cc b/components/mus/ws/window_tree_host_impl.cc index 8214b692..413f52a 100644 --- a/components/mus/ws/window_tree_host_impl.cc +++ b/components/mus/ws/window_tree_host_impl.cc
@@ -7,6 +7,7 @@ #include "base/debug/debugger.h" #include "base/strings/utf_string_conversions.h" #include "components/mus/common/types.h" +#include "components/mus/public/interfaces/input_event_constants.mojom.h" #include "components/mus/ws/connection_manager.h" #include "components/mus/ws/display_manager.h" #include "components/mus/ws/focus_controller.h" @@ -43,7 +44,8 @@ display_manager_( DisplayManager::Create(app_impl, gpu_state, surfaces_state)), window_manager_(window_manager.Pass()), - tree_awaiting_input_ack_(nullptr) { + tree_awaiting_input_ack_(nullptr), + last_cursor_(0) { display_manager_->Init(this); if (client_) { client_.set_connection_error_handler(base::Bind( @@ -131,6 +133,11 @@ display_manager_->SetImeVisibility(visible); } +void WindowTreeHostImpl::OnCursorUpdated(ServerWindow* window) { + if (window == event_dispatcher_.mouse_cursor_source_window()) + UpdateNativeCursor(window->cursor()); +} + void WindowTreeHostImpl::SetSize(mojo::SizePtr size) { display_manager_->SetViewportSize(size.To<gfx::Size>()); } @@ -217,6 +224,13 @@ event_dispatcher_.OnEvent(next_event.Pass()); } +void WindowTreeHostImpl::UpdateNativeCursor(int32_t cursor_id) { + if (cursor_id != last_cursor_) { + display_manager_->SetCursorById(cursor_id); + last_cursor_ = cursor_id; + } +} + ServerWindow* WindowTreeHostImpl::GetRootWindow() { return root_.get(); } @@ -366,6 +380,14 @@ bool in_nonclient_area, mojom::EventPtr event) { DCHECK(!event_ack_timer_.IsRunning()); + + if (event->pointer_data && + event->pointer_data->kind == mojom::PointerKind::POINTER_KIND_MOUSE) { + DCHECK(event_dispatcher_.mouse_cursor_source_window()); + UpdateNativeCursor( + event_dispatcher_.mouse_cursor_source_window()->cursor()); + } + // If the event is in the non-client area the event goes to the owner of // the window. Otherwise if the window is an embed root, forward to the // embedded window.
diff --git a/components/mus/ws/window_tree_host_impl.h b/components/mus/ws/window_tree_host_impl.h index 3ed61fe..1d50dc0e 100644 --- a/components/mus/ws/window_tree_host_impl.h +++ b/components/mus/ws/window_tree_host_impl.h
@@ -93,6 +93,10 @@ const ui::TextInputState& state); void SetImeVisibility(ServerWindow* window, bool visible); + // Called when a client updates a cursor. This will update the cursor on the + // native display if the cursor is currently under |window|. + void OnCursorUpdated(ServerWindow* window); + // WindowTreeHost: void SetSize(mojo::SizePtr size) override; void SetTitle(const mojo::String& title) override; @@ -118,6 +122,8 @@ void OnEventAckTimeout(); void DispatchNextEventFromQueue(); + void UpdateNativeCursor(int32_t cursor_id); + // DisplayManagerDelegate: ServerWindow* GetRootWindow() override; void OnEvent(mojom::EventPtr event) override; @@ -159,6 +165,9 @@ mojom::WindowManagerPtr window_manager_; mojom::WindowTree* tree_awaiting_input_ack_; + // The last cursor set. Used to track whether we need to change the cursor. + int32_t last_cursor_; + std::set<WindowId> activation_parents_; // Set of windows with surfaces that need to be destroyed once the frame
diff --git a/components/mus/ws/window_tree_impl.cc b/components/mus/ws/window_tree_impl.cc index 38c9305..b58cc5b 100644 --- a/components/mus/ws/window_tree_impl.cc +++ b/components/mus/ws/window_tree_impl.cc
@@ -221,14 +221,14 @@ void WindowTreeImpl::ProcessClientAreaChanged( const ServerWindow* window, - const gfx::Insets& old_client_area, const gfx::Insets& new_client_area, + const std::vector<gfx::Rect>& new_additional_client_areas, bool originated_change) { if (originated_change || !IsWindowKnown(window)) return; - client()->OnClientAreaChanged(WindowIdToTransportId(window->id()), - mojo::Insets::From(old_client_area), - mojo::Insets::From(new_client_area)); + client()->OnClientAreaChanged( + WindowIdToTransportId(window->id()), mojo::Insets::From(new_client_area), + mojo::Array<mojo::RectPtr>::From(new_additional_client_areas)); } void WindowTreeImpl::ProcessViewportMetricsChanged( @@ -364,6 +364,15 @@ NotifyDrawnStateChanged(window, window_target_drawn_state); } +void WindowTreeImpl::ProcessCursorChanged(const ServerWindow* window, + int32_t cursor_id, + bool originated_change) { + if (originated_change) + return; + client()->OnWindowPredefinedCursorChanged(WindowIdToTransportId(window->id()), + mojom::Cursor(cursor_id)); +} + void WindowTreeImpl::ProcessFocusChanged( const ServerWindow* old_focused_window, const ServerWindow* new_focused_window) { @@ -648,16 +657,13 @@ client_->OnChangeCompleted(change_id, success); } -void WindowTreeImpl::AddWindow(Id parent_id, - Id child_id, - const Callback<void(bool)>& callback) { - callback.Run(AddWindow(WindowIdFromTransportId(parent_id), - WindowIdFromTransportId(child_id))); +void WindowTreeImpl::AddWindow(uint32_t change_id, Id parent_id, Id child_id) { + client_->OnChangeCompleted(change_id, + AddWindow(WindowIdFromTransportId(parent_id), + WindowIdFromTransportId(child_id))); } -void WindowTreeImpl::RemoveWindowFromParent( - Id window_id, - const Callback<void(bool)>& callback) { +void WindowTreeImpl::RemoveWindowFromParent(uint32_t change_id, Id window_id) { bool success = false; ServerWindow* window = GetWindow(WindowIdFromTransportId(window_id)); if (window && window->parent() && @@ -667,7 +673,7 @@ OperationType::REMOVE_WINDOW_FROM_PARENT); window->parent()->Remove(window); } - callback.Run(success); + client_->OnChangeCompleted(change_id, success); } void WindowTreeImpl::AddTransientWindow(uint32_t change_id, @@ -694,10 +700,10 @@ client_->OnChangeCompleted(change_id, success); } -void WindowTreeImpl::ReorderWindow(Id window_id, +void WindowTreeImpl::ReorderWindow(uint32_t change_id, + Id window_id, Id relative_window_id, - mojom::OrderDirection direction, - const Callback<void(bool)>& callback) { + mojom::OrderDirection direction) { bool success = false; ServerWindow* window = GetWindow(WindowIdFromTransportId(window_id)); ServerWindow* relative_window = @@ -709,7 +715,7 @@ connection_manager_->ProcessWindowReorder(window, relative_window, direction); } - callback.Run(success); + client_->OnChangeCompleted(change_id, success); } void WindowTreeImpl::GetWindowTree( @@ -787,7 +793,7 @@ window->CreateSurface(type, surface.Pass(), client.Pass()); } -void WindowTreeImpl::SetWindowTextInputState(uint32_t window_id, +void WindowTreeImpl::SetWindowTextInputState(Id window_id, mojo::TextInputStatePtr state) { ServerWindow* window = GetWindow(WindowIdFromTransportId(window_id)); bool success = window && access_policy_->CanSetWindowTextInputState(window); @@ -820,14 +826,18 @@ GetHost()->OnEventAck(this); } -void WindowTreeImpl::SetClientArea(Id transport_window_id, - mojo::InsetsPtr insets) { +void WindowTreeImpl::SetClientArea( + Id transport_window_id, + mojo::InsetsPtr insets, + mojo::Array<mojo::RectPtr> transport_additional_client_areas) { ServerWindow* window = GetWindow(WindowIdFromTransportId(transport_window_id)); if (!window || !access_policy_->CanSetClientArea(window)) return; - window->SetClientArea(insets.To<gfx::Insets>()); + std::vector<gfx::Rect> additional_client_areas = + transport_additional_client_areas.To<std::vector<gfx::Rect>>(); + window->SetClientArea(insets.To<gfx::Insets>(), additional_client_areas); } void WindowTreeImpl::Embed(Id transport_window_id, @@ -840,24 +850,41 @@ callback.Run(result, connection_id); } -void WindowTreeImpl::SetFocus(uint32_t window_id) { +void WindowTreeImpl::SetFocus(uint32_t change_id, Id window_id) { ServerWindow* window = GetWindow(WindowIdFromTransportId(window_id)); // TODO(beng): consider shifting non-policy drawn check logic to VTH's // FocusController. - if (window && window->IsDrawn() && access_policy_->CanSetFocus(window)) { + WindowTreeHostImpl* host = GetHost(); + const bool success = window && window->IsDrawn() && + access_policy_->CanSetFocus(window) && host; + if (success) { Operation op(this, connection_manager_, OperationType::SET_FOCUS); - WindowTreeHostImpl* host = GetHost(); - if (host) - host->SetFocusedWindow(window); + host->SetFocusedWindow(window); } + client_->OnChangeCompleted(change_id, success); } -void WindowTreeImpl::SetCanFocus(uint32_t window_id, bool can_focus) { +void WindowTreeImpl::SetCanFocus(Id window_id, bool can_focus) { ServerWindow* window = GetWindow(WindowIdFromTransportId(window_id)); if (window && ShouldRouteToWindowManager(window)) window->set_can_focus(can_focus); } +void WindowTreeImpl::SetPredefinedCursor(uint32_t change_id, + Id window_id, + mus::mojom::Cursor cursor_id) { + ServerWindow* window = GetWindow(WindowIdFromTransportId(window_id)); + + // Only the owner of the window can change the bounds. + bool success = window && access_policy_->CanSetCursorProperties(window); + if (success) { + Operation op(this, connection_manager_, + OperationType::SET_WINDOW_PREDEFINED_CURSOR); + window->SetPredefinedCursor(cursor_id); + } + client_->OnChangeCompleted(change_id, success); +} + void WindowTreeImpl::WmResponse(uint32 change_id, bool response) { if (GetHost() && GetHost()->GetWindowTree() == this) connection_manager_->WindowManagerChangeCompleted(change_id, response);
diff --git a/components/mus/ws/window_tree_impl.h b/components/mus/ws/window_tree_impl.h index 0a92f4f..7b1ee906d 100644 --- a/components/mus/ws/window_tree_impl.h +++ b/components/mus/ws/window_tree_impl.h
@@ -95,10 +95,11 @@ const gfx::Rect& old_bounds, const gfx::Rect& new_bounds, bool originated_change); - void ProcessClientAreaChanged(const ServerWindow* window, - const gfx::Insets& old_client_area, - const gfx::Insets& new_client_area, - bool originated_change); + void ProcessClientAreaChanged( + const ServerWindow* window, + const gfx::Insets& new_client_area, + const std::vector<gfx::Rect>& new_additional_client_areas, + bool originated_change); void ProcessViewportMetricsChanged(const mojom::ViewportMetrics& old_metrics, const mojom::ViewportMetrics& new_metrics, bool originated_change); @@ -121,6 +122,9 @@ void ProcessWindowDeleted(const WindowId& window, bool originated_change); void ProcessWillChangeWindowVisibility(const ServerWindow* window, bool originated_change); + void ProcessCursorChanged(const ServerWindow* window, + int32_t cursor_id, + bool originated_change); void ProcessFocusChanged(const ServerWindow* old_focused_window, const ServerWindow* new_focused_window); void ProcessTransientWindowAdded(const ServerWindow* window, @@ -197,21 +201,17 @@ mojo::Map<mojo::String, mojo::Array<uint8_t>> transport_properties) override; void DeleteWindow(uint32_t change_id, Id transport_window_id) override; - void AddWindow(Id parent_id, - Id child_id, - const mojo::Callback<void(bool)>& callback) override; - void RemoveWindowFromParent( - Id window_id, - const mojo::Callback<void(bool)>& callback) override; + void AddWindow(uint32_t change_id, Id parent_id, Id child_id) override; + void RemoveWindowFromParent(uint32_t change_id, Id window_id) override; void AddTransientWindow(uint32_t change_id, Id window_id, Id transient_window_id) override; void RemoveTransientWindowFromParent(uint32_t change_id, Id transient_window_id) override; - void ReorderWindow(Id window_id, + void ReorderWindow(uint32_t change_Id, + Id window_id, Id relative_window_id, - mojom::OrderDirection direction, - const mojo::Callback<void(bool)>& callback) override; + mojom::OrderDirection direction) override; void GetWindowTree( Id window_id, const mojo::Callback<void(mojo::Array<mojom::WindowDataPtr>)>& callback) @@ -234,15 +234,21 @@ mojom::WindowTreeClientPtr client, uint32_t policy_bitmask, const EmbedCallback& callback) override; - void SetFocus(uint32_t window_id) override; - void SetCanFocus(uint32_t window_id, bool can_focus) override; - void SetWindowTextInputState(uint32_t window_id, + void SetFocus(uint32_t change_id, Id window_id) override; + void SetCanFocus(Id window_id, bool can_focus) override; + void SetPredefinedCursor(uint32_t change_id, + Id window_id, + mus::mojom::Cursor cursor_id) override; + void SetWindowTextInputState(Id window_id, mojo::TextInputStatePtr state) override; void SetImeVisibility(Id transport_window_id, bool visible, mojo::TextInputStatePtr state) override; void OnWindowInputEventAck(uint32_t event_id) override; - void SetClientArea(Id transport_window_id, mojo::InsetsPtr insets) override; + void SetClientArea( + Id transport_window_id, + mojo::InsetsPtr insets, + mojo::Array<mojo::RectPtr> transport_additional_client_areas) override; void WmResponse(uint32 change_id, bool response) override; // AccessPolicyDelegate:
diff --git a/components/mus/ws/window_tree_unittest.cc b/components/mus/ws/window_tree_unittest.cc index 3c9ab24..e8e545ae 100644 --- a/components/mus/ws/window_tree_unittest.cc +++ b/components/mus/ws/window_tree_unittest.cc
@@ -77,9 +77,10 @@ tracker_.OnWindowBoundsChanged(window, old_bounds.Pass(), new_bounds.Pass()); } - void OnClientAreaChanged(uint32_t window_id, - mojo::InsetsPtr old_client_area, - mojo::InsetsPtr new_client_area) override {} + void OnClientAreaChanged( + uint32_t window_id, + mojo::InsetsPtr new_client_area, + mojo::Array<mojo::RectPtr> new_additional_client_areas) override {} void OnTransientWindowAdded(uint32_t window_id, uint32_t transient_window_id) override {} void OnTransientWindowRemoved(uint32_t window_id, @@ -124,6 +125,10 @@ void OnWindowFocused(uint32_t focused_window_id) override { tracker_.OnWindowFocused(focused_window_id); } + void OnWindowPredefinedCursorChanged(uint32 window_id, + mojom::Cursor cursor_id) override { + tracker_.OnWindowPredefinedCursorChanged(window_id, cursor_id); + } void OnChangeCompleted(uint32_t change_id, bool success) override {} void WmSetBounds(uint32_t change_id, Id window_id, @@ -220,7 +225,8 @@ // Empty implementation of DisplayManager. class TestDisplayManager : public DisplayManager { public: - TestDisplayManager() {} + explicit TestDisplayManager(int32_t* cursor_id_storage) + : cursor_id_storage_(cursor_id_storage) {} ~TestDisplayManager() override {} // DisplayManager: @@ -237,6 +243,7 @@ const gfx::Rect& bounds) override {} void SetViewportSize(const gfx::Size& size) override {} void SetTitle(const base::string16& title) override {} + void SetCursorById(int32_t cursor) override { *cursor_id_storage_ = cursor; } const mojom::ViewportMetrics& GetViewportMetrics() override { return display_metrices_; } @@ -247,22 +254,27 @@ private: mojom::ViewportMetrics display_metrices_; + int32_t* cursor_id_storage_; + DISALLOW_COPY_AND_ASSIGN(TestDisplayManager); }; // Factory that dispenses TestDisplayManagers. class TestDisplayManagerFactory : public DisplayManagerFactory { public: - TestDisplayManagerFactory() {} + explicit TestDisplayManagerFactory(int32_t* cursor_id_storage) + : cursor_id_storage_(cursor_id_storage) {} ~TestDisplayManagerFactory() {} DisplayManager* CreateDisplayManager( mojo::ApplicationImpl* app_impl, const scoped_refptr<GpuState>& gpu_state, const scoped_refptr<mus::SurfacesState>& surfaces_state) override { - return new TestDisplayManager(); + return new TestDisplayManager(cursor_id_storage_); } private: + int32_t* cursor_id_storage_; + DISALLOW_COPY_AND_ASSIGN(TestDisplayManagerFactory); }; @@ -302,13 +314,32 @@ return event.Pass(); } +EventPtr CreateMouseDownEvent(int x, int y) { + EventPtr event = CreatePointerDownEvent(x, y); + event->flags = static_cast<mus::mojom::EventFlags>( + event->flags | mojom::EVENT_FLAGS_LEFT_MOUSE_BUTTON); + event->pointer_data->kind = mojom::POINTER_KIND_MOUSE; + return event.Pass(); +} + +EventPtr CreateMouseUpEvent(int x, int y) { + EventPtr event = CreatePointerUpEvent(x, y); + event->flags = static_cast<mus::mojom::EventFlags>( + event->flags | mojom::EVENT_FLAGS_LEFT_MOUSE_BUTTON); + event->pointer_data->kind = mojom::POINTER_KIND_MOUSE; + return event.Pass(); +} + } // namespace // ----------------------------------------------------------------------------- class WindowTreeTest : public testing::Test { public: - WindowTreeTest() : wm_client_(nullptr) {} + WindowTreeTest() + : wm_client_(nullptr), + cursor_id_(0), + display_manager_factory_(&cursor_id_) {} ~WindowTreeTest() override {} // WindowTreeImpl for the window manager. @@ -327,6 +358,7 @@ ConnectionManager* connection_manager() { return connection_manager_.get(); } TestWindowTreeClient* wm_client() { return wm_client_; } + int32_t cursor_id() { return cursor_id_; } TestWindowTreeHostConnection* host_connection() { return host_connection_; } @@ -345,6 +377,11 @@ AckPreviousEvent(); } + // Embeds a child window to the root window. Shared setup between several of + // the unit tests. + void SetupEventTargeting(TestWindowTreeClient** out_client, + ServerWindow** out_window); + protected: // testing::Test: void SetUp() override { @@ -367,6 +404,7 @@ private: // TestWindowTreeClient that is used for the WM connection. TestWindowTreeClient* wm_client_; + int32_t cursor_id_; TestDisplayManagerFactory display_manager_factory_; TestConnectionManagerDelegate delegate_; TestWindowTreeHostConnection* host_connection_; @@ -376,6 +414,52 @@ DISALLOW_COPY_AND_ASSIGN(WindowTreeTest); }; +void WindowTreeTest::SetupEventTargeting(TestWindowTreeClient** out_client, + ServerWindow** out_window) { + const WindowId embed_window_id(wm_connection()->id(), 1); + EXPECT_TRUE( + wm_connection()->NewWindow(embed_window_id, ServerWindow::Properties())); + EXPECT_TRUE(wm_connection()->SetWindowVisibility(embed_window_id, true)); + EXPECT_TRUE( + wm_connection()->AddWindow(*(wm_connection()->root()), embed_window_id)); + host_connection()->window_tree_host()->root_window()->SetBounds( + gfx::Rect(0, 0, 100, 100)); + mojom::WindowTreeClientPtr client; + mojo::InterfaceRequest<mojom::WindowTreeClient> client_request = + GetProxy(&client); + wm_client()->Bind(client_request.Pass()); + ConnectionSpecificId connection_id = 0; + wm_connection()->Embed(embed_window_id, client.Pass(), + mojom::WindowTree::ACCESS_POLICY_DEFAULT, + &connection_id); + WindowTreeImpl* connection1 = + connection_manager()->GetConnectionWithRoot(embed_window_id); + ASSERT_TRUE(connection1 != nullptr); + ASSERT_NE(connection1, wm_connection()); + + connection_manager() + ->GetWindow(embed_window_id) + ->SetBounds(gfx::Rect(0, 0, 50, 50)); + + const WindowId child1(connection1->id(), 1); + EXPECT_TRUE(connection1->NewWindow(child1, ServerWindow::Properties())); + EXPECT_TRUE(connection1->AddWindow(embed_window_id, child1)); + connection1->GetHost()->AddActivationParent( + WindowIdToTransportId(embed_window_id)); + + ServerWindow* v1 = connection1->GetWindow(child1); + v1->SetVisible(true); + v1->SetBounds(gfx::Rect(20, 20, 20, 20)); + EnableHitTest(v1); + + TestWindowTreeClient* embed_connection = last_window_tree_client(); + embed_connection->tracker()->changes()->clear(); + wm_client()->tracker()->changes()->clear(); + + *out_client = embed_connection; + *out_window = v1; +} + // Verifies focus correctly changes on pointer events. TEST_F(WindowTreeTest, FocusOnPointer) { const WindowId embed_window_id(wm_connection()->id(), 1); @@ -464,46 +548,9 @@ } TEST_F(WindowTreeTest, BasicInputEventTarget) { - const WindowId embed_window_id(wm_connection()->id(), 1); - EXPECT_TRUE( - wm_connection()->NewWindow(embed_window_id, ServerWindow::Properties())); - EXPECT_TRUE(wm_connection()->SetWindowVisibility(embed_window_id, true)); - EXPECT_TRUE( - wm_connection()->AddWindow(*(wm_connection()->root()), embed_window_id)); - host_connection()->window_tree_host()->root_window()->SetBounds( - gfx::Rect(0, 0, 100, 100)); - mojom::WindowTreeClientPtr client; - mojo::InterfaceRequest<mojom::WindowTreeClient> client_request = - GetProxy(&client); - wm_client()->Bind(client_request.Pass()); - ConnectionSpecificId connection_id = 0; - wm_connection()->Embed(embed_window_id, - client.Pass(), - mojom::WindowTree::ACCESS_POLICY_DEFAULT, - &connection_id); - WindowTreeImpl* connection1 = - connection_manager()->GetConnectionWithRoot(embed_window_id); - ASSERT_TRUE(connection1 != nullptr); - ASSERT_NE(connection1, wm_connection()); - - connection_manager() - ->GetWindow(embed_window_id) - ->SetBounds(gfx::Rect(0, 0, 50, 50)); - - const WindowId child1(connection1->id(), 1); - EXPECT_TRUE(connection1->NewWindow(child1, ServerWindow::Properties())); - EXPECT_TRUE(connection1->AddWindow(embed_window_id, child1)); - connection1->GetHost()->AddActivationParent( - WindowIdToTransportId(embed_window_id)); - - ServerWindow* v1 = connection1->GetWindow(child1); - v1->SetVisible(true); - v1->SetBounds(gfx::Rect(20, 20, 20, 20)); - EnableHitTest(v1); - - TestWindowTreeClient* embed_connection = last_window_tree_client(); - embed_connection->tracker()->changes()->clear(); - wm_client()->tracker()->changes()->clear(); + TestWindowTreeClient* embed_connection = nullptr; + ServerWindow* out_window = nullptr; + EXPECT_NO_FATAL_FAILURE(SetupEventTargeting(&embed_connection, &out_window)); // Send an event to |v1|. |embed_connection| should get the event, not // |wm_client|, since |v1| lives inside an embedded window. @@ -518,6 +565,85 @@ ChangesToDescription1(*embed_connection->tracker()->changes())[1]); } +TEST_F(WindowTreeTest, CursorChangesWhenMouseOverWindowAndWindowSetsCursor) { + TestWindowTreeClient* embed_connection = nullptr; + ServerWindow* out_window = nullptr; + EXPECT_NO_FATAL_FAILURE(SetupEventTargeting(&embed_connection, &out_window)); + + // Like in BasicInputEventTarget, we send a pointer down event to be + // dispatched. This is only to place the mouse cursor over that window though. + DispatchEventAndAckImmediately(CreateMouseMoveEvent(21, 22)); + + out_window->SetPredefinedCursor(mojom::Cursor::CURSOR_IBEAM); + + // Because the cursor is over the window when SetCursor was called, we should + // have immediately changed the cursor. + EXPECT_EQ(mojom::Cursor::CURSOR_IBEAM, cursor_id()); +} + +TEST_F(WindowTreeTest, CursorChangesWhenEnteringWindowWithDifferentCursor) { + TestWindowTreeClient* embed_connection = nullptr; + ServerWindow* out_window = nullptr; + EXPECT_NO_FATAL_FAILURE(SetupEventTargeting(&embed_connection, &out_window)); + + // Let's create a pointer event outside the window and then move the pointer + // inside. + DispatchEventAndAckImmediately(CreateMouseMoveEvent(5, 5)); + out_window->SetPredefinedCursor(mojom::Cursor::CURSOR_IBEAM); + EXPECT_EQ(mojom::Cursor::CURSOR_NULL, cursor_id()); + + DispatchEventAndAckImmediately(CreateMouseMoveEvent(21, 22)); + EXPECT_EQ(mojom::Cursor::CURSOR_IBEAM, cursor_id()); +} + +TEST_F(WindowTreeTest, TouchesDontChangeCursor) { + TestWindowTreeClient* embed_connection = nullptr; + ServerWindow* out_window = nullptr; + EXPECT_NO_FATAL_FAILURE(SetupEventTargeting(&embed_connection, &out_window)); + + // Let's create a pointer event outside the window and then move the pointer + // inside. + DispatchEventAndAckImmediately(CreateMouseMoveEvent(5, 5)); + out_window->SetPredefinedCursor(mojom::Cursor::CURSOR_IBEAM); + EXPECT_EQ(mojom::Cursor::CURSOR_NULL, cursor_id()); + + // With a touch event, we shouldn't update the cursor. + DispatchEventAndAckImmediately(CreatePointerDownEvent(21, 22)); + EXPECT_EQ(mojom::Cursor::CURSOR_NULL, cursor_id()); +} + +TEST_F(WindowTreeTest, DragOutsideWindow) { + TestWindowTreeClient* embed_connection = nullptr; + ServerWindow* out_window = nullptr; + EXPECT_NO_FATAL_FAILURE(SetupEventTargeting(&embed_connection, &out_window)); + + // Start with the cursor outside the window. Setting the cursor shouldn't + // change the cursor. + DispatchEventAndAckImmediately(CreateMouseMoveEvent(5, 5)); + out_window->SetPredefinedCursor(mojom::Cursor::CURSOR_IBEAM); + EXPECT_EQ(mojom::Cursor::CURSOR_NULL, cursor_id()); + + // Move the pointer to the inside of the window + DispatchEventAndAckImmediately(CreateMouseMoveEvent(21, 22)); + EXPECT_EQ(mojom::Cursor::CURSOR_IBEAM, cursor_id()); + + // Start the drag. + DispatchEventAndAckImmediately(CreateMouseDownEvent(21, 22)); + EXPECT_EQ(mojom::Cursor::CURSOR_IBEAM, cursor_id()); + + // Move the cursor (mouse is still down) outside the window. + DispatchEventAndAckImmediately(CreateMouseMoveEvent(5, 5)); + EXPECT_EQ(mojom::Cursor::CURSOR_IBEAM, cursor_id()); + + // Release the cursor. We should now adapt the cursor of the window + // underneath the pointer. + DispatchEventAndAckImmediately(CreateMouseUpEvent(5, 5)); + EXPECT_EQ(mojom::Cursor::CURSOR_NULL, cursor_id()); +} + +// TODO(erg): Add tests for when programmatic changes to the window hierarchy +// would cause the window that supplies the cursor to change. + TEST_F(WindowTreeTest, EventAck) { const WindowId embed_window_id(wm_connection()->id(), 1); EXPECT_TRUE(
diff --git a/components/nacl/loader/nacl_main_platform_delegate_win.cc b/components/nacl/loader/nacl_main_platform_delegate_win.cc index e4d0ad5..c0caa5e2 100644 --- a/components/nacl/loader/nacl_main_platform_delegate_win.cc +++ b/components/nacl/loader/nacl_main_platform_delegate_win.cc
@@ -17,9 +17,6 @@ // Cause advapi32 to load before the sandbox is turned on. unsigned int dummy_rand; rand_s(&dummy_rand); - // Warm up language subsystems before the sandbox is turned on. - ::GetUserDefaultLangID(); - ::GetUserDefaultLCID(); // Turn the sandbox on. target_services->LowerToken();
diff --git a/components/nacl/renderer/plugin/plugin.cc b/components/nacl/renderer/plugin/plugin.cc index a790696..44ea7a4 100644 --- a/components/nacl/renderer/plugin/plugin.cc +++ b/components/nacl/renderer/plugin/plugin.cc
@@ -9,6 +9,7 @@ #include <string> +#include "base/logging.h" #include "components/nacl/renderer/plugin/nacl_subprocess.h" #include "components/nacl/renderer/plugin/plugin_error.h" #include "components/nacl/renderer/plugin/service_runtime.h" @@ -19,7 +20,6 @@ #include "native_client/src/include/nacl_scoped_ptr.h" #include "native_client/src/include/portability.h" #include "native_client/src/include/portability_io.h" -#include "native_client/src/shared/platform/nacl_check.h" #include "native_client/src/trusted/desc/nacl_desc_wrapper.h" #include "ppapi/c/pp_errors.h" #include "ppapi/cpp/module.h"
diff --git a/components/nacl/renderer/plugin/pnacl_coordinator.cc b/components/nacl/renderer/plugin/pnacl_coordinator.cc index 052f289..28caad5 100644 --- a/components/nacl/renderer/plugin/pnacl_coordinator.cc +++ b/components/nacl/renderer/plugin/pnacl_coordinator.cc
@@ -8,13 +8,13 @@ #include <sstream> #include <utility> +#include "base/logging.h" #include "components/nacl/renderer/plugin/plugin.h" #include "components/nacl/renderer/plugin/plugin_error.h" #include "components/nacl/renderer/plugin/pnacl_translate_thread.h" #include "components/nacl/renderer/plugin/service_runtime.h" #include "components/nacl/renderer/plugin/temporary_file.h" #include "native_client/src/include/portability_io.h" -#include "native_client/src/shared/platform/nacl_check.h" #include "native_client/src/trusted/service_runtime/include/sys/stat.h" #include "ppapi/c/pp_bool.h" #include "ppapi/c/pp_errors.h"
diff --git a/components/nacl/renderer/plugin/pnacl_coordinator.h b/components/nacl/renderer/plugin/pnacl_coordinator.h index 8c9f4a5..05dbaed 100644 --- a/components/nacl/renderer/plugin/pnacl_coordinator.h +++ b/components/nacl/renderer/plugin/pnacl_coordinator.h
@@ -11,7 +11,6 @@ #include "components/nacl/renderer/plugin/plugin_error.h" #include "components/nacl/renderer/plugin/pnacl_resources.h" #include "native_client/src/include/nacl_macros.h" -#include "native_client/src/shared/platform/nacl_sync_raii.h" #include "native_client/src/shared/srpc/nacl_srpc.h" #include "native_client/src/trusted/desc/nacl_desc_wrapper.h" #include "ppapi/cpp/completion_callback.h"
diff --git a/components/nacl/renderer/plugin/pnacl_resources.cc b/components/nacl/renderer/plugin/pnacl_resources.cc index 9e65d697..ac5a292 100644 --- a/components/nacl/renderer/plugin/pnacl_resources.cc +++ b/components/nacl/renderer/plugin/pnacl_resources.cc
@@ -6,10 +6,10 @@ #include <vector> +#include "base/logging.h" #include "components/nacl/renderer/plugin/plugin.h" #include "components/nacl/renderer/plugin/utility.h" #include "native_client/src/include/portability_io.h" -#include "native_client/src/shared/platform/nacl_check.h" #include "native_client/src/trusted/desc/nacl_desc_wrapper.h" #include "ppapi/c/pp_errors.h" @@ -42,21 +42,14 @@ const std::string& PnaclResources::GetUrl(ResourceType type) const { size_t index = static_cast<size_t>(type); - if (index < NUM_TYPES) { - return resources_[index].tool_name; - } - // TODO(jvoung): Use NOTREACHED() from base/logging.h once - // we are able to use base/logging.h without conflicting - // with NaCl macros. - DCHECK(false && "Index out of bounds"); - // Return a dummy tool name. + DCHECK(index < NUM_TYPES); return resources_[index].tool_name; } PP_NaClFileInfo PnaclResources::TakeFileInfo(ResourceType type) { size_t index = static_cast<size_t>(type); if (index >= NUM_TYPES) { - DCHECK(false && "Index out of bounds"); + NOTREACHED(); return kInvalidNaClFileInfo; } PP_NaClFileInfo to_return = resources_[index].file_info;
diff --git a/components/nacl/renderer/plugin/pnacl_translate_thread.cc b/components/nacl/renderer/plugin/pnacl_translate_thread.cc index 8b26a11..c7d64c7 100644 --- a/components/nacl/renderer/plugin/pnacl_translate_thread.cc +++ b/components/nacl/renderer/plugin/pnacl_translate_thread.cc
@@ -13,6 +13,7 @@ #include "components/nacl/renderer/plugin/temporary_file.h" #include "components/nacl/renderer/plugin/utility.h" #include "native_client/src/shared/platform/nacl_check.h" +#include "native_client/src/shared/platform/nacl_sync_raii.h" #include "native_client/src/trusted/desc/nacl_desc_wrapper.h" #include "ppapi/cpp/var.h"
diff --git a/components/nacl/renderer/plugin/sel_ldr_launcher_chrome.cc b/components/nacl/renderer/plugin/sel_ldr_launcher_chrome.cc index ece90f0..305c386 100644 --- a/components/nacl/renderer/plugin/sel_ldr_launcher_chrome.cc +++ b/components/nacl/renderer/plugin/sel_ldr_launcher_chrome.cc
@@ -3,8 +3,9 @@ // found in the LICENSE file. #include "components/nacl/renderer/plugin/sel_ldr_launcher_chrome.h" + +#include "base/logging.h" #include "native_client/src/include/nacl_macros.h" -#include "native_client/src/shared/platform/nacl_check.h" namespace plugin {
diff --git a/components/nacl/renderer/plugin/service_runtime.cc b/components/nacl/renderer/plugin/service_runtime.cc index fd01c3b..016c6bf 100644 --- a/components/nacl/renderer/plugin/service_runtime.cc +++ b/components/nacl/renderer/plugin/service_runtime.cc
@@ -23,7 +23,6 @@ #include "native_client/src/include/portability_io.h" #include "native_client/src/include/portability_string.h" #include "native_client/src/public/imc_types.h" -#include "native_client/src/shared/platform/nacl_check.h" #include "native_client/src/shared/platform/nacl_log.h" #include "native_client/src/trusted/nonnacl_util/sel_ldr_launcher.h" #include "native_client/src/trusted/service_runtime/nacl_error_code.h"
diff --git a/components/nacl/renderer/plugin/temporary_file.cc b/components/nacl/renderer/plugin/temporary_file.cc index 95e8a52..9fc1a68 100644 --- a/components/nacl/renderer/plugin/temporary_file.cc +++ b/components/nacl/renderer/plugin/temporary_file.cc
@@ -4,10 +4,10 @@ #include "components/nacl/renderer/plugin/temporary_file.h" +#include "base/logging.h" #include "components/nacl/renderer/plugin/plugin.h" #include "components/nacl/renderer/plugin/utility.h" #include "native_client/src/include/portability_io.h" -#include "native_client/src/shared/platform/nacl_check.h" #include "native_client/src/trusted/service_runtime/include/sys/stat.h" #include "ppapi/c/private/pp_file_handle.h" #include "ppapi/cpp/core.h"
diff --git a/components/nacl/renderer/plugin/utility.cc b/components/nacl/renderer/plugin/utility.cc index c994f73..6a31850 100644 --- a/components/nacl/renderer/plugin/utility.cc +++ b/components/nacl/renderer/plugin/utility.cc
@@ -11,7 +11,6 @@ #include "components/nacl/renderer/plugin/utility.h" #include "native_client/src/include/portability_io.h" #include "native_client/src/include/portability_process.h" -#include "native_client/src/shared/platform/nacl_check.h" #include "ppapi/cpp/module.h" namespace plugin {
diff --git a/components/plugins/renderer/webview_plugin.h b/components/plugins/renderer/webview_plugin.h index 75d079c..74b4b1b 100644 --- a/components/plugins/renderer/webview_plugin.h +++ b/components/plugins/renderer/webview_plugin.h
@@ -110,13 +110,6 @@ void didFinishLoading() override; void didFailLoading(const blink::WebURLError& error) override; - // Called in response to WebPluginContainer::loadFrameRequest - void didFinishLoadingFrameRequest(const blink::WebURL& url, - void* notifyData) override {} - void didFailLoadingFrameRequest(const blink::WebURL& url, - void* notify_data, - const blink::WebURLError& error) override {} - // WebViewClient methods: bool acceptsLoadDrops() override;
diff --git a/components/safe_browsing_db/util.cc b/components/safe_browsing_db/util.cc index 9507075a..c34c161 100644 --- a/components/safe_browsing_db/util.cc +++ b/components/safe_browsing_db/util.cc
@@ -143,32 +143,35 @@ std::string Unescape(const std::string& url) { std::string unescaped_str(url); - std::string old_unescaped_str; const int kMaxLoopIterations = 1024; + size_t old_size = 0; int loop_var = 0; do { - old_unescaped_str = unescaped_str; + old_size = unescaped_str.size(); unescaped_str = net::UnescapeURLComponent( - old_unescaped_str, net::UnescapeRule::SPOOFING_AND_CONTROL_CHARS | - net::UnescapeRule::SPACES | - net::UnescapeRule::URL_SPECIAL_CHARS); - } while (unescaped_str != old_unescaped_str && ++loop_var <= - kMaxLoopIterations); + unescaped_str, net::UnescapeRule::SPOOFING_AND_CONTROL_CHARS | + net::UnescapeRule::SPACES | + net::UnescapeRule::URL_SPECIAL_CHARS); + } while (old_size != unescaped_str.size() && + ++loop_var <= kMaxLoopIterations); return unescaped_str; } std::string Escape(const std::string& url) { std::string escaped_str; + // The escaped string is larger so allocate double the length to reduce the + // chance of the string being grown. + escaped_str.reserve(url.length() * 2); const char* kHexString = "0123456789ABCDEF"; for (size_t i = 0; i < url.length(); i++) { unsigned char c = static_cast<unsigned char>(url[i]); if (c <= ' ' || c > '~' || c == '#' || c == '%') { - escaped_str.push_back('%'); - escaped_str.push_back(kHexString[c >> 4]); - escaped_str.push_back(kHexString[c & 0xf]); + escaped_str += '%'; + escaped_str += kHexString[c >> 4]; + escaped_str += kHexString[c & 0xf]; } else { - escaped_str.push_back(c); + escaped_str += c; } } @@ -230,22 +233,21 @@ &parsed); // 3. In hostname, remove all leading and trailing dots. - const std::string host = - (parsed.host.len > 0) - ? url_unescaped_str.substr(parsed.host.begin, parsed.host.len) - : std::string(); - std::string host_without_end_dots; - base::TrimString(host, ".", &host_without_end_dots); + base::StringPiece host; + if (parsed.host.len > 0) + host.set(url_unescaped_str.data() + parsed.host.begin, parsed.host.len); + + base::StringPiece host_without_end_dots = + base::TrimString(host, ".", base::TrimPositions::TRIM_ALL); // 4. In hostname, replace consecutive dots with a single dot. std::string host_without_consecutive_dots(RemoveConsecutiveChars( host_without_end_dots, '.')); // 5. In path, replace runs of consecutive slashes with a single slash. - std::string path = - (parsed.path.len > 0) - ? url_unescaped_str.substr(parsed.path.begin, parsed.path.len) - : std::string(); + base::StringPiece path; + if (parsed.path.len > 0) + path.set(url_unescaped_str.data() + parsed.path.begin, parsed.path.len); std::string path_without_consecutive_slash(RemoveConsecutiveChars(path, '/')); url::Replacements<char> hp_replacements;
diff --git a/components/scheduler/BUILD.gn b/components/scheduler/BUILD.gn index a22b377..83d83e59 100644 --- a/components/scheduler/BUILD.gn +++ b/components/scheduler/BUILD.gn
@@ -43,12 +43,12 @@ "base/task_queue_manager_delegate_for_test.h", "base/task_queue_manager_unittest.cc", "base/task_queue_selector_unittest.cc", - "base/task_queue_sets_unittest.cc", "base/test_always_fail_time_source.cc", "base/test_always_fail_time_source.h", "base/test_time_source.cc", "base/test_time_source.h", "base/time_domain_unittest.cc", + "base/work_queue_sets_unittest.cc", "child/idle_helper_unittest.cc", "child/scheduler_helper_unittest.cc", "child/scheduler_tqm_delegate_for_test.cc",
diff --git a/components/scheduler/base/lazy_now.h b/components/scheduler/base/lazy_now.h index 34c659b..959a245 100644 --- a/components/scheduler/base/lazy_now.h +++ b/components/scheduler/base/lazy_now.h
@@ -6,6 +6,7 @@ #define COMPONENTS_SCHEDULER_BASE_LAZY_NOW_H_ #include "base/time/time.h" +#include "components/scheduler/scheduler_export.h" namespace base { class TickClock; @@ -15,7 +16,7 @@ // Now() is somewhat expensive so it makes sense not to call Now() unless we // really need to. -class LazyNow { +class SCHEDULER_EXPORT LazyNow { public: explicit LazyNow(base::TimeTicks now) : tick_clock_(nullptr), now_(now) { DCHECK(!now.is_null());
diff --git a/components/scheduler/base/real_time_domain.cc b/components/scheduler/base/real_time_domain.cc index d894eca..5f0b3e1 100644 --- a/components/scheduler/base/real_time_domain.cc +++ b/components/scheduler/base/real_time_domain.cc
@@ -6,29 +6,28 @@ #include "base/bind.h" #include "components/scheduler/base/task_queue_impl.h" +#include "components/scheduler/base/task_queue_manager.h" #include "components/scheduler/base/task_queue_manager_delegate.h" namespace scheduler { -RealTimeDomain::RealTimeDomain() : TimeDomain(nullptr), weak_factory_(this) {} +RealTimeDomain::RealTimeDomain() + : TimeDomain(nullptr), task_queue_manager_(nullptr) {} RealTimeDomain::~RealTimeDomain() {} void RealTimeDomain::OnRegisterWithTaskQueueManager( - TaskQueueManagerDelegate* task_queue_manager_delegate, - base::Closure do_work_closure) { - task_queue_manager_delegate_ = task_queue_manager_delegate; - do_work_closure_ = do_work_closure; - DCHECK(task_queue_manager_delegate_); + TaskQueueManager* task_queue_manager) { + task_queue_manager_ = task_queue_manager; + DCHECK(task_queue_manager_); } LazyNow RealTimeDomain::CreateLazyNow() { - DCHECK(task_queue_manager_delegate_); - return LazyNow(task_queue_manager_delegate_); + return task_queue_manager_->CreateLazyNow(); } void RealTimeDomain::RequestWakeup(LazyNow* lazy_now, base::TimeDelta delay) { - PostWrappedDoWork(lazy_now->Now(), lazy_now->Now() + delay); + task_queue_manager_->MaybeScheduleDelayedWork(FROM_HERE, lazy_now, delay); } bool RealTimeDomain::MaybeAdvanceTime() { @@ -36,33 +35,15 @@ if (!NextScheduledRunTime(&next_run_time)) return false; - DCHECK(task_queue_manager_delegate_); - base::TimeTicks now = task_queue_manager_delegate_->NowTicks(); - if (now >= next_run_time) + LazyNow lazy_now = task_queue_manager_->CreateLazyNow(); + if (lazy_now.Now() >= next_run_time) return true; - PostWrappedDoWork(now, next_run_time); + task_queue_manager_->MaybeScheduleDelayedWork(FROM_HERE, &lazy_now, + next_run_time - lazy_now.Now()); return false; } -void RealTimeDomain::PostWrappedDoWork(base::TimeTicks now, - base::TimeTicks run_time) { - DCHECK_GE(run_time, now); - DCHECK(task_queue_manager_delegate_); - if (pending_wakeups_.insert(run_time).second) { - task_queue_manager_delegate_->PostDelayedTask( - FROM_HERE, - base::Bind(&RealTimeDomain::WrappedDoWorkTask, - weak_factory_.GetWeakPtr(), run_time), - run_time - now); - } -} - -void RealTimeDomain::WrappedDoWorkTask(base::TimeTicks run_time) { - pending_wakeups_.erase(run_time); - do_work_closure_.Run(); -} - void RealTimeDomain::AsValueIntoInternal( base::trace_event::TracedValue* state) const {}
diff --git a/components/scheduler/base/real_time_domain.h b/components/scheduler/base/real_time_domain.h index 82525637..ab20d80 100644 --- a/components/scheduler/base/real_time_domain.h +++ b/components/scheduler/base/real_time_domain.h
@@ -12,7 +12,6 @@ #include "components/scheduler/scheduler_export.h" namespace scheduler { -class TaskQueueManagerDelegate; class SCHEDULER_EXPORT RealTimeDomain : public TimeDomain { public: @@ -26,20 +25,13 @@ protected: void OnRegisterWithTaskQueueManager( - TaskQueueManagerDelegate* task_queue_manager_delegate, - base::Closure do_work_closure) override; + TaskQueueManager* task_queue_manager) override; void RequestWakeup(LazyNow* lazy_now, base::TimeDelta delay) override; void AsValueIntoInternal( base::trace_event::TracedValue* state) const override; private: - void PostWrappedDoWork(base::TimeTicks now, base::TimeTicks run_time); - void WrappedDoWorkTask(base::TimeTicks run_time); - - TaskQueueManagerDelegate* task_queue_manager_delegate_; // NOT OWNED - std::set<base::TimeTicks> pending_wakeups_; - base::Closure do_work_closure_; - base::WeakPtrFactory<RealTimeDomain> weak_factory_; + TaskQueueManager* task_queue_manager_; // NOT OWNED DISALLOW_COPY_AND_ASSIGN(RealTimeDomain); };
diff --git a/components/scheduler/base/task_queue.cc b/components/scheduler/base/task_queue.cc index 24aadb7..b5f7827 100644 --- a/components/scheduler/base/task_queue.cc +++ b/components/scheduler/base/task_queue.cc
@@ -3,12 +3,3 @@ // found in the LICENSE file. #include "components/scheduler/base/task_queue.h" - -namespace scheduler { - -bool TaskQueue::HasPendingImmediateTask() const { - QueueState state = GetQueueState(); - return state == QueueState::NEEDS_PUMPING || state == QueueState::HAS_WORK; -} - -} // namespace scheduler
diff --git a/components/scheduler/base/task_queue.h b/components/scheduler/base/task_queue.h index fbbbc25..a9964d9 100644 --- a/components/scheduler/base/task_queue.h +++ b/components/scheduler/base/task_queue.h
@@ -74,22 +74,6 @@ FIRST_WAKEUP_POLICY = CAN_WAKE_OTHER_QUEUES, }; - enum class QueueState { - // A queue in the EMPTY state is empty and has no tasks in either the - // work or incoming task queue. - EMPTY, - // A queue in the NEEDS_PUMPING state has no tasks in the work task queue, - // but has tasks in the incoming task queue which can be pumped to make them - // runnable. - NEEDS_PUMPING, - // A queue in the HAS_WORK state has tasks in the work task queue which - // are runnable. - HAS_WORK, - // The work and incomming queues are empty but there is delayed work - // scheduled. - NO_IMMEDIATE_WORK, - }; - // Options for constructing a TaskQueue. Once set the |name|, // |should_monitor_quiescence| and |wakeup_policy| are immutable. The // |pump_policy| can be mutated with |SetPumpPolicy()|. @@ -141,16 +125,16 @@ // thread this TaskQueue was created by. virtual bool IsQueueEnabled() const = 0; - // Returns true if there no tasks in either the work or incoming task queue. - // This method ignores delayed tasks that are scheduled to run in the future. - // Note that this function involves taking a lock, so calling it has some - // overhead. NOTE this must be called on the thread this TaskQueue was created - // by. - virtual bool HasPendingImmediateTask() const; + // Returns true if the queue is completely empty. + virtual bool IsEmpty() const = 0; - // Returns the QueueState. Note that this function involves taking a lock, so - // calling it has some overhead. - virtual QueueState GetQueueState() const = 0; + // Returns true if the queue has work that's ready to execute now, or if it + // would have if the queue was pumped. NOTE this must be called on the thread + // this TaskQueue was created by. + virtual bool HasPendingImmediateWork() const = 0; + + // Returns true if tasks can't run now but could if the queue was pumped. + virtual bool NeedsPumping() const = 0; // Can be called on any thread. virtual const char* GetName() const = 0; @@ -170,7 +154,12 @@ // This function only needs to be called if automatic pumping is disabled. // By default automatic pumping is enabled for all queues. NOTE this must be // called on the thread this TaskQueue was created by. - virtual void PumpQueue() = 0; + // + // The |may_post_dowork| parameter controls whether or not PumpQueue calls + // TaskQueueManager::MaybeScheduleImmediateWork. + // TODO(alexclarke): Add a base::RunLoop observer so we can get rid of + // |may_post_dowork|. + virtual void PumpQueue(bool may_post_dowork) = 0; // These functions can only be called on the same thread that the task queue // manager executes its tasks on.
diff --git a/components/scheduler/base/task_queue_impl.cc b/components/scheduler/base/task_queue_impl.cc index f58fabd..1d2b249 100644 --- a/components/scheduler/base/task_queue_impl.cc +++ b/components/scheduler/base/task_queue_impl.cc
@@ -7,6 +7,7 @@ #include "components/scheduler/base/task_queue_manager.h" #include "components/scheduler/base/task_queue_manager_delegate.h" #include "components/scheduler/base/time_domain.h" +#include "components/scheduler/base/work_queue.h" namespace scheduler { namespace internal { @@ -24,7 +25,7 @@ disabled_by_default_tracing_category), disabled_by_default_verbose_tracing_category_( disabled_by_default_verbose_tracing_category), - main_thread_only_(task_queue_manager), + main_thread_only_(task_queue_manager, this), wakeup_policy_(spec.wakeup_policy), should_monitor_quiescence_(spec.should_monitor_quiescence), should_notify_observers_(spec.should_notify_observers) { @@ -52,6 +53,7 @@ TaskQueueImpl::Task::Task(const tracked_objects::Location& posted_from, const base::Closure& task, + base::TimeTicks desired_run_time, int sequence_number, bool nestable) : PendingTask(posted_from, task, base::TimeTicks(), nestable), @@ -59,6 +61,22 @@ enqueue_order_set_(false), #endif enqueue_order_(0) { + delayed_run_time = desired_run_time; + sequence_num = sequence_number; +} + +TaskQueueImpl::Task::Task(const tracked_objects::Location& posted_from, + const base::Closure& task, + base::TimeTicks desired_run_time, + int sequence_number, + bool nestable, + int enqueue_order) + : PendingTask(posted_from, task, base::TimeTicks(), nestable), +#ifndef NDEBUG + enqueue_order_set_(true), +#endif + enqueue_order_(enqueue_order) { + delayed_run_time = desired_run_time; sequence_num = sequence_number; } @@ -72,9 +90,17 @@ TaskQueueImpl::AnyThread::~AnyThread() {} TaskQueueImpl::MainThreadOnly::MainThreadOnly( - TaskQueueManager* task_queue_manager) + TaskQueueManager* task_queue_manager, + TaskQueueImpl* task_queue) : task_queue_manager(task_queue_manager), - set_index(0) {} + delayed_work_queue( + new WorkQueue(task_queue_manager->selector_.delayed_task_queue_sets(), + task_queue, + "delayed")), + immediate_work_queue(new WorkQueue( + task_queue_manager->selector_.immediate_task_queue_sets(), + task_queue, + "immediate")) {} TaskQueueImpl::MainThreadOnly::~MainThreadOnly() {} @@ -89,9 +115,10 @@ any_thread().task_queue_manager = nullptr; main_thread_only().task_queue_manager = nullptr; - any_thread().delayed_task_queue = std::priority_queue<Task>(); - any_thread().incoming_queue = std::queue<Task>(); - main_thread_only().work_queue = std::queue<Task>(); + any_thread().delayed_incoming_queue = std::priority_queue<Task>(); + any_thread().immediate_incoming_queue = std::queue<Task>(); + main_thread_only().immediate_work_queue->Clear(); + main_thread_only().delayed_work_queue->Clear(); } bool TaskQueueImpl::RunsTasksOnCurrentThread() const { @@ -135,40 +162,61 @@ base::TimeTicks desired_run_time, TaskType task_type) { DCHECK(any_thread().task_queue_manager); - Task pending_task(from_here, task, - any_thread().task_queue_manager->GetNextSequenceNumber(), - task_type != TaskType::NON_NESTABLE); - any_thread().task_queue_manager->DidQueueTask(pending_task); - + int sequence_number = + any_thread().task_queue_manager->GetNextSequenceNumber(); if (!desired_run_time.is_null()) { - pending_task.delayed_run_time = std::max(lazy_now->Now(), desired_run_time); - // TODO(alexclarke): consider emplace() when C++11 library features allowed. - any_thread().delayed_task_queue.push(pending_task); - TraceQueueSize(true); - // Schedule a later call to MoveReadyDelayedTasksToIncomingQueue. - if (base::PlatformThread::CurrentId() == thread_id_) { - any_thread().time_domain->ScheduleDelayedWork(this, desired_run_time, - lazy_now); - } else { - // NOTE posting a delayed task from a different thread is not expected to - // be common. This pathway is less optimal than perhaps it could be - // because it causes two main thread tasks to be run. Should this - // assumption prove to be false in future, we may need to revisit this. - Task thread_hop_task( - FROM_HERE, base::Bind(&TaskQueueImpl::ScheduleDelayedWorkTask, this, - any_thread().time_domain, desired_run_time), - any_thread().task_queue_manager->GetNextSequenceNumber(), true); - thread_hop_task.set_enqueue_order(thread_hop_task.sequence_num); - any_thread().task_queue_manager->DidQueueTask(thread_hop_task); - EnqueueTaskLocked(thread_hop_task); - } - return true; + PushOntoDelayedIncomingQueueLocked( + Task(from_here, task, std::max(lazy_now->Now(), desired_run_time), + sequence_number, task_type != TaskType::NON_NESTABLE), + lazy_now); + } else { + PushOntoImmediateIncomingQueueLocked( + Task(from_here, task, base::TimeTicks(), sequence_number, + task_type != TaskType::NON_NESTABLE, sequence_number)); } - pending_task.set_enqueue_order(pending_task.sequence_num); - EnqueueTaskLocked(pending_task); return true; } +void TaskQueueImpl::PushOntoDelayedIncomingQueueLocked( + const Task&& pending_task, + LazyNow* lazy_now) { + any_thread().task_queue_manager->DidQueueTask(pending_task); + any_thread().delayed_incoming_queue.push(pending_task); + + // Schedule a later call to MoveReadyDelayedTasksToDelayedWorkQueue. + if (base::PlatformThread::CurrentId() == thread_id_) { + any_thread().time_domain->ScheduleDelayedWork( + this, pending_task.delayed_run_time, lazy_now); + TraceQueueSize(true); + } else { + // NOTE posting a delayed task from a different thread is not expected to + // be common. This pathway is less optimal than perhaps it could be + // because it causes two main thread tasks to be run. Should this + // assumption prove to be false in future, we may need to revisit this. + int thread_hop_task_sequence_number = + any_thread().task_queue_manager->GetNextSequenceNumber(); + PushOntoImmediateIncomingQueueLocked(Task( + FROM_HERE, + base::Bind(&TaskQueueImpl::ScheduleDelayedWorkTask, this, + any_thread().time_domain, pending_task.delayed_run_time), + base::TimeTicks(), thread_hop_task_sequence_number, false, + thread_hop_task_sequence_number)); + } +} + +void TaskQueueImpl::PushOntoImmediateIncomingQueueLocked( + const Task&& pending_task) { + if (any_thread().immediate_incoming_queue.empty()) + any_thread().time_domain->RegisterAsUpdatableTaskQueue(this); + if (any_thread().pump_policy == PumpPolicy::AUTO && + any_thread().immediate_incoming_queue.empty()) { + any_thread().task_queue_manager->MaybeScheduleImmediateWork(FROM_HERE); + } + any_thread().task_queue_manager->DidQueueTask(pending_task); + any_thread().immediate_incoming_queue.push(pending_task); + TraceQueueSize(true); +} + void TaskQueueImpl::ScheduleDelayedWorkTask(TimeDomain* time_domain, base::TimeTicks desired_run_time) { DCHECK(main_thread_checker_.CalledOnValidThread()); @@ -176,27 +224,6 @@ time_domain->ScheduleDelayedWork(this, desired_run_time, &lazy_now); } -void TaskQueueImpl::MoveReadyDelayedTasksToIncomingQueue(LazyNow* lazy_now) { - base::AutoLock lock(any_thread_lock_); - if (!any_thread().task_queue_manager) - return; - - MoveReadyDelayedTasksToIncomingQueueLocked(lazy_now); -} - -void TaskQueueImpl::MoveReadyDelayedTasksToIncomingQueueLocked( - LazyNow* lazy_now) { - // Enqueue all delayed tasks that should be running now. - while (!any_thread().delayed_task_queue.empty() && - any_thread().delayed_task_queue.top().delayed_run_time <= - lazy_now->Now()) { - // TODO(alexclarke): consider std::move() when allowed. - EnqueueDelayedTaskLocked(any_thread().delayed_task_queue.top()); - any_thread().delayed_task_queue.pop(); - } - TraceQueueSize(true); -} - bool TaskQueueImpl::IsQueueEnabled() const { if (!main_thread_only().task_queue_manager) return false; @@ -204,21 +231,41 @@ return main_thread_only().task_queue_manager->selector_.IsQueueEnabled(this); } -TaskQueue::QueueState TaskQueueImpl::GetQueueState() const { - if (!main_thread_only().work_queue.empty()) - return QueueState::HAS_WORK; - - { - base::AutoLock lock(any_thread_lock_); - if (any_thread().incoming_queue.empty()) { - if (any_thread().delayed_task_queue.empty()) - return QueueState::EMPTY; - else - return QueueState::NO_IMMEDIATE_WORK; - } else { - return QueueState::NEEDS_PUMPING; - } +bool TaskQueueImpl::IsEmpty() const { + if (!main_thread_only().delayed_work_queue->Empty() || + !main_thread_only().immediate_work_queue->Empty()) { + return false; } + + base::AutoLock lock(any_thread_lock_); + return any_thread().immediate_incoming_queue.empty() && + any_thread().delayed_incoming_queue.empty(); +} + +bool TaskQueueImpl::HasPendingImmediateWork() const { + if (!main_thread_only().delayed_work_queue->Empty() || + !main_thread_only().immediate_work_queue->Empty()) { + return true; + } + + return NeedsPumping(); +} + +bool TaskQueueImpl::NeedsPumping() const { + if (!main_thread_only().immediate_work_queue->Empty()) + return false; + + base::AutoLock lock(any_thread_lock_); + if (!any_thread().immediate_incoming_queue.empty()) + return true; + + // If there's no immediate Incoming work then we only need pumping if there + // is a delayed task that should be running now. + if (any_thread().delayed_incoming_queue.empty()) + return false; + + return any_thread().delayed_incoming_queue.top().delayed_run_time <= + any_thread().time_domain->CreateLazyNow().Now(); } bool TaskQueueImpl::TaskIsOlderThanQueuedTasks(const Task* task) { @@ -228,13 +275,20 @@ if (!task) return true; - // Return false if there are no task in the incoming queue. - if (any_thread().incoming_queue.empty()) + // Return false if task is newer than the oldest immediate task. + if (!any_thread().immediate_incoming_queue.empty() && + task->enqueue_order() > + any_thread().immediate_incoming_queue.front().enqueue_order()) { return false; + } - const TaskQueueImpl::Task& oldest_queued_task = - any_thread().incoming_queue.front(); - return task->enqueue_order() < oldest_queued_task.enqueue_order(); + int enqueue_order; + if (!main_thread_only().delayed_work_queue->GetFrontTaskEnqueueOrder( + &enqueue_order)) { + return true; + } + + return task->enqueue_order() < enqueue_order; } bool TaskQueueImpl::ShouldAutoPumpQueueLocked(bool should_trigger_wakeup, @@ -244,41 +298,50 @@ if (any_thread().pump_policy == PumpPolicy::AFTER_WAKEUP && (!should_trigger_wakeup || TaskIsOlderThanQueuedTasks(previous_task))) return false; - if (any_thread().incoming_queue.empty()) - return false; return true; } -void TaskQueueImpl::UpdateWorkQueue(LazyNow* lazy_now, - bool should_trigger_wakeup, - const Task* previous_task) { - DCHECK(main_thread_only().work_queue.empty()); - base::AutoLock lock(any_thread_lock_); - if (!ShouldAutoPumpQueueLocked(should_trigger_wakeup, previous_task)) - return; - MoveReadyDelayedTasksToIncomingQueueLocked(lazy_now); - std::swap(main_thread_only().work_queue, any_thread().incoming_queue); - // |any_thread().incoming_queue| is now empty so TimeDomain::UpdateQueues - // no longer needs to consider this queue for reloading. - any_thread().time_domain->UnregisterAsUpdatableTaskQueue(this); - if (!main_thread_only().work_queue.empty()) { - DCHECK(any_thread().task_queue_manager); - any_thread().task_queue_manager->selector_.GetTaskQueueSets()->OnPushQueue( - this); - TraceQueueSize(true); +void TaskQueueImpl::MoveReadyDelayedTasksToDelayedWorkQueueLocked( + LazyNow* lazy_now) { + // Enqueue all delayed tasks that should be running now. + while (!any_thread().delayed_incoming_queue.empty() && + any_thread().delayed_incoming_queue.top().delayed_run_time <= + lazy_now->Now()) { + main_thread_only().delayed_work_queue->PushAndSetEnqueueOrder( + std::move(any_thread().delayed_incoming_queue.top()), + any_thread().task_queue_manager->GetNextSequenceNumber()); + any_thread().delayed_incoming_queue.pop(); } } -TaskQueueImpl::Task TaskQueueImpl::TakeTaskFromWorkQueue() { - // TODO(alexclarke): consider std::move() when allowed. - Task pending_task = main_thread_only().work_queue.front(); - main_thread_only().work_queue.pop(); - DCHECK(main_thread_only().task_queue_manager); - main_thread_only() - .task_queue_manager->selector_.GetTaskQueueSets() - ->OnPopQueue(this); - TraceQueueSize(false); - return pending_task; +void TaskQueueImpl::UpdateDelayedWorkQueue(LazyNow* lazy_now, + bool should_trigger_wakeup, + const Task* previous_task) { + base::AutoLock lock(any_thread_lock_); + if (!any_thread().task_queue_manager) + return; + if (!ShouldAutoPumpQueueLocked(should_trigger_wakeup, previous_task)) + return; + MoveReadyDelayedTasksToDelayedWorkQueueLocked(lazy_now); + TraceQueueSize(true); +} + +void TaskQueueImpl::UpdateImmediateWorkQueue(bool should_trigger_wakeup, + const Task* previous_task) { + DCHECK(main_thread_only().immediate_work_queue->Empty()); + base::AutoLock lock(any_thread_lock_); + if (!any_thread().task_queue_manager) + return; + if (!ShouldAutoPumpQueueLocked(should_trigger_wakeup, previous_task)) + return; + + main_thread_only().immediate_work_queue->Swap( + any_thread().immediate_incoming_queue); + + // |any_thread().immediate_incoming_queue| is now empty so + // TimeDomain::UpdateQueues no longer needs to consider this queue for + // reloading. + any_thread().time_domain->UnregisterAsUpdatableTaskQueue(this); } void TaskQueueImpl::TraceQueueSize(bool is_locked) const { @@ -292,101 +355,59 @@ else any_thread_lock_.AssertAcquired(); TRACE_COUNTER1(disabled_by_default_tracing_category_, GetName(), - any_thread().incoming_queue.size() + - main_thread_only().work_queue.size() + - any_thread().delayed_task_queue.size()); + any_thread().immediate_incoming_queue.size() + + main_thread_only().immediate_work_queue->Size() + + main_thread_only().delayed_work_queue->Size() + + any_thread().delayed_incoming_queue.size()); if (!is_locked) any_thread_lock_.Release(); } -void TaskQueueImpl::EnqueueTaskLocked(const Task& pending_task) { - if (!any_thread().task_queue_manager) - return; - if (any_thread().incoming_queue.empty()) - any_thread().time_domain->RegisterAsUpdatableTaskQueue(this); - if (any_thread().pump_policy == PumpPolicy::AUTO && - any_thread().incoming_queue.empty()) { - any_thread().task_queue_manager->MaybePostDoWorkOnMainRunner(); - } - // TODO(alexclarke): consider std::move() when allowed. - any_thread().incoming_queue.push(pending_task); - TraceQueueSize(true); -} - -// TODO(alexclarke): Consider merging EnqueueTaskLocked & -// EnqueueDelayedTaskLocked. -void TaskQueueImpl::EnqueueDelayedTaskLocked(const Task& pending_task) { - if (!any_thread().task_queue_manager) - return; - if (any_thread().incoming_queue.empty()) - any_thread().time_domain->RegisterAsUpdatableTaskQueue(this); - // TODO(alexclarke): consider std::move() when allowed. - any_thread().incoming_queue.push(pending_task); - any_thread().incoming_queue.back().set_enqueue_order( - any_thread().task_queue_manager->GetNextSequenceNumber()); - TraceQueueSize(true); -} - void TaskQueueImpl::SetPumpPolicy(PumpPolicy pump_policy) { base::AutoLock lock(any_thread_lock_); if (pump_policy == PumpPolicy::AUTO && any_thread().pump_policy != PumpPolicy::AUTO) { - PumpQueueLocked(); + PumpQueueLocked(true); } any_thread().pump_policy = pump_policy; } -void TaskQueueImpl::PumpQueueLocked() { - if (!any_thread().task_queue_manager) +void TaskQueueImpl::PumpQueueLocked(bool may_post_dowork) { + TaskQueueManager* task_queue_manager = any_thread().task_queue_manager; + if (!task_queue_manager) return; LazyNow lazy_now(any_thread().time_domain->CreateLazyNow()); - MoveReadyDelayedTasksToIncomingQueueLocked(&lazy_now); + MoveReadyDelayedTasksToDelayedWorkQueueLocked(&lazy_now); - bool was_empty = main_thread_only().work_queue.empty(); - while (!any_thread().incoming_queue.empty()) { - // TODO(alexclarke): consider std::move() when allowed. - main_thread_only().work_queue.push(any_thread().incoming_queue.front()); - any_thread().incoming_queue.pop(); + while (!any_thread().immediate_incoming_queue.empty()) { + main_thread_only().immediate_work_queue->Push( + std::move(any_thread().immediate_incoming_queue.front())); + any_thread().immediate_incoming_queue.pop(); } - // |incoming_queue| is now empty so TimeDomain::UpdateQueues no longer needs - // to consider this queue for reloading. + + // |immediate_incoming_queue| is now empty so TimeDomain::UpdateQueues no + // longer needs to consider this queue for reloading. any_thread().time_domain->UnregisterAsUpdatableTaskQueue(this); - if (!main_thread_only().work_queue.empty()) { - if (was_empty) { - any_thread() - .task_queue_manager->selector_.GetTaskQueueSets() - ->OnPushQueue(this); - } - any_thread().task_queue_manager->MaybePostDoWorkOnMainRunner(); + + if (main_thread_only().immediate_work_queue->Empty() && + main_thread_only().delayed_work_queue->Empty()) { + return; } + + if (may_post_dowork) + task_queue_manager->MaybeScheduleImmediateWork(FROM_HERE); } -void TaskQueueImpl::PumpQueue() { +void TaskQueueImpl::PumpQueue(bool may_post_dowork) { base::AutoLock lock(any_thread_lock_); - PumpQueueLocked(); + PumpQueueLocked(may_post_dowork); } const char* TaskQueueImpl::GetName() const { return name_; } -bool TaskQueueImpl::GetWorkQueueFrontTaskEnqueueOrder( - int* enqueue_order) const { - if (main_thread_only().work_queue.empty()) - return false; - *enqueue_order = main_thread_only().work_queue.front().enqueue_order(); - return true; -} - -void TaskQueueImpl::PushTaskOntoWorkQueueForTest(const Task& task) { - main_thread_only().work_queue.push(task); -} - -void TaskQueueImpl::PopTaskFromWorkQueueForTest() { - main_thread_only().work_queue.pop(); -} - void TaskQueueImpl::SetQueuePriority(QueuePriority priority) { if (!main_thread_only().task_queue_manager) return; @@ -454,23 +475,32 @@ bool verbose_tracing_enabled = false; TRACE_EVENT_CATEGORY_GROUP_ENABLED( disabled_by_default_verbose_tracing_category_, &verbose_tracing_enabled); - state->SetInteger("incoming_queue_size", any_thread().incoming_queue.size()); - state->SetInteger("work_queue_size", main_thread_only().work_queue.size()); - state->SetInteger("delayed_task_queue_size", - any_thread().delayed_task_queue.size()); + state->SetInteger("immediate_incoming_queue_size", + any_thread().immediate_incoming_queue.size()); + state->SetInteger("delayed_incoming_queue_size", + any_thread().delayed_incoming_queue.size()); + state->SetInteger("immediate_work_queue_size", + main_thread_only().immediate_work_queue->Size()); + state->SetInteger("delayed_work_queue_size", + main_thread_only().delayed_work_queue->Size()); if (verbose_tracing_enabled) { - state->BeginArray("incoming_queue"); - QueueAsValueInto(any_thread().incoming_queue, state); + state->BeginArray("immediate_incoming_queue"); + QueueAsValueInto(any_thread().immediate_incoming_queue, state); state->EndArray(); - state->BeginArray("work_queue"); - QueueAsValueInto(main_thread_only().work_queue, state); + state->BeginArray("delayed_work_queue"); + main_thread_only().delayed_work_queue->AsValueInto(state); state->EndArray(); - state->BeginArray("delayed_task_queue"); - QueueAsValueInto(any_thread().delayed_task_queue, state); + state->BeginArray("immediate_work_queue"); + main_thread_only().immediate_work_queue->AsValueInto(state); + state->EndArray(); + state->BeginArray("delayed_incoming_queue"); + QueueAsValueInto(any_thread().delayed_incoming_queue, state); state->EndArray(); } - state->SetString("priority", PriorityToString(static_cast<QueuePriority>( - main_thread_only().set_index))); + state->SetString( + "priority", + PriorityToString(static_cast<QueuePriority>( + main_thread_only().immediate_work_queue->work_queue_set_index()))); state->EndDictionary(); } @@ -546,10 +576,5 @@ state->EndDictionary(); } -size_t TaskQueueImpl::IncomingQueueSizeForTest() const { - base::AutoLock lock(any_thread_lock_); - return any_thread().incoming_queue.size(); -} - } // namespace internal } // namespace scheduler
diff --git a/components/scheduler/base/task_queue_impl.h b/components/scheduler/base/task_queue_impl.h index aa846394..7f85f9a 100644 --- a/components/scheduler/base/task_queue_impl.h +++ b/components/scheduler/base/task_queue_impl.h
@@ -20,6 +20,9 @@ class TaskQueueManager; namespace internal { +class WorkQueue; +class WorkQueueSets; + class SCHEDULER_EXPORT TaskQueueImpl final : public TaskQueue { public: TaskQueueImpl(TaskQueueManager* task_queue_manager, @@ -33,9 +36,17 @@ Task(); Task(const tracked_objects::Location& posted_from, const base::Closure& task, + base::TimeTicks desired_run_time, int sequence_number, bool nestable); + Task(const tracked_objects::Location& posted_from, + const base::Closure& task, + base::TimeTicks desired_run_time, + int sequence_number, + bool nestable, + int enqueue_order); + int enqueue_order() const { #ifndef NDEBUG DCHECK(enqueue_order_set_); @@ -57,7 +68,7 @@ #endif // Similar to sequence number, but the |enqueue_order| is set by // EnqueueTasksLocked and is not initially defined for delayed tasks until - // they are enqueued on the |incoming_queue_|. + // they are enqueued on the |immediate_incoming_queue_|. int enqueue_order_; }; @@ -72,21 +83,22 @@ base::TimeDelta delay) override; bool IsQueueEnabled() const override; - QueueState GetQueueState() const override; + bool IsEmpty() const override; + bool HasPendingImmediateWork() const override; + bool NeedsPumping() const override; void SetQueuePriority(QueuePriority priority) override; - void PumpQueue() override; + void PumpQueue(bool may_post_dowork) override; void SetPumpPolicy(PumpPolicy pump_policy) override; void AddTaskObserver(base::MessageLoop::TaskObserver* task_observer) override; void RemoveTaskObserver( base::MessageLoop::TaskObserver* task_observer) override; void SetTimeDomain(TimeDomain* time_domain) override; - void UpdateWorkQueue(LazyNow* lazy_now, - bool should_trigger_wakeup, - const Task* previous_task); - Task TakeTaskFromWorkQueue(); - - std::queue<Task>& work_queue() { return main_thread_only().work_queue; } + void UpdateImmediateWorkQueue(bool should_trigger_wakeup, + const Task* previous_task); + void UpdateDelayedWorkQueue(LazyNow* lazy_now, + bool should_trigger_wakeup, + const Task* previous_task); WakeupPolicy wakeup_policy() const { DCHECK(main_thread_checker_.CalledOnValidThread()); @@ -97,19 +109,6 @@ void AsValueInto(base::trace_event::TracedValue* state) const; - size_t get_task_queue_set_index() const { - return main_thread_only().set_index; - } - - void set_task_queue_set_index(size_t set_index) { - main_thread_only().set_index = set_index; - } - - // If the work queue isn't empty, |enqueue_order| gets set to the enqueue - // order of the front task and the function returns true. Otherwise the - // function returns false. - bool GetWorkQueueFrontTaskEnqueueOrder(int* enqueue_order) const; - bool GetQuiescenceMonitored() const { return should_monitor_quiescence_; } bool GetShouldNotifyObservers() const { return should_notify_observers_; @@ -118,20 +117,6 @@ void NotifyWillProcessTask(const base::PendingTask& pending_task); void NotifyDidProcessTask(const base::PendingTask& pending_task); - // Delayed task posted to the underlying run loop, which locks - // |any_thread_lock_| and calls MoveReadyDelayedTasksToIncomingQueueLocked to - // process dealyed tasks that need to be run now. Thread safe, but in - // practice it's always called from the main thread. - void MoveReadyDelayedTasksToIncomingQueue(LazyNow* lazy_now); - - // Test support functions. These should not be used in production code. - void PushTaskOntoWorkQueueForTest(const Task& task); - void PopTaskFromWorkQueueForTest(); - size_t WorkQueueSizeForTest() const { - return main_thread_only().work_queue.size(); - } - size_t IncomingQueueSizeForTest() const; - // Can be called on any thread. static const char* PumpPolicyToString(TaskQueue::PumpPolicy pump_policy); @@ -142,7 +127,25 @@ // Can be called on any thread. static const char* PriorityToString(TaskQueue::QueuePriority priority); + WorkQueue* delayed_work_queue() { + return main_thread_only().delayed_work_queue.get(); + } + + const WorkQueue* delayed_work_queue() const { + return main_thread_only().delayed_work_queue.get(); + } + + WorkQueue* immediate_work_queue() { + return main_thread_only().immediate_work_queue.get(); + } + + const WorkQueue* immediate_work_queue() const { + return main_thread_only().immediate_work_queue.get(); + } + private: + friend class WorkQueue; + enum class TaskType { NORMAL, NON_NESTABLE, @@ -159,21 +162,23 @@ // locked before accessing from other threads. TaskQueueManager* task_queue_manager; - std::queue<Task> incoming_queue; + std::queue<Task> immediate_incoming_queue; + std::priority_queue<Task> delayed_incoming_queue; PumpPolicy pump_policy; - std::priority_queue<Task> delayed_task_queue; TimeDomain* time_domain; }; struct MainThreadOnly { - MainThreadOnly(TaskQueueManager* task_queue_manager); + MainThreadOnly(TaskQueueManager* task_queue_manager, + TaskQueueImpl* task_queue); ~MainThreadOnly(); // Another copy of TaskQueueManager for lock-free access from the main // thread. See description inside struct AnyThread for details. TaskQueueManager* task_queue_manager; - std::queue<Task> work_queue; + scoped_ptr<WorkQueue> delayed_work_queue; + scoped_ptr<WorkQueue> immediate_work_queue; base::ObserverList<base::MessageLoop::TaskObserver> task_observers; size_t set_index; }; @@ -192,23 +197,25 @@ void ScheduleDelayedWorkTask(TimeDomain* time_domain, base::TimeTicks desired_run_time); - // Enqueues any delayed tasks which should be run now on the incoming_queue_. - // Must be called with |any_thread_lock_| locked. - void MoveReadyDelayedTasksToIncomingQueueLocked(LazyNow* lazy_now); + // Enqueues any delayed tasks which should be run now on the + // |delayed_work_queue|. Must be called with |any_thread_lock_| locked. + void MoveReadyDelayedTasksToDelayedWorkQueueLocked(LazyNow* lazy_now); - void PumpQueueLocked(); + void MoveReadyImmediateTasksToImmediateWorkQueueLocked(); + + void PumpQueueLocked(bool may_post_dowork); bool TaskIsOlderThanQueuedTasks(const Task* task); bool ShouldAutoPumpQueueLocked(bool should_trigger_wakeup, const Task* previous_task); - // Push the task onto the |incoming_queue_| and for auto pumped queues it - // calls MaybePostDoWorkOnMainRunner if the incomming queue was empty. - void EnqueueTaskLocked(const Task& pending_task); + // Push the task onto the |delayed_incoming_queue| + void PushOntoDelayedIncomingQueueLocked(const Task&& pending_task, + LazyNow* lazy_now); - // Push the task onto the |incoming_queue_| and allocates an - // enqueue_order for it based on |enqueue_order_policy|. Does not call - // MaybePostDoWorkOnMainRunner! - void EnqueueDelayedTaskLocked(const Task& pending_task); + // Push the task onto the |immediate_incoming_queue| and for auto pumped + // queues it calls MaybePostDoWorkOnMainRunner if the Incoming queue was + // empty. + void PushOntoImmediateIncomingQueueLocked(const Task&& pending_task); void TraceQueueSize(bool is_locked) const; static void QueueAsValueInto(const std::queue<Task>& queue,
diff --git a/components/scheduler/base/task_queue_manager.cc b/components/scheduler/base/task_queue_manager.cc index ec478db..6fec6e0 100644 --- a/components/scheduler/base/task_queue_manager.cc +++ b/components/scheduler/base/task_queue_manager.cc
@@ -12,7 +12,8 @@ #include "components/scheduler/base/task_queue_impl.h" #include "components/scheduler/base/task_queue_manager_delegate.h" #include "components/scheduler/base/task_queue_selector.h" -#include "components/scheduler/base/task_queue_sets.h" +#include "components/scheduler/base/work_queue.h" +#include "components/scheduler/base/work_queue_sets.h" namespace scheduler { @@ -24,7 +25,6 @@ : real_time_domain_(new RealTimeDomain()), delegate_(delegate), task_was_run_on_quiescence_monitored_queue_(false), - pending_dowork_count_(0), work_batch_size_(1), tracing_category_(tracing_category), disabled_by_default_tracing_category_( @@ -39,10 +39,12 @@ "TaskQueueManager", this); selector_.SetTaskQueueSelectorObserver(this); - decrement_pending_and_do_work_closure_ = - base::Bind(&TaskQueueManager::DoWork, weak_factory_.GetWeakPtr(), true); - do_work_closure_ = - base::Bind(&TaskQueueManager::DoWork, weak_factory_.GetWeakPtr(), false); + from_main_thread_immediate_do_work_closure_ = + base::Bind(&TaskQueueManager::DoWork, weak_factory_.GetWeakPtr(), + base::TimeTicks(), true); + from_other_thread_immediate_do_work_closure_ = + base::Bind(&TaskQueueManager::DoWork, weak_factory_.GetWeakPtr(), + base::TimeTicks(), false); // TODO(alexclarke): Change this to be a parameter that's passed in. RegisterTimeDomain(real_time_domain_.get()); @@ -60,8 +62,7 @@ void TaskQueueManager::RegisterTimeDomain(TimeDomain* time_domain) { time_domains_.insert(time_domain); - time_domain->OnRegisterWithTaskQueueManager(delegate_.get(), - do_work_closure_); + time_domain->OnRegisterWithTaskQueueManager(this); } void TaskQueueManager::UnregisterTimeDomain(TimeDomain* time_domain) { @@ -117,27 +118,50 @@ } } -void TaskQueueManager::MaybePostDoWorkOnMainRunner() { +void TaskQueueManager::MaybeScheduleImmediateWork( + const tracked_objects::Location& from_here) { bool on_main_thread = delegate_->BelongsToCurrentThread(); + // De-duplicate DoWork posts. if (on_main_thread) { - // We only want one pending DoWork posted from the main thread, or we risk - // an explosion of pending DoWorks which could starve out everything else. - if (pending_dowork_count_ > 0) { + if (!main_thread_pending_wakeups_.insert(base::TimeTicks()).second) { return; } - pending_dowork_count_++; - delegate_->PostTask(FROM_HERE, decrement_pending_and_do_work_closure_); + delegate_->PostTask(from_here, from_main_thread_immediate_do_work_closure_); } else { - delegate_->PostTask(FROM_HERE, do_work_closure_); + base::AutoLock lock(other_thread_lock_); + if (!other_thread_pending_wakeups_.insert(base::TimeTicks()).second) + return; + delegate_->PostTask(from_here, + from_other_thread_immediate_do_work_closure_); } } -void TaskQueueManager::DoWork(bool decrement_pending_dowork_count) { - if (decrement_pending_dowork_count) { - pending_dowork_count_--; - DCHECK_GE(pending_dowork_count_, 0); - } +void TaskQueueManager::MaybeScheduleDelayedWork( + const tracked_objects::Location& from_here, + LazyNow* lazy_now, + base::TimeDelta delay) { DCHECK(main_thread_checker_.CalledOnValidThread()); + DCHECK_GE(delay, base::TimeDelta()); + base::TimeTicks run_time = lazy_now->Now() + delay; + // De-duplicate DoWork posts. + if (!main_thread_pending_wakeups_.insert(run_time).second) + return; + delegate_->PostDelayedTask( + from_here, base::Bind(&TaskQueueManager::DoWork, + weak_factory_.GetWeakPtr(), run_time, true), + delay); +} + +void TaskQueueManager::DoWork(base::TimeTicks run_time, bool from_main_thread) { + DCHECK(main_thread_checker_.CalledOnValidThread()); + TRACE_EVENT1(tracing_category_, "TaskQueueManager::DoWork", + "from_main_thread", from_main_thread); + if (from_main_thread) { + main_thread_pending_wakeups_.erase(run_time); + } else { + base::AutoLock lock(other_thread_lock_); + other_thread_pending_wakeups_.erase(run_time); + } if (!delegate_->IsNested()) queues_to_delete_.clear(); @@ -148,11 +172,12 @@ internal::TaskQueueImpl::Task previous_task; for (int i = 0; i < work_batch_size_; i++) { - internal::TaskQueueImpl* queue; - if (!SelectQueueToService(&queue)) + internal::WorkQueue* work_queue; + if (!SelectWorkQueueToService(&work_queue)) { break; + } - switch (ProcessTaskFromWorkQueue(queue, &previous_task)) { + switch (ProcessTaskFromWorkQueue(work_queue, &previous_task)) { case ProcessTaskResult::DEFERRED: // If a task was deferred, try again with another task. Note that this // means deferred tasks (i.e. non-nestable tasks) will never trigger @@ -163,7 +188,7 @@ case ProcessTaskResult::TASK_QUEUE_MANAGER_DELETED: return; // The TaskQueueManager got deleted, we must bail out. } - bool should_trigger_wakeup = queue->wakeup_policy() == + bool should_trigger_wakeup = work_queue->task_queue()->wakeup_policy() == TaskQueue::WakeupPolicy::CAN_WAKE_OTHER_QUEUES; UpdateWorkQueues(should_trigger_wakeup, &previous_task); @@ -177,7 +202,7 @@ // when there's no more work left to be done, rather than posting a // continuation task. if (!selector_.EnabledWorkQueuesEmpty() || TryAdvanceTimeDomains()) { - MaybePostDoWorkOnMainRunner(); + MaybeScheduleImmediateWork(FROM_HERE); } else { // Tell the task runner we have no more work. delegate_->OnNoMoreImmediateWork(); @@ -192,12 +217,12 @@ return can_advance; } -bool TaskQueueManager::SelectQueueToService( - internal::TaskQueueImpl** out_queue) { - bool should_run = selector_.SelectQueueToService(out_queue); +bool TaskQueueManager::SelectWorkQueueToService( + internal::WorkQueue** out_work_queue) { + bool should_run = selector_.SelectWorkQueueToService(out_work_queue); TRACE_EVENT_OBJECT_SNAPSHOT_WITH_ID( disabled_by_default_tracing_category_, "TaskQueueManager", this, - AsValueWithSelectorResult(should_run, *out_queue)); + AsValueWithSelectorResult(should_run, *out_work_queue)); return should_run; } @@ -207,16 +232,17 @@ } TaskQueueManager::ProcessTaskResult TaskQueueManager::ProcessTaskFromWorkQueue( - internal::TaskQueueImpl* queue, + internal::WorkQueue* work_queue, internal::TaskQueueImpl::Task* out_previous_task) { DCHECK(main_thread_checker_.CalledOnValidThread()); scoped_refptr<DeletionSentinel> protect(deletion_sentinel_); - // TODO(alexclarke): consider std::move() when allowed. - internal::TaskQueueImpl::Task pending_task = queue->TakeTaskFromWorkQueue(); + internal::TaskQueueImpl* queue = work_queue->task_queue(); if (queue->GetQuiescenceMonitored()) task_was_run_on_quiescence_monitored_queue_ = true; + internal::TaskQueueImpl::Task pending_task = + work_queue->TakeTaskFromWorkQueue(); if (!pending_task.nestable && delegate_->IsNested()) { // Defer non-nestable work to the main task runner. NOTE these tasks can be // arbitrarily delayed so the additional delay should not be a problem. @@ -290,10 +316,14 @@ return task_sequence_num_.GetNext(); } +LazyNow TaskQueueManager::CreateLazyNow() const { + return LazyNow(delegate_.get()); +} + scoped_refptr<base::trace_event::ConvertableToTraceFormat> TaskQueueManager::AsValueWithSelectorResult( bool should_run, - internal::TaskQueueImpl* selected_queue) const { + internal::WorkQueue* selected_work_queue) const { DCHECK(main_thread_checker_.CalledOnValidThread()); scoped_refptr<base::trace_event::TracedValue> state = new base::trace_event::TracedValue(); @@ -304,8 +334,11 @@ state->BeginDictionary("selector"); selector_.AsValueInto(state.get()); state->EndDictionary(); - if (should_run) - state->SetString("selected_queue", selected_queue->GetName()); + if (should_run) { + state->SetString("selected_queue", + selected_work_queue->task_queue()->GetName()); + state->SetString("work_queue_name", selected_work_queue->name()); + } state->BeginArray("time_domains"); for (auto& time_domain : time_domains_) @@ -317,8 +350,10 @@ void TaskQueueManager::OnTaskQueueEnabled(internal::TaskQueueImpl* queue) { DCHECK(main_thread_checker_.CalledOnValidThread()); // Only schedule DoWork if there's something to do. - if (!queue->work_queue().empty()) - MaybePostDoWorkOnMainRunner(); + if (!queue->immediate_work_queue()->Empty() || + !queue->delayed_work_queue()->Empty()) { + MaybeScheduleImmediateWork(FROM_HERE); + } } } // namespace scheduler
diff --git a/components/scheduler/base/task_queue_manager.h b/components/scheduler/base/task_queue_manager.h index f7090bd..b9705547 100644 --- a/components/scheduler/base/task_queue_manager.h +++ b/components/scheduler/base/task_queue_manager.h
@@ -62,6 +62,19 @@ const char* disabled_by_default_verbose_tracing_category); ~TaskQueueManager() override; + // Requests that a task to process work is posted on the main task runner. + // These tasks are de-duplicated in two buckets: main-thread and all other + // threads. This distinction is done to reduce the overehead from locks, we + // assume the main-thread path will be hot. + void MaybeScheduleImmediateWork(const tracked_objects::Location& from_here); + + // Requests that a delayed task to process work is posted on the main task + // runner. These delayed tasks are de-duplicated. Must be called on the thread + // this class was created on. + void MaybeScheduleDelayedWork(const tracked_objects::Location& from_here, + LazyNow* lazy_now, + base::TimeDelta delay); + // Set the number of tasks executed in a single invocation of the task queue // manager. Increasing the batch size can reduce the overhead of yielding // back to the main message loop -- at the cost of potentially delaying other @@ -105,6 +118,8 @@ RealTimeDomain* real_time_domain() const { return real_time_domain_.get(); } + LazyNow CreateLazyNow() const; + private: friend class LazyNow; friend class internal::TaskQueueImpl; @@ -128,13 +143,8 @@ // Called by the task queue to register a new pending task. void DidQueueTask(const internal::TaskQueueImpl::Task& pending_task); - // Post a task to call DoWork() on the main task runner. Only one pending - // DoWork is allowed from the main thread, to prevent an explosion of pending - // DoWorks. - void MaybePostDoWorkOnMainRunner(); - // Use the selector to choose a pending task and run it. - void DoWork(bool decrement_pending_dowork_count); + void DoWork(base::TimeTicks run_time, bool from_main_thread); // Delayed Tasks with run_times <= Now() are enqueued onto the work queue. // Reloads any empty work queues which have automatic pumping enabled and @@ -147,7 +157,7 @@ // Chooses the next work queue to service. Returns true if |out_queue| // indicates the queue from which the next task should be run, false to // avoid running any tasks. - bool SelectQueueToService(internal::TaskQueueImpl** out_queue); + bool SelectWorkQueueToService(internal::WorkQueue** out_work_queue); // Runs a single nestable task from the |queue|. On exit, |out_task| will // contain the task which was executed. Non-nestable task are reposted on the @@ -158,7 +168,7 @@ TASK_QUEUE_MANAGER_DELETED }; ProcessTaskResult ProcessTaskFromWorkQueue( - internal::TaskQueueImpl* queue, + internal::WorkQueue* work_queue, internal::TaskQueueImpl::Task* out_previous_task); bool RunsTasksOnCurrentThread() const; @@ -172,7 +182,7 @@ scoped_refptr<base::trace_event::ConvertableToTraceFormat> AsValueWithSelectorResult(bool should_run, - internal::TaskQueueImpl* selected_queue) const; + internal::WorkQueue* selected_work_queue) const; std::set<TimeDomain*> time_domains_; scoped_ptr<RealTimeDomain> real_time_domain_; @@ -191,14 +201,18 @@ scoped_refptr<TaskQueueManagerDelegate> delegate_; internal::TaskQueueSelector selector_; - base::Closure decrement_pending_and_do_work_closure_; - base::Closure do_work_closure_; + base::Closure from_main_thread_immediate_do_work_closure_; + base::Closure from_other_thread_immediate_do_work_closure_; bool task_was_run_on_quiescence_monitored_queue_; - // The pending_dowork_count_ is only tracked on the main thread since that's - // where re-entrant problems happen. - int pending_dowork_count_; + // To reduce locking overhead we track pending calls to DoWork seperatly for + // the main thread and other threads. + std::set<base::TimeTicks> main_thread_pending_wakeups_; + + // Protects |other_thread_pending_wakeups_|. + mutable base::Lock other_thread_lock_; + std::set<base::TimeTicks> other_thread_pending_wakeups_; int work_batch_size_;
diff --git a/components/scheduler/base/task_queue_manager_perftest.cc b/components/scheduler/base/task_queue_manager_perftest.cc index dcdb5069..c1c69309 100644 --- a/components/scheduler/base/task_queue_manager_perftest.cc +++ b/components/scheduler/base/task_queue_manager_perftest.cc
@@ -10,7 +10,7 @@ #include "components/scheduler/base/task_queue_impl.h" #include "components/scheduler/base/task_queue_manager_delegate_for_test.h" #include "components/scheduler/base/task_queue_selector.h" -#include "components/scheduler/base/task_queue_sets.h" +#include "components/scheduler/base/work_queue_sets.h" #include "testing/gtest/include/gtest/gtest.h" #include "testing/perf/perf_test.h"
diff --git a/components/scheduler/base/task_queue_manager_unittest.cc b/components/scheduler/base/task_queue_manager_unittest.cc index f1d9dc4..6396d362 100644 --- a/components/scheduler/base/task_queue_manager_unittest.cc +++ b/components/scheduler/base/task_queue_manager_unittest.cc
@@ -14,10 +14,11 @@ #include "components/scheduler/base/task_queue_impl.h" #include "components/scheduler/base/task_queue_manager_delegate_for_test.h" #include "components/scheduler/base/task_queue_selector.h" -#include "components/scheduler/base/task_queue_sets.h" #include "components/scheduler/base/test_always_fail_time_source.h" #include "components/scheduler/base/test_time_source.h" #include "components/scheduler/base/virtual_time_domain.h" +#include "components/scheduler/base/work_queue.h" +#include "components/scheduler/base/work_queue_sets.h" #include "testing/gmock/include/gmock/gmock.h" using testing::ElementsAre; @@ -216,12 +217,12 @@ Initialize(1u); std::vector<int> run_order; - EXPECT_FALSE(runners_[0]->HasPendingImmediateTask()); + EXPECT_FALSE(runners_[0]->HasPendingImmediateWork()); runners_[0]->PostTask(FROM_HERE, base::Bind(&TestTask, 1, &run_order)); - EXPECT_TRUE(runners_[0]->HasPendingImmediateTask()); + EXPECT_TRUE(runners_[0]->HasPendingImmediateWork()); test_task_runner_->RunUntilIdle(); - EXPECT_FALSE(runners_[0]->HasPendingImmediateTask()); + EXPECT_FALSE(runners_[0]->HasPendingImmediateWork()); } TEST_F(TaskQueueManagerTest, DelayedTaskPosting) { @@ -232,8 +233,7 @@ runners_[0]->PostDelayedTask(FROM_HERE, base::Bind(&TestTask, 1, &run_order), delay); EXPECT_EQ(delay, test_task_runner_->DelayToNextTaskTime()); - EXPECT_EQ(TaskQueue::QueueState::NO_IMMEDIATE_WORK, - runners_[0]->GetQueueState()); + EXPECT_FALSE(runners_[0]->HasPendingImmediateWork()); EXPECT_TRUE(run_order.empty()); // The task doesn't run before the delay has completed. @@ -243,7 +243,7 @@ // After the delay has completed, the task runs normally. test_task_runner_->RunForPeriod(base::TimeDelta::FromMilliseconds(1)); EXPECT_THAT(run_order, ElementsAre(1)); - EXPECT_EQ(TaskQueue::QueueState::EMPTY, runners_[0]->GetQueueState()); + EXPECT_FALSE(runners_[0]->HasPendingImmediateWork()); } bool MessageLoopTaskCounter(size_t* count) { @@ -377,10 +377,10 @@ EXPECT_FALSE(test_task_runner_->HasPendingTasks()); // However polling still works. - EXPECT_TRUE(runners_[0]->HasPendingImmediateTask()); + EXPECT_TRUE(runners_[0]->HasPendingImmediateWork()); // After pumping the task runs normally. - runners_[0]->PumpQueue(); + runners_[0]->PumpQueue(true); EXPECT_TRUE(test_task_runner_->HasPendingTasks()); test_task_runner_->RunUntilIdle(); EXPECT_THAT(run_order, ElementsAre(1)); @@ -462,13 +462,13 @@ delay); // After pumping but before the delay period has expired, task does not run. - runners_[0]->PumpQueue(); + runners_[0]->PumpQueue(true); test_task_runner_->RunForPeriod(base::TimeDelta::FromMilliseconds(5)); EXPECT_TRUE(run_order.empty()); // Once the delay has expired, pumping causes the task to run. now_src_->Advance(base::TimeDelta::FromMilliseconds(5)); - runners_[0]->PumpQueue(); + runners_[0]->PumpQueue(true); EXPECT_TRUE(test_task_runner_->HasPendingTasks()); test_task_runner_->RunPendingTasks(); EXPECT_THAT(run_order, ElementsAre(1)); @@ -496,7 +496,7 @@ EXPECT_TRUE(run_order.empty()); // Once the delay has expired, pumping causes the task to run. - runners_[0]->PumpQueue(); + runners_[0]->PumpQueue(true); test_task_runner_->RunUntilIdle(); EXPECT_THAT(run_order, ElementsAre(1, 2)); } @@ -522,11 +522,11 @@ // Posting two tasks and pumping twice should result in two tasks in the work // queue. runners_[0]->PostTask(FROM_HERE, base::Bind(&TestTask, 1, &run_order)); - runners_[0]->PumpQueue(); + runners_[0]->PumpQueue(true); runners_[0]->PostTask(FROM_HERE, base::Bind(&TestTask, 2, &run_order)); - runners_[0]->PumpQueue(); + runners_[0]->PumpQueue(true); - EXPECT_EQ(2u, runners_[0]->WorkQueueSizeForTest()); + EXPECT_EQ(2u, runners_[0]->immediate_work_queue()->Size()); } void ReentrantTestTask(scoped_refptr<base::SingleThreadTaskRunner> runner, @@ -596,7 +596,7 @@ FROM_HERE, base::Bind(&RePostingTestTask, runners_[0], &run_count)); test_task_runner_->RunPendingTasks(); - // NOTE without the executing_task_ check in MaybePostDoWorkOnMainRunner there + // NOTE without the executing_task_ check in MaybeScheduleDoWork there // will be two tasks here. EXPECT_EQ(1u, test_task_runner_->NumPendingTasks()); EXPECT_EQ(1, run_count); @@ -691,7 +691,7 @@ // This still shouldn't wake TQM as manual queue was not pumped. EXPECT_TRUE(run_order.empty()); - runners_[1]->PumpQueue(); + runners_[1]->PumpQueue(true); test_task_runner_->RunUntilIdle(); // Executing a task on an auto pumped queue should wake the TQM. EXPECT_THAT(run_order, ElementsAre(2, 1)); @@ -1005,83 +1005,152 @@ EXPECT_TRUE(manager_->GetAndClearSystemIsQuiescentBit()); } -TEST_F(TaskQueueManagerTest, HasPendingImmediateTask) { +TEST_F(TaskQueueManagerTest, HasPendingImmediateWork) { Initialize(2u); internal::TaskQueueImpl* queue0 = runners_[0].get(); internal::TaskQueueImpl* queue1 = runners_[1].get(); queue0->SetPumpPolicy(TaskQueue::PumpPolicy::AUTO); queue1->SetPumpPolicy(TaskQueue::PumpPolicy::MANUAL); - EXPECT_FALSE(queue0->HasPendingImmediateTask()); - EXPECT_FALSE(queue1->HasPendingImmediateTask()); + EXPECT_FALSE(queue0->HasPendingImmediateWork()); + EXPECT_FALSE(queue1->HasPendingImmediateWork()); queue0->PostTask(FROM_HERE, base::Bind(NullTask)); queue1->PostTask(FROM_HERE, base::Bind(NullTask)); - EXPECT_TRUE(queue0->HasPendingImmediateTask()); - EXPECT_TRUE(queue1->HasPendingImmediateTask()); + EXPECT_TRUE(queue0->HasPendingImmediateWork()); + EXPECT_TRUE(queue1->HasPendingImmediateWork()); test_task_runner_->RunUntilIdle(); - EXPECT_FALSE(queue0->HasPendingImmediateTask()); - EXPECT_TRUE(queue1->HasPendingImmediateTask()); + EXPECT_FALSE(queue0->HasPendingImmediateWork()); + EXPECT_TRUE(queue1->HasPendingImmediateWork()); - queue1->PumpQueue(); - EXPECT_FALSE(queue0->HasPendingImmediateTask()); - EXPECT_TRUE(queue1->HasPendingImmediateTask()); + queue1->PumpQueue(true); + EXPECT_FALSE(queue0->HasPendingImmediateWork()); + EXPECT_TRUE(queue1->HasPendingImmediateWork()); test_task_runner_->RunUntilIdle(); - EXPECT_FALSE(queue0->HasPendingImmediateTask()); - EXPECT_FALSE(queue1->HasPendingImmediateTask()); + EXPECT_FALSE(queue0->HasPendingImmediateWork()); + EXPECT_FALSE(queue1->HasPendingImmediateWork()); } -TEST_F(TaskQueueManagerTest, GetQueueState) { +TEST_F(TaskQueueManagerTest, HasPendingImmediateWorkAndNeedsPumping) { Initialize(2u); internal::TaskQueueImpl* queue0 = runners_[0].get(); internal::TaskQueueImpl* queue1 = runners_[1].get(); queue0->SetPumpPolicy(TaskQueue::PumpPolicy::AUTO); queue1->SetPumpPolicy(TaskQueue::PumpPolicy::MANUAL); - EXPECT_EQ(TaskQueue::QueueState::EMPTY, queue0->GetQueueState()); - EXPECT_EQ(TaskQueue::QueueState::EMPTY, queue1->GetQueueState()); + EXPECT_FALSE(queue0->HasPendingImmediateWork()); + EXPECT_FALSE(queue0->NeedsPumping()); + EXPECT_FALSE(queue1->HasPendingImmediateWork()); + EXPECT_FALSE(queue1->NeedsPumping()); queue0->PostTask(FROM_HERE, base::Bind(NullTask)); queue0->PostTask(FROM_HERE, base::Bind(NullTask)); queue1->PostTask(FROM_HERE, base::Bind(NullTask)); - EXPECT_EQ(TaskQueue::QueueState::NEEDS_PUMPING, queue0->GetQueueState()); - EXPECT_EQ(TaskQueue::QueueState::NEEDS_PUMPING, queue1->GetQueueState()); + EXPECT_TRUE(queue0->HasPendingImmediateWork()); + EXPECT_TRUE(queue0->NeedsPumping()); + EXPECT_TRUE(queue1->HasPendingImmediateWork()); + EXPECT_TRUE(queue1->NeedsPumping()); test_task_runner_->SetRunTaskLimit(1); test_task_runner_->RunPendingTasks(); - EXPECT_EQ(TaskQueue::QueueState::HAS_WORK, queue0->GetQueueState()); - EXPECT_EQ(TaskQueue::QueueState::NEEDS_PUMPING, queue1->GetQueueState()); + EXPECT_TRUE(queue0->HasPendingImmediateWork()); + EXPECT_FALSE(queue0->NeedsPumping()); + EXPECT_TRUE(queue1->HasPendingImmediateWork()); + EXPECT_TRUE(queue1->NeedsPumping()); test_task_runner_->ClearRunTaskLimit(); test_task_runner_->RunUntilIdle(); - EXPECT_EQ(TaskQueue::QueueState::EMPTY, queue0->GetQueueState()); - EXPECT_EQ(TaskQueue::QueueState::NEEDS_PUMPING, queue1->GetQueueState()); + EXPECT_FALSE(queue0->HasPendingImmediateWork()); + EXPECT_FALSE(queue0->NeedsPumping()); + EXPECT_TRUE(queue1->HasPendingImmediateWork()); + EXPECT_TRUE(queue1->NeedsPumping()); - queue1->PumpQueue(); - EXPECT_EQ(TaskQueue::QueueState::EMPTY, queue0->GetQueueState()); - EXPECT_EQ(TaskQueue::QueueState::HAS_WORK, queue1->GetQueueState()); + queue1->PumpQueue(true); + EXPECT_FALSE(queue0->HasPendingImmediateWork()); + EXPECT_FALSE(queue0->NeedsPumping()); + EXPECT_TRUE(queue1->HasPendingImmediateWork()); + EXPECT_FALSE(queue1->NeedsPumping()); test_task_runner_->RunUntilIdle(); - EXPECT_EQ(TaskQueue::QueueState::EMPTY, queue0->GetQueueState()); - EXPECT_EQ(TaskQueue::QueueState::EMPTY, queue1->GetQueueState()); + EXPECT_FALSE(queue0->HasPendingImmediateWork()); + EXPECT_FALSE(queue0->NeedsPumping()); + EXPECT_FALSE(queue1->HasPendingImmediateWork()); + EXPECT_FALSE(queue1->NeedsPumping()); } -TEST_F(TaskQueueManagerTest, DelayedTaskDoesNotSkipAHeadOfNonDelayedTask) { +void ExpensiveTestTask(int value, + base::SimpleTestTickClock* clock, + std::vector<int>* out_result) { + out_result->push_back(value); + clock->Advance(base::TimeDelta::FromMilliseconds(1)); +} + +TEST_F(TaskQueueManagerTest, ImmediateAndDelayedTaskRoundRobbin) { + Initialize(1u); + + std::vector<int> run_order; + base::TimeDelta delay = base::TimeDelta::FromMilliseconds(10); + runners_[0]->PostDelayedTask( + FROM_HERE, base::Bind(&ExpensiveTestTask, 10, now_src_.get(), &run_order), + delay); + runners_[0]->PostDelayedTask( + FROM_HERE, base::Bind(&ExpensiveTestTask, 11, now_src_.get(), &run_order), + delay); + runners_[0]->PostDelayedTask( + FROM_HERE, base::Bind(&ExpensiveTestTask, 12, now_src_.get(), &run_order), + delay); + runners_[0]->PostDelayedTask( + FROM_HERE, base::Bind(&ExpensiveTestTask, 13, now_src_.get(), &run_order), + delay); + + test_task_runner_->RunForPeriod(delay); + + runners_[0]->PostTask( + FROM_HERE, base::Bind(&ExpensiveTestTask, 0, now_src_.get(), &run_order)); + runners_[0]->PostTask( + FROM_HERE, base::Bind(&ExpensiveTestTask, 1, now_src_.get(), &run_order)); + runners_[0]->PostTask( + FROM_HERE, base::Bind(&ExpensiveTestTask, 2, now_src_.get(), &run_order)); + runners_[0]->PostTask( + FROM_HERE, base::Bind(&ExpensiveTestTask, 3, now_src_.get(), &run_order)); + + test_task_runner_->SetAutoAdvanceNowToPendingTasks(true); + test_task_runner_->RunUntilIdle(); + + EXPECT_THAT(run_order, ElementsAre(10, 0, 11, 1, 12, 2, 13, 3)); +} + +TEST_F(TaskQueueManagerTest, + DelayedTaskDoesNotSkipAHeadOfNonDelayedTask_SameQueue) { + Initialize(1u); + + std::vector<int> run_order; + base::TimeDelta delay = base::TimeDelta::FromMilliseconds(10); + runners_[0]->PostTask(FROM_HERE, base::Bind(&TestTask, 2, &run_order)); + runners_[0]->PostTask(FROM_HERE, base::Bind(&TestTask, 3, &run_order)); + runners_[0]->PostDelayedTask(FROM_HERE, base::Bind(&TestTask, 1, &run_order), + delay); + + now_src_->Advance(delay * 2); + test_task_runner_->RunUntilIdle(); + + EXPECT_THAT(run_order, ElementsAre(2, 3, 1)); +} + +TEST_F(TaskQueueManagerTest, + DelayedTaskDoesNotSkipAHeadOfNonDelayedTask_DifferentQueues) { Initialize(2u); std::vector<int> run_order; base::TimeDelta delay = base::TimeDelta::FromMilliseconds(10); - runners_[0]->PostDelayedTask(FROM_HERE, base::Bind(&TestTask, 1, &run_order), - delay); runners_[1]->PostTask(FROM_HERE, base::Bind(&TestTask, 2, &run_order)); runners_[1]->PostTask(FROM_HERE, base::Bind(&TestTask, 3, &run_order)); + runners_[0]->PostDelayedTask(FROM_HERE, base::Bind(&TestTask, 1, &run_order), + delay); now_src_->Advance(delay * 2); - // After task 2 has run, the automatic selector will have to choose between - // tasks 1 and 3. The sequence numbers are used to choose between the two - // tasks and if they are correct task 1 will run last. test_task_runner_->RunUntilIdle(); EXPECT_THAT(run_order, ElementsAre(2, 3, 1)); @@ -1171,7 +1240,7 @@ // The sequence numbers are a zero-based monotonically incrememting counter // which should be set when the task is posted rather than when it's enqueued - // onto the incomming queue. + // onto the Incoming queue. EXPECT_THAT(observer.sequence_numbers(), ElementsAre(3, 2, 1, 0)); manager_->RemoveTaskObserver(&observer); @@ -1373,11 +1442,13 @@ base::TimeDelta::FromMilliseconds(30)); domain_b->AdvanceTo(start_time + base::TimeDelta::FromMilliseconds(50)); + manager_->MaybeScheduleImmediateWork(FROM_HERE); test_task_runner_->RunUntilIdle(); EXPECT_THAT(run_order, ElementsAre(4, 5, 6)); domain_a->AdvanceTo(start_time + base::TimeDelta::FromMilliseconds(50)); + manager_->MaybeScheduleImmediateWork(FROM_HERE); test_task_runner_->RunUntilIdle(); EXPECT_THAT(run_order, ElementsAre(4, 5, 6, 1, 2, 3)); @@ -1406,6 +1477,7 @@ base::TimeDelta::FromMilliseconds(40)); domain_a->AdvanceTo(start_time + base::TimeDelta::FromMilliseconds(20)); + manager_->MaybeScheduleImmediateWork(FROM_HERE); test_task_runner_->RunUntilIdle(); EXPECT_THAT(run_order, ElementsAre(1, 2)); @@ -1415,6 +1487,7 @@ runners_[0]->SetTimeDomain(domain_b.get()); domain_b->AdvanceTo(start_time + base::TimeDelta::FromMilliseconds(50)); + manager_->MaybeScheduleImmediateWork(FROM_HERE); test_task_runner_->RunUntilIdle(); EXPECT_THAT(run_order, ElementsAre(1, 2, 3, 4)); @@ -1447,4 +1520,185 @@ test_task_runner_->RunUntilIdle(); } +namespace { + +class QuadraticTask { + public: + QuadraticTask(scoped_refptr<internal::TaskQueueImpl> task_queue, + base::TimeDelta delay, + base::SimpleTestTickClock* now_src) + : count_(0), task_queue_(task_queue), delay_(delay), now_src_(now_src) {} + + void SetShouldExit(base::Callback<bool()> should_exit) { + should_exit_ = should_exit; + } + + void Run() { + if (should_exit_.Run()) + return; + count_++; + task_queue_->PostDelayedTask( + FROM_HERE, base::Bind(&QuadraticTask::Run, base::Unretained(this)), + delay_); + task_queue_->PostDelayedTask( + FROM_HERE, base::Bind(&QuadraticTask::Run, base::Unretained(this)), + delay_); + now_src_->Advance(base::TimeDelta::FromMilliseconds(5)); + } + + int count() const { return count_; } + + private: + int count_; + scoped_refptr<internal::TaskQueueImpl> task_queue_; + base::TimeDelta delay_; + base::Callback<bool()> should_exit_; + base::SimpleTestTickClock* now_src_; +}; + +class LinearTask { + public: + LinearTask(scoped_refptr<internal::TaskQueueImpl> task_queue, + base::TimeDelta delay, + base::SimpleTestTickClock* now_src) + : count_(0), task_queue_(task_queue), delay_(delay), now_src_(now_src) {} + + void SetShouldExit(base::Callback<bool()> should_exit) { + should_exit_ = should_exit; + } + + void Run() { + if (should_exit_.Run()) + return; + count_++; + task_queue_->PostDelayedTask( + FROM_HERE, base::Bind(&LinearTask::Run, base::Unretained(this)), + delay_); + now_src_->Advance(base::TimeDelta::FromMilliseconds(5)); + } + + int count() const { return count_; } + + private: + int count_; + scoped_refptr<internal::TaskQueueImpl> task_queue_; + base::TimeDelta delay_; + base::Callback<bool()> should_exit_; + base::SimpleTestTickClock* now_src_; +}; + +bool ShouldExit(QuadraticTask* quadratic_task, LinearTask* linear_task) { + return quadratic_task->count() == 1000 || linear_task->count() == 1000; +} + +} // namespace + +TEST_F(TaskQueueManagerTest, DelayedTasksDontStarveNonDelayedWork_SameQueue) { + Initialize(1u); + + QuadraticTask quadratic_delayed_task( + runners_[0], base::TimeDelta::FromMilliseconds(10), now_src_.get()); + LinearTask linear_immediate_task(runners_[0], base::TimeDelta(), + now_src_.get()); + base::Callback<bool()> should_exit = + base::Bind(ShouldExit, &quadratic_delayed_task, &linear_immediate_task); + quadratic_delayed_task.SetShouldExit(should_exit); + linear_immediate_task.SetShouldExit(should_exit); + + quadratic_delayed_task.Run(); + linear_immediate_task.Run(); + + test_task_runner_->SetAutoAdvanceNowToPendingTasks(true); + test_task_runner_->RunUntilIdle(); + + double ratio = static_cast<double>(linear_immediate_task.count()) / + static_cast<double>(quadratic_delayed_task.count()); + + EXPECT_GT(ratio, 0.9); + EXPECT_LT(ratio, 1.1); +} + +TEST_F(TaskQueueManagerTest, ImmediateWorkCanStarveDelayedTasks_SameQueue) { + Initialize(1u); + + QuadraticTask quadratic_immediate_task(runners_[0], base::TimeDelta(), + now_src_.get()); + LinearTask linear_delayed_task( + runners_[0], base::TimeDelta::FromMilliseconds(10), now_src_.get()); + base::Callback<bool()> should_exit = + base::Bind(&ShouldExit, &quadratic_immediate_task, &linear_delayed_task); + + quadratic_immediate_task.SetShouldExit(should_exit); + linear_delayed_task.SetShouldExit(should_exit); + + quadratic_immediate_task.Run(); + linear_delayed_task.Run(); + + test_task_runner_->SetAutoAdvanceNowToPendingTasks(true); + test_task_runner_->RunUntilIdle(); + + double ratio = static_cast<double>(linear_delayed_task.count()) / + static_cast<double>(quadratic_immediate_task.count()); + + // This is by design, we want to enforce a strict ordering in task execution + // where by delayed tasks can not skip ahead of non-delayed work. + EXPECT_GT(ratio, 0.0); + EXPECT_LT(ratio, 0.1); +} + +TEST_F(TaskQueueManagerTest, + DelayedTasksDontStarveNonDelayedWork_DifferentQueue) { + Initialize(2u); + + QuadraticTask quadratic_delayed_task( + runners_[0], base::TimeDelta::FromMilliseconds(10), now_src_.get()); + LinearTask linear_immediate_task(runners_[1], base::TimeDelta(), + now_src_.get()); + base::Callback<bool()> should_exit = + base::Bind(ShouldExit, &quadratic_delayed_task, &linear_immediate_task); + quadratic_delayed_task.SetShouldExit(should_exit); + linear_immediate_task.SetShouldExit(should_exit); + + quadratic_delayed_task.Run(); + linear_immediate_task.Run(); + + test_task_runner_->SetAutoAdvanceNowToPendingTasks(true); + test_task_runner_->RunUntilIdle(); + + double ratio = static_cast<double>(linear_immediate_task.count()) / + static_cast<double>(quadratic_delayed_task.count()); + + EXPECT_GT(ratio, 0.9); + EXPECT_LT(ratio, 1.1); +} + +TEST_F(TaskQueueManagerTest, + ImmediateWorkCanStarveDelayedTasks_DifferentQueue) { + Initialize(2u); + + QuadraticTask quadratic_immediate_task(runners_[0], base::TimeDelta(), + now_src_.get()); + LinearTask linear_delayed_task( + runners_[1], base::TimeDelta::FromMilliseconds(10), now_src_.get()); + base::Callback<bool()> should_exit = + base::Bind(&ShouldExit, &quadratic_immediate_task, &linear_delayed_task); + + quadratic_immediate_task.SetShouldExit(should_exit); + linear_delayed_task.SetShouldExit(should_exit); + + quadratic_immediate_task.Run(); + linear_delayed_task.Run(); + + test_task_runner_->SetAutoAdvanceNowToPendingTasks(true); + test_task_runner_->RunUntilIdle(); + + double ratio = static_cast<double>(linear_delayed_task.count()) / + static_cast<double>(quadratic_immediate_task.count()); + + // This is by design, we want to enforce a strict ordering in task execution + // where by delayed tasks can not skip ahead of non-delayed work. + EXPECT_GT(ratio, 0.0); + EXPECT_LT(ratio, 0.1); +} + } // namespace scheduler
diff --git a/components/scheduler/base/task_queue_selector.cc b/components/scheduler/base/task_queue_selector.cc index 0b65ec3d..c72c33a 100644 --- a/components/scheduler/base/task_queue_selector.cc +++ b/components/scheduler/base/task_queue_selector.cc
@@ -7,12 +7,15 @@ #include "base/logging.h" #include "base/trace_event/trace_event_argument.h" #include "components/scheduler/base/task_queue_impl.h" +#include "components/scheduler/base/work_queue.h" namespace scheduler { namespace internal { TaskQueueSelector::TaskQueueSelector() - : task_queue_sets_(TaskQueue::QUEUE_PRIORITY_COUNT), + : delayed_work_queue_sets_(TaskQueue::QUEUE_PRIORITY_COUNT), + immediate_work_queue_sets_(TaskQueue::QUEUE_PRIORITY_COUNT), + force_select_immediate_(true), starvation_count_(0), task_queue_selector_observer_(nullptr) {} @@ -20,21 +23,29 @@ void TaskQueueSelector::AddQueue(internal::TaskQueueImpl* queue) { DCHECK(main_thread_checker_.CalledOnValidThread()); - task_queue_sets_.AssignQueueToSet(queue, TaskQueue::NORMAL_PRIORITY); + delayed_work_queue_sets_.AssignQueueToSet(queue->delayed_work_queue(), + TaskQueue::NORMAL_PRIORITY); + immediate_work_queue_sets_.AssignQueueToSet(queue->immediate_work_queue(), + TaskQueue::NORMAL_PRIORITY); } void TaskQueueSelector::RemoveQueue(internal::TaskQueueImpl* queue) { DCHECK(main_thread_checker_.CalledOnValidThread()); - task_queue_sets_.RemoveQueue(queue); + delayed_work_queue_sets_.RemoveQueue(queue->delayed_work_queue()); + immediate_work_queue_sets_.RemoveQueue(queue->immediate_work_queue()); } void TaskQueueSelector::SetQueuePriority(internal::TaskQueueImpl* queue, TaskQueue::QueuePriority priority) { DCHECK(main_thread_checker_.CalledOnValidThread()); DCHECK_LT(priority, TaskQueue::QUEUE_PRIORITY_COUNT); + int old_set_index = queue->immediate_work_queue()->work_queue_set_index(); TaskQueue::QueuePriority old_priority = - static_cast<TaskQueue::QueuePriority>(queue->get_task_queue_set_index()); - task_queue_sets_.AssignQueueToSet(queue, priority); + static_cast<TaskQueue::QueuePriority>(old_set_index); + delayed_work_queue_sets_.AssignQueueToSet(queue->delayed_work_queue(), + priority); + immediate_work_queue_sets_.AssignQueueToSet(queue->immediate_work_queue(), + priority); if (task_queue_selector_observer_ && old_priority == TaskQueue::DISABLED_PRIORITY) { task_queue_selector_observer_->OnTaskQueueEnabled(queue); @@ -44,8 +55,9 @@ bool TaskQueueSelector::IsQueueEnabled( const internal::TaskQueueImpl* queue) const { DCHECK(main_thread_checker_.CalledOnValidThread()); - return static_cast<TaskQueue::QueuePriority>( - queue->get_task_queue_set_index()) != TaskQueue::DISABLED_PRIORITY; + size_t set_index = queue->delayed_work_queue()->work_queue_set_index(); + return static_cast<TaskQueue::QueuePriority>(set_index) != + TaskQueue::DISABLED_PRIORITY; } TaskQueue::QueuePriority TaskQueueSelector::NextPriority( @@ -54,23 +66,83 @@ return static_cast<TaskQueue::QueuePriority>(static_cast<int>(priority) + 1); } -bool TaskQueueSelector::ChooseOldestWithPriority( +bool TaskQueueSelector::ChooseOldestImmediateTaskWithPriority( TaskQueue::QueuePriority priority, - internal::TaskQueueImpl** out_queue) const { - return task_queue_sets_.GetOldestQueueInSet(priority, out_queue); + WorkQueue** out_work_queue) const { + return immediate_work_queue_sets_.GetOldestQueueInSet(priority, + out_work_queue); } -bool TaskQueueSelector::SelectQueueToService( - internal::TaskQueueImpl** out_queue) { +bool TaskQueueSelector::ChooseOldestDelayedTaskWithPriority( + TaskQueue::QueuePriority priority, + WorkQueue** out_work_queue) const { + return delayed_work_queue_sets_.GetOldestQueueInSet(priority, out_work_queue); +} + +bool TaskQueueSelector::ChooseOldestImmediateOrDelayedTaskWithPriority( + TaskQueue::QueuePriority priority, + WorkQueue** out_work_queue) const { + WorkQueue* immediate_queue; + if (immediate_work_queue_sets_.GetOldestQueueInSet(priority, + &immediate_queue)) { + WorkQueue* delayed_queue; + if (delayed_work_queue_sets_.GetOldestQueueInSet(priority, + &delayed_queue)) { + int immediate_enqueue_order; + int delayed_enqueue_order; + bool have_immediate_task = + immediate_queue->GetFrontTaskEnqueueOrder(&immediate_enqueue_order); + bool have_delayed_task = + delayed_queue->GetFrontTaskEnqueueOrder(&delayed_enqueue_order); + DCHECK(have_immediate_task); + DCHECK(have_delayed_task); + if (immediate_enqueue_order < delayed_enqueue_order) { + *out_work_queue = immediate_queue; + } else { + *out_work_queue = delayed_queue; + } + } else { + *out_work_queue = immediate_queue; + } + return true; + } else { + if (delayed_work_queue_sets_.GetOldestQueueInSet(priority, + out_work_queue)) { + return true; + } else { + return false; + } + } +} + +bool TaskQueueSelector::ChooseOldestWithPriority( + TaskQueue::QueuePriority priority, + WorkQueue** out_work_queue) const { + if (force_select_immediate_) { + if (ChooseOldestImmediateTaskWithPriority(priority, out_work_queue)) { + return true; + } + if (ChooseOldestDelayedTaskWithPriority(priority, out_work_queue)) { + return true; + } + return false; + } else { + return ChooseOldestImmediateOrDelayedTaskWithPriority(priority, + out_work_queue); + } +} + +bool TaskQueueSelector::SelectWorkQueueToService(WorkQueue** out_work_queue) { DCHECK(main_thread_checker_.CalledOnValidThread()); + force_select_immediate_ = !force_select_immediate_; // Always service the control queue if it has any work. - if (ChooseOldestWithPriority(TaskQueue::CONTROL_PRIORITY, out_queue)) { + if (ChooseOldestWithPriority(TaskQueue::CONTROL_PRIORITY, out_work_queue)) { DidSelectQueueWithPriority(TaskQueue::CONTROL_PRIORITY); return true; } // Select from the normal priority queue if we are starving it. if (starvation_count_ >= kMaxStarvationTasks && - ChooseOldestWithPriority(TaskQueue::NORMAL_PRIORITY, out_queue)) { + ChooseOldestWithPriority(TaskQueue::NORMAL_PRIORITY, out_work_queue)) { DidSelectQueueWithPriority(TaskQueue::NORMAL_PRIORITY); return true; } @@ -78,7 +150,7 @@ for (TaskQueue::QueuePriority priority = TaskQueue::HIGH_PRIORITY; priority < TaskQueue::DISABLED_PRIORITY; priority = NextPriority(priority)) { - if (ChooseOldestWithPriority(priority, out_queue)) { + if (ChooseOldestWithPriority(priority, out_work_queue)) { DidSelectQueueWithPriority(priority); return true; } @@ -107,6 +179,7 @@ base::trace_event::TracedValue* state) const { DCHECK(main_thread_checker_.CalledOnValidThread()); state->SetInteger("starvation_count", starvation_count_); + state->SetBoolean("try_delayed_first", force_select_immediate_); } void TaskQueueSelector::SetTaskQueueSelectorObserver(Observer* observer) { @@ -117,11 +190,18 @@ for (TaskQueue::QueuePriority priority = TaskQueue::HIGH_PRIORITY; priority < TaskQueue::DISABLED_PRIORITY; priority = NextPriority(priority)) { - if (!task_queue_sets_.IsSetEmpty(priority)) + if (!delayed_work_queue_sets_.IsSetEmpty(priority) || + !immediate_work_queue_sets_.IsSetEmpty(priority)) { return false; + } } return true; } +void TaskQueueSelector::SetForceSelectImmediateForTest( + bool force_select_immediate) { + force_select_immediate_ = force_select_immediate; +} + } // namespace internal } // namespace scheduler
diff --git a/components/scheduler/base/task_queue_selector.h b/components/scheduler/base/task_queue_selector.h index 59e1349..2093528 100644 --- a/components/scheduler/base/task_queue_selector.h +++ b/components/scheduler/base/task_queue_selector.h
@@ -10,7 +10,7 @@ #include "base/compiler_specific.h" #include "base/pending_task.h" #include "base/threading/thread_checker.h" -#include "components/scheduler/base/task_queue_sets.h" +#include "components/scheduler/base/work_queue_sets.h" #include "components/scheduler/scheduler_export.h" namespace scheduler { @@ -39,11 +39,11 @@ void RemoveQueue(internal::TaskQueueImpl* queue); // Called to choose the work queue from which the next task should be taken - // and run. Return true if |out_queue| indicates the queue to service or + // and run. Return true if |out_work_queue| indicates the queue to service or // false to avoid running any task. // // This function is called on the main thread. - bool SelectQueueToService(internal::TaskQueueImpl** out_queue); + bool SelectWorkQueueToService(WorkQueue** out_work_queue); // Serialize the selector state for tracing. void AsValueInto(base::trace_event::TracedValue* state) const; @@ -60,22 +60,38 @@ // on the main thread. If |observer| is null, then no callbacks will occur. void SetTaskQueueSelectorObserver(Observer* observer); - TaskQueueSets* GetTaskQueueSets() { return &task_queue_sets_; } + WorkQueueSets* delayed_task_queue_sets() { return &delayed_work_queue_sets_; } + WorkQueueSets* immediate_task_queue_sets() { + return &immediate_work_queue_sets_; + } // Returns true if all the enabled work queues are empty. Returns false // otherwise. bool EnabledWorkQueuesEmpty() const; + protected: + // Return true if |out_queue| contains the queue with the oldest pending task + // from the set of queues of |priority|, or false if all queues of that + // priority are empty. + bool ChooseOldestWithPriority(TaskQueue::QueuePriority priority, + WorkQueue** out_work_queue) const; + + void SetForceSelectImmediateForTest(bool force_select_immediate); + private: // Returns the priority which is next after |priority|. static TaskQueue::QueuePriority NextPriority( TaskQueue::QueuePriority priority); - // Return true if |out_queue| contains the queue with the oldest pending task - // from the set of queues of |priority|, or false if all queues of that - // priority are empty. - bool ChooseOldestWithPriority(TaskQueue::QueuePriority priority, - internal::TaskQueueImpl** out_queue) const; + bool ChooseOldestImmediateTaskWithPriority(TaskQueue::QueuePriority priority, + WorkQueue** out_work_queue) const; + + bool ChooseOldestDelayedTaskWithPriority(TaskQueue::QueuePriority priority, + WorkQueue** out_work_queue) const; + + bool ChooseOldestImmediateOrDelayedTaskWithPriority( + TaskQueue::QueuePriority priority, + WorkQueue** out_work_queue) const; // Called whenever the selector chooses a task queue for execution with the // priority |priority|. @@ -86,8 +102,11 @@ // TODO(rmcilroy): Check if this is a good value. static const size_t kMaxStarvationTasks = 5; + private: base::ThreadChecker main_thread_checker_; - TaskQueueSets task_queue_sets_; + WorkQueueSets delayed_work_queue_sets_; + WorkQueueSets immediate_work_queue_sets_; + bool force_select_immediate_; size_t starvation_count_; Observer* task_queue_selector_observer_; // NOT OWNED
diff --git a/components/scheduler/base/task_queue_selector_unittest.cc b/components/scheduler/base/task_queue_selector_unittest.cc index da64fac..6eb4457 100644 --- a/components/scheduler/base/task_queue_selector_unittest.cc +++ b/components/scheduler/base/task_queue_selector_unittest.cc
@@ -8,8 +8,9 @@ #include "base/memory/scoped_ptr.h" #include "base/pending_task.h" #include "components/scheduler/base/task_queue_impl.h" -#include "components/scheduler/base/task_queue_sets.h" #include "components/scheduler/base/virtual_time_domain.h" +#include "components/scheduler/base/work_queue.h" +#include "components/scheduler/base/work_queue_sets.h" #include "testing/gmock/include/gmock/gmock.h" #include "testing/gtest/include/gtest/gtest.h" @@ -29,44 +30,57 @@ DISALLOW_COPY_AND_ASSIGN(MockObserver); }; +class TaskQueueSelectorForTest : public TaskQueueSelector { + public: + using TaskQueueSelector::ChooseOldestWithPriority; + using TaskQueueSelector::SetForceSelectImmediateForTest; +}; + class TaskQueueSelectorTest : public testing::Test { public: TaskQueueSelectorTest() : test_closure_(base::Bind(&TaskQueueSelectorTest::TestFunction)) {} ~TaskQueueSelectorTest() override {} - std::vector<TaskQueueImpl::Task> GetTasks(int count) { - std::vector<TaskQueueImpl::Task> tasks; - for (int i = 0; i < count; i++) { - TaskQueueImpl::Task task(FROM_HERE, test_closure_, 0, true); - task.set_enqueue_order(i); - tasks.push_back(task); - } - return tasks; - } - - void PushTasks(const std::vector<TaskQueueImpl::Task>& tasks, - const size_t queue_indices[]) { + void PushTasks(const size_t queue_indices[], size_t num_tasks) { std::set<size_t> changed_queue_set; - for (size_t i = 0; i < tasks.size(); i++) { + for (size_t i = 0; i < num_tasks; i++) { changed_queue_set.insert(queue_indices[i]); - task_queues_[queue_indices[i]]->PushTaskOntoWorkQueueForTest(tasks[i]); + task_queues_[queue_indices[i]]->immediate_work_queue()->PushTaskForTest( + TaskQueueImpl::Task(FROM_HERE, test_closure_, base::TimeTicks(), 0, + true, i)); } for (size_t queue_index : changed_queue_set) { - selector_.GetTaskQueueSets()->OnPushQueue( - task_queues_[queue_index].get()); + selector_.immediate_task_queue_sets()->OnPushQueue( + task_queues_[queue_index]->immediate_work_queue()); + } + } + + void PushTasksWithEnqueueOrder(const size_t queue_indices[], + const size_t enqueue_orders[], + size_t num_tasks) { + std::set<size_t> changed_queue_set; + for (size_t i = 0; i < num_tasks; i++) { + changed_queue_set.insert(queue_indices[i]); + task_queues_[queue_indices[i]]->immediate_work_queue()->PushTaskForTest( + TaskQueueImpl::Task(FROM_HERE, test_closure_, base::TimeTicks(), 0, + true, enqueue_orders[i])); + } + for (size_t queue_index : changed_queue_set) { + selector_.immediate_task_queue_sets()->OnPushQueue( + task_queues_[queue_index]->immediate_work_queue()); } } std::vector<size_t> PopTasks() { std::vector<size_t> order; - TaskQueueImpl* chosen_queue; - while (selector_.SelectQueueToService(&chosen_queue)) { + WorkQueue* chosen_work_queue; + while (selector_.SelectWorkQueueToService(&chosen_work_queue)) { size_t chosen_queue_index = - queue_to_index_map_.find(chosen_queue)->second; + queue_to_index_map_.find(chosen_work_queue->task_queue())->second; order.push_back(chosen_queue_index); - chosen_queue->PopTaskFromWorkQueueForTest(); - selector_.GetTaskQueueSets()->OnPopQueue(chosen_queue); + chosen_work_queue->PopTaskForTest(); + selector_.immediate_task_queue_sets()->OnPopQueue(chosen_work_queue); } return order; } @@ -92,31 +106,28 @@ const size_t kTaskQueueCount = 5; base::Closure test_closure_; - TaskQueueSelector selector_; + TaskQueueSelectorForTest selector_; scoped_ptr<VirtualTimeDomain> virtual_time_domain_; std::vector<scoped_refptr<TaskQueueImpl>> task_queues_; std::map<TaskQueueImpl*, size_t> queue_to_index_map_; }; TEST_F(TaskQueueSelectorTest, TestDefaultPriority) { - std::vector<TaskQueueImpl::Task> tasks = GetTasks(5); size_t queue_order[] = {4, 3, 2, 1, 0}; - PushTasks(tasks, queue_order); + PushTasks(queue_order, 5); EXPECT_THAT(PopTasks(), testing::ElementsAre(4, 3, 2, 1, 0)); } TEST_F(TaskQueueSelectorTest, TestHighPriority) { - std::vector<TaskQueueImpl::Task> tasks = GetTasks(5); size_t queue_order[] = {0, 1, 2, 3, 4}; - PushTasks(tasks, queue_order); + PushTasks(queue_order, 5); selector_.SetQueuePriority(task_queues_[2].get(), TaskQueue::HIGH_PRIORITY); EXPECT_THAT(PopTasks(), testing::ElementsAre(2, 0, 1, 3, 4)); } TEST_F(TaskQueueSelectorTest, TestBestEffortPriority) { - std::vector<TaskQueueImpl::Task> tasks = GetTasks(5); size_t queue_order[] = {0, 1, 2, 3, 4}; - PushTasks(tasks, queue_order); + PushTasks(queue_order, 5); selector_.SetQueuePriority(task_queues_[0].get(), TaskQueue::BEST_EFFORT_PRIORITY); selector_.SetQueuePriority(task_queues_[2].get(), TaskQueue::HIGH_PRIORITY); @@ -124,9 +135,8 @@ } TEST_F(TaskQueueSelectorTest, TestControlPriority) { - std::vector<TaskQueueImpl::Task> tasks = GetTasks(5); size_t queue_order[] = {0, 1, 2, 3, 4}; - PushTasks(tasks, queue_order); + PushTasks(queue_order, 5); selector_.SetQueuePriority(task_queues_[4].get(), TaskQueue::CONTROL_PRIORITY); EXPECT_TRUE(selector_.IsQueueEnabled(task_queues_[4].get())); @@ -157,9 +167,8 @@ MockObserver mock_observer; selector_.SetTaskQueueSelectorObserver(&mock_observer); - std::vector<TaskQueueImpl::Task> tasks = GetTasks(5); size_t queue_order[] = {0, 1, 2, 3, 4}; - PushTasks(tasks, queue_order); + PushTasks(queue_order, 5); selector_.SetQueuePriority(task_queues_[2].get(), TaskQueue::DISABLED_PRIORITY); EXPECT_FALSE(selector_.IsQueueEnabled(task_queues_[2].get())); @@ -177,61 +186,53 @@ } TEST_F(TaskQueueSelectorTest, TestEmptyQueues) { - TaskQueueImpl* chosen_queue = nullptr; - EXPECT_FALSE(selector_.SelectQueueToService(&chosen_queue)); + WorkQueue* chosen_work_queue = nullptr; + EXPECT_FALSE(selector_.SelectWorkQueueToService(&chosen_work_queue)); // Test only disabled queues. - std::vector<TaskQueueImpl::Task> tasks = GetTasks(1); size_t queue_order[] = {0}; - PushTasks(tasks, queue_order); + PushTasks(queue_order, 1); selector_.SetQueuePriority(task_queues_[0].get(), TaskQueue::DISABLED_PRIORITY); EXPECT_FALSE(selector_.IsQueueEnabled(task_queues_[0].get())); - EXPECT_FALSE(selector_.SelectQueueToService(&chosen_queue)); + EXPECT_FALSE(selector_.SelectWorkQueueToService(&chosen_work_queue)); } TEST_F(TaskQueueSelectorTest, TestAge) { - std::vector<TaskQueueImpl::Task> tasks; - int enqueue_order[] = {10, 1, 2, 9, 4}; - for (int i = 0; i < 5; i++) { - TaskQueueImpl::Task task(FROM_HERE, test_closure_, 0, true); - task.set_enqueue_order(enqueue_order[i]); - tasks.push_back(task); - } + size_t enqueue_order[] = {10, 1, 2, 9, 4}; size_t queue_order[] = {0, 1, 2, 3, 4}; - PushTasks(tasks, queue_order); + PushTasksWithEnqueueOrder(queue_order, enqueue_order, 5); EXPECT_THAT(PopTasks(), testing::ElementsAre(1, 2, 4, 3, 0)); } TEST_F(TaskQueueSelectorTest, TestControlStarvesOthers) { - std::vector<TaskQueueImpl::Task> tasks = GetTasks(4); size_t queue_order[] = {0, 1, 2, 3}; - PushTasks(tasks, queue_order); + PushTasks(queue_order, 4); selector_.SetQueuePriority(task_queues_[3].get(), TaskQueue::CONTROL_PRIORITY); selector_.SetQueuePriority(task_queues_[2].get(), TaskQueue::HIGH_PRIORITY); selector_.SetQueuePriority(task_queues_[1].get(), TaskQueue::BEST_EFFORT_PRIORITY); for (int i = 0; i < 100; i++) { - TaskQueueImpl* chosen_queue = nullptr; - EXPECT_TRUE(selector_.SelectQueueToService(&chosen_queue)); - EXPECT_EQ(task_queues_[3].get(), chosen_queue); + WorkQueue* chosen_work_queue = nullptr; + EXPECT_TRUE(selector_.SelectWorkQueueToService(&chosen_work_queue)); + EXPECT_EQ(task_queues_[3].get(), chosen_work_queue->task_queue()); // Don't remove task from queue to simulate all queues still being full. } } TEST_F(TaskQueueSelectorTest, TestHighPriorityDoesNotStarveNormal) { - std::vector<TaskQueueImpl::Task> tasks = GetTasks(3); size_t queue_order[] = {0, 1, 2}; - PushTasks(tasks, queue_order); + PushTasks(queue_order, 3); selector_.SetQueuePriority(task_queues_[2].get(), TaskQueue::HIGH_PRIORITY); selector_.SetQueuePriority(task_queues_[1].get(), TaskQueue::BEST_EFFORT_PRIORITY); size_t counts[] = {0, 0, 0}; for (int i = 0; i < 100; i++) { - TaskQueueImpl* chosen_queue = nullptr; - EXPECT_TRUE(selector_.SelectQueueToService(&chosen_queue)); - size_t chosen_queue_index = queue_to_index_map_.find(chosen_queue)->second; + WorkQueue* chosen_work_queue = nullptr; + EXPECT_TRUE(selector_.SelectWorkQueueToService(&chosen_work_queue)); + size_t chosen_queue_index = + queue_to_index_map_.find(chosen_work_queue->task_queue())->second; counts[chosen_queue_index]++; // Don't remove task from queue to simulate all queues still being full. } @@ -241,29 +242,28 @@ } TEST_F(TaskQueueSelectorTest, TestBestEffortGetsStarved) { - std::vector<TaskQueueImpl::Task> tasks = GetTasks(2); size_t queue_order[] = {0, 1}; - PushTasks(tasks, queue_order); + PushTasks(queue_order, 2); selector_.SetQueuePriority(task_queues_[0].get(), TaskQueue::BEST_EFFORT_PRIORITY); selector_.SetQueuePriority(task_queues_[1].get(), TaskQueue::NORMAL_PRIORITY); - TaskQueueImpl* chosen_queue = nullptr; + WorkQueue* chosen_work_queue = nullptr; for (int i = 0; i < 100; i++) { - EXPECT_TRUE(selector_.SelectQueueToService(&chosen_queue)); - EXPECT_EQ(task_queues_[1].get(), chosen_queue); + EXPECT_TRUE(selector_.SelectWorkQueueToService(&chosen_work_queue)); + EXPECT_EQ(task_queues_[1].get(), chosen_work_queue->task_queue()); // Don't remove task from queue to simulate all queues still being full. } selector_.SetQueuePriority(task_queues_[1].get(), TaskQueue::HIGH_PRIORITY); for (int i = 0; i < 100; i++) { - EXPECT_TRUE(selector_.SelectQueueToService(&chosen_queue)); - EXPECT_EQ(task_queues_[1].get(), chosen_queue); + EXPECT_TRUE(selector_.SelectWorkQueueToService(&chosen_work_queue)); + EXPECT_EQ(task_queues_[1].get(), chosen_work_queue->task_queue()); // Don't remove task from queue to simulate all queues still being full. } selector_.SetQueuePriority(task_queues_[1].get(), TaskQueue::CONTROL_PRIORITY); for (int i = 0; i < 100; i++) { - EXPECT_TRUE(selector_.SelectQueueToService(&chosen_queue)); - EXPECT_EQ(task_queues_[1].get(), chosen_queue); + EXPECT_TRUE(selector_.SelectWorkQueueToService(&chosen_work_queue)); + EXPECT_EQ(task_queues_[1].get(), chosen_work_queue->task_queue()); // Don't remove task from queue to simulate all queues still being full. } } @@ -274,14 +274,90 @@ TEST_F(TaskQueueSelectorTest, EnabledWorkQueuesEmpty) { EXPECT_TRUE(selector_.EnabledWorkQueuesEmpty()); - std::vector<TaskQueueImpl::Task> tasks = GetTasks(2); size_t queue_order[] = {0, 1}; - PushTasks(tasks, queue_order); + PushTasks(queue_order, 2); EXPECT_FALSE(selector_.EnabledWorkQueuesEmpty()); PopTasks(); EXPECT_TRUE(selector_.EnabledWorkQueuesEmpty()); } +TEST_F(TaskQueueSelectorTest, ChooseOldestWithPriority_Empty) { + WorkQueue* chosen_work_queue = nullptr; + EXPECT_FALSE(selector_.ChooseOldestWithPriority(TaskQueue::NORMAL_PRIORITY, + &chosen_work_queue)); +} + +TEST_F(TaskQueueSelectorTest, ChooseOldestWithPriority_OnlyDelayed) { + task_queues_[0]->delayed_work_queue()->PushTaskForTest(TaskQueueImpl::Task( + FROM_HERE, test_closure_, base::TimeTicks(), 0, true, 0)); + selector_.delayed_task_queue_sets()->OnPushQueue( + task_queues_[0]->delayed_work_queue()); + + WorkQueue* chosen_work_queue = nullptr; + EXPECT_TRUE(selector_.ChooseOldestWithPriority(TaskQueue::NORMAL_PRIORITY, + &chosen_work_queue)); + EXPECT_EQ(chosen_work_queue, task_queues_[0]->delayed_work_queue()); +} + +TEST_F(TaskQueueSelectorTest, ChooseOldestWithPriority_OnlyImmediate) { + task_queues_[0]->immediate_work_queue()->PushTaskForTest(TaskQueueImpl::Task( + FROM_HERE, test_closure_, base::TimeTicks(), 0, true, 0)); + selector_.immediate_task_queue_sets()->OnPushQueue( + task_queues_[0]->immediate_work_queue()); + + WorkQueue* chosen_work_queue = nullptr; + EXPECT_TRUE(selector_.ChooseOldestWithPriority(TaskQueue::NORMAL_PRIORITY, + &chosen_work_queue)); + EXPECT_EQ(chosen_work_queue, task_queues_[0]->immediate_work_queue()); +} + +struct ChooseOldestWithPriorityTestParam { + int delayed_task_enqueue_order; + int immediate_task_enqueue_order; + bool force_select_immediate; + const char* expected_work_queue_name; +}; + +static const ChooseOldestWithPriorityTestParam + kChooseOldestWithPriorityTestCases[] = { + {1, 2, false, "delayed"}, + {1, 2, true, "immediate"}, + {2, 1, false, "immediate"}, + {2, 1, true, "immediate"}, +}; + +class ChooseOldestWithPriorityTest + : public TaskQueueSelectorTest, + public testing::WithParamInterface<ChooseOldestWithPriorityTestParam> {}; + +TEST_P(ChooseOldestWithPriorityTest, RoundRobinTest) { + task_queues_[0]->immediate_work_queue()->PushTaskForTest( + TaskQueueImpl::Task(FROM_HERE, test_closure_, base::TimeTicks(), + GetParam().immediate_task_enqueue_order, true, + GetParam().immediate_task_enqueue_order)); + selector_.immediate_task_queue_sets()->OnPushQueue( + task_queues_[0]->immediate_work_queue()); + + task_queues_[0]->delayed_work_queue()->PushTaskForTest( + TaskQueueImpl::Task(FROM_HERE, test_closure_, base::TimeTicks(), + GetParam().delayed_task_enqueue_order, true, + GetParam().delayed_task_enqueue_order)); + selector_.delayed_task_queue_sets()->OnPushQueue( + task_queues_[0]->delayed_work_queue()); + + selector_.SetForceSelectImmediateForTest(GetParam().force_select_immediate); + + WorkQueue* chosen_work_queue = nullptr; + EXPECT_TRUE(selector_.ChooseOldestWithPriority(TaskQueue::NORMAL_PRIORITY, + &chosen_work_queue)); + EXPECT_EQ(chosen_work_queue->task_queue(), task_queues_[0].get()); + EXPECT_STREQ(chosen_work_queue->name(), GetParam().expected_work_queue_name); +} + +INSTANTIATE_TEST_CASE_P(ChooseOldestWithPriorityTest, + ChooseOldestWithPriorityTest, + testing::ValuesIn(kChooseOldestWithPriorityTestCases)); + } // namespace internal } // namespace scheduler
diff --git a/components/scheduler/base/task_queue_sets.cc b/components/scheduler/base/task_queue_sets.cc deleted file mode 100644 index 9463823f..0000000 --- a/components/scheduler/base/task_queue_sets.cc +++ /dev/null
@@ -1,96 +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. - -#include "components/scheduler/base/task_queue_sets.h" - -#include "base/logging.h" -#include "components/scheduler/base/task_queue_impl.h" - -namespace scheduler { -namespace internal { - -TaskQueueSets::TaskQueueSets(size_t num_sets) - : enqueue_order_to_queue_maps_(num_sets) {} - -TaskQueueSets::~TaskQueueSets() {} - -void TaskQueueSets::RemoveQueue(internal::TaskQueueImpl* queue) { - int enqueue_order; - bool has_enqueue_order = - queue->GetWorkQueueFrontTaskEnqueueOrder(&enqueue_order); - if (!has_enqueue_order) - return; - size_t set_index = queue->get_task_queue_set_index(); - DCHECK_LT(set_index, enqueue_order_to_queue_maps_.size()); - DCHECK_EQ( - queue, - enqueue_order_to_queue_maps_[set_index].find(enqueue_order)->second); - enqueue_order_to_queue_maps_[set_index].erase(enqueue_order); -} - -void TaskQueueSets::AssignQueueToSet(internal::TaskQueueImpl* queue, - size_t set_index) { - DCHECK_LT(set_index, enqueue_order_to_queue_maps_.size()); - int enqueue_order; - bool has_enqueue_order = - queue->GetWorkQueueFrontTaskEnqueueOrder(&enqueue_order); - size_t old_set = queue->get_task_queue_set_index(); - DCHECK_LT(old_set, enqueue_order_to_queue_maps_.size()); - queue->set_task_queue_set_index(set_index); - if (!has_enqueue_order) - return; - enqueue_order_to_queue_maps_[old_set].erase(enqueue_order); - enqueue_order_to_queue_maps_[set_index].insert( - std::make_pair(enqueue_order, queue)); -} - -void TaskQueueSets::OnPushQueue(internal::TaskQueueImpl* queue) { - int enqueue_order; - bool has_enqueue_order = - queue->GetWorkQueueFrontTaskEnqueueOrder(&enqueue_order); - DCHECK(has_enqueue_order); - size_t set_index = queue->get_task_queue_set_index(); - DCHECK_LT(set_index, enqueue_order_to_queue_maps_.size()) << " set_index = " - << set_index; - enqueue_order_to_queue_maps_[set_index].insert( - std::make_pair(enqueue_order, queue)); -} - -void TaskQueueSets::OnPopQueue(internal::TaskQueueImpl* queue) { - size_t set_index = queue->get_task_queue_set_index(); - DCHECK_LT(set_index, enqueue_order_to_queue_maps_.size()); - DCHECK(!enqueue_order_to_queue_maps_[set_index].empty()) << " set_index = " - << set_index; - DCHECK_EQ(enqueue_order_to_queue_maps_[set_index].begin()->second, queue) - << " set_index = " << set_index; - // O(1) amortised. - enqueue_order_to_queue_maps_[set_index].erase( - enqueue_order_to_queue_maps_[set_index].begin()); - int enqueue_order; - bool has_enqueue_order = - queue->GetWorkQueueFrontTaskEnqueueOrder(&enqueue_order); - if (!has_enqueue_order) - return; - enqueue_order_to_queue_maps_[set_index].insert( - std::make_pair(enqueue_order, queue)); -} - -bool TaskQueueSets::GetOldestQueueInSet( - size_t set_index, - internal::TaskQueueImpl** out_queue) const { - DCHECK_LT(set_index, enqueue_order_to_queue_maps_.size()); - if (enqueue_order_to_queue_maps_[set_index].empty()) - return false; - *out_queue = enqueue_order_to_queue_maps_[set_index].begin()->second; - return true; -} - -bool TaskQueueSets::IsSetEmpty(size_t set_index) const { - DCHECK_LT(set_index, enqueue_order_to_queue_maps_.size()) << " set_index = " - << set_index; - return enqueue_order_to_queue_maps_[set_index].empty(); -} - -} // namespace internal -} // namespace scheduler
diff --git a/components/scheduler/base/task_queue_sets_unittest.cc b/components/scheduler/base/task_queue_sets_unittest.cc deleted file mode 100644 index 8d42503a..0000000 --- a/components/scheduler/base/task_queue_sets_unittest.cc +++ /dev/null
@@ -1,248 +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. - -#include "components/scheduler/base/task_queue_sets.h" - -#include "components/scheduler/base/task_queue_impl.h" -#include "components/scheduler/base/virtual_time_domain.h" -#include "testing/gmock/include/gmock/gmock.h" - -namespace scheduler { -class TimeDomain; - -namespace internal { - -class TaskQueueSetsTest : public testing::Test { - public: - void SetUp() override { - virtual_time_domain_ = make_scoped_ptr<VirtualTimeDomain>( - new VirtualTimeDomain(nullptr, base::TimeTicks())); - task_queue_sets_.reset(new TaskQueueSets(kNumSets)); - } - - protected: - enum { - kNumSets = 5 // An arbitary choice. - }; - - TaskQueueImpl* NewTaskQueue(const char* queue_name) { - scoped_refptr<internal::TaskQueueImpl> queue = - make_scoped_refptr(new internal::TaskQueueImpl( - nullptr, virtual_time_domain_.get(), TaskQueue::Spec(queue_name), - "test", "test")); - task_queues_.push_back(queue); - return queue.get(); - } - - TaskQueueImpl::Task FakeTaskWithEnqueueOrder(int enqueue_order) { - TaskQueueImpl::Task fake_task(FROM_HERE, base::Closure(), 0, true); - fake_task.set_enqueue_order(enqueue_order); - return fake_task; - } - - scoped_ptr<VirtualTimeDomain> virtual_time_domain_; - std::vector<scoped_refptr<internal::TaskQueueImpl>> task_queues_; - scoped_ptr<TaskQueueSets> task_queue_sets_; -}; - -TEST_F(TaskQueueSetsTest, AssignQueueToSet) { - internal::TaskQueueImpl* queue = NewTaskQueue("queue"); - size_t set = TaskQueue::NORMAL_PRIORITY; - task_queue_sets_->AssignQueueToSet(queue, set); - - EXPECT_EQ(set, queue->get_task_queue_set_index()); -} - -TEST_F(TaskQueueSetsTest, GetOldestQueueInSet_QueueEmpty) { - internal::TaskQueueImpl* queue = NewTaskQueue("queue"); - size_t set = TaskQueue::NORMAL_PRIORITY; - task_queue_sets_->AssignQueueToSet(queue, set); - - internal::TaskQueueImpl* selected_queue; - EXPECT_FALSE(task_queue_sets_->GetOldestQueueInSet(set, &selected_queue)); -} - -TEST_F(TaskQueueSetsTest, OnPushQueue) { - internal::TaskQueueImpl* queue = NewTaskQueue("queue"); - size_t set = TaskQueue::NORMAL_PRIORITY; - task_queue_sets_->AssignQueueToSet(queue, set); - - internal::TaskQueueImpl* selected_queue; - EXPECT_FALSE(task_queue_sets_->GetOldestQueueInSet(set, &selected_queue)); - - queue->PushTaskOntoWorkQueueForTest(FakeTaskWithEnqueueOrder(10)); - task_queue_sets_->OnPushQueue(queue); - - EXPECT_TRUE(task_queue_sets_->GetOldestQueueInSet(set, &selected_queue)); - EXPECT_EQ(queue, selected_queue); -} - -TEST_F(TaskQueueSetsTest, GetOldestQueueInSet_SingleTaskInSet) { - internal::TaskQueueImpl* queue = NewTaskQueue("queue"); - queue->PushTaskOntoWorkQueueForTest(FakeTaskWithEnqueueOrder(10)); - size_t set = 1; - task_queue_sets_->AssignQueueToSet(queue, set); - - internal::TaskQueueImpl* selected_queue; - EXPECT_TRUE(task_queue_sets_->GetOldestQueueInSet(set, &selected_queue)); - EXPECT_EQ(queue, selected_queue); -} - -TEST_F(TaskQueueSetsTest, GetOldestQueueInSet_MultipleAgesInSet) { - internal::TaskQueueImpl* queue1 = NewTaskQueue("queue1"); - internal::TaskQueueImpl* queue2 = NewTaskQueue("queue2"); - internal::TaskQueueImpl* queue3 = NewTaskQueue("queue2"); - queue1->PushTaskOntoWorkQueueForTest(FakeTaskWithEnqueueOrder(6)); - queue2->PushTaskOntoWorkQueueForTest(FakeTaskWithEnqueueOrder(5)); - queue3->PushTaskOntoWorkQueueForTest(FakeTaskWithEnqueueOrder(4)); - size_t set = 2; - task_queue_sets_->AssignQueueToSet(queue1, set); - task_queue_sets_->AssignQueueToSet(queue2, set); - task_queue_sets_->AssignQueueToSet(queue3, set); - - internal::TaskQueueImpl* selected_queue; - EXPECT_TRUE(task_queue_sets_->GetOldestQueueInSet(set, &selected_queue)); - EXPECT_EQ(queue3, selected_queue); -} - -TEST_F(TaskQueueSetsTest, OnPopQueue) { - internal::TaskQueueImpl* queue1 = NewTaskQueue("queue1"); - internal::TaskQueueImpl* queue2 = NewTaskQueue("queue2"); - internal::TaskQueueImpl* queue3 = NewTaskQueue("queue3"); - queue1->PushTaskOntoWorkQueueForTest(FakeTaskWithEnqueueOrder(6)); - queue2->PushTaskOntoWorkQueueForTest(FakeTaskWithEnqueueOrder(3)); - queue2->PushTaskOntoWorkQueueForTest(FakeTaskWithEnqueueOrder(1)); - queue3->PushTaskOntoWorkQueueForTest(FakeTaskWithEnqueueOrder(4)); - size_t set = 3; - task_queue_sets_->AssignQueueToSet(queue1, set); - task_queue_sets_->AssignQueueToSet(queue2, set); - task_queue_sets_->AssignQueueToSet(queue3, set); - - internal::TaskQueueImpl* selected_queue; - EXPECT_TRUE(task_queue_sets_->GetOldestQueueInSet(set, &selected_queue)); - EXPECT_EQ(queue2, selected_queue); - - queue2->PopTaskFromWorkQueueForTest(); - task_queue_sets_->OnPopQueue(queue2); - - EXPECT_TRUE(task_queue_sets_->GetOldestQueueInSet(set, &selected_queue)); - EXPECT_EQ(queue2, selected_queue); -} - -TEST_F(TaskQueueSetsTest, OnPopQueue_QueueBecomesEmpty) { - internal::TaskQueueImpl* queue1 = NewTaskQueue("queue"); - internal::TaskQueueImpl* queue2 = NewTaskQueue("queue"); - internal::TaskQueueImpl* queue3 = NewTaskQueue("queue"); - queue1->PushTaskOntoWorkQueueForTest(FakeTaskWithEnqueueOrder(6)); - queue2->PushTaskOntoWorkQueueForTest(FakeTaskWithEnqueueOrder(5)); - queue3->PushTaskOntoWorkQueueForTest(FakeTaskWithEnqueueOrder(4)); - size_t set = 4; - task_queue_sets_->AssignQueueToSet(queue1, set); - task_queue_sets_->AssignQueueToSet(queue2, set); - task_queue_sets_->AssignQueueToSet(queue3, set); - - internal::TaskQueueImpl* selected_queue; - EXPECT_TRUE(task_queue_sets_->GetOldestQueueInSet(set, &selected_queue)); - EXPECT_EQ(queue3, selected_queue); - - queue3->PopTaskFromWorkQueueForTest(); - task_queue_sets_->OnPopQueue(queue3); - - EXPECT_TRUE(task_queue_sets_->GetOldestQueueInSet(set, &selected_queue)); - EXPECT_EQ(queue2, selected_queue); -} - -TEST_F(TaskQueueSetsTest, - GetOldestQueueInSet_MultipleAgesInSetIntegerRollover) { - internal::TaskQueueImpl* queue1 = NewTaskQueue("queue1"); - internal::TaskQueueImpl* queue2 = NewTaskQueue("queue2"); - internal::TaskQueueImpl* queue3 = NewTaskQueue("queue3"); - queue1->PushTaskOntoWorkQueueForTest(FakeTaskWithEnqueueOrder(0x7ffffff1)); - queue2->PushTaskOntoWorkQueueForTest(FakeTaskWithEnqueueOrder(0x7ffffff0)); - queue3->PushTaskOntoWorkQueueForTest(FakeTaskWithEnqueueOrder(-0x7ffffff1)); - size_t set = 0; - task_queue_sets_->AssignQueueToSet(queue1, set); - task_queue_sets_->AssignQueueToSet(queue2, set); - task_queue_sets_->AssignQueueToSet(queue3, set); - - internal::TaskQueueImpl* selected_queue; - EXPECT_TRUE(task_queue_sets_->GetOldestQueueInSet(set, &selected_queue)); - EXPECT_EQ(queue2, selected_queue); -} - -TEST_F(TaskQueueSetsTest, GetOldestQueueInSet_MultipleAgesInSet_RemoveQueue) { - internal::TaskQueueImpl* queue1 = NewTaskQueue("queue1"); - internal::TaskQueueImpl* queue2 = NewTaskQueue("queue2"); - internal::TaskQueueImpl* queue3 = NewTaskQueue("queue3"); - queue1->PushTaskOntoWorkQueueForTest(FakeTaskWithEnqueueOrder(6)); - queue2->PushTaskOntoWorkQueueForTest(FakeTaskWithEnqueueOrder(5)); - queue3->PushTaskOntoWorkQueueForTest(FakeTaskWithEnqueueOrder(4)); - size_t set = 1; - task_queue_sets_->AssignQueueToSet(queue1, set); - task_queue_sets_->AssignQueueToSet(queue2, set); - task_queue_sets_->AssignQueueToSet(queue3, set); - task_queue_sets_->RemoveQueue(queue3); - - internal::TaskQueueImpl* selected_queue; - EXPECT_TRUE(task_queue_sets_->GetOldestQueueInSet(set, &selected_queue)); - EXPECT_EQ(queue2, selected_queue); -} - -TEST_F(TaskQueueSetsTest, AssignQueueToSet_Complex) { - internal::TaskQueueImpl* queue1 = NewTaskQueue("queue1"); - internal::TaskQueueImpl* queue2 = NewTaskQueue("queue2"); - internal::TaskQueueImpl* queue3 = NewTaskQueue("queue3"); - internal::TaskQueueImpl* queue4 = NewTaskQueue("queue4"); - queue1->PushTaskOntoWorkQueueForTest(FakeTaskWithEnqueueOrder(6)); - queue2->PushTaskOntoWorkQueueForTest(FakeTaskWithEnqueueOrder(5)); - queue3->PushTaskOntoWorkQueueForTest(FakeTaskWithEnqueueOrder(4)); - queue4->PushTaskOntoWorkQueueForTest(FakeTaskWithEnqueueOrder(3)); - size_t set1 = 1; - size_t set2 = 2; - task_queue_sets_->AssignQueueToSet(queue1, set1); - task_queue_sets_->AssignQueueToSet(queue2, set1); - task_queue_sets_->AssignQueueToSet(queue3, set2); - task_queue_sets_->AssignQueueToSet(queue4, set2); - - internal::TaskQueueImpl* selected_queue; - EXPECT_TRUE(task_queue_sets_->GetOldestQueueInSet(set1, &selected_queue)); - EXPECT_EQ(queue2, selected_queue); - - EXPECT_TRUE(task_queue_sets_->GetOldestQueueInSet(set2, &selected_queue)); - EXPECT_EQ(queue4, selected_queue); - - task_queue_sets_->AssignQueueToSet(queue4, set1); - - EXPECT_TRUE(task_queue_sets_->GetOldestQueueInSet(set1, &selected_queue)); - EXPECT_EQ(queue4, selected_queue); - - EXPECT_TRUE(task_queue_sets_->GetOldestQueueInSet(set2, &selected_queue)); - EXPECT_EQ(queue3, selected_queue); -} - -TEST_F(TaskQueueSetsTest, IsSetEmpty_NoWork) { - size_t set = 0; - EXPECT_TRUE(task_queue_sets_->IsSetEmpty(set)); - - internal::TaskQueueImpl* queue = NewTaskQueue("queue"); - task_queue_sets_->AssignQueueToSet(queue, set); - EXPECT_TRUE(task_queue_sets_->IsSetEmpty(set)); -} - -TEST_F(TaskQueueSetsTest, IsSetEmpty_Work) { - size_t set = 0; - EXPECT_TRUE(task_queue_sets_->IsSetEmpty(set)); - - internal::TaskQueueImpl* queue = NewTaskQueue("queue"); - queue->PushTaskOntoWorkQueueForTest(FakeTaskWithEnqueueOrder(1)); - task_queue_sets_->AssignQueueToSet(queue, set); - EXPECT_FALSE(task_queue_sets_->IsSetEmpty(set)); - - queue->PopTaskFromWorkQueueForTest(); - task_queue_sets_->OnPopQueue(queue); - EXPECT_TRUE(task_queue_sets_->IsSetEmpty(set)); -} - -} // namespace internal -} // namespace scheduler
diff --git a/components/scheduler/base/time_domain.cc b/components/scheduler/base/time_domain.cc index e64b4e9..e23883e 100644 --- a/components/scheduler/base/time_domain.cc +++ b/components/scheduler/base/time_domain.cc
@@ -8,6 +8,7 @@ #include "components/scheduler/base/task_queue_impl.h" #include "components/scheduler/base/task_queue_manager_delegate.h" +#include "components/scheduler/base/work_queue.h" #include "components/scheduler/scheduler_export.h" namespace scheduler { @@ -125,8 +126,8 @@ DCHECK(main_thread_checker_.CalledOnValidThread()); LazyNow lazy_now(CreateLazyNow()); - // Move any ready delayed tasks into the incomming queues. - WakeupReadyDelayedQueues(&lazy_now); + // Move any ready delayed tasks into the Incoming queues. + WakeupReadyDelayedQueues(&lazy_now, should_trigger_wakeup, previous_task); MoveNewlyUpdatableQueuesIntoUpdatableQueueSet(); @@ -136,8 +137,8 @@ // NOTE Update work queue may erase itself from |updatable_queue_set_|. // This is fine, erasing an element won't invalidate any interator, as long // as the iterator isn't the element being delated. - if (queue->work_queue().empty()) - queue->UpdateWorkQueue(&lazy_now, should_trigger_wakeup, previous_task); + if (queue->immediate_work_queue()->Empty()) + queue->UpdateImmediateWorkQueue(should_trigger_wakeup, previous_task); } } @@ -150,7 +151,10 @@ } } -void TimeDomain::WakeupReadyDelayedQueues(LazyNow* lazy_now) { +void TimeDomain::WakeupReadyDelayedQueues( + LazyNow* lazy_now, + bool should_trigger_wakeup, + const internal::TaskQueueImpl::Task* previous_task) { // Wake up any queues with pending delayed work. Note std::multipmap stores // the elements sorted by key, so the begin() iterator points to the earliest // queue to wakeup. @@ -161,12 +165,14 @@ if (next_wakeup->first > lazy_now->Now()) break; // A queue could have any number of delayed tasks pending so it's worthwhile - // deduping calls to MoveReadyDelayedTasksToIncomingQueue since it takes a - // lock. NOTE the order in which these are called matters since the order + // deduping calls to UpdateDelayedWorkQueue since it takes a lock. + // NOTE the order in which these are called matters since the order // in which EnqueueTaskLocks is called is respected when choosing which // queue to execute a task from. - if (dedup_set.insert(next_wakeup->second).second) - next_wakeup->second->MoveReadyDelayedTasksToIncomingQueue(lazy_now); + if (dedup_set.insert(next_wakeup->second).second) { + next_wakeup->second->UpdateDelayedWorkQueue( + lazy_now, should_trigger_wakeup, previous_task); + } delayed_wakeup_multimap_.erase(next_wakeup); } }
diff --git a/components/scheduler/base/time_domain.h b/components/scheduler/base/time_domain.h index 5cf39b70..e8691f3 100644 --- a/components/scheduler/base/time_domain.h +++ b/components/scheduler/base/time_domain.h
@@ -76,7 +76,7 @@ // UpdateWorkQueue on. void RegisterAsUpdatableTaskQueue(internal::TaskQueueImpl* queue); - // Schedules a call to TaskQueueImpl::MoveReadyDelayedTasksToIncomingQueue + // Schedules a call to TaskQueueImpl::MoveReadyDelayedTasksToDelayedWorkQueue // when this TimeDomain reaches |delayed_run_time|. void ScheduleDelayedWork(internal::TaskQueueImpl* queue, base::TimeTicks delayed_run_time, @@ -98,20 +98,22 @@ // Called by the TaskQueueManager when the TimeDomain is registered. virtual void OnRegisterWithTaskQueueManager( - TaskQueueManagerDelegate* task_queue_manager_delegate, - base::Closure do_work_closure) = 0; + TaskQueueManager* task_queue_manager) = 0; // The implementaion will secedule task processing to run with |delay| with - // respect to the TimeDomain's time source. + // respect to the TimeDomain's time source. Always called on the main thread. virtual void RequestWakeup(LazyNow* lazy_now, base::TimeDelta delay) = 0; // For implementation specific tracing. virtual void AsValueIntoInternal( base::trace_event::TracedValue* state) const = 0; - // Call TaskQueueImpl::MoveReadyDelayedTasksToIncomingQueue for each - // queue where the delay has elapsed. - void WakeupReadyDelayedQueues(LazyNow* lazy_now); + // Call TaskQueueImpl::UpdateDelayedWorkQueue for each queue where the delay + // has elapsed. + void WakeupReadyDelayedQueues( + LazyNow* lazy_now, + bool should_trigger_wakeup, + const internal::TaskQueueImpl::Task* previous_task); private: void MoveNewlyUpdatableQueuesIntoUpdatableQueueSet();
diff --git a/components/scheduler/base/time_domain_unittest.cc b/components/scheduler/base/time_domain_unittest.cc index e699e18..568d373 100644 --- a/components/scheduler/base/time_domain_unittest.cc +++ b/components/scheduler/base/time_domain_unittest.cc
@@ -10,6 +10,7 @@ #include "components/scheduler/base/task_queue_manager.h" #include "components/scheduler/base/task_queue_manager_delegate_for_test.h" #include "components/scheduler/base/test_time_source.h" +#include "components/scheduler/base/work_queue.h" #include "testing/gmock/include/gmock/gmock.h" using testing::_; @@ -41,8 +42,7 @@ bool MaybeAdvanceTime() override { return false; } const char* GetName() const override { return "Test"; } void OnRegisterWithTaskQueueManager( - TaskQueueManagerDelegate* task_queue_manager_delegate, - base::Closure do_work_closure) override {} + TaskQueueManager* task_queue_manager) override {} MOCK_METHOD2(RequestWakeup, void(LazyNow* lazy_now, base::TimeDelta delay)); @@ -159,14 +159,14 @@ task_queue_manager.NewTaskQueue(TaskQueue::Spec("test_queue")); // Post a delayed task on |dummy_queue| and advance the queue's clock so that - // next time MoveReadyDelayedTasksToIncomingQueue is called, the task will - // get moved onto the incomming queue. + // next time MoveReadyDelayedTasksToDelayedWorkQueue is called, the task will + // get moved onto the Incoming queue. base::TimeDelta dummy_delay = base::TimeDelta::FromMilliseconds(10); dummy_queue->PostDelayedTask(FROM_HERE, base::Closure(), dummy_delay); dummy_time_source.Advance(dummy_delay); // Now we can test that ScheduleDelayedWork triggers calls to - // MoveReadyDelayedTasksToIncomingQueue as expected. + // MoveReadyDelayedTasksToDelayedWorkQueue as expected. base::TimeDelta delay = base::TimeDelta::FromMilliseconds(50); base::TimeTicks delayed_runtime = time_domain_->Now() + delay; EXPECT_CALL(*time_domain_.get(), RequestWakeup(_, delay)); @@ -175,11 +175,11 @@ &lazy_now); time_domain_->UpdateWorkQueues(false, nullptr); - EXPECT_EQ(0UL, dummy_queue->IncomingQueueSizeForTest()); + EXPECT_EQ(0UL, dummy_queue->delayed_work_queue()->Size()); time_domain_->SetNow(delayed_runtime); time_domain_->UpdateWorkQueues(false, nullptr); - EXPECT_EQ(1UL, dummy_queue->IncomingQueueSizeForTest()); + EXPECT_EQ(1UL, dummy_queue->delayed_work_queue()->Size()); } namespace {
diff --git a/components/scheduler/base/virtual_time_domain.cc b/components/scheduler/base/virtual_time_domain.cc index 0ed6abb..0abea94 100644 --- a/components/scheduler/base/virtual_time_domain.cc +++ b/components/scheduler/base/virtual_time_domain.cc
@@ -6,22 +6,21 @@ #include "base/bind.h" #include "components/scheduler/base/task_queue_impl.h" +#include "components/scheduler/base/task_queue_manager.h" #include "components/scheduler/base/task_queue_manager_delegate.h" namespace scheduler { VirtualTimeDomain::VirtualTimeDomain(TimeDomain::Observer* observer, base::TimeTicks initial_time) - : TimeDomain(observer), now_(initial_time) {} + : TimeDomain(observer), now_(initial_time), task_queue_manager_(nullptr) {} VirtualTimeDomain::~VirtualTimeDomain() {} void VirtualTimeDomain::OnRegisterWithTaskQueueManager( - TaskQueueManagerDelegate* task_queue_manager_delegate, - base::Closure do_work_closure) { - task_queue_manager_delegate_ = task_queue_manager_delegate; - do_work_closure_ = do_work_closure; - DCHECK(task_queue_manager_delegate_); + TaskQueueManager* task_queue_manager) { + task_queue_manager_ = task_queue_manager; + DCHECK(task_queue_manager_); } LazyNow VirtualTimeDomain::CreateLazyNow() { @@ -31,7 +30,9 @@ void VirtualTimeDomain::RequestWakeup(LazyNow* lazy_now, base::TimeDelta delay) { - // We don't need to do anything here because AdvanceTo posts a DoWork. + // We don't need to do anything here because the caller of AdvanceTo is + // responsible for calling TaskQueueManager::MaybeScheduleImmediateWork if + // needed. } bool VirtualTimeDomain::MaybeAdvanceTime() { @@ -45,9 +46,10 @@ base::AutoLock lock(lock_); DCHECK_GE(now, now_); now_ = now; - DCHECK(task_queue_manager_delegate_); +} - task_queue_manager_delegate_->PostTask(FROM_HERE, do_work_closure_); +void VirtualTimeDomain::RequestDoWork() { + task_queue_manager_->MaybeScheduleImmediateWork(FROM_HERE); } const char* VirtualTimeDomain::GetName() const {
diff --git a/components/scheduler/base/virtual_time_domain.h b/components/scheduler/base/virtual_time_domain.h index 78239c1c..0242a62 100644 --- a/components/scheduler/base/virtual_time_domain.h +++ b/components/scheduler/base/virtual_time_domain.h
@@ -11,7 +11,6 @@ #include "components/scheduler/scheduler_export.h" namespace scheduler { -class TaskQueueManagerDelegate; class SCHEDULER_EXPORT VirtualTimeDomain : public TimeDomain { public: @@ -25,22 +24,24 @@ const char* GetName() const override; // Advances this time domain to |now|. NOTE |now| is supposed to be - // monotonically increasing. + // monotonically increasing. NOTE it's the responsibility of the caller to + // call TaskQueueManager::MaybeScheduleImmediateWork if needed. void AdvanceTo(base::TimeTicks now); protected: void OnRegisterWithTaskQueueManager( - TaskQueueManagerDelegate* task_queue_manager_delegate, - base::Closure do_work_closure) override; + TaskQueueManager* task_queue_manager) override; void RequestWakeup(LazyNow* lazy_now, base::TimeDelta delay) override; void AsValueIntoInternal( base::trace_event::TracedValue* state) const override; + void RequestDoWork(); + private: mutable base::Lock lock_; // Protects |now_|. base::TimeTicks now_; - TaskQueueManagerDelegate* task_queue_manager_delegate_; // NOT OWNED + TaskQueueManager* task_queue_manager_; // NOT OWNED base::Closure do_work_closure_; DISALLOW_COPY_AND_ASSIGN(VirtualTimeDomain);
diff --git a/components/scheduler/base/work_queue.cc b/components/scheduler/base/work_queue.cc new file mode 100644 index 0000000..1e46c42b --- /dev/null +++ b/components/scheduler/base/work_queue.cc
@@ -0,0 +1,84 @@ +// 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. + +#include "components/scheduler/base/work_queue.h" + +#include "components/scheduler/base/work_queue_sets.h" + +namespace scheduler { +namespace internal { + +WorkQueue::WorkQueue(WorkQueueSets* task_queue_sets, + TaskQueueImpl* task_queue, + const char* name) + : work_queue_sets_(task_queue_sets), + task_queue_(task_queue), + work_queue_set_index_(0), + name_(name) {} + +void WorkQueue::AsValueInto(base::trace_event::TracedValue* state) const { + std::queue<TaskQueueImpl::Task> queue_copy(work_queue_); + while (!queue_copy.empty()) { + TaskQueueImpl::TaskAsValueInto(queue_copy.front(), state); + queue_copy.pop(); + } +} + +WorkQueue::~WorkQueue() {} + +void WorkQueue::Clear() { + work_queue_ = std::queue<TaskQueueImpl::Task>(); +} + +bool WorkQueue::GetFrontTaskEnqueueOrder(int* enqueue_order) const { + if (work_queue_.empty()) + return false; + *enqueue_order = work_queue_.front().enqueue_order(); + return true; +} + +void WorkQueue::Push(const TaskQueueImpl::Task&& task) { + bool was_empty = work_queue_.empty(); + work_queue_.push(task); + if (was_empty) + work_queue_sets_->OnPushQueue(this); +} + +void WorkQueue::PushTaskForTest(const TaskQueueImpl::Task&& task) { + work_queue_.push(task); +} + +void WorkQueue::PushAndSetEnqueueOrder(const TaskQueueImpl::Task&& task, + int enqueue_order) { + bool was_empty = work_queue_.empty(); + work_queue_.push(task); + work_queue_.back().set_enqueue_order(enqueue_order); + + if (was_empty) + work_queue_sets_->OnPushQueue(this); +} + +void WorkQueue::PopTaskForTest() { + work_queue_.pop(); +} + +void WorkQueue::Swap(std::queue<TaskQueueImpl::Task>& incoming_queue) { + std::swap(work_queue_, incoming_queue); + + if (!work_queue_.empty()) + work_queue_sets_->OnPushQueue(this); + task_queue_->TraceQueueSize(false); +} + +TaskQueueImpl::Task WorkQueue::TakeTaskFromWorkQueue() { + DCHECK(!work_queue_.empty()); + TaskQueueImpl::Task pending_task = std::move(work_queue_.front()); + work_queue_.pop(); + work_queue_sets_->OnPopQueue(this); + task_queue_->TraceQueueSize(false); + return pending_task; +} + +} // namespace internal +} // namespace scheduler
diff --git a/components/scheduler/base/work_queue.h b/components/scheduler/base/work_queue.h new file mode 100644 index 0000000..635766f9 --- /dev/null +++ b/components/scheduler/base/work_queue.h
@@ -0,0 +1,82 @@ +// 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. + +#ifndef CONTENT_RENDERER_SCHEDULER_BASE_WORK_QUEUE_H_ +#define CONTENT_RENDERER_SCHEDULER_BASE_WORK_QUEUE_H_ + +#include <set> + +#include "base/trace_event/trace_event.h" +#include "base/trace_event/trace_event_argument.h" +#include "components/scheduler/base/task_queue_impl.h" +#include "components/scheduler/scheduler_export.h" + +namespace scheduler { +namespace internal { +class WorkQueueSets; + +class SCHEDULER_EXPORT WorkQueue { + public: + WorkQueue(WorkQueueSets* task_queue_sets, + TaskQueueImpl* task_queue, + const char* name); + ~WorkQueue(); + + void AsValueInto(base::trace_event::TracedValue* state) const; + + // Clears the |work_queue_|. + void Clear(); + + // returns true if the |work_queue_| is empty. + bool Empty() const { return work_queue_.empty(); } + + // If the |work_queue_| isn't empty, |enqueue_order| gets set to the enqueue + // order of the front task and the function returns true. Otherwise the + // function returns false. + bool GetFrontTaskEnqueueOrder(int* enqueue_order) const; + + // Pushes the task onto the |work_queue_| and informs the WorkQueueSets if + // the head changed. + void Push(const TaskQueueImpl::Task&& task); + + // Pushes the task onto the |work_queue_|, sets the |enqueue_order| and + // informs the WorkQueueSets if the head changed. + void PushAndSetEnqueueOrder(const TaskQueueImpl::Task&& task, + int enqueue_order); + + // Swap the |work_queue_| with |incoming_queue| and informs the + // WorkQueueSets if the head changed. + void Swap(std::queue<TaskQueueImpl::Task>& incoming_queue); + + size_t Size() const { return work_queue_.size(); } + + // Pulls a task off the |work_queue_| and informs the WorkQueueSets. + TaskQueueImpl::Task TakeTaskFromWorkQueue(); + + const char* name() const { return name_; } + + TaskQueueImpl* task_queue() const { return task_queue_; } + + size_t work_queue_set_index() const { return work_queue_set_index_; } + + void set_work_queue_set_index(size_t work_queue_set_index) { + work_queue_set_index_ = work_queue_set_index; + } + + // Test support functions. These should not be used in production code. + void PopTaskForTest(); + void PushTaskForTest(const TaskQueueImpl::Task&& task); + + private: + std::queue<TaskQueueImpl::Task> work_queue_; + WorkQueueSets* work_queue_sets_; // NOT OWNED. + TaskQueueImpl* task_queue_; // NOT OWNED. + size_t work_queue_set_index_; + const char* name_; +}; + +} // namespace internal +} // namespace scheduler + +#endif // CONTENT_RENDERER_SCHEDULER_BASE_WORK_QUEUE_H_
diff --git a/components/scheduler/base/work_queue_sets.cc b/components/scheduler/base/work_queue_sets.cc new file mode 100644 index 0000000..b4a9d5a --- /dev/null +++ b/components/scheduler/base/work_queue_sets.cc
@@ -0,0 +1,92 @@ +// 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. + +#include "components/scheduler/base/work_queue_sets.h" + +#include "base/logging.h" +#include "components/scheduler/base/work_queue.h" + +namespace scheduler { +namespace internal { + +WorkQueueSets::WorkQueueSets(size_t num_sets) + : enqueue_order_to_work_queue_maps_(num_sets) {} + +WorkQueueSets::~WorkQueueSets() {} + +void WorkQueueSets::RemoveQueue(WorkQueue* work_queue) { + int enqueue_order; + bool has_enqueue_order = work_queue->GetFrontTaskEnqueueOrder(&enqueue_order); + if (!has_enqueue_order) + return; + size_t set_index = work_queue->work_queue_set_index(); + DCHECK_LT(set_index, enqueue_order_to_work_queue_maps_.size()); + DCHECK_EQ( + work_queue, + enqueue_order_to_work_queue_maps_[set_index].find(enqueue_order)->second); + enqueue_order_to_work_queue_maps_[set_index].erase(enqueue_order); +} + +void WorkQueueSets::AssignQueueToSet(WorkQueue* work_queue, size_t set_index) { + DCHECK_LT(set_index, enqueue_order_to_work_queue_maps_.size()); + int enqueue_order; + bool has_enqueue_order = work_queue->GetFrontTaskEnqueueOrder(&enqueue_order); + size_t old_set = work_queue->work_queue_set_index(); + DCHECK_LT(old_set, enqueue_order_to_work_queue_maps_.size()); + work_queue->set_work_queue_set_index(set_index); + if (!has_enqueue_order) + return; + enqueue_order_to_work_queue_maps_[old_set].erase(enqueue_order); + enqueue_order_to_work_queue_maps_[set_index].insert( + std::make_pair(enqueue_order, work_queue)); +} + +void WorkQueueSets::OnPushQueue(WorkQueue* work_queue) { + int enqueue_order; + bool has_enqueue_order = work_queue->GetFrontTaskEnqueueOrder(&enqueue_order); + DCHECK(has_enqueue_order); + size_t set_index = work_queue->work_queue_set_index(); + DCHECK_LT(set_index, enqueue_order_to_work_queue_maps_.size()) + << " set_index = " << set_index; + enqueue_order_to_work_queue_maps_[set_index].insert( + std::make_pair(enqueue_order, work_queue)); +} + +void WorkQueueSets::OnPopQueue(WorkQueue* work_queue) { + size_t set_index = work_queue->work_queue_set_index(); + DCHECK_LT(set_index, enqueue_order_to_work_queue_maps_.size()); + DCHECK(!enqueue_order_to_work_queue_maps_[set_index].empty()) + << " set_index = " << set_index; + DCHECK_EQ(enqueue_order_to_work_queue_maps_[set_index].begin()->second, + work_queue) + << " set_index = " << set_index; + // O(1) amortised. + enqueue_order_to_work_queue_maps_[set_index].erase( + enqueue_order_to_work_queue_maps_[set_index].begin()); + int enqueue_order; + bool has_enqueue_order = work_queue->GetFrontTaskEnqueueOrder(&enqueue_order); + if (!has_enqueue_order) + return; + enqueue_order_to_work_queue_maps_[set_index].insert( + std::make_pair(enqueue_order, work_queue)); +} + +bool WorkQueueSets::GetOldestQueueInSet(size_t set_index, + WorkQueue** out_work_queue) const { + DCHECK_LT(set_index, enqueue_order_to_work_queue_maps_.size()); + if (enqueue_order_to_work_queue_maps_[set_index].empty()) + return false; + *out_work_queue = + enqueue_order_to_work_queue_maps_[set_index].begin()->second; + return true; +} + +bool WorkQueueSets::IsSetEmpty(size_t set_index) const { + DCHECK_LT(set_index, enqueue_order_to_work_queue_maps_.size()) + << " set_index = " << set_index; + return enqueue_order_to_work_queue_maps_[set_index].empty(); +} + +} // namespace internal +} // namespace scheduler
diff --git a/components/scheduler/base/task_queue_sets.h b/components/scheduler/base/work_queue_sets.h similarity index 62% rename from components/scheduler/base/task_queue_sets.h rename to components/scheduler/base/work_queue_sets.h index e3b17ec..9e7c569 100644 --- a/components/scheduler/base/task_queue_sets.h +++ b/components/scheduler/base/work_queue_sets.h
@@ -2,46 +2,48 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#ifndef COMPONENTS_SCHEDULER_BASE_TASK_QUEUE_SETS_H_ -#define COMPONENTS_SCHEDULER_BASE_TASK_QUEUE_SETS_H_ +#ifndef COMPONENTS_SCHEDULER_BASE_WORK_QUEUE_SETS_H_ +#define COMPONENTS_SCHEDULER_BASE_WORK_QUEUE_SETS_H_ #include <map> #include <vector> #include "base/macros.h" #include "base/trace_event/trace_event_argument.h" -#include "components/scheduler/base/task_queue.h" +#include "components/scheduler/base/task_queue_impl.h" #include "components/scheduler/scheduler_export.h" namespace scheduler { namespace internal { class TaskQueueImpl; -class SCHEDULER_EXPORT TaskQueueSets { +class SCHEDULER_EXPORT WorkQueueSets { public: - explicit TaskQueueSets(size_t num_sets); - ~TaskQueueSets(); + explicit WorkQueueSets(size_t num_sets); + ~WorkQueueSets(); // O(log num queues) - void RemoveQueue(internal::TaskQueueImpl* queue); + void RemoveQueue(WorkQueue* work_queue); // O(log num queues) - void AssignQueueToSet(internal::TaskQueueImpl* queue, size_t set_index); + void AssignQueueToSet(WorkQueue* queue, size_t set_index); // O(log num queues) - void OnPushQueue(internal::TaskQueueImpl* queue); + void OnPushQueue(WorkQueue* work_queue); // If empty it's O(1) amortized, otherwise it's O(log num queues) - void OnPopQueue(internal::TaskQueueImpl* queue); + void OnPopQueue(WorkQueue* work_queue); // O(1) - bool GetOldestQueueInSet(size_t set_index, - internal::TaskQueueImpl** out_queue) const; + bool GetOldestQueueInSet(size_t set_index, WorkQueue** out_work_queue) const; // O(1) bool IsSetEmpty(size_t set_index) const; private: + bool GetWorkQueueFrontTaskEnqueueOrder(WorkQueue* work_queue, + int* enqueue_order) const; + struct EnqueueOrderComparitor { // The enqueueorder numbers are generated in sequence. These will // eventually overflow and roll-over to negative numbers. We must take care @@ -62,14 +64,14 @@ } }; - typedef std::map<int, internal::TaskQueueImpl*, EnqueueOrderComparitor> - EnqueueOrderToQueueMap; - std::vector<EnqueueOrderToQueueMap> enqueue_order_to_queue_maps_; + typedef std::map<int, WorkQueue*, EnqueueOrderComparitor> + EnqueueOrderToWorkQueueMap; + std::vector<EnqueueOrderToWorkQueueMap> enqueue_order_to_work_queue_maps_; - DISALLOW_COPY_AND_ASSIGN(TaskQueueSets); + DISALLOW_COPY_AND_ASSIGN(WorkQueueSets); }; } // namespace internal } // namespace scheduler -#endif // COMPONENTS_SCHEDULER_BASE_TASK_QUEUE_SETS_H_ +#endif // COMPONENTS_SCHEDULER_BASE_WORK_QUEUE_SETS_H_
diff --git a/components/scheduler/base/work_queue_sets_unittest.cc b/components/scheduler/base/work_queue_sets_unittest.cc new file mode 100644 index 0000000..c5aef58 --- /dev/null +++ b/components/scheduler/base/work_queue_sets_unittest.cc
@@ -0,0 +1,246 @@ +// 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. + +#include "components/scheduler/base/work_queue_sets.h" + +#include "components/scheduler/base/work_queue.h" +#include "testing/gmock/include/gmock/gmock.h" + +namespace scheduler { +class TimeDomain; + +namespace internal { + +class WorkQueueSetsTest : public testing::Test { + public: + void SetUp() override { work_queue_sets_.reset(new WorkQueueSets(kNumSets)); } + + protected: + enum { + kNumSets = 5 // An arbitary choice. + }; + + WorkQueue* NewTaskQueue(const char* queue_name) { + WorkQueue* queue = new WorkQueue(work_queue_sets_.get(), nullptr, "test"); + work_queues_.push_back(make_scoped_ptr(queue)); + return queue; + } + + TaskQueueImpl::Task FakeTaskWithEnqueueOrder(int enqueue_order) { + TaskQueueImpl::Task fake_task(FROM_HERE, base::Closure(), base::TimeTicks(), + 0, true); + fake_task.set_enqueue_order(enqueue_order); + return fake_task; + } + + std::vector<scoped_ptr<WorkQueue>> work_queues_; + scoped_ptr<WorkQueueSets> work_queue_sets_; +}; + +TEST_F(WorkQueueSetsTest, AssignQueueToSet) { + WorkQueue* work_queue = NewTaskQueue("queue"); + size_t set = TaskQueue::NORMAL_PRIORITY; + work_queue_sets_->AssignQueueToSet(work_queue, set); + + EXPECT_EQ(set, work_queue->work_queue_set_index()); +} + +TEST_F(WorkQueueSetsTest, GetOldestQueueInSet_QueueEmpty) { + WorkQueue* work_queue = NewTaskQueue("queue"); + size_t set = TaskQueue::NORMAL_PRIORITY; + work_queue_sets_->AssignQueueToSet(work_queue, set); + + WorkQueue* selected_work_queue; + EXPECT_FALSE( + work_queue_sets_->GetOldestQueueInSet(set, &selected_work_queue)); +} + +TEST_F(WorkQueueSetsTest, OnPushQueue) { + WorkQueue* work_queue = NewTaskQueue("queue"); + size_t set = TaskQueue::NORMAL_PRIORITY; + work_queue_sets_->AssignQueueToSet(work_queue, set); + + WorkQueue* selected_work_queue; + EXPECT_FALSE( + work_queue_sets_->GetOldestQueueInSet(set, &selected_work_queue)); + + work_queue->Push(FakeTaskWithEnqueueOrder(10)); + work_queue_sets_->OnPushQueue(work_queue); + + EXPECT_TRUE(work_queue_sets_->GetOldestQueueInSet(set, &selected_work_queue)); + EXPECT_EQ(work_queue, selected_work_queue); +} + +TEST_F(WorkQueueSetsTest, GetOldestQueueInSet_SingleTaskInSet) { + WorkQueue* work_queue = NewTaskQueue("queue"); + work_queue->Push(FakeTaskWithEnqueueOrder(10)); + size_t set = 1; + work_queue_sets_->AssignQueueToSet(work_queue, set); + + WorkQueue* selected_work_queue; + EXPECT_TRUE(work_queue_sets_->GetOldestQueueInSet(set, &selected_work_queue)); + EXPECT_EQ(work_queue, selected_work_queue); +} + +TEST_F(WorkQueueSetsTest, GetOldestQueueInSet_MultipleAgesInSet) { + WorkQueue* queue1 = NewTaskQueue("queue1"); + WorkQueue* queue2 = NewTaskQueue("queue2"); + WorkQueue* queue3 = NewTaskQueue("queue2"); + queue1->Push(FakeTaskWithEnqueueOrder(6)); + queue2->Push(FakeTaskWithEnqueueOrder(5)); + queue3->Push(FakeTaskWithEnqueueOrder(4)); + size_t set = 2; + work_queue_sets_->AssignQueueToSet(queue1, set); + work_queue_sets_->AssignQueueToSet(queue2, set); + work_queue_sets_->AssignQueueToSet(queue3, set); + + WorkQueue* selected_work_queue; + EXPECT_TRUE(work_queue_sets_->GetOldestQueueInSet(set, &selected_work_queue)); + EXPECT_EQ(queue3, selected_work_queue); +} + +TEST_F(WorkQueueSetsTest, OnPopQueue) { + WorkQueue* queue1 = NewTaskQueue("queue1"); + WorkQueue* queue2 = NewTaskQueue("queue2"); + WorkQueue* queue3 = NewTaskQueue("queue3"); + queue1->Push(FakeTaskWithEnqueueOrder(6)); + queue2->Push(FakeTaskWithEnqueueOrder(3)); + queue2->Push(FakeTaskWithEnqueueOrder(1)); + queue3->Push(FakeTaskWithEnqueueOrder(4)); + size_t set = 3; + work_queue_sets_->AssignQueueToSet(queue1, set); + work_queue_sets_->AssignQueueToSet(queue2, set); + work_queue_sets_->AssignQueueToSet(queue3, set); + + WorkQueue* selected_work_queue; + EXPECT_TRUE(work_queue_sets_->GetOldestQueueInSet(set, &selected_work_queue)); + EXPECT_EQ(queue2, selected_work_queue); + + queue2->PopTaskForTest(); + work_queue_sets_->OnPopQueue(queue2); + + EXPECT_TRUE(work_queue_sets_->GetOldestQueueInSet(set, &selected_work_queue)); + EXPECT_EQ(queue2, selected_work_queue); +} + +TEST_F(WorkQueueSetsTest, OnPopQueue_QueueBecomesEmpty) { + WorkQueue* queue1 = NewTaskQueue("queue"); + WorkQueue* queue2 = NewTaskQueue("queue"); + WorkQueue* queue3 = NewTaskQueue("queue"); + queue1->Push(FakeTaskWithEnqueueOrder(6)); + queue2->Push(FakeTaskWithEnqueueOrder(5)); + queue3->Push(FakeTaskWithEnqueueOrder(4)); + size_t set = 4; + work_queue_sets_->AssignQueueToSet(queue1, set); + work_queue_sets_->AssignQueueToSet(queue2, set); + work_queue_sets_->AssignQueueToSet(queue3, set); + + WorkQueue* selected_work_queue; + EXPECT_TRUE(work_queue_sets_->GetOldestQueueInSet(set, &selected_work_queue)); + EXPECT_EQ(queue3, selected_work_queue); + + queue3->PopTaskForTest(); + work_queue_sets_->OnPopQueue(queue3); + + EXPECT_TRUE(work_queue_sets_->GetOldestQueueInSet(set, &selected_work_queue)); + EXPECT_EQ(queue2, selected_work_queue); +} + +TEST_F(WorkQueueSetsTest, + GetOldestQueueInSet_MultipleAgesInSetIntegerRollover) { + WorkQueue* queue1 = NewTaskQueue("queue1"); + WorkQueue* queue2 = NewTaskQueue("queue2"); + WorkQueue* queue3 = NewTaskQueue("queue3"); + queue1->Push(FakeTaskWithEnqueueOrder(0x7ffffff1)); + queue2->Push(FakeTaskWithEnqueueOrder(0x7ffffff0)); + queue3->Push(FakeTaskWithEnqueueOrder(-0x7ffffff1)); + size_t set = 0; + work_queue_sets_->AssignQueueToSet(queue1, set); + work_queue_sets_->AssignQueueToSet(queue2, set); + work_queue_sets_->AssignQueueToSet(queue3, set); + + WorkQueue* selected_work_queue; + EXPECT_TRUE(work_queue_sets_->GetOldestQueueInSet(set, &selected_work_queue)); + EXPECT_EQ(queue2, selected_work_queue); +} + +TEST_F(WorkQueueSetsTest, GetOldestQueueInSet_MultipleAgesInSet_RemoveQueue) { + WorkQueue* queue1 = NewTaskQueue("queue1"); + WorkQueue* queue2 = NewTaskQueue("queue2"); + WorkQueue* queue3 = NewTaskQueue("queue3"); + queue1->Push(FakeTaskWithEnqueueOrder(6)); + queue2->Push(FakeTaskWithEnqueueOrder(5)); + queue3->Push(FakeTaskWithEnqueueOrder(4)); + size_t set = 1; + work_queue_sets_->AssignQueueToSet(queue1, set); + work_queue_sets_->AssignQueueToSet(queue2, set); + work_queue_sets_->AssignQueueToSet(queue3, set); + work_queue_sets_->RemoveQueue(queue3); + + WorkQueue* selected_work_queue; + EXPECT_TRUE(work_queue_sets_->GetOldestQueueInSet(set, &selected_work_queue)); + EXPECT_EQ(queue2, selected_work_queue); +} + +TEST_F(WorkQueueSetsTest, AssignQueueToSet_Complex) { + WorkQueue* queue1 = NewTaskQueue("queue1"); + WorkQueue* queue2 = NewTaskQueue("queue2"); + WorkQueue* queue3 = NewTaskQueue("queue3"); + WorkQueue* queue4 = NewTaskQueue("queue4"); + queue1->Push(FakeTaskWithEnqueueOrder(6)); + queue2->Push(FakeTaskWithEnqueueOrder(5)); + queue3->Push(FakeTaskWithEnqueueOrder(4)); + queue4->Push(FakeTaskWithEnqueueOrder(3)); + size_t set1 = 1; + size_t set2 = 2; + work_queue_sets_->AssignQueueToSet(queue1, set1); + work_queue_sets_->AssignQueueToSet(queue2, set1); + work_queue_sets_->AssignQueueToSet(queue3, set2); + work_queue_sets_->AssignQueueToSet(queue4, set2); + + WorkQueue* selected_work_queue; + EXPECT_TRUE( + work_queue_sets_->GetOldestQueueInSet(set1, &selected_work_queue)); + EXPECT_EQ(queue2, selected_work_queue); + + EXPECT_TRUE( + work_queue_sets_->GetOldestQueueInSet(set2, &selected_work_queue)); + EXPECT_EQ(queue4, selected_work_queue); + + work_queue_sets_->AssignQueueToSet(queue4, set1); + + EXPECT_TRUE( + work_queue_sets_->GetOldestQueueInSet(set1, &selected_work_queue)); + EXPECT_EQ(queue4, selected_work_queue); + + EXPECT_TRUE( + work_queue_sets_->GetOldestQueueInSet(set2, &selected_work_queue)); + EXPECT_EQ(queue3, selected_work_queue); +} + +TEST_F(WorkQueueSetsTest, IsSetEmpty_NoWork) { + size_t set = 0; + EXPECT_TRUE(work_queue_sets_->IsSetEmpty(set)); + + WorkQueue* work_queue = NewTaskQueue("queue"); + work_queue_sets_->AssignQueueToSet(work_queue, set); + EXPECT_TRUE(work_queue_sets_->IsSetEmpty(set)); +} + +TEST_F(WorkQueueSetsTest, IsSetEmpty_Work) { + size_t set = 0; + EXPECT_TRUE(work_queue_sets_->IsSetEmpty(set)); + + WorkQueue* work_queue = NewTaskQueue("queue"); + work_queue->Push(FakeTaskWithEnqueueOrder(1)); + work_queue_sets_->AssignQueueToSet(work_queue, set); + EXPECT_FALSE(work_queue_sets_->IsSetEmpty(set)); + + work_queue->PopTaskForTest(); + work_queue_sets_->OnPopQueue(work_queue); + EXPECT_TRUE(work_queue_sets_->IsSetEmpty(set)); +} + +} // namespace internal +} // namespace scheduler
diff --git a/components/scheduler/child/idle_helper.cc b/components/scheduler/child/idle_helper.cc index b0fb06a..9612fb2 100644 --- a/components/scheduler/child/idle_helper.cc +++ b/components/scheduler/child/idle_helper.cc
@@ -93,7 +93,7 @@ if (long_idle_period_duration >= base::TimeDelta::FromMilliseconds(kMinimumIdlePeriodDurationMillis)) { *next_long_idle_period_delay_out = long_idle_period_duration; - if (!idle_queue_->HasPendingImmediateTask()) { + if (!idle_queue_->HasPendingImmediateWork()) { return IdlePeriodState::IN_LONG_IDLE_PERIOD_PAUSED; } else if (long_idle_period_duration == max_long_idle_period_duration) { return IdlePeriodState::IN_LONG_IDLE_PERIOD_WITH_MAX_DEADLINE; @@ -175,7 +175,7 @@ TRACE_EVENT0(disabled_by_default_tracing_category_, "StartIdlePeriod"); idle_queue_->SetQueuePriority(TaskQueue::BEST_EFFORT_PRIORITY); - idle_queue_->PumpQueue(); + idle_queue_->PumpQueue(true); state_.UpdateState(new_state, idle_period_deadline, now); } @@ -224,13 +224,13 @@ DCHECK(IsInLongIdlePeriod(state_.idle_period_state())); TRACE_EVENT0(disabled_by_default_tracing_category_, "UpdateLongIdlePeriodStateAfterIdleTask"); - TaskQueue::QueueState queue_state = idle_queue_->GetQueueState(); - if (queue_state == TaskQueue::QueueState::EMPTY) { + + if (!idle_queue_->HasPendingImmediateWork()) { // If there are no more idle tasks then pause long idle period ticks until a // new idle task is posted. state_.UpdateState(IdlePeriodState::IN_LONG_IDLE_PERIOD_PAUSED, state_.idle_period_deadline(), base::TimeTicks()); - } else if (queue_state == TaskQueue::QueueState::NEEDS_PUMPING) { + } else if (idle_queue_->NeedsPumping()) { // If there is still idle work to do then just start the next idle period. base::TimeDelta next_long_idle_period_delay; if (state_.idle_period_state() ==
diff --git a/components/scheduler/child/scheduler_helper_unittest.cc b/components/scheduler/child/scheduler_helper_unittest.cc index f2d60cf..8f7a649 100644 --- a/components/scheduler/child/scheduler_helper_unittest.cc +++ b/components/scheduler/child/scheduler_helper_unittest.cc
@@ -176,7 +176,7 @@ EXPECT_CALL(observer, WillProcessTask(_)).Times(0); EXPECT_CALL(observer, DidProcessTask(_)).Times(0); - scheduler_helper_->ControlAfterWakeUpTaskRunner()->PumpQueue(); + scheduler_helper_->ControlAfterWakeUpTaskRunner()->PumpQueue(true); RunUntilIdle(); }
diff --git a/components/scheduler/child/scheduler_tqm_delegate_for_test.cc b/components/scheduler/child/scheduler_tqm_delegate_for_test.cc index ddd7a3a..10e910f 100644 --- a/components/scheduler/child/scheduler_tqm_delegate_for_test.cc +++ b/components/scheduler/child/scheduler_tqm_delegate_for_test.cc
@@ -29,7 +29,7 @@ void SchedulerTqmDelegateForTest::SetDefaultTaskRunner( scoped_refptr<base::SingleThreadTaskRunner> task_runner) { - default_task_runner_ = task_runner.Pass(); + default_task_runner_ = std::move(task_runner); } void SchedulerTqmDelegateForTest::RestoreDefaultTaskRunner() {
diff --git a/components/scheduler/child/worker_scheduler.cc b/components/scheduler/child/worker_scheduler.cc index 18f6cec..c0bd7fd 100644 --- a/components/scheduler/child/worker_scheduler.cc +++ b/components/scheduler/child/worker_scheduler.cc
@@ -4,6 +4,8 @@ #include "components/scheduler/child/worker_scheduler.h" +#include <utility> + #include "base/message_loop/message_loop.h" #include "components/scheduler/child/scheduler_tqm_delegate.h" #include "components/scheduler/child/worker_scheduler_impl.h" @@ -19,7 +21,7 @@ // static scoped_ptr<WorkerScheduler> WorkerScheduler::Create( scoped_refptr<SchedulerTqmDelegate> main_task_runner) { - return make_scoped_ptr(new WorkerSchedulerImpl(main_task_runner.Pass())); + return make_scoped_ptr(new WorkerSchedulerImpl(std::move(main_task_runner))); } } // namespace scheduler
diff --git a/components/scheduler/renderer/renderer_scheduler_impl.cc b/components/scheduler/renderer/renderer_scheduler_impl.cc index 0ef81cd..d93b780 100644 --- a/components/scheduler/renderer/renderer_scheduler_impl.cc +++ b/components/scheduler/renderer/renderer_scheduler_impl.cc
@@ -542,7 +542,7 @@ case UseCase::MAIN_THREAD_GESTURE: case UseCase::SYNCHRONIZED_GESTURE: - return compositor_task_runner_->HasPendingImmediateTask() || + return compositor_task_runner_->HasPendingImmediateWork() || MainThreadOnly().touchstart_expected_soon; case UseCase::TOUCHSTART:
diff --git a/components/scheduler/renderer/throttling_helper.cc b/components/scheduler/renderer/throttling_helper.cc index 88f9ae7..c7525720 100644 --- a/components/scheduler/renderer/throttling_helper.cc +++ b/components/scheduler/renderer/throttling_helper.cc
@@ -41,7 +41,7 @@ task_queue->SetTimeDomain(time_domain_.get()); task_queue->SetPumpPolicy(TaskQueue::PumpPolicy::MANUAL); - MaybeSchedulePumpThrottledTasksLocked(); + MaybeSchedulePumpThrottledTasksLocked(FROM_HERE); } void ThrottlingHelper::Unthrottle(TaskQueue* task_queue) { @@ -59,13 +59,13 @@ } TRACE_EVENT0(tracing_category_, "ThrottlingHelper::OnTimeDomainHasImmediateWork"); - MaybeSchedulePumpThrottledTasksLocked(); + MaybeSchedulePumpThrottledTasksLocked(FROM_HERE); } void ThrottlingHelper::OnTimeDomainHasDelayedWork() { TRACE_EVENT0(tracing_category_, "ThrottlingHelper::OnTimeDomainHasDelayedWork"); - MaybeSchedulePumpThrottledTasksLocked(); + MaybeSchedulePumpThrottledTasksLocked(FROM_HERE); } void ThrottlingHelper::PumpThrottledTasks() { @@ -75,15 +75,15 @@ time_domain_->AdvanceTo(tick_clock_->NowTicks()); bool work_to_do = false; for (TaskQueue* task_queue : throttled_queues_) { - if (task_queue->GetQueueState() == TaskQueue::QueueState::EMPTY) + if (task_queue->IsEmpty()) continue; work_to_do = true; - task_queue->PumpQueue(); + task_queue->PumpQueue(false); } if (work_to_do) - MaybeSchedulePumpThrottledTasksLocked(); + MaybeSchedulePumpThrottledTasksLocked(FROM_HERE); } /* static */ @@ -93,13 +93,14 @@ return one_second - ((now - base::TimeTicks()) % one_second); } -void ThrottlingHelper::MaybeSchedulePumpThrottledTasksLocked() { +void ThrottlingHelper::MaybeSchedulePumpThrottledTasksLocked( + const tracked_objects::Location& from_here) { if (pending_pump_throttled_tasks_) return; pending_pump_throttled_tasks_ = true; task_runner_->PostDelayedTask( - FROM_HERE, pump_throttled_tasks_closure_, + from_here, pump_throttled_tasks_closure_, DelayToNextRunTimeInSeconds(tick_clock_->NowTicks())); }
diff --git a/components/scheduler/renderer/throttling_helper.h b/components/scheduler/renderer/throttling_helper.h index 8417d53..dd4d0fd 100644 --- a/components/scheduler/renderer/throttling_helper.h +++ b/components/scheduler/renderer/throttling_helper.h
@@ -38,7 +38,8 @@ private: void PumpThrottledTasks(); - void MaybeSchedulePumpThrottledTasksLocked(); + void MaybeSchedulePumpThrottledTasksLocked( + const tracked_objects::Location& from_here); std::set<TaskQueue*> throttled_queues_; base::Closure pump_throttled_tasks_closure_;
diff --git a/components/scheduler/renderer/throttling_helper_unittest.cc b/components/scheduler/renderer/throttling_helper_unittest.cc index 9526f06..ff82aa3 100644 --- a/components/scheduler/renderer/throttling_helper_unittest.cc +++ b/components/scheduler/renderer/throttling_helper_unittest.cc
@@ -200,4 +200,30 @@ base::TimeDelta::FromMilliseconds(2000.0))); } +namespace { +bool MessageLoopTaskCounter(size_t* count) { + *count = *count + 1; + return true; +} + +void NopTask() {} + +} // namespace + +TEST_F(ThrottlingHelperTest, + SingleThrottledTaskPumpedAndRunWithNoExtraneousMessageLoopTasks) { + throttling_helper_->Throttle(timer_queue_.get()); + + base::TimeDelta delay(base::TimeDelta::FromMilliseconds(10)); + timer_queue_->PostDelayedTask(FROM_HERE, base::Bind(&NopTask), delay); + + size_t task_count = 0; + mock_task_runner_->RunTasksWhile( + base::Bind(&MessageLoopTaskCounter, &task_count)); + + // NOTE PumpThrottledTasks will always run at least twice because we can only + // detect if the queues have become empty before pumping. + EXPECT_EQ(2u, task_count); +} + } // namespace scheduler
diff --git a/components/scheduler/scheduler.gypi b/components/scheduler/scheduler.gypi index c6a79b78..21ca898 100644 --- a/components/scheduler/scheduler.gypi +++ b/components/scheduler/scheduler.gypi
@@ -24,10 +24,12 @@ 'base/task_queue_manager_delegate.h', 'base/task_queue_selector.cc', 'base/task_queue_selector.h', - 'base/task_queue_sets.cc', - 'base/task_queue_sets.h', 'base/time_domain.cc', 'base/time_domain.h', + 'base/work_queue.cc', + 'base/work_queue.h', + 'base/work_queue_sets.cc', + 'base/work_queue_sets.h', 'base/pollable_thread_safe_flag.cc', 'base/pollable_thread_safe_flag.h', 'base/virtual_time_domain.cc',
diff --git a/components/scheduler/test/lazy_scheduler_message_loop_delegate_for_tests.cc b/components/scheduler/test/lazy_scheduler_message_loop_delegate_for_tests.cc index ca35441..8c8788a5 100644 --- a/components/scheduler/test/lazy_scheduler_message_loop_delegate_for_tests.cc +++ b/components/scheduler/test/lazy_scheduler_message_loop_delegate_for_tests.cc
@@ -4,6 +4,8 @@ #include "components/scheduler/test/lazy_scheduler_message_loop_delegate_for_tests.h" +#include <utility> + #include "base/time/default_tick_clock.h" namespace scheduler { @@ -37,17 +39,17 @@ DCHECK(message_loop_); original_task_runner_ = message_loop_->task_runner(); if (pending_task_runner_) - message_loop_->SetTaskRunner(pending_task_runner_.Pass()); + message_loop_->SetTaskRunner(std::move(pending_task_runner_)); return message_loop_; } void LazySchedulerMessageLoopDelegateForTests::SetDefaultTaskRunner( scoped_refptr<base::SingleThreadTaskRunner> task_runner) { if (!HasMessageLoop()) { - pending_task_runner_ = task_runner.Pass(); + pending_task_runner_ = std::move(task_runner); return; } - message_loop_->SetTaskRunner(task_runner.Pass()); + message_loop_->SetTaskRunner(std::move(task_runner)); } void LazySchedulerMessageLoopDelegateForTests::RestoreDefaultTaskRunner() {
diff --git a/components/search_engines.gypi b/components/search_engines.gypi index 64ddbe9..1205392 100644 --- a/components/search_engines.gypi +++ b/components/search_engines.gypi
@@ -44,8 +44,8 @@ 'search_engines/default_search_policy_handler.h', 'search_engines/default_search_pref_migration.cc', 'search_engines/default_search_pref_migration.h', - 'search_engines/detect_desktop_search_win.cc', - 'search_engines/detect_desktop_search_win.h', + 'search_engines/desktop_search_win.cc', + 'search_engines/desktop_search_win.h', 'search_engines/keyword_table.cc', 'search_engines/keyword_table.h', 'search_engines/keyword_web_data_service.cc',
diff --git a/components/search_engines/BUILD.gn b/components/search_engines/BUILD.gn index 46fb5e3..e2fa0e4 100644 --- a/components/search_engines/BUILD.gn +++ b/components/search_engines/BUILD.gn
@@ -11,8 +11,8 @@ "default_search_manager.h", "default_search_pref_migration.cc", "default_search_pref_migration.h", - "detect_desktop_search_win.cc", - "detect_desktop_search_win.h", + "desktop_search_win.cc", + "desktop_search_win.h", "keyword_table.cc", "keyword_table.h", "keyword_web_data_service.cc", @@ -114,7 +114,7 @@ sources = [ "default_search_manager_unittest.cc", "default_search_pref_migration_unittest.cc", - "detect_desktop_search_win_unittest.cc", + "desktop_search_win_unittest.cc", "keyword_table_unittest.cc", "search_host_to_urls_map_unittest.cc", "template_url_prepopulate_data_unittest.cc",
diff --git a/components/search_engines/detect_desktop_search_win.cc b/components/search_engines/desktop_search_win.cc similarity index 63% rename from components/search_engines/detect_desktop_search_win.cc rename to components/search_engines/desktop_search_win.cc index 563e80d..b1bae71 100644 --- a/components/search_engines/detect_desktop_search_win.cc +++ b/components/search_engines/desktop_search_win.cc
@@ -2,17 +2,42 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#include "components/search_engines/detect_desktop_search_win.h" +#include "components/search_engines/desktop_search_win.h" #include <string> #include "base/memory/scoped_ptr.h" +#include "base/prefs/pref_service.h" #include "base/strings/string_util.h" +#include "components/pref_registry/pref_registry_syncable.h" #include "components/search_engines/prepopulated_engines.h" #include "components/search_engines/template_url.h" #include "components/search_engines/template_url_prepopulate_data.h" #include "net/base/url_util.h" +namespace prefs { +const char kWindowsDesktopSearchRedirectionPref[] = + "windows_desktop_search_redirection"; +} // namespace prefs + +const base::Feature kWindowsDesktopSearchRedirectionFeature = { + "WindowsDesktopSearchRedirection", base::FEATURE_DISABLED_BY_DEFAULT +}; + +void RegisterWindowsDesktopSearchRedirectionPref( + user_prefs::PrefRegistrySyncable* registry) { + registry->RegisterBooleanPref(prefs::kWindowsDesktopSearchRedirectionPref, + false); +} + +bool ShouldRedirectWindowsDesktopSearchToDefaultSearchEngine( + PrefService* pref_service) { + DCHECK(pref_service); + return base::FeatureList::IsEnabled( + kWindowsDesktopSearchRedirectionFeature) && + pref_service->GetBoolean(prefs::kWindowsDesktopSearchRedirectionPref); +} + bool DetectWindowsDesktopSearch(const GURL& url, const SearchTermsData& search_terms_data, base::string16* search_terms) { @@ -37,7 +62,7 @@ // Use a case-insensitive comparison because the key is sometimes in capital // letters. if (base::EqualsCaseInsensitiveASCII(it.GetKey(), kBingSourceQueryKey)) { - std::string source = it.GetValue(); + const std::string source = it.GetValue(); if (source == kBingSourceDesktopText || source == kBingSourceDesktopVoice) return true; }
diff --git a/components/search_engines/desktop_search_win.h b/components/search_engines/desktop_search_win.h new file mode 100644 index 0000000..162e95f2 --- /dev/null +++ b/components/search_engines/desktop_search_win.h
@@ -0,0 +1,44 @@ +// 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. + +#ifndef COMPONENTS_SEARCH_ENGINES_DESKTOP_SEARCH_WIN_H_ +#define COMPONENTS_SEARCH_ENGINES_DESKTOP_SEARCH_WIN_H_ + +#include "base/feature_list.h" +#include "base/strings/string16.h" + +class GURL; +class PrefService; +class SearchTermsData; + +namespace user_prefs { +class PrefRegistrySyncable; +} + +namespace prefs { +// Name of the Windows desktop search redirection preference. +extern const char kWindowsDesktopSearchRedirectionPref[]; +} + +// Windows desktop search redirection feature. This is exposed in the header +// file so that it can be referenced from about_flags.cc. +extern const base::Feature kWindowsDesktopSearchRedirectionFeature; + +// Registers the Windows desktop search redirection preference into |registry|. +void RegisterWindowsDesktopSearchRedirectionPref( + user_prefs::PrefRegistrySyncable* registry); + +// Indicates whether Windows desktop searches should be redirected to the +// default search engine. This is only true when both the preference and the +// feature are enabled. The preference value is read from |pref_service|. +bool ShouldRedirectWindowsDesktopSearchToDefaultSearchEngine( + PrefService* pref_service); + +// Detects whether a URL comes from a Windows Desktop search. If so, puts the +// search terms in |search_terms| and returns true. +bool DetectWindowsDesktopSearch(const GURL& url, + const SearchTermsData& search_terms_data, + base::string16* search_terms); + +#endif // COMPONENTS_SEARCH_ENGINES_DESKTOP_SEARCH_WIN_H_
diff --git a/components/search_engines/desktop_search_win_unittest.cc b/components/search_engines/desktop_search_win_unittest.cc new file mode 100644 index 0000000..a49e3ef1 --- /dev/null +++ b/components/search_engines/desktop_search_win_unittest.cc
@@ -0,0 +1,45 @@ +// 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. + +#include "components/search_engines/desktop_search_win.h" + +#include "base/macros.h" +#include "base/strings/string16.h" +#include "components/search_engines/testing_search_terms_data.h" +#include "testing/gtest/include/gtest/gtest.h" +#include "url/gurl.h" + +namespace { +struct DetectWindowsDesktopSearchTestData { + const char* url; + const wchar_t* expected_search_terms; +}; +} // namespace + +TEST(WindowsDesktopSearch, DetectWindowsDesktopSearch) { + const DetectWindowsDesktopSearchTestData test_data[] = { + {"https://www.google.com", L""}, + {"https://www.bing.com/search", L""}, + {"https://www.bing.com/search?q=keyword&form=QBLH", L""}, + {"https://www.bing.com/search?q=keyword&form=WNSGPH", L"keyword"}, + {"https://www.bing.com/search?q=keyword&form=WNSBOX", L"keyword"}, + {"https://www.bing.com/search?q=keyword&FORM=WNSGPH", L"keyword"}, + {"https://www.bing.com/search?q=keyword&FORM=WNSBOX", L"keyword"}, + {"https://www.bing.com/search?form=WNSGPH&q=keyword", L"keyword"}, + {"https://www.bing.com/search?q=keyword&form=WNSGPH&other=stuff", + L"keyword"}, + {"https://www.bing.com/search?q=%C3%A8+%C3%A9&form=WNSGPH", L"\xE8 \xE9"}, + }; + + for (size_t i = 0; i < arraysize(test_data); ++i) { + TestingSearchTermsData search_terms_data("https://www.google.com"); + base::string16 search_terms; + bool is_desktop_search = DetectWindowsDesktopSearch( + GURL(test_data[i].url), search_terms_data, &search_terms); + const base::string16 expected_search_terms( + test_data[i].expected_search_terms); + EXPECT_EQ(!expected_search_terms.empty(), is_desktop_search); + EXPECT_EQ(expected_search_terms, search_terms); + } +}
diff --git a/components/search_engines/detect_desktop_search_win.h b/components/search_engines/detect_desktop_search_win.h deleted file mode 100644 index 3d648a62..0000000 --- a/components/search_engines/detect_desktop_search_win.h +++ /dev/null
@@ -1,19 +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. - -#ifndef COMPONENTS_SEARCH_ENGINES_DETECT_DESKTOP_SEARCH_WIN_H_ -#define COMPONENTS_SEARCH_ENGINES_DETECT_DESKTOP_SEARCH_WIN_H_ - -#include "base/strings/string16.h" - -class GURL; -class SearchTermsData; - -// Detects whether a URL comes from a Windows Desktop search. If so, puts the -// search terms in |search_terms| and returns true. -bool DetectWindowsDesktopSearch(const GURL& url, - const SearchTermsData& search_terms_data, - base::string16* search_terms); - -#endif // COMPONENTS_SEARCH_ENGINES_DETECT_DESKTOP_SEARCH_WIN_H_
diff --git a/components/search_engines/search_engines_switches.cc b/components/search_engines/search_engines_switches.cc index f15afa7a..190662c 100644 --- a/components/search_engines/search_engines_switches.cc +++ b/components/search_engines/search_engines_switches.cc
@@ -10,10 +10,4 @@ // testing. const char kExtraSearchQueryParams[] = "extra-search-query-params"; -#if defined(OS_WIN) -// Use the default search provider for desktop search. -const char kUseDefaultSearchProviderForDesktopSearch[] = - "use-default-search-provider-for-desktop-search"; -#endif // defined(OS_WIN) - } // namespace switches
diff --git a/components/search_engines/search_engines_switches.h b/components/search_engines/search_engines_switches.h index fc3ab109..476280c 100644 --- a/components/search_engines/search_engines_switches.h +++ b/components/search_engines/search_engines_switches.h
@@ -11,10 +11,6 @@ extern const char kExtraSearchQueryParams[]; -#if defined(OS_WIN) -extern const char kUseDefaultSearchProviderForDesktopSearch[]; -#endif // defined(OS_WIN) - } // namespace switches #endif // COMPONENTS_SEARCH_ENGINES_SEARCH_ENGINES_SWITCHES_H_
diff --git a/components/security_interstitials/core/browser/resources/interstitial_v2.js b/components/security_interstitials/core/browser/resources/interstitial_v2.js index e29ae8e..43e76833 100644 --- a/components/security_interstitials/core/browser/resources/interstitial_v2.js +++ b/components/security_interstitials/core/browser/resources/interstitial_v2.js
@@ -31,8 +31,17 @@ * @param {string} cmd The command to send. */ function sendCommand(cmd) { +<if expr="not is_ios"> window.domAutomationController.setAutomationId(1); window.domAutomationController.send(cmd); +</if> +<if expr="is_ios"> + // TODO(crbug.com/565877): Revisit message passing for WKWebView. + var iframe = document.createElement('IFRAME'); + iframe.setAttribute('src', 'js-command:' + cmd); + document.documentElement.appendChild(iframe); + iframe.parentNode.removeChild(iframe); +</if> } /**
diff --git a/components/sync_bookmarks/bookmark_change_processor.cc b/components/sync_bookmarks/bookmark_change_processor.cc index 0f1a79d3..df65f78e 100644 --- a/components/sync_bookmarks/bookmark_change_processor.cc +++ b/components/sync_bookmarks/bookmark_change_processor.cc
@@ -100,8 +100,8 @@ const gfx::Image& favicon = model->GetFavicon(src); // Check for empty images. This can happen if the favicon is - // still being loaded. - if (favicon.IsEmpty()) + // still being loaded. Also avoid syncing touch icons. + if (favicon.IsEmpty() || model->GetFaviconType(src) != favicon_base::FAVICON) return; // Re-encode the BookmarkNode's favicon as a PNG, and pass the data to the
diff --git a/components/sync_driver/non_blocking_data_type_controller_unittest.cc b/components/sync_driver/non_blocking_data_type_controller_unittest.cc index 0c857fd..9d92f44 100644 --- a/components/sync_driver/non_blocking_data_type_controller_unittest.cc +++ b/components/sync_driver/non_blocking_data_type_controller_unittest.cc
@@ -19,6 +19,7 @@ #include "sync/engine/commit_queue.h" #include "sync/internal_api/public/activation_context.h" #include "sync/internal_api/public/shared_model_type_processor.h" +#include "sync/internal_api/public/test/fake_model_type_service.h" #include "testing/gtest/include/gtest/gtest.h" namespace sync_driver_v2 { @@ -187,9 +188,9 @@ protected: void CreateTypeProcessor() { - // TODO(pavely): stop passing ModelTypeStore. - type_processor_.reset(new syncer_v2::SharedModelTypeProcessor( - syncer::DICTIONARY, base::WeakPtr<syncer_v2::ModelTypeStore>())); + // TODO(stanisc): Controller should discover the service via SyncClient. + type_processor_.reset( + new syncer_v2::SharedModelTypeProcessor(syncer::DICTIONARY, &service_)); type_processor_for_ui_ = type_processor_->AsWeakPtrForUI(); } @@ -330,6 +331,7 @@ scoped_refptr<base::TestSimpleTaskRunner> sync_thread_runner_; MockSyncBackend backend_; MockBackendDataTypeConfigurer configurer_; + syncer_v2::FakeModelTypeService service_; }; TEST_F(NonBlockingDataTypeControllerTest, InitialState) {
diff --git a/components/test/data/arc/icon_100p.png b/components/test/data/arc/icon_100p.png new file mode 100644 index 0000000..80a5d686 --- /dev/null +++ b/components/test/data/arc/icon_100p.png Binary files differ
diff --git a/components/test/data/arc/icon_125p.png b/components/test/data/arc/icon_125p.png new file mode 100644 index 0000000..c9bae8e --- /dev/null +++ b/components/test/data/arc/icon_125p.png Binary files differ
diff --git a/components/test/data/arc/icon_133p.png b/components/test/data/arc/icon_133p.png new file mode 100644 index 0000000..565bbac --- /dev/null +++ b/components/test/data/arc/icon_133p.png Binary files differ
diff --git a/components/test/data/arc/icon_140p.png b/components/test/data/arc/icon_140p.png new file mode 100644 index 0000000..f85cae5a --- /dev/null +++ b/components/test/data/arc/icon_140p.png Binary files differ
diff --git a/components/test/data/arc/icon_150p.png b/components/test/data/arc/icon_150p.png new file mode 100644 index 0000000..e3471fd --- /dev/null +++ b/components/test/data/arc/icon_150p.png Binary files differ
diff --git a/components/test/data/arc/icon_180p.png b/components/test/data/arc/icon_180p.png new file mode 100644 index 0000000..91c8dcb --- /dev/null +++ b/components/test/data/arc/icon_180p.png Binary files differ
diff --git a/components/test/data/arc/icon_200p.png b/components/test/data/arc/icon_200p.png new file mode 100644 index 0000000..be3aa10 --- /dev/null +++ b/components/test/data/arc/icon_200p.png Binary files differ
diff --git a/components/test/data/arc/icon_250p.png b/components/test/data/arc/icon_250p.png new file mode 100644 index 0000000..4843664 --- /dev/null +++ b/components/test/data/arc/icon_250p.png Binary files differ
diff --git a/components/test/data/arc/icon_300p.png b/components/test/data/arc/icon_300p.png new file mode 100644 index 0000000..d0afd969 --- /dev/null +++ b/components/test/data/arc/icon_300p.png Binary files differ
diff --git a/components/test_runner/mock_webrtc_peer_connection_handler.cc b/components/test_runner/mock_webrtc_peer_connection_handler.cc index 3aaa91d..1fb0bc9 100644 --- a/components/test_runner/mock_webrtc_peer_connection_handler.cc +++ b/components/test_runner/mock_webrtc_peer_connection_handler.cc
@@ -9,11 +9,11 @@ #include "components/test_runner/mock_webrtc_dtmf_sender_handler.h" #include "components/test_runner/test_interfaces.h" #include "components/test_runner/web_test_delegate.h" -#include "third_party/WebKit/public/platform/WebMediaConstraints.h" #include "third_party/WebKit/public/platform/WebMediaStream.h" #include "third_party/WebKit/public/platform/WebMediaStreamSource.h" #include "third_party/WebKit/public/platform/WebMediaStreamTrack.h" #include "third_party/WebKit/public/platform/WebRTCDataChannelInit.h" +#include "third_party/WebKit/public/platform/WebRTCOfferOptions.h" #include "third_party/WebKit/public/platform/WebRTCPeerConnectionHandlerClient.h" #include "third_party/WebKit/public/platform/WebRTCStatsResponse.h" #include "third_party/WebKit/public/platform/WebRTCVoidRequest.h" @@ -178,24 +178,24 @@ void MockWebRTCPeerConnectionHandler::createOffer( const WebRTCSessionDescriptionRequest& request, const WebMediaConstraints& constraints) { - WebString should_succeed; - if (constraints.getMandatoryConstraintValue("succeed", should_succeed) && - should_succeed == "true") { - WebRTCSessionDescription session_description; - session_description.initialize("offer", "local"); - interfaces_->GetDelegate()->PostTask( - new RTCSessionDescriptionRequestSuccededTask( - this, request, session_description)); - } else - interfaces_->GetDelegate()->PostTask( - new RTCSessionDescriptionRequestFailedTask(this, request)); + interfaces_->GetDelegate()->PostTask( + new RTCSessionDescriptionRequestFailedTask(this, request)); } void MockWebRTCPeerConnectionHandler::createOffer( const WebRTCSessionDescriptionRequest& request, const blink::WebRTCOfferOptions& options) { - interfaces_->GetDelegate()->PostTask( - new RTCSessionDescriptionRequestFailedTask(this, request)); + WebString should_succeed; + if (options.iceRestart() && options.voiceActivityDetection()) { + WebRTCSessionDescription session_description; + session_description.initialize("offer", "local"); + interfaces_->GetDelegate()->PostTask( + new RTCSessionDescriptionRequestSuccededTask( + this, request, session_description)); + } else { + interfaces_->GetDelegate()->PostTask( + new RTCSessionDescriptionRequestFailedTask(this, request)); + } } void MockWebRTCPeerConnectionHandler::createAnswer(
diff --git a/components/test_runner/test_plugin.h b/components/test_runner/test_plugin.h index 129dc2a..6c52dfe8 100644 --- a/components/test_runner/test_plugin.h +++ b/components/test_runner/test_plugin.h
@@ -85,11 +85,6 @@ void didReceiveData(const char* data, int data_length) override {} void didFinishLoading() override {} void didFailLoading(const blink::WebURLError& error) override {} - void didFinishLoadingFrameRequest(const blink::WebURL& url, - void* notify_data) override {} - void didFailLoadingFrameRequest(const blink::WebURL& url, - void* notify_data, - const blink::WebURLError& error) override {} bool isPlaceholder() override; // cc::TextureLayerClient methods:
diff --git a/components/variations/variations_request_scheduler.cc b/components/variations/variations_request_scheduler.cc index 9c239afa..4834421 100644 --- a/components/variations/variations_request_scheduler.cc +++ b/components/variations/variations_request_scheduler.cc
@@ -50,8 +50,8 @@ if (base::StringToSizeT(period_min_str, &period_min)) return base::TimeDelta::FromMinutes(period_min); - // The default fetch interval is every 5 hours. - return base::TimeDelta::FromHours(5); + // The default fetch interval is every 30 minutes. + return base::TimeDelta::FromMinutes(30); } base::Closure VariationsRequestScheduler::task() const {
diff --git a/content/browser/BUILD.gn b/content/browser/BUILD.gn index 9501557..ff1b66d 100644 --- a/content/browser/BUILD.gn +++ b/content/browser/BUILD.gn
@@ -110,6 +110,7 @@ sources += [ "mojo/mojo_shell_client_host.cc", "mojo/mojo_shell_client_host.h", + "mojo/renderer_capability_filter.cc", ] # Non-iOS deps.
diff --git a/content/browser/accessibility/android_granularity_movement_browsertest.cc b/content/browser/accessibility/android_granularity_movement_browsertest.cc index 74a67a4..6ddf830 100644 --- a/content/browser/accessibility/android_granularity_movement_browsertest.cc +++ b/content/browser/accessibility/android_granularity_movement_browsertest.cc
@@ -204,7 +204,7 @@ BrowserAccessibility* pre = root->PlatformGetChild(0); ASSERT_EQ(0U, pre->PlatformChildCount()); - ASSERT_EQ(base::ASCIIToUTF16("'One, ', 'two, ', 'three!'"), + ASSERT_EQ(base::ASCIIToUTF16("'One,', 'two,', 'three!'"), TraverseNodeAtGranularity(pre, GRANULARITY_LINE)); }
diff --git a/content/browser/accessibility/browser_accessibility.cc b/content/browser/accessibility/browser_accessibility.cc index 196656c..a057213d 100644 --- a/content/browser/accessibility/browser_accessibility.cc +++ b/content/browser/accessibility/browser_accessibility.cc
@@ -41,15 +41,25 @@ if (InternalChildCount() == 0) return true; - // All of these roles may have children that we use as internal - // implementation details, but we want to expose them as leaves - // to platform accessibility APIs. + // These types of objects may have children that we use as internal + // implementation details, but we want to expose them as leaves to platform + // accessibility APIs because screen readers might be confused if they find + // any children. + if (IsSimpleTextControl() || IsTextOnlyObject()) + return true; + + // Roles whose children are only presentational according to the ARIA and + // HTML5 Specs. + // (Note that whilst ARIA buttons can have only presentational children, HTML5 + // buttons are allowed to have content.) switch (GetRole()) { - case ui::AX_ROLE_COMBO_BOX: - case ui::AX_ROLE_LINE_BREAK: + case ui::AX_ROLE_IMAGE: + case ui::AX_ROLE_MATH: + case ui::AX_ROLE_METER: + case ui::AX_ROLE_SCROLL_BAR: case ui::AX_ROLE_SLIDER: - case ui::AX_ROLE_STATIC_TEXT: - case ui::AX_ROLE_TEXT_FIELD: + case ui::AX_ROLE_SPLITTER: + case ui::AX_ROLE_PROGRESS_INDICATOR: return true; default: return false; @@ -712,7 +722,7 @@ } } -bool BrowserAccessibility::IsTextControl() const { +bool BrowserAccessibility::IsSimpleTextControl() const { // Time fields, color wells and spinner buttons might also use text fields as // constituent parts, but they are not considered text fields as a whole. switch (GetRole()) { @@ -725,6 +735,12 @@ } } +// Indicates if this object is at the root of a rich edit text control. +bool BrowserAccessibility::IsRichTextControl() const { + return HasState(ui::AX_STATE_RICHLY_EDITABLE) && + (!GetParent() || !GetParent()->HasState(ui::AX_STATE_RICHLY_EDITABLE)); +} + std::string BrowserAccessibility::ComputeAccessibleNameFromDescendants() { std::string name; for (size_t i = 0; i < InternalChildCount(); ++i) {
diff --git a/content/browser/accessibility/browser_accessibility.h b/content/browser/accessibility/browser_accessibility.h index a516b5f..e5e5927 100644 --- a/content/browser/accessibility/browser_accessibility.h +++ b/content/browser/accessibility/browser_accessibility.h
@@ -296,7 +296,9 @@ bool IsWebAreaForPresentationalIframe() const; bool IsControl() const; - bool IsTextControl() const; + bool IsSimpleTextControl() const; + // Indicates if this object is at the root of a rich edit text control. + bool IsRichTextControl() const; // If an object is focusable but has no accessible name, use this // to compute a name from its descendants.
diff --git a/content/browser/accessibility/browser_accessibility_cocoa.h b/content/browser/accessibility/browser_accessibility_cocoa.h index fbebd859..6c5a3e6 100644 --- a/content/browser/accessibility/browser_accessibility_cocoa.h +++ b/content/browser/accessibility/browser_accessibility_cocoa.h
@@ -61,10 +61,6 @@ // Returns the requested text range from this object's value attribute. - (NSString*)valueForRange:(NSRange)range; -// Indicates if this object is at the root of a rich edit text field. -@property(nonatomic, readonly, getter=isRichEditTextField) - BOOL richEditTextField; - // Internally-used method. @property(nonatomic, readonly) NSPoint origin;
diff --git a/content/browser/accessibility/browser_accessibility_cocoa.mm b/content/browser/accessibility/browser_accessibility_cocoa.mm index bf183096..20a3621 100644 --- a/content/browser/accessibility/browser_accessibility_cocoa.mm +++ b/content/browser/accessibility/browser_accessibility_cocoa.mm
@@ -228,7 +228,7 @@ }; } else if ([searchKey isEqualToString:@"AXTextFieldSearchKey"]) { return [](BrowserAccessibility* start, BrowserAccessibility* current) { - return current->GetRole() == ui::AX_ROLE_TEXT_FIELD; + return current->IsSimpleTextControl() || current->IsRichTextControl(); }; } else if ([searchKey isEqualToString:@"AXUnderlineSearchKey"]) { // TODO(dmazzoni): implement this. @@ -928,6 +928,9 @@ // Returns a string indicating the NSAccessibility role of this object. - (NSString*)role { + if (!browserAccessibility_) + return nil; + ui::AXRole role = [self internalRole]; if (role == ui::AX_ROLE_CANVAS && browserAccessibility_->GetBoolAttribute( @@ -945,9 +948,9 @@ else return NSAccessibilityButtonRole; } - if ((role == ui::AX_ROLE_TEXT_FIELD && + if ((browserAccessibility_->IsSimpleTextControl() && browserAccessibility_->HasState(ui::AX_STATE_MULTILINE)) || - [self isRichEditTextField]) { + browserAccessibility_->IsRichTextControl()) { return NSAccessibilityTextAreaRole; } @@ -1433,21 +1436,6 @@ children_.swap(*other); } -// Indicates if this object is at the root of a rich edit text field. -- (BOOL)isRichEditTextField { - if (!browserAccessibility_) - return NO; - - if (browserAccessibility_->HasState(ui::AX_STATE_RICHLY_EDITABLE) && - !(browserAccessibility_->GetParent() && - browserAccessibility_->GetParent()->HasState( - ui::AX_STATE_RICHLY_EDITABLE))) { - return YES; - } - - return NO; -} - // Returns the requested text range from this object's value attribute. - (NSString*)valueForRange:(NSRange)range { if (!browserAccessibility_)
diff --git a/content/browser/accessibility/browser_accessibility_win.cc b/content/browser/accessibility/browser_accessibility_win.cc index 99821b8..3009bfa 100644 --- a/content/browser/accessibility/browser_accessibility_win.cc +++ b/content/browser/accessibility/browser_accessibility_win.cc
@@ -3421,8 +3421,8 @@ } void BrowserAccessibilityWin::UpdateStep2ComputeHypertext() { - if (!PlatformChildCount()) { - if (IsTextControl()) + if (PlatformIsLeaf()) { + if (IsSimpleTextControl()) win_attributes_->hypertext += value(); else win_attributes_->hypertext += name(); @@ -3702,14 +3702,18 @@ DCHECK(child.GetParent() == this); // Handle the case when we are dealing with a direct text-only child. + // (Note that this object might be a platform leaf, e.g. an ARIA searchbox, + // and so InternalChild... functions need to be used. Also, direct text-only + // children should not be present at tree roots and so no cross-tree traversal + // is necessary.) if (child.IsTextOnlyObject()) { int32 hypertextOffset = 0; int32 index_in_parent = child.GetIndexInParent(); DCHECK_GE(index_in_parent, 0); - DCHECK_LT(index_in_parent, static_cast<int32>(PlatformChildCount())); + DCHECK_LT(index_in_parent, static_cast<int32>(InternalChildCount())); for (uint32 i = 0; i < static_cast<uint32>(index_in_parent); ++i) { const BrowserAccessibilityWin* sibling = - PlatformGetChild(i)->ToBrowserAccessibilityWin(); + InternalGetChild(i)->ToBrowserAccessibilityWin(); DCHECK(sibling); if (sibling->IsTextOnlyObject()) hypertextOffset += sibling->hypertext().length(); @@ -3791,8 +3795,8 @@ // We can safely assume that the endpoint is in another part of the tree or // at common parent, and that this object is a descendant of common parent. int32 endpoint_index_in_common_parent = -1; - for (uint32 i = 0; i < common_parent->PlatformChildCount(); ++i) { - const BrowserAccessibility* child = common_parent->PlatformGetChild(i); + for (uint32 i = 0; i < common_parent->InternalChildCount(); ++i) { + const BrowserAccessibility* child = common_parent->InternalGetChild(i); DCHECK(child); if (endpoint_object.IsDescendantOf(child)) { endpoint_index_in_common_parent = child->GetIndexInParent(); @@ -3812,19 +3816,19 @@ int BrowserAccessibilityWin::GetSelectionAnchor() const { int32 anchor_id = manager()->GetTreeData().sel_anchor_object_id; - BrowserAccessibilityWin* anchor_object = manager()->GetFromID( - anchor_id)->ToBrowserAccessibilityWin(); + const auto anchor_object = + manager()->GetFromID(anchor_id)->ToBrowserAccessibilityWin(); if (!anchor_object) return -1; - int32 anchor_offset = manager()->GetTreeData().sel_anchor_offset; + int anchor_offset = manager()->GetTreeData().sel_anchor_offset; return GetHypertextOffsetFromEndpoint(*anchor_object, anchor_offset); } int BrowserAccessibilityWin::GetSelectionFocus() const { int32 focus_id = manager()->GetTreeData().sel_focus_object_id; - BrowserAccessibilityWin* focus_object = manager()->GetFromID( - focus_id)->ToBrowserAccessibilityWin(); + const auto focus_object = + manager()->GetFromID(focus_id)->ToBrowserAccessibilityWin(); if (!focus_object) return -1; @@ -4023,10 +4027,8 @@ LONG start_offset, ui::TextBoundaryDirection direction) { HandleSpecialTextOffset(text, &start_offset); - if (ia2_boundary == IA2_TEXT_BOUNDARY_WORD && - GetRole() == ui::AX_ROLE_TEXT_FIELD) { + if (ia2_boundary == IA2_TEXT_BOUNDARY_WORD && IsSimpleTextControl()) return GetWordStartBoundary(static_cast<int>(start_offset), direction); - } ui::TextBoundaryType boundary = IA2TextBoundaryToTextBoundary(ia2_boundary); const std::vector<int32>& line_breaks = GetIntListAttribute( @@ -4115,7 +4117,7 @@ // Expose input-text type attribute. base::string16 type; base::string16 html_tag = GetString16Attribute(ui::AX_ATTR_HTML_TAG); - if (GetRole() == ui::AX_ROLE_TEXT_FIELD && html_tag == L"input" && + if (IsSimpleTextControl() && html_tag == L"input" && GetHtmlAttribute("type", &type)) { SanitizeStringAttributeForIA2(type, &type); win_attributes_->ia2_attributes.push_back(L"text-input-type:" + type);
diff --git a/content/browser/accessibility/dump_accessibility_events_browsertest.cc b/content/browser/accessibility/dump_accessibility_events_browsertest.cc index 304fc071..3bd1fd7 100644 --- a/content/browser/accessibility/dump_accessibility_events_browsertest.cc +++ b/content/browser/accessibility/dump_accessibility_events_browsertest.cc
@@ -213,8 +213,11 @@ #if defined(OS_WIN) #define MAYBE_AccessibilityEventsListboxNext \ DISABLED_AccessibilityEventsListboxNext +#define MAYBE_AccessibilityEventsMenuListPopup \ + DISABLED_AccessibilityEventsMenuListPopup #else #define MAYBE_AccessibilityEventsListboxNext AccessibilityEventsListboxNext +#define MAYBE_AccessibilityEventsMenuListPopup AccessibilityEventsMenuListPopup #endif IN_PROC_BROWSER_TEST_F(DumpAccessibilityEventsTest, @@ -233,7 +236,7 @@ } IN_PROC_BROWSER_TEST_F(DumpAccessibilityEventsTest, - AccessibilityEventsMenuListPopup) { + MAYBE_AccessibilityEventsMenuListPopup) { RunEventTest(FILE_PATH_LITERAL("menulist-popup.html")); }
diff --git a/content/browser/android/content_view_core_impl.cc b/content/browser/android/content_view_core_impl.cc index 0c3a6ae1..61296db 100644 --- a/content/browser/android/content_view_core_impl.cc +++ b/content/browser/android/content_view_core_impl.cc
@@ -610,18 +610,18 @@ selection_rect_pix.right(), selection_rect_pix.bottom()); } -void ContentViewCoreImpl::ShowPastePopup(int x_dip, int y_dip) { +bool ContentViewCoreImpl::ShowPastePopup(int x_dip, int y_dip) { RenderWidgetHostViewAndroid* view = GetRenderWidgetHostViewAndroid(); if (!view) - return; + return false; view->OnShowingPastePopup(gfx::PointF(x_dip, y_dip)); JNIEnv* env = AttachCurrentThread(); ScopedJavaLocalRef<jobject> obj = java_ref_.get(env); if (obj.is_null()) - return; - Java_ContentViewCore_showPastePopupWithFeedback( + return false; + return Java_ContentViewCore_showPastePopupWithFeedback( env, obj.obj(), static_cast<jint>(x_dip * dpi_scale()), static_cast<jint>(y_dip * dpi_scale())); }
diff --git a/content/browser/android/content_view_core_impl.h b/content/browser/android/content_view_core_impl.h index c3acf0b..10444f75 100644 --- a/content/browser/android/content_view_core_impl.h +++ b/content/browser/android/content_view_core_impl.h
@@ -53,7 +53,7 @@ ui::ViewAndroid* GetViewAndroid() const override; ui::WindowAndroid* GetWindowAndroid() const override; const scoped_refptr<cc::Layer>& GetLayer() const override; - void ShowPastePopup(int x, int y) override; + bool ShowPastePopup(int x, int y) override; void GetScaledContentBitmap( float scale, SkColorType preferred_color_type,
diff --git a/content/browser/bad_message.h b/content/browser/bad_message.h index 31f166c..356eb0e2 100644 --- a/content/browser/bad_message.h +++ b/content/browser/bad_message.h
@@ -123,6 +123,7 @@ RFH_OWNER_PROPERTY = 99, BDH_EMPTY_OR_INVALID_FILTERS = 100, WC_CONTENT_WITH_CERT_ERRORS_BAD_SECURITY_INFO = 101, + RFMF_RENDERER_FAKED_ITS_OWN_DEATH = 102, // Please add new elements here. The naming convention is abbreviated class // name (e.g. RenderFrameHost becomes RFH) plus a unique description of the
diff --git a/content/browser/bluetooth/bluetooth_dispatcher_host.cc b/content/browser/bluetooth/bluetooth_dispatcher_host.cc index 898a7283..7758a3e 100644 --- a/content/browser/bluetooth/bluetooth_dispatcher_host.cc +++ b/content/browser/bluetooth/bluetooth_dispatcher_host.cc
@@ -11,6 +11,8 @@ #include "content/browser/bluetooth/bluetooth_dispatcher_host.h" +#include <utility> + #include "base/bind.h" #include "base/single_thread_task_runner.h" #include "base/strings/utf_string_conversions.h" @@ -297,7 +299,7 @@ devices_with_discovered_services_.clear(); } - set_adapter(mock_adapter.Pass()); + set_adapter(std::move(mock_adapter)); } BluetoothDispatcherHost::~BluetoothDispatcherHost() {
diff --git a/content/browser/browser_context.cc b/content/browser/browser_context.cc index be99f673..d516cd48 100644 --- a/content/browser/browser_context.cc +++ b/content/browser/browser_context.cc
@@ -122,8 +122,6 @@ BrowserContext* context) { DCHECK_CURRENTLY_ON(BrowserThread::UI); if (!context->GetUserData(kDownloadManagerKeyName)) { - ResourceDispatcherHostImpl* rdh = ResourceDispatcherHostImpl::Get(); - DCHECK(rdh); DownloadManager* download_manager = new DownloadManagerImpl( GetContentClient()->browser()->GetNetLog(), context);
diff --git a/content/browser/devtools/site_per_process_devtools_browsertest.cc b/content/browser/devtools/site_per_process_devtools_browsertest.cc index 661ab8f..489cd50 100644 --- a/content/browser/devtools/site_per_process_devtools_browsertest.cc +++ b/content/browser/devtools/site_per_process_devtools_browsertest.cc
@@ -109,8 +109,7 @@ IN_PROC_BROWSER_TEST_F(SitePerProcessDevToolsBrowserTest, AgentHostForFrames) { host_resolver()->AddRule("*", "127.0.0.1"); - ASSERT_TRUE(test_server()->Start()); - GURL main_url(test_server()->GetURL("files/site_per_process_main.html")); + GURL main_url(embedded_test_server()->GetURL("/site_per_process_main.html")); NavigateToURL(shell(), main_url); scoped_refptr<DevToolsAgentHost> page_agent = @@ -127,7 +126,7 @@ // Load same-site page into iframe. FrameTreeNode* child = root->child_at(0); - GURL http_url(test_server()->GetURL("files/title1.html")); + GURL http_url(embedded_test_server()->GetURL("/title1.html")); NavigateFrameToURL(child, http_url); scoped_refptr<DevToolsAgentHost> child_frame_agent = @@ -136,7 +135,7 @@ // Load cross-site page into iframe. GURL::Replacements replace_host; - GURL cross_site_url(test_server()->GetURL("files/title2.html")); + GURL cross_site_url(embedded_test_server()->GetURL("/title2.html")); replace_host.SetHostStr("foo.com"); cross_site_url = cross_site_url.ReplaceComponents(replace_host); NavigateFrameToURL(root->child_at(0), cross_site_url);
diff --git a/content/browser/download/download_browsertest.cc b/content/browser/download/download_browsertest.cc index 37b9b858..6b5cb00 100644 --- a/content/browser/download/download_browsertest.cc +++ b/content/browser/download/download_browsertest.cc
@@ -5,10 +5,14 @@ // This file contains download browser tests that are known to be runnable // in a pure content context. Over time tests should be migrated here. +#include <vector> + +#include "base/callback_helpers.h" #include "base/command_line.h" #include "base/files/file_path.h" #include "base/files/file_util.h" #include "base/files/scoped_temp_dir.h" +#include "base/format_macros.h" #include "base/memory/ref_counted.h" #include "base/strings/stringprintf.h" #include "base/strings/utf_string_conversions.h" @@ -28,6 +32,7 @@ #include "content/public/test/content_browser_test.h" #include "content/public/test/content_browser_test_utils.h" #include "content/public/test/download_test_observer.h" +#include "content/public/test/test_download_request_handler.h" #include "content/public/test/test_file_error_injector.h" #include "content/public/test/test_utils.h" #include "content/shell/browser/shell.h" @@ -37,7 +42,6 @@ #include "net/test/embedded_test_server/embedded_test_server.h" #include "net/test/embedded_test_server/http_request.h" #include "net/test/embedded_test_server/http_response.h" -#include "net/test/spawned_test_server/spawned_test_server.h" #include "net/test/url_request/url_request_mock_http_job.h" #include "net/test/url_request/url_request_slow_download_job.h" #include "testing/gmock/include/gmock/gmock.h" @@ -378,71 +382,11 @@ std::vector<DownloadOpenDelayedCallback> delayed_callbacks_; }; -// Record all state transitions and byte counts on the observed download. -class RecordingDownloadObserver : DownloadItem::Observer { - public: - struct RecordStruct { - DownloadItem::DownloadState state; - int bytes_received; - }; - - typedef std::vector<RecordStruct> RecordVector; - - RecordingDownloadObserver(DownloadItem* download) - : download_(download) { - last_state_.state = download->GetState(); - last_state_.bytes_received = download->GetReceivedBytes(); - download_->AddObserver(this); - } - - ~RecordingDownloadObserver() override { RemoveObserver(); } - - void CompareToExpectedRecord(const RecordStruct expected[], size_t size) { - EXPECT_EQ(size, record_.size()); - int min = size > record_.size() ? record_.size() : size; - for (int i = 0; i < min; ++i) { - EXPECT_EQ(expected[i].state, record_[i].state) << "Iteration " << i; - EXPECT_EQ(expected[i].bytes_received, record_[i].bytes_received) - << "Iteration " << i; - } - } - - private: - void OnDownloadUpdated(DownloadItem* download) override { - DCHECK_EQ(download_, download); - DownloadItem::DownloadState state = download->GetState(); - int bytes = download->GetReceivedBytes(); - if (last_state_.state != state || last_state_.bytes_received > bytes) { - last_state_.state = state; - last_state_.bytes_received = bytes; - record_.push_back(last_state_); - } - } - - void OnDownloadDestroyed(DownloadItem* download) override { - DCHECK_EQ(download_, download); - RemoveObserver(); - } - - void RemoveObserver() { - if (download_) { - download_->RemoveObserver(this); - download_ = NULL; - } - } - - DownloadItem* download_; - RecordStruct last_state_; - RecordVector record_; -}; - // Get the next created download. class DownloadCreateObserver : DownloadManager::Observer { public: DownloadCreateObserver(DownloadManager* manager) - : manager_(manager), - item_(NULL), - waiting_(false) { + : manager_(manager), item_(NULL) { manager_->AddObserver(this); } @@ -463,16 +407,16 @@ if (!item_) item_ = download; - if (waiting_) - base::MessageLoopForUI::current()->QuitWhenIdle(); + if (!completion_closure_.is_null()) + base::ResetAndReturn(&completion_closure_).Run(); } DownloadItem* WaitForFinished() { DCHECK_CURRENTLY_ON(BrowserThread::UI); if (!item_) { - waiting_ = true; - RunMessageLoop(); - waiting_ = false; + base::RunLoop run_loop; + completion_closure_ = run_loop.QuitClosure(); + run_loop.Run(); } return item_; } @@ -480,28 +424,11 @@ private: DownloadManager* manager_; DownloadItem* item_; - bool waiting_; + base::Closure completion_closure_; }; - -// Filter for waiting for a certain number of bytes. -bool DataReceivedFilter(int number_of_bytes, DownloadItem* download) { - return download->GetReceivedBytes() >= number_of_bytes; -} - -// Filter for download completion. -bool DownloadCompleteFilter(DownloadItem* download) { - return download->GetState() == DownloadItem::COMPLETE; -} - -// Filter for saving the size of the download when the first IN_PROGRESS -// is hit. -bool InitialSizeFilter(int* download_size, DownloadItem* download) { - if (download->GetState() != DownloadItem::IN_PROGRESS) - return false; - - *download_size = download->GetReceivedBytes(); - return true; +bool IsDownloadInState(DownloadItem::DownloadState state, DownloadItem* item) { + return item->GetState() == state; } // Request handler to be used with CreateRedirectHandler(). @@ -530,12 +457,15 @@ // Request handler to be used with CreateBasicResponseHandler(). scoped_ptr<net::test_server::HttpResponse> HandleRequestAndSendBasicResponse( const std::string& relative_url, + const base::StringPairs& headers, const std::string& content_type, const std::string& body, const net::test_server::HttpRequest& request) { scoped_ptr<net::test_server::BasicHttpResponse> response; if (request.relative_url == relative_url) { response.reset(new net::test_server::BasicHttpResponse); + for (const auto& pair : headers) + response->AddCustomHeader(pair.first, pair.second); response->set_content_type(content_type); response->set_content(body); } @@ -546,27 +476,64 @@ // HTTP 200 status code, a Content-Type header and a body. net::EmbeddedTestServer::HandleRequestCallback CreateBasicResponseHandler( const std::string& relative_url, + const base::StringPairs& headers, const std::string& content_type, const std::string& body) { - return base::Bind( - &HandleRequestAndSendBasicResponse, relative_url, content_type, body); + return base::Bind(&HandleRequestAndSendBasicResponse, relative_url, headers, + content_type, body); } -} // namespace +// Helper class to "flatten" handling of +// TestDownloadRequestHandler::OnStartHandler. +class TestRequestStartHandler { + public: + // Construct an OnStartHandler that can be set as the on_start_handler for + // TestDownloadRequestHandler::Parameters. + TestDownloadRequestHandler::OnStartHandler GetOnStartHandler() { + EXPECT_FALSE(used_) << "GetOnStartHandler() should only be called once for " + "an instance of TestRequestStartHandler."; + used_ = true; + return base::Bind(&TestRequestStartHandler::OnStartHandler, + base::Unretained(this)); + } + + // Wait until the OnStartHandlers returned in a prior call to + // GetOnStartHandler() is invoked. + void WaitForCallback() { + if (response_callback_.is_null()) + run_loop_.Run(); + } + + // Respond to the OnStartHandler() invocation using |headers| and |error|. + void RespondWith(const std::string& headers, net::Error error) { + ASSERT_FALSE(response_callback_.is_null()); + response_callback_.Run(headers, error); + } + + // Return the headers returned from the invocation of OnStartHandler. + const net::HttpRequestHeaders& headers() const { + EXPECT_FALSE(response_callback_.is_null()); + return request_headers_; + } + + private: + void OnStartHandler(const net::HttpRequestHeaders& headers, + const TestDownloadRequestHandler::OnStartResponseCallback& + response_callback) { + request_headers_ = headers; + response_callback_ = response_callback; + if (run_loop_.running()) + run_loop_.Quit(); + } + + bool used_ = false; + base::RunLoop run_loop_; + net::HttpRequestHeaders request_headers_; + TestDownloadRequestHandler::OnStartResponseCallback response_callback_; +}; class DownloadContentTest : public ContentBrowserTest { protected: - // An initial send from a website of at least this size will not be - // help up by buffering in the underlying downloads ByteStream data - // transfer. This is important because on resumption tests we wait - // until we've gotten the data we expect before allowing the test server - // to send its reset, to get around hard close semantics on the Windows - // socket layer implementation. - int GetSafeBufferChunk() const { - return (DownloadResourceHandler::kDownloadByteStreamSize / - ByteStreamWriter::kFractionBufferBeforeSending) + 1; - } - void SetUpOnMainThread() override { ASSERT_TRUE(downloads_directory_.CreateUniqueTempDir()); @@ -601,19 +568,22 @@ DownloadTestObserver::ON_DANGEROUS_DOWNLOAD_FAIL); } - // Create a DownloadTestObserverInProgress that will wait for the - // specified number of downloads to start. - DownloadCreateObserver* CreateInProgressWaiter( - Shell* shell, int num_downloads) { - DownloadManager* download_manager = DownloadManagerForShell(shell); - return new DownloadCreateObserver(download_manager); + void WaitForInterrupt(DownloadItem* download) { + DownloadUpdatedObserver( + download, base::Bind(&IsDownloadInState, DownloadItem::INTERRUPTED)) + .WaitForEvent(); } - DownloadTestObserver* CreateInterruptedWaiter( - Shell* shell, int num_downloads) { - DownloadManager* download_manager = DownloadManagerForShell(shell); - return new DownloadTestObserverInterrupted(download_manager, num_downloads, - DownloadTestObserver::ON_DANGEROUS_DOWNLOAD_FAIL); + void WaitForInProgress(DownloadItem* download) { + DownloadUpdatedObserver( + download, base::Bind(&IsDownloadInState, DownloadItem::IN_PROGRESS)) + .WaitForEvent(); + } + + void WaitForCompletion(DownloadItem* download) { + DownloadUpdatedObserver( + download, base::Bind(&IsDownloadInState, DownloadItem::COMPLETE)) + .WaitForEvent(); } // Note: Cannot be used with other alternative DownloadFileFactorys @@ -675,67 +645,35 @@ // Start a download and return the item. DownloadItem* StartDownloadAndReturnItem(GURL url) { scoped_ptr<DownloadCreateObserver> observer( - CreateInProgressWaiter(shell(), 1)); - NavigateToURL(shell(), url); - observer->WaitForFinished(); - std::vector<DownloadItem*> downloads; - DownloadManagerForShell(shell())->GetAllDownloads(&downloads); - EXPECT_EQ(1u, downloads.size()); - if (1u != downloads.size()) - return NULL; - return downloads[0]; + new DownloadCreateObserver(DownloadManagerForShell(shell()))); + shell()->LoadURL(url); + return observer->WaitForFinished(); } - // Wait for data - void WaitForData(DownloadItem* download, int size) { - DownloadUpdatedObserver data_observer( - download, base::Bind(&DataReceivedFilter, size)); - data_observer.WaitForEvent(); - ASSERT_EQ(size, download->GetReceivedBytes()); - ASSERT_EQ(DownloadItem::IN_PROGRESS, download->GetState()); - } + static void ReadAndVerifyFileContents(int seed, + int64_t expected_size, + const base::FilePath& path) { + base::File file(path, base::File::FLAG_OPEN | base::File::FLAG_READ); + ASSERT_TRUE(file.IsValid()); + int64_t file_length = file.GetLength(); + ASSERT_EQ(expected_size, file_length); - // Tell the test server to release a pending RST and confirm - // that the interrupt is received properly (for download resumption - // testing). - void ReleaseRSTAndConfirmInterruptForResume(DownloadItem* download) { - scoped_ptr<DownloadTestObserver> rst_observer( - CreateInterruptedWaiter(shell(), 1)); - NavigateToURL(shell(), spawned_test_server()->GetURL("download-finish")); - rst_observer->WaitForFinished(); - EXPECT_EQ(DownloadItem::INTERRUPTED, download->GetState()); - } + const int64_t kBufferSize = 64 * 1024; + std::vector<char> pattern; + std::vector<char> data; + pattern.resize(kBufferSize); + data.resize(kBufferSize); + for (int64_t offset = 0; offset < file_length;) { + int bytes_read = file.Read(offset, &data.front(), kBufferSize); + ASSERT_LT(0, bytes_read); + ASSERT_GE(kBufferSize, bytes_read); - // Confirm file status expected for the given location in a stream - // provided by the resume test server. - void ConfirmFileStatusForResume( - DownloadItem* download, bool file_exists, - int received_bytes, int total_bytes, - const base::FilePath& expected_filename) { - // expected_filename is only known if the file exists. - ASSERT_EQ(file_exists, !expected_filename.empty()); - EXPECT_EQ(received_bytes, download->GetReceivedBytes()); - EXPECT_EQ(total_bytes, download->GetTotalBytes()); - EXPECT_EQ(expected_filename.value(), - download->GetFullPath().BaseName().value()); - EXPECT_EQ(file_exists, - (!download->GetFullPath().empty() && - base::PathExists(download->GetFullPath()))); - - if (file_exists) { - std::string file_contents; - EXPECT_TRUE(base::ReadFileToString( - download->GetFullPath(), &file_contents)); - - ASSERT_EQ(static_cast<size_t>(received_bytes), file_contents.size()); - for (int i = 0; i < received_bytes; ++i) { - EXPECT_EQ(static_cast<char>((i * 2 + 15) % 256), file_contents[i]) - << "File contents diverged at position " << i - << " for " << expected_filename.value(); - - if (static_cast<char>((i * 2 + 15) % 256) != file_contents[i]) - return; - } + TestDownloadRequestHandler::GetPatternBytes(seed, offset, bytes_read, + &pattern.front()); + ASSERT_EQ(0, memcmp(&pattern.front(), &data.front(), bytes_read)) + << "Comparing block at offset " << offset << " and length " + << bytes_read; + offset += bytes_read; } } @@ -752,23 +690,19 @@ scoped_ptr<TestShellDownloadManagerDelegate> test_delegate_; }; +} // namespace + IN_PROC_BROWSER_TEST_F(DownloadContentTest, DownloadCancelled) { SetupEnsureNoPendingDownloads(); // Create a download, wait until it's started, and confirm // we're in the expected state. - scoped_ptr<DownloadCreateObserver> observer( - CreateInProgressWaiter(shell(), 1)); - NavigateToURL(shell(), GURL(net::URLRequestSlowDownloadJob::kUnknownSizeUrl)); - observer->WaitForFinished(); - - std::vector<DownloadItem*> downloads; - DownloadManagerForShell(shell())->GetAllDownloads(&downloads); - ASSERT_EQ(1u, downloads.size()); - ASSERT_EQ(DownloadItem::IN_PROGRESS, downloads[0]->GetState()); + DownloadItem* download = StartDownloadAndReturnItem( + GURL(net::URLRequestSlowDownloadJob::kUnknownSizeUrl)); + ASSERT_EQ(DownloadItem::IN_PROGRESS, download->GetState()); // Cancel the download and wait for download system quiesce. - downloads[0]->Cancel(true); + download->Cancel(true); scoped_refptr<DownloadTestFlushObserver> flush_observer( new DownloadTestFlushObserver(DownloadManagerForShell(shell()))); flush_observer->WaitForFlush(); @@ -784,28 +718,14 @@ // Create a download, wait until it's started, and confirm // we're in the expected state. - scoped_ptr<DownloadCreateObserver> observer1( - CreateInProgressWaiter(shell(), 1)); - NavigateToURL(shell(), GURL(net::URLRequestSlowDownloadJob::kUnknownSizeUrl)); - observer1->WaitForFinished(); - - std::vector<DownloadItem*> downloads; - DownloadManagerForShell(shell())->GetAllDownloads(&downloads); - ASSERT_EQ(1u, downloads.size()); - ASSERT_EQ(DownloadItem::IN_PROGRESS, downloads[0]->GetState()); - DownloadItem* download1 = downloads[0]; // The only download. + DownloadItem* download1 = StartDownloadAndReturnItem( + GURL(net::URLRequestSlowDownloadJob::kUnknownSizeUrl)); + ASSERT_EQ(DownloadItem::IN_PROGRESS, download1->GetState()); // Start the second download and wait until it's done. GURL url(net::URLRequestMockHTTPJob::GetMockUrl("download-test.lib")); - // Download the file and wait. - NavigateToURLAndWaitForDownload(shell(), url, DownloadItem::COMPLETE); - - // Should now have 2 items on the manager. - downloads.clear(); - DownloadManagerForShell(shell())->GetAllDownloads(&downloads); - ASSERT_EQ(2u, downloads.size()); - // We don't know the order of the downloads. - DownloadItem* download2 = downloads[(download1 == downloads[0]) ? 1 : 0]; + DownloadItem* download2 = StartDownloadAndReturnItem(url); + WaitForCompletion(download2); ASSERT_EQ(DownloadItem::IN_PROGRESS, download1->GetState()); ASSERT_EQ(DownloadItem::COMPLETE, download2->GetState()); @@ -962,21 +882,15 @@ // works properly. IN_PROC_BROWSER_TEST_F(DownloadContentTest, ShutdownInProgress) { // Create a download that won't complete. - scoped_ptr<DownloadCreateObserver> observer( - CreateInProgressWaiter(shell(), 1)); - NavigateToURL(shell(), GURL(net::URLRequestSlowDownloadJob::kUnknownSizeUrl)); - observer->WaitForFinished(); + DownloadItem* download = StartDownloadAndReturnItem( + GURL(net::URLRequestSlowDownloadJob::kUnknownSizeUrl)); - // Get the item. - std::vector<DownloadItem*> items; - DownloadManagerForShell(shell())->GetAllDownloads(&items); - ASSERT_EQ(1u, items.size()); - EXPECT_EQ(DownloadItem::IN_PROGRESS, items[0]->GetState()); + EXPECT_EQ(DownloadItem::IN_PROGRESS, download->GetState()); // Shutdown the download manager and make sure we get the right // notifications in the right order. StrictMock<MockDownloadItemObserver> item_observer; - items[0]->AddObserver(&item_observer); + download->AddObserver(&item_observer); MockDownloadManagerObserver manager_observer( DownloadManagerForShell(shell())); // Don't care about ModelChanged() events. @@ -988,11 +902,12 @@ EXPECT_CALL(manager_observer, MockManagerGoingDown( DownloadManagerForShell(shell()))) .WillOnce(Return()); - EXPECT_CALL(item_observer, OnDownloadUpdated( - AllOf(items[0], - Property(&DownloadItem::GetState, DownloadItem::CANCELLED)))) + EXPECT_CALL( + item_observer, + OnDownloadUpdated(AllOf(download, Property(&DownloadItem::GetState, + DownloadItem::CANCELLED)))) .WillOnce(Return()); - EXPECT_CALL(item_observer, OnDownloadDestroyed(items[0])) + EXPECT_CALL(item_observer, OnDownloadDestroyed(download)) .WillOnce(Return()); } @@ -1009,7 +924,6 @@ BrowserThread::PostTask(BrowserThread::IO, FROM_HERE, base::Bind(&base::PlatformThread::Sleep, base::TimeDelta::FromMilliseconds(25))); - items.clear(); } // Try to shutdown just after we release the download file, by delaying @@ -1068,237 +982,222 @@ DownloadManagerForShell(shell())->Shutdown(); } -IN_PROC_BROWSER_TEST_F(DownloadContentTest, ResumeInterruptedDownload) { +// Test resumption with a response that contains strong validators. +IN_PROC_BROWSER_TEST_F(DownloadContentTest, Resume_WithStrongValidators) { base::CommandLine::ForCurrentProcess()->AppendSwitch( switches::kEnableDownloadResumption); - ASSERT_TRUE(spawned_test_server()->Start()); - GURL url = spawned_test_server()->GetURL( - base::StringPrintf("rangereset?size=%d&rst_boundary=%d", - GetSafeBufferChunk() * 3, GetSafeBufferChunk())); + TestDownloadRequestHandler request_handler; + TestDownloadRequestHandler::Parameters parameters = + TestDownloadRequestHandler::Parameters::WithSingleInterruption(); + const TestDownloadRequestHandler::InjectedError interruption = + parameters.injected_errors.front(); + request_handler.StartServing(parameters); - MockDownloadManagerObserver dm_observer(DownloadManagerForShell(shell())); - EXPECT_CALL(dm_observer, OnDownloadCreated(_,_)).Times(1); + DownloadItem* download = StartDownloadAndReturnItem(request_handler.url()); + WaitForInterrupt(download); - DownloadItem* download(StartDownloadAndReturnItem(url)); - WaitForData(download, GetSafeBufferChunk()); - ::testing::Mock::VerifyAndClearExpectations(&dm_observer); + ASSERT_EQ(interruption.offset, download->GetReceivedBytes()); + ASSERT_EQ(parameters.size, download->GetTotalBytes()); - // Confirm resumption while in progress doesn't do anything. download->Resume(); - ASSERT_EQ(GetSafeBufferChunk(), download->GetReceivedBytes()); - ASSERT_EQ(DownloadItem::IN_PROGRESS, download->GetState()); + WaitForCompletion(download); - // Tell the server to send the RST and confirm the interrupt happens. - ReleaseRSTAndConfirmInterruptForResume(download); - ConfirmFileStatusForResume( - download, true, GetSafeBufferChunk(), GetSafeBufferChunk() * 3, - base::FilePath(FILE_PATH_LITERAL("rangereset.crdownload"))); + ASSERT_EQ(parameters.size, download->GetReceivedBytes()); + ASSERT_EQ(parameters.size, download->GetTotalBytes()); + ASSERT_NO_FATAL_FAILURE(ReadAndVerifyFileContents( + parameters.pattern_generator_seed, parameters.size, + download->GetTargetFilePath())); - // Resume, confirming received bytes on resumption is correct. - // Make sure no creation calls are included. - EXPECT_CALL(dm_observer, OnDownloadCreated(_,_)).Times(0); - int initial_size = 0; - DownloadUpdatedObserver initial_size_observer( - download, base::Bind(&InitialSizeFilter, &initial_size)); - download->Resume(); - initial_size_observer.WaitForEvent(); - EXPECT_EQ(GetSafeBufferChunk(), initial_size); - ::testing::Mock::VerifyAndClearExpectations(&dm_observer); + // Characterization risk: The next portion of the test examines the requests + // that were sent out while downloading our resource. These requests + // correspond to the requests that were generated by the browser and the + // downloads system and may change as implementation details change. + TestDownloadRequestHandler::CompletedRequests requests; + request_handler.GetCompletedRequestInfo(&requests); - // and wait for expected data. - WaitForData(download, GetSafeBufferChunk() * 2); + ASSERT_EQ(2u, requests.size()); - // Tell the server to send the RST and confirm the interrupt happens. - ReleaseRSTAndConfirmInterruptForResume(download); - ConfirmFileStatusForResume( - download, true, GetSafeBufferChunk() * 2, GetSafeBufferChunk() * 3, - base::FilePath(FILE_PATH_LITERAL("rangereset.crdownload"))); + // The first request only transferrs bytes up until the interruption point. + EXPECT_EQ(interruption.offset, requests[0].transferred_byte_count); - // Resume and wait for completion. - DownloadUpdatedObserver completion_observer( - download, base::Bind(DownloadCompleteFilter)); - download->Resume(); - completion_observer.WaitForEvent(); + // The next request should only have transferred the remainder of the + // resource. + EXPECT_EQ(parameters.size - interruption.offset, + requests[1].transferred_byte_count); - ConfirmFileStatusForResume( - download, true, GetSafeBufferChunk() * 3, GetSafeBufferChunk() * 3, - base::FilePath(FILE_PATH_LITERAL("rangereset"))); + std::string value; + ASSERT_TRUE(requests[1].request_headers.GetHeader( + net::HttpRequestHeaders::kIfRange, &value)); + EXPECT_EQ(parameters.etag, value); - // Confirm resumption while complete doesn't do anything. - download->Resume(); - ASSERT_EQ(GetSafeBufferChunk() * 3, download->GetReceivedBytes()); - ASSERT_EQ(DownloadItem::COMPLETE, download->GetState()); - RunAllPendingInMessageLoop(); - ASSERT_EQ(GetSafeBufferChunk() * 3, download->GetReceivedBytes()); - ASSERT_EQ(DownloadItem::COMPLETE, download->GetState()); + ASSERT_TRUE(requests[1].request_headers.GetHeader( + net::HttpRequestHeaders::kRange, &value)); + EXPECT_EQ(base::StringPrintf("bytes=%" PRId64 "-", interruption.offset), + value); } -// Confirm restart fallback happens if a range request is bounced. -IN_PROC_BROWSER_TEST_F(DownloadContentTest, ResumeInterruptedDownloadNoRange) { - base::CommandLine::ForCurrentProcess()->AppendSwitch( - switches::kEnableDownloadResumption); - ASSERT_TRUE(spawned_test_server()->Start()); - - // Auto-restart if server doesn't handle ranges. - GURL url = spawned_test_server()->GetURL(base::StringPrintf( - // First download hits an RST, rest don't, no ranges. - "rangereset?size=%d&rst_boundary=%d&" - "token=NoRange&rst_limit=1&bounce_range", - GetSafeBufferChunk() * 3, GetSafeBufferChunk())); - - // Start the download and wait for first data chunk. - DownloadItem* download(StartDownloadAndReturnItem(url)); - WaitForData(download, GetSafeBufferChunk()); - - RecordingDownloadObserver recorder(download); - - ReleaseRSTAndConfirmInterruptForResume(download); - ConfirmFileStatusForResume( - download, true, GetSafeBufferChunk(), GetSafeBufferChunk() * 3, - base::FilePath(FILE_PATH_LITERAL("rangereset.crdownload"))); - - DownloadUpdatedObserver completion_observer( - download, base::Bind(DownloadCompleteFilter)); - download->Resume(); - completion_observer.WaitForEvent(); - - ConfirmFileStatusForResume( - download, true, GetSafeBufferChunk() * 3, GetSafeBufferChunk() * 3, - base::FilePath(FILE_PATH_LITERAL("rangereset"))); - - static const RecordingDownloadObserver::RecordStruct expected_record[] = { - // Result of RST - {DownloadItem::INTERRUPTED, GetSafeBufferChunk()}, - // Starting continuation - {DownloadItem::IN_PROGRESS, GetSafeBufferChunk()}, - // Notification of receiving whole file. - {DownloadItem::IN_PROGRESS, 0}, - // Completion. - {DownloadItem::COMPLETE, GetSafeBufferChunk() * 3}, - }; - - recorder.CompareToExpectedRecord(expected_record, arraysize(expected_record)); -} - -// Confirm we don't try to resume if we don't have a verifier. +// A partial resumption results in an HTTP 200 response. I.e. the server ignored +// the range request and sent the entire resource instead. For If-Range requests +// (as opposed to If-Match), the behavior for a precondition failure is also to +// respond with a 200. So this test case covers both validation failure and +// ignoring the range request. IN_PROC_BROWSER_TEST_F(DownloadContentTest, - ResumeInterruptedDownloadNoVerifiers) { + Resume_RestartIfNotPartialResponse) { base::CommandLine::ForCurrentProcess()->AppendSwitch( switches::kEnableDownloadResumption); - ASSERT_TRUE(spawned_test_server()->Start()); + const int kOriginalPatternGeneratorSeed = 1; + const int kNewPatternGeneratorSeed = 2; - GURL url = spawned_test_server()->GetURL(base::StringPrintf( - // First download hits an RST, rest don't, no verifiers. - "rangereset?size=%d&rst_boundary=%d&" - "token=NoRange&rst_limit=1&no_verifiers", - GetSafeBufferChunk() * 3, GetSafeBufferChunk())); + TestDownloadRequestHandler::Parameters parameters = + TestDownloadRequestHandler::Parameters::WithSingleInterruption(); + parameters.pattern_generator_seed = kOriginalPatternGeneratorSeed; + const TestDownloadRequestHandler::InjectedError interruption = + parameters.injected_errors.front(); - // Start the download and wait for first data chunk. - DownloadItem* download(StartDownloadAndReturnItem(url)); - WaitForData(download, GetSafeBufferChunk()); + TestDownloadRequestHandler request_handler; + request_handler.StartServing(parameters); - RecordingDownloadObserver recorder(download); + DownloadItem* download = StartDownloadAndReturnItem(request_handler.url()); + WaitForInterrupt(download); - ReleaseRSTAndConfirmInterruptForResume(download); - ConfirmFileStatusForResume( - download, false, GetSafeBufferChunk(), GetSafeBufferChunk() * 3, - base::FilePath()); + ASSERT_EQ(interruption.offset, download->GetReceivedBytes()); + ASSERT_EQ(parameters.size, download->GetTotalBytes()); - DownloadUpdatedObserver completion_observer( - download, base::Bind(DownloadCompleteFilter)); + parameters = TestDownloadRequestHandler::Parameters(); + parameters.support_byte_ranges = false; + parameters.pattern_generator_seed = kNewPatternGeneratorSeed; + request_handler.StartServing(parameters); + download->Resume(); - completion_observer.WaitForEvent(); + WaitForCompletion(download); - ConfirmFileStatusForResume( - download, true, GetSafeBufferChunk() * 3, GetSafeBufferChunk() * 3, - base::FilePath(FILE_PATH_LITERAL("rangereset"))); + ASSERT_EQ(parameters.size, download->GetReceivedBytes()); + ASSERT_EQ(parameters.size, download->GetTotalBytes()); + ASSERT_NO_FATAL_FAILURE( + ReadAndVerifyFileContents(kNewPatternGeneratorSeed, parameters.size, + download->GetTargetFilePath())); - static const RecordingDownloadObserver::RecordStruct expected_record[] = { - // Result of RST - {DownloadItem::INTERRUPTED, GetSafeBufferChunk()}, - // Restart for lack of verifiers - {DownloadItem::IN_PROGRESS, 0}, - // Completion. - {DownloadItem::COMPLETE, GetSafeBufferChunk() * 3}, - }; + // When the downloads system sees the full response, it should accept the + // response without restarting. On the network, we should deterministically + // see two requests: + // * The original request which transfers upto our interruption point. + // * The resumption attempt, which receives the entire entity. + TestDownloadRequestHandler::CompletedRequests requests; + request_handler.GetCompletedRequestInfo(&requests); - recorder.CompareToExpectedRecord(expected_record, arraysize(expected_record)); + ASSERT_EQ(2u, requests.size()); + + // The first request only transfers data up to the interruption point. + EXPECT_EQ(interruption.offset, requests[0].transferred_byte_count); + + // The second request transfers the entire response. + EXPECT_EQ(parameters.size, requests[1].transferred_byte_count); + + std::string value; + ASSERT_TRUE(requests[1].request_headers.GetHeader( + net::HttpRequestHeaders::kIfRange, &value)); + EXPECT_EQ(parameters.etag, value); + + ASSERT_TRUE(requests[1].request_headers.GetHeader( + net::HttpRequestHeaders::kRange, &value)); + EXPECT_EQ(base::StringPrintf("bytes=%" PRId64 "-", interruption.offset), + value); } -IN_PROC_BROWSER_TEST_F(DownloadContentTest, ResumeWithDeletedFile) { +// Confirm we restart if we don't have a verifier. +IN_PROC_BROWSER_TEST_F(DownloadContentTest, Resume_RestartIfNoETag) { base::CommandLine::ForCurrentProcess()->AppendSwitch( switches::kEnableDownloadResumption); - ASSERT_TRUE(spawned_test_server()->Start()); + const int kOriginalPatternGeneratorSeed = 1; + const int kNewPatternGeneratorSeed = 2; - GURL url = spawned_test_server()->GetURL(base::StringPrintf( - // First download hits an RST, rest don't - "rangereset?size=%d&rst_boundary=%d&" - "token=NoRange&rst_limit=1", - GetSafeBufferChunk() * 3, GetSafeBufferChunk())); + TestDownloadRequestHandler::Parameters parameters = + TestDownloadRequestHandler::Parameters::WithSingleInterruption(); + ASSERT_EQ(1u, parameters.injected_errors.size()); + parameters.etag.clear(); + parameters.pattern_generator_seed = kOriginalPatternGeneratorSeed; - // Start the download and wait for first data chunk. - DownloadItem* download(StartDownloadAndReturnItem(url)); - WaitForData(download, GetSafeBufferChunk()); + TestDownloadRequestHandler request_handler; + request_handler.StartServing(parameters); + DownloadItem* download = StartDownloadAndReturnItem(request_handler.url()); + WaitForInterrupt(download); - RecordingDownloadObserver recorder(download); + parameters.pattern_generator_seed = kNewPatternGeneratorSeed; + parameters.ClearInjectedErrors(); + request_handler.StartServing(parameters); - ReleaseRSTAndConfirmInterruptForResume(download); - ConfirmFileStatusForResume( - download, true, GetSafeBufferChunk(), GetSafeBufferChunk() * 3, - base::FilePath(FILE_PATH_LITERAL("rangereset.crdownload"))); + download->Resume(); + WaitForCompletion(download); + + ASSERT_EQ(parameters.size, download->GetReceivedBytes()); + ASSERT_EQ(parameters.size, download->GetTotalBytes()); + ASSERT_NO_FATAL_FAILURE( + ReadAndVerifyFileContents(kNewPatternGeneratorSeed, parameters.size, + download->GetTargetFilePath())); + + TestDownloadRequestHandler::CompletedRequests requests; + request_handler.GetCompletedRequestInfo(&requests); + + // Neither If-Range nor Range headers should be present in the second request. + ASSERT_EQ(2u, requests.size()); + std::string value; + EXPECT_FALSE(requests[1].request_headers.GetHeader( + net::HttpRequestHeaders::kIfRange, &value)); + EXPECT_FALSE(requests[1].request_headers.GetHeader( + net::HttpRequestHeaders::kRange, &value)); +} + +// Partial file goes missing before the download is resumed. The download should +// restart. +IN_PROC_BROWSER_TEST_F(DownloadContentTest, Resume_RestartIfNoPartialFile) { + base::CommandLine::ForCurrentProcess()->AppendSwitch( + switches::kEnableDownloadResumption); + TestDownloadRequestHandler::Parameters parameters = + TestDownloadRequestHandler::Parameters::WithSingleInterruption(); + + TestDownloadRequestHandler request_handler; + request_handler.StartServing(parameters); + DownloadItem* download = StartDownloadAndReturnItem(request_handler.url()); + WaitForInterrupt(download); // Delete the intermediate file. - base::DeleteFile(download->GetFullPath(), false); + ASSERT_TRUE(base::PathExists(download->GetFullPath())); + ASSERT_TRUE(base::DeleteFile(download->GetFullPath(), false)); - DownloadUpdatedObserver completion_observer( - download, base::Bind(DownloadCompleteFilter)); + parameters.ClearInjectedErrors(); + request_handler.StartServing(parameters); + download->Resume(); - completion_observer.WaitForEvent(); + WaitForCompletion(download); - ConfirmFileStatusForResume( - download, true, GetSafeBufferChunk() * 3, GetSafeBufferChunk() * 3, - base::FilePath(FILE_PATH_LITERAL("rangereset"))); - - static const RecordingDownloadObserver::RecordStruct expected_record[] = { - // Result of RST - {DownloadItem::INTERRUPTED, GetSafeBufferChunk()}, - // Starting continuation - {DownloadItem::IN_PROGRESS, GetSafeBufferChunk()}, - // Error because file isn't there. - {DownloadItem::INTERRUPTED, 0}, - // Restart. - {DownloadItem::IN_PROGRESS, 0}, - // Completion. - {DownloadItem::COMPLETE, GetSafeBufferChunk() * 3}, - }; - - recorder.CompareToExpectedRecord(expected_record, arraysize(expected_record)); + ASSERT_EQ(parameters.size, download->GetReceivedBytes()); + ASSERT_EQ(parameters.size, download->GetTotalBytes()); + ASSERT_NO_FATAL_FAILURE(ReadAndVerifyFileContents( + parameters.pattern_generator_seed, parameters.size, + download->GetTargetFilePath())); } -IN_PROC_BROWSER_TEST_F(DownloadContentTest, ResumeWithFileInitError) { +IN_PROC_BROWSER_TEST_F(DownloadContentTest, Resume_RecoverFromInitFileError) { base::CommandLine::ForCurrentProcess()->AppendSwitch( switches::kEnableDownloadResumption); - GURL url(net::URLRequestMockHTTPJob::GetMockUrl("download-test.lib")); + TestDownloadRequestHandler request_handler; + request_handler.StartServing(TestDownloadRequestHandler::Parameters()); // Setup the error injector. scoped_refptr<TestFileErrorInjector> injector( TestFileErrorInjector::Create(DownloadManagerForShell(shell()))); - TestFileErrorInjector::FileErrorInfo err = { - url.spec(), - TestFileErrorInjector::FILE_OPERATION_INITIALIZE, - 0, - DOWNLOAD_INTERRUPT_REASON_FILE_NO_SPACE - }; + const TestFileErrorInjector::FileErrorInfo err = { + request_handler.url().spec(), + TestFileErrorInjector::FILE_OPERATION_INITIALIZE, 0, + DOWNLOAD_INTERRUPT_REASON_FILE_NO_SPACE}; injector->AddError(err); injector->InjectErrors(); // Start and watch for interrupt. - scoped_ptr<DownloadTestObserver> int_observer( - CreateInterruptedWaiter(shell(), 1)); - DownloadItem* download(StartDownloadAndReturnItem(url)); - int_observer->WaitForFinished(); + DownloadItem* download(StartDownloadAndReturnItem(request_handler.url())); + WaitForInterrupt(download); ASSERT_EQ(DownloadItem::INTERRUPTED, download->GetState()); EXPECT_EQ(DOWNLOAD_INTERRUPT_REASON_FILE_NO_SPACE, download->GetLastReason()); @@ -1318,37 +1217,32 @@ injector->InjectErrors(); // Resume and watch completion. - DownloadUpdatedObserver completion_observer( - download, base::Bind(DownloadCompleteFilter)); download->Resume(); - completion_observer.WaitForEvent(); + WaitForCompletion(download); EXPECT_EQ(download->GetState(), DownloadItem::COMPLETE); } IN_PROC_BROWSER_TEST_F(DownloadContentTest, - ResumeWithFileIntermediateRenameError) { + Resume_RecoverFromIntermediateFileRenameError) { base::CommandLine::ForCurrentProcess()->AppendSwitch( switches::kEnableDownloadResumption); - GURL url(net::URLRequestMockHTTPJob::GetMockUrl("download-test.lib")); + TestDownloadRequestHandler request_handler; + request_handler.StartServing(TestDownloadRequestHandler::Parameters()); // Setup the error injector. scoped_refptr<TestFileErrorInjector> injector( TestFileErrorInjector::Create(DownloadManagerForShell(shell()))); - TestFileErrorInjector::FileErrorInfo err = { - url.spec(), - TestFileErrorInjector::FILE_OPERATION_RENAME_UNIQUIFY, - 0, - DOWNLOAD_INTERRUPT_REASON_FILE_NO_SPACE - }; + const TestFileErrorInjector::FileErrorInfo err = { + request_handler.url().spec(), + TestFileErrorInjector::FILE_OPERATION_RENAME_UNIQUIFY, 0, + DOWNLOAD_INTERRUPT_REASON_FILE_NO_SPACE}; injector->AddError(err); injector->InjectErrors(); // Start and watch for interrupt. - scoped_ptr<DownloadTestObserver> int_observer( - CreateInterruptedWaiter(shell(), 1)); - DownloadItem* download(StartDownloadAndReturnItem(url)); - int_observer->WaitForFinished(); + DownloadItem* download(StartDownloadAndReturnItem(request_handler.url())); + WaitForInterrupt(download); ASSERT_EQ(DownloadItem::INTERRUPTED, download->GetState()); EXPECT_EQ(DOWNLOAD_INTERRUPT_REASON_FILE_NO_SPACE, download->GetLastReason()); @@ -1369,18 +1263,17 @@ injector->ClearErrors(); injector->InjectErrors(); - // Resume and watch completion. - DownloadUpdatedObserver completion_observer( - download, base::Bind(DownloadCompleteFilter)); download->Resume(); - completion_observer.WaitForEvent(); + WaitForCompletion(download); EXPECT_EQ(download->GetState(), DownloadItem::COMPLETE); } -IN_PROC_BROWSER_TEST_F(DownloadContentTest, ResumeWithFileFinalRenameError) { +IN_PROC_BROWSER_TEST_F(DownloadContentTest, + Resume_RecoverFromFinalRenameError) { base::CommandLine::ForCurrentProcess()->AppendSwitch( switches::kEnableDownloadResumption); - GURL url(net::URLRequestMockHTTPJob::GetMockUrl("download-test.lib")); + TestDownloadRequestHandler request_handler; + request_handler.StartServing(TestDownloadRequestHandler::Parameters()); // Setup the error injector. scoped_refptr<TestFileErrorInjector> injector( @@ -1388,19 +1281,15 @@ DownloadManagerForShell(shell())->RemoveAllDownloads(); TestFileErrorInjector::FileErrorInfo err = { - url.spec(), - TestFileErrorInjector::FILE_OPERATION_RENAME_ANNOTATE, - 0, - DOWNLOAD_INTERRUPT_REASON_FILE_NO_SPACE - }; + request_handler.url().spec(), + TestFileErrorInjector::FILE_OPERATION_RENAME_ANNOTATE, 0, + DOWNLOAD_INTERRUPT_REASON_FILE_NO_SPACE}; injector->AddError(err); injector->InjectErrors(); // Start and watch for interrupt. - scoped_ptr<DownloadTestObserver> int_observer( - CreateInterruptedWaiter(shell(), 1)); - DownloadItem* download(StartDownloadAndReturnItem(url)); - int_observer->WaitForFinished(); + DownloadItem* download(StartDownloadAndReturnItem(request_handler.url())); + WaitForInterrupt(download); ASSERT_EQ(DownloadItem::INTERRUPTED, download->GetState()); EXPECT_EQ(DOWNLOAD_INTERRUPT_REASON_FILE_NO_SPACE, download->GetLastReason()); @@ -1419,11 +1308,8 @@ injector->ClearErrors(); injector->InjectErrors(); - // Resume and watch completion. - DownloadUpdatedObserver completion_observer( - download, base::Bind(DownloadCompleteFilter)); download->Resume(); - completion_observer.WaitForEvent(); + WaitForCompletion(download); EXPECT_EQ(download->GetState(), DownloadItem::COMPLETE); } @@ -1432,23 +1318,16 @@ IN_PROC_BROWSER_TEST_F(DownloadContentTest, CancelInterruptedDownload) { base::CommandLine::ForCurrentProcess()->AppendSwitch( switches::kEnableDownloadResumption); - ASSERT_TRUE(spawned_test_server()->Start()); + TestDownloadRequestHandler request_handler; + request_handler.StartServing( + TestDownloadRequestHandler::Parameters::WithSingleInterruption()); - GURL url1 = spawned_test_server()->GetURL( - base::StringPrintf("rangereset?size=%d&rst_boundary=%d", - GetSafeBufferChunk() * 3, GetSafeBufferChunk())); + DownloadItem* download = StartDownloadAndReturnItem(request_handler.url()); + WaitForInterrupt(download); - DownloadItem* download(StartDownloadAndReturnItem(url1)); - WaitForData(download, GetSafeBufferChunk()); - - ReleaseRSTAndConfirmInterruptForResume(download); - ConfirmFileStatusForResume( - download, true, GetSafeBufferChunk(), GetSafeBufferChunk() * 3, - base::FilePath(FILE_PATH_LITERAL("rangereset.crdownload"))); - - base::FilePath intermediate_path(download->GetFullPath()); + base::FilePath intermediate_path = download->GetFullPath(); ASSERT_FALSE(intermediate_path.empty()); - EXPECT_TRUE(base::PathExists(intermediate_path)); + ASSERT_TRUE(base::PathExists(intermediate_path)); download->Cancel(true /* user_cancel */); RunAllPendingInMessageLoop(BrowserThread::FILE); @@ -1459,81 +1338,59 @@ EXPECT_TRUE(download->GetFullPath().empty()); } -IN_PROC_BROWSER_TEST_F(DownloadContentTest, RemoveDownload) { +IN_PROC_BROWSER_TEST_F(DownloadContentTest, RemoveInterruptedDownload) { base::CommandLine::ForCurrentProcess()->AppendSwitch( switches::kEnableDownloadResumption); - ASSERT_TRUE(spawned_test_server()->Start()); + TestDownloadRequestHandler request_handler; + request_handler.StartServing( + TestDownloadRequestHandler::Parameters::WithSingleInterruption()); - // An interrupted download should remove the intermediate file when it is - // removed. - { - GURL url1 = spawned_test_server()->GetURL( - base::StringPrintf("rangereset?size=%d&rst_boundary=%d", - GetSafeBufferChunk() * 3, GetSafeBufferChunk())); + DownloadItem* download = StartDownloadAndReturnItem(request_handler.url()); + WaitForInterrupt(download); - DownloadItem* download(StartDownloadAndReturnItem(url1)); - WaitForData(download, GetSafeBufferChunk()); - ReleaseRSTAndConfirmInterruptForResume(download); - ConfirmFileStatusForResume( - download, true, GetSafeBufferChunk(), GetSafeBufferChunk() * 3, - base::FilePath(FILE_PATH_LITERAL("rangereset.crdownload"))); + base::FilePath intermediate_path = download->GetFullPath(); + ASSERT_FALSE(intermediate_path.empty()); + ASSERT_TRUE(base::PathExists(intermediate_path)); - base::FilePath intermediate_path(download->GetFullPath()); - ASSERT_FALSE(intermediate_path.empty()); - EXPECT_TRUE(base::PathExists(intermediate_path)); + download->Remove(); + RunAllPendingInMessageLoop(BrowserThread::FILE); + RunAllPendingInMessageLoop(); - download->Remove(); - RunAllPendingInMessageLoop(BrowserThread::FILE); - RunAllPendingInMessageLoop(); + // The intermediate file should now be gone. + EXPECT_FALSE(base::PathExists(intermediate_path)); +} - // The intermediate file should now be gone. - EXPECT_FALSE(base::PathExists(intermediate_path)); - } - +IN_PROC_BROWSER_TEST_F(DownloadContentTest, RemoveCompletedDownload) { // A completed download shouldn't delete the downloaded file when it is // removed. - { - // Start the second download and wait until it's done. - GURL url2(net::URLRequestMockHTTPJob::GetMockUrl("download-test.lib")); - scoped_ptr<DownloadTestObserver> completion_observer( - CreateWaiter(shell(), 1)); - DownloadItem* download(StartDownloadAndReturnItem(url2)); - completion_observer->WaitForFinished(); + TestDownloadRequestHandler request_handler; + request_handler.StartServing(TestDownloadRequestHandler::Parameters()); + scoped_ptr<DownloadTestObserver> completion_observer( + CreateWaiter(shell(), 1)); + DownloadItem* download(StartDownloadAndReturnItem(request_handler.url())); + completion_observer->WaitForFinished(); - // The target path should exist. - base::FilePath target_path(download->GetTargetFilePath()); - EXPECT_TRUE(base::PathExists(target_path)); - download->Remove(); - RunAllPendingInMessageLoop(BrowserThread::FILE); - RunAllPendingInMessageLoop(); + // The target path should exist. + base::FilePath target_path(download->GetTargetFilePath()); + EXPECT_TRUE(base::PathExists(target_path)); + download->Remove(); + RunAllPendingInMessageLoop(BrowserThread::FILE); + RunAllPendingInMessageLoop(); - // The file should still exist. - EXPECT_TRUE(base::PathExists(target_path)); - } + // The file should still exist. + EXPECT_TRUE(base::PathExists(target_path)); } IN_PROC_BROWSER_TEST_F(DownloadContentTest, RemoveResumingDownload) { - SetupEnsureNoPendingDownloads(); base::CommandLine::ForCurrentProcess()->AppendSwitch( switches::kEnableDownloadResumption); - ASSERT_TRUE(spawned_test_server()->Start()); + TestDownloadRequestHandler::Parameters parameters = + TestDownloadRequestHandler::Parameters::WithSingleInterruption(); + TestDownloadRequestHandler request_handler; + request_handler.StartServing(parameters); - GURL url = spawned_test_server()->GetURL( - base::StringPrintf("rangereset?size=%d&rst_boundary=%d", - GetSafeBufferChunk() * 3, GetSafeBufferChunk())); - - MockDownloadManagerObserver dm_observer(DownloadManagerForShell(shell())); - EXPECT_CALL(dm_observer, OnDownloadCreated(_,_)).Times(1); - - DownloadItem* download(StartDownloadAndReturnItem(url)); - WaitForData(download, GetSafeBufferChunk()); - ::testing::Mock::VerifyAndClearExpectations(&dm_observer); - - // Tell the server to send the RST and confirm the interrupt happens. - ReleaseRSTAndConfirmInterruptForResume(download); - ConfirmFileStatusForResume( - download, true, GetSafeBufferChunk(), GetSafeBufferChunk() * 3, - base::FilePath(FILE_PATH_LITERAL("rangereset.crdownload"))); + DownloadItem* download = StartDownloadAndReturnItem(request_handler.url()); + WaitForInterrupt(download); base::FilePath intermediate_path(download->GetFullPath()); ASSERT_FALSE(intermediate_path.empty()); @@ -1541,96 +1398,120 @@ // Resume and remove download. We expect only a single OnDownloadCreated() // call, and that's for the second download created below. + MockDownloadManagerObserver dm_observer(DownloadManagerForShell(shell())); EXPECT_CALL(dm_observer, OnDownloadCreated(_,_)).Times(1); + + TestRequestStartHandler request_start_handler; + parameters.on_start_handler = request_start_handler.GetOnStartHandler(); + request_handler.StartServing(parameters); + download->Resume(); + request_start_handler.WaitForCallback(); + + // At this point, the download resumption request has been sent out, but the + // reponse hasn't been received yet. download->Remove(); + request_start_handler.RespondWith(std::string(), net::OK); + // The intermediate file should now be gone. RunAllPendingInMessageLoop(BrowserThread::FILE); RunAllPendingInMessageLoop(); EXPECT_FALSE(base::PathExists(intermediate_path)); - // Start the second download and wait until it's done. The test server is - // single threaded. The response to this download request should follow the - // response to the previous resumption request. - GURL url2( - spawned_test_server()->GetURL("rangereset?size=100&rst_limit=0&token=x")); - NavigateToURLAndWaitForDownload(shell(), url2, DownloadItem::COMPLETE); + parameters.ClearInjectedErrors(); + parameters.on_start_handler.Reset(); + request_handler.StartServing(parameters); + // Start the second download and wait until it's done. This exercises the + // entire downloads stack and effectively flushes all of our worker threads. + // We are testing whether the URL request created in the previous + // DownloadItem::Resume() call reulted in a new download or not. + NavigateToURLAndWaitForDownload(shell(), request_handler.url(), + DownloadItem::COMPLETE); EXPECT_TRUE(EnsureNoPendingDownloads()); } IN_PROC_BROWSER_TEST_F(DownloadContentTest, CancelResumingDownload) { - SetupEnsureNoPendingDownloads(); base::CommandLine::ForCurrentProcess()->AppendSwitch( switches::kEnableDownloadResumption); - ASSERT_TRUE(spawned_test_server()->Start()); + TestDownloadRequestHandler::Parameters parameters = + TestDownloadRequestHandler::Parameters::WithSingleInterruption(); + TestDownloadRequestHandler request_handler; + request_handler.StartServing(parameters); - GURL url = spawned_test_server()->GetURL( - base::StringPrintf("rangereset?size=%d&rst_boundary=%d", - GetSafeBufferChunk() * 3, GetSafeBufferChunk())); - - MockDownloadManagerObserver dm_observer(DownloadManagerForShell(shell())); - EXPECT_CALL(dm_observer, OnDownloadCreated(_,_)).Times(1); - - DownloadItem* download(StartDownloadAndReturnItem(url)); - WaitForData(download, GetSafeBufferChunk()); - ::testing::Mock::VerifyAndClearExpectations(&dm_observer); - - // Tell the server to send the RST and confirm the interrupt happens. - ReleaseRSTAndConfirmInterruptForResume(download); - ConfirmFileStatusForResume( - download, true, GetSafeBufferChunk(), GetSafeBufferChunk() * 3, - base::FilePath(FILE_PATH_LITERAL("rangereset.crdownload"))); + DownloadItem* download = StartDownloadAndReturnItem(request_handler.url()); + WaitForInterrupt(download); base::FilePath intermediate_path(download->GetFullPath()); ASSERT_FALSE(intermediate_path.empty()); EXPECT_TRUE(base::PathExists(intermediate_path)); - // Resume and cancel download. We expect only a single OnDownloadCreated() + // Resume and remove download. We expect only a single OnDownloadCreated() // call, and that's for the second download created below. + MockDownloadManagerObserver dm_observer(DownloadManagerForShell(shell())); EXPECT_CALL(dm_observer, OnDownloadCreated(_,_)).Times(1); + + TestRequestStartHandler request_start_handler; + parameters.on_start_handler = request_start_handler.GetOnStartHandler(); + request_handler.StartServing(parameters); + download->Resume(); - download->Cancel(true); + request_start_handler.WaitForCallback(); + + // At this point, the download item has initiated a network request for the + // resumption attempt, but hasn't received a response yet. + download->Cancel(true /* user_cancel */); + + request_start_handler.RespondWith(std::string(), net::OK); // The intermediate file should now be gone. + RunAllPendingInMessageLoop(BrowserThread::IO); RunAllPendingInMessageLoop(BrowserThread::FILE); RunAllPendingInMessageLoop(); EXPECT_FALSE(base::PathExists(intermediate_path)); - EXPECT_TRUE(download->GetFullPath().empty()); - // Start the second download and wait until it's done. The test server is - // single threaded. The response to this download request should follow the - // response to the previous resumption request. - GURL url2( - spawned_test_server()->GetURL("rangereset?size=100&rst_limit=0&token=x")); - NavigateToURLAndWaitForDownload(shell(), url2, DownloadItem::COMPLETE); + parameters.ClearInjectedErrors(); + parameters.on_start_handler.Reset(); + request_handler.StartServing(parameters); + // Start the second download and wait until it's done. This exercises the + // entire downloads stack and effectively flushes all of our worker threads. + // We are testing whether the URL request created in the previous + // DownloadItem::Resume() call reulted in a new download or not. + NavigateToURLAndWaitForDownload(shell(), request_handler.url(), + DownloadItem::COMPLETE); EXPECT_TRUE(EnsureNoPendingDownloads()); } // Check that the cookie policy is correctly updated when downloading a file // that redirects cross origin. IN_PROC_BROWSER_TEST_F(DownloadContentTest, CookiePolicy) { - ASSERT_TRUE(spawned_test_server()->Start()); - net::HostPortPair host_port = spawned_test_server()->host_port_pair(); - DCHECK_EQ(host_port.host(), std::string("127.0.0.1")); + net::EmbeddedTestServer origin_one; + net::EmbeddedTestServer origin_two; + ASSERT_TRUE(origin_one.Start()); + ASSERT_TRUE(origin_two.Start()); // Block third-party cookies. ShellNetworkDelegate::SetAcceptAllCookies(false); // |url| redirects to a different origin |download| which tries to set a // cookie. - std::string download(base::StringPrintf( - "http://localhost:%d/set-cookie?A=B", host_port.port())); - GURL url(spawned_test_server()->GetURL("server-redirect?" + download)); + base::StringPairs cookie_header; + cookie_header.push_back( + std::make_pair(std::string("Set-Cookie"), std::string("A=B"))); + origin_one.RegisterRequestHandler(CreateBasicResponseHandler( + "/foo", cookie_header, "application/octet-stream", "abcd")); + origin_two.RegisterRequestHandler( + CreateRedirectHandler("/bar", origin_one.GetURL("/foo"))); // Download the file. SetupEnsureNoPendingDownloads(); - scoped_ptr<DownloadUrlParameters> dl_params( - DownloadUrlParameters::FromWebContents(shell()->web_contents(), url)); + scoped_ptr<DownloadUrlParameters> download_parameters( + DownloadUrlParameters::FromWebContents(shell()->web_contents(), + origin_two.GetURL("/bar"))); scoped_ptr<DownloadTestObserver> observer(CreateWaiter(shell(), 1)); - DownloadManagerForShell(shell())->DownloadUrl(dl_params.Pass()); + DownloadManagerForShell(shell())->DownloadUrl(download_parameters.Pass()); observer->WaitForFinished(); // Get the important info from other threads and check it. @@ -1644,7 +1525,7 @@ // Check that the cookies were correctly set. EXPECT_EQ("A=B", content::GetCookies(shell()->web_contents()->GetBrowserContext(), - GURL(download))); + origin_one.GetURL("/"))); } // A filename suggestion specified via a @download attribute should not be @@ -1676,7 +1557,7 @@ origin_one.RegisterRequestHandler( CreateRedirectHandler("/ping", origin_two.GetURL("/download"))); origin_two.RegisterRequestHandler(CreateBasicResponseHandler( - "/download", "application/octet-stream", "Hello")); + "/download", base::StringPairs(), "application/octet-stream", "Hello")); NavigateToURLAndWaitForDownload( shell(), referrer_url, DownloadItem::COMPLETE); @@ -1724,7 +1605,7 @@ origin_two.RegisterRequestHandler( CreateRedirectHandler("/pong", origin_one.GetURL("/download"))); origin_one.RegisterRequestHandler(CreateBasicResponseHandler( - "/download", "application/octet-stream", "Hello")); + "/download", base::StringPairs(), "application/octet-stream", "Hello")); NavigateToURLAndWaitForDownload( shell(), referrer_url, DownloadItem::COMPLETE); @@ -1743,12 +1624,7 @@ // The content body is empty. Make sure this case is handled properly and we // don't regress on http://crbug.com/320394. IN_PROC_BROWSER_TEST_F(DownloadContentTest, DownloadGZipWithNoContent) { - net::EmbeddedTestServer test_server; - ASSERT_TRUE(test_server.Start()); - - GURL url = test_server.GetURL("/empty.bin"); - test_server.ServeFilesFromDirectory(GetTestFilePath("download", "")); - + GURL url = net::URLRequestMockHTTPJob::GetMockUrl("empty.bin"); NavigateToURLAndWaitForDownload(shell(), url, DownloadItem::COMPLETE); // That's it. This should work without crashing. }
diff --git a/content/browser/download/download_item_impl.cc b/content/browser/download/download_item_impl.cc index 28340133..33de9d6 100644 --- a/content/browser/download/download_item_impl.cc +++ b/content/browser/download/download_item_impl.cc
@@ -666,19 +666,12 @@ } bool DownloadItemImpl::IsDangerous() const { -#if defined(OS_WIN) || defined(OS_MACOSX) || defined(OS_CHROMEOS) - // TODO(noelutz): At this point only the windows views and OSX UI supports - // warnings based on dangerous content. return (danger_type_ == DOWNLOAD_DANGER_TYPE_DANGEROUS_FILE || danger_type_ == DOWNLOAD_DANGER_TYPE_DANGEROUS_URL || danger_type_ == DOWNLOAD_DANGER_TYPE_DANGEROUS_CONTENT || danger_type_ == DOWNLOAD_DANGER_TYPE_UNCOMMON_CONTENT || danger_type_ == DOWNLOAD_DANGER_TYPE_DANGEROUS_HOST || danger_type_ == DOWNLOAD_DANGER_TYPE_POTENTIALLY_UNWANTED); -#else - return (danger_type_ == DOWNLOAD_DANGER_TYPE_DANGEROUS_FILE || - danger_type_ == DOWNLOAD_DANGER_TYPE_DANGEROUS_URL); -#endif } DownloadDangerType DownloadItemImpl::GetDangerType() const {
diff --git a/content/browser/frame_host/render_frame_host_impl.cc b/content/browser/frame_host/render_frame_host_impl.cc index 8c87841..18a88eb4 100644 --- a/content/browser/frame_host/render_frame_host_impl.cc +++ b/content/browser/frame_host/render_frame_host_impl.cc
@@ -1847,11 +1847,8 @@ // Only send the message if we aren't suspended at the start of a cross-site // request. if (navigations_suspended_) { - // Shouldn't be possible to have a second navigation while suspended, since - // navigations will only be suspended during a cross-site request. If a - // second navigation occurs, RenderFrameHostManager will cancel this pending - // RFH and create a new pending RFH. - DCHECK(!suspended_nav_params_.get()); + // This may replace an existing set of params, if this is a pending RFH that + // is navigated twice consecutively. suspended_nav_params_.reset( new NavigationParams(common_params, start_params, request_params)); } else {
diff --git a/content/browser/frame_host/render_frame_host_manager.cc b/content/browser/frame_host/render_frame_host_manager.cc index 67a150e1..dab752c 100644 --- a/content/browser/frame_host/render_frame_host_manager.cc +++ b/content/browser/frame_host/render_frame_host_manager.cc
@@ -1269,6 +1269,12 @@ SiteInstance* new_site_instance, const GURL& new_effective_url, bool new_is_view_source_mode) const { + // A subframe must stay in the same BrowsingInstance as its parent. + // TODO(nasko): Ensure that SiteInstance swap is still triggered for subframes + // in the cases covered by the rest of the checks in this method. + if (!frame_tree_node_->IsMainFrame()) + return false; + // If new_entry already has a SiteInstance, assume it is correct. We only // need to force a swap if it is in a different BrowsingInstance. if (new_site_instance) { @@ -2320,17 +2326,18 @@ return render_frame_host_.get(); } - // If we are currently navigating cross-process, we want to get back to normal - // and then navigate as usual. - if (pending_render_frame_host_) - CancelPending(); - SiteInstance* current_instance = render_frame_host_->GetSiteInstance(); scoped_refptr<SiteInstance> new_instance = GetSiteInstanceForNavigation( dest_url, source_instance, dest_instance, nullptr, transition, dest_is_restore, dest_is_view_source_mode); - DCHECK(!pending_render_frame_host_); + // If we are currently navigating cross-process to a pending RFH for a + // different SiteInstance, we want to get back to normal and then navigate as + // usual. We will reuse the pending RFH below if it matches the destination + // SiteInstance. + if (pending_render_frame_host_ && + pending_render_frame_host_->GetSiteInstance() != new_instance) + CancelPending(); if (new_instance.get() != current_instance) { TRACE_EVENT_INSTANT2( @@ -2342,10 +2349,12 @@ // New SiteInstance: create a pending RFH to navigate. - CreatePendingRenderFrameHost(current_instance, new_instance.get()); + if (!pending_render_frame_host_) + CreatePendingRenderFrameHost(current_instance, new_instance.get()); DCHECK(pending_render_frame_host_); if (!pending_render_frame_host_) return nullptr; + DCHECK_EQ(new_instance, pending_render_frame_host_->GetSiteInstance()); pending_render_frame_host_->UpdatePendingWebUI(dest_url, bindings); pending_render_frame_host_->CommitPendingWebUI(); @@ -2371,20 +2380,20 @@ } // Otherwise, it's safe to treat this as a pending cross-process transition. - // We need to wait until the beforeunload handler has run, unless we are - // transferring an existing request (in which case it has already run). - // Suspend the new render view (i.e., don't let it send the cross-process - // Navigate message) until we hear back from the old renderer's - // beforeunload handler. If the handler returns false, we'll have to - // cancel the request. - DCHECK(!pending_render_frame_host_->are_navigations_suspended()); bool is_transfer = transferred_request_id != GlobalRequestID(); if (is_transfer) { // We don't need to stop the old renderer or run beforeunload/unload // handlers, because those have already been done. DCHECK(cross_site_transferring_request_->request_id() == transferred_request_id); - } else { + } else if (!pending_render_frame_host_->are_navigations_suspended()) { + // If the pending RFH hasn't already been suspended from a previous + // attempt to navigate it, then we need to wait for the beforeunload + // handler to run. Suspend navigations in the pending RFH until we hear + // back from the old RFH's beforeunload handler (via OnBeforeUnloadACK or + // a timeout). If the handler returns false, we'll have to cancel the + // request. + // // Also make sure the old render view stops, in case a load is in // progress. (We don't want to do this for transfers, since it will // interrupt the transfer with an unexpected DidStopLoading.) @@ -2392,10 +2401,6 @@ render_frame_host_->GetRoutingID())); pending_render_frame_host_->SetNavigationsSuspended(true, base::TimeTicks()); - // Unless we are transferring an existing request, we should now tell the - // old render view to run its beforeunload handler, since it doesn't - // otherwise know that the cross-site request is happening. This will - // trigger a call to OnBeforeUnloadACK with the reply. render_frame_host_->DispatchBeforeUnload(true); }
diff --git a/content/browser/frame_host/render_frame_host_manager_browsertest.cc b/content/browser/frame_host/render_frame_host_manager_browsertest.cc index cba8284..f66fba6 100644 --- a/content/browser/frame_host/render_frame_host_manager_browsertest.cc +++ b/content/browser/frame_host/render_frame_host_manager_browsertest.cc
@@ -2413,4 +2413,47 @@ shell(), embedded_test_server()->GetURL("b.com", "/title3.html"))); } +// Ensure that we use the same pending RenderFrameHost if a second navigation to +// its site occurs before it commits. Otherwise the renderer process will have +// two competing pending RenderFrames that both try to swap with the same +// RenderFrameProxy. See https://crbug.com/545900. +IN_PROC_BROWSER_TEST_F(RenderFrameHostManagerTest, + ConsecutiveNavigationsToSite) { + StartEmbeddedServer(); + EXPECT_TRUE(NavigateToURL( + shell(), embedded_test_server()->GetURL("a.com", "/title1.html"))); + + // Open a popup and navigate it to b.com to keep the b.com process alive. + Shell* new_shell = + OpenPopup(shell()->web_contents(), GURL(url::kAboutBlankURL), "popup"); + NavigateToURL(new_shell, + embedded_test_server()->GetURL("b.com", "/title3.html")); + + // Start a cross-site navigation to the same site but don't commit. + GURL cross_site_url(embedded_test_server()->GetURL("b.com", "/title1.html")); + NavigationStallDelegate stall_delegate(cross_site_url); + ResourceDispatcherHost::Get()->SetDelegate(&stall_delegate); + shell()->LoadURL(cross_site_url); + + WebContentsImpl* web_contents = static_cast<WebContentsImpl*>( + shell()->web_contents()); + RenderFrameHostImpl* pending_rfh = + web_contents->GetRenderManagerForTesting()->pending_frame_host(); + ASSERT_TRUE(pending_rfh); + + // Navigate to the same new site and verify that we commit in the same RFH. + GURL cross_site_url2(embedded_test_server()->GetURL("b.com", "/title2.html")); + TestNavigationObserver navigation_observer(web_contents, 1); + shell()->LoadURL(cross_site_url2); + EXPECT_EQ(pending_rfh, + web_contents->GetRenderManagerForTesting()->pending_frame_host()); + navigation_observer.Wait(); + EXPECT_EQ(cross_site_url2, web_contents->GetLastCommittedURL()); + EXPECT_EQ(pending_rfh, web_contents->GetMainFrame()); + EXPECT_FALSE( + web_contents->GetRenderManagerForTesting()->pending_frame_host()); + + ResourceDispatcherHost::Get()->SetDelegate(nullptr); +} + } // namespace content
diff --git a/content/browser/frame_host/render_frame_message_filter.cc b/content/browser/frame_host/render_frame_message_filter.cc index b13d6d78..462f219 100644 --- a/content/browser/frame_host/render_frame_message_filter.cc +++ b/content/browser/frame_host/render_frame_message_filter.cc
@@ -299,6 +299,8 @@ IPC_MESSAGE_HANDLER(FrameHostMsg_CookiesEnabled, OnCookiesEnabled) IPC_MESSAGE_HANDLER(FrameHostMsg_Are3DAPIsBlocked, OnAre3DAPIsBlocked) IPC_MESSAGE_HANDLER(FrameHostMsg_DidLose3DContext, OnDidLose3DContext) + IPC_MESSAGE_HANDLER_GENERIC(FrameHostMsg_RenderProcessGone, + OnRenderProcessGone()) #if defined(ENABLE_PLUGINS) IPC_MESSAGE_HANDLER_DELAY_REPLY(FrameHostMsg_GetPlugins, OnGetPlugins) IPC_MESSAGE_HANDLER(FrameHostMsg_GetPluginInfo, OnGetPluginInfo) @@ -468,6 +470,14 @@ top_origin_url, guilt); } +void RenderFrameMessageFilter::OnRenderProcessGone() { + // FrameHostMessage_RenderProcessGone is a synthetic IPC message used by + // RenderProcessHostImpl to clean things up after a crash (it's injected + // downstream of this filter). Allowing it to proceed would enable a renderer + // to fake its own death; instead, actually kill the renderer. + bad_message::ReceivedBadMessage( + this, bad_message::RFMF_RENDERER_FAKED_ITS_OWN_DEATH); +} #if defined(ENABLE_PLUGINS)
diff --git a/content/browser/frame_host/render_frame_message_filter.h b/content/browser/frame_host/render_frame_message_filter.h index 43dc78b5a..3642128 100644 --- a/content/browser/frame_host/render_frame_message_filter.h +++ b/content/browser/frame_host/render_frame_message_filter.h
@@ -99,6 +99,8 @@ ThreeDAPIType context_type, int arb_robustness_status_code); + void OnRenderProcessGone(); + #if defined(ENABLE_PLUGINS) void OnGetPlugins(bool refresh, IPC::Message* reply_msg); void GetPluginsCallback(IPC::Message* reply_msg,
diff --git a/content/browser/renderer_host/render_message_filter_browsertest.cc b/content/browser/frame_host/render_frame_message_filter_browsertest.cc similarity index 76% rename from content/browser/renderer_host/render_message_filter_browsertest.cc rename to content/browser/frame_host/render_frame_message_filter_browsertest.cc index 3f05b5f..96eb9c1 100644 --- a/content/browser/renderer_host/render_message_filter_browsertest.cc +++ b/content/browser/frame_host/render_frame_message_filter_browsertest.cc
@@ -7,6 +7,8 @@ #include "base/basictypes.h" #include "base/command_line.h" #include "base/files/file_path.h" +#include "base/test/histogram_tester.h" +#include "content/browser/bad_message.h" #include "content/browser/frame_host/frame_tree.h" #include "content/browser/web_contents/web_contents_impl.h" #include "content/common/frame_messages.h" @@ -21,6 +23,7 @@ #include "ipc/ipc_security_test_util.h" #include "net/dns/mock_host_resolver.h" #include "net/test/embedded_test_server/embedded_test_server.h" +#include "testing/gmock/include/gmock/gmock.h" #include "testing/gtest/include/gtest/gtest.h" namespace content { @@ -36,11 +39,11 @@ } // namespace -using RenderMessageFilterBrowserTest = ContentBrowserTest; +using RenderFrameMessageFilterBrowserTest = ContentBrowserTest; // Exercises basic cookie operations via javascript, including an http page // interacting with secure cookies. -IN_PROC_BROWSER_TEST_F(RenderMessageFilterBrowserTest, Cookies) { +IN_PROC_BROWSER_TEST_F(RenderFrameMessageFilterBrowserTest, Cookies) { host_resolver()->AddRule("*", "127.0.0.1"); ASSERT_TRUE(embedded_test_server()->Start()); SetupCrossSiteRedirector(embedded_test_server()); @@ -49,8 +52,8 @@ https_server.ServeFilesFromSourceDirectory("content/test/data"); ASSERT_TRUE(https_server.Start()); - // The server sends a HttpOnly cookie. The RenderMessageFilter should never - // allow this to be sent to any renderer process. + // The server sends a HttpOnly cookie. The RenderFrameMessageFilter should + // never allow this to be sent to any renderer process. GURL https_url = https_server.GetURL("/set-cookie?notforjs=1;HttpOnly"); GURL http_url = embedded_test_server()->GetURL("/frame_with_load_event.html"); @@ -100,9 +103,10 @@ EXPECT_EQ("B=2; D=4", GetCookieFromJS(web_contents_http->GetMainFrame())); } -// The RenderMessageFilter will kill processes when they access the cookies of -// sites other than the site the process is dedicated to, under site isolation. -IN_PROC_BROWSER_TEST_F(RenderMessageFilterBrowserTest, +// The RenderFrameMessageFilter will kill processes when they access the cookies +// of sites other than the site the process is dedicated to, under site +// isolation. +IN_PROC_BROWSER_TEST_F(RenderFrameMessageFilterBrowserTest, CrossSiteCookieSecurityEnforcement) { // The code under test is only active under site isolation. if (!AreAllSitesIsolatedForTesting()) { @@ -173,4 +177,36 @@ v.DepictFrameTree(tab->GetFrameTree()->root())); } +// FrameHostMsg_RenderProcessGone is a synthetic message that's really an +// implementation detail of RenderProcessHostImpl's crash recovery. It should be +// ignored if it arrives over the IPC channel. +IN_PROC_BROWSER_TEST_F(RenderFrameMessageFilterBrowserTest, RenderProcessGone) { + GURL web_url("http://foo.com/simple_page.html"); + NavigateToURL(shell(), web_url); + RenderFrameHost* web_rfh = shell()->web_contents()->GetMainFrame(); + + base::HistogramTester uma; + + ASSERT_TRUE(web_rfh->IsRenderFrameLive()); + RenderProcessHostWatcher web_process_killed( + web_rfh->GetProcess(), RenderProcessHostWatcher::WATCH_FOR_PROCESS_EXIT); + IPC::IpcSecurityTestUtil::PwnMessageReceived( + web_rfh->GetProcess()->GetChannel(), + FrameHostMsg_RenderProcessGone( + web_rfh->GetRoutingID(), base::TERMINATION_STATUS_NORMAL_TERMINATION, + 0)); + + EXPECT_THAT(uma.GetAllSamples("Stability.BadMessageTerminated.Content"), + testing::ElementsAre(base::Bucket( + bad_message::RFMF_RENDERER_FAKED_ITS_OWN_DEATH, 1))); + + // If the message had gone through, we'd have marked the RFH as dead but + // left the RPH and its connection alive, and the Wait below would hang. + web_process_killed.Wait(); + + ASSERT_FALSE(web_rfh->GetProcess()->HasConnection()); + ASSERT_FALSE(web_rfh->IsRenderFrameLive()); + ASSERT_FALSE(web_process_killed.did_exit_normally()); +} + } // namespace content
diff --git a/content/browser/frame_host/render_frame_proxy_host.cc b/content/browser/frame_host/render_frame_proxy_host.cc index c921e04..1f0c182 100644 --- a/content/browser/frame_host/render_frame_proxy_host.cc +++ b/content/browser/frame_host/render_frame_proxy_host.cc
@@ -146,6 +146,7 @@ IPC_MESSAGE_HANDLER(FrameHostMsg_OpenURL, OnOpenURL) IPC_MESSAGE_HANDLER(FrameHostMsg_RouteMessageEvent, OnRouteMessageEvent) IPC_MESSAGE_HANDLER(FrameHostMsg_DidChangeOpener, OnDidChangeOpener) + IPC_MESSAGE_HANDLER(FrameHostMsg_AdvanceFocus, OnAdvanceFocus) IPC_MESSAGE_UNHANDLED(handled = false) IPC_END_MESSAGE_MAP() return handled; @@ -325,4 +326,29 @@ GetSiteInstance()); } +void RenderFrameProxyHost::OnAdvanceFocus(blink::WebFocusType type, + int32_t source_routing_id) { + RenderFrameHostImpl* target_rfh = + frame_tree_node_->render_manager()->current_frame_host(); + + // Translate the source RenderFrameHost in this process to its equivalent + // RenderFrameProxyHost in the target process. This is needed for continuing + // the focus traversal from correct place in a parent frame after one of its + // child frames finishes its traversal. + RenderFrameHostImpl* source_rfh = + RenderFrameHostImpl::FromID(GetProcess()->GetID(), source_routing_id); + int32_t source_proxy_routing_id = MSG_ROUTING_NONE; + if (source_rfh) { + RenderFrameProxyHost* source_proxy = + source_rfh->frame_tree_node() + ->render_manager() + ->GetRenderFrameProxyHost(target_rfh->GetSiteInstance()); + if (source_proxy) + source_proxy_routing_id = source_proxy->GetRoutingID(); + } + + target_rfh->Send(new FrameMsg_AdvanceFocus(target_rfh->GetRoutingID(), type, + source_proxy_routing_id)); +} + } // namespace content
diff --git a/content/browser/frame_host/render_frame_proxy_host.h b/content/browser/frame_host/render_frame_proxy_host.h index fd5fc6c..c8b0db0 100644 --- a/content/browser/frame_host/render_frame_proxy_host.h +++ b/content/browser/frame_host/render_frame_proxy_host.h
@@ -10,6 +10,7 @@ #include "content/browser/site_instance_impl.h" #include "ipc/ipc_listener.h" #include "ipc/ipc_sender.h" +#include "third_party/WebKit/public/platform/WebFocusType.h" struct FrameMsg_PostMessage_Params; @@ -129,6 +130,7 @@ void OnOpenURL(const FrameHostMsg_OpenURL_Params& params); void OnRouteMessageEvent(const FrameMsg_PostMessage_Params& params); void OnDidChangeOpener(int32 opener_routing_id); + void OnAdvanceFocus(blink::WebFocusType type, int32_t source_routing_id); // This RenderFrameProxyHost's routing id. int routing_id_;
diff --git a/content/browser/indexed_db/indexed_db_browsertest.cc b/content/browser/indexed_db/indexed_db_browsertest.cc index 0428d35..bafe726 100644 --- a/content/browser/indexed_db/indexed_db_browsertest.cc +++ b/content/browser/indexed_db/indexed_db_browsertest.cc
@@ -778,7 +778,15 @@ exit(0); } -IN_PROC_BROWSER_TEST_F(IndexedDBBrowserTest, VersionChangeCrashResilience) { +// Fails to cleanup GPU processes on swarming. +// http://crbug.com/552543 +#if defined(OS_WIN) +#define MAYBE_VersionChangeCrashResilience DISABLED_VersionChangeCrashResilience +#else +#define MAYBE_VersionChangeCrashResilience VersionChangeCrashResilience +#endif +IN_PROC_BROWSER_TEST_F(IndexedDBBrowserTest, + MAYBE_VersionChangeCrashResilience) { NavigateAndWaitForTitle(shell(), "version_change_crash.html", "#part3", "pass - part3 - rolled back"); }
diff --git a/content/browser/mojo/OWNERS b/content/browser/mojo/OWNERS new file mode 100644 index 0000000..570120f --- /dev/null +++ b/content/browser/mojo/OWNERS
@@ -0,0 +1,13 @@ +# Changes to the renderer capability filter require a security review to avoid +# exposing new sandbox escapes and undesirable services. +per-file renderer_capability_filter.cc=set noparent +per-file renderer_capability_filter.cc=dcheng@chromium.org +per-file renderer_capability_filter.cc=inferno@chromium.org +per-file renderer_capability_filter.cc=jln@chromium.org +per-file renderer_capability_filter.cc=jschuh@chromium.org +per-file renderer_capability_filter.cc=kenrb@chromium.org +per-file renderer_capability_filter.cc=mkwst@chromium.org +per-file renderer_capability_filter.cc=nasko@chromium.org +per-file renderer_capability_filter.cc=palmer@chromium.org +per-file renderer_capability_filter.cc=tsepez@chromium.org +per-file renderer_capability_filter.cc=wfh@chromium.org
diff --git a/content/browser/mojo/mojo_shell_client_host.cc b/content/browser/mojo/mojo_shell_client_host.cc index 8616a37..53be44dd1 100644 --- a/content/browser/mojo/mojo_shell_client_host.cc +++ b/content/browser/mojo/mojo_shell_client_host.cc
@@ -4,7 +4,6 @@ #include "base/strings/stringprintf.h" #include "base/thread_task_runner_handle.h" -#include "components/mus/public/interfaces/gpu.mojom.h" #include "content/browser/mojo/mojo_shell_client_host.h" #include "content/common/mojo/mojo_messages.h" #include "content/public/browser/render_process_host.h" @@ -104,14 +103,10 @@ std::string url = base::StringPrintf("exe:chrome_renderer%d", child_process_id); - mojo::CapabilityFilterPtr filter(mojo::CapabilityFilter::New()); - mojo::Array<mojo::String> window_manager_interfaces; - window_manager_interfaces.push_back(mus::mojom::Gpu::Name_); - filter->filter.insert("mojo:mus", window_manager_interfaces.Pass()); application_manager->CreateInstanceForHandle( mojo::ScopedHandle(mojo::Handle(handle.release().value())), url, - filter.Pass()); + CreateCapabilityFilterForRenderer()); // Send the other end to the child via Chrome IPC. base::PlatformFile client_file = PlatformFileFromScopedPlatformHandle(
diff --git a/content/browser/mojo/mojo_shell_client_host.h b/content/browser/mojo/mojo_shell_client_host.h index c59924f..53f5a1e86 100644 --- a/content/browser/mojo/mojo_shell_client_host.h +++ b/content/browser/mojo/mojo_shell_client_host.h
@@ -8,6 +8,7 @@ #include <string> #include "base/process/process_handle.h" +#include "mojo/application/public/interfaces/shell.mojom.h" namespace content { @@ -30,6 +31,13 @@ void SendExternalMojoShellHandleToChild(base::ProcessHandle process_handle, RenderProcessHost* render_process_host); +// Constructs a Capability Filter for the renderer's application instance in the +// external shell. This contains the restrictions imposed on what applications +// and interfaces the renderer can see. The implementation lives in +// renderer_capability_filter.cc so that it can be subject to specific security +// review. +mojo::CapabilityFilterPtr CreateCapabilityFilterForRenderer(); + } // namespace content #endif // CONTENT_BROWSER_MOJO_MOJO_SHELL_CLIENT_HOST_H_
diff --git a/content/browser/mojo/renderer_capability_filter.cc b/content/browser/mojo/renderer_capability_filter.cc new file mode 100644 index 0000000..871e692 --- /dev/null +++ b/content/browser/mojo/renderer_capability_filter.cc
@@ -0,0 +1,20 @@ +// 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. + +#include "components/mus/public/interfaces/gpu.mojom.h" +#include "content/browser/mojo/mojo_shell_client_host.h" + +namespace content { + +mojo::CapabilityFilterPtr CreateCapabilityFilterForRenderer() { + // See https://goo.gl/gkBtCR for a description of what this is and what to + // think about when changing it. + mojo::CapabilityFilterPtr filter(mojo::CapabilityFilter::New()); + mojo::Array<mojo::String> window_manager_interfaces; + window_manager_interfaces.push_back(mus::mojom::Gpu::Name_); + filter->filter.insert("mojo:mus", window_manager_interfaces.Pass()); + return filter; +} + +} // namespace content
diff --git a/content/browser/net/browser_online_state_observer.cc b/content/browser/net/browser_online_state_observer.cc index 23071d6..9b457f9b 100644 --- a/content/browser/net/browser_online_state_observer.cc +++ b/content/browser/net/browser_online_state_observer.cc
@@ -6,11 +6,15 @@ #include "content/common/view_messages.h" #include "content/browser/renderer_host/render_process_host_impl.h" +#include "content/public/browser/notification_service.h" +#include "content/public/browser/notification_types.h" namespace content { BrowserOnlineStateObserver::BrowserOnlineStateObserver() { net::NetworkChangeNotifier::AddMaxBandwidthObserver(this); + registrar_.Add(this, content::NOTIFICATION_RENDERER_PROCESS_CREATED, + content::NotificationService::AllSources()); } BrowserOnlineStateObserver::~BrowserOnlineStateObserver() { @@ -27,4 +31,20 @@ } } +void BrowserOnlineStateObserver::Observe( + int type, + const content::NotificationSource& source, + const content::NotificationDetails& details) { + DCHECK_EQ(NOTIFICATION_RENDERER_PROCESS_CREATED, type); + + content::RenderProcessHost* rph = + content::Source<content::RenderProcessHost>(source).ptr(); + double max_bandwidth_mbps; + net::NetworkChangeNotifier::ConnectionType connection_type; + net::NetworkChangeNotifier::GetMaxBandwidthAndConnectionType( + &max_bandwidth_mbps, &connection_type); + rph->Send(new ViewMsg_NetworkConnectionChanged(connection_type, + max_bandwidth_mbps)); +} + } // namespace content
diff --git a/content/browser/net/browser_online_state_observer.h b/content/browser/net/browser_online_state_observer.h index b722eff..3a7867e 100644 --- a/content/browser/net/browser_online_state_observer.h +++ b/content/browser/net/browser_online_state_observer.h
@@ -6,6 +6,8 @@ #define CONTENT_BROWSER_NET_BROWSER_ONLINE_STATE_OBSERVER_H_ #include "base/basictypes.h" +#include "content/public/browser/notification_observer.h" +#include "content/public/browser/notification_registrar.h" #include "net/base/network_change_notifier.h" namespace content { @@ -13,17 +15,25 @@ // Listens for changes to the online state and manages sending // updates to each RenderProcess via RenderProcessHost IPC. class BrowserOnlineStateObserver - : public net::NetworkChangeNotifier::MaxBandwidthObserver { + : public net::NetworkChangeNotifier::MaxBandwidthObserver, + public content::NotificationObserver { public: BrowserOnlineStateObserver(); ~BrowserOnlineStateObserver() override; - // MaxBandwidthObserver implementation. + // MaxBandwidthObserver implementation void OnMaxBandwidthChanged( double max_bandwidth_mbps, net::NetworkChangeNotifier::ConnectionType type) override; + // NotificationObserver implementation + void Observe(int type, + const content::NotificationSource& source, + const content::NotificationDetails& details) override; + private: + content::NotificationRegistrar registrar_; + DISALLOW_COPY_AND_ASSIGN(BrowserOnlineStateObserver); };
diff --git a/content/browser/net_info_browsertest.cc b/content/browser/net_info_browsertest.cc index 5701787b..bfc4d813 100644 --- a/content/browser/net_info_browsertest.cc +++ b/content/browser/net_info_browsertest.cc
@@ -76,6 +76,18 @@ } }; +// Make sure the type is correct when the page is first opened. +IN_PROC_BROWSER_TEST_F(NetInfoBrowserTest, VerifyNetworkStateInitialized) { + SetConnectionType(net::NetworkChangeNotifier::CONNECTION_ETHERNET, + net::NetworkChangeNotifier::SUBTYPE_GIGABIT_ETHERNET); + NavigateToURL(shell(), content::GetTestUrl("", "net_info.html")); + EXPECT_TRUE(RunScriptExtractBool("getOnLine()")); + EXPECT_EQ("ethernet", RunScriptExtractString("getType()")); + EXPECT_EQ(net::NetworkChangeNotifier::GetMaxBandwidthForConnectionSubtype( + net::NetworkChangeNotifier::SUBTYPE_GIGABIT_ETHERNET), + RunScriptExtractDouble("getDownlinkMax()")); +} + // Make sure that type changes in the browser make their way to // navigator.connection.type. IN_PROC_BROWSER_TEST_F(NetInfoBrowserTest, NetworkChangePlumbsToNavigator) { @@ -110,4 +122,25 @@ EXPECT_TRUE(RunScriptExtractBool("getOnLine()")); } +// Creating a new render view shouldn't reinitialize Blink's +// NetworkStateNotifier. See https://crbug.com/535081. +IN_PROC_BROWSER_TEST_F(NetInfoBrowserTest, TwoRenderViewsInOneProcess) { + SetConnectionType(net::NetworkChangeNotifier::CONNECTION_ETHERNET, + net::NetworkChangeNotifier::SUBTYPE_GIGABIT_ETHERNET); + NavigateToURL(shell(), content::GetTestUrl("", "net_info.html")); + EXPECT_TRUE(RunScriptExtractBool("getOnLine()")); + + SetConnectionType(net::NetworkChangeNotifier::CONNECTION_NONE, + net::NetworkChangeNotifier::SUBTYPE_NONE); + EXPECT_FALSE(RunScriptExtractBool("getOnLine()")); + + // Open the same page in a new window on the same process. + EXPECT_TRUE( + ExecuteScript(shell()->web_contents(), "window.open(\"net_info.html\")")); + + // The network state should not have reinitialized to what it was when opening + // the first window (online). + EXPECT_FALSE(RunScriptExtractBool("getOnLine()")); +} + } // namespace content
diff --git a/content/browser/power_save_blocker_impl.h b/content/browser/power_save_blocker_impl.h index a304226..76af7253 100644 --- a/content/browser/power_save_blocker_impl.h +++ b/content/browser/power_save_blocker_impl.h
@@ -43,6 +43,13 @@ // }; scoped_refptr<Delegate> delegate_; +#if defined(USE_X11) + // Since display sleep prevention also implies system suspend prevention, for + // the Linux FreeDesktop API case, there needs to be a second delegate to + // block system suspend when screen saver / display sleep is blocked. + scoped_refptr<Delegate> freedesktop_suspend_delegate_; +#endif + DISALLOW_COPY_AND_ASSIGN(PowerSaveBlockerImpl); };
diff --git a/content/browser/power_save_blocker_x11.cc b/content/browser/power_save_blocker_x11.cc index 4783063..d5c79f43 100644 --- a/content/browser/power_save_blocker_x11.cc +++ b/content/browser/power_save_blocker_x11.cc
@@ -52,12 +52,17 @@ const char kGnomeAPIInterfaceName[] = "org.gnome.SessionManager"; const char kGnomeAPIObjectPath[] = "/org/gnome/SessionManager"; -const char kFreeDesktopAPIServiceName[] = "org.freedesktop.PowerManagement"; -const char kFreeDesktopAPIInterfaceName[] = +const char kFreeDesktopAPIPowerServiceName[] = + "org.freedesktop.PowerManagement"; +const char kFreeDesktopAPIPowerInterfaceName[] = "org.freedesktop.PowerManagement.Inhibit"; -const char kFreeDesktopAPIObjectPath[] = +const char kFreeDesktopAPIPowerObjectPath[] = "/org/freedesktop/PowerManagement/Inhibit"; +const char kFreeDesktopAPIScreenServiceName[] = "org.freedesktop.ScreenSaver"; +const char kFreeDesktopAPIScreenInterfaceName[] = "org.freedesktop.ScreenSaver"; +const char kFreeDesktopAPIScreenObjectPath[] = "/org/freedesktop/ScreenSaver"; + } // namespace namespace content { @@ -66,7 +71,9 @@ : public base::RefCountedThreadSafe<PowerSaveBlockerImpl::Delegate> { public: // Picks an appropriate D-Bus API to use based on the desktop environment. - Delegate(PowerSaveBlockerType type, const std::string& description); + Delegate(PowerSaveBlockerType type, + const std::string& description, + bool freedesktop_only); // Post a task to initialize the delegate on the UI thread, which will itself // then post a task to apply the power save block on the FILE thread. @@ -109,6 +116,7 @@ const PowerSaveBlockerType type_; const std::string description_; + const bool freedesktop_only_; // Initially, we post a message to the UI thread to select an API. When it // finishes, it will post a message to the FILE thread to perform the actual @@ -138,9 +146,11 @@ }; PowerSaveBlockerImpl::Delegate::Delegate(PowerSaveBlockerType type, - const std::string& description) + const std::string& description, + bool freedesktop_only) : type_(type), description_(description), + freedesktop_only_(freedesktop_only), api_(NO_API), enqueue_apply_(false), inhibit_cookie_(0) { @@ -176,7 +186,9 @@ DCHECK_CURRENTLY_ON(BrowserThread::UI); base::AutoLock lock(lock_); api_ = SelectAPI(); - if (enqueue_apply_ && api_ != NO_API) { + bool api_matches = + freedesktop_only_ ? api_ == FREEDESKTOP_API : api_ != NO_API; + if (enqueue_apply_ && api_matches) { // The thread we use here becomes the origin and D-Bus thread for the D-Bus // library, so we need to use the same thread above for RemoveBlock(). It // must be a thread that allows I/O operations, so we use the FILE thread. @@ -235,11 +247,22 @@ } break; case FREEDESKTOP_API: - object_proxy = bus_->GetObjectProxy( - kFreeDesktopAPIServiceName, - dbus::ObjectPath(kFreeDesktopAPIObjectPath)); - method_call.reset( - new dbus::MethodCall(kFreeDesktopAPIInterfaceName, "Inhibit")); + switch (type_) { + case kPowerSaveBlockPreventDisplaySleep: + object_proxy = bus_->GetObjectProxy( + kFreeDesktopAPIScreenServiceName, + dbus::ObjectPath(kFreeDesktopAPIScreenObjectPath)); + method_call.reset(new dbus::MethodCall( + kFreeDesktopAPIScreenInterfaceName, "Inhibit")); + break; + case kPowerSaveBlockPreventAppSuspension: + object_proxy = bus_->GetObjectProxy( + kFreeDesktopAPIPowerServiceName, + dbus::ObjectPath(kFreeDesktopAPIPowerObjectPath)); + method_call.reset(new dbus::MethodCall( + kFreeDesktopAPIPowerInterfaceName, "Inhibit")); + break; + } message_writer.reset(new dbus::MessageWriter(method_call.get())); // The arguments of the method are: // app_id: The application identifier @@ -311,11 +334,22 @@ new dbus::MethodCall(kGnomeAPIInterfaceName, "Uninhibit")); break; case FREEDESKTOP_API: - object_proxy = bus_->GetObjectProxy( - kFreeDesktopAPIServiceName, - dbus::ObjectPath(kFreeDesktopAPIObjectPath)); - method_call.reset( - new dbus::MethodCall(kFreeDesktopAPIInterfaceName, "UnInhibit")); + switch (type_) { + case kPowerSaveBlockPreventDisplaySleep: + object_proxy = bus_->GetObjectProxy( + kFreeDesktopAPIScreenServiceName, + dbus::ObjectPath(kFreeDesktopAPIScreenObjectPath)); + method_call.reset(new dbus::MethodCall( + kFreeDesktopAPIScreenInterfaceName, "UnInhibit")); + break; + case kPowerSaveBlockPreventAppSuspension: + object_proxy = bus_->GetObjectProxy( + kFreeDesktopAPIPowerServiceName, + dbus::ObjectPath(kFreeDesktopAPIPowerObjectPath)); + method_call.reset(new dbus::MethodCall( + kFreeDesktopAPIPowerInterfaceName, "UnInhibit")); + break; + } break; } @@ -383,12 +417,21 @@ PowerSaveBlockerImpl::PowerSaveBlockerImpl(PowerSaveBlockerType type, Reason reason, const std::string& description) - : delegate_(new Delegate(type, description)) { + : delegate_(new Delegate(type, description, false /* freedesktop_only */)) { delegate_->Init(); + + if (type == kPowerSaveBlockPreventDisplaySleep) { + freedesktop_suspend_delegate_ = + new Delegate(kPowerSaveBlockPreventAppSuspension, description, + true /* freedesktop_only */); + freedesktop_suspend_delegate_->Init(); + } } PowerSaveBlockerImpl::~PowerSaveBlockerImpl() { delegate_->CleanUp(); + if (freedesktop_suspend_delegate_) + freedesktop_suspend_delegate_->CleanUp(); } } // namespace content
diff --git a/content/browser/renderer_host/media/video_capture_gpu_jpeg_decoder.cc b/content/browser/renderer_host/media/video_capture_gpu_jpeg_decoder.cc index 4e88200..a370ccf5 100644 --- a/content/browser/renderer_host/media/video_capture_gpu_jpeg_decoder.cc +++ b/content/browser/renderer_host/media/video_capture_gpu_jpeg_decoder.cc
@@ -4,6 +4,8 @@ #include "content/browser/renderer_host/media/video_capture_gpu_jpeg_decoder.h" +#include <utility> + #include "base/bind.h" #include "base/command_line.h" #include "base/logging.h" @@ -210,7 +212,7 @@ BrowserGpuChannelHostFactory::instance()->GetGpuChannel()); task_runner->PostTask( FROM_HERE, base::Bind(&VideoCaptureGpuJpegDecoder::FinishInitialization, - weak_this, base::Passed(&gpu_channel_host))); + weak_this, std::move(gpu_channel_host))); } void VideoCaptureGpuJpegDecoder::FinishInitialization( @@ -220,7 +222,7 @@ if (!gpu_channel_host) { LOG(ERROR) << "Failed to establish GPU channel for JPEG decoder"; } else if (gpu_channel_host->gpu_info().jpeg_decode_accelerator_supported) { - gpu_channel_host_ = gpu_channel_host.Pass(); + gpu_channel_host_ = std::move(gpu_channel_host); decoder_ = gpu_channel_host_->CreateJpegDecoder(this); } decoder_status_ = decoder_ ? INIT_PASSED : FAILED;
diff --git a/content/browser/renderer_host/render_process_host_impl.cc b/content/browser/renderer_host/render_process_host_impl.cc index 4c2413e3..60b94257 100644 --- a/content/browser/renderer_host/render_process_host_impl.cc +++ b/content/browser/renderer_host/render_process_host_impl.cc
@@ -1385,7 +1385,6 @@ switches::kEnablePreciseMemoryInfo, switches::kEnablePreferCompositingToLCDText, switches::kEnablePrefixedEncryptedMedia, - switches::kEnablePushMessagePayload, switches::kEnableRGBA4444Textures, switches::kEnableRendererMojoChannel, switches::kEnableSkiaBenchmarking,
diff --git a/content/browser/renderer_host/render_view_host_impl.cc b/content/browser/renderer_host/render_view_host_impl.cc index d33bc94..b772300a 100644 --- a/content/browser/renderer_host/render_view_host_impl.cc +++ b/content/browser/renderer_host/render_view_host_impl.cc
@@ -74,7 +74,6 @@ #include "content/public/common/url_utils.h" #include "net/base/filename_util.h" #include "net/base/net_util.h" -#include "net/base/network_change_notifier.h" #include "net/url_request/url_request_context_getter.h" #include "storage/browser/fileapi/isolated_context.h" #include "third_party/skia/include/core/SkBitmap.h" @@ -506,11 +505,6 @@ prefs.javascript_enabled = true; } - net::NetworkChangeNotifier::GetMaxBandwidthAndConnectionType( - &prefs.net_info_max_bandwidth_mbps, &prefs.net_info_connection_type); - prefs.is_online = prefs.net_info_connection_type != - net::NetworkChangeNotifier::CONNECTION_NONE; - prefs.number_of_cpu_cores = base::SysInfo::NumberOfProcessors(); prefs.viewport_enabled =
diff --git a/content/browser/renderer_host/render_widget_host_view_mus.cc b/content/browser/renderer_host/render_widget_host_view_mus.cc index bc0ae25..76f405a 100644 --- a/content/browser/renderer_host/render_widget_host_view_mus.cc +++ b/content/browser/renderer_host/render_widget_host_view_mus.cc
@@ -12,6 +12,7 @@ #include "content/common/render_widget_window_tree_client_factory.mojom.h" #include "content/public/common/mojo_shell_connection.h" #include "mojo/application/public/cpp/application_impl.h" +#include "ui/aura/window.h" namespace blink { struct WebScreenInfo; @@ -61,18 +62,15 @@ } void RenderWidgetHostViewMus::SetSize(const gfx::Size& size) { - size_ = size; - gfx::Rect bounds = window_->window()->bounds(); - // TODO(fsamuel): figure out position. - bounds.set_x(10); - bounds.set_y(150); - bounds.set_size(size); + platform_view_->SetSize(size); + gfx::Rect bounds = platform_view_->GetNativeView()->GetBoundsInRootWindow(); window_->window()->SetBounds(bounds); - host_->WasResized(); } void RenderWidgetHostViewMus::SetBounds(const gfx::Rect& rect) { - SetSize(rect.size()); + platform_view_->SetBounds(rect); + gfx::Rect bounds = platform_view_->GetNativeView()->GetBoundsInRootWindow(); + window_->window()->SetBounds(bounds); } void RenderWidgetHostViewMus::Focus() { @@ -91,7 +89,7 @@ } gfx::Rect RenderWidgetHostViewMus::GetViewBounds() const { - return gfx::Rect(size_); + return platform_view_->GetViewBounds(); } gfx::Vector2dF RenderWidgetHostViewMus::GetLastScrollOffset() const { @@ -142,7 +140,7 @@ } gfx::NativeView RenderWidgetHostViewMus::GetNativeView() const { - return gfx::NativeView(); + return platform_view_->GetNativeView(); } gfx::NativeViewId RenderWidgetHostViewMus::GetNativeViewId() const { @@ -244,7 +242,7 @@ } gfx::Rect RenderWidgetHostViewMus::GetBoundsInRootWindow() { - return GetViewBounds(); + return platform_view_->GetBoundsInRootWindow(); } #if defined(OS_MACOSX)
diff --git a/content/browser/renderer_host/render_widget_host_view_mus.h b/content/browser/renderer_host/render_widget_host_view_mus.h index d3ae71dc..4029668 100644 --- a/content/browser/renderer_host/render_widget_host_view_mus.h +++ b/content/browser/renderer_host/render_widget_host_view_mus.h
@@ -124,7 +124,6 @@ RenderWidgetHostImpl* host_; scoped_ptr<mus::ScopedWindowPtr> window_; - gfx::Size size_; // The platform view for this RenderWidgetHostView. // RenderWidgetHostViewMus mostly only cares about stuff related to // compositing, the rest are directly forwared to this |platform_view_|.
diff --git a/content/browser/resource_loading_browsertest.cc b/content/browser/resource_loading_browsertest.cc index 5765fe3..c68d577 100644 --- a/content/browser/resource_loading_browsertest.cc +++ b/content/browser/resource_loading_browsertest.cc
@@ -16,12 +16,12 @@ }; const char kResourceLoadingNonMobilePage[] = - "files/resource_loading/resource_loading_non_mobile.html"; + "/resource_loading/resource_loading_non_mobile.html"; IN_PROC_BROWSER_TEST_F(ResourceLoadingBrowserTest, ResourceLoadingAvoidDoubleDownloads) { - ASSERT_TRUE(test_server()->Start()); - GURL url = test_server()->GetURL(kResourceLoadingNonMobilePage); + ASSERT_TRUE(embedded_test_server()->Start()); + GURL url = embedded_test_server()->GetURL(kResourceLoadingNonMobilePage); NavigateToURL(shell(), url); int data = -1; EXPECT_TRUE(ExecuteScriptAndExtractInt(shell()->web_contents(), @@ -30,4 +30,3 @@ } } // namespace content -
diff --git a/content/browser/service_worker/service_worker_version.cc b/content/browser/service_worker/service_worker_version.cc index 47083d1..6c0d21a 100644 --- a/content/browser/service_worker/service_worker_version.cc +++ b/content/browser/service_worker/service_worker_version.cc
@@ -421,7 +421,8 @@ } // namespace const int ServiceWorkerVersion::kTimeoutTimerDelaySeconds = 30; -const int ServiceWorkerVersion::kStartWorkerTimeoutMinutes = 5; +const int ServiceWorkerVersion::kStartInstalledWorkerTimeoutSeconds = 10; +const int ServiceWorkerVersion::kStartNewWorkerTimeoutMinutes = 5; const int ServiceWorkerVersion::kRequestTimeoutMinutes = 5; const int ServiceWorkerVersion::kStopWorkerTimeoutSeconds = 5; @@ -1145,6 +1146,11 @@ DCHECK_EQ(RUNNING, running_status()); RestartTick(&idle_time_); + // Reset the interval to normal. If may have been shortened so starting an + // existing worker can timeout quickly. + SetTimeoutTimerInterval( + base::TimeDelta::FromSeconds(kTimeoutTimerDelaySeconds)); + // Fire all start callbacks. scoped_refptr<ServiceWorkerVersion> protect(this); RunCallbacks(this, &start_callbacks_, SERVICE_WORKER_OK); @@ -1158,15 +1164,8 @@ // Shorten the interval so stalling in stopped can be fixed quickly. Once the // worker stops, the timer is disabled. The interval will be reset to normal // when the worker starts up again. - DCHECK(timeout_timer_.IsRunning()); - base::TimeDelta delay = - base::TimeDelta::FromSeconds(kStopWorkerTimeoutSeconds); - if (timeout_timer_.GetCurrentDelay() != delay) { - timeout_timer_.Stop(); - timeout_timer_.Start(FROM_HERE, delay, this, - &ServiceWorkerVersion::OnTimeoutTimer); - } - + SetTimeoutTimerInterval( + base::TimeDelta::FromSeconds(kStopWorkerTimeoutSeconds)); FOR_EACH_OBSERVER(Listener, listeners_, OnRunningStateChanged(this)); } @@ -2030,9 +2029,16 @@ // Ping will be activated in OnScriptLoaded. ping_controller_->Deactivate(); + // Make the timer delay shorter for starting an existing + // worker so stalled in starting workers can be timed out quickly. + // The timer will be reset to normal in OnStarted or the next start + // attempt. + const int delay_in_seconds = IsInstalled(status_) + ? kStartInstalledWorkerTimeoutSeconds + : kTimeoutTimerDelaySeconds; timeout_timer_.Start(FROM_HERE, - base::TimeDelta::FromSeconds(kTimeoutTimerDelaySeconds), - this, &ServiceWorkerVersion::OnTimeoutTimer); + base::TimeDelta::FromSeconds(delay_in_seconds), this, + &ServiceWorkerVersion::OnTimeoutTimer); } void ServiceWorkerVersion::StopTimeoutTimer() { @@ -2047,6 +2053,15 @@ } } +void ServiceWorkerVersion::SetTimeoutTimerInterval(base::TimeDelta interval) { + DCHECK(timeout_timer_.IsRunning()); + if (timeout_timer_.GetCurrentDelay() != interval) { + timeout_timer_.Stop(); + timeout_timer_.Start(FROM_HERE, interval, this, + &ServiceWorkerVersion::OnTimeoutTimer); + } +} + void ServiceWorkerVersion::OnTimeoutTimer() { DCHECK(running_status() == STARTING || running_status() == RUNNING || running_status() == STOPPING) @@ -2087,8 +2102,11 @@ } // Starting a worker hasn't finished within a certain period. - if (GetTickDuration(start_time_) > - base::TimeDelta::FromMinutes(kStartWorkerTimeoutMinutes)) { + const base::TimeDelta start_limit = + IsInstalled(status()) + ? base::TimeDelta::FromSeconds(kStartInstalledWorkerTimeoutSeconds) + : base::TimeDelta::FromMinutes(kStartNewWorkerTimeoutMinutes); + if (GetTickDuration(start_time_) > start_limit) { DCHECK(running_status() == STARTING || running_status() == STOPPING) << running_status(); scoped_refptr<ServiceWorkerVersion> protect(this);
diff --git a/content/browser/service_worker/service_worker_version.h b/content/browser/service_worker/service_worker_version.h index 3d474b72..2da6a3a 100644 --- a/content/browser/service_worker/service_worker_version.h +++ b/content/browser/service_worker/service_worker_version.h
@@ -405,8 +405,10 @@ // The timeout timer interval. static const int kTimeoutTimerDelaySeconds; - // Timeout for the worker to start. - static const int kStartWorkerTimeoutMinutes; + // Timeout for an installed worker to start. + static const int kStartInstalledWorkerTimeoutSeconds; + // Timeout for a new worker to start. + static const int kStartNewWorkerTimeoutMinutes; // Timeout for a request to be handled. static const int kRequestTimeoutMinutes; // Timeout for the worker to stop. @@ -526,6 +528,7 @@ void StartTimeoutTimer(); void StopTimeoutTimer(); void OnTimeoutTimer(); + void SetTimeoutTimerInterval(base::TimeDelta interval); // Called by PingController for ping protocol. ServiceWorkerStatusCode PingWorker();
diff --git a/content/browser/service_worker/service_worker_version_unittest.cc b/content/browser/service_worker/service_worker_version_unittest.cc index 55a6d91..e527f56 100644 --- a/content/browser/service_worker/service_worker_version_unittest.cc +++ b/content/browser/service_worker/service_worker_version_unittest.cc
@@ -713,7 +713,7 @@ version_->stale_time_ = base::TimeTicks::Now() - base::TimeDelta::FromMinutes( - ServiceWorkerVersion::kStartWorkerTimeoutMinutes + 1); + ServiceWorkerVersion::kStartNewWorkerTimeoutMinutes + 1); version_->OnTimeoutTimer(); EXPECT_TRUE(version_->stale_time_.is_null()); EXPECT_TRUE(version_->update_timer_.IsRunning()); @@ -728,7 +728,7 @@ base::TimeTicks stale_time = base::TimeTicks::Now() - base::TimeDelta::FromMinutes( - ServiceWorkerVersion::kStartWorkerTimeoutMinutes + 1); + ServiceWorkerVersion::kStartNewWorkerTimeoutMinutes + 1); version_->stale_time_ = stale_time; // Stale time is not deferred. @@ -822,7 +822,7 @@ version_->start_time_ = base::TimeTicks::Now() - base::TimeDelta::FromMinutes( - ServiceWorkerVersion::kStartWorkerTimeoutMinutes + 1); + ServiceWorkerVersion::kStartNewWorkerTimeoutMinutes + 1); version_->timeout_timer_.user_task().Run(); base::RunLoop().RunUntilIdle(); EXPECT_EQ(SERVICE_WORKER_ERROR_TIMEOUT, status);
diff --git a/content/browser/site_per_process_browsertest.cc b/content/browser/site_per_process_browsertest.cc index 007c6cd..cd46ef8f 100644 --- a/content/browser/site_per_process_browsertest.cc +++ b/content/browser/site_per_process_browsertest.cc
@@ -4069,6 +4069,91 @@ EXPECT_EQ("FOO", result); } +// Ensure that sequential focus navigation (advancing focused elements with +// <tab> and <shift-tab>) works across cross-process subframes. +// The test sets up six inputs fields in a page with two cross-process +// subframes: +// child1 child2 +// /------------\ /------------\. +// | 2. <input> | | 4. <input> | +// 1. <input> | 3. <input> | | 5. <input> | 6. <input> +// \------------/ \------------/. +// +// The test then presses <tab> six times to cycle through focused elements 1-6. +// The test then repeats this with <shift-tab> to cycle in reverse order. +IN_PROC_BROWSER_TEST_F(SitePerProcessBrowserTest, SequentialFocusNavigation) { + GURL main_url(embedded_test_server()->GetURL( + "a.com", "/cross_site_iframe_factory.html?a(b,c)")); + EXPECT_TRUE(NavigateToURL(shell(), main_url)); + + WebContents* contents = shell()->web_contents(); + FrameTreeNode* root = + static_cast<WebContentsImpl*>(contents)->GetFrameTree()->root(); + + // Assign a name to each frame. This will be sent along in test messages + // from focus events. + EXPECT_TRUE(ExecuteScript(root->current_frame_host(), + "window.name = 'root';")); + EXPECT_TRUE(ExecuteScript(root->child_at(0)->current_frame_host(), + "window.name = 'child1';")); + EXPECT_TRUE(ExecuteScript(root->child_at(1)->current_frame_host(), + "window.name = 'child2';")); + + // This script will insert two <input> fields in the document, one at the + // beginning and one at the end. For root frame, this means that we will + // have an <input>, then two <iframe> elements, then another <input>. + std::string script = + "function onFocus(e) {" + " domAutomationController.setAutomationId(0);" + " domAutomationController.send(window.name + '-focused-' + e.target.id);" + "}" + "var input1 = document.createElement('input');" + "input1.id = 'input1';" + "var input2 = document.createElement('input');" + "input2.id = 'input2';" + "document.body.insertBefore(input1, document.body.firstChild);" + "document.body.appendChild(input2);" + "input1.addEventListener('focus', onFocus, false);" + "input2.addEventListener('focus', onFocus, false);"; + + // Add two input fields to each of the three frames. + EXPECT_TRUE(ExecuteScript(root->current_frame_host(), script)); + EXPECT_TRUE(ExecuteScript(root->child_at(0)->current_frame_host(), script)); + EXPECT_TRUE(ExecuteScript(root->child_at(1)->current_frame_host(), script)); + + // Helper to simulate a tab press and wait for a focus message. + auto press_tab_and_wait_for_message = [contents](bool reverse) { + DOMMessageQueue msg_queue; + std::string reply; + SimulateKeyPress(contents, ui::VKEY_TAB, false, reverse /* shift */, false, + false); + EXPECT_TRUE(msg_queue.WaitForMessage(&reply)); + return reply; + }; + + // Press <tab> six times to focus each of the <input> elements in turn. + EXPECT_EQ("\"root-focused-input1\"", press_tab_and_wait_for_message(false)); + EXPECT_EQ(root, root->frame_tree()->GetFocusedFrame()); + EXPECT_EQ("\"child1-focused-input1\"", press_tab_and_wait_for_message(false)); + EXPECT_EQ(root->child_at(0), root->frame_tree()->GetFocusedFrame()); + EXPECT_EQ("\"child1-focused-input2\"", press_tab_and_wait_for_message(false)); + EXPECT_EQ("\"child2-focused-input1\"", press_tab_and_wait_for_message(false)); + EXPECT_EQ(root->child_at(1), root->frame_tree()->GetFocusedFrame()); + EXPECT_EQ("\"child2-focused-input2\"", press_tab_and_wait_for_message(false)); + EXPECT_EQ("\"root-focused-input2\"", press_tab_and_wait_for_message(false)); + EXPECT_EQ(root, root->frame_tree()->GetFocusedFrame()); + + // Now, press <shift-tab> to navigate focus in the reverse direction. + EXPECT_EQ("\"child2-focused-input2\"", press_tab_and_wait_for_message(true)); + EXPECT_EQ(root->child_at(1), root->frame_tree()->GetFocusedFrame()); + EXPECT_EQ("\"child2-focused-input1\"", press_tab_and_wait_for_message(true)); + EXPECT_EQ("\"child1-focused-input2\"", press_tab_and_wait_for_message(true)); + EXPECT_EQ(root->child_at(0), root->frame_tree()->GetFocusedFrame()); + EXPECT_EQ("\"child1-focused-input1\"", press_tab_and_wait_for_message(true)); + EXPECT_EQ("\"root-focused-input1\"", press_tab_and_wait_for_message(true)); + EXPECT_EQ(root, root->frame_tree()->GetFocusedFrame()); +} + // A WebContentsDelegate to capture ContextMenu creation events. class ContextMenuObserverDelegate : public WebContentsDelegate { public:
diff --git a/content/browser/web_contents/web_contents_android.cc b/content/browser/web_contents/web_contents_android.cc index e4fa397..9e301ab0 100644 --- a/content/browser/web_contents/web_contents_android.cc +++ b/content/browser/web_contents/web_contents_android.cc
@@ -675,6 +675,11 @@ result_callback); } +void WebContentsAndroid::OnContextMenuClosed(JNIEnv* env, jobject obj) { + static_cast<WebContentsImpl*>(web_contents_) + ->NotifyContextMenuClosed(CustomContextMenuContext()); +} + void WebContentsAndroid::OnFinishGetContentBitmap( ScopedJavaGlobalRef<jobject>* obj, ScopedJavaGlobalRef<jobject>* callback, @@ -690,4 +695,5 @@ java_bitmap.obj(), response); } + } // namespace content
diff --git a/content/browser/web_contents/web_contents_android.h b/content/browser/web_contents/web_contents_android.h index 1bc37393..c4eb33cf 100644 --- a/content/browser/web_contents/web_contents_android.h +++ b/content/browser/web_contents/web_contents_android.h
@@ -174,6 +174,9 @@ jfloat y, jfloat width, jfloat height); + + void OnContextMenuClosed(JNIEnv* env, jobject obj); + void set_synchronous_compositor_client(SynchronousCompositorClient* client) { synchronous_compositor_client_ = client; }
diff --git a/content/child/BUILD.gn b/content/child/BUILD.gn index 3ebac31..5a70f60a 100644 --- a/content/child/BUILD.gn +++ b/content/child/BUILD.gn
@@ -72,15 +72,6 @@ "npapi/plugin_instance.h", "npapi/plugin_lib.cc", "npapi/plugin_lib.h", - "npapi/plugin_stream.cc", - "npapi/plugin_stream.h", - "npapi/plugin_stream_posix.cc", - "npapi/plugin_stream_url.cc", - "npapi/plugin_stream_url.h", - "npapi/plugin_string_stream.cc", - "npapi/plugin_string_stream.h", - "npapi/plugin_url_fetcher.cc", - "npapi/plugin_url_fetcher.h", "npapi/webplugin.h", "npapi/webplugin_delegate.h", "npapi/webplugin_delegate_impl.cc", @@ -98,7 +89,6 @@ ] } else if (is_win) { sources -= [ - "npapi/plugin_stream_win.cc", "npapi/webplugin_delegate_impl_win.cc", "npapi/webplugin_ime_win.cc", "npapi/webplugin_ime_win.h",
diff --git a/content/child/child_gpu_memory_buffer_manager.cc b/content/child/child_gpu_memory_buffer_manager.cc index c83ceea6..21a512f 100644 --- a/content/child/child_gpu_memory_buffer_manager.cc +++ b/content/child/child_gpu_memory_buffer_manager.cc
@@ -45,18 +45,13 @@ content::GetNextGenericSharedMemoryId(), size.width(), size.height(), format, usage, &handle); bool success = sender_->Send(message); - if (!success || handle.is_null()) - return nullptr; + CHECK(success); + CHECK(!handle.is_null()); scoped_ptr<GpuMemoryBufferImpl> buffer(GpuMemoryBufferImpl::CreateFromHandle( handle, size, format, usage, base::Bind(&DeletedGpuMemoryBuffer, sender_, handle.id))); - if (!buffer) { - sender_->Send(new ChildProcessHostMsg_DeletedGpuMemoryBuffer( - handle.id, gpu::SyncToken())); - return nullptr; - } - + CHECK(buffer); return buffer.Pass(); }
diff --git a/content/child/npapi/plugin_host.cc b/content/child/npapi/plugin_host.cc index ea7d0a0..4f3006e0 100644 --- a/content/child/npapi/plugin_host.cc +++ b/content/child/npapi/plugin_host.cc
@@ -16,7 +16,6 @@ #include "build/build_config.h" #include "content/child/npapi/plugin_instance.h" #include "content/child/npapi/plugin_lib.h" -#include "content/child/npapi/plugin_stream_url.h" #include "content/child/npapi/webplugin_delegate.h" #include "content/public/common/content_client.h" #include "content/public/common/content_switches.h" @@ -339,174 +338,28 @@ // Requests a range of bytes for a seekable stream. NPError NPN_RequestRead(NPStream* stream, NPByteRange* range_list) { - if (!stream || !range_list) - return NPERR_GENERIC_ERROR; - - scoped_refptr<PluginInstance> plugin( - reinterpret_cast<PluginInstance*>(stream->ndata)); - if (!plugin.get()) - return NPERR_GENERIC_ERROR; - - plugin->RequestRead(stream, range_list); - return NPERR_NO_ERROR; + return NPERR_GENERIC_ERROR; } -// Generic form of GetURL for common code between GetURL and GetURLNotify. -static NPError GetURLNotify(NPP id, - const char* url, - const char* target, - bool notify, - void* notify_data) { - if (!url) - return NPERR_INVALID_URL; - - scoped_refptr<PluginInstance> plugin(FindInstance(id)); - if (!plugin.get()) { - return NPERR_GENERIC_ERROR; - } - - plugin->RequestURL(url, "GET", target, NULL, 0, notify, notify_data); - return NPERR_NO_ERROR; -} - -// Requests creation of a new stream with the contents of the -// specified URL; gets notification of the result. NPError NPN_GetURLNotify(NPP id, const char* url, const char* target, void* notify_data) { - // This is identical to NPN_GetURL, but after finishing, the - // browser will call NPP_URLNotify to inform the plugin that - // it has completed. - - // According to the NPAPI documentation, if target == _self - // or a parent to _self, the browser should return NPERR_INVALID_PARAM, - // because it can't notify the plugin once deleted. This is - // absolutely false; firefox doesn't do this, and Flash relies on - // being able to use this. - - // Also according to the NPAPI documentation, we should return - // NPERR_INVALID_URL if the url requested is not valid. However, - // this would require that we synchronously start fetching the - // URL. That just isn't practical. As such, there really is - // no way to return this error. From looking at the Firefox - // implementation, it doesn't look like Firefox does this either. - - return GetURLNotify(id, url, target, true, notify_data); + return NPERR_GENERIC_ERROR; } NPError NPN_GetURL(NPP id, const char* url, const char* target) { - // Notes: - // Request from the Plugin to fetch content either for the plugin - // or to be placed into a browser window. - // - // If target == null, the browser fetches content and streams to plugin. - // otherwise, the browser loads content into an existing browser frame. - // If the target is the window/frame containing the plugin, the plugin - // may be destroyed. - // If the target is _blank, a mailto: or news: url open content in a new - // browser window - // If the target is _self, no other instance of the plugin is created. The - // plugin continues to operate in its own window - - return GetURLNotify(id, url, target, false, 0); -} - -// Generic form of PostURL for common code between PostURL and PostURLNotify. -static NPError PostURLNotify(NPP id, - const char* url, - const char* target, - uint32_t len, - const char* buf, - NPBool file, - bool notify, - void* notify_data) { - if (!url) - return NPERR_INVALID_URL; - - scoped_refptr<PluginInstance> plugin(FindInstance(id)); - if (!plugin.get()) { - NOTREACHED(); - return NPERR_GENERIC_ERROR; - } - - std::string post_file_contents; - - if (file) { - // Post data to be uploaded from a file. This can be handled in two - // ways. - // 1. Read entire file and send the contents as if it was a post data - // specified in the argument - // 2. Send just the file details and read them in the browser at the - // time of sending the request. - // Approach 2 is more efficient but complicated. Approach 1 has a major - // drawback of sending potentially large data over two IPC hops. In a way - // 'large data over IPC' problem exists as it is in case of plugin giving - // the data directly instead of in a file. - // Currently we are going with the approach 1 to get the feature working. - // We can optimize this later with approach 2. - - // TODO(joshia): Design a scheme to send a file descriptor instead of - // entire file contents across. - - // Security alert: - // --------------- - // Here we are blindly uploading whatever file requested by a plugin. - // This is risky as someone could exploit a plugin to send private - // data in arbitrary locations. - // A malicious (non-sandboxed) plugin has unfeterred access to OS - // resources and can do this anyway without using browser's HTTP stack. - // FWIW, Firefox and Safari don't perform any security checks. - - if (!buf) - return NPERR_FILE_NOT_FOUND; - - std::string file_path_ascii(buf); - base::FilePath file_path; - static const char kFileUrlPrefix[] = "file:"; - if (base::StartsWith(file_path_ascii, kFileUrlPrefix, - base::CompareCase::INSENSITIVE_ASCII)) { - GURL file_url(file_path_ascii); - DCHECK(file_url.SchemeIsFile()); - net::FileURLToFilePath(file_url, &file_path); - } else { - file_path = base::FilePath::FromUTF8Unsafe(file_path_ascii); - } - - base::File::Info post_file_info; - if (!base::GetFileInfo(file_path, &post_file_info) || - post_file_info.is_directory) - return NPERR_FILE_NOT_FOUND; - - if (!base::ReadFileToString(file_path, &post_file_contents)) - return NPERR_FILE_NOT_FOUND; - - buf = post_file_contents.c_str(); - len = post_file_contents.size(); - } - - // The post data sent by a plugin contains both headers - // and post data. Example: - // Content-type: text/html - // Content-length: 200 - // - // <200 bytes of content here> - // - // Unfortunately, our stream needs these broken apart, - // so we need to parse the data and set headers and data - // separately. - plugin->RequestURL(url, "POST", target, buf, len, notify, notify_data); - return NPERR_NO_ERROR; + return NPERR_GENERIC_ERROR; } NPError NPN_PostURLNotify(NPP id, - const char* url, - const char* target, - uint32_t len, - const char* buf, - NPBool file, - void* notify_data) { - return PostURLNotify(id, url, target, len, buf, file, true, notify_data); + const char* url, + const char* target, + uint32_t len, + const char* buf, + NPBool file, + void* notify_data) { + return NPERR_GENERIC_ERROR; } NPError NPN_PostURL(NPP id, @@ -515,28 +368,7 @@ uint32_t len, const char* buf, NPBool file) { - // POSTs data to an URL, either from a temp file or a buffer. - // If file is true, buf contains a temp file (which host will delete after - // completing), and len contains the length of the filename. - // If file is false, buf contains the data to send, and len contains the - // length of the buffer - // - // If target is null, - // server response is returned to the plugin - // If target is _current, _self, or _top, - // server response is written to the plugin window and plugin is unloaded. - // If target is _new or _blank, - // server response is written to a new browser window - // If target is an existing frame, - // server response goes to that frame. - // - // For protocols other than FTP - // file uploads must be line-end converted from \r\n to \n - // - // Note: you cannot specify headers (even a blank line) in a memory buffer, - // use NPN_PostURLNotify - - return PostURLNotify(id, url, target, len, buf, file, false, 0); + return NPERR_GENERIC_ERROR; } NPError NPN_NewStream(NPP id, @@ -1098,10 +930,6 @@ } void NPN_URLRedirectResponse(NPP instance, void* notify_data, NPBool allow) { - scoped_refptr<PluginInstance> plugin(FindInstance(instance)); - if (plugin.get()) { - plugin->URLRedirectResponse(!!allow, notify_data); - } } } // extern "C"
diff --git a/content/child/npapi/plugin_instance.cc b/content/child/npapi/plugin_instance.cc index c6c15441..4684fd7 100644 --- a/content/child/npapi/plugin_instance.cc +++ b/content/child/npapi/plugin_instance.cc
@@ -15,8 +15,6 @@ #include "build/build_config.h" #include "content/child/npapi/plugin_host.h" #include "content/child/npapi/plugin_lib.h" -#include "content/child/npapi/plugin_stream_url.h" -#include "content/child/npapi/plugin_string_stream.h" #include "content/child/npapi/webplugin.h" #include "content/child/npapi/webplugin_delegate.h" #include "content/child/npapi/webplugin_resource_client.h" @@ -40,7 +38,6 @@ transparent_(true), webplugin_(0), mime_type_(mime_type), - get_notify_data_(0), use_mozilla_user_agent_(false), #if defined (OS_MACOSX) #ifdef NP_NO_QUICKDRAW @@ -57,11 +54,7 @@ #endif task_runner_(base::ThreadTaskRunnerHandle::Get()), load_manually_(false), - in_close_streams_(false), - next_timer_id_(1), - next_notify_id_(0), - next_range_request_id_(0), - handles_url_redirects_(false) { + next_timer_id_(1) { npp_ = new NPP_t(); npp_->ndata = 0; npp_->pdata = 0; @@ -73,8 +66,6 @@ } PluginInstance::~PluginInstance() { - CloseStreams(); - if (npp_ != 0) { delete npp_; npp_ = 0; @@ -84,73 +75,6 @@ plugin_->CloseInstance(); } -PluginStreamUrl* PluginInstance::CreateStream(unsigned long resource_id, - const GURL& url, - const std::string& mime_type, - int notify_id) { - - bool notify; - void* notify_data; - GetNotifyData(notify_id, ¬ify, ¬ify_data); - PluginStreamUrl* stream = new PluginStreamUrl( - resource_id, url, this, notify, notify_data); - - AddStream(stream); - return stream; -} - -void PluginInstance::AddStream(PluginStream* stream) { - open_streams_.push_back(make_scoped_refptr(stream)); -} - -void PluginInstance::RemoveStream(PluginStream* stream) { - if (in_close_streams_) - return; - - std::vector<scoped_refptr<PluginStream> >::iterator stream_index; - for (stream_index = open_streams_.begin(); - stream_index != open_streams_.end(); ++stream_index) { - if (stream_index->get() == stream) { - open_streams_.erase(stream_index); - break; - } - } -} - -bool PluginInstance::IsValidStream(const NPStream* stream) { - std::vector<scoped_refptr<PluginStream> >::iterator stream_index; - for (stream_index = open_streams_.begin(); - stream_index != open_streams_.end(); ++stream_index) { - if ((*stream_index)->stream() == stream) - return true; - } - - return false; -} - -void PluginInstance::CloseStreams() { - in_close_streams_ = true; - for (unsigned int index = 0; index < open_streams_.size(); ++index) { - // Close all streams on the way down. - open_streams_[index]->Close(NPRES_USER_BREAK); - } - open_streams_.clear(); - in_close_streams_ = false; -} - -WebPluginResourceClient* PluginInstance::GetRangeRequest( - int id) { - PendingRangeRequestMap::iterator iter = pending_range_requests_.find(id); - if (iter == pending_range_requests_.end()) { - NOTREACHED(); - return NULL; - } - - WebPluginResourceClient* rv = iter->second->AsResourceClient(); - pending_range_requests_.erase(iter); - return rv; -} - bool PluginInstance::Start(const GURL& url, char** const param_names, char** const param_values, @@ -162,12 +86,6 @@ NPError err = NPP_New(mode, param_count, const_cast<char **>(param_names), const_cast<char **>(param_values)); - - if (err == NPERR_NO_ERROR) { - handles_url_redirects_ = - ((npp_functions_->version >= NPVERS_HAS_URL_REDIRECT_HANDLING) && - (npp_functions_->urlredirectnotify)); - } return err == NPERR_NO_ERROR; } @@ -192,21 +110,6 @@ return true; } -// WebPluginLoadDelegate methods -void PluginInstance::DidFinishLoadWithReason(const GURL& url, - NPReason reason, - int notify_id) { - bool notify; - void* notify_data; - GetNotifyData(notify_id, ¬ify, ¬ify_data); - if (!notify) { - NOTREACHED(); - return; - } - - NPP_URLNotify(url.spec().c_str(), reason, notify_data); -} - unsigned PluginInstance::GetBackingTextureId() { // By default the plugin instance is not backed by an OpenGL texture. return 0; @@ -280,7 +183,7 @@ DCHECK(npp_functions_ != 0); DCHECK(npp_functions_->destroystream != 0); - if (stream == NULL || !IsValidStream(stream) || (stream->ndata == NULL)) + if (stream == NULL || (stream->ndata == NULL)) return NPERR_INVALID_INSTANCE_ERROR; if (npp_functions_->destroystream != 0) { @@ -326,16 +229,6 @@ files_created_.push_back(file_name); } -void PluginInstance::NPP_URLNotify(const char* url, - NPReason reason, - void* notifyData) { - DCHECK(npp_functions_ != 0); - DCHECK(npp_functions_->urlnotify != 0); - if (npp_functions_->urlnotify != 0) { - npp_functions_->urlnotify(npp_, url, reason, notifyData); - } -} - NPError PluginInstance::NPP_GetValue(NPPVariable variable, void* value) { DCHECK(npp_functions_ != 0); // getvalue is NULL for Shockwave @@ -371,71 +264,6 @@ return false; } -void PluginInstance::NPP_URLRedirectNotify(const char* url, int32_t status, - void* notify_data) { - DCHECK(npp_functions_ != 0); - if (npp_functions_->urlredirectnotify != 0) { - npp_functions_->urlredirectnotify(npp_, url, status, notify_data); - } -} - -void PluginInstance::SendJavaScriptStream(const GURL& url, - const std::string& result, - bool success, - int notify_id) { - bool notify; - void* notify_data; - GetNotifyData(notify_id, ¬ify, ¬ify_data); - - if (success) { - PluginStringStream *stream = - new PluginStringStream(this, url, notify, notify_data); - AddStream(stream); - stream->SendToPlugin(result, "text/html"); - } else { - // NOTE: Sending an empty stream here will crash MacroMedia - // Flash 9. Just send the URL Notify. - if (notify) - NPP_URLNotify(url.spec().c_str(), NPRES_DONE, notify_data); - } -} - -void PluginInstance::DidReceiveManualResponse(const GURL& url, - const std::string& mime_type, - const std::string& headers, - uint32 expected_length, - uint32 last_modified) { - DCHECK(load_manually_); - - plugin_data_stream_ = - CreateStream(static_cast<unsigned long>(-1), url, mime_type, 0); - plugin_data_stream_->DidReceiveResponse(mime_type, headers, expected_length, - last_modified, true); -} - -void PluginInstance::DidReceiveManualData(const char* buffer, int length) { - DCHECK(load_manually_); - if (plugin_data_stream_.get() != NULL) { - plugin_data_stream_->DidReceiveData(buffer, length, 0); - } -} - -void PluginInstance::DidFinishManualLoading() { - DCHECK(load_manually_); - if (plugin_data_stream_.get() != NULL) { - plugin_data_stream_->DidFinishLoading(plugin_data_stream_->ResourceId()); - plugin_data_stream_->Close(NPRES_DONE); - plugin_data_stream_ = NULL; - } -} - -void PluginInstance::DidManualLoadFail() { - DCHECK(load_manually_); - if (plugin_data_stream_.get() != NULL) { - plugin_data_stream_->DidFail(plugin_data_stream_->ResourceId()); - plugin_data_stream_ = NULL; - } -} void PluginInstance::PluginThreadAsyncCall(void (*func)(void*), void* user_data) { @@ -526,76 +354,6 @@ popups_enabled_stack_.pop(); } -void PluginInstance::RequestRead(NPStream* stream, NPByteRange* range_list) { - std::string range_info = "bytes="; - - while (range_list) { - range_info += base::IntToString(range_list->offset); - range_info.push_back('-'); - range_info += - base::UintToString(range_list->offset + range_list->length - 1); - range_list = range_list->next; - if (range_list) - range_info.push_back(','); - } - - if (plugin_data_stream_.get()) { - if (plugin_data_stream_->stream() == stream) { - webplugin_->CancelDocumentLoad(); - plugin_data_stream_ = NULL; - } - } - - // The lifetime of a NPStream instance depends on the PluginStream instance - // which owns it. When a plugin invokes NPN_RequestRead on a seekable stream, - // we don't want to create a new stream when the corresponding response is - // received. We send over a cookie which represents the PluginStream - // instance which is sent back from the renderer when the response is - // received. - std::vector<scoped_refptr<PluginStream> >::iterator stream_index; - for (stream_index = open_streams_.begin(); - stream_index != open_streams_.end(); ++stream_index) { - PluginStream* plugin_stream = stream_index->get(); - if (plugin_stream->stream() == stream) { - // A stream becomes seekable the first time NPN_RequestRead - // is called on it. - plugin_stream->set_seekable(true); - - if (base::CommandLine::ForCurrentProcess()->HasSwitch( - switches::kDisableDirectNPAPIRequests)) { - pending_range_requests_[++next_range_request_id_] = plugin_stream; - webplugin_->InitiateHTTPRangeRequest( - stream->url, range_info.c_str(), next_range_request_id_); - return; - } else { - PluginStreamUrl* plugin_stream_url = - static_cast<PluginStreamUrl*>(plugin_stream); - plugin_stream_url->FetchRange(range_info); - return; - } - } - } - NOTREACHED(); -} - -void PluginInstance::RequestURL(const char* url, - const char* method, - const char* target, - const char* buf, - unsigned int len, - bool notify, - void* notify_data) { - int notify_id = 0; - if (notify) { - notify_id = ++next_notify_id_; - pending_requests_[notify_id] = notify_data; - } - - webplugin_->HandleURLRequest( - url, method, target, buf, len, notify_id, popups_allowed(), - notify ? handles_url_redirects_ : false); -} - bool PluginInstance::ConvertPoint(double source_x, double source_y, NPCoordinateSpace source_space, double* dest_x, double* dest_y, @@ -666,33 +424,4 @@ #endif } -void PluginInstance::GetNotifyData(int notify_id, - bool* notify, - void** notify_data) { - PendingRequestMap::iterator iter = pending_requests_.find(notify_id); - if (iter != pending_requests_.end()) { - *notify = true; - *notify_data = iter->second; - pending_requests_.erase(iter); - } else { - *notify = false; - *notify_data = NULL; - } -} - -void PluginInstance::URLRedirectResponse(bool allow, void* notify_data) { - // The notify_data passed in allows us to identify the matching stream. - std::vector<scoped_refptr<PluginStream> >::iterator stream_index; - for (stream_index = open_streams_.begin(); - stream_index != open_streams_.end(); ++stream_index) { - PluginStream* plugin_stream = stream_index->get(); - if (plugin_stream->notify_data() == notify_data) { - PluginStreamUrl* plugin_stream_url = - static_cast<PluginStreamUrl*>(plugin_stream); - plugin_stream_url->URLRedirectResponse(allow); - break; - } - } -} - } // namespace content
diff --git a/content/child/npapi/plugin_instance.h b/content/child/npapi/plugin_instance.h index 9558930..bf5a5fe0 100644 --- a/content/child/npapi/plugin_instance.h +++ b/content/child/npapi/plugin_instance.h
@@ -31,8 +31,6 @@ class PluginLib; class PluginHost; -class PluginStream; -class PluginStreamUrl; class WebPlugin; class WebPluginResourceClient; @@ -121,30 +119,6 @@ } #endif - // Creates a stream for sending an URL. If notify_id is non-zero, it will - // send a notification to the plugin when the stream is complete; otherwise it - // will not. Set object_url to true if the load is for the object tag's url, - // or false if it's for a url that the plugin fetched through - // NPN_GetUrl[Notify]. - PluginStreamUrl* CreateStream(unsigned long resource_id, - const GURL& url, - const std::string& mime_type, - int notify_id); - - // For each instance, we track all streams. When the - // instance closes, all remaining streams are also - // closed. All streams associated with this instance - // should call AddStream so that they can be cleaned - // up when the instance shuts down. - void AddStream(PluginStream* stream); - - // This is called when a stream is closed. We remove the stream from the - // list, which releases the reference maintained to the stream. - void RemoveStream(PluginStream* stream); - - // Closes all open streams on this instance. - void CloseStreams(); - // Returns the WebPluginResourceClient object for a stream that has become // seekable. WebPluginResourceClient* GetRangeRequest(int id); @@ -155,10 +129,6 @@ // Returns the form value of this instance. bool GetFormValue(base::string16* value); - // WebViewDelegate methods that we implement. This is for handling - // callbacks during getURLNotify. - void DidFinishLoadWithReason(const GURL& url, NPReason reason, int notify_id); - // If true, send the Mozilla user agent instead of Chrome's to the plugin. bool use_mozilla_user_agent() { return use_mozilla_user_agent_; } void set_use_mozilla_user_agent() { use_mozilla_user_agent_ = true; } @@ -205,17 +175,7 @@ void SendJavaScriptStream(const GURL& url, const std::string& result, - bool success, - int notify_id); - - void DidReceiveManualResponse(const GURL& url, - const std::string& mime_type, - const std::string& headers, - uint32 expected_length, - uint32 last_modified); - void DidReceiveManualData(const char* buffer, int length); - void DidFinishManualLoading(); - void DidManualLoadFail(); + bool success); void PushPopupsEnabledState(bool enabled); void PopPopupsEnabledState(); @@ -224,25 +184,6 @@ return popups_enabled_stack_.empty() ? false : popups_enabled_stack_.top(); } - // Initiates byte range reads for plugins. - void RequestRead(NPStream* stream, NPByteRange* range_list); - - // Handles GetURL/GetURLNotify/PostURL/PostURLNotify requests initiated - // by plugins. - void RequestURL(const char* url, - const char* method, - const char* target, - const char* buf, - unsigned int len, - bool notify, - void* notify_data); - - // Handles NPN_URLRedirectResponse calls issued by plugins in response to - // HTTP URL redirect notifications. - void URLRedirectResponse(bool allow, void* notify_data); - - bool handles_url_redirects() const { return handles_url_redirects_; } - private: friend class base::RefCountedThreadSafe<PluginInstance>; @@ -261,8 +202,6 @@ void OnPluginThreadAsyncCall(void (*func)(void *), void* userData); void OnTimerCall(void (*func)(NPP id, uint32 timer_id), NPP id, uint32 timer_id); - bool IsValidStream(const NPStream* stream); - void GetNotifyData(int notify_id, bool* notify, void** notify_data); // This is a hack to get the real player plugin to work with chrome // The real player plugin dll(nppl3260) when loaded by firefox is loaded via @@ -289,14 +228,11 @@ NPP npp_; scoped_refptr<PluginHost> host_; NPPluginFuncs* npp_functions_; - std::vector<scoped_refptr<PluginStream> > open_streams_; gfx::PluginWindowHandle window_handle_; bool windowless_; bool transparent_; WebPlugin* webplugin_; std::string mime_type_; - GURL get_url_; - intptr_t get_notify_data_; bool use_mozilla_user_agent_; #if defined(OS_MACOSX) NPDrawingModel drawing_model_; @@ -306,7 +242,6 @@ NPCocoaEvent* currently_handled_event_; // weak #endif scoped_refptr<base::SingleThreadTaskRunner> task_runner_; - scoped_refptr<PluginStreamUrl> plugin_data_stream_; // This flag if true indicates that the plugin data would be passed from // webkit. if false indicates that the plugin should download the data. @@ -316,9 +251,6 @@ // NPN_GetURL/NPN_GetURLNotify calls. std::stack<bool> popups_enabled_stack_; - // True if in CloseStreams(). - bool in_close_streams_; - // List of files created for the current plugin instance. File names are // added to the list every time the NPP_StreamAsFile function is called. std::vector<base::FilePath> files_created_; @@ -334,21 +266,6 @@ typedef std::map<uint32, TimerInfo> TimerMap; TimerMap timers_; - // Tracks pending GET/POST requests so that the plugin-given data doesn't - // cross process boundaries to an untrusted process. - typedef std::map<int, void*> PendingRequestMap; - PendingRequestMap pending_requests_; - int next_notify_id_; - - // Used to track pending range requests so that when WebPlugin replies to us - // we can match the reply to the stream. - typedef std::map<int, scoped_refptr<PluginStream> > PendingRangeRequestMap; - PendingRangeRequestMap pending_range_requests_; - int next_range_request_id_; - // The plugin handles the NPAPI URL redirect notification API. - // See here https://wiki.mozilla.org/NPAPI:HTTPRedirectHandling - bool handles_url_redirects_; - DISALLOW_COPY_AND_ASSIGN(PluginInstance); };
diff --git a/content/child/npapi/plugin_stream.cc b/content/child/npapi/plugin_stream.cc deleted file mode 100644 index 282f69b..0000000 --- a/content/child/npapi/plugin_stream.cc +++ /dev/null
@@ -1,282 +0,0 @@ -// Copyright (c) 2012 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -// TODO : Support NP_ASFILEONLY mode -// TODO : Support NP_SEEK mode -// TODO : Support SEEKABLE=true in NewStream - -#include "content/child/npapi/plugin_stream.h" - -#include <algorithm> - -#include "base/bind.h" -#include "base/location.h" -#include "base/single_thread_task_runner.h" -#include "base/strings/string_util.h" -#include "base/strings/utf_string_conversions.h" -#include "base/thread_task_runner_handle.h" -#include "content/child/npapi/plugin_instance.h" -#include "net/base/mime_util.h" -#include "url/gurl.h" - -namespace content { - -PluginStream::PluginStream( - PluginInstance* instance, - const char* url, - bool need_notify, - void* notify_data) - : instance_(instance), - notify_needed_(need_notify), - notify_data_(notify_data), - close_on_write_data_(false), - requested_plugin_mode_(NP_NORMAL), - opened_(false), - data_offset_(0), - seekable_stream_(false) { - memset(&stream_, 0, sizeof(stream_)); - stream_.url = base::strdup(url); - ResetTempFileHandle(); - ResetTempFileName(); -} - -PluginStream::~PluginStream() { - // always close our temporary files. - CloseTempFile(); - free(const_cast<char*>(stream_.url)); -} - -bool PluginStream::Open(const std::string& mime_type, - const std::string& headers, - uint32 length, - uint32 last_modified, - bool request_is_seekable) { - headers_ = headers; - NPP id = instance_->npp(); - stream_.end = length; - stream_.lastmodified = last_modified; - stream_.pdata = 0; - stream_.ndata = id->ndata; - stream_.notifyData = notify_data_; - if (!headers_.empty()) - stream_.headers = headers_.c_str(); - - bool seekable_stream = false; - if (request_is_seekable) { - std::string headers_lc = base::ToLowerASCII(headers); - if (headers_lc.find("accept-ranges: bytes") != std::string::npos) { - seekable_stream = true; - } - } - - const char* char_mime_type = "application/x-unknown-content-type"; - std::string temp_mime_type; - if (!mime_type.empty()) { - char_mime_type = mime_type.c_str(); - } else { - GURL gurl(stream_.url); - - base::FilePath path = base::FilePath::FromUTF8Unsafe(gurl.path()); - if (net::GetMimeTypeFromFile(path, &temp_mime_type)) - char_mime_type = temp_mime_type.c_str(); - } - - // Silverlight expects a valid mime type - DCHECK_NE(0U, strlen(char_mime_type)); - NPError err = instance_->NPP_NewStream((NPMIMEType)char_mime_type, - &stream_, seekable_stream, - &requested_plugin_mode_); - if (err != NPERR_NO_ERROR) { - Notify(err); - return false; - } - - opened_ = true; - - if (requested_plugin_mode_ == NP_SEEK) { - seekable_stream_ = true; - } - // If the plugin has requested certain modes, then we need a copy - // of this file on disk. Open it and save it as we go. - if (RequestedPluginModeIsAsFile()) { - if (OpenTempFile() == false) { - return false; - } - } - - mime_type_ = char_mime_type; - return true; -} - -int PluginStream::Write(const char* buffer, const int length, - int data_offset) { - // There may be two streams to write to - the plugin and the file. - // It is unclear what to do if we cannot write to both. The rules of - // this function are that the plugin must consume at least as many - // bytes as returned by the WriteReady call. So, we will attempt to - // write that many to both streams. If we can't write that many bytes - // to each stream, we'll return failure. - - DCHECK(opened_); - if (WriteToFile(buffer, length) && - WriteToPlugin(buffer, length, data_offset)) { - return length; - } - - return -1; -} - -bool PluginStream::WriteToFile(const char* buf, size_t length) { - // For ASFILEONLY, ASFILE, and SEEK modes, we need to write - // to the disk - if (TempFileIsValid() && RequestedPluginModeIsAsFile()) { - size_t totalBytesWritten = 0, bytes; - do { - bytes = WriteBytes(buf, length); - totalBytesWritten += bytes; - } while (bytes > 0U && totalBytesWritten < length); - - if (totalBytesWritten != length) { - return false; - } - } - - return true; -} - -bool PluginStream::WriteToPlugin(const char* buf, const int length, - const int data_offset) { - // For NORMAL and ASFILE modes, we send the data to the plugin now - if (requested_plugin_mode_ != NP_NORMAL && - requested_plugin_mode_ != NP_ASFILE && - requested_plugin_mode_ != NP_SEEK) { - return true; - } - - int written = TryWriteToPlugin(buf, length, data_offset); - if (written == -1) - return false; - - if (written < length) { - // Buffer the remaining data. - size_t remaining = length - written; - size_t previous_size = delivery_data_.size(); - delivery_data_.resize(previous_size + remaining); - data_offset_ = data_offset; - memcpy(&delivery_data_[previous_size], buf + written, remaining); - base::ThreadTaskRunnerHandle::Get()->PostTask( - FROM_HERE, base::Bind(&PluginStream::OnDelayDelivery, this)); - } - - return true; -} - -void PluginStream::OnDelayDelivery() { - // It is possible that the plugin stream may have closed before the task - // was hit. - if (!opened_) - return; - - int size = static_cast<int>(delivery_data_.size()); - int written = TryWriteToPlugin(&delivery_data_.front(), size, data_offset_); - if (written > 0) { - // Remove the data that we already wrote. - delivery_data_.erase(delivery_data_.begin(), - delivery_data_.begin() + written); - } -} - -int PluginStream::TryWriteToPlugin(const char* buf, const int length, - const int data_offset) { - int byte_offset = 0; - - if (data_offset > 0) - data_offset_ = data_offset; - - while (byte_offset < length) { - int bytes_remaining = length - byte_offset; - int bytes_to_write = instance_->NPP_WriteReady(&stream_); - if (bytes_to_write > bytes_remaining) - bytes_to_write = bytes_remaining; - - if (bytes_to_write == 0) - return byte_offset; - - int bytes_consumed = instance_->NPP_Write( - &stream_, data_offset_, bytes_to_write, - const_cast<char*>(buf + byte_offset)); - if (bytes_consumed < 0) { - // The plugin failed, which means that we need to close the stream. - Close(NPRES_NETWORK_ERR); - return -1; - } - if (bytes_consumed == 0) { - // The plugin couldn't take all of the data now. - return byte_offset; - } - - // The plugin might report more that we gave it. - bytes_consumed = std::min(bytes_consumed, bytes_to_write); - - data_offset_ += bytes_consumed; - byte_offset += bytes_consumed; - } - - if (close_on_write_data_) - Close(NPRES_DONE); - - return length; -} - -bool PluginStream::Close(NPReason reason) { - if (opened_ == true) { - opened_ = false; - - if (delivery_data_.size()) { - if (reason == NPRES_DONE) { - // There is more data to be streamed, don't destroy the stream now. - close_on_write_data_ = true; - return true; - } else { - // Stop any pending data from being streamed - delivery_data_.resize(0); - } - } - - // If we have a temp file, be sure to close it. - // Also, allow the plugin to access it now. - if (TempFileIsValid()) { - CloseTempFile(); - if (reason == NPRES_DONE) - WriteAsFile(); - } - - if (stream_.ndata != NULL) { - // Stream hasn't been closed yet. - NPError err = instance_->NPP_DestroyStream(&stream_, reason); - DCHECK(err == NPERR_NO_ERROR); - } - } - - Notify(reason); - return true; -} - -WebPluginResourceClient* PluginStream::AsResourceClient() { - return NULL; -} - -void PluginStream::Notify(NPReason reason) { - if (notify_needed_) { - instance_->NPP_URLNotify(stream_.url, reason, notify_data_); - notify_needed_ = false; - } -} - -bool PluginStream::RequestedPluginModeIsAsFile() const { - return (requested_plugin_mode_ == NP_ASFILE || - requested_plugin_mode_ == NP_ASFILEONLY); -} - -} // namespace content
diff --git a/content/child/npapi/plugin_stream.h b/content/child/npapi/plugin_stream.h deleted file mode 100644 index 644e16c..0000000 --- a/content/child/npapi/plugin_stream.h +++ /dev/null
@@ -1,148 +0,0 @@ -// Copyright (c) 2012 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef CONTENT_CHILD_NPAPI_PLUGIN_STREAM_H_ -#define CONTENT_CHILD_NPAPI_PLUGIN_STREAM_H_ - -#include <string> -#include <vector> - -#include "base/files/file_path.h" -#include "base/memory/ref_counted.h" -#include "build/build_config.h" -#include "third_party/npapi/bindings/npapi.h" - -namespace content { - -class PluginInstance; -class WebPluginResourceClient; - -// Base class for a NPAPI stream. Tracks basic elements -// of a stream for NPAPI notifications and stream position. -class PluginStream : public base::RefCounted<PluginStream> { - public: - // Create a new PluginStream object. If needNotify is true, then the - // plugin will be notified when the stream has been fully sent. - PluginStream(PluginInstance* instance, - const char* url, - bool need_notify, - void* notify_data); - - // Opens the stream to the Plugin. - // If the mime-type is not specified, we'll try to find one based on the - // mime-types table and the extension (if any) in the URL. - // If the size of the stream is known, use length to set the size. If - // not known, set length to 0. - // The request_is_seekable parameter indicates whether byte range requests - // can be issued on the stream. - bool Open(const std::string &mime_type, - const std::string &headers, - uint32 length, - uint32 last_modified, - bool request_is_seekable); - - // Writes to the stream. - int Write(const char* buf, const int len, int data_offset); - - // Write the result as a file. - void WriteAsFile(); - - // Notify the plugin that a stream is complete. - void Notify(NPReason reason); - - // Close the stream. - virtual bool Close(NPReason reason); - - virtual WebPluginResourceClient* AsResourceClient(); - - // Cancels any HTTP requests initiated by the stream. - virtual void CancelRequest() {} - - NPStream* stream() { return &stream_; } - - PluginInstance* instance() { return instance_.get(); } - - // setter/getter for the seekable attribute on the stream. - bool seekable() const { return seekable_stream_; } - - void set_seekable(bool seekable) { seekable_stream_ = seekable; } - - // getters for reading the notification related attributes on the stream. - bool notify_needed() const { return notify_needed_; } - - void* notify_data() const { return notify_data_; } - - protected: - friend class base::RefCounted<PluginStream>; - - virtual ~PluginStream(); - - // Check if the stream is open. - bool open() { return opened_; } - - private: - // Per platform method to reset the temporary file handle. - void ResetTempFileHandle(); - - // Per platform method to reset the temporary file name. - void ResetTempFileName(); - - // Open a temporary file for this stream. - // If successful, will set temp_file_name_, temp_file_handle_, and - // return true. - bool OpenTempFile(); - - // Closes the temporary file if it is open. - void CloseTempFile(); - - // Sends the data to the file. Called From WriteToFile. - size_t WriteBytes(const char* buf, size_t length); - - // Sends the data to the file if it's open. - bool WriteToFile(const char* buf, size_t length); - - // Sends the data to the plugin. If it's not ready, handles buffering it - // and retrying later. - bool WriteToPlugin(const char* buf, const int length, const int data_offset); - - // Send the data to the plugin, returning how many bytes it accepted, or -1 - // if an error occurred. - int TryWriteToPlugin(const char* buf, const int length, - const int data_offset); - - // The callback which calls TryWriteToPlugin. - void OnDelayDelivery(); - - // Returns true if the temp file is valid and open for writing. - bool TempFileIsValid() const; - - // Returns true if |requested_plugin_mode_| is NP_ASFILE or NP_ASFILEONLY. - bool RequestedPluginModeIsAsFile() const; - - private: - NPStream stream_; - std::string headers_; - scoped_refptr<PluginInstance> instance_; - bool notify_needed_; - void* notify_data_; - bool close_on_write_data_; - uint16 requested_plugin_mode_; - bool opened_; -#if defined(OS_WIN) - char temp_file_name_[MAX_PATH]; - HANDLE temp_file_handle_; -#elif defined(OS_POSIX) - FILE* temp_file_; - base::FilePath temp_file_path_; -#endif - std::vector<char> delivery_data_; - int data_offset_; - bool seekable_stream_; - std::string mime_type_; - DISALLOW_COPY_AND_ASSIGN(PluginStream); -}; - -} // namespace content - -#endif // CONTENT_CHILD_NPAPI_PLUGIN_STREAM_H_
diff --git a/content/child/npapi/plugin_stream_posix.cc b/content/child/npapi/plugin_stream_posix.cc deleted file mode 100644 index ed9687c..0000000 --- a/content/child/npapi/plugin_stream_posix.cc +++ /dev/null
@@ -1,59 +0,0 @@ -// Copyright (c) 2012 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "content/child/npapi/plugin_stream.h" - -#include <string.h> - -#include "base/files/file_path.h" -#include "base/files/file_util.h" -#include "base/logging.h" -#include "content/child/npapi/plugin_instance.h" - -namespace content { - -void PluginStream::ResetTempFileHandle() { - temp_file_ = NULL; -} - -void PluginStream::ResetTempFileName() { - temp_file_path_ = base::FilePath(); -} - -void PluginStream::WriteAsFile() { - if (RequestedPluginModeIsAsFile()) - instance_->NPP_StreamAsFile(&stream_, temp_file_path_.value().c_str()); -} - -size_t PluginStream::WriteBytes(const char* buf, size_t length) { - return fwrite(buf, sizeof(char), length, temp_file_); -} - -bool PluginStream::OpenTempFile() { - DCHECK_EQ(static_cast<FILE*>(NULL), temp_file_); - - if (base::CreateTemporaryFile(&temp_file_path_)) - temp_file_ = base::OpenFile(temp_file_path_, "a"); - - if (!temp_file_) { - base::DeleteFile(temp_file_path_, false); - ResetTempFileName(); - return false; - } - return true; -} - -void PluginStream::CloseTempFile() { - if (!TempFileIsValid()) - return; - - base::CloseFile(temp_file_); - ResetTempFileHandle(); -} - -bool PluginStream::TempFileIsValid() const { - return temp_file_ != NULL; -} - -} // namespace content
diff --git a/content/child/npapi/plugin_stream_url.cc b/content/child/npapi/plugin_stream_url.cc deleted file mode 100644 index 84490d7d..0000000 --- a/content/child/npapi/plugin_stream_url.cc +++ /dev/null
@@ -1,217 +0,0 @@ -// Copyright (c) 2012 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "content/child/npapi/plugin_stream_url.h" - -#include <algorithm> - -#include "base/stl_util.h" -#include "base/strings/string_util.h" -#include "content/child/npapi/plugin_host.h" -#include "content/child/npapi/plugin_instance.h" -#include "content/child/npapi/plugin_lib.h" -#include "content/child/npapi/plugin_url_fetcher.h" -#include "content/child/npapi/webplugin.h" -#include "net/http/http_response_headers.h" - -namespace content { - -PluginStreamUrl::PluginStreamUrl( - unsigned long resource_id, - const GURL &url, - PluginInstance *instance, - bool notify_needed, - void *notify_data) - : PluginStream(instance, url.spec().c_str(), notify_needed, notify_data), - url_(url), - id_(resource_id) { -} - -void PluginStreamUrl::SetPluginURLFetcher(PluginURLFetcher* fetcher) { - plugin_url_fetcher_.reset(fetcher); -} - -void PluginStreamUrl::URLRedirectResponse(bool allow) { - if (plugin_url_fetcher_.get()) { - plugin_url_fetcher_->URLRedirectResponse(allow); - } else { - instance()->webplugin()->URLRedirectResponse(allow, id_); - } - - if (allow) - UpdateUrl(pending_redirect_url_.c_str()); -} - -void PluginStreamUrl::FetchRange(const std::string& range) { - PluginURLFetcher* range_fetcher = new PluginURLFetcher( - this, url_, plugin_url_fetcher_->first_party_for_cookies(), "GET", NULL, - 0, plugin_url_fetcher_->referrer(), range, false, false, - plugin_url_fetcher_->origin_pid(), - plugin_url_fetcher_->render_frame_id(), - plugin_url_fetcher_->render_view_id(), id_, - plugin_url_fetcher_->copy_stream_data()); - range_request_fetchers_.push_back(range_fetcher); -} - -bool PluginStreamUrl::Close(NPReason reason) { - // Protect the stream against it being destroyed or the whole plugin instance - // being destroyed within the destroy stream handler. - scoped_refptr<PluginStream> protect(this); - CancelRequest(); - bool result = PluginStream::Close(reason); - instance()->RemoveStream(this); - return result; -} - -WebPluginResourceClient* PluginStreamUrl::AsResourceClient() { - return static_cast<WebPluginResourceClient*>(this); -} - -void PluginStreamUrl::CancelRequest() { - if (id_ > 0) { - if (plugin_url_fetcher_.get()) { - plugin_url_fetcher_->Cancel(); - } else { - if (instance()->webplugin()) { - instance()->webplugin()->CancelResource(id_); - } - } - id_ = 0; - } - if (instance()->webplugin()) { - for (size_t i = 0; i < range_requests_.size(); ++i) - instance()->webplugin()->CancelResource(range_requests_[i]); - } - - range_requests_.clear(); - - STLDeleteElements(&range_request_fetchers_); -} - -void PluginStreamUrl::WillSendRequest(const GURL& url, int http_status_code) { - if (notify_needed()) { - // If the plugin participates in HTTP url redirect handling then notify it. - if (net::HttpResponseHeaders::IsRedirectResponseCode(http_status_code) && - instance()->handles_url_redirects()) { - pending_redirect_url_ = url.spec(); - instance()->NPP_URLRedirectNotify(url.spec().c_str(), http_status_code, - notify_data()); - return; - } - } - url_ = url; - UpdateUrl(url.spec().c_str()); -} - -void PluginStreamUrl::DidReceiveResponse(const std::string& mime_type, - const std::string& headers, - uint32 expected_length, - uint32 last_modified, - bool request_is_seekable) { - // Protect the stream against it being destroyed or the whole plugin instance - // being destroyed within the new stream handler. - scoped_refptr<PluginStream> protect(this); - - bool opened = Open(mime_type, - headers, - expected_length, - last_modified, - request_is_seekable); - if (!opened) { - CancelRequest(); - instance()->RemoveStream(this); - } else { - SetDeferLoading(false); - } -} - -void PluginStreamUrl::DidReceiveData(const char* buffer, int length, - int data_offset) { - if (!open()) - return; - - // Protect the stream against it being destroyed or the whole plugin instance - // being destroyed within the write handlers - scoped_refptr<PluginStream> protect(this); - - if (length > 0) { - // The PluginStreamUrl instance could get deleted if the plugin fails to - // accept data in NPP_Write. - if (Write(const_cast<char*>(buffer), length, data_offset) > 0) { - SetDeferLoading(false); - } - } -} - -void PluginStreamUrl::DidFinishLoading(unsigned long resource_id) { - if (!seekable()) { - Close(NPRES_DONE); - } else { - std::vector<unsigned long>::iterator it_resource = std::find( - range_requests_.begin(), - range_requests_.end(), - resource_id); - // Resource id must be known to us - either main resource id, or one - // of the resources, created for range requests. - DCHECK(resource_id == id_ || it_resource != range_requests_.end()); - // We should notify the plugin about failed/finished requests to ensure - // that the number of active resource clients does not continue to grow. - if (instance()->webplugin()) - instance()->webplugin()->CancelResource(resource_id); - if (it_resource != range_requests_.end()) - range_requests_.erase(it_resource); - } -} - -void PluginStreamUrl::DidFail(unsigned long resource_id) { - Close(NPRES_NETWORK_ERR); -} - -bool PluginStreamUrl::IsMultiByteResponseExpected() { - return seekable(); -} - -int PluginStreamUrl::ResourceId() { - return id_; -} - -PluginStreamUrl::~PluginStreamUrl() { - if (!plugin_url_fetcher_.get() && instance() && instance()->webplugin()) { - instance()->webplugin()->ResourceClientDeleted(AsResourceClient()); - } - - STLDeleteElements(&range_request_fetchers_); -} - -void PluginStreamUrl::AddRangeRequestResourceId(unsigned long resource_id) { - DCHECK_NE(resource_id, 0u); - range_requests_.push_back(resource_id); -} - -void PluginStreamUrl::SetDeferLoading(bool value) { - // If we determined that the request had failed via the HTTP headers in the - // response then we send out a failure notification to the plugin process, as - // certain plugins don't handle HTTP failure codes correctly. - if (plugin_url_fetcher_.get()) { - if (!value && plugin_url_fetcher_->pending_failure_notification()) { - // This object may be deleted now. - DidFail(id_); - } - return; - } - if (id_ > 0) - instance()->webplugin()->SetDeferResourceLoading(id_, value); - for (size_t i = 0; i < range_requests_.size(); ++i) - instance()->webplugin()->SetDeferResourceLoading(range_requests_[i], - value); -} - -void PluginStreamUrl::UpdateUrl(const char* url) { - DCHECK(!open()); - free(const_cast<char*>(stream()->url)); - stream()->url = base::strdup(url); - pending_redirect_url_.clear(); -} - -} // namespace content
diff --git a/content/child/npapi/plugin_stream_url.h b/content/child/npapi/plugin_stream_url.h deleted file mode 100644 index dea2fe4d..0000000 --- a/content/child/npapi/plugin_stream_url.h +++ /dev/null
@@ -1,93 +0,0 @@ -// Copyright (c) 2012 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef CONTENT_CHILD_NPAPI_PLUGIN_STREAM_URL_H_ -#define CONTENT_CHILD_NPAPI_PLUGIN_STREAM_URL_H_ - -#include <vector> - -#include "base/memory/scoped_ptr.h" -#include "content/child/npapi/plugin_stream.h" -#include "content/child/npapi/webplugin_resource_client.h" -#include "url/gurl.h" - -namespace content { -class PluginInstance; -class PluginURLFetcher; - -// A NPAPI Stream based on a URL. -class PluginStreamUrl : public PluginStream, - public WebPluginResourceClient { - public: - // Create a new stream for sending to the plugin by fetching - // a URL. If notifyNeeded is set, then the plugin will be notified - // when the stream has been fully sent to the plugin. Initialize - // must be called before the object is used. - PluginStreamUrl(unsigned long resource_id, - const GURL &url, - PluginInstance *instance, - bool notify_needed, - void *notify_data); - - void SetPluginURLFetcher(PluginURLFetcher* fetcher); - - void URLRedirectResponse(bool allow); - - void FetchRange(const std::string& range); - - // Stop sending the stream to the client. - // Overrides the base Close so we can cancel our fetching the URL if - // it is still loading. - bool Close(NPReason reason) override; - WebPluginResourceClient* AsResourceClient() override; - void CancelRequest() override; - - // WebPluginResourceClient methods - void WillSendRequest(const GURL& url, int http_status_code) override; - void DidReceiveResponse(const std::string& mime_type, - const std::string& headers, - uint32 expected_length, - uint32 last_modified, - bool request_is_seekable) override; - void DidReceiveData(const char* buffer, int length, int data_offset) override; - void DidFinishLoading(unsigned long resource_id) override; - void DidFail(unsigned long resource_id) override; - bool IsMultiByteResponseExpected() override; - int ResourceId() override; - void AddRangeRequestResourceId(unsigned long resource_id) override; - - protected: - ~PluginStreamUrl() override; - - private: - void SetDeferLoading(bool value); - - // In case of a redirect, this can be called to update the url. But it must - // be called before Open(). - void UpdateUrl(const char* url); - - GURL url_; - unsigned long id_; - - // Ids of additional resources requested via range requests issued on - // seekable streams. - // This is used when we're loading resources through the renderer, i.e. not - // using plugin_url_fetcher_. - std::vector<unsigned long> range_requests_; - // This is used when we're using plugin_url_fetcher_. - std::vector<PluginURLFetcher*> range_request_fetchers_; - - // If the plugin participates in HTTP URL redirect handling then this member - // holds the url being redirected to while we wait for the plugin to make a - // decision on whether to allow or deny the redirect. - std::string pending_redirect_url_; - - scoped_ptr<PluginURLFetcher> plugin_url_fetcher_; - - DISALLOW_COPY_AND_ASSIGN(PluginStreamUrl); -}; - -} // namespace content - -#endif // CONTENT_CHILD_NPAPI_PLUGIN_STREAM_URL_H_
diff --git a/content/child/npapi/plugin_stream_win.cc b/content/child/npapi/plugin_stream_win.cc deleted file mode 100644 index af55f2f..0000000 --- a/content/child/npapi/plugin_stream_win.cc +++ /dev/null
@@ -1,79 +0,0 @@ -// Copyright (c) 2012 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "content/child/npapi/plugin_stream.h" - -#include "base/logging.h" -#include "content/child/npapi/plugin_instance.h" - -namespace content { - -void PluginStream::ResetTempFileHandle() { - temp_file_handle_ = INVALID_HANDLE_VALUE; -} - -void PluginStream::ResetTempFileName() { - temp_file_name_[0] = '\0'; -} - -void PluginStream::WriteAsFile() { - if (RequestedPluginModeIsAsFile()) - instance_->NPP_StreamAsFile(&stream_, temp_file_name_); -} - -size_t PluginStream::WriteBytes(const char *buf, size_t length) { - DWORD bytes; - - if (!WriteFile(temp_file_handle_, buf, length, &bytes, 0)) - return 0U; - - return static_cast<size_t>(bytes); -} - -bool PluginStream::OpenTempFile() { - DCHECK_EQ(INVALID_HANDLE_VALUE, temp_file_handle_); - - // The reason for using all the Ascii versions of these filesystem - // calls is that the filename which we pass back to the plugin - // via NPAPI is an ascii filename. Otherwise, we'd use wide-chars. - // - // TODO: - // This is a bug in NPAPI itself, and it needs to be fixed. - // The case which will fail is if a user has a multibyte name, - // but has the system locale set to english. GetTempPathA will - // return junk in this case, causing us to be unable to open the - // file. - - char temp_directory[MAX_PATH]; - if (GetTempPathA(MAX_PATH, temp_directory) == 0) - return false; - if (GetTempFileNameA(temp_directory, "npstream", 0, temp_file_name_) == 0) - return false; - temp_file_handle_ = CreateFileA(temp_file_name_, - FILE_ALL_ACCESS, - FILE_SHARE_READ, - 0, - CREATE_ALWAYS, - FILE_ATTRIBUTE_NORMAL, - 0); - if (temp_file_handle_ == INVALID_HANDLE_VALUE) { - ResetTempFileName(); - return false; - } - return true; -} - -void PluginStream::CloseTempFile() { - if (!TempFileIsValid()) - return; - - CloseHandle(temp_file_handle_); - ResetTempFileHandle(); -} - -bool PluginStream::TempFileIsValid() const { - return temp_file_handle_ != INVALID_HANDLE_VALUE; -} - -} // namespace content
diff --git a/content/child/npapi/plugin_string_stream.cc b/content/child/npapi/plugin_string_stream.cc deleted file mode 100644 index 15f38ad..0000000 --- a/content/child/npapi/plugin_string_stream.cc +++ /dev/null
@@ -1,37 +0,0 @@ -// Copyright (c) 2010 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "content/child/npapi/plugin_string_stream.h" - -#include "url/gurl.h" - -namespace content { - -PluginStringStream::PluginStringStream( - PluginInstance* instance, - const GURL& url, - bool notify_needed, - void* notify_data) - : PluginStream(instance, url.spec().c_str(), notify_needed, notify_data) { -} - -PluginStringStream::~PluginStringStream() { -} - -void PluginStringStream::SendToPlugin(const std::string &data, - const std::string &mime_type) { - // Protect the stream against it being destroyed or the whole plugin instance - // being destroyed within the plugin stream callbacks. - scoped_refptr<PluginStringStream> protect(this); - - int length = static_cast<int>(data.length()); - if (Open(mime_type, std::string(), length, 0, false)) { - // TODO - check if it was not fully sent, and figure out a backup plan. - int written = Write(data.c_str(), length, 0); - NPReason reason = written == length ? NPRES_DONE : NPRES_NETWORK_ERR; - Close(reason); - } -} - -} // namespace content
diff --git a/content/child/npapi/plugin_string_stream.h b/content/child/npapi/plugin_string_stream.h deleted file mode 100644 index 73dac44..0000000 --- a/content/child/npapi/plugin_string_stream.h +++ /dev/null
@@ -1,40 +0,0 @@ -// Copyright (c) 2006-2008 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef CONTENT_CHILD_NPAPI_PLUGIN_STRING_STREAM_H_ -#define CONTENT_CHILD_NPAPI_PLUGIN_STRING_STREAM_H_ - -#include "content/child/npapi/plugin_stream.h" - -class GURL; - -namespace content { - -class PluginInstance; - -// An NPAPI stream from a string. -class PluginStringStream : public PluginStream { - public: - // Create a new stream for sending to the plugin. - // If notify_needed, will notify the plugin after the data has - // all been sent. - PluginStringStream(PluginInstance* instance, - const GURL& url, - bool notify_needed, - void* notify_data); - - // Initiates the sending of data to the plugin. - void SendToPlugin(const std::string& data, - const std::string& mime_type); - - private: - ~PluginStringStream() override; - - DISALLOW_COPY_AND_ASSIGN(PluginStringStream); -}; - - -} // namespace content - -#endif // CONTENT_CHILD_NPAPI_PLUGIN_STRING_STREAM_H_
diff --git a/content/child/npapi/plugin_url_fetcher.cc b/content/child/npapi/plugin_url_fetcher.cc deleted file mode 100644 index a307f68..0000000 --- a/content/child/npapi/plugin_url_fetcher.cc +++ /dev/null
@@ -1,406 +0,0 @@ -// Copyright (c) 2013 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "content/child/npapi/plugin_url_fetcher.h" - -#include "base/memory/scoped_ptr.h" -#include "content/child/child_thread_impl.h" -#include "content/child/multipart_response_delegate.h" -#include "content/child/npapi/plugin_host.h" -#include "content/child/npapi/plugin_instance.h" -#include "content/child/npapi/plugin_stream_url.h" -#include "content/child/npapi/webplugin.h" -#include "content/child/npapi/webplugin_resource_client.h" -#include "content/child/plugin_messages.h" -#include "content/child/request_extra_data.h" -#include "content/child/request_info.h" -#include "content/child/resource_dispatcher.h" -#include "content/child/web_url_loader_impl.h" -#include "content/common/resource_request_body.h" -#include "content/common/service_worker/service_worker_types.h" -#include "content/public/common/resource_response_info.h" -#include "net/base/load_flags.h" -#include "net/base/net_errors.h" -#include "net/http/http_response_headers.h" -#include "net/url_request/redirect_info.h" -#include "third_party/WebKit/public/platform/WebURLLoaderClient.h" -#include "third_party/WebKit/public/platform/WebURLResponse.h" - -namespace content { -namespace { - -// This class handles individual multipart responses. It is instantiated when -// we receive HTTP status code 206 in the HTTP response. This indicates -// that the response could have multiple parts each separated by a boundary -// specified in the response header. -// TODO(jam): this is similar to MultiPartResponseClient in webplugin_impl.cc, -// we should remove that other class once we switch to loading from the plugin -// process by default. -class MultiPartResponseClient : public blink::WebURLLoaderClient { - public: - explicit MultiPartResponseClient(PluginStreamUrl* plugin_stream) - : byte_range_lower_bound_(0), plugin_stream_(plugin_stream) {} - - // blink::WebURLLoaderClient implementation: - void didReceiveResponse(blink::WebURLLoader* loader, - const blink::WebURLResponse& response) override { - int64 byte_range_upper_bound, instance_size; - if (!MultipartResponseDelegate::ReadContentRanges(response, - &byte_range_lower_bound_, - &byte_range_upper_bound, - &instance_size)) { - NOTREACHED(); - } - } - void didReceiveData(blink::WebURLLoader* loader, - const char* data, - int data_length, - int encoded_data_length) override { - // TODO(ananta) - // We should defer further loads on multipart resources on the same lines - // as regular resources requested by plugins to prevent reentrancy. - int64 data_offset = byte_range_lower_bound_; - byte_range_lower_bound_ += data_length; - plugin_stream_->DidReceiveData(data, data_length, data_offset); - // DANGER: this instance may be deleted at this point. - } - - private: - // The lower bound of the byte range. - int64 byte_range_lower_bound_; - // The handler for the data. - PluginStreamUrl* plugin_stream_; -}; - -} // namespace - -PluginURLFetcher::PluginURLFetcher(PluginStreamUrl* plugin_stream, - const GURL& url, - const GURL& first_party_for_cookies, - const std::string& method, - const char* buf, - unsigned int len, - const Referrer& referrer, - const std::string& range, - bool notify_redirects, - bool is_plugin_src_load, - int origin_pid, - int render_frame_id, - int render_view_id, - unsigned long resource_id, - bool copy_stream_data) - : plugin_stream_(plugin_stream), - url_(url), - first_party_for_cookies_(first_party_for_cookies), - referrer_(referrer), - notify_redirects_(notify_redirects), - is_plugin_src_load_(is_plugin_src_load), - origin_pid_(origin_pid), - render_frame_id_(render_frame_id), - render_view_id_(render_view_id), - resource_id_(resource_id), - copy_stream_data_(copy_stream_data), - data_offset_(0), - pending_failure_notification_(false), - request_id_(-1), - weak_factory_(this) { - RequestInfo request_info; - request_info.method = method; - request_info.url = url; - request_info.first_party_for_cookies = first_party_for_cookies; - request_info.referrer = referrer; - request_info.load_flags = net::LOAD_NORMAL; - request_info.requestor_pid = origin_pid; - request_info.request_type = RESOURCE_TYPE_OBJECT; - request_info.routing_id = render_view_id; - // ServiceWorker is disabled for NPAPI. - request_info.skip_service_worker = true; - - RequestExtraData extra_data; - extra_data.set_render_frame_id(render_frame_id); - extra_data.set_is_main_frame(false); - request_info.extra_data = &extra_data; - - std::vector<char> body; - if (method == "POST") { - bool content_type_found = false; - std::vector<std::string> names; - std::vector<std::string> values; - PluginHost::SetPostData(buf, len, &names, &values, &body); - for (size_t i = 0; i < names.size(); ++i) { - if (!request_info.headers.empty()) - request_info.headers += "\r\n"; - request_info.headers += names[i] + ": " + values[i]; - if (base::LowerCaseEqualsASCII(names[i], "content-type")) - content_type_found = true; - } - - if (!content_type_found) { - if (!request_info.headers.empty()) - request_info.headers += "\r\n"; - request_info.headers += "Content-Type: application/x-www-form-urlencoded"; - } - } else { - if (!range.empty()) - request_info.headers = std::string("Range: ") + range; - } - - scoped_refptr<ResourceRequestBody> request_body = new ResourceRequestBody; - if (!body.empty()) - request_body->AppendBytes(&body[0], body.size()); - - request_id_ = ChildThreadImpl::current()->resource_dispatcher()->StartAsync( - request_info, request_body.get(), this); - - // TODO(jam): range requests -} - -PluginURLFetcher::~PluginURLFetcher() { - if (request_id_ >= 0) { - ChildThreadImpl::current()->resource_dispatcher()->RemovePendingRequest( - request_id_); - } -} - -void PluginURLFetcher::Cancel() { - ChildThreadImpl::current()->resource_dispatcher()->Cancel(request_id_); - - // Due to races and nested event loops, PluginURLFetcher may still receive - // events from the bridge before being destroyed. Do not forward additional - // events back to the plugin, via either |plugin_stream_| or - // |multipart_delegate_| which has its own pointer via - // MultiPartResponseClient. - if (multipart_delegate_) - multipart_delegate_->Cancel(); - plugin_stream_ = NULL; -} - -void PluginURLFetcher::URLRedirectResponse(bool allow) { - if (!plugin_stream_) - return; - - if (allow) { - ChildThreadImpl::current()->resource_dispatcher()->SetDefersLoading( - request_id_, false); - } else { - ChildThreadImpl::current()->resource_dispatcher()->Cancel(request_id_); - plugin_stream_->DidFail(resource_id_); // That will delete |this|. - } -} - -void PluginURLFetcher::OnUploadProgress(uint64 position, uint64 size) { -} - -bool PluginURLFetcher::OnReceivedRedirect( - const net::RedirectInfo& redirect_info, - const ResourceResponseInfo& info) { - if (!plugin_stream_) - return false; - - // TODO(jam): THIS LOGIC IS COPIED FROM WebPluginImpl::willSendRequest until - // kDirectNPAPIRequests is the default and we can remove the old path there. - - // Currently this check is just to catch an https -> http redirect when - // loading the main plugin src URL. Longer term, we could investigate - // firing mixed diplay or scripting issues for subresource loads - // initiated by plugins. - if (is_plugin_src_load_ && - !plugin_stream_->instance()->webplugin()->CheckIfRunInsecureContent( - redirect_info.new_url)) { - plugin_stream_->DidFail(resource_id_); // That will delete |this|. - return false; - } - - GURL old_url = url_; - url_ = redirect_info.new_url; - first_party_for_cookies_ = redirect_info.new_first_party_for_cookies; - - // If the plugin does not participate in url redirect notifications then just - // block cross origin 307 POST redirects. - if (!notify_redirects_) { - if (redirect_info.status_code == 307 && - redirect_info.new_method == "POST" && - old_url.GetOrigin() != url_.GetOrigin()) { - plugin_stream_->DidFail(resource_id_); // That will delete |this|. - return false; - } - } else { - // Pause the request while we ask the plugin what to do about the redirect. - ChildThreadImpl::current()->resource_dispatcher()->SetDefersLoading( - request_id_, true); - plugin_stream_->WillSendRequest(url_, redirect_info.status_code); - } - - return true; -} - -void PluginURLFetcher::OnReceivedResponse(const ResourceResponseInfo& info) { - if (!plugin_stream_) - return; - - // TODO(jam): THIS LOGIC IS COPIED FROM WebPluginImpl::didReceiveResponse - // GetAllHeaders, and GetResponseInfo until kDirectNPAPIRequests is the - // default and we can remove the old path there. - - bool request_is_seekable = true; - DCHECK(!multipart_delegate_.get()); - if (plugin_stream_->seekable()) { - int response_code = info.headers->response_code(); - if (response_code == 206) { - blink::WebURLResponse response; - response.initialize(); - WebURLLoaderImpl::PopulateURLResponse(url_, info, &response, - false /* report_security_info */); - - std::string multipart_boundary; - if (MultipartResponseDelegate::ReadMultipartBoundary( - response, &multipart_boundary)) { - plugin_stream_->instance()->webplugin()->DidStartLoading(); - - MultiPartResponseClient* multi_part_response_client = - new MultiPartResponseClient(plugin_stream_); - - multipart_delegate_.reset(new MultipartResponseDelegate( - multi_part_response_client, NULL, response, multipart_boundary)); - - // Multiple ranges requested, data will be delivered by - // MultipartResponseDelegate. - data_offset_ = 0; - return; - } - - int64 upper_bound = 0, instance_size = 0; - // Single range requested - go through original processing for - // non-multipart requests, but update data offset. - MultipartResponseDelegate::ReadContentRanges( - response, &data_offset_, &upper_bound, &instance_size); - } else if (response_code == 200) { - // TODO: should we handle this case? We used to but it's not clear that we - // still need to. This was bug 5403, fixed in r7139. - } - } - - // If the length comes in as -1, then it indicates that it was not - // read off the HTTP headers. We replicate Safari webkit behavior here, - // which is to set it to 0. - int expected_length = std::max(static_cast<int>(info.content_length), 0); - - base::Time temp; - uint32 last_modified = 0; - std::string headers; - if (info.headers.get()) { // NULL for data: urls. - if (info.headers->GetLastModifiedValue(&temp)) - last_modified = static_cast<uint32>(temp.ToDoubleT()); - - // TODO(darin): Shouldn't we also report HTTP version numbers? - int response_code = info.headers->response_code(); - headers = base::StringPrintf("HTTP %d ", response_code); - headers += info.headers->GetStatusText(); - headers += "\n"; - - void* iter = NULL; - std::string name, value; - while (info.headers->EnumerateHeaderLines(&iter, &name, &value)) { - // TODO(darin): Should we really exclude headers with an empty value? - if (!name.empty() && !value.empty()) - headers += name + ": " + value + "\n"; - } - - // Bug http://b/issue?id=925559. The flash plugin would not handle the HTTP - // error codes in the stream header and as a result, was unaware of the fate - // of the HTTP requests issued via NPN_GetURLNotify. Webkit and FF destroy - // the stream and invoke the NPP_DestroyStream function on the plugin if the - // HTTPrequest fails. - if ((url_.SchemeIs(url::kHttpScheme) || url_.SchemeIs(url::kHttpsScheme)) && - (response_code < 100 || response_code >= 400)) { - pending_failure_notification_ = true; - } - } - - plugin_stream_->DidReceiveResponse(info.mime_type, - headers, - expected_length, - last_modified, - request_is_seekable); -} - -void PluginURLFetcher::OnDownloadedData(int len, - int encoded_data_length) { -} - -void PluginURLFetcher::OnReceivedData(scoped_ptr<ReceivedData> data) { - const char* payload = data->payload(); - int data_length = data->length(); - int encoded_data_length = data->encoded_length(); - if (!plugin_stream_) - return; - - if (multipart_delegate_) { - multipart_delegate_->OnReceivedData(payload, data_length, - encoded_data_length); - } else { - int64 offset = data_offset_; - data_offset_ += data_length; - - if (copy_stream_data_) { - // QuickTime writes to this memory, and since we got it from - // ResourceDispatcher it's not mapped for write access in this process. - // http://crbug.com/308466. - scoped_ptr<char[]> data_copy(new char[data_length]); - memcpy(data_copy.get(), payload, data_length); - plugin_stream_->DidReceiveData(data_copy.get(), data_length, offset); - } else { - plugin_stream_->DidReceiveData(payload, data_length, offset); - } - // DANGER: this instance may be deleted at this point. - } -} - -void PluginURLFetcher::OnCompletedRequest( - int error_code, - bool was_ignored_by_handler, - bool stale_copy_in_cache, - const std::string& security_info, - const base::TimeTicks& completion_time, - int64 total_transfer_size) { - if (!plugin_stream_) - return; - - if (multipart_delegate_) { - multipart_delegate_->OnCompletedRequest(); - multipart_delegate_.reset(); - } - - if (error_code == net::OK) { - plugin_stream_->DidFinishLoading(resource_id_); - } else { - plugin_stream_->DidFail(resource_id_); - } -} - -void PluginURLFetcher::OnReceivedCompletedResponse( - const content::ResourceResponseInfo& info, - scoped_ptr<ReceivedData> data, - int error_code, - bool was_ignored_by_handler, - bool stale_copy_in_cache, - const std::string& security_info, - const base::TimeTicks& completion_time, - int64 total_transfer_size) { - // |this| can be deleted on each callback. |weak_this| is placed here to - // detect the deletion. - base::WeakPtr<PluginURLFetcher> weak_this = weak_factory_.GetWeakPtr(); - OnReceivedResponse(info); - - if (!weak_this) - return; - if (data) - OnReceivedData(data.Pass()); - - if (!weak_this) - return; - OnCompletedRequest(error_code, was_ignored_by_handler, stale_copy_in_cache, - security_info, completion_time, total_transfer_size); -} -} // namespace content
diff --git a/content/child/npapi/plugin_url_fetcher.h b/content/child/npapi/plugin_url_fetcher.h deleted file mode 100644 index 8b0f09a..0000000 --- a/content/child/npapi/plugin_url_fetcher.h +++ /dev/null
@@ -1,102 +0,0 @@ -// Copyright (c) 2013 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef CONTENT_CHILD_NPAPI_PLUGIN_URL_FETCHER_H_ -#define CONTENT_CHILD_NPAPI_PLUGIN_URL_FETCHER_H_ - -#include <string> - -#include "base/memory/scoped_ptr.h" -#include "base/memory/weak_ptr.h" -#include "content/public/child/request_peer.h" -#include "content/public/common/referrer.h" -#include "url/gurl.h" - -namespace content { -class MultipartResponseDelegate; -class PluginStreamUrl; - -// Fetches URLS for a plugin using ResourceDispatcher. -class PluginURLFetcher : public RequestPeer { - public: - PluginURLFetcher(PluginStreamUrl* plugin_stream, - const GURL& url, - const GURL& first_party_for_cookies, - const std::string& method, - const char* buf, - unsigned int len, - const Referrer& referrer, - const std::string& range, - bool notify_redirects, - bool is_plugin_src_load, - int origin_pid, - int render_frame_id, - int render_view_id, - unsigned long resource_id, - bool copy_stream_data); - ~PluginURLFetcher() override; - - // Cancels the current request. - void Cancel(); - - // Called with the plugin's reply to NPP_URLRedirectNotify. - void URLRedirectResponse(bool allow); - - GURL first_party_for_cookies() { return first_party_for_cookies_; } - Referrer referrer() { return referrer_; } - int origin_pid() { return origin_pid_; } - int render_frame_id() { return render_frame_id_; } - int render_view_id() { return render_view_id_; } - bool copy_stream_data() { return copy_stream_data_; } - bool pending_failure_notification() { return pending_failure_notification_; } - - private: - // RequestPeer implementation: - void OnUploadProgress(uint64 position, uint64 size) override; - bool OnReceivedRedirect(const net::RedirectInfo& redirect_info, - const ResourceResponseInfo& info) override; - void OnReceivedResponse(const ResourceResponseInfo& info) override; - void OnDownloadedData(int len, int encoded_data_length) override; - void OnReceivedData(scoped_ptr<ReceivedData> data) override; - void OnCompletedRequest(int error_code, - bool was_ignored_by_handler, - bool stale_copy_in_cache, - const std::string& security_info, - const base::TimeTicks& completion_time, - int64 total_transfer_size) override; - void OnReceivedCompletedResponse(const ResourceResponseInfo& info, - scoped_ptr<ReceivedData> data, - int error_code, - bool was_ignored_by_handler, - bool stale_copy_in_cache, - const std::string& security_info, - const base::TimeTicks& completion_time, - int64 total_transfer_size) override; - - // |plugin_stream_| becomes NULL after Cancel() to ensure no further calls - // |reach it. - PluginStreamUrl* plugin_stream_; - GURL url_; - GURL first_party_for_cookies_; - Referrer referrer_; - bool notify_redirects_; - bool is_plugin_src_load_; - int origin_pid_; - int render_frame_id_; - int render_view_id_; - unsigned long resource_id_; - bool copy_stream_data_; - int64 data_offset_; - bool pending_failure_notification_; - int request_id_; - - scoped_ptr<MultipartResponseDelegate> multipart_delegate_; - base::WeakPtrFactory<PluginURLFetcher> weak_factory_; - - DISALLOW_COPY_AND_ASSIGN(PluginURLFetcher); -}; - -} // namespace content - -#endif // CONTENT_CHILD_NPAPI_PLUGIN_URL_FETCHER_H_
diff --git a/content/child/npapi/webplugin.h b/content/child/npapi/webplugin.h index c1281f1..13466ea 100644 --- a/content/child/npapi/webplugin.h +++ b/content/child/npapi/webplugin.h
@@ -70,26 +70,9 @@ virtual std::string GetCookies(const GURL& url, const GURL& first_party_for_cookies) = 0; - // Handles GetURL/GetURLNotify/PostURL/PostURLNotify requests initiated - // by plugins. If the plugin wants notification of the result, notify_id will - // be non-zero. - virtual void HandleURLRequest(const char* url, - const char* method, - const char* target, - const char* buf, - unsigned int len, - int notify_id, - bool popups_allowed, - bool notify_redirects) = 0; - // Cancels document load. virtual void CancelDocumentLoad() = 0; - // Initiates a HTTP range request for an existing stream. - virtual void InitiateHTTPRangeRequest(const char* url, - const char* range_info, - int range_request_id) = 0; - virtual void DidStartLoading() = 0; virtual void DidStopLoading() = 0;
diff --git a/content/child/npapi/webplugin_delegate.h b/content/child/npapi/webplugin_delegate.h index 8f13c8d..c18eb76 100644 --- a/content/child/npapi/webplugin_delegate.h +++ b/content/child/npapi/webplugin_delegate.h
@@ -87,65 +87,8 @@ // Returns false if the value is not available. virtual bool GetFormValue(base::string16* value) = 0; - // Receives notification about a resource load that the plugin initiated - // for a frame. - virtual void DidFinishLoadWithReason(const GURL& url, NPReason reason, - int notify_id) = 0; - // Returns the process id of the process that is running the plugin. virtual int GetProcessId() = 0; - - // The result, UTF-8 encoded, of the script execution is returned via this - // function. - virtual void SendJavaScriptStream(const GURL& url, - const std::string& result, - bool success, - int notify_id) = 0; - - // Receives notification about data being available. - virtual void DidReceiveManualResponse(const GURL& url, - const std::string& mime_type, - const std::string& headers, - uint32 expected_length, - uint32 last_modified) = 0; - - // Receives the data. - virtual void DidReceiveManualData(const char* buffer, int length) = 0; - - // Indicates end of data load. - virtual void DidFinishManualLoading() = 0; - - // Indicates a failure in data receipt. - virtual void DidManualLoadFail() = 0; - - // Creates a WebPluginResourceClient instance and returns the same. - virtual WebPluginResourceClient* CreateResourceClient( - unsigned long resource_id, - const GURL& url, - int notify_id) = 0; - - // Creates a WebPluginResourceClient instance for an existing stream that is - // has become seekable. - virtual WebPluginResourceClient* CreateSeekableResourceClient( - unsigned long resource_id, int range_request_id) = 0; - - // Tell the plugin that the given URL should be fetched. This is a result of - // loading the plugin data or the plugin calling HandleURLRequest which didn't - // end up being routed to another frame or being a javscript:// URL. - virtual void FetchURL(unsigned long resource_id, - int notify_id, - const GURL& url, - const GURL& first_party_for_cookies, - const std::string& method, - const char* buf, - unsigned int len, - const Referrer& referrer, - bool notify_redirects, - bool is_plugin_src_load, - int origin_pid, - int render_frame_id, - int render_view_id) = 0; - }; } // namespace content
diff --git a/content/child/npapi/webplugin_delegate_impl.cc b/content/child/npapi/webplugin_delegate_impl.cc index 18149c3..8323bc8 100644 --- a/content/child/npapi/webplugin_delegate_impl.cc +++ b/content/child/npapi/webplugin_delegate_impl.cc
@@ -14,8 +14,6 @@ #include "base/strings/utf_string_conversions.h" #include "content/child/npapi/plugin_instance.h" #include "content/child/npapi/plugin_lib.h" -#include "content/child/npapi/plugin_stream_url.h" -#include "content/child/npapi/plugin_url_fetcher.h" #include "third_party/WebKit/public/web/WebInputEvent.h" using blink::WebCursorInfo; @@ -102,12 +100,6 @@ void WebPluginDelegateImpl::DestroyInstance() { if (instance_.get() && (instance_->npp()->ndata != NULL)) { - // Shutdown all streams before destroying so that - // no streams are left "in progress". Need to do - // this before calling set_web_plugin(NULL) because the - // instance uses the helper to do the download. - instance_->CloseStreams(); - window_.window = NULL; if (creation_succeeded_ && !(quirks_ & PLUGIN_QUIRK_DONT_SET_NULL_WINDOW_HANDLE_ON_DESTROY)) { @@ -193,56 +185,11 @@ return instance_->GetFormValue(value); } -void WebPluginDelegateImpl::DidFinishLoadWithReason(const GURL& url, - NPReason reason, - int notify_id) { - if (quirks_ & PLUGIN_QUIRK_ALWAYS_NOTIFY_SUCCESS && - reason == NPRES_NETWORK_ERR) { - // Flash needs this or otherwise it unloads the launching swf object. - reason = NPRES_DONE; - } - - instance()->DidFinishLoadWithReason(url, reason, notify_id); -} - int WebPluginDelegateImpl::GetProcessId() { // We are in process, so the plugin pid is this current process pid. return base::GetCurrentProcId(); } -void WebPluginDelegateImpl::SendJavaScriptStream(const GURL& url, - const std::string& result, - bool success, - int notify_id) { - instance()->SendJavaScriptStream(url, result, success, notify_id); -} - -void WebPluginDelegateImpl::DidReceiveManualResponse( - const GURL& url, const std::string& mime_type, - const std::string& headers, uint32 expected_length, uint32 last_modified) { - if (!windowless_) { - // Calling NPP_WriteReady before NPP_SetWindow causes movies to not load in - // Flash. See http://b/issue?id=892174. - DCHECK(windowed_did_set_window_); - } - - instance()->DidReceiveManualResponse(url, mime_type, headers, - expected_length, last_modified); -} - -void WebPluginDelegateImpl::DidReceiveManualData(const char* buffer, - int length) { - instance()->DidReceiveManualData(buffer, length); -} - -void WebPluginDelegateImpl::DidFinishManualLoading() { - instance()->DidFinishManualLoading(); -} - -void WebPluginDelegateImpl::DidManualLoadFail() { - instance()->DidManualLoadFail(); -} - base::FilePath WebPluginDelegateImpl::GetPluginPath() { return instance()->plugin_lib()->plugin_info().path; } @@ -289,44 +236,4 @@ } } -WebPluginResourceClient* WebPluginDelegateImpl::CreateResourceClient( - unsigned long resource_id, const GURL& url, int notify_id) { - return instance()->CreateStream( - resource_id, url, std::string(), notify_id); -} - -WebPluginResourceClient* WebPluginDelegateImpl::CreateSeekableResourceClient( - unsigned long resource_id, int range_request_id) { - WebPluginResourceClient* resource_client = instance()->GetRangeRequest( - range_request_id); - if (resource_client) - resource_client->AddRangeRequestResourceId(resource_id); - return resource_client; -} - -void WebPluginDelegateImpl::FetchURL(unsigned long resource_id, - int notify_id, - const GURL& url, - const GURL& first_party_for_cookies, - const std::string& method, - const char* buf, - unsigned int len, - const Referrer& referrer, - bool notify_redirects, - bool is_plugin_src_load, - int origin_pid, - int render_frame_id, - int render_view_id) { - // TODO(jam): once we switch over to resource loading always happening in this - // code path, remove WebPluginResourceClient abstraction. - PluginStreamUrl* plugin_stream = instance()->CreateStream( - resource_id, url, std::string(), notify_id); - - bool copy_stream_data = !!(quirks_ & PLUGIN_QUIRK_COPY_STREAM_DATA); - plugin_stream->SetPluginURLFetcher(new PluginURLFetcher( - plugin_stream, url, first_party_for_cookies, method, buf, len, - referrer, std::string(), notify_redirects, is_plugin_src_load, origin_pid, - render_frame_id, render_view_id, resource_id, copy_stream_data)); -} - } // namespace content
diff --git a/content/child/npapi/webplugin_delegate_impl.h b/content/child/npapi/webplugin_delegate_impl.h index 72f559a9..9d75082 100644 --- a/content/child/npapi/webplugin_delegate_impl.h +++ b/content/child/npapi/webplugin_delegate_impl.h
@@ -92,41 +92,7 @@ NPObject* GetPluginScriptableObject() override; NPP GetPluginNPP() override; bool GetFormValue(base::string16* value) override; - void DidFinishLoadWithReason(const GURL& url, - NPReason reason, - int notify_id) override; int GetProcessId() override; - void SendJavaScriptStream(const GURL& url, - const std::string& result, - bool success, - int notify_id) override; - void DidReceiveManualResponse(const GURL& url, - const std::string& mime_type, - const std::string& headers, - uint32 expected_length, - uint32 last_modified) override; - void DidReceiveManualData(const char* buffer, int length) override; - void DidFinishManualLoading() override; - void DidManualLoadFail() override; - WebPluginResourceClient* CreateResourceClient(unsigned long resource_id, - const GURL& url, - int notify_id) override; - WebPluginResourceClient* CreateSeekableResourceClient( - unsigned long resource_id, - int range_request_id) override; - void FetchURL(unsigned long resource_id, - int notify_id, - const GURL& url, - const GURL& first_party_for_cookies, - const std::string& method, - const char* buf, - unsigned int len, - const Referrer& referrer, - bool notify_redirects, - bool is_plugin_src_load, - int origin_pid, - int render_frame_id, - int render_view_id) override; // End of WebPluginDelegate implementation. gfx::PluginWindowHandle windowed_handle() const { return windowed_handle_; }
diff --git a/content/child/npapi/webplugin_delegate_impl_win.cc b/content/child/npapi/webplugin_delegate_impl_win.cc index d64af01c..8dd3687 100644 --- a/content/child/npapi/webplugin_delegate_impl_win.cc +++ b/content/child/npapi/webplugin_delegate_impl_win.cc
@@ -23,7 +23,6 @@ #include "base/win/windows_version.h" #include "content/child/npapi/plugin_instance.h" #include "content/child/npapi/plugin_lib.h" -#include "content/child/npapi/plugin_stream_url.h" #include "content/child/npapi/webplugin.h" #include "content/child/npapi/webplugin_ime_win.h" #include "content/common/cursors/webcursor.h"
diff --git a/content/child/npapi/webplugin_resource_client.h b/content/child/npapi/webplugin_resource_client.h index fc392649..9604f60 100644 --- a/content/child/npapi/webplugin_resource_client.h +++ b/content/child/npapi/webplugin_resource_client.h
@@ -32,7 +32,6 @@ // is cleared. This applies for seekable streams. virtual void DidFinishLoading(unsigned long resource_id) = 0; virtual void DidFail(unsigned long resource_id) = 0; - virtual bool IsMultiByteResponseExpected() = 0; virtual int ResourceId() = 0; // Tells this object that it will get responses from multiple resources. // This is necessary since the plugin process uses a single instance of
diff --git a/content/child/plugin_messages.h b/content/child/plugin_messages.h index 25d4545..f742338 100644 --- a/content/child/plugin_messages.h +++ b/content/child/plugin_messages.h
@@ -34,16 +34,6 @@ IPC_STRUCT_MEMBER(int, host_render_view_routing_id) IPC_STRUCT_END() -IPC_STRUCT_BEGIN(PluginHostMsg_URLRequest_Params) - IPC_STRUCT_MEMBER(std::string, url) - IPC_STRUCT_MEMBER(std::string, method) - IPC_STRUCT_MEMBER(std::string, target) - IPC_STRUCT_MEMBER(std::vector<char>, buffer) - IPC_STRUCT_MEMBER(int, notify_id) - IPC_STRUCT_MEMBER(bool, popups_allowed) - IPC_STRUCT_MEMBER(bool, notify_redirects) -IPC_STRUCT_END() - IPC_STRUCT_BEGIN(PluginMsg_DidReceiveResponseParams) IPC_STRUCT_MEMBER(unsigned long, id) IPC_STRUCT_MEMBER(std::string, mime_type) @@ -55,7 +45,6 @@ IPC_STRUCT_BEGIN(PluginMsg_FetchURL_Params) IPC_STRUCT_MEMBER(unsigned long, resource_id) - IPC_STRUCT_MEMBER(int, notify_id) IPC_STRUCT_MEMBER(GURL, url) IPC_STRUCT_MEMBER(GURL, first_party_for_cookies) IPC_STRUCT_MEMBER(std::string, method) @@ -116,11 +105,6 @@ base::string16 /* value */, bool /* success */) -IPC_MESSAGE_ROUTED3(PluginMsg_DidFinishLoadWithReason, - GURL /* url */, - int /* reason */, - int /* notify_id */) - // Updates the plugin location. IPC_MESSAGE_ROUTED1(PluginMsg_UpdateGeometry, PluginMsg_UpdateGeometry_Param) @@ -159,44 +143,12 @@ IPC_MESSAGE_ROUTED1(PluginMsg_DidFail, unsigned long /* id */) -IPC_MESSAGE_ROUTED4(PluginMsg_SendJavaScriptStream, - GURL /* url */, - std::string /* result */, - bool /* success */, - int /* notify_id */) - -IPC_MESSAGE_ROUTED2(PluginMsg_DidReceiveManualResponse, - GURL /* url */, - PluginMsg_DidReceiveResponseParams) - -IPC_MESSAGE_ROUTED1(PluginMsg_DidReceiveManualData, - std::vector<char> /* buffer */) - -IPC_MESSAGE_ROUTED0(PluginMsg_DidFinishManualLoading) - -IPC_MESSAGE_ROUTED0(PluginMsg_DidManualLoadFail) - -IPC_MESSAGE_ROUTED3(PluginMsg_HandleURLRequestReply, - unsigned long /* resource_id */, - GURL /* url */, - int /* notify_id */) - -IPC_MESSAGE_ROUTED2(PluginMsg_HTTPRangeRequestReply, - unsigned long /* resource_id */, - int /* range_request_id */) - IPC_MESSAGE_CONTROL1(PluginMsg_SignalModalDialogEvent, int /* render_view_id */) IPC_MESSAGE_CONTROL1(PluginMsg_ResetModalDialogEvent, int /* render_view_id */) -IPC_MESSAGE_ROUTED1(PluginMsg_FetchURL, - PluginMsg_FetchURL_Params) - -IPC_MESSAGE_CONTROL1(PluginHostMsg_DidAbortLoading, - int /* render_view_id */) - #if defined(OS_WIN) IPC_MESSAGE_ROUTED4(PluginMsg_ImeCompositionUpdated, base::string16 /* text */, @@ -237,9 +189,6 @@ IPC_SYNC_MESSAGE_ROUTED1_0(PluginHostMsg_SetWindow, gfx::PluginWindowHandle /* window */) -IPC_MESSAGE_ROUTED1(PluginHostMsg_URLRequest, - PluginHostMsg_URLRequest_Params) - IPC_MESSAGE_ROUTED1(PluginHostMsg_CancelResource, int /* id */) @@ -271,11 +220,6 @@ IPC_MESSAGE_ROUTED0(PluginHostMsg_CancelDocumentLoad) -IPC_MESSAGE_ROUTED3(PluginHostMsg_InitiateHTTPRangeRequest, - std::string /* url */, - std::string /* range_info */, - int /* range_request_id */) - IPC_MESSAGE_ROUTED0(PluginHostMsg_DidStartLoading) IPC_MESSAGE_ROUTED0(PluginHostMsg_DidStopLoading)
diff --git a/content/child/runtime_features.cc b/content/child/runtime_features.cc index 3cdaf40..be71402 100644 --- a/content/child/runtime_features.cc +++ b/content/child/runtime_features.cc
@@ -185,9 +185,6 @@ if (command_line.HasSwitch(switches::kReducedReferrerGranularity)) WebRuntimeFeatures::enableReducedReferrerGranularity(true); - if (command_line.HasSwitch(switches::kEnablePushMessagePayload)) - WebRuntimeFeatures::enablePushMessagingData(true); - if (command_line.HasSwitch(switches::kDisablePermissionsAPI)) WebRuntimeFeatures::enablePermissionsAPI(false);
diff --git a/content/child/service_worker/service_worker_dispatcher.cc b/content/child/service_worker/service_worker_dispatcher.cc index 5426087..832395a 100644 --- a/content/child/service_worker/service_worker_dispatcher.cc +++ b/content/child/service_worker/service_worker_dispatcher.cc
@@ -300,7 +300,7 @@ registration->SetActive( GetOrCreateServiceWorker(ServiceWorkerHandleReference::Create( attrs.active, thread_safe_sender_.get()))); - return registration.Pass(); + return registration; } scoped_refptr<WebServiceWorkerRegistrationImpl> @@ -325,7 +325,7 @@ registration->SetInstalling(GetOrCreateServiceWorker(installing_ref.Pass())); registration->SetWaiting(GetOrCreateServiceWorker(waiting_ref.Pass())); registration->SetActive(GetOrCreateServiceWorker(active_ref.Pass())); - return registration.Pass(); + return registration; } void ServiceWorkerDispatcher::OnAssociateRegistration(
diff --git a/content/common/BUILD.gn b/content/common/BUILD.gn index dc85add3..759bf97 100644 --- a/content/common/BUILD.gn +++ b/content/common/BUILD.gn
@@ -231,9 +231,9 @@ "gpu/client/gpu_memory_buffer_impl_io_surface.h", "gpu/gpu_memory_buffer_factory_io_surface.cc", "gpu/gpu_memory_buffer_factory_io_surface.h", - "gpu/media/vt.h", - "gpu/media/vt_video_decode_accelerator.cc", - "gpu/media/vt_video_decode_accelerator.h", + "gpu/media/vt_mac.h", + "gpu/media/vt_video_decode_accelerator_mac.cc", + "gpu/media/vt_video_decode_accelerator_mac.h", ] + get_target_outputs(":libvt_generate_stubs") sources -= [ "plugin_list_posix.cc" ] @@ -469,8 +469,8 @@ if (is_win) { sources += [ - "gpu/media/dxva_video_decode_accelerator.cc", - "gpu/media/dxva_video_decode_accelerator.h", + "gpu/media/dxva_video_decode_accelerator_win.cc", + "gpu/media/dxva_video_decode_accelerator_win.h", ] configs += [ "//third_party/khronos:khronos_headers" ] deps += [ "//ui/gl" ]
diff --git a/content/common/browser_plugin/browser_plugin_messages.h b/content/common/browser_plugin/browser_plugin_messages.h index ca06826..91f5f60 100644 --- a/content/common/browser_plugin/browser_plugin_messages.h +++ b/content/common/browser_plugin/browser_plugin_messages.h
@@ -37,7 +37,6 @@ IPC_ENUM_TRAITS_MAX_VALUE(blink::WebDragStatus, blink::WebDragStatusLast) -IPC_ENUM_TRAITS_MAX_VALUE(blink::WebFocusType, blink::WebFocusTypeLast) IPC_STRUCT_BEGIN(BrowserPluginHostMsg_Attach_Params) IPC_STRUCT_MEMBER(bool, focused)
diff --git a/content/common/cursors/webcursor.cc b/content/common/cursors/webcursor.cc index faa6d703..b2dfcdf 100644 --- a/content/common/cursors/webcursor.cc +++ b/content/common/cursors/webcursor.cc
@@ -112,8 +112,12 @@ if (size_x > 0 && size_y > 0) { // The * 4 is because the expected format is an array of RGBA pixel // values. - if (size_x * size_y * 4 > data_len) + if (size_x * size_y * 4 != data_len) { + LOG(WARNING) << "WebCursor's data length and image size mismatch: " + << size_x << "x" << size_y << "x4 != " + << data_len; return false; + } hotspot_.set_x(hotspot_x); hotspot_.set_y(hotspot_y);
diff --git a/content/common/frame_messages.h b/content/common/frame_messages.h index f4fc8b5..01d5fdf 100644 --- a/content/common/frame_messages.h +++ b/content/common/frame_messages.h
@@ -29,6 +29,7 @@ #include "content/public/common/three_d_api_types.h" #include "content/public/common/transition_element.h" #include "ipc/ipc_message_macros.h" +#include "third_party/WebKit/public/platform/WebFocusType.h" #include "third_party/WebKit/public/web/WebFrameOwnerProperties.h" #include "third_party/WebKit/public/web/WebTreeScopeType.h" #include "ui/gfx/ipc/gfx_param_traits.h" @@ -58,6 +59,7 @@ blink::WebContextMenuData::MediaTypeLast) IPC_ENUM_TRAITS_MAX_VALUE(blink::WebContextMenuData::InputFieldType, blink::WebContextMenuData::InputFieldTypeLast) +IPC_ENUM_TRAITS_MAX_VALUE(blink::WebFocusType, blink::WebFocusTypeLast) IPC_ENUM_TRAITS_MAX_VALUE(blink::WebFrameOwnerProperties::ScrollingMode, blink::WebFrameOwnerProperties::ScrollingMode::Last) IPC_ENUM_TRAITS(blink::WebSandboxFlags) // Bitmask. @@ -720,6 +722,14 @@ IPC_MESSAGE_ROUTED1(FrameMsg_SetFrameOwnerProperties, blink::WebFrameOwnerProperties /* frame_owner_properties */) +// Request to continue running the sequential focus navigation algorithm in +// this frame. |source_routing_id| identifies the frame that issued this +// request. This message is sent when pressing <tab> or <shift-tab> needs to +// find the next focusable element in a cross-process frame. +IPC_MESSAGE_ROUTED2(FrameMsg_AdvanceFocus, + blink::WebFocusType /* type */, + int32_t /* source_routing_id */) + #if defined(ENABLE_PLUGINS) // Notifies the renderer of updates to the Plugin Power Saver origin whitelist. IPC_MESSAGE_ROUTED1(FrameMsg_UpdatePluginContentOriginWhitelist, @@ -1250,6 +1260,15 @@ IPC_MESSAGE_ROUTED1(FrameHostMsg_UpdatePageImportanceSignals, content::PageImportanceSignals) +// This message is sent from a RenderFrameProxy when sequential focus +// navigation needs to advance into its actual frame. |source_routing_id| +// identifies the frame that issued this request. This is used when pressing +// <tab> or <shift-tab> hits an out-of-process iframe when searching for the +// next focusable element. +IPC_MESSAGE_ROUTED2(FrameHostMsg_AdvanceFocus, + blink::WebFocusType /* type */, + int32_t /* source_routing_id */) + #if defined(OS_MACOSX) || defined(OS_ANDROID) // Message to show/hide a popup menu using native controls.
diff --git a/content/common/gpu/client/gpu_video_decode_accelerator_host.cc b/content/common/gpu/client/gpu_video_decode_accelerator_host.cc index a329dcc..621d210 100644 --- a/content/common/gpu/client/gpu_video_decode_accelerator_host.cc +++ b/content/common/gpu/client/gpu_video_decode_accelerator_host.cc
@@ -81,7 +81,7 @@ PostNotifyError(PLATFORM_FAILURE); } -bool GpuVideoDecodeAcceleratorHost::Initialize(media::VideoCodecProfile profile, +bool GpuVideoDecodeAcceleratorHost::Initialize(const Config& config, Client* client) { DCHECK(CalledOnValidThread()); client_ = client; @@ -93,7 +93,7 @@ channel_->AddRoute(route_id, weak_this_factory_.GetWeakPtr()); bool succeeded = false; - Send(new GpuCommandBufferMsg_CreateVideoDecoder(impl_->route_id(), profile, + Send(new GpuCommandBufferMsg_CreateVideoDecoder(impl_->route_id(), config, route_id, &succeeded)); if (!succeeded) {
diff --git a/content/common/gpu/client/gpu_video_decode_accelerator_host.h b/content/common/gpu/client/gpu_video_decode_accelerator_host.h index 9f9e8e2..33a516f 100644 --- a/content/common/gpu/client/gpu_video_decode_accelerator_host.h +++ b/content/common/gpu/client/gpu_video_decode_accelerator_host.h
@@ -35,7 +35,7 @@ bool OnMessageReceived(const IPC::Message& message) override; // media::VideoDecodeAccelerator implementation. - bool Initialize(media::VideoCodecProfile profile, Client* client) override; + bool Initialize(const Config& config, Client* client) override; void SetCdm(int cdm_id) override; void Decode(const media::BitstreamBuffer& bitstream_buffer) override; void AssignPictureBuffers(
diff --git a/content/common/gpu/gpu_command_buffer_stub.cc b/content/common/gpu/gpu_command_buffer_stub.cc index eead7fb3..86a3711 100644 --- a/content/common/gpu/gpu_command_buffer_stub.cc +++ b/content/common/gpu/gpu_command_buffer_stub.cc
@@ -881,13 +881,13 @@ } void GpuCommandBufferStub::OnCreateVideoDecoder( - media::VideoCodecProfile profile, + const media::VideoDecodeAccelerator::Config& config, int32 decoder_route_id, IPC::Message* reply_message) { TRACE_EVENT0("gpu", "GpuCommandBufferStub::OnCreateVideoDecoder"); GpuVideoDecodeAccelerator* decoder = new GpuVideoDecodeAccelerator( decoder_route_id, this, channel_->io_task_runner()); - decoder->Initialize(profile, reply_message); + decoder->Initialize(config, reply_message); // decoder is registered as a DestructionObserver of this stub and will // self-delete during destruction of this stub. }
diff --git a/content/common/gpu/gpu_command_buffer_stub.h b/content/common/gpu/gpu_command_buffer_stub.h index 2e529a6..188ede0 100644 --- a/content/common/gpu/gpu_command_buffer_stub.h +++ b/content/common/gpu/gpu_command_buffer_stub.h
@@ -21,7 +21,7 @@ #include "gpu/command_buffer/service/gpu_scheduler.h" #include "ipc/ipc_listener.h" #include "ipc/ipc_sender.h" -#include "media/base/video_decoder_config.h" +#include "media/video/video_decode_accelerator.h" #include "ui/events/latency_info.h" #include "ui/gfx/geometry/size.h" #include "ui/gfx/gpu_memory_buffer.h" @@ -180,7 +180,7 @@ void OnDestroyTransferBuffer(int32 id); void OnGetTransferBuffer(int32 id, IPC::Message* reply_message); - void OnCreateVideoDecoder(media::VideoCodecProfile profile, + void OnCreateVideoDecoder(const media::VideoDecodeAccelerator::Config& config, int32 route_id, IPC::Message* reply_message); void OnCreateVideoEncoder(media::VideoPixelFormat input_format,
diff --git a/content/common/gpu/gpu_messages.h b/content/common/gpu/gpu_messages.h index e75ed254..d463ef0f 100644 --- a/content/common/gpu/gpu_messages.h +++ b/content/common/gpu/gpu_messages.h
@@ -216,6 +216,11 @@ IPC_STRUCT_TRAITS_MEMBER(device_string) IPC_STRUCT_TRAITS_END() +IPC_STRUCT_TRAITS_BEGIN(media::VideoDecodeAccelerator::Config) + IPC_STRUCT_TRAITS_MEMBER(profile) + IPC_STRUCT_TRAITS_MEMBER(is_encrypted) +IPC_STRUCT_TRAITS_END() + IPC_STRUCT_TRAITS_BEGIN(gpu::VideoDecodeAcceleratorSupportedProfile) IPC_STRUCT_TRAITS_MEMBER(profile) IPC_STRUCT_TRAITS_MEMBER(max_resolution) @@ -600,7 +605,7 @@ // Created decoders should be freed with AcceleratedVideoDecoderMsg_Destroy when // no longer needed. IPC_SYNC_MESSAGE_ROUTED2_1(GpuCommandBufferMsg_CreateVideoDecoder, - media::VideoCodecProfile /* profile */, + media::VideoDecodeAccelerator::Config, /* config */ int32, /* route_id */ bool /* succeeded */)
diff --git a/content/common/gpu/media/android_video_decode_accelerator.cc b/content/common/gpu/media/android_video_decode_accelerator.cc index 3f1e8774..00e1bb6 100644 --- a/content/common/gpu/media/android_video_decode_accelerator.cc +++ b/content/common/gpu/media/android_video_decode_accelerator.cc
@@ -81,6 +81,7 @@ : client_(NULL), make_context_current_(make_context_current), codec_(media::kCodecH264), + is_encrypted_(false), state_(NO_ERROR), picturebuffers_requested_(false), gl_decoder_(decoder), @@ -91,14 +92,18 @@ DCHECK(thread_checker_.CalledOnValidThread()); } -bool AndroidVideoDecodeAccelerator::Initialize(media::VideoCodecProfile profile, +bool AndroidVideoDecodeAccelerator::Initialize(const Config& config, Client* client) { DCHECK(!media_codec_); DCHECK(thread_checker_.CalledOnValidThread()); TRACE_EVENT0("media", "AVDA::Initialize"); + DVLOG(1) << __FUNCTION__ << ": profile:" << config.profile + << " is_encrypted:" << config.is_encrypted; + client_ = client; - codec_ = VideoCodecProfileToVideoCodec(profile); + codec_ = VideoCodecProfileToVideoCodec(config.profile); + is_encrypted_ = config.is_encrypted; bool profile_supported = codec_ == media::kCodecVP8; #if defined(ENABLE_MEDIA_PIPELINE_ON_ANDROID) @@ -107,7 +112,7 @@ #endif if (!profile_supported) { - LOG(ERROR) << "Unsupported profile: " << profile; + LOG(ERROR) << "Unsupported profile: " << config.profile; return false; }
diff --git a/content/common/gpu/media/android_video_decode_accelerator.h b/content/common/gpu/media/android_video_decode_accelerator.h index 8384bc8..2e8058af 100644 --- a/content/common/gpu/media/android_video_decode_accelerator.h +++ b/content/common/gpu/media/android_video_decode_accelerator.h
@@ -95,7 +95,7 @@ ~AndroidVideoDecodeAccelerator() override; // media::VideoDecodeAccelerator implementation: - bool Initialize(media::VideoCodecProfile profile, Client* client) override; + bool Initialize(const Config& config, Client* client) override; void SetCdm(int cdm_id) override; void Decode(const media::BitstreamBuffer& bitstream_buffer) override; void AssignPictureBuffers( @@ -178,6 +178,9 @@ // Codec type. Used when we configure media codec. media::VideoCodec codec_; + // Whether the stream is encrypted. + bool is_encrypted_; + // The current state of this class. For now, this is used only for setting // error state. State state_;
diff --git a/content/common/gpu/media/dxva_video_decode_accelerator.cc b/content/common/gpu/media/dxva_video_decode_accelerator_win.cc similarity index 99% rename from content/common/gpu/media/dxva_video_decode_accelerator.cc rename to content/common/gpu/media/dxva_video_decode_accelerator_win.cc index 46e9dce..0e71f1e 100644 --- a/content/common/gpu/media/dxva_video_decode_accelerator.cc +++ b/content/common/gpu/media/dxva_video_decode_accelerator_win.cc
@@ -2,15 +2,15 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#include "content/common/gpu/media/dxva_video_decode_accelerator.h" +#include "content/common/gpu/media/dxva_video_decode_accelerator_win.h" #if !defined(OS_WIN) #error This file should only be built on Windows. #endif // !defined(OS_WIN) -#include <ks.h> #include <codecapi.h> #include <dxgi1_2.h> +#include <ks.h> #include <mfapi.h> #include <mferror.h> #include <ntverp.h> @@ -632,15 +632,20 @@ client_ = NULL; } -bool DXVAVideoDecodeAccelerator::Initialize(media::VideoCodecProfile profile, - Client* client) { +bool DXVAVideoDecodeAccelerator::Initialize(const Config& config, + Client* client) { + if (config.is_encrypted) { + NOTREACHED() << "Encrypted streams are not supported for this VDA"; + return false; + } + client_ = client; main_thread_task_runner_ = base::MessageLoop::current()->task_runner(); bool profile_supported = false; for (const auto& supported_profile : kSupportedProfiles) { - if (profile == supported_profile) { + if (config.profile == supported_profile) { profile_supported = true; break; } @@ -692,7 +697,7 @@ media::InitializeMediaFoundation(); - RETURN_AND_NOTIFY_ON_FAILURE(InitDecoder(profile), + RETURN_AND_NOTIFY_ON_FAILURE(InitDecoder(config.profile), "Failed to initialize decoder", PLATFORM_FAILURE, false); RETURN_AND_NOTIFY_ON_FAILURE(GetStreamsInfoAndBufferReqs(),
diff --git a/content/common/gpu/media/dxva_video_decode_accelerator.h b/content/common/gpu/media/dxva_video_decode_accelerator_win.h similarity index 98% rename from content/common/gpu/media/dxva_video_decode_accelerator.h rename to content/common/gpu/media/dxva_video_decode_accelerator_win.h index 86125ed..d3e85fe 100644 --- a/content/common/gpu/media/dxva_video_decode_accelerator.h +++ b/content/common/gpu/media/dxva_video_decode_accelerator_win.h
@@ -64,8 +64,7 @@ ~DXVAVideoDecodeAccelerator() override; // media::VideoDecodeAccelerator implementation. - bool Initialize(media::VideoCodecProfile profile, - Client* client) override; + bool Initialize(const Config& config, Client* client) override; void Decode(const media::BitstreamBuffer& bitstream_buffer) override; void AssignPictureBuffers( const std::vector<media::PictureBuffer>& buffers) override;
diff --git a/content/common/gpu/media/fake_video_decode_accelerator.cc b/content/common/gpu/media/fake_video_decode_accelerator.cc index eff497f4..12aec65 100644 --- a/content/common/gpu/media/fake_video_decode_accelerator.cc +++ b/content/common/gpu/media/fake_video_decode_accelerator.cc
@@ -41,13 +41,18 @@ FakeVideoDecodeAccelerator::~FakeVideoDecodeAccelerator() { } -bool FakeVideoDecodeAccelerator::Initialize(media::VideoCodecProfile profile, +bool FakeVideoDecodeAccelerator::Initialize(const Config& config, Client* client) { DCHECK(child_task_runner_->BelongsToCurrentThread()); - if (profile == media::VIDEO_CODEC_PROFILE_UNKNOWN) { + if (config.profile == media::VIDEO_CODEC_PROFILE_UNKNOWN) { LOG(ERROR) << "unknown codec profile"; return false; } + if (config.is_encrypted) { + NOTREACHED() << "encrypted streams are not supported"; + return false; + } + // V4L2VideoDecodeAccelerator waits until first decode call to ask for buffers // This class asks for it on initialization instead. client_ = client;
diff --git a/content/common/gpu/media/fake_video_decode_accelerator.h b/content/common/gpu/media/fake_video_decode_accelerator.h index a669c823..bb88ff7 100644 --- a/content/common/gpu/media/fake_video_decode_accelerator.h +++ b/content/common/gpu/media/fake_video_decode_accelerator.h
@@ -25,8 +25,7 @@ const base::Callback<bool(void)>& make_context_current); ~FakeVideoDecodeAccelerator() override; - bool Initialize(media::VideoCodecProfile profile, - Client* client) override; + bool Initialize(const Config& config, Client* client) override; void Decode(const media::BitstreamBuffer& bitstream_buffer) override; void AssignPictureBuffers( const std::vector<media::PictureBuffer>& buffers) override;
diff --git a/content/common/gpu/media/gpu_video_decode_accelerator.cc b/content/common/gpu/media/gpu_video_decode_accelerator.cc index ed4d179..2dfe85b 100644 --- a/content/common/gpu/media/gpu_video_decode_accelerator.cc +++ b/content/common/gpu/media/gpu_video_decode_accelerator.cc
@@ -30,9 +30,9 @@ #if defined(OS_WIN) #include "base/win/windows_version.h" -#include "content/common/gpu/media/dxva_video_decode_accelerator.h" +#include "content/common/gpu/media/dxva_video_decode_accelerator_win.h" #elif defined(OS_MACOSX) -#include "content/common/gpu/media/vt_video_decode_accelerator.h" +#include "content/common/gpu/media/vt_video_decode_accelerator_mac.h" #elif defined(OS_CHROMEOS) #if defined(USE_V4L2_CODEC) #include "content/common/gpu/media/v4l2_device.h" @@ -323,7 +323,7 @@ } void GpuVideoDecodeAccelerator::Initialize( - const media::VideoCodecProfile profile, + const media::VideoDecodeAccelerator::Config& config, IPC::Message* init_done_msg) { DCHECK(!video_decode_accelerator_); @@ -356,7 +356,7 @@ for (const auto& create_vda_function : create_vda_fps) { video_decode_accelerator_ = (this->*create_vda_function)(); if (!video_decode_accelerator_ || - !video_decode_accelerator_->Initialize(profile, this)) + !video_decode_accelerator_->Initialize(config, this)) continue; if (video_decode_accelerator_->CanDecodeOnIOThread()) { @@ -367,7 +367,8 @@ return; } video_decode_accelerator_.reset(); - LOG(ERROR) << "HW video decode not available for profile " << profile; + LOG(ERROR) << "HW video decode not available for profile " << config.profile + << (config.is_encrypted ? " with encryption" : ""); SendCreateDecoderReply(init_done_msg, false); }
diff --git a/content/common/gpu/media/gpu_video_decode_accelerator.h b/content/common/gpu/media/gpu_video_decode_accelerator.h index ad1e142f..b6fba877 100644 --- a/content/common/gpu/media/gpu_video_decode_accelerator.h +++ b/content/common/gpu/media/gpu_video_decode_accelerator.h
@@ -65,10 +65,10 @@ bool Send(IPC::Message* message) override; // Initialize VDAs from the set of VDAs supported for current platform until - // one of them succeeds for given |profile|. Send the |init_done_msg| when + // one of them succeeds for given |config|. Send the |init_done_msg| when // done. filter_ is passed to GpuCommandBufferStub channel only if the chosen // VDA can decode on IO thread. - void Initialize(const media::VideoCodecProfile profile, + void Initialize(const media::VideoDecodeAccelerator::Config& config, IPC::Message* init_done_msg); private:
diff --git a/content/common/gpu/media/v4l2_slice_video_decode_accelerator.cc b/content/common/gpu/media/v4l2_slice_video_decode_accelerator.cc index a682648b..f17dc629 100644 --- a/content/common/gpu/media/v4l2_slice_video_decode_accelerator.cc +++ b/content/common/gpu/media/v4l2_slice_video_decode_accelerator.cc
@@ -433,10 +433,14 @@ } } -bool V4L2SliceVideoDecodeAccelerator::Initialize( - media::VideoCodecProfile profile, - VideoDecodeAccelerator::Client* client) { - DVLOGF(3) << "profile: " << profile; +bool V4L2SliceVideoDecodeAccelerator::Initialize(const Config& config, + Client* client) { + DVLOGF(3) << "profile: " << config.profile; + if (config.is_encrypted) { + NOTREACHED() << "Encrypted streams are not supported for this VDA"; + return false; + } + DCHECK(child_task_runner_->BelongsToCurrentThread()); DCHECK_EQ(state_, kUninitialized); @@ -444,7 +448,7 @@ new base::WeakPtrFactory<VideoDecodeAccelerator::Client>(client)); client_ = client_ptr_factory_->GetWeakPtr(); - video_profile_ = profile; + video_profile_ = config.profile; if (video_profile_ >= media::H264PROFILE_MIN && video_profile_ <= media::H264PROFILE_MAX) {
diff --git a/content/common/gpu/media/v4l2_slice_video_decode_accelerator.h b/content/common/gpu/media/v4l2_slice_video_decode_accelerator.h index dd12487..4a7c9075 100644 --- a/content/common/gpu/media/v4l2_slice_video_decode_accelerator.h +++ b/content/common/gpu/media/v4l2_slice_video_decode_accelerator.h
@@ -42,8 +42,7 @@ ~V4L2SliceVideoDecodeAccelerator() override; // media::VideoDecodeAccelerator implementation. - bool Initialize(media::VideoCodecProfile profile, - VideoDecodeAccelerator::Client* client) override; + bool Initialize(const Config& config, Client* client) override; void Decode(const media::BitstreamBuffer& bitstream_buffer) override; void AssignPictureBuffers( const std::vector<media::PictureBuffer>& buffers) override;
diff --git a/content/common/gpu/media/v4l2_video_decode_accelerator.cc b/content/common/gpu/media/v4l2_video_decode_accelerator.cc index f217080..64672fc 100644 --- a/content/common/gpu/media/v4l2_video_decode_accelerator.cc +++ b/content/common/gpu/media/v4l2_video_decode_accelerator.cc
@@ -199,16 +199,21 @@ DCHECK(output_buffer_map_.empty()); } -bool V4L2VideoDecodeAccelerator::Initialize(media::VideoCodecProfile profile, +bool V4L2VideoDecodeAccelerator::Initialize(const Config& config, Client* client) { DVLOG(3) << "Initialize()"; + if (config.is_encrypted) { + NOTREACHED() << "Encrypted streams are not supported for this VDA"; + return false; + } + DCHECK(child_task_runner_->BelongsToCurrentThread()); DCHECK_EQ(decoder_state_, kUninitialized); client_ptr_factory_.reset(new base::WeakPtrFactory<Client>(client)); client_ = client_ptr_factory_->GetWeakPtr(); - switch (profile) { + switch (config.profile) { case media::H264PROFILE_BASELINE: DVLOG(2) << "Initialize(): profile H264PROFILE_BASELINE"; break; @@ -225,10 +230,10 @@ DVLOG(2) << "Initialize(): profile VP9PROFILE_ANY"; break; default: - DLOG(ERROR) << "Initialize(): unsupported profile=" << profile; + DLOG(ERROR) << "Initialize(): unsupported profile=" << config.profile; return false; }; - video_profile_ = profile; + video_profile_ = config.profile; if (egl_display_ == EGL_NO_DISPLAY) { LOG(ERROR) << "Initialize(): could not get EGLDisplay";
diff --git a/content/common/gpu/media/v4l2_video_decode_accelerator.h b/content/common/gpu/media/v4l2_video_decode_accelerator.h index 58daa0eb8..58fc6f4 100644 --- a/content/common/gpu/media/v4l2_video_decode_accelerator.h +++ b/content/common/gpu/media/v4l2_video_decode_accelerator.h
@@ -83,8 +83,7 @@ // media::VideoDecodeAccelerator implementation. // Note: Initialize() and Destroy() are synchronous. - bool Initialize(media::VideoCodecProfile profile, - Client* client) override; + bool Initialize(const Config& config, Client* client) override; void Decode(const media::BitstreamBuffer& bitstream_buffer) override; void AssignPictureBuffers( const std::vector<media::PictureBuffer>& buffers) override;
diff --git a/content/common/gpu/media/vaapi_video_decode_accelerator.cc b/content/common/gpu/media/vaapi_video_decode_accelerator.cc index bce58ab6..fab601ed 100644 --- a/content/common/gpu/media/vaapi_video_decode_accelerator.cc +++ b/content/common/gpu/media/vaapi_video_decode_accelerator.cc
@@ -316,13 +316,20 @@ DCHECK_EQ(message_loop_, base::MessageLoop::current()); } -bool VaapiVideoDecodeAccelerator::Initialize(media::VideoCodecProfile profile, +bool VaapiVideoDecodeAccelerator::Initialize(const Config& config, Client* client) { DCHECK_EQ(message_loop_, base::MessageLoop::current()); + if (config.is_encrypted) { + NOTREACHED() << "Encrypted streams are not supported for this VDA"; + return false; + } + client_ptr_factory_.reset(new base::WeakPtrFactory<Client>(client)); client_ = client_ptr_factory_->GetWeakPtr(); + media::VideoCodecProfile profile = config.profile; + base::AutoLock auto_lock(lock_); DCHECK_EQ(state_, kUninitialized); DVLOG(2) << "Initializing VAVDA, profile: " << profile;
diff --git a/content/common/gpu/media/vaapi_video_decode_accelerator.h b/content/common/gpu/media/vaapi_video_decode_accelerator.h index e870351..1244893 100644 --- a/content/common/gpu/media/vaapi_video_decode_accelerator.h +++ b/content/common/gpu/media/vaapi_video_decode_accelerator.h
@@ -57,7 +57,7 @@ ~VaapiVideoDecodeAccelerator() override; // media::VideoDecodeAccelerator implementation. - bool Initialize(media::VideoCodecProfile profile, Client* client) override; + bool Initialize(const Config& config, Client* client) override; void Decode(const media::BitstreamBuffer& bitstream_buffer) override; void AssignPictureBuffers( const std::vector<media::PictureBuffer>& buffers) override;
diff --git a/content/common/gpu/media/video_decode_accelerator_unittest.cc b/content/common/gpu/media/video_decode_accelerator_unittest.cc index 9a8b774..82c5b692 100644 --- a/content/common/gpu/media/video_decode_accelerator_unittest.cc +++ b/content/common/gpu/media/video_decode_accelerator_unittest.cc
@@ -57,7 +57,7 @@ #if defined(OS_WIN) #include "base/win/windows_version.h" -#include "content/common/gpu/media/dxva_video_decode_accelerator.h" +#include "content/common/gpu/media/dxva_video_decode_accelerator_win.h" #elif defined(OS_CHROMEOS) #if defined(USE_V4L2_CODEC) #include "content/common/gpu/media/v4l2_device.h"
diff --git a/content/common/gpu/media/vt.h b/content/common/gpu/media/vt_mac.h similarity index 100% rename from content/common/gpu/media/vt.h rename to content/common/gpu/media/vt_mac.h
diff --git a/content/common/gpu/media/vt_video_decode_accelerator.cc b/content/common/gpu/media/vt_video_decode_accelerator_mac.cc similarity index 98% rename from content/common/gpu/media/vt_video_decode_accelerator.cc rename to content/common/gpu/media/vt_video_decode_accelerator_mac.cc index a98ce79c..6b3e0dc7 100644 --- a/content/common/gpu/media/vt_video_decode_accelerator.cc +++ b/content/common/gpu/media/vt_video_decode_accelerator_mac.cc
@@ -17,7 +17,7 @@ #include "base/sys_info.h" #include "base/thread_task_runner_handle.h" #include "base/version.h" -#include "content/common/gpu/media/vt_video_decode_accelerator.h" +#include "content/common/gpu/media/vt_video_decode_accelerator_mac.h" #include "content/public/common/content_switches.h" #include "media/base/limits.h" #include "ui/gl/gl_context.h" @@ -313,10 +313,15 @@ DCHECK(gpu_thread_checker_.CalledOnValidThread()); } -bool VTVideoDecodeAccelerator::Initialize( - media::VideoCodecProfile profile, - Client* client) { +bool VTVideoDecodeAccelerator::Initialize(const Config& config, + Client* client) { DCHECK(gpu_thread_checker_.CalledOnValidThread()); + + if (config.is_encrypted) { + NOTREACHED() << "Encrypted streams are not supported for this VDA"; + return false; + } + client_ = client; if (!InitializeVideoToolbox()) @@ -324,7 +329,7 @@ bool profile_supported = false; for (const auto& supported_profile : kSupportedProfiles) { - if (profile == supported_profile) { + if (config.profile == supported_profile) { profile_supported = true; break; }
diff --git a/content/common/gpu/media/vt_video_decode_accelerator.h b/content/common/gpu/media/vt_video_decode_accelerator_mac.h similarity index 97% rename from content/common/gpu/media/vt_video_decode_accelerator.h rename to content/common/gpu/media/vt_video_decode_accelerator_mac.h index 27f1c4e..27a8190 100644 --- a/content/common/gpu/media/vt_video_decode_accelerator.h +++ b/content/common/gpu/media/vt_video_decode_accelerator_mac.h
@@ -11,12 +11,13 @@ #include <queue> #include "base/mac/scoped_cftyperef.h" +#include "base/macros.h" #include "base/memory/linked_ptr.h" #include "base/memory/weak_ptr.h" #include "base/message_loop/message_loop.h" #include "base/threading/thread.h" #include "base/threading/thread_checker.h" -#include "content/common/gpu/media/vt.h" +#include "content/common/gpu/media/vt_mac.h" #include "media/filters/h264_parser.h" #include "media/video/h264_poc.h" #include "media/video/video_decode_accelerator.h" @@ -40,7 +41,7 @@ ~VTVideoDecodeAccelerator() override; // VideoDecodeAccelerator implementation. - bool Initialize(media::VideoCodecProfile profile, Client* client) override; + bool Initialize(const Config& config, Client* client) override; void Decode(const media::BitstreamBuffer& bitstream) override; void AssignPictureBuffers( const std::vector<media::PictureBuffer>& pictures) override;
diff --git a/content/common/sandbox_linux/sandbox_seccomp_bpf_linux.cc b/content/common/sandbox_linux/sandbox_seccomp_bpf_linux.cc index de2bcc0..0b8db74be 100644 --- a/content/common/sandbox_linux/sandbox_seccomp_bpf_linux.cc +++ b/content/common/sandbox_linux/sandbox_seccomp_bpf_linux.cc
@@ -76,22 +76,6 @@ #if !defined(OS_NACL_NONSFI) -inline bool IsChromeOS() { -#if defined(OS_CHROMEOS) - return true; -#else - return false; -#endif -} - -inline bool IsArchitectureArm() { -#if defined(__arm__) - return true; -#else - return false; -#endif -} - class BlacklistDebugAndNumaPolicy : public SandboxBPFBasePolicy { public: BlacklistDebugAndNumaPolicy() {} @@ -128,6 +112,25 @@ return Allow(); } +// nacl_helper needs to be tiny and includes only part of content/ +// in its dependencies. Make sure to not link things that are not needed. +#if !defined(IN_NACL_HELPER) +inline bool IsChromeOS() { +#if defined(OS_CHROMEOS) + return true; +#else + return false; +#endif +} + +inline bool IsArchitectureArm() { +#if defined(__arm__) + return true; +#else + return false; +#endif +} + // If a BPF policy is engaged for |process_type|, run a few sanity checks. void RunSandboxSanityChecks(const std::string& process_type) { if (process_type == switches::kRendererProcess || @@ -157,9 +160,6 @@ } } -// nacl_helper needs to be tiny and includes only part of content/ -// in its dependencies. Make sure to not link things that are not needed. -#if !defined(IN_NACL_HELPER) scoped_ptr<SandboxBPFBasePolicy> GetGpuProcessSandbox() { const base::CommandLine& command_line = *base::CommandLine::ForCurrentProcess(); @@ -210,10 +210,6 @@ bool StartBPFSandbox(const base::CommandLine& command_line, const std::string& process_type) { NOTREACHED(); - // Avoid -Wunused-function with no-op code. - ignore_result(IsChromeOS); - ignore_result(IsArchitectureArm); - ignore_result(RunSandboxSanityChecks); return false; } #endif // !defined(IN_NACL_HELPER)
diff --git a/content/common/sandbox_mac.mm b/content/common/sandbox_mac.mm index 4dc7d94..8d28ffb0 100644 --- a/content/common/sandbox_mac.mm +++ b/content/common/sandbox_mac.mm
@@ -33,7 +33,7 @@ #include "base/strings/sys_string_conversions.h" #include "base/strings/utf_string_conversions.h" #include "base/sys_info.h" -#include "content/common/gpu/media/vt_video_decode_accelerator.h" +#include "content/common/gpu/media/vt_video_decode_accelerator_mac.h" #include "content/grit/content_resources.h" #include "content/public/common/content_client.h" #include "content/public/common/content_switches.h"
diff --git a/content/content_child.gypi b/content/content_child.gypi index f74ecae..792e2fe03 100644 --- a/content/content_child.gypi +++ b/content/content_child.gypi
@@ -153,16 +153,6 @@ 'child/npapi/plugin_instance_mac.mm', 'child/npapi/plugin_lib.cc', 'child/npapi/plugin_lib.h', - 'child/npapi/plugin_stream.cc', - 'child/npapi/plugin_stream.h', - 'child/npapi/plugin_stream_posix.cc', - 'child/npapi/plugin_stream_url.cc', - 'child/npapi/plugin_stream_url.h', - 'child/npapi/plugin_stream_win.cc', - 'child/npapi/plugin_string_stream.cc', - 'child/npapi/plugin_string_stream.h', - 'child/npapi/plugin_url_fetcher.cc', - 'child/npapi/plugin_url_fetcher.h', 'child/npapi/plugin_web_event_converter_mac.h', 'child/npapi/plugin_web_event_converter_mac.mm', 'child/npapi/webplugin.h',
diff --git a/content/content_common.gypi b/content/content_common.gypi index 8af6123..b809c351 100644 --- a/content/content_common.gypi +++ b/content/content_common.gypi
@@ -676,9 +676,9 @@ 'common/gpu/client/gpu_memory_buffer_impl_io_surface.h', 'common/gpu/gpu_memory_buffer_factory_io_surface.cc', 'common/gpu/gpu_memory_buffer_factory_io_surface.h', - 'common/gpu/media/vt.h', - 'common/gpu/media/vt_video_decode_accelerator.cc', - 'common/gpu/media/vt_video_decode_accelerator.h', + 'common/gpu/media/vt_mac.h', + 'common/gpu/media/vt_video_decode_accelerator_mac.cc', + 'common/gpu/media/vt_video_decode_accelerator_mac.h', ], 'sources!': [ 'common/plugin_list_posix.cc', @@ -1039,8 +1039,8 @@ }, }, 'sources': [ - 'common/gpu/media/dxva_video_decode_accelerator.cc', - 'common/gpu/media/dxva_video_decode_accelerator.h', + 'common/gpu/media/dxva_video_decode_accelerator_win.cc', + 'common/gpu/media/dxva_video_decode_accelerator_win.h', ], 'include_dirs': [ '<(DEPTH)/third_party/khronos',
diff --git a/content/content_shell.gypi b/content/content_shell.gypi index 9462cc4d..5b81135 100644 --- a/content/content_shell.gypi +++ b/content/content_shell.gypi
@@ -573,12 +573,8 @@ 'shell/tools/plugin/PluginTest.cpp', 'shell/tools/plugin/PluginTest.h', 'shell/tools/plugin/TestObject.cpp', - 'shell/tools/plugin/Tests/DocumentOpenInDestroyStream.cpp', 'shell/tools/plugin/Tests/EvaluateJSAfterRemovingPluginElement.cpp', 'shell/tools/plugin/Tests/FormValue.cpp', - 'shell/tools/plugin/Tests/GetURLNotifyWithURLThatFailsToLoad.cpp', - 'shell/tools/plugin/Tests/GetURLWithJavaScriptURL.cpp', - 'shell/tools/plugin/Tests/GetURLWithJavaScriptURLDestroyingPlugin.cpp', 'shell/tools/plugin/Tests/GetUserAgentWithNullNPPFromNPPNew.cpp', 'shell/tools/plugin/Tests/LeakWindowScriptableObject.cpp', 'shell/tools/plugin/Tests/LogNPPSetWindow.cpp',
diff --git a/content/content_tests.gypi b/content/content_tests.gypi index 2e9ec20..5dfc0a5 100644 --- a/content/content_tests.gypi +++ b/content/content_tests.gypi
@@ -75,6 +75,8 @@ 'public/test/test_browser_thread_bundle.h', 'public/test/test_content_client_initializer.cc', 'public/test/test_content_client_initializer.h', + 'public/test/test_download_request_handler.cc', + 'public/test/test_download_request_handler.h', 'public/test/test_file_error_injector.cc', 'public/test/test_file_error_injector.h', 'public/test/test_file_system_backend.cc', @@ -220,15 +222,16 @@ 'browser/frame_host/navigation_controller_impl_browsertest.cc', 'browser/frame_host/render_frame_host_impl_browsertest.cc', 'browser/frame_host/render_frame_host_manager_browsertest.cc', + 'browser/frame_host/render_frame_message_filter_browsertest.cc', 'browser/frame_host/render_widget_host_view_child_frame_browsertest.cc', 'browser/gpu/gpu_ipc_browsertests.cc', 'browser/host_zoom_map_impl_browsertest.cc', 'browser/indexed_db/indexed_db_browsertest.cc', 'browser/indexed_db/mock_browsertest_indexed_db_class_factory.cc', 'browser/indexed_db/mock_browsertest_indexed_db_class_factory.h', - 'browser/loader/resource_dispatcher_host_browsertest.cc', - 'browser/loader/cross_site_resource_handler_browsertest.cc', 'browser/loader/async_resource_handler_browsertest.cc', + 'browser/loader/cross_site_resource_handler_browsertest.cc', + 'browser/loader/resource_dispatcher_host_browsertest.cc', 'browser/manifest/manifest_browsertest.cc', 'browser/media/android/media_session_browsertest.cc', 'browser/media/encrypted_media_browsertest.cc', @@ -243,7 +246,6 @@ 'browser/renderer_host/input/touch_action_browsertest.cc', 'browser/renderer_host/input/touch_input_browsertest.cc', 'browser/renderer_host/input/touch_selection_controller_client_aura_browsertest.cc', - 'browser/renderer_host/render_message_filter_browsertest.cc', 'browser/renderer_host/render_process_host_browsertest.cc', 'browser/renderer_host/render_view_host_browsertest.cc', 'browser/renderer_host/render_widget_host_view_browsertest.cc', @@ -498,9 +500,9 @@ 'browser/media/android/media_session_uma_helper_unittest.cc', 'browser/media/audio_stream_monitor_unittest.cc', 'browser/media/capture/audio_mirroring_manager_unittest.cc', + 'browser/media/capture/cursor_renderer_aura_unittest.cc', 'browser/media/capture/web_contents_audio_input_stream_unittest.cc', 'browser/media/capture/web_contents_video_capture_device_unittest.cc', - 'browser/media/capture/cursor_renderer_aura_unittest.cc', 'browser/media/media_internals_unittest.cc', 'browser/media/midi_host_unittest.cc', 'browser/media/webrtc_identity_store_unittest.cc', @@ -652,10 +654,10 @@ 'common/fileapi/file_system_util_unittest.cc', 'common/font_warmup_win_unittest.cc', 'common/gpu/client/gpu_memory_buffer_impl_shared_memory_unittest.cc', + 'common/gpu/gpu_channel_manager_unittest.cc', 'common/gpu/gpu_channel_test_common.cc', 'common/gpu/gpu_channel_test_common.h', 'common/gpu/gpu_channel_unittest.cc', - 'common/gpu/gpu_channel_manager_unittest.cc', 'common/host_discardable_shared_memory_manager_unittest.cc', 'common/host_shared_bitmap_manager_unittest.cc', 'common/indexed_db/indexed_db_key_unittest.cc', @@ -695,7 +697,6 @@ 'renderer/gpu/render_widget_compositor_unittest.cc', 'renderer/ico_image_decoder_unittest.cc', 'renderer/input/input_event_filter_unittest.cc', - 'renderer/peripheral_content_heuristic_unittest.cc', 'renderer/manifest/manifest_parser_unittest.cc', 'renderer/media/android/media_info_loader_unittest.cc', 'renderer/media/audio_message_filter_unittest.cc', @@ -706,6 +707,7 @@ 'renderer/media/video_capture_impl_manager_unittest.cc', 'renderer/media/video_capture_impl_unittest.cc', 'renderer/media/video_capture_message_filter_unittest.cc', + 'renderer/peripheral_content_heuristic_unittest.cc', 'renderer/raster_worker_pool_unittest.cc', 'renderer/render_thread_impl_unittest.cc', 'renderer/render_widget_unittest.cc',
diff --git a/content/gpu/gpu_main.cc b/content/gpu/gpu_main.cc index 6c7e8af2..973b0a0 100644 --- a/content/gpu/gpu_main.cc +++ b/content/gpu/gpu_main.cc
@@ -55,7 +55,7 @@ #if defined(OS_WIN) #include "base/win/windows_version.h" #include "base/win/scoped_com_initializer.h" -#include "content/common/gpu/media/dxva_video_decode_accelerator.h" +#include "content/common/gpu/media/dxva_video_decode_accelerator_win.h" #include "sandbox/win/src/sandbox.h" #endif
diff --git a/content/plugin/plugin_channel.cc b/content/plugin/plugin_channel.cc index 219f2f15..852d71a2b 100644 --- a/content/plugin/plugin_channel.cc +++ b/content/plugin/plugin_channel.cc
@@ -253,7 +253,6 @@ OnDestroyInstance) IPC_MESSAGE_HANDLER(PluginMsg_GenerateRouteID, OnGenerateRouteID) IPC_MESSAGE_HANDLER(PluginProcessMsg_ClearSiteData, OnClearSiteData) - IPC_MESSAGE_HANDLER(PluginHostMsg_DidAbortLoading, OnDidAbortLoading) IPC_MESSAGE_UNHANDLED(handled = false) IPC_END_MESSAGE_MAP() DCHECK(handled); @@ -327,13 +326,4 @@ Send(new PluginProcessHostMsg_ClearSiteDataResult(success)); } -void PluginChannel::OnDidAbortLoading(int render_view_id) { - for (size_t i = 0; i < plugin_stubs_.size(); ++i) { - if (plugin_stubs_[i]->webplugin()->host_render_view_routing_id() == - render_view_id) { - plugin_stubs_[i]->delegate()->instance()->CloseStreams(); - } - } -} - } // namespace content
diff --git a/content/plugin/webplugin_delegate_stub.cc b/content/plugin/webplugin_delegate_stub.cc index b7fdf0b..ba53302 100644 --- a/content/plugin/webplugin_delegate_stub.cc +++ b/content/plugin/webplugin_delegate_stub.cc
@@ -98,8 +98,6 @@ IPC_MESSAGE_HANDLER(PluginMsg_DidReceiveData, OnDidReceiveData) IPC_MESSAGE_HANDLER(PluginMsg_DidFinishLoading, OnDidFinishLoading) IPC_MESSAGE_HANDLER(PluginMsg_DidFail, OnDidFail) - IPC_MESSAGE_HANDLER(PluginMsg_DidFinishLoadWithReason, - OnDidFinishLoadWithReason) IPC_MESSAGE_HANDLER(PluginMsg_SetFocus, OnSetFocus) IPC_MESSAGE_HANDLER(PluginMsg_HandleInputEvent, OnHandleInputEvent) IPC_MESSAGE_HANDLER(PluginMsg_Paint, OnPaint) @@ -109,8 +107,6 @@ IPC_MESSAGE_HANDLER(PluginMsg_GetFormValue, OnGetFormValue) IPC_MESSAGE_HANDLER(PluginMsg_UpdateGeometry, OnUpdateGeometry) IPC_MESSAGE_HANDLER(PluginMsg_UpdateGeometrySync, OnUpdateGeometry) - IPC_MESSAGE_HANDLER(PluginMsg_SendJavaScriptStream, - OnSendJavaScriptStream) IPC_MESSAGE_HANDLER(PluginMsg_SetContentAreaFocus, OnSetContentAreaFocus) #if defined(OS_WIN) && !defined(USE_AURA) IPC_MESSAGE_HANDLER(PluginMsg_ImeCompositionUpdated, @@ -126,17 +122,6 @@ IPC_MESSAGE_HANDLER(PluginMsg_ImeCompositionCompleted, OnImeCompositionCompleted) #endif - IPC_MESSAGE_HANDLER(PluginMsg_DidReceiveManualResponse, - OnDidReceiveManualResponse) - IPC_MESSAGE_HANDLER(PluginMsg_DidReceiveManualData, OnDidReceiveManualData) - IPC_MESSAGE_HANDLER(PluginMsg_DidFinishManualLoading, - OnDidFinishManualLoading) - IPC_MESSAGE_HANDLER(PluginMsg_DidManualLoadFail, OnDidManualLoadFail) - IPC_MESSAGE_HANDLER(PluginMsg_HandleURLRequestReply, - OnHandleURLRequestReply) - IPC_MESSAGE_HANDLER(PluginMsg_HTTPRangeRequestReply, - OnHTTPRangeRequestReply) - IPC_MESSAGE_HANDLER(PluginMsg_FetchURL, OnFetchURL) IPC_MESSAGE_UNHANDLED(handled = false) IPC_END_MESSAGE_MAP() @@ -246,11 +231,6 @@ client->DidFail(id); } -void WebPluginDelegateStub::OnDidFinishLoadWithReason( - const GURL& url, int reason, int notify_id) { - delegate_->DidFinishLoadWithReason(url, reason, notify_id); -} - void WebPluginDelegateStub::OnSetFocus(bool focused) { delegate_->SetFocus(focused); #if defined(OS_WIN) && !defined(USE_AURA) @@ -312,13 +292,6 @@ *success = delegate_->GetFormValue(value); } -void WebPluginDelegateStub::OnSendJavaScriptStream(const GURL& url, - const std::string& result, - bool success, - int notify_id) { - delegate_->SendJavaScriptStream(url, result, success, notify_id); -} - void WebPluginDelegateStub::OnSetContentAreaFocus(bool has_focus) { if (delegate_) delegate_->SetContentAreaHasFocus(has_focus); @@ -376,61 +349,4 @@ } #endif // OS_MACOSX -void WebPluginDelegateStub::OnDidReceiveManualResponse( - const GURL& url, - const PluginMsg_DidReceiveResponseParams& params) { - delegate_->DidReceiveManualResponse(url, params.mime_type, params.headers, - params.expected_length, - params.last_modified); -} - -void WebPluginDelegateStub::OnDidReceiveManualData( - const std::vector<char>& buffer) { - delegate_->DidReceiveManualData(&buffer.front(), - static_cast<int>(buffer.size())); -} - -void WebPluginDelegateStub::OnDidFinishManualLoading() { - delegate_->DidFinishManualLoading(); -} - -void WebPluginDelegateStub::OnDidManualLoadFail() { - delegate_->DidManualLoadFail(); -} - -void WebPluginDelegateStub::OnHandleURLRequestReply( - unsigned long resource_id, const GURL& url, int notify_id) { - WebPluginResourceClient* resource_client = - delegate_->CreateResourceClient(resource_id, url, notify_id); - webplugin_->OnResourceCreated(resource_id, resource_client); -} - -void WebPluginDelegateStub::OnHTTPRangeRequestReply( - unsigned long resource_id, int range_request_id) { - WebPluginResourceClient* resource_client = - delegate_->CreateSeekableResourceClient(resource_id, range_request_id); - webplugin_->OnResourceCreated(resource_id, resource_client); -} - -void WebPluginDelegateStub::OnFetchURL( - const PluginMsg_FetchURL_Params& params) { - const char* data = NULL; - if (params.post_data.size()) - data = ¶ms.post_data[0]; - - delegate_->FetchURL(params.resource_id, - params.notify_id, - params.url, - params.first_party_for_cookies, - params.method, - data, - static_cast<unsigned int>(params.post_data.size()), - Referrer(params.referrer, params.referrer_policy), - params.notify_redirect, - params.is_plugin_src_load, - channel_->renderer_id(), - params.render_frame_id, - webplugin_->host_render_view_routing_id()); -} - } // namespace content
diff --git a/content/plugin/webplugin_delegate_stub.h b/content/plugin/webplugin_delegate_stub.h index 63964e1..e150661 100644 --- a/content/plugin/webplugin_delegate_stub.h +++ b/content/plugin/webplugin_delegate_stub.h
@@ -67,7 +67,6 @@ int data_offset); void OnDidFinishLoading(int id); void OnDidFail(int id); - void OnDidFinishLoadWithReason(const GURL& url, int reason, int notify_id); void OnSetFocus(bool focused); void OnHandleInputEvent(const blink::WebInputEvent* event, bool* handled, WebCursor* cursor); @@ -75,10 +74,6 @@ void OnDidPaint(); void OnUpdateGeometry(const PluginMsg_UpdateGeometry_Param& param); void OnGetPluginScriptableObject(int* route_id); - void OnSendJavaScriptStream(const GURL& url, - const std::string& result, - bool success, - int notify_id); void OnGetFormValue(base::string16* value, bool* success); void OnSetContentAreaFocus(bool has_focus); @@ -99,18 +94,6 @@ void OnImeCompositionCompleted(const base::string16& text); #endif - void OnDidReceiveManualResponse( - const GURL& url, - const PluginMsg_DidReceiveResponseParams& params); - void OnDidReceiveManualData(const std::vector<char>& buffer); - void OnDidFinishManualLoading(); - void OnDidManualLoadFail(); - void OnHandleURLRequestReply(unsigned long resource_id, - const GURL& url, - int notify_id); - void OnHTTPRangeRequestReply(unsigned long resource_id, int range_request_id); - void OnFetchURL(const PluginMsg_FetchURL_Params& params); - std::string mime_type_; int instance_id_;
diff --git a/content/plugin/webplugin_proxy.cc b/content/plugin/webplugin_proxy.cc index 5bd3d67e..13447907 100644 --- a/content/plugin/webplugin_proxy.cc +++ b/content/plugin/webplugin_proxy.cc
@@ -269,46 +269,6 @@ resource_clients_[resource_id] = client; } -void WebPluginProxy::HandleURLRequest(const char* url, - const char* method, - const char* target, - const char* buf, - unsigned int len, - int notify_id, - bool popups_allowed, - bool notify_redirects) { - if (!target && base::EqualsCaseInsensitiveASCII(method, "GET")) { - // Please refer to https://bugzilla.mozilla.org/show_bug.cgi?id=366082 - // for more details on this. - if (delegate_->GetQuirks() & - WebPluginDelegateImpl::PLUGIN_QUIRK_BLOCK_NONSTANDARD_GETURL_REQUESTS) { - GURL request_url(url); - if (!request_url.SchemeIs(url::kHttpScheme) && - !request_url.SchemeIs(url::kHttpsScheme) && - !request_url.SchemeIs(url::kFtpScheme)) { - return; - } - } - } - - PluginHostMsg_URLRequest_Params params; - params.url = url; - params.method = method; - if (target) - params.target = std::string(target); - - if (len) { - params.buffer.resize(len); - memcpy(¶ms.buffer.front(), buf, len); - } - - params.notify_id = notify_id; - params.popups_allowed = popups_allowed; - params.notify_redirects = notify_redirects; - - Send(new PluginHostMsg_URLRequest(route_id_, params)); -} - void WebPluginProxy::Paint(const gfx::Rect& rect) { #if defined(OS_MACOSX) if (!windowless_context()) @@ -500,12 +460,6 @@ Send(new PluginHostMsg_CancelDocumentLoad(route_id_)); } -void WebPluginProxy::InitiateHTTPRangeRequest( - const char* url, const char* range_info, int range_request_id) { - Send(new PluginHostMsg_InitiateHTTPRangeRequest( - route_id_, url, range_info, range_request_id)); -} - void WebPluginProxy::DidStartLoading() { Send(new PluginHostMsg_DidStartLoading(route_id_)); }
diff --git a/content/plugin/webplugin_proxy.h b/content/plugin/webplugin_proxy.h index 7e54434..cc000cd 100644 --- a/content/plugin/webplugin_proxy.h +++ b/content/plugin/webplugin_proxy.h
@@ -66,23 +66,12 @@ const std::string& cookie) override; std::string GetCookies(const GURL& url, const GURL& first_party_for_cookies) override; - void HandleURLRequest(const char* url, - const char* method, - const char* target, - const char* buf, - unsigned int len, - int notify_id, - bool popups_allowed, - bool notify_redirects) override; void UpdateGeometry(const gfx::Rect& window_rect, const gfx::Rect& clip_rect, const TransportDIB::Handle& windowless_buffer0, const TransportDIB::Handle& windowless_buffer1, int windowless_buffer_index); void CancelDocumentLoad() override; - void InitiateHTTPRangeRequest(const char* url, - const char* range_info, - int range_request_id) override; void DidStartLoading() override; void DidStopLoading() override; void SetDeferResourceLoading(unsigned long resource_id, bool defer) override;
diff --git a/content/public/android/java/src/org/chromium/content/browser/ContentViewCore.java b/content/public/android/java/src/org/chromium/content/browser/ContentViewCore.java index de62b51..db35349 100644 --- a/content/public/android/java/src/org/chromium/content/browser/ContentViewCore.java +++ b/content/public/android/java/src/org/chromium/content/browser/ContentViewCore.java
@@ -2561,11 +2561,15 @@ @SuppressWarnings("unused") @CalledByNative - private void showPastePopupWithFeedback(int x, int y) { + private boolean showPastePopupWithFeedback(int x, int y) { // TODO(jdduke): Remove this when there is a better signal that long press caused // showing of the paste popup. See http://crbug.com/150151. if (showPastePopup(x, y)) { mContainerView.performHapticFeedback(HapticFeedbackConstants.LONG_PRESS); + if (mWebContents != null) mWebContents.onContextMenuOpened(); + return true; + } else { + return false; } } @@ -2594,6 +2598,11 @@ mWebContents.paste(); dismissTextHandles(); } + + @Override + public void onDismiss() { + if (mWebContents != null) mWebContents.onContextMenuClosed(); + } }; if (supportsFloatingActionMode()) { mPastePopupMenu = new FloatingPastePopupMenu(getContainerView(), delegate);
diff --git a/content/public/android/java/src/org/chromium/content/browser/input/FloatingPastePopupMenu.java b/content/public/android/java/src/org/chromium/content/browser/input/FloatingPastePopupMenu.java index 7f7723b..3423dfa3 100644 --- a/content/public/android/java/src/org/chromium/content/browser/input/FloatingPastePopupMenu.java +++ b/content/public/android/java/src/org/chromium/content/browser/input/FloatingPastePopupMenu.java
@@ -162,6 +162,7 @@ @Override public void onDestroyActionMode() { mActionMode = null; + mDelegate.onDismiss(); } @Override
diff --git a/content/public/android/java/src/org/chromium/content/browser/input/LegacyPastePopupMenu.java b/content/public/android/java/src/org/chromium/content/browser/input/LegacyPastePopupMenu.java index 39ee0e6..abe69273 100644 --- a/content/public/android/java/src/org/chromium/content/browser/input/LegacyPastePopupMenu.java +++ b/content/public/android/java/src/org/chromium/content/browser/input/LegacyPastePopupMenu.java
@@ -14,6 +14,7 @@ import android.view.ViewGroup; import android.view.ViewGroup.LayoutParams; import android.widget.PopupWindow; +import android.widget.PopupWindow.OnDismissListener; /** * Paste popup implementation based on TextView.PastePopupMenu. @@ -33,7 +34,7 @@ private final int mLineOffsetY; private final int mWidthOffsetX; - public LegacyPastePopupMenu(View parent, PastePopupMenuDelegate delegate) { + public LegacyPastePopupMenu(View parent, final PastePopupMenuDelegate delegate) { mParent = parent; mDelegate = delegate; mContext = parent.getContext(); @@ -44,6 +45,12 @@ mContainer.setWidth(ViewGroup.LayoutParams.WRAP_CONTENT); mContainer.setHeight(ViewGroup.LayoutParams.WRAP_CONTENT); + mContainer.setOnDismissListener(new OnDismissListener() { + @Override + public void onDismiss() { + delegate.onDismiss(); + } + }); final int[] popupLayoutAttrs = { android.R.attr.textEditPasteWindowLayout,
diff --git a/content/public/android/java/src/org/chromium/content/browser/input/PastePopupMenu.java b/content/public/android/java/src/org/chromium/content/browser/input/PastePopupMenu.java index 6b948968..051379e 100644 --- a/content/public/android/java/src/org/chromium/content/browser/input/PastePopupMenu.java +++ b/content/public/android/java/src/org/chromium/content/browser/input/PastePopupMenu.java
@@ -16,6 +16,11 @@ * Called to initiate a paste after the popup has been tapped. */ void paste(); + + /** + * Called when the popup menu is dismissed. + */ + void onDismiss(); } /**
diff --git a/content/public/android/java/src/org/chromium/content/browser/webcontents/WebContentsImpl.java b/content/public/android/java/src/org/chromium/content/browser/webcontents/WebContentsImpl.java index 6ecb3f8..e2d6cef 100644 --- a/content/public/android/java/src/org/chromium/content/browser/webcontents/WebContentsImpl.java +++ b/content/public/android/java/src/org/chromium/content/browser/webcontents/WebContentsImpl.java
@@ -84,6 +84,8 @@ // Lazily created proxy observer for handling all Java-based WebContentsObservers. private WebContentsObserverProxy mObserverProxy; + private boolean mContextMenuOpened; + private WebContentsImpl( long nativeWebContentsAndroid, NavigationController navigationController) { mNativeWebContentsAndroid = nativeWebContentsAndroid; @@ -430,6 +432,24 @@ srcRect.top, srcRect.left, srcRect.width(), srcRect.height()); } + @Override + public void onContextMenuOpened() { + mContextMenuOpened = true; + } + + @Override + public void onContextMenuClosed() { + if (!mContextMenuOpened) { + return; + } else { + mContextMenuOpened = false; + } + + if (mNativeWebContentsAndroid != 0) { + nativeOnContextMenuClosed(mNativeWebContentsAndroid); + } + } + @CalledByNative private void onGetContentBitmapFinished(ContentBitmapCallback callback, Bitmap bitmap, int response) { @@ -494,4 +514,5 @@ private native void nativeGetContentBitmap(long nativeWebContentsAndroid, ContentBitmapCallback callback, Bitmap.Config config, float scale, float x, float y, float width, float height); + private native void nativeOnContextMenuClosed(long nativeWebContentsAndroid); }
diff --git a/content/public/android/java/src/org/chromium/content_public/browser/WebContents.java b/content/public/android/java/src/org/chromium/content_public/browser/WebContents.java index 919fd1b..4a1729b 100644 --- a/content/public/android/java/src/org/chromium/content_public/browser/WebContents.java +++ b/content/public/android/java/src/org/chromium/content_public/browser/WebContents.java
@@ -323,6 +323,18 @@ void removeObserver(WebContentsObserver observer); /** + * Called when context menu gets opened. + */ + void onContextMenuOpened(); + + /** + * Called when context menu gets closed. Note that closing context menu that is + * not triggered by WebContents will still call this. However, it will have no effect + * if onContextMenuOpened() isn't called in advance. + */ + void onContextMenuClosed(); + + /** * @return The character encoding for the current visible page. */ @VisibleForTesting
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 da0544e..eff9d4f 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
@@ -37,22 +37,22 @@ ChildProcessLauncher.allocateBoundConnectionForTesting(context); // Verify that the connection is not considered as allocated. - assertTrue("Failed connection wasn't released from the allocator.", - CriteriaHelper.pollForCriteria(new Criteria() { - @Override - public boolean isSatisfied() { - return ChildProcessLauncher.allocatedConnectionsCountForTesting( - appContext) == 0; - } - })); + CriteriaHelper.pollForCriteria(new Criteria( + "Failed connection wasn't released from the allocator.") { + @Override + public boolean isSatisfied() { + return ChildProcessLauncher.allocatedConnectionsCountForTesting( + appContext) == 0; + } + }); - assertTrue("Failed connection wasn't released from ChildProcessLauncher.", - CriteriaHelper.pollForCriteria(new Criteria() { - @Override - public boolean isSatisfied() { - return ChildProcessLauncher.connectedServicesCountForTesting() == 0; - } - })); + CriteriaHelper.pollForCriteria(new Criteria( + "Failed connection wasn't released from ChildProcessLauncher.") { + @Override + public boolean isSatisfied() { + return ChildProcessLauncher.connectedServicesCountForTesting() == 0; + } + }); } /** @@ -77,22 +77,22 @@ assertTrue(connection.crashServiceForTesting()); // Verify that the connection gets cleaned-up. - assertTrue("Crashed connection wasn't released from the allocator.", - CriteriaHelper.pollForCriteria(new Criteria() { - @Override - public boolean isSatisfied() { - return ChildProcessLauncher.allocatedConnectionsCountForTesting( - appContext) == 0; - } - })); + CriteriaHelper.pollForCriteria(new Criteria( + "Crashed connection wasn't released from the allocator.") { + @Override + public boolean isSatisfied() { + return ChildProcessLauncher.allocatedConnectionsCountForTesting( + appContext) == 0; + } + }); - assertTrue("Crashed connection wasn't released from ChildProcessLauncher.", - CriteriaHelper.pollForCriteria(new Criteria() { - @Override - public boolean isSatisfied() { - return ChildProcessLauncher.connectedServicesCountForTesting() == 0; - } - })); + CriteriaHelper.pollForCriteria(new Criteria( + "Crashed connection wasn't released from ChildProcessLauncher.") { + @Override + public boolean isSatisfied() { + return ChildProcessLauncher.connectedServicesCountForTesting() == 0; + } + }); } /** @@ -113,42 +113,42 @@ new FileDescriptorInfo[0], ChildProcessLauncher.CALLBACK_FOR_RENDERER_PROCESS, 0); // Verify that the connection completes the setup. - assertTrue("The connection wasn't registered in ChildProcessLauncher after setup.", - CriteriaHelper.pollForCriteria(new Criteria() { - @Override - public boolean isSatisfied() { - return ChildProcessLauncher.connectedServicesCountForTesting() == 1; - } - })); + CriteriaHelper.pollForCriteria(new Criteria( + "The connection wasn't registered in ChildProcessLauncher after setup.") { + @Override + public boolean isSatisfied() { + return ChildProcessLauncher.connectedServicesCountForTesting() == 1; + } + }); - assertTrue("The connection failed to get a pid in setup.", - CriteriaHelper.pollForCriteria(new Criteria() { + CriteriaHelper.pollForCriteria( + new Criteria("The connection failed to get a pid in setup.") { @Override public boolean isSatisfied() { return connection.getPid() != 0; } - })); + }); // Crash the service. assertTrue(connection.crashServiceForTesting()); // Verify that the connection gets cleaned-up. - assertTrue("Crashed connection wasn't released from the allocator.", - CriteriaHelper.pollForCriteria(new Criteria() { - @Override - public boolean isSatisfied() { - return ChildProcessLauncher.allocatedConnectionsCountForTesting( - appContext) == 0; - } - })); + CriteriaHelper.pollForCriteria(new Criteria( + "Crashed connection wasn't released from the allocator.") { + @Override + public boolean isSatisfied() { + return ChildProcessLauncher.allocatedConnectionsCountForTesting( + appContext) == 0; + } + }); - assertTrue("Crashed connection wasn't released from ChildProcessLauncher.", - CriteriaHelper.pollForCriteria(new Criteria() { - @Override - public boolean isSatisfied() { - return ChildProcessLauncher.connectedServicesCountForTesting() == 0; - } - })); + CriteriaHelper.pollForCriteria(new Criteria( + "Crashed connection wasn't released from ChildProcessLauncher.") { + @Override + public boolean isSatisfied() { + return ChildProcessLauncher.connectedServicesCountForTesting() == 0; + } + }); // Verify that the connection pid remains set after termination. assertTrue(connection.getPid() != 0); @@ -180,51 +180,51 @@ new FileDescriptorInfo[0], ChildProcessLauncher.CALLBACK_FOR_RENDERER_PROCESS, 0); // Verify that the connection completes the setup. - assertTrue("The connection wasn't registered in ChildProcessLauncher after setup.", - CriteriaHelper.pollForCriteria(new Criteria() { + CriteriaHelper.pollForCriteria( + new Criteria( + "The connection wasn't registered in ChildProcessLauncher after setup.") { @Override public boolean isSatisfied() { return ChildProcessLauncher.connectedServicesCountForTesting() == 1; } - })); + }); - assertTrue("The connection failed to get a pid in setup.", - CriteriaHelper.pollForCriteria(new Criteria() { + CriteriaHelper.pollForCriteria( + new Criteria("The connection failed to get a pid in setup.") { @Override public boolean isSatisfied() { return connection.getPid() != 0; } - })); + }); // Crash the service. assertTrue(connection.crashServiceForTesting()); // Verify that a new service is started for the pending spawn. - assertTrue("Failed to spawn from queue.", - CriteriaHelper.pollForCriteria(new Criteria() { - @Override - public boolean isSatisfied() { - return ChildProcessLauncher.pendingSpawnsCountForTesting() == 0; - } - })); + CriteriaHelper.pollForCriteria(new Criteria("Failed to spawn from queue.") { + @Override + public boolean isSatisfied() { + return ChildProcessLauncher.pendingSpawnsCountForTesting() == 0; + } + }); - assertTrue("The connection wasn't allocated for the pending spawn.", - CriteriaHelper.pollForCriteria(new Criteria() { + CriteriaHelper.pollForCriteria( + new Criteria("The connection wasn't allocated for the pending spawn.") { @Override public boolean isSatisfied() { return ChildProcessLauncher.allocatedConnectionsCountForTesting( appContext) == 1; } - })); + }); // Verify that the connection completes the setup for the pending spawn. - assertTrue("The connection wasn't registered in ChildProcessLauncher after setup.", - CriteriaHelper.pollForCriteria(new Criteria() { - @Override - public boolean isSatisfied() { - return ChildProcessLauncher.connectedServicesCountForTesting() == 1; - } - })); + CriteriaHelper.pollForCriteria(new Criteria( + "The connection wasn't registered in ChildProcessLauncher after setup.") { + @Override + public boolean isSatisfied() { + return ChildProcessLauncher.connectedServicesCountForTesting() == 1; + } + }); } private ChildProcessConnectionImpl startConnection() throws InterruptedException { @@ -234,13 +234,12 @@ ChildProcessLauncher.allocateBoundConnectionForTesting(context); // Wait for the service to connect. - assertTrue("The connection wasn't established.", - CriteriaHelper.pollForCriteria(new Criteria() { - @Override - public boolean isSatisfied() { - return connection.isConnected(); - } - })); + CriteriaHelper.pollForCriteria(new Criteria("The connection wasn't established.") { + @Override + public boolean isSatisfied() { + return connection.isConnected(); + } + }); return connection; }
diff --git a/content/public/android/javatests/src/org/chromium/content/browser/ClipboardTest.java b/content/public/android/javatests/src/org/chromium/content/browser/ClipboardTest.java index ea036e7..69cdf4d 100644 --- a/content/public/android/javatests/src/org/chromium/content/browser/ClipboardTest.java +++ b/content/public/android/javatests/src/org/chromium/content/browser/ClipboardTest.java
@@ -35,7 +35,7 @@ protected void setUp() throws Exception { super.setUp(); launchContentShellWithUrl(TEST_PAGE_DATA_URL); - assertTrue("Page failed to load", waitForActiveShellToBeDoneLoading()); + waitForActiveShellToBeDoneLoading(); } /** @@ -60,12 +60,12 @@ copy(webContents); // Waits until data has been made available on the Android clipboard. - assertTrue(CriteriaHelper.pollForUIThreadCriteria(new Criteria() { + CriteriaHelper.pollForUIThreadCriteria(new Criteria() { @Override public boolean isSatisfied() { return hasPrimaryClip(clipboardManager); } - })); + }); // Verify that the data on the clipboard is what we expect it to be. For Android JB MR2 // and higher we expect HTML content, for other versions the plain-text representation.
diff --git a/content/public/android/javatests/src/org/chromium/content/browser/ContentViewCoreSelectionTest.java b/content/public/android/javatests/src/org/chromium/content/browser/ContentViewCoreSelectionTest.java index a7beabc..eb6e769 100644 --- a/content/public/android/javatests/src/org/chromium/content/browser/ContentViewCoreSelectionTest.java +++ b/content/public/android/javatests/src/org/chromium/content/browser/ContentViewCoreSelectionTest.java
@@ -43,12 +43,12 @@ super.setUp(); launchContentShellWithUrl(DATA_URL); - assertTrue("Page failed to load", waitForActiveShellToBeDoneLoading()); + waitForActiveShellToBeDoneLoading(); mContentViewCore = getContentViewCore(); assertWaitForPageScaleFactorMatch(1.1f); - assertWaitForSelectActionBarVisible(false); - assertWaitForPastePopupStatus(false); + waitForSelectActionBarVisible(false); + waitForPastePopupStatus(false); } @SmallTest @@ -57,14 +57,14 @@ requestFocusOnUiThread(true); DOMUtils.longPressNode(this, mContentViewCore, "textarea"); - assertWaitForSelectActionBarVisible(true); + waitForSelectActionBarVisible(true); requestFocusOnUiThread(false); - assertWaitForSelectActionBarVisible(false); + waitForSelectActionBarVisible(false); assertFalse(mContentViewCore.hasSelection()); requestFocusOnUiThread(true); - assertWaitForSelectActionBarVisible(false); + waitForSelectActionBarVisible(false); assertFalse(mContentViewCore.hasSelection()); } @@ -74,21 +74,21 @@ requestFocusOnUiThread(true); DOMUtils.longPressNode(this, mContentViewCore, "textarea"); - assertWaitForSelectActionBarVisible(true); + waitForSelectActionBarVisible(true); assertTrue(mContentViewCore.hasSelection()); mContentViewCore.preserveSelectionOnNextLossOfFocus(); requestFocusOnUiThread(false); - assertWaitForSelectActionBarVisible(false); + waitForSelectActionBarVisible(false); assertTrue(mContentViewCore.hasSelection()); requestFocusOnUiThread(true); - assertWaitForSelectActionBarVisible(true); + waitForSelectActionBarVisible(true); assertTrue(mContentViewCore.hasSelection()); // Losing focus yet again should properly clear the selection. requestFocusOnUiThread(false); - assertWaitForSelectActionBarVisible(false); + waitForSelectActionBarVisible(false); assertFalse(mContentViewCore.hasSelection()); } @@ -96,15 +96,15 @@ @Feature({"TextSelection"}) public void testSelectionPreservedAfterReshown() throws Throwable { DOMUtils.longPressNode(this, mContentViewCore, "textarea"); - assertWaitForSelectActionBarVisible(true); + waitForSelectActionBarVisible(true); assertTrue(mContentViewCore.hasSelection()); setVisibileOnUiThread(false); - assertWaitForSelectActionBarVisible(false); + waitForSelectActionBarVisible(false); assertTrue(mContentViewCore.hasSelection()); setVisibileOnUiThread(true); - assertWaitForSelectActionBarVisible(true); + waitForSelectActionBarVisible(true); assertTrue(mContentViewCore.hasSelection()); } @@ -112,15 +112,15 @@ @Feature({"TextSelection"}) public void testSelectionPreservedAfterReattached() throws Throwable { DOMUtils.longPressNode(this, mContentViewCore, "textarea"); - assertWaitForSelectActionBarVisible(true); + waitForSelectActionBarVisible(true); assertTrue(mContentViewCore.hasSelection()); setAttachedOnUiThread(false); - assertWaitForSelectActionBarVisible(false); + waitForSelectActionBarVisible(false); assertTrue(mContentViewCore.hasSelection()); setAttachedOnUiThread(true); - assertWaitForSelectActionBarVisible(true); + waitForSelectActionBarVisible(true); assertTrue(mContentViewCore.hasSelection()); } @@ -129,10 +129,10 @@ public void testPastePopupNotShownOnLongPressingNonEmptyInput() throws Throwable { copyStringToClipboard("SampleTextToCopy"); DOMUtils.longPressNode(this, mContentViewCore, "empty_input_text"); - assertWaitForPastePopupStatus(true); + waitForPastePopupStatus(true); DOMUtils.longPressNode(this, mContentViewCore, "input_text"); - assertWaitForSelectActionBarVisible(true); - assertWaitForPastePopupStatus(false); + waitForSelectActionBarVisible(true); + waitForPastePopupStatus(false); } @SmallTest @@ -140,9 +140,9 @@ public void testPastePopupClearedOnTappingEmptyInput() throws Throwable { copyStringToClipboard("SampleTextToCopy"); DOMUtils.longPressNode(this, mContentViewCore, "empty_input_text"); - assertWaitForPastePopupStatus(true); + waitForPastePopupStatus(true); DOMUtils.clickNode(this, mContentViewCore, "empty_input_text"); - assertWaitForPastePopupStatus(false); + waitForPastePopupStatus(false); } @SmallTest @@ -150,9 +150,9 @@ public void testPastePopupClearedOnTappingNonEmptyInput() throws Throwable { copyStringToClipboard("SampleTextToCopy"); DOMUtils.longPressNode(this, mContentViewCore, "empty_input_text"); - assertWaitForPastePopupStatus(true); + waitForPastePopupStatus(true); DOMUtils.clickNode(this, mContentViewCore, "input_text"); - assertWaitForPastePopupStatus(false); + waitForPastePopupStatus(false); } @SmallTest @@ -160,9 +160,9 @@ public void testPastePopupClearedOnTappingOutsideInput() throws Throwable { copyStringToClipboard("SampleTextToCopy"); DOMUtils.longPressNode(this, mContentViewCore, "empty_input_text"); - assertWaitForPastePopupStatus(true); + waitForPastePopupStatus(true); DOMUtils.clickNode(this, mContentViewCore, "plain_text_2"); - assertWaitForPastePopupStatus(false); + waitForPastePopupStatus(false); } @SmallTest @@ -170,9 +170,9 @@ public void testPastePopupClearedOnLongPressingOutsideInput() throws Throwable { copyStringToClipboard("SampleTextToCopy"); DOMUtils.longPressNode(this, mContentViewCore, "empty_input_text"); - assertWaitForPastePopupStatus(true); + waitForPastePopupStatus(true); DOMUtils.longPressNode(this, mContentViewCore, "plain_text_2"); - assertWaitForPastePopupStatus(false); + waitForPastePopupStatus(false); } @SmallTest @@ -180,10 +180,10 @@ public void testPastePopupNotShownOnLongPressingDisabledInput() throws Throwable { copyStringToClipboard("SampleTextToCopy"); DOMUtils.longPressNode(this, mContentViewCore, "empty_input_text"); - assertWaitForPastePopupStatus(true); + waitForPastePopupStatus(true); assertTrue(mContentViewCore.hasInsertion()); DOMUtils.longPressNode(this, mContentViewCore, "disabled_text"); - assertWaitForPastePopupStatus(false); + waitForPastePopupStatus(false); assertFalse(mContentViewCore.hasInsertion()); } @@ -192,21 +192,21 @@ public void testPastePopupDismissedOnDestroy() throws Throwable { copyStringToClipboard("SampleTextToCopy"); DOMUtils.longPressNode(this, mContentViewCore, "empty_input_text"); - assertWaitForPastePopupStatus(true); + waitForPastePopupStatus(true); ThreadUtils.runOnUiThreadBlocking(new Runnable() { @Override public void run() { mContentViewCore.destroy(); } }); - assertWaitForPastePopupStatus(false); + waitForPastePopupStatus(false); } @SmallTest @Feature({"TextInput"}) public void testActionBarConfiguredCorrectlyForInput() throws Throwable { DOMUtils.longPressNode(this, mContentViewCore, "input_text"); - assertWaitForSelectActionBarVisible(true); + waitForSelectActionBarVisible(true); assertTrue(mContentViewCore.hasSelection()); assertNotNull(mContentViewCore.getSelectActionHandler()); assertTrue(mContentViewCore.getSelectActionHandler().isSelectionEditable()); @@ -217,7 +217,7 @@ @Feature({"TextInput"}) public void testActionBarConfiguredCorrectlyForPassword() throws Throwable { DOMUtils.longPressNode(this, mContentViewCore, "input_password"); - assertWaitForSelectActionBarVisible(true); + waitForSelectActionBarVisible(true); assertTrue(mContentViewCore.hasSelection()); assertNotNull(mContentViewCore.getSelectActionHandler()); assertTrue(mContentViewCore.getSelectActionHandler().isSelectionEditable()); @@ -228,7 +228,7 @@ @Feature({"TextInput"}) public void testActionBarConfiguredCorrectlyForPlainText() throws Throwable { DOMUtils.longPressNode(this, mContentViewCore, "plain_text_1"); - assertWaitForSelectActionBarVisible(true); + waitForSelectActionBarVisible(true); assertTrue(mContentViewCore.hasSelection()); assertNotNull(mContentViewCore.getSelectActionHandler()); assertFalse(mContentViewCore.getSelectActionHandler().isSelectionEditable()); @@ -239,7 +239,7 @@ @Feature({"TextInput"}) public void testActionBarConfiguredCorrectlyForTextArea() throws Throwable { DOMUtils.longPressNode(this, mContentViewCore, "textarea"); - assertWaitForSelectActionBarVisible(true); + waitForSelectActionBarVisible(true); assertTrue(mContentViewCore.hasSelection()); assertNotNull(mContentViewCore.getSelectActionHandler()); assertTrue(mContentViewCore.getSelectActionHandler().isSelectionEditable()); @@ -250,52 +250,52 @@ @Feature({"TextInput"}) public void testSelectActionBarPlainTextCopy() throws Exception { DOMUtils.longPressNode(this, mContentViewCore, "plain_text_1"); - assertWaitForSelectActionBarVisible(true); + waitForSelectActionBarVisible(true); assertTrue(mContentViewCore.hasSelection()); assertNotNull(mContentViewCore.getSelectActionHandler()); selectActionBarCopy(); - assertClipboardContents(mContentViewCore.getContext(), "SamplePlainTextOne"); + waitForClipboardContents(mContentViewCore.getContext(), "SamplePlainTextOne"); } @SmallTest @Feature({"TextInput"}) public void testSelectActionBarInputCopy() throws Exception { DOMUtils.longPressNode(this, mContentViewCore, "input_text"); - assertWaitForSelectActionBarVisible(true); + waitForSelectActionBarVisible(true); assertTrue(mContentViewCore.hasSelection()); assertNotNull(mContentViewCore.getSelectActionHandler()); selectActionBarCopy(); - assertClipboardContents(mContentViewCore.getContext(), "SampleInputText"); + waitForClipboardContents(mContentViewCore.getContext(), "SampleInputText"); } @SmallTest @Feature({"TextInput"}) public void testSelectActionBarPasswordCopy() throws Exception { DOMUtils.longPressNode(this, mContentViewCore, "plain_text_1"); - assertWaitForSelectActionBarVisible(true); + waitForSelectActionBarVisible(true); assertTrue(mContentViewCore.hasSelection()); assertNotNull(mContentViewCore.getSelectActionHandler()); selectActionBarCopy(); - assertClipboardContents(mContentViewCore.getContext(), "SamplePlainTextOne"); + waitForClipboardContents(mContentViewCore.getContext(), "SamplePlainTextOne"); DOMUtils.longPressNode(this, mContentViewCore, "input_password"); - assertWaitForSelectActionBarVisible(true); + waitForSelectActionBarVisible(true); assertTrue(mContentViewCore.hasSelection()); assertNotNull(mContentViewCore.getSelectActionHandler()); selectActionBarCopy(); // Copy option won't be there for Password, hence no change in Clipboard // Validating with previous Clipboard content - assertClipboardContents(mContentViewCore.getContext(), "SamplePlainTextOne"); + waitForClipboardContents(mContentViewCore.getContext(), "SamplePlainTextOne"); } @SmallTest @Feature({"TextInput"}) public void testSelectActionBarTextAreaCopy() throws Exception { DOMUtils.longPressNode(this, mContentViewCore, "textarea"); - assertWaitForSelectActionBarVisible(true); + waitForSelectActionBarVisible(true); assertTrue(mContentViewCore.hasSelection()); assertNotNull(mContentViewCore.getSelectActionHandler()); selectActionBarCopy(); - assertClipboardContents(mContentViewCore.getContext(), "SampleTextArea"); + waitForClipboardContents(mContentViewCore.getContext(), "SampleTextArea"); } @SmallTest @@ -303,30 +303,30 @@ public void testSelectActionBarPlainTextCut() throws Exception { copyStringToClipboard("SampleTextToCopy"); DOMUtils.longPressNode(this, mContentViewCore, "plain_text_1"); - assertWaitForSelectActionBarVisible(true); + waitForSelectActionBarVisible(true); assertTrue(mContentViewCore.hasSelection()); assertEquals(mContentViewCore.getSelectedText(), "SamplePlainTextOne"); assertNotNull(mContentViewCore.getSelectActionHandler()); selectActionBarCut(); - assertWaitForSelectActionBarVisible(true); + waitForSelectActionBarVisible(true); assertTrue(mContentViewCore.hasSelection()); // Cut option won't be available for plain text. // Hence validating previous Clipboard content. - assertClipboardContents(mContentViewCore.getContext(), "SampleTextToCopy"); + waitForClipboardContents(mContentViewCore.getContext(), "SampleTextToCopy"); } @SmallTest @Feature({"TextInput"}) public void testSelectActionBarInputCut() throws Exception { DOMUtils.longPressNode(this, mContentViewCore, "input_text"); - assertWaitForSelectActionBarVisible(true); + waitForSelectActionBarVisible(true); assertTrue(mContentViewCore.hasSelection()); assertEquals(mContentViewCore.getSelectedText(), "SampleInputText"); assertNotNull(mContentViewCore.getSelectActionHandler()); selectActionBarCut(); - assertWaitForSelectActionBarVisible(false); + waitForSelectActionBarVisible(false); assertFalse(mContentViewCore.hasSelection()); - assertClipboardContents(mContentViewCore.getContext(), "SampleInputText"); + waitForClipboardContents(mContentViewCore.getContext(), "SampleInputText"); assertEquals(mContentViewCore.getSelectedText(), ""); } @@ -335,29 +335,29 @@ public void testSelectActionBarPasswordCut() throws Exception { copyStringToClipboard("SampleTextToCopy"); DOMUtils.longPressNode(this, mContentViewCore, "input_password"); - assertWaitForSelectActionBarVisible(true); + waitForSelectActionBarVisible(true); assertTrue(mContentViewCore.hasSelection()); assertNotNull(mContentViewCore.getSelectActionHandler()); selectActionBarCut(); - assertWaitForSelectActionBarVisible(true); + waitForSelectActionBarVisible(true); assertTrue(mContentViewCore.hasSelection()); // Cut option won't be there for Password, hence no change in Clipboard // Validating with previous Clipboard content - assertClipboardContents(mContentViewCore.getContext(), "SampleTextToCopy"); + waitForClipboardContents(mContentViewCore.getContext(), "SampleTextToCopy"); } @SmallTest @Feature({"TextInput"}) public void testSelectActionBarTextAreaCut() throws Exception { DOMUtils.longPressNode(this, mContentViewCore, "textarea"); - assertWaitForSelectActionBarVisible(true); + waitForSelectActionBarVisible(true); assertTrue(mContentViewCore.hasSelection()); assertEquals(mContentViewCore.getSelectedText(), "SampleTextArea"); assertNotNull(mContentViewCore.getSelectActionHandler()); selectActionBarCut(); - assertWaitForSelectActionBarVisible(false); + waitForSelectActionBarVisible(false); assertFalse(mContentViewCore.hasSelection()); - assertClipboardContents(mContentViewCore.getContext(), "SampleTextArea"); + waitForClipboardContents(mContentViewCore.getContext(), "SampleTextArea"); assertEquals(mContentViewCore.getSelectedText(), ""); } @@ -365,24 +365,24 @@ @Feature({"TextSelection"}) public void testSelectActionBarPlainTextSelectAll() throws Exception { DOMUtils.longPressNode(this, mContentViewCore, "plain_text_1"); - assertWaitForSelectActionBarVisible(true); + waitForSelectActionBarVisible(true); assertTrue(mContentViewCore.hasSelection()); assertNotNull(mContentViewCore.getSelectActionHandler()); selectActionBarSelectAll(); assertTrue(mContentViewCore.hasSelection()); - assertWaitForSelectActionBarVisible(true); + waitForSelectActionBarVisible(true); } @SmallTest @Feature({"TextInput"}) public void testSelectActionBarInputSelectAll() throws Exception { DOMUtils.longPressNode(this, mContentViewCore, "input_text"); - assertWaitForSelectActionBarVisible(true); + waitForSelectActionBarVisible(true); assertTrue(mContentViewCore.hasSelection()); assertNotNull(mContentViewCore.getSelectActionHandler()); selectActionBarSelectAll(); assertTrue(mContentViewCore.hasSelection()); - assertWaitForSelectActionBarVisible(true); + waitForSelectActionBarVisible(true); assertEquals(mContentViewCore.getSelectedText(), "SampleInputText"); } @@ -390,24 +390,24 @@ @Feature({"TextInput"}) public void testSelectActionBarPasswordSelectAll() throws Exception { DOMUtils.longPressNode(this, mContentViewCore, "input_password"); - assertWaitForSelectActionBarVisible(true); + waitForSelectActionBarVisible(true); assertTrue(mContentViewCore.hasSelection()); assertNotNull(mContentViewCore.getSelectActionHandler()); selectActionBarSelectAll(); assertTrue(mContentViewCore.hasSelection()); - assertWaitForSelectActionBarVisible(true); + waitForSelectActionBarVisible(true); } @SmallTest @Feature({"TextInput"}) public void testSelectActionBarTextAreaSelectAll() throws Exception { DOMUtils.longPressNode(this, mContentViewCore, "textarea"); - assertWaitForSelectActionBarVisible(true); + waitForSelectActionBarVisible(true); assertTrue(mContentViewCore.hasSelection()); assertNotNull(mContentViewCore.getSelectActionHandler()); selectActionBarSelectAll(); assertTrue(mContentViewCore.hasSelection()); - assertWaitForSelectActionBarVisible(true); + waitForSelectActionBarVisible(true); assertEquals(mContentViewCore.getSelectedText(), "SampleTextArea"); } @@ -415,23 +415,23 @@ @Feature({"TextSelection", "TextInput"}) public void testCursorPositionAfterHidingActionMode() throws Exception { DOMUtils.longPressNode(this, mContentViewCore, "textarea"); - assertWaitForSelectActionBarVisible(true); + waitForSelectActionBarVisible(true); assertTrue(mContentViewCore.hasSelection()); assertNotNull(mContentViewCore.getSelectActionHandler()); selectActionBarSelectAll(); assertTrue(mContentViewCore.hasSelection()); - assertWaitForSelectActionBarVisible(true); + waitForSelectActionBarVisible(true); assertEquals(mContentViewCore.getSelectedText(), "SampleTextArea"); hideSelectActionMode(); - assertWaitForSelectActionBarVisible(false); - assertTrue(CriteriaHelper.pollForUIThreadCriteria(new Criteria() { + waitForSelectActionBarVisible(false); + CriteriaHelper.pollForUIThreadCriteria(new Criteria() { @Override public boolean isSatisfied() { return "SampleTextArea".equals(mContentViewCore.getImeAdapterForTest() .getInputConnectionForTest() .getTextBeforeCursor(50, 0)); } - })); + }); } @SmallTest @@ -439,12 +439,12 @@ public void testSelectActionBarPlainTextPaste() throws Exception { copyStringToClipboard("SampleTextToCopy"); DOMUtils.longPressNode(this, mContentViewCore, "plain_text_1"); - assertWaitForSelectActionBarVisible(true); + waitForSelectActionBarVisible(true); assertTrue(mContentViewCore.hasSelection()); assertNotNull(mContentViewCore.getSelectActionHandler()); selectActionBarPaste(); DOMUtils.longPressNode(this, mContentViewCore, "plain_text_1"); - assertWaitForSelectActionBarVisible(true); + waitForSelectActionBarVisible(true); assertTrue(mContentViewCore.hasSelection()); // Paste option won't be available for plain text. // Hence content won't be changed. @@ -460,13 +460,13 @@ public void testSelectActionBarInputPaste() throws Exception { copyStringToClipboard("SampleTextToCopy"); DOMUtils.longPressNode(this, mContentViewCore, "input_text"); - assertWaitForSelectActionBarVisible(true); + waitForSelectActionBarVisible(true); assertTrue(mContentViewCore.hasSelection()); assertNotNull(mContentViewCore.getSelectActionHandler()); selectActionBarPaste(); DOMUtils.clickNode(this, mContentViewCore, "plain_text_1"); DOMUtils.longPressNode(this, mContentViewCore, "input_text"); - assertWaitForSelectActionBarVisible(true); + waitForSelectActionBarVisible(true); assertTrue(mContentViewCore.hasSelection()); assertEquals(mContentViewCore.getSelectedText(), "SampleTextToCopy"); } @@ -478,7 +478,7 @@ // Select the password field. DOMUtils.longPressNode(this, mContentViewCore, "input_password"); - assertWaitForSelectActionBarVisible(true); + waitForSelectActionBarVisible(true); assertTrue(mContentViewCore.hasSelection()); assertEquals(mContentViewCore.getSelectedText().length(), "SamplePassword".length()); @@ -486,14 +486,14 @@ // "SamplePassword". assertNotNull(mContentViewCore.getSelectActionHandler()); selectActionBarPaste(); - assertWaitForSelectActionBarVisible(false); + waitForSelectActionBarVisible(false); assertFalse(mContentViewCore.hasSelection()); // Ensure the new text matches the pasted text. Note that we can't // actually compare strings as password field selections only provide // a placeholder with the correct length. DOMUtils.longPressNode(this, mContentViewCore, "input_password"); - assertWaitForSelectActionBarVisible(true); + waitForSelectActionBarVisible(true); assertTrue(mContentViewCore.hasSelection()); assertEquals(mContentViewCore.getSelectedText().length(), "SamplePassword2".length()); } @@ -503,13 +503,13 @@ public void testSelectActionBarTextAreaPaste() throws Exception { copyStringToClipboard("SampleTextToCopy"); DOMUtils.longPressNode(this, mContentViewCore, "textarea"); - assertWaitForSelectActionBarVisible(true); + waitForSelectActionBarVisible(true); assertTrue(mContentViewCore.hasSelection()); assertNotNull(mContentViewCore.getSelectActionHandler()); selectActionBarPaste(); DOMUtils.clickNode(this, mContentViewCore, "plain_text_1"); DOMUtils.longPressNode(this, mContentViewCore, "textarea"); - assertWaitForSelectActionBarVisible(true); + waitForSelectActionBarVisible(true); assertTrue(mContentViewCore.hasSelection()); assertEquals(mContentViewCore.getSelectedText(), "SampleTextToCopy"); } @@ -518,7 +518,7 @@ @Feature({"TextInput"}) public void testSelectActionBarSearchAndShareLaunchesNewTask() throws Exception { DOMUtils.longPressNode(this, mContentViewCore, "textarea"); - assertWaitForSelectActionBarVisible(true); + waitForSelectActionBarVisible(true); assertTrue(mContentViewCore.hasSelection()); assertNotNull(mContentViewCore.getSelectActionHandler()); selectActionBarSearch(); @@ -594,9 +594,9 @@ }); } - private void assertClipboardContents(final Context context, final String expectedContents) + private void waitForClipboardContents(final Context context, final String expectedContents) throws InterruptedException { - assertTrue(CriteriaHelper.pollForUIThreadCriteria(new Criteria() { + CriteriaHelper.pollForUIThreadCriteria(new Criteria() { @Override public boolean isSatisfied() { ClipboardManager clipboardManager = @@ -605,17 +605,17 @@ return clip != null && clip.getItemCount() == 1 && TextUtils.equals(clip.getItemAt(0).getText(), expectedContents); } - })); + }); } - private void assertWaitForSelectActionBarVisible( + private void waitForSelectActionBarVisible( final boolean visible) throws InterruptedException { - assertTrue(CriteriaHelper.pollForUIThreadCriteria(new Criteria() { + CriteriaHelper.pollForUIThreadCriteria(new Criteria() { @Override public boolean isSatisfied() { return visible == mContentViewCore.isSelectActionBarShowing(); } - })); + }); } private void setVisibileOnUiThread(final boolean show) { @@ -664,12 +664,12 @@ clipboardManager.setPrimaryClip(clip); } - private void assertWaitForPastePopupStatus(final boolean show) throws InterruptedException { - assertTrue(CriteriaHelper.pollForUIThreadCriteria(new Criteria() { + private void waitForPastePopupStatus(final boolean show) throws InterruptedException { + CriteriaHelper.pollForUIThreadCriteria(new Criteria() { @Override public boolean isSatisfied() { return show == mContentViewCore.isPastePopupShowing(); } - })); + }); } }
diff --git a/content/public/android/javatests/src/org/chromium/content/browser/ContentViewLocationTest.java b/content/public/android/javatests/src/org/chromium/content/browser/ContentViewLocationTest.java index 3d76ef2..8e626c9 100644 --- a/content/public/android/javatests/src/org/chromium/content/browser/ContentViewLocationTest.java +++ b/content/public/android/javatests/src/org/chromium/content/browser/ContentViewLocationTest.java
@@ -50,7 +50,7 @@ mJavascriptHelper.waitUntilHasValue(); assertEquals(0, Integer.parseInt(mJavascriptHelper.getJsonResultAndClear())); - assertTrue(CriteriaHelper.pollForCriteria(new Criteria() { + CriteriaHelper.pollForCriteria(new Criteria() { @Override public boolean isSatisfied() { mJavascriptHelper.evaluateJavaScriptForTests(getWebContents(), "positionCount"); @@ -61,7 +61,7 @@ } return Integer.parseInt(mJavascriptHelper.getJsonResultAndClear()) > 0; } - })); + }); } private void startGeolocationWatchPosition() throws Throwable { @@ -71,12 +71,12 @@ } private void ensureGeolocationRunning(final boolean running) throws Exception { - assertTrue(CriteriaHelper.pollForCriteria(new Criteria() { + CriteriaHelper.pollForCriteria(new Criteria() { @Override public boolean isSatisfied() { return mMockLocationProvider.isRunning() == running; } - })); + }); } @Override
diff --git a/content/public/android/javatests/src/org/chromium/content/browser/ContentViewPopupZoomerTest.java b/content/public/android/javatests/src/org/chromium/content/browser/ContentViewPopupZoomerTest.java index 6d72ad1..64b62486 100644 --- a/content/public/android/javatests/src/org/chromium/content/browser/ContentViewPopupZoomerTest.java +++ b/content/public/android/javatests/src/org/chromium/content/browser/ContentViewPopupZoomerTest.java
@@ -26,10 +26,11 @@ return null; } - private static class PopupShowingCriteria implements Criteria { + private static class PopupShowingCriteria extends Criteria { private final ViewGroup mView; private final boolean mShouldBeShown; public PopupShowingCriteria(ViewGroup view, boolean shouldBeShown) { + super(shouldBeShown ? "Popup did not get shown." : "Popup shown incorrectly."); mView = view; mShouldBeShown = shouldBeShown; } @@ -41,9 +42,10 @@ } } - private static class PopupHasNonZeroDimensionsCriteria implements Criteria { + private static class PopupHasNonZeroDimensionsCriteria extends Criteria { private final ViewGroup mView; public PopupHasNonZeroDimensionsCriteria(ViewGroup view) { + super("The zoomer popup has zero dimensions."); mView = view; } @Override @@ -82,22 +84,19 @@ @DisabledTest // crbug.com/167045 public void testPopupZoomerShowsUp() throws InterruptedException, TimeoutException { launchContentShellWithUrl(generateTestUrl(100, 15, "clickme")); - assertTrue("Page failed to load", waitForActiveShellToBeDoneLoading()); + waitForActiveShellToBeDoneLoading(); final ContentViewCore viewCore = getContentViewCore(); final ViewGroup view = viewCore.getContainerView(); // The popup should be hidden before the click. - assertTrue("The zoomer popup is shown after load.", - CriteriaHelper.pollForCriteria(new PopupShowingCriteria(view, false))); + CriteriaHelper.pollForCriteria(new PopupShowingCriteria(view, false)); // Once clicked, the popup should show up. DOMUtils.clickNode(this, viewCore, "clickme"); - assertTrue("The zoomer popup did not show up on click.", - CriteriaHelper.pollForCriteria(new PopupShowingCriteria(view, true))); + CriteriaHelper.pollForCriteria(new PopupShowingCriteria(view, true)); // The shown popup should have valid dimensions eventually. - assertTrue("The zoomer popup has zero dimensions.", - CriteriaHelper.pollForCriteria(new PopupHasNonZeroDimensionsCriteria(view))); + CriteriaHelper.pollForCriteria(new PopupHasNonZeroDimensionsCriteria(view)); } }
diff --git a/content/public/android/javatests/src/org/chromium/content/browser/ContentViewScrollingTest.java b/content/public/android/javatests/src/org/chromium/content/browser/ContentViewScrollingTest.java index 0ea171c..a73cf9b 100644 --- a/content/public/android/javatests/src/org/chromium/content/browser/ContentViewScrollingTest.java +++ b/content/public/android/javatests/src/org/chromium/content/browser/ContentViewScrollingTest.java
@@ -102,7 +102,7 @@ private void assertWaitForScroll(final boolean hugLeft, final boolean hugTop) throws InterruptedException { - assertTrue(CriteriaHelper.pollForCriteria(new Criteria() { + CriteriaHelper.pollForCriteria(new Criteria() { @Override public boolean isSatisfied() { // Scrolling and flinging don't result in exact coordinates. @@ -117,7 +117,7 @@ : getContentViewCore().getNativeScrollYForTest() > maxThreshold; return xCorrect && yCorrect; } - })); + }); } private void fling(final int vx, final int vy) throws Throwable { @@ -169,7 +169,7 @@ super.setUp(); launchContentShellWithUrl(LARGE_PAGE); - assertTrue("Page failed to load", waitForActiveShellToBeDoneLoading()); + waitForActiveShellToBeDoneLoading(); assertWaitForPageScaleFactorMatch(2.0f); assertEquals(0, getContentViewCore().getNativeScrollXForTest()); @@ -362,11 +362,11 @@ }); scrollTo(scrollToX, scrollToY); assertWaitForScroll(false, false); - assertTrue(CriteriaHelper.pollForCriteria(new Criteria() { + CriteriaHelper.pollForCriteria(new Criteria() { @Override public boolean isSatisfied() { return containerViewInternals.isScrollChanged(); } - })); + }); } }
diff --git a/content/public/android/javatests/src/org/chromium/content/browser/GestureDetectorResetTest.java b/content/public/android/javatests/src/org/chromium/content/browser/GestureDetectorResetTest.java index 853c8a3e..dda203e57e 100644 --- a/content/public/android/javatests/src/org/chromium/content/browser/GestureDetectorResetTest.java +++ b/content/public/android/javatests/src/org/chromium/content/browser/GestureDetectorResetTest.java
@@ -34,14 +34,16 @@ + "<div id=\"test\">not clicked</div><br/>" + "</body></html>"); - private static class NodeContentsIsEqualToCriteria implements Criteria { + private static class NodeContentsIsEqualToCriteria extends Criteria { private final ContentViewCore mViewCore; private final String mNodeId; private final String mExpectedContents; public NodeContentsIsEqualToCriteria( + String failureReason, ContentViewCore viewCore, String nodeId, String expectedContents) { + super(failureReason); mViewCore = viewCore; mNodeId = nodeId; mExpectedContents = expectedContents; @@ -68,17 +70,17 @@ ContentViewCore contentViewCore) throws InterruptedException, Exception, Throwable { // Initially the text on the page should say "not clicked". - assertTrue("The page contents is invalid " + disambiguation, - CriteriaHelper.pollForCriteria(new NodeContentsIsEqualToCriteria( - contentViewCore, "test", "not clicked"))); + CriteriaHelper.pollForCriteria(new NodeContentsIsEqualToCriteria( + "The page contents is invalid " + disambiguation, contentViewCore, + "test", "not clicked")); // Click the button. DOMUtils.clickNode(this, contentViewCore, "button"); // After the click, the text on the page should say "clicked". - assertTrue("The page contents didn't change after a click " + disambiguation, - CriteriaHelper.pollForCriteria(new NodeContentsIsEqualToCriteria( - contentViewCore, "test", "clicked"))); + CriteriaHelper.pollForCriteria(new NodeContentsIsEqualToCriteria( + "The page contents didn't change after a click " + disambiguation, + contentViewCore, "test", "clicked")); } /** @@ -94,7 +96,7 @@ throws InterruptedException, Exception, Throwable { // Load the test page. launchContentShellWithUrl(CLICK_TEST_URL); - assertTrue("Page failed to load", waitForActiveShellToBeDoneLoading()); + waitForActiveShellToBeDoneLoading(); final ContentViewCore viewCore = getContentViewCore(); final TestCallbackHelperContainer viewClient =
diff --git a/content/public/android/javatests/src/org/chromium/content/browser/InterstitialPageTest.java b/content/public/android/javatests/src/org/chromium/content/browser/InterstitialPageTest.java index f95d749..4ad685a 100644 --- a/content/public/android/javatests/src/org/chromium/content/browser/InterstitialPageTest.java +++ b/content/public/android/javatests/src/org/chromium/content/browser/InterstitialPageTest.java
@@ -63,8 +63,9 @@ waitForActiveShellToBeDoneLoading(); } - private boolean waitForInterstitial(final boolean shouldBeShown) throws InterruptedException { - return CriteriaHelper.pollForUIThreadCriteria(new Criteria() { + private void waitForInterstitial(final boolean shouldBeShown) throws InterruptedException { + CriteriaHelper.pollForUIThreadCriteria(new Criteria( + shouldBeShown ? "Interstitial never shown." : "Interstitial never hidden.") { @Override public boolean isSatisfied() { return shouldBeShown @@ -111,11 +112,11 @@ } }); - assertTrue("Interstitial never shown.", waitForInterstitial(true)); + waitForInterstitial(true); assertTrue("WebContentsObserver not notified of interstitial showing", observer.isInterstitialShowing()); TouchCommon.singleClickView(getContentViewCore().getContainerView(), 10, 10); - assertTrue("Interstitial never hidden.", waitForInterstitial(false)); + waitForInterstitial(false); assertTrue("WebContentsObserver not notified of interstitial hiding", !observer.isInterstitialShowing()); }
diff --git a/content/public/android/javatests/src/org/chromium/content/browser/MediaSessionTest.java b/content/public/android/javatests/src/org/chromium/content/browser/MediaSessionTest.java index 9a9576dd..6932f3e8 100644 --- a/content/public/android/javatests/src/org/chromium/content/browser/MediaSessionTest.java +++ b/content/public/android/javatests/src/org/chromium/content/browser/MediaSessionTest.java
@@ -63,8 +63,8 @@ mAudioFocusState = AudioManager.AUDIOFOCUS_LOSS; } - public boolean waitForFocusStateChange(final int focusType) throws InterruptedException { - return CriteriaHelper.pollForCriteria(new Criteria() { + public void waitForFocusStateChange(final int focusType) throws InterruptedException { + CriteriaHelper.pollForCriteria(new Criteria() { @Override public boolean isSatisfied() { return getAudioFocusState() == focusType; @@ -100,19 +100,19 @@ public void testDontStopEachOther() throws Exception { assertTrue(DOMUtils.isMediaPaused(getWebContents(), LONG_AUDIO)); DOMUtils.playMedia(getWebContents(), LONG_AUDIO); - assertTrue(DOMUtils.waitForMediaPlay(getWebContents(), LONG_AUDIO)); + DOMUtils.waitForMediaPlay(getWebContents(), LONG_AUDIO); assertTrue(DOMUtils.isMediaPaused(getWebContents(), LONG_VIDEO)); DOMUtils.playMedia(getWebContents(), LONG_VIDEO); - assertTrue(DOMUtils.waitForMediaPlay(getWebContents(), LONG_VIDEO)); + DOMUtils.waitForMediaPlay(getWebContents(), LONG_VIDEO); assertTrue(DOMUtils.isMediaPaused(getWebContents(), SHORT_VIDEO)); DOMUtils.playMedia(getWebContents(), SHORT_VIDEO); - assertTrue(DOMUtils.waitForMediaPlay(getWebContents(), SHORT_VIDEO)); + DOMUtils.waitForMediaPlay(getWebContents(), SHORT_VIDEO); assertTrue(DOMUtils.isMediaPaused(getWebContents(), SHORT_AUDIO)); DOMUtils.playMedia(getWebContents(), SHORT_AUDIO); - assertTrue(DOMUtils.waitForMediaPlay(getWebContents(), SHORT_AUDIO)); + DOMUtils.waitForMediaPlay(getWebContents(), SHORT_AUDIO); assertFalse(DOMUtils.isMediaPaused(getWebContents(), SHORT_AUDIO)); assertFalse(DOMUtils.isMediaPaused(getWebContents(), LONG_AUDIO)); @@ -128,11 +128,11 @@ assertEquals(AudioManager.AUDIOFOCUS_GAIN, mAudioFocusChangeListener.getAudioFocusState()); DOMUtils.playMedia(getWebContents(), VERY_SHORT_AUDIO); - assertTrue(DOMUtils.waitForMediaPlay(getWebContents(), VERY_SHORT_AUDIO)); + DOMUtils.waitForMediaPlay(getWebContents(), VERY_SHORT_AUDIO); - assertTrue(mAudioFocusChangeListener.waitForFocusStateChange( - AudioManager.AUDIOFOCUS_LOSS_TRANSIENT_CAN_DUCK)); - assertTrue(mAudioFocusChangeListener.waitForFocusStateChange(AudioManager.AUDIOFOCUS_GAIN)); + mAudioFocusChangeListener.waitForFocusStateChange( + AudioManager.AUDIOFOCUS_LOSS_TRANSIENT_CAN_DUCK); + mAudioFocusChangeListener.waitForFocusStateChange(AudioManager.AUDIOFOCUS_GAIN); } @MediumTest @@ -143,11 +143,11 @@ assertEquals(AudioManager.AUDIOFOCUS_GAIN, mAudioFocusChangeListener.getAudioFocusState()); DOMUtils.playMedia(getWebContents(), VERY_SHORT_VIDEO); - assertTrue(DOMUtils.waitForMediaPlay(getWebContents(), VERY_SHORT_VIDEO)); + DOMUtils.waitForMediaPlay(getWebContents(), VERY_SHORT_VIDEO); - assertTrue(mAudioFocusChangeListener.waitForFocusStateChange( - AudioManager.AUDIOFOCUS_LOSS_TRANSIENT_CAN_DUCK)); - assertTrue(mAudioFocusChangeListener.waitForFocusStateChange(AudioManager.AUDIOFOCUS_GAIN)); + mAudioFocusChangeListener.waitForFocusStateChange( + AudioManager.AUDIOFOCUS_LOSS_TRANSIENT_CAN_DUCK); + mAudioFocusChangeListener.waitForFocusStateChange(AudioManager.AUDIOFOCUS_GAIN); } @SmallTest @@ -158,9 +158,9 @@ assertEquals(AudioManager.AUDIOFOCUS_GAIN, mAudioFocusChangeListener.getAudioFocusState()); DOMUtils.playMedia(getWebContents(), LONG_AUDIO); - assertTrue(DOMUtils.waitForMediaPlay(getWebContents(), LONG_AUDIO)); + DOMUtils.waitForMediaPlay(getWebContents(), LONG_AUDIO); - assertTrue(mAudioFocusChangeListener.waitForFocusStateChange(AudioManager.AUDIOFOCUS_LOSS)); + mAudioFocusChangeListener.waitForFocusStateChange(AudioManager.AUDIOFOCUS_LOSS); } @SmallTest @@ -171,9 +171,9 @@ assertEquals(AudioManager.AUDIOFOCUS_GAIN, mAudioFocusChangeListener.getAudioFocusState()); DOMUtils.playMedia(getWebContents(), LONG_VIDEO); - assertTrue(DOMUtils.waitForMediaPlay(getWebContents(), LONG_VIDEO)); + DOMUtils.waitForMediaPlay(getWebContents(), LONG_VIDEO); - assertTrue(mAudioFocusChangeListener.waitForFocusStateChange(AudioManager.AUDIOFOCUS_LOSS)); + mAudioFocusChangeListener.waitForFocusStateChange(AudioManager.AUDIOFOCUS_LOSS); } @SmallTest @@ -184,13 +184,13 @@ assertEquals(AudioManager.AUDIOFOCUS_GAIN, mAudioFocusChangeListener.getAudioFocusState()); DOMUtils.playMedia(getWebContents(), SHORT_AUDIO); - assertTrue(DOMUtils.waitForMediaPlay(getWebContents(), SHORT_AUDIO)); - assertTrue(mAudioFocusChangeListener.waitForFocusStateChange( - AudioManager.AUDIOFOCUS_LOSS_TRANSIENT_CAN_DUCK)); + DOMUtils.waitForMediaPlay(getWebContents(), SHORT_AUDIO); + mAudioFocusChangeListener.waitForFocusStateChange( + AudioManager.AUDIOFOCUS_LOSS_TRANSIENT_CAN_DUCK); DOMUtils.playMedia(getWebContents(), LONG_AUDIO); - assertTrue(DOMUtils.waitForMediaPlay(getWebContents(), LONG_AUDIO)); - assertTrue(mAudioFocusChangeListener.waitForFocusStateChange(AudioManager.AUDIOFOCUS_LOSS)); + DOMUtils.waitForMediaPlay(getWebContents(), LONG_AUDIO); + mAudioFocusChangeListener.waitForFocusStateChange(AudioManager.AUDIOFOCUS_LOSS); } @SmallTest @@ -201,13 +201,13 @@ assertEquals(AudioManager.AUDIOFOCUS_GAIN, mAudioFocusChangeListener.getAudioFocusState()); DOMUtils.playMedia(getWebContents(), SHORT_VIDEO); - assertTrue(DOMUtils.waitForMediaPlay(getWebContents(), SHORT_VIDEO)); - assertTrue(mAudioFocusChangeListener.waitForFocusStateChange( - AudioManager.AUDIOFOCUS_LOSS_TRANSIENT_CAN_DUCK)); + DOMUtils.waitForMediaPlay(getWebContents(), SHORT_VIDEO); + mAudioFocusChangeListener.waitForFocusStateChange( + AudioManager.AUDIOFOCUS_LOSS_TRANSIENT_CAN_DUCK); DOMUtils.playMedia(getWebContents(), LONG_VIDEO); - assertTrue(DOMUtils.waitForMediaPlay(getWebContents(), LONG_VIDEO)); - assertTrue(mAudioFocusChangeListener.waitForFocusStateChange(AudioManager.AUDIOFOCUS_LOSS)); + DOMUtils.waitForMediaPlay(getWebContents(), LONG_VIDEO); + mAudioFocusChangeListener.waitForFocusStateChange(AudioManager.AUDIOFOCUS_LOSS); } @SmallTest @@ -218,16 +218,16 @@ assertEquals(AudioManager.AUDIOFOCUS_GAIN, mAudioFocusChangeListener.getAudioFocusState()); DOMUtils.playMedia(getWebContents(), SHORT_AUDIO); - assertTrue(DOMUtils.waitForMediaPlay(getWebContents(), SHORT_AUDIO)); + DOMUtils.waitForMediaPlay(getWebContents(), SHORT_AUDIO); // Wait for the media to be really playing. - assertTrue(mAudioFocusChangeListener.waitForFocusStateChange( - AudioManager.AUDIOFOCUS_LOSS_TRANSIENT_CAN_DUCK)); + mAudioFocusChangeListener.waitForFocusStateChange( + AudioManager.AUDIOFOCUS_LOSS_TRANSIENT_CAN_DUCK); mAudioFocusChangeListener.requestAudioFocus(AudioManager.AUDIOFOCUS_GAIN); assertEquals(AudioManager.AUDIOFOCUS_GAIN, mAudioFocusChangeListener.getAudioFocusState()); - assertTrue(DOMUtils.waitForMediaPause(getWebContents(), SHORT_AUDIO)); + DOMUtils.waitForMediaPause(getWebContents(), SHORT_AUDIO); } @SmallTest @@ -238,16 +238,16 @@ assertEquals(AudioManager.AUDIOFOCUS_GAIN, mAudioFocusChangeListener.getAudioFocusState()); DOMUtils.playMedia(getWebContents(), SHORT_VIDEO); - assertTrue(DOMUtils.waitForMediaPlay(getWebContents(), SHORT_VIDEO)); + DOMUtils.waitForMediaPlay(getWebContents(), SHORT_VIDEO); // Wait for the media to be really playing. - assertTrue(mAudioFocusChangeListener.waitForFocusStateChange( - AudioManager.AUDIOFOCUS_LOSS_TRANSIENT_CAN_DUCK)); + mAudioFocusChangeListener.waitForFocusStateChange( + AudioManager.AUDIOFOCUS_LOSS_TRANSIENT_CAN_DUCK); mAudioFocusChangeListener.requestAudioFocus(AudioManager.AUDIOFOCUS_GAIN); assertEquals(AudioManager.AUDIOFOCUS_GAIN, mAudioFocusChangeListener.getAudioFocusState()); - assertTrue(DOMUtils.waitForMediaPause(getWebContents(), SHORT_VIDEO)); + DOMUtils.waitForMediaPause(getWebContents(), SHORT_VIDEO); } @MediumTest @@ -258,15 +258,15 @@ assertEquals(AudioManager.AUDIOFOCUS_GAIN, mAudioFocusChangeListener.getAudioFocusState()); DOMUtils.playMedia(getWebContents(), LONG_AUDIO); - assertTrue(DOMUtils.waitForMediaPlay(getWebContents(), LONG_AUDIO)); + DOMUtils.waitForMediaPlay(getWebContents(), LONG_AUDIO); // Wait for the media to be really playing. - assertTrue(mAudioFocusChangeListener.waitForFocusStateChange(AudioManager.AUDIOFOCUS_LOSS)); + mAudioFocusChangeListener.waitForFocusStateChange(AudioManager.AUDIOFOCUS_LOSS); mAudioFocusChangeListener.requestAudioFocus(AudioManager.AUDIOFOCUS_GAIN); assertEquals(AudioManager.AUDIOFOCUS_GAIN, mAudioFocusChangeListener.getAudioFocusState()); - assertTrue(DOMUtils.waitForMediaPause(getWebContents(), LONG_AUDIO)); + DOMUtils.waitForMediaPause(getWebContents(), LONG_AUDIO); } @SmallTest @@ -277,15 +277,15 @@ assertEquals(AudioManager.AUDIOFOCUS_GAIN, mAudioFocusChangeListener.getAudioFocusState()); DOMUtils.playMedia(getWebContents(), LONG_VIDEO); - assertTrue(DOMUtils.waitForMediaPlay(getWebContents(), LONG_VIDEO)); + DOMUtils.waitForMediaPlay(getWebContents(), LONG_VIDEO); // Wait for the media to be really playing. - assertTrue(mAudioFocusChangeListener.waitForFocusStateChange(AudioManager.AUDIOFOCUS_LOSS)); + mAudioFocusChangeListener.waitForFocusStateChange(AudioManager.AUDIOFOCUS_LOSS); mAudioFocusChangeListener.requestAudioFocus(AudioManager.AUDIOFOCUS_GAIN); assertEquals(AudioManager.AUDIOFOCUS_GAIN, mAudioFocusChangeListener.getAudioFocusState()); - assertTrue(DOMUtils.waitForMediaPause(getWebContents(), LONG_VIDEO)); + DOMUtils.waitForMediaPause(getWebContents(), LONG_VIDEO); } @SmallTest @@ -296,20 +296,20 @@ assertEquals(AudioManager.AUDIOFOCUS_GAIN, mAudioFocusChangeListener.getAudioFocusState()); DOMUtils.playMedia(getWebContents(), LONG_AUDIO); - assertTrue(DOMUtils.waitForMediaPlay(getWebContents(), LONG_AUDIO)); + DOMUtils.waitForMediaPlay(getWebContents(), LONG_AUDIO); DOMUtils.playMedia(getWebContents(), LONG_VIDEO); - assertTrue(DOMUtils.waitForMediaPlay(getWebContents(), LONG_VIDEO)); + DOMUtils.waitForMediaPlay(getWebContents(), LONG_VIDEO); // Wait for the media to be really playing. - assertTrue(mAudioFocusChangeListener.waitForFocusStateChange(AudioManager.AUDIOFOCUS_LOSS)); + mAudioFocusChangeListener.waitForFocusStateChange(AudioManager.AUDIOFOCUS_LOSS); mAudioFocusChangeListener.requestAudioFocus( AudioManager.AUDIOFOCUS_GAIN_TRANSIENT_MAY_DUCK); assertEquals(AudioManager.AUDIOFOCUS_GAIN_TRANSIENT_MAY_DUCK, mAudioFocusChangeListener.getAudioFocusState()); - assertTrue(DOMUtils.waitForMediaPause(getWebContents(), LONG_AUDIO)); - assertTrue(DOMUtils.waitForMediaPause(getWebContents(), LONG_VIDEO)); + DOMUtils.waitForMediaPause(getWebContents(), LONG_AUDIO); + DOMUtils.waitForMediaPause(getWebContents(), LONG_VIDEO); } @MediumTest @@ -320,25 +320,25 @@ assertEquals(AudioManager.AUDIOFOCUS_GAIN, mAudioFocusChangeListener.getAudioFocusState()); DOMUtils.playMedia(getWebContents(), LONG_AUDIO); - assertTrue(DOMUtils.waitForMediaPlay(getWebContents(), LONG_AUDIO)); + DOMUtils.waitForMediaPlay(getWebContents(), LONG_AUDIO); DOMUtils.playMedia(getWebContents(), LONG_VIDEO); - assertTrue(DOMUtils.waitForMediaPlay(getWebContents(), LONG_VIDEO)); + DOMUtils.waitForMediaPlay(getWebContents(), LONG_VIDEO); // Wait for the media to be really playing. - assertTrue(mAudioFocusChangeListener.waitForFocusStateChange(AudioManager.AUDIOFOCUS_LOSS)); + mAudioFocusChangeListener.waitForFocusStateChange(AudioManager.AUDIOFOCUS_LOSS); mAudioFocusChangeListener.requestAudioFocus( AudioManager.AUDIOFOCUS_GAIN_TRANSIENT_MAY_DUCK); assertEquals(AudioManager.AUDIOFOCUS_GAIN_TRANSIENT_MAY_DUCK, mAudioFocusChangeListener.getAudioFocusState()); - assertTrue(DOMUtils.waitForMediaPause(getWebContents(), LONG_AUDIO)); - assertTrue(DOMUtils.waitForMediaPause(getWebContents(), LONG_VIDEO)); + DOMUtils.waitForMediaPause(getWebContents(), LONG_AUDIO); + DOMUtils.waitForMediaPause(getWebContents(), LONG_VIDEO); mAudioFocusChangeListener.abandonAudioFocus(); - assertTrue(DOMUtils.waitForMediaPlay(getWebContents(), LONG_AUDIO)); - assertTrue(DOMUtils.waitForMediaPlay(getWebContents(), LONG_VIDEO)); + DOMUtils.waitForMediaPlay(getWebContents(), LONG_AUDIO); + DOMUtils.waitForMediaPlay(getWebContents(), LONG_VIDEO); } @MediumTest @@ -349,23 +349,23 @@ assertEquals(AudioManager.AUDIOFOCUS_GAIN, mAudioFocusChangeListener.getAudioFocusState()); DOMUtils.playMedia(getWebContents(), LONG_AUDIO); - assertTrue(DOMUtils.waitForMediaPlay(getWebContents(), LONG_AUDIO)); + DOMUtils.waitForMediaPlay(getWebContents(), LONG_AUDIO); DOMUtils.playMedia(getWebContents(), LONG_VIDEO); - assertTrue(DOMUtils.waitForMediaPlay(getWebContents(), LONG_VIDEO)); + DOMUtils.waitForMediaPlay(getWebContents(), LONG_VIDEO); // Wait for the media to be really playing. - assertTrue(mAudioFocusChangeListener.waitForFocusStateChange(AudioManager.AUDIOFOCUS_LOSS)); + mAudioFocusChangeListener.waitForFocusStateChange(AudioManager.AUDIOFOCUS_LOSS); mAudioFocusChangeListener.requestAudioFocus(AudioManager.AUDIOFOCUS_GAIN_TRANSIENT); assertEquals(AudioManager.AUDIOFOCUS_GAIN_TRANSIENT, mAudioFocusChangeListener.getAudioFocusState()); - assertTrue(DOMUtils.waitForMediaPause(getWebContents(), LONG_AUDIO)); - assertTrue(DOMUtils.waitForMediaPause(getWebContents(), LONG_VIDEO)); + DOMUtils.waitForMediaPause(getWebContents(), LONG_AUDIO); + DOMUtils.waitForMediaPause(getWebContents(), LONG_VIDEO); mAudioFocusChangeListener.abandonAudioFocus(); - assertTrue(DOMUtils.waitForMediaPlay(getWebContents(), LONG_AUDIO)); - assertTrue(DOMUtils.waitForMediaPlay(getWebContents(), LONG_VIDEO)); + DOMUtils.waitForMediaPlay(getWebContents(), LONG_AUDIO); + DOMUtils.waitForMediaPlay(getWebContents(), LONG_VIDEO); } }
diff --git a/content/public/android/javatests/src/org/chromium/content/browser/ScreenOrientationListenerTest.java b/content/public/android/javatests/src/org/chromium/content/browser/ScreenOrientationListenerTest.java index 1d1ebcc..fb55de2 100644 --- a/content/public/android/javatests/src/org/chromium/content/browser/ScreenOrientationListenerTest.java +++ b/content/public/android/javatests/src/org/chromium/content/browser/ScreenOrientationListenerTest.java
@@ -127,7 +127,13 @@ }); getInstrumentation().waitForIdleSync(); - CriteriaHelper.pollForCriteria(criteria); + try { + CriteriaHelper.pollForCriteria(criteria); + } catch (AssertionError e) { + // This should not be here but the Criteria does not support cases where the orientation + // is not being changed (i.e. where the Natural orientation matches the one you are + // locking to). crbug.com/565587 + } } @Override
diff --git a/content/public/android/javatests/src/org/chromium/content/browser/ScreenOrientationProviderTest.java b/content/public/android/javatests/src/org/chromium/content/browser/ScreenOrientationProviderTest.java index 75d36244..0a95dbd 100644 --- a/content/public/android/javatests/src/org/chromium/content/browser/ScreenOrientationProviderTest.java +++ b/content/public/android/javatests/src/org/chromium/content/browser/ScreenOrientationProviderTest.java
@@ -103,7 +103,7 @@ /** * Call |lockOrientation| and wait for an orientation change. */ - private boolean lockOrientationAndWait(final int orientations) throws InterruptedException { + private void lockOrientationAndWait(final int orientations) throws InterruptedException { OrientationChangeObserverCriteria criteria = new OrientationChangeObserverCriteria(mObserver); @@ -115,7 +115,13 @@ }); getInstrumentation().waitForIdleSync(); - return CriteriaHelper.pollForCriteria(criteria); + try { + CriteriaHelper.pollForCriteria(criteria); + } catch (AssertionError e) { + // This should not be here but the Criteria does not support cases where the orientation + // is not being changed (i.e. where the Natural orientation matches the one you are + // locking to). crbug.com/565587 + } } @Override @@ -145,7 +151,13 @@ lockOrientationAndWait(ScreenOrientationValues.PORTRAIT_PRIMARY); // Make sure mObserver is updated before we start the tests. - CriteriaHelper.pollForCriteria(criteria); + try { + CriteriaHelper.pollForCriteria(criteria); + } catch (AssertionError e) { + // This should not be here but the Criteria does not support cases where the orientation + // is not being changed (i.e. where the Natural orientation matches the one you are + // locking to). crbug.com/565587 + } } @Override
diff --git a/content/public/android/javatests/src/org/chromium/content/browser/TestsJavaScriptEvalTest.java b/content/public/android/javatests/src/org/chromium/content/browser/TestsJavaScriptEvalTest.java index 0eed6b8..29b7b41 100644 --- a/content/public/android/javatests/src/org/chromium/content/browser/TestsJavaScriptEvalTest.java +++ b/content/public/android/javatests/src/org/chromium/content/browser/TestsJavaScriptEvalTest.java
@@ -33,7 +33,7 @@ public void testJavaScriptEvalIsCorrectlyOrdered() throws InterruptedException, Exception, Throwable { launchContentShellWithUrl(JSTEST_URL); - assertTrue("Page failed to load", waitForActiveShellToBeDoneLoading()); + waitForActiveShellToBeDoneLoading(); final WebContents webContents = getWebContents(); for (int i = 0; i < 30; ++i) {
diff --git a/content/public/android/javatests/src/org/chromium/content/browser/VibrationManagerImplTest.java b/content/public/android/javatests/src/org/chromium/content/browser/VibrationManagerImplTest.java index 634d76bd..2613065 100644 --- a/content/public/android/javatests/src/org/chromium/content/browser/VibrationManagerImplTest.java +++ b/content/public/android/javatests/src/org/chromium/content/browser/VibrationManagerImplTest.java
@@ -60,7 +60,7 @@ protected void setUp() throws Exception { super.setUp(); launchContentShellWithUrl("about:blank"); - assertTrue("Page failed to load", waitForActiveShellToBeDoneLoading()); + waitForActiveShellToBeDoneLoading(); mFakeWrapper = new FakeAndroidVibratorWrapper(); VibrationManagerImpl.setVibratorWrapperForTesting(mFakeWrapper); @@ -80,12 +80,12 @@ loadNewShell(URL_VIBRATOR_VIBRATE); // Waits until VibrationManagerImpl.Vibrate() got called. - assertTrue(CriteriaHelper.pollForUIThreadCriteria(new Criteria() { + CriteriaHelper.pollForUIThreadCriteria(new Criteria() { @Override public boolean isSatisfied() { return mFakeWrapper.mMilliSeconds != -1; } - })); + }); assertEquals( "Did not get vibrate mMilliSeconds correctly", 3000, mFakeWrapper.mMilliSeconds); @@ -102,12 +102,12 @@ loadNewShell(URL_VIBRATOR_CANCEL); // Waits until VibrationManagerImpl.Cancel() got called. - assertTrue(CriteriaHelper.pollForUIThreadCriteria(new Criteria() { + CriteriaHelper.pollForUIThreadCriteria(new Criteria() { @Override public boolean isSatisfied() { return mFakeWrapper.mCancelled; } - })); + }); assertTrue("Did not get cancelled", mFakeWrapper.mCancelled); }
diff --git a/content/public/android/javatests/src/org/chromium/content/browser/input/AdapterInputConnectionTest.java b/content/public/android/javatests/src/org/chromium/content/browser/input/AdapterInputConnectionTest.java index 636129f..83fbf8eb 100644 --- a/content/public/android/javatests/src/org/chromium/content/browser/input/AdapterInputConnectionTest.java +++ b/content/public/android/javatests/src/org/chromium/content/browser/input/AdapterInputConnectionTest.java
@@ -31,7 +31,7 @@ public void setUp() throws Exception { super.setUp(); launchContentShellWithUrl("about:blank"); - assertTrue("Page failed to load", waitForActiveShellToBeDoneLoading()); + waitForActiveShellToBeDoneLoading(); mWrapper = new TestInputMethodManagerWrapper(getActivity()); mImeAdapter = new TestImeAdapter(mWrapper, new TestImeAdapterDelegate()); mConnection = new AdapterInputConnection(
diff --git a/content/public/android/javatests/src/org/chromium/content/browser/input/ImeTest.java b/content/public/android/javatests/src/org/chromium/content/browser/input/ImeTest.java index bbb1878..99686a4 100644 --- a/content/public/android/javatests/src/org/chromium/content/browser/input/ImeTest.java +++ b/content/public/android/javatests/src/org/chromium/content/browser/input/ImeTest.java
@@ -69,7 +69,7 @@ super.setUp(); launchContentShellWithUrl(DATA_URL); - assertTrue("Page failed to load", waitForActiveShellToBeDoneLoading()); + waitForActiveShellToBeDoneLoading(); mContentViewCore = getContentViewCore(); mWebContents = getWebContents(); @@ -82,8 +82,7 @@ mCallbackContainer = new TestCallbackHelperContainer(mContentViewCore); // TODO(aurimas) remove this wait once crbug.com/179511 is fixed. assertWaitForPageScaleFactorMatch(1); - assertTrue(DOMUtils.waitForNonZeroNodeBounds( - mWebContents, "input_text")); + DOMUtils.waitForNonZeroNodeBounds(mWebContents, "input_text"); DOMUtils.clickNode(this, mContentViewCore, "input_text"); assertWaitForKeyboardStatus(true); @@ -100,12 +99,17 @@ private void assertNoFurtherStateUpdate(final int index) throws InterruptedException { final List<TestImeState> states = mConnectionFactory.getImeStateList(); - assertFalse(CriteriaHelper.pollForUIThreadCriteria(new Criteria() { - @Override - public boolean isSatisfied() { - return states.size() > index; - } - })); + try { + CriteriaHelper.pollForUIThreadCriteria(new Criteria() { + @Override + public boolean isSatisfied() { + return states.size() > index; + } + }); + fail("Unexpected updates pending"); + } catch (AssertionError e) { + // TODO(tedchoc): This is horrible and should never timeout to determine success. + } } @MediumTest @@ -206,13 +210,14 @@ private void waitForKeyboardStates(int show, int hide, int restart, Integer[] history) throws InterruptedException { final String expected = stringifyKeyboardStates(show, hide, restart, history); - assertTrue("Expected: {" + expected + "}, Actual: {" + getKeyboardStates() + "}", - CriteriaHelper.pollForUIThreadCriteria(new Criteria() { - @Override - public boolean isSatisfied() { - return expected.equals(getKeyboardStates()); - } - })); + CriteriaHelper.pollForUIThreadCriteria(new Criteria() { + @Override + public boolean isSatisfied() { + updateFailureReason( + "Expected: {" + expected + "}, Actual: {" + getKeyboardStates() + "}"); + return expected.equals(getKeyboardStates()); + } + }); } private void resetAllStates() { @@ -329,12 +334,12 @@ // hide status of IME, so we will just check whether showIme() has been triggered. DOMUtils.longPressNode(this, mContentViewCore, "input_text"); final int newCount = showCount + 2; - assertTrue(CriteriaHelper.pollForUIThreadCriteria(new Criteria() { + CriteriaHelper.pollForUIThreadCriteria(new Criteria() { @Override public boolean isSatisfied() { return newCount == mInputMethodManagerWrapper.getShowSoftInputCounter(); } - })); + }); } private void attachPhysicalKeyboard() { @@ -390,13 +395,18 @@ detachPhysicalKeyboard(); - // We should not show soft keyboard here because focus has been lost. - assertFalse(CriteriaHelper.pollForUIThreadCriteria(new Criteria() { - @Override - public boolean isSatisfied() { - return mInputMethodManagerWrapper.isShowWithoutHideOutstanding(); - } - })); + try { + // We should not show soft keyboard here because focus has been lost. + CriteriaHelper.pollForUIThreadCriteria(new Criteria() { + @Override + public boolean isSatisfied() { + return mInputMethodManagerWrapper.isShowWithoutHideOutstanding(); + } + }); + fail("Keyboard incorrectly showing"); + } catch (AssertionError e) { + // TODO(tedchoc): This is horrible and should never timeout to determine success. + } } @SmallTest @@ -885,23 +895,23 @@ waitAndVerifyStatesAndCalls(2, "", 0, 0, -1, -1); DOMUtils.longPressNode(this, mContentViewCore, "input_text"); - assertTrue(CriteriaHelper.pollForUIThreadCriteria(new Criteria() { + CriteriaHelper.pollForUIThreadCriteria(new Criteria() { @Override public boolean isSatisfied() { return mContentViewCore.isPastePopupShowing(); } - })); + }); DOMUtils.clickNode(this, mContentViewCore, "input_text"); assertWaitForKeyboardStatus(true); DOMUtils.longPressNode(this, mContentViewCore, "input_text"); setComposingText("h", 1); - assertTrue(CriteriaHelper.pollForUIThreadCriteria(new Criteria() { + CriteriaHelper.pollForUIThreadCriteria(new Criteria() { @Override public boolean isSatisfied() { return !mContentViewCore.isPastePopupShowing(); } - })); + }); assertFalse(mContentViewCore.hasInsertion()); } @@ -965,36 +975,36 @@ } private void assertWaitForKeyboardStatus(final boolean show) throws InterruptedException { - assertTrue(CriteriaHelper.pollForUIThreadCriteria(new Criteria() { + CriteriaHelper.pollForUIThreadCriteria(new Criteria() { @Override public boolean isSatisfied() { boolean hasConnection = getAdapterInputConnection() != null; return show == mInputMethodManagerWrapper.isShowWithoutHideOutstanding() && show == hasConnection; } - })); + }); } private void assertWaitForSelectActionBarStatus( final boolean show) throws InterruptedException { - assertTrue(CriteriaHelper.pollForUIThreadCriteria(new Criteria() { + CriteriaHelper.pollForUIThreadCriteria(new Criteria() { @Override public boolean isSatisfied() { return show == mContentViewCore.isSelectActionBarShowing(); } - })); + }); } private void waitAndVerifyStates(final int index, String text, final int selectionStart, final int selectionEnd, final int compositionStart, final int compositionEnd) throws InterruptedException { final List<TestImeState> states = mConnectionFactory.getImeStateList(); - assertTrue(CriteriaHelper.pollForUIThreadCriteria(new Criteria() { + CriteriaHelper.pollForUIThreadCriteria(new Criteria() { @Override public boolean isSatisfied() { return states.size() > index; } - })); + }); states.get(index).assertEqualState( text, selectionStart, selectionEnd, compositionStart, compositionEnd); } @@ -1008,16 +1018,17 @@ // Wait and verify calls to InputMethodManager. final Range selection = new Range(selectionStart, selectionEnd); final Range composition = new Range(compositionStart, compositionEnd); - assertTrue("Actual selection was: " + mInputMethodManagerWrapper.getSelection() + CriteriaHelper.pollForUIThreadCriteria(new Criteria() { + @Override + public boolean isSatisfied() { + updateFailureReason( + "Actual selection was: " + mInputMethodManagerWrapper.getSelection() + ", and actual composition was: " - + mInputMethodManagerWrapper.getComposition(), - CriteriaHelper.pollForUIThreadCriteria(new Criteria() { - @Override - public boolean isSatisfied() { - return mInputMethodManagerWrapper.getSelection().equals(selection) - && mInputMethodManagerWrapper.getComposition().equals(composition); - } - })); + + mInputMethodManagerWrapper.getComposition()); + return mInputMethodManagerWrapper.getSelection().equals(selection) + && mInputMethodManagerWrapper.getComposition().equals(composition); + } + }); } private void resetUpdateStateList() { @@ -1038,7 +1049,7 @@ private void assertClipboardContents(final Activity activity, final String expectedContents) throws InterruptedException { - assertTrue(CriteriaHelper.pollForUIThreadCriteria(new Criteria() { + CriteriaHelper.pollForUIThreadCriteria(new Criteria() { @Override public boolean isSatisfied() { ClipboardManager clipboardManager = @@ -1047,7 +1058,7 @@ return clip != null && clip.getItemCount() == 1 && TextUtils.equals(clip.getItemAt(0).getText(), expectedContents); } - })); + }); } private ImeAdapter getImeAdapter() { @@ -1196,7 +1207,7 @@ throws InterruptedException, TimeoutException { DOMUtils.focusNode(mWebContents, id); assertWaitForKeyboardStatus(shouldShowKeyboard); - assertTrue(CriteriaHelper.pollForCriteria(new Criteria() { + CriteriaHelper.pollForCriteria(new Criteria() { @Override public boolean isSatisfied() { try { @@ -1205,7 +1216,7 @@ return false; } } - })); + }); // When we focus another element, the connection may be recreated. mConnection = (TestAdapterInputConnection) getAdapterInputConnection(); }
diff --git a/content/public/android/javatests/src/org/chromium/content/browser/input/SelectPopupTest.java b/content/public/android/javatests/src/org/chromium/content/browser/input/SelectPopupTest.java index 4142437c..3994efe 100644 --- a/content/public/android/javatests/src/org/chromium/content/browser/input/SelectPopupTest.java +++ b/content/public/android/javatests/src/org/chromium/content/browser/input/SelectPopupTest.java
@@ -40,14 +40,22 @@ + "</select>" + "</body></html>"); - private class PopupShowingCriteria implements Criteria { + private class PopupShowingCriteria extends Criteria { + public PopupShowingCriteria() { + super("The select popup is not showing as expected."); + } + @Override public boolean isSatisfied() { return getContentViewCore().getSelectPopupForTest() != null; } } - private class PopupHiddenCriteria implements Criteria { + private class PopupHiddenCriteria extends Criteria { + public PopupHiddenCriteria() { + super("The select popup is not hidden as expected."); + } + @Override public boolean isSatisfied() { return getContentViewCore().getSelectPopupForTest() == null; @@ -58,7 +66,7 @@ public void setUp() throws Exception { super.setUp(); launchContentShellWithUrl(SELECT_URL); - assertTrue("Page failed to load", waitForActiveShellToBeDoneLoading()); + waitForActiveShellToBeDoneLoading(); // TODO(aurimas) remove this wait once crbug.com/179511 is fixed. assertWaitForPageScaleFactorMatch(1); } @@ -72,8 +80,7 @@ @RerunWithUpdatedContainerView public void testReloadWhilePopupShowing() throws InterruptedException, Exception, Throwable { // The popup should be hidden before the click. - assertTrue("The select popup is shown after load.", - CriteriaHelper.pollForCriteria(new PopupHiddenCriteria())); + CriteriaHelper.pollForCriteria(new PopupHiddenCriteria()); final ContentViewCore viewCore = getContentViewCore(); final TestCallbackHelperContainer viewClient = new TestCallbackHelperContainer(viewCore); @@ -81,8 +88,7 @@ // Once clicked, the popup should show up. DOMUtils.clickNode(this, viewCore, "select"); - assertTrue("The select popup did not show up on click.", - CriteriaHelper.pollForCriteria(new PopupShowingCriteria())); + CriteriaHelper.pollForCriteria(new PopupShowingCriteria()); // Reload the test page. int currentCallCount = onPageFinishedHelper.getCallCount(); @@ -97,12 +103,10 @@ WAIT_TIMEOUT_SECONDS, TimeUnit.SECONDS); // The popup should be hidden after the page reload. - assertTrue("The select popup did not hide after reload.", - CriteriaHelper.pollForCriteria(new PopupHiddenCriteria())); + CriteriaHelper.pollForCriteria(new PopupHiddenCriteria()); // Click the select and wait for the popup to show. DOMUtils.clickNode(this, viewCore, "select"); - assertTrue("The select popup did not show on click after reload.", - CriteriaHelper.pollForCriteria(new PopupShowingCriteria())); + CriteriaHelper.pollForCriteria(new PopupShowingCriteria()); } }
diff --git a/content/public/android/javatests/src/org/chromium/content/common/CleanupReferenceTest.java b/content/public/android/javatests/src/org/chromium/content/common/CleanupReferenceTest.java index 602d2f6..29a9060 100644 --- a/content/public/android/javatests/src/org/chromium/content/common/CleanupReferenceTest.java +++ b/content/public/android/javatests/src/org/chromium/content/common/CleanupReferenceTest.java
@@ -66,12 +66,12 @@ // Ensure compiler / instrumentation does not strip out the assignment. assertTrue(instance == null); collectGarbage(); - assertTrue(CriteriaHelper.pollForCriteria(new Criteria() { + CriteriaHelper.pollForCriteria(new Criteria() { @Override public boolean isSatisfied() { return sObjectCount.get() == 0; } - })); + }); } @SuppressFBWarnings("UC_USELESS_OBJECT") @@ -95,12 +95,12 @@ // to be GC'ed only when building using GN. assertTrue(sObjectCount.get() != -1); collectGarbage(); - assertTrue(CriteriaHelper.pollForCriteria(new Criteria() { + CriteriaHelper.pollForCriteria(new Criteria() { @Override public boolean isSatisfied() { return sObjectCount.get() == 0; } - })); + }); } }
diff --git a/content/public/browser/android/content_view_core.h b/content/public/browser/android/content_view_core.h index e904036..5f487f8a 100644 --- a/content/public/browser/android/content_view_core.h +++ b/content/public/browser/android/content_view_core.h
@@ -48,7 +48,7 @@ virtual ui::ViewAndroid* GetViewAndroid() const = 0; virtual ui::WindowAndroid* GetWindowAndroid() const = 0; virtual const scoped_refptr<cc::Layer>& GetLayer() const = 0; - virtual void ShowPastePopup(int x, int y) = 0; + virtual bool ShowPastePopup(int x, int y) = 0; // Request a scaled content readback. The result is passed through the // callback. The boolean parameter indicates whether the readback was a
diff --git a/content/public/common/common_param_traits_macros.h b/content/public/common/common_param_traits_macros.h index 48ba994a..f71d867 100644 --- a/content/public/common/common_param_traits_macros.h +++ b/content/public/common/common_param_traits_macros.h
@@ -138,9 +138,6 @@ IPC_STRUCT_TRAITS_MEMBER(application_cache_enabled) IPC_STRUCT_TRAITS_MEMBER(tabs_to_links) IPC_STRUCT_TRAITS_MEMBER(hyperlink_auditing_enabled) - IPC_STRUCT_TRAITS_MEMBER(is_online) - IPC_STRUCT_TRAITS_MEMBER(net_info_connection_type) - IPC_STRUCT_TRAITS_MEMBER(net_info_max_bandwidth_mbps) IPC_STRUCT_TRAITS_MEMBER(allow_universal_access_from_file_urls) IPC_STRUCT_TRAITS_MEMBER(allow_file_access_from_file_urls) IPC_STRUCT_TRAITS_MEMBER(webaudio_enabled) @@ -155,7 +152,6 @@ IPC_STRUCT_TRAITS_MEMBER(privileged_webgl_extensions_enabled) IPC_STRUCT_TRAITS_MEMBER(webgl_errors_to_console_enabled) IPC_STRUCT_TRAITS_MEMBER(mock_scrollbars_enabled) - IPC_STRUCT_TRAITS_MEMBER(asynchronous_spell_checking_enabled) IPC_STRUCT_TRAITS_MEMBER(unified_textchecker_enabled) IPC_STRUCT_TRAITS_MEMBER(accelerated_2d_canvas_enabled) IPC_STRUCT_TRAITS_MEMBER(minimum_accelerated_2d_canvas_size)
diff --git a/content/public/common/content_switches.cc b/content/public/common/content_switches.cc index 35708aea..0077b5f 100644 --- a/content/public/common/content_switches.cc +++ b/content/public/common/content_switches.cc
@@ -405,9 +405,6 @@ // also applys to workers. const char kEnablePreciseMemoryInfo[] = "enable-precise-memory-info"; -// Enables payloads for received push messages when using the W3C Push API. -const char kEnablePushMessagePayload[] = "enable-push-message-payload"; - // Enables RGBA_4444 textures. const char kEnableRGBA4444Textures[] = "enable-rgba-4444-textures";
diff --git a/content/public/common/content_switches.h b/content/public/common/content_switches.h index 2533f42a..987ef41 100644 --- a/content/public/common/content_switches.h +++ b/content/public/common/content_switches.h
@@ -124,7 +124,6 @@ CONTENT_EXPORT extern const char kEnablePinch[]; CONTENT_EXPORT extern const char kEnablePluginPlaceholderTesting[]; CONTENT_EXPORT extern const char kEnablePreciseMemoryInfo[]; -CONTENT_EXPORT extern const char kEnablePushMessagePayload[]; CONTENT_EXPORT extern const char kEnableRGBA4444Textures[]; CONTENT_EXPORT extern const char kEnableSandboxLogging[]; extern const char kEnableSkiaBenchmarking[];
diff --git a/content/public/common/web_preferences.cc b/content/public/common/web_preferences.cc index c6023b4d..a86de33b 100644 --- a/content/public/common/web_preferences.cc +++ b/content/public/common/web_preferences.cc
@@ -96,11 +96,6 @@ tabs_to_links(true), caret_browsing_enabled(false), hyperlink_auditing_enabled(true), - is_online(true), - net_info_connection_type(net::NetworkChangeNotifier::CONNECTION_NONE), - net_info_max_bandwidth_mbps( - net::NetworkChangeNotifier::GetMaxBandwidthForConnectionSubtype( - net::NetworkChangeNotifier::SUBTYPE_NONE)), allow_universal_access_from_file_urls(false), allow_file_access_from_file_urls(false), webaudio_enabled(false), @@ -113,7 +108,6 @@ privileged_webgl_extensions_enabled(false), webgl_errors_to_console_enabled(true), mock_scrollbars_enabled(false), - asynchronous_spell_checking_enabled(true), unified_textchecker_enabled(false), accelerated_2d_canvas_enabled(false), minimum_accelerated_2d_canvas_size(257 * 256),
diff --git a/content/public/common/web_preferences.h b/content/public/common/web_preferences.h index 0378cd7..eb8f77e 100644 --- a/content/public/common/web_preferences.h +++ b/content/public/common/web_preferences.h
@@ -11,7 +11,6 @@ #include "base/strings/string16.h" #include "content/common/content_export.h" -#include "net/base/network_change_notifier.h" #include "ui/base/touch/touch_device.h" #include "url/gurl.h" @@ -102,9 +101,6 @@ bool tabs_to_links; bool caret_browsing_enabled; bool hyperlink_auditing_enabled; - bool is_online; - net::NetworkChangeNotifier::ConnectionType net_info_connection_type; - double net_info_max_bandwidth_mbps; bool allow_universal_access_from_file_urls; bool allow_file_access_from_file_urls; bool webaudio_enabled; @@ -117,7 +113,6 @@ bool privileged_webgl_extensions_enabled; bool webgl_errors_to_console_enabled; bool mock_scrollbars_enabled; - bool asynchronous_spell_checking_enabled; bool unified_textchecker_enabled; bool accelerated_2d_canvas_enabled; int minimum_accelerated_2d_canvas_size;
diff --git a/content/public/renderer/render_frame.h b/content/public/renderer/render_frame.h index 82caa92..2011c4e6 100644 --- a/content/public/renderer/render_frame.h +++ b/content/public/renderer/render_frame.h
@@ -189,6 +189,9 @@ // Whether or not this frame is using Lo-Fi. virtual bool IsUsingLoFi() const = 0; + // Whether or not this frame is currently pasting. + virtual bool IsPasting() const = 0; + protected: ~RenderFrame() override {}
diff --git a/content/public/renderer/render_view.h b/content/public/renderer/render_view.h index dcf1de4..1f0a235 100644 --- a/content/public/renderer/render_view.h +++ b/content/public/renderer/render_view.h
@@ -24,6 +24,7 @@ class WebURLRequest; class WebView; struct WebContextMenuData; +struct WebRect; } namespace gfx { @@ -123,6 +124,13 @@ bool animate) = 0; #endif + // Converts the |rect| from Blink's Viewport coordinates to the + // coordinates in the native window used to display the content, in + // DIP. They're identical in tradional world, but will differ when + // use-zoom-for-dsf feature is eanbled, and Viewport coordinates + // becomes DSF times larger than window coordinates. + virtual void convertViewportToWindow(blink::WebRect* rect) = 0; + protected: ~RenderView() override {}
diff --git a/content/public/test/android/javatests/src/org/chromium/content/browser/test/NativeLibraryTestBase.java b/content/public/test/android/javatests/src/org/chromium/content/browser/test/NativeLibraryTestBase.java index 86cc0ec..b4528ed 100644 --- a/content/public/test/android/javatests/src/org/chromium/content/browser/test/NativeLibraryTestBase.java +++ b/content/public/test/android/javatests/src/org/chromium/content/browser/test/NativeLibraryTestBase.java
@@ -36,7 +36,7 @@ assertFalse(ThreadUtils.runningOnUiThread()); try { - assertTrue(ApplicationUtils.waitForLibraryDependencies(getInstrumentation())); + ApplicationUtils.waitForLibraryDependencies(getInstrumentation()); } catch (InterruptedException e) { fail("Library dependencies were never initialized."); }
diff --git a/content/public/test/android/javatests/src/org/chromium/content/browser/test/util/ApplicationUtils.java b/content/public/test/android/javatests/src/org/chromium/content/browser/test/util/ApplicationUtils.java index aec69b0..2366bbd 100644 --- a/content/public/test/android/javatests/src/org/chromium/content/browser/test/util/ApplicationUtils.java +++ b/content/public/test/android/javatests/src/org/chromium/content/browser/test/util/ApplicationUtils.java
@@ -19,11 +19,10 @@ * instrumented. * * @param instrumentation The test instrumentation. - * @return Whether the library dependencies were initialized. */ - public static boolean waitForLibraryDependencies(final Instrumentation instrumentation) + public static void waitForLibraryDependencies(final Instrumentation instrumentation) throws InterruptedException { - return CriteriaHelper.pollForUIThreadCriteria(new Criteria() { + CriteriaHelper.pollForUIThreadCriteria(new Criteria() { @Override public boolean isSatisfied() { Context context = instrumentation.getTargetContext();
diff --git a/content/public/test/android/javatests/src/org/chromium/content/browser/test/util/Criteria.java b/content/public/test/android/javatests/src/org/chromium/content/browser/test/util/Criteria.java index b7349aac..871441c 100644 --- a/content/public/test/android/javatests/src/org/chromium/content/browser/test/util/Criteria.java +++ b/content/public/test/android/javatests/src/org/chromium/content/browser/test/util/Criteria.java
@@ -6,12 +6,50 @@ /** * Provides a means for validating whether some condition/criteria has been met. + * <p> + * See {@link CriteriaHelper} for usage guidelines. */ -public interface Criteria { +public abstract class Criteria { + + private String mFailureReason; + + /** + * Constructs a Criteria with a default failure message. + */ + public Criteria() { + this("Criteria not met in allotted time."); + } + + /** + * Constructs a Criteria with an explicit message to be shown on failure. + * @param failureReason The failure reason to be shown. + */ + public Criteria(String failureReason) { + mFailureReason = failureReason; + } /** * @return Whether the criteria this is testing has been satisfied. */ - public boolean isSatisfied(); + public abstract boolean isSatisfied(); + + /** + * @return The failure message that will be logged if the criteria is not satisfied within + * the specified time range. + */ + public final String getFailureReason() { + return mFailureReason; + } + + /** + * Updates the message to displayed if this criteria does not succeed in the alloted time. For + * correctness, you should be updating this in {@link #isSatisfied()} to ensure the error state + * is the same that you last checked. + * + * @param reason The failure reason to be shown. + */ + public void updateFailureReason(String reason) { + mFailureReason = reason; + } }
diff --git a/content/public/test/android/javatests/src/org/chromium/content/browser/test/util/CriteriaHelper.java b/content/public/test/android/javatests/src/org/chromium/content/browser/test/util/CriteriaHelper.java index 3316c7b..2b08359 100644 --- a/content/public/test/android/javatests/src/org/chromium/content/browser/test/util/CriteriaHelper.java +++ b/content/public/test/android/javatests/src/org/chromium/content/browser/test/util/CriteriaHelper.java
@@ -8,6 +8,8 @@ import android.os.SystemClock; +import junit.framework.Assert; + import org.chromium.base.ThreadUtils; import java.util.concurrent.Callable; @@ -19,6 +21,23 @@ * If possible, use callbacks or testing delegates instead of criteria as they * do not introduce any polling delays. Should only use Criteria if no suitable * other approach exists. + * + * <p> + * <pre> + * Sample Usage: + * <code> + * public void waitForTabTitle(final Tab tab, final String title) { + * CriteriaHelper.pollForUIThreadCriteria(new Criteria() { + * {@literal @}Override + * public boolean isSatisified() { + * updateFailureReason("Tab title did not match -- expected: " + title + * + ", actual: " + tab.getTitle()); + * return TextUtils.equals(tab.getTitle(), title); + * } + * }); + * } + * </code> + * </pre> */ public class CriteriaHelper { @@ -34,10 +53,9 @@ * @param maxTimeoutMs The maximum number of ms that this check will be performed for * before timeout. * @param checkIntervalMs The number of ms between checks. - * @return true iff checking has ended with the criteria being satisfied. * @throws InterruptedException */ - public static boolean pollForCriteria(Criteria criteria, long maxTimeoutMs, + public static void pollForCriteria(Criteria criteria, long maxTimeoutMs, long checkIntervalMs) throws InterruptedException { boolean isSatisfied = criteria.isSatisfied(); long startTime = SystemClock.uptimeMillis(); @@ -45,19 +63,18 @@ Thread.sleep(checkIntervalMs); isSatisfied = criteria.isSatisfied(); } - return isSatisfied; + Assert.assertTrue(criteria.getFailureReason(), isSatisfied); } /** * Checks whether the given Criteria is satisfied polling at a default interval. * * @param criteria The Criteria that will be checked. - * @return iff checking has ended with the criteria being satisfied. * @throws InterruptedException * @see #pollForCriteria(Criteria, long, long) */ - public static boolean pollForCriteria(Criteria criteria) throws InterruptedException { - return pollForCriteria(criteria, DEFAULT_MAX_TIME_TO_POLL, DEFAULT_POLLING_INTERVAL); + public static void pollForCriteria(Criteria criteria) throws InterruptedException { + pollForCriteria(criteria, DEFAULT_MAX_TIME_TO_POLL, DEFAULT_POLLING_INTERVAL); } /** @@ -68,11 +85,10 @@ * @param maxTimeoutMs The maximum number of ms that this check will be performed for * before timeout. * @param checkIntervalMs The number of ms between checks. - * @return iff checking has ended with the criteria being satisfied. * @throws InterruptedException * @see #pollForCriteria(Criteria) */ - public static boolean pollForUIThreadCriteria(final Criteria criteria, long maxTimeoutMs, + public static void pollForUIThreadCriteria(final Criteria criteria, long maxTimeoutMs, long checkIntervalMs) throws InterruptedException { final Callable<Boolean> callable = new Callable<Boolean>() { @Override @@ -81,7 +97,7 @@ } }; - return pollForCriteria(new Criteria() { + pollForCriteria(new Criteria() { @Override public boolean isSatisfied() { return ThreadUtils.runOnUiThreadBlockingNoException(callable); @@ -93,30 +109,11 @@ * Checks whether the given Criteria is satisfied polling at a default interval on the UI * thread. * @param criteria The Criteria that will be checked. - * @return iff checking has ended with the criteria being satisfied. * @throws InterruptedException * @see #pollForCriteria(Criteria) */ - public static boolean pollForUIThreadCriteria(final Criteria criteria) + public static void pollForUIThreadCriteria(final Criteria criteria) throws InterruptedException { - return pollForUIThreadCriteria(criteria, DEFAULT_MAX_TIME_TO_POLL, - DEFAULT_POLLING_INTERVAL); - } - - /** - * Performs the runnable action, then checks whether the given criteria are satisfied - * until the specified timeout, using the pollForCriteria method. If not, then the runnable - * action is performed again, to a maximum of maxAttempts tries. - */ - public static boolean runUntilCriteria(Runnable runnable, Criteria criteria, - int maxAttempts, long maxTimeoutMs, long checkIntervalMs) throws InterruptedException { - int count = 0; - boolean success = false; - while (count < maxAttempts && !success) { - count++; - runnable.run(); - success = pollForCriteria(criteria, maxTimeoutMs, checkIntervalMs); - } - return success; + pollForUIThreadCriteria(criteria, DEFAULT_MAX_TIME_TO_POLL, DEFAULT_POLLING_INTERVAL); } }
diff --git a/content/public/test/android/javatests/src/org/chromium/content/browser/test/util/DOMUtils.java b/content/public/test/android/javatests/src/org/chromium/content/browser/test/util/DOMUtils.java index ebd34a7..53891d7 100644 --- a/content/public/test/android/javatests/src/org/chromium/content/browser/test/util/DOMUtils.java +++ b/content/public/test/android/javatests/src/org/chromium/content/browser/test/util/DOMUtils.java
@@ -68,11 +68,10 @@ * Waits until the playback of the media with given {@code id} has started. * @param webContents The WebContents in which the media element lives. * @param id The element's id to check. - * @return Whether the playback has started. */ - public static boolean waitForMediaPlay(final WebContents webContents, final String id) + public static void waitForMediaPlay(final WebContents webContents, final String id) throws InterruptedException { - return CriteriaHelper.pollForCriteria(new Criteria() { + CriteriaHelper.pollForCriteria(new Criteria() { @Override public boolean isSatisfied() { try { @@ -92,11 +91,10 @@ * Waits until the playback of the media with given {@code id} has stopped. * @param webContents The WebContents in which the media element lives. * @param id The element's id to check. - * @return Whether the playback has paused. */ - public static boolean waitForMediaPause(final WebContents webContents, final String id) + public static void waitForMediaPause(final WebContents webContents, final String id) throws InterruptedException { - return CriteriaHelper.pollForCriteria(new Criteria() { + CriteriaHelper.pollForCriteria(new Criteria() { @Override public boolean isSatisfied() { try { @@ -308,12 +306,11 @@ * Wait until a given node has non-zero bounds. * @param webContents The WebContents in which the node lives. * @param nodeId The id of the node. - * @return Whether the node started having non-zero bounds. */ - public static boolean waitForNonZeroNodeBounds(final WebContents webContents, + public static void waitForNonZeroNodeBounds(final WebContents webContents, final String nodeId) throws InterruptedException { - return CriteriaHelper.pollForCriteria(new Criteria() { + CriteriaHelper.pollForCriteria(new Criteria() { @Override public boolean isSatisfied() { try {
diff --git a/content/public/test/android/javatests/src/org/chromium/content/browser/test/util/OrientationChangeObserverCriteria.java b/content/public/test/android/javatests/src/org/chromium/content/browser/test/util/OrientationChangeObserverCriteria.java index 18ceeebd..9ef5aa84 100644 --- a/content/public/test/android/javatests/src/org/chromium/content/browser/test/util/OrientationChangeObserverCriteria.java +++ b/content/public/test/android/javatests/src/org/chromium/content/browser/test/util/OrientationChangeObserverCriteria.java
@@ -7,7 +7,7 @@ /** * Criteria used to know when an orientation change happens. */ -public class OrientationChangeObserverCriteria implements Criteria { +public class OrientationChangeObserverCriteria extends Criteria { private final MockOrientationObserver mObserver; private final int mTarget;
diff --git a/content/public/test/browser_test_base.h b/content/public/test/browser_test_base.h index 781d836..23abda8d 100644 --- a/content/public/test/browser_test_base.h +++ b/content/public/test/browser_test_base.h
@@ -81,13 +81,6 @@ // Sets expected browser exit code, in case it's different than 0 (success). void set_expected_exit_code(int code) { expected_exit_code_ = code; } - // Returns the testing server. Guaranteed to be non-NULL. - // TODO(phajdan.jr): Remove test_server accessor (http://crbug.com/96594). - const net::SpawnedTestServer* test_server() const { - return spawned_test_server_.get(); - } - net::SpawnedTestServer* test_server() { return spawned_test_server_.get(); } - const net::SpawnedTestServer* spawned_test_server() const { return spawned_test_server_.get(); }
diff --git a/content/public/test/test_download_request_handler.cc b/content/public/test/test_download_request_handler.cc new file mode 100644 index 0000000..1c89e0e --- /dev/null +++ b/content/public/test/test_download_request_handler.cc
@@ -0,0 +1,671 @@ +// 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. + +#include "content/public/test/test_download_request_handler.h" + +#include <inttypes.h> + +#include "base/logging.h" +#include "base/memory/weak_ptr.h" +#include "base/run_loop.h" +#include "base/sequenced_task_runner.h" +#include "base/strings/stringprintf.h" +#include "base/threading/sequenced_task_runner_handle.h" +#include "content/public/browser/browser_thread.h" +#include "net/base/io_buffer.h" +#include "net/http/http_request_headers.h" +#include "net/http/http_response_headers.h" +#include "net/url_request/url_request_filter.h" +#include "net/url_request/url_request_interceptor.h" + +namespace content { + +// Intercepts URLRequests on behalf of TestDownloadRequestHandler. Necessarily +// lives on the IO thread since that's where net::URLRequestFilter invokes the +// URLRequestInterceptor. +class TestDownloadRequestHandler::Interceptor + : public net::URLRequestInterceptor { + public: + // Invoked on the IO thread to register a URLRequestInterceptor for |url|. + // Returns an IO-thread bound weak pointer for interacting with the + // interceptor. + static base::WeakPtr<Interceptor> Register( + const GURL& url, + scoped_refptr<base::SequencedTaskRunner> client_task_runner); + + using JobFactory = + base::Callback<net::URLRequestJob*(net::URLRequest*, + net::NetworkDelegate*, + base::WeakPtr<Interceptor>)>; + + ~Interceptor() override; + + // Unregisters the URLRequestInterceptor. In reality it unregisters whatever + // was registered to intercept |url_|. Since |this| is owned by + // net::URLRequestFilter, unregistering the interceptor deletes |this| as a + // side-effect. + void Unregister(); + + // Change the URLRequestJob factory. Can be called multiple times. + void SetJobFactory(const JobFactory& factory); + + // Sets |requests| to the vector of completed requests and clears the internal + // list. The returned requests are stored in the order in which they were + // reported as being complete (not necessarily the order in which they were + // received). + void GetAndResetCompletedRequests( + TestDownloadRequestHandler::CompletedRequests* requests); + + // Can be called by a URLRequestJob to notify this interceptor of a completed + // request. + void AddCompletedRequest( + const TestDownloadRequestHandler::CompletedRequest& request); + + // Returns the task runner that should be used for invoking any client + // supplied callbacks. + scoped_refptr<base::SequencedTaskRunner> GetClientTaskRunner(); + + private: + Interceptor(const GURL& url, + scoped_refptr<base::SequencedTaskRunner> client_task_runner); + + // net::URLRequestInterceptor + net::URLRequestJob* MaybeInterceptRequest( + net::URLRequest* request, + net::NetworkDelegate* network_delegate) const override; + + TestDownloadRequestHandler::CompletedRequests completed_requests_; + GURL url_; + JobFactory job_factory_; + scoped_refptr<base::SequencedTaskRunner> client_task_runner_; + + // mutable because MaybeInterceptRequest() is inexplicably const. + mutable base::WeakPtrFactory<Interceptor> weak_ptr_factory_; + DISALLOW_COPY_AND_ASSIGN(Interceptor); +}; + +// A URLRequestJob that constructs a response to a URLRequest based on the +// contents of a Parameters object. It can handle partial (i.e. byte range +// requests). Created on and lives on the IO thread. +class TestDownloadRequestHandler::PartialResponseJob + : public net::URLRequestJob { + public: + static net::URLRequestJob* Factory(const Parameters& parameters, + net::URLRequest* request, + net::NetworkDelegate* delegate, + base::WeakPtr<Interceptor> interceptor); + + // URLRequestJob + void Start() override; + void GetResponseInfo(net::HttpResponseInfo* response_info) override; + int64 GetTotalReceivedBytes() const override; + bool GetMimeType(std::string* mime_type) const override; + int GetResponseCode() const override; + int ReadRawData(net::IOBuffer* buf, int buf_size) override; + + private: + PartialResponseJob(scoped_ptr<Parameters> parameters, + base::WeakPtr<Interceptor> interceptor, + net::URLRequest* url_request, + net::NetworkDelegate* network_delegate); + + ~PartialResponseJob() override; + void ReportCompletedRequest(int64_t transferred_byte_count); + static void OnStartResponseCallbackOnPossiblyIncorrectThread( + base::WeakPtr<PartialResponseJob> job, + const std::string& headers, + net::Error error); + void OnStartResponseCallback(const std::string& headers, net::Error error); + + // In general, the Parameters object can specify an explicit OnStart handler. + // In its absence or if the explicit OnStart handler requests the default + // behavior, this method can be invoked to respond to the request based on the + // remaining Parameters fields (as if there was no OnStart handler). + void HandleOnStartDefault(); + + // Respond Start() assuming that any If-Match or If-Range headers have been + // successfully validated. This handler assumes that there *must* be a Range + // header even though the spec doesn't strictly require it for If-Match. + bool HandleRangeAssumingValidatorMatch(); + + // Adds headers that describe the entity (Content-Type, ETag, Last-Modified). + // It also adds an 'Accept-Ranges' header if appropriate. + void AddCommonEntityHeaders(); + + // Schedules NotifyHeadersComplete() to be called and sets + // offset_of_next_read_ to begin reading. Since this interceptor is avoiding + // network requests and hence may complete synchronously, it schedules the + // NotifyHeadersComplete() call asynchronously in order to avoid unexpected + // re-entrancy. + void NotifyHeadersCompleteAndPrepareToRead(); + + scoped_ptr<Parameters> parameters_; + + base::WeakPtr<Interceptor> interceptor_; + net::HttpResponseInfo response_info_; + int64_t offset_of_next_read_ = -1; + int64_t requested_range_begin_ = -1; + int64_t requested_range_end_ = -1; + base::WeakPtrFactory<PartialResponseJob> weak_factory_; + + DISALLOW_COPY_AND_ASSIGN(PartialResponseJob); +}; + +namespace { + +template <class T> +void StoreValueAndInvokeClosure(const base::Closure& closure, + T* value_receiver, + T value) { + *value_receiver = value; + closure.Run(); +} + +// Xorshift* PRNG from https://en.wikipedia.org/wiki/Xorshift +uint64_t XorShift64StarWithIndex(uint64_t seed, uint64_t index) { + const uint64_t kMultiplier = UINT64_C(2685821657736338717); + uint64_t x = seed * kMultiplier + index; + x ^= x >> 12; + x ^= x << 25; + x ^= x >> 27; + return x * kMultiplier; +} + +void RespondToOnStartedCallbackWithStaticHeaders( + const std::string& headers, + const net::HttpRequestHeaders&, + const TestDownloadRequestHandler::OnStartResponseCallback& callback) { + callback.Run(headers, net::OK); +} + +GURL GetNextURLForDownloadInterceptor() { + static int index = 0; + std::string url_string = + base::StringPrintf("https://%d.default.example.com/download/", ++index); + return GURL(url_string); +} + +scoped_refptr<net::HttpResponseHeaders> HeadersFromString( + const std::string& headers_string) { + scoped_refptr<net::HttpResponseHeaders> headers = + new net::HttpResponseHeaders(net::HttpUtil::AssembleRawHeaders( + headers_string.c_str(), headers_string.size())); + return headers; +} + +} // namespace + +// static +net::URLRequestJob* TestDownloadRequestHandler::PartialResponseJob::Factory( + const Parameters& parameters, + net::URLRequest* request, + net::NetworkDelegate* delegate, + base::WeakPtr<Interceptor> interceptor) { + return new PartialResponseJob(make_scoped_ptr(new Parameters(parameters)), + interceptor, request, delegate); +} + +TestDownloadRequestHandler::PartialResponseJob::PartialResponseJob( + scoped_ptr<Parameters> parameters, + base::WeakPtr<Interceptor> interceptor, + net::URLRequest* request, + net::NetworkDelegate* network_delegate) + : net::URLRequestJob(request, network_delegate), + parameters_(parameters.Pass()), + interceptor_(interceptor), + weak_factory_(this) { + DCHECK(parameters_.get()); + DCHECK_LT(0, parameters_->size); + DCHECK_NE(-1, parameters_->pattern_generator_seed); +} + +TestDownloadRequestHandler::PartialResponseJob::~PartialResponseJob() {} + +void TestDownloadRequestHandler::PartialResponseJob::Start() { + DCHECK_CURRENTLY_ON(BrowserThread::IO); + DVLOG(1) << "Starting request for " << request()->url().spec(); + + if (parameters_->on_start_handler.is_null() || !interceptor_.get()) { + HandleOnStartDefault(); + return; + } + + DVLOG(1) << "Invoking custom OnStart handler."; + interceptor_->GetClientTaskRunner()->PostTask( + FROM_HERE, + base::Bind( + parameters_->on_start_handler, request()->extra_request_headers(), + base::Bind(&PartialResponseJob:: + OnStartResponseCallbackOnPossiblyIncorrectThread, + weak_factory_.GetWeakPtr()))); +} + +void TestDownloadRequestHandler::PartialResponseJob::GetResponseInfo( + net::HttpResponseInfo* response_info) { + *response_info = response_info_; +} + +int64 TestDownloadRequestHandler::PartialResponseJob::GetTotalReceivedBytes() + const { + return offset_of_next_read_ - requested_range_begin_; +} + +bool TestDownloadRequestHandler::PartialResponseJob::GetMimeType( + std::string* mime_type) const { + *mime_type = parameters_->content_type; + return !parameters_->content_type.empty(); +} + +int TestDownloadRequestHandler::PartialResponseJob::GetResponseCode() const { + return response_info_.headers.get() ? response_info_.headers->response_code() + : 0; +} + +int TestDownloadRequestHandler::PartialResponseJob::ReadRawData( + net::IOBuffer* buf, + int buf_size) { + DVLOG(1) << "Preparing to read " << buf_size << " bytes"; + + // requested_range_begin_ == -1 implies that the body was empty. + if (offset_of_next_read_ > requested_range_end_ || + requested_range_begin_ == -1) { + ReportCompletedRequest(requested_range_end_ - requested_range_begin_ + 1); + DVLOG(1) << "Done reading."; + return 0; + } + + int64_t range_end = + std::min(requested_range_end_, offset_of_next_read_ + buf_size - 1); + + if (!parameters_->injected_errors.empty()) { + const InjectedError& injected_error = parameters_->injected_errors.front(); + + if (offset_of_next_read_ == injected_error.offset) { + int error = injected_error.error; + SetStatus(net::URLRequestStatus(net::URLRequestStatus::FAILED, error)); + DVLOG(1) << "Returning error " << net::ErrorToString(error); + ReportCompletedRequest(injected_error.offset - requested_range_begin_); + parameters_->injected_errors.pop(); + return error; + } + + if (offset_of_next_read_ < injected_error.offset && + injected_error.offset <= range_end) + range_end = injected_error.offset - 1; + } + int bytes_to_copy = (range_end - offset_of_next_read_) + 1; + + TestDownloadRequestHandler::GetPatternBytes( + parameters_->pattern_generator_seed, offset_of_next_read_, bytes_to_copy, + buf->data()); + DVLOG(1) << "Read " << bytes_to_copy << " bytes at offset " + << offset_of_next_read_; + offset_of_next_read_ += bytes_to_copy; + return bytes_to_copy; +} + +void TestDownloadRequestHandler::PartialResponseJob::ReportCompletedRequest( + int64_t transferred_byte_count) { + if (interceptor_.get()) { + TestDownloadRequestHandler::CompletedRequest completed_request; + completed_request.transferred_byte_count = transferred_byte_count; + completed_request.request_headers = request()->extra_request_headers(); + interceptor_->AddCompletedRequest(completed_request); + } +} + +// static +void TestDownloadRequestHandler::PartialResponseJob:: + OnStartResponseCallbackOnPossiblyIncorrectThread( + base::WeakPtr<PartialResponseJob> job, + const std::string& headers, + net::Error error) { + BrowserThread::PostTask( + BrowserThread::IO, FROM_HERE, + base::Bind(&PartialResponseJob::OnStartResponseCallback, job, headers, + error)); +} + +void TestDownloadRequestHandler::PartialResponseJob::OnStartResponseCallback( + const std::string& headers, + net::Error error) { + DVLOG(1) << "OnStartResponse invoked with error:" << error + << " and headers:" << std::endl + << headers; + DCHECK_CURRENTLY_ON(BrowserThread::IO); + if (headers.empty() && error == net::OK) { + HandleOnStartDefault(); + return; + } + + if (error != net::OK) { + NotifyStartError(net::URLRequestStatus::FromError(error)); + return; + } + + response_info_.headers = new net::HttpResponseHeaders( + net::HttpUtil::AssembleRawHeaders(headers.c_str(), headers.size())); + NotifyHeadersCompleteAndPrepareToRead(); +} + +void TestDownloadRequestHandler::PartialResponseJob::HandleOnStartDefault() { + DCHECK_CURRENTLY_ON(BrowserThread::IO); + SetStatus(net::URLRequestStatus()); + + const net::HttpRequestHeaders& extra_headers = + request()->extra_request_headers(); + + DCHECK(request()->method() == "GET") << "PartialResponseJob only " + "knows how to respond to GET " + "requests"; + std::string value; + + // If the request contains an 'If-Range' header and the value matches our + // ETag, then try to handle the range request. + if (parameters_->support_byte_ranges && + extra_headers.GetHeader(net::HttpRequestHeaders::kIfRange, &value) && + value == parameters_->etag && HandleRangeAssumingValidatorMatch()) + return; + + if (parameters_->support_byte_ranges && + extra_headers.GetHeader("If-Match", &value)) { + if (value == parameters_->etag && HandleRangeAssumingValidatorMatch()) + return; + + // Unlike If-Range, If-Match returns an error if the validators don't match. + response_info_.headers = HeadersFromString( + "HTTP/1.1 412 Precondition failed\r\n" + "Content-Length: 0\r\n"); + requested_range_begin_ = requested_range_end_ = -1; + NotifyHeadersCompleteAndPrepareToRead(); + return; + } + + requested_range_begin_ = 0; + requested_range_end_ = parameters_->size - 1; + response_info_.headers = + HeadersFromString(base::StringPrintf("HTTP/1.1 200 Success\r\n" + "Content-Length: %" PRId64 "\r\n", + parameters_->size)); + AddCommonEntityHeaders(); + NotifyHeadersCompleteAndPrepareToRead(); + return; +} + +bool TestDownloadRequestHandler::PartialResponseJob:: + HandleRangeAssumingValidatorMatch() { + const net::HttpRequestHeaders& extra_headers = + request()->extra_request_headers(); + + std::string range_header; + std::vector<net::HttpByteRange> byte_ranges; + + // There needs to be a 'Range' header and it should have exactly one range. + // This server is not going to deal with multiple ranges. + if (!extra_headers.GetHeader(net::HttpRequestHeaders::kRange, + &range_header) || + !net::HttpUtil::ParseRangeHeader(range_header, &byte_ranges) || + byte_ranges.size() != 1) + return false; + + // The request may have specified a range that's out of bounds. + if (!byte_ranges[0].ComputeBounds(parameters_->size)) { + response_info_.headers = HeadersFromString( + base::StringPrintf("HTTP/1.1 416 Range not satisfiable\r\n" + "Content-Range: bytes */%" PRId64 "\r\n" + "Content-Length: 0\r\n", + parameters_->size)); + requested_range_begin_ = requested_range_end_ = -1; + NotifyHeadersCompleteAndPrepareToRead(); + return true; + } + + requested_range_begin_ = byte_ranges[0].first_byte_position(); + requested_range_end_ = byte_ranges[0].last_byte_position(); + response_info_.headers = + HeadersFromString(base::StringPrintf( + "HTTP/1.1 206 Partial content\r\n" + "Content-Range: bytes %" PRId64 "-%" PRId64 "/%" PRId64 "\r\n" + "Content-Length: %" PRId64 "\r\n", + requested_range_begin_, requested_range_end_, parameters_->size, + (requested_range_end_ - requested_range_begin_) + 1)); + AddCommonEntityHeaders(); + NotifyHeadersCompleteAndPrepareToRead(); + return true; +} + +void TestDownloadRequestHandler::PartialResponseJob::AddCommonEntityHeaders() { + if (parameters_->support_byte_ranges) + response_info_.headers->AddHeader("Accept-Ranges: bytes"); + + if (!parameters_->content_type.empty()) + response_info_.headers->AddHeader(base::StringPrintf( + "Content-Type: %s", parameters_->content_type.c_str())); + + if (!parameters_->etag.empty()) + response_info_.headers->AddHeader( + base::StringPrintf("ETag: %s", parameters_->etag.c_str())); + + if (!parameters_->last_modified.empty()) + response_info_.headers->AddHeader(base::StringPrintf( + "Last-Modified: %s", parameters_->last_modified.c_str())); +} + +void TestDownloadRequestHandler::PartialResponseJob:: + NotifyHeadersCompleteAndPrepareToRead() { + std::string normalized_headers; + response_info_.headers->GetNormalizedHeaders(&normalized_headers); + DVLOG(1) << "Notify ready with headers:\n" << normalized_headers; + + offset_of_next_read_ = requested_range_begin_; + + // Flush out injected_errors that no longer apply. We are going to skip over + // ones where the |offset| == |requested_range_begin_| as well. While it + // prevents injecting an error at offset 0, it makes it much easier to set up + // parameter sets for download resumption. It means that when a request is + // interrupted at offset O, a subsequent request for the range O-<end> won't + // immediately interrupt as well. If we don't exclude interruptions at + // relative offset 0, then test writers would need to reset the parameter + // prior to each resumption rather than once at the beginning of the test. + while (!parameters_->injected_errors.empty() && + parameters_->injected_errors.front().offset <= requested_range_begin_) + parameters_->injected_errors.pop(); + + base::MessageLoop::current()->PostTask( + FROM_HERE, base::Bind(&PartialResponseJob::NotifyHeadersComplete, + weak_factory_.GetWeakPtr())); +} + +// static +base::WeakPtr<TestDownloadRequestHandler::Interceptor> +TestDownloadRequestHandler::Interceptor::Register( + const GURL& url, + scoped_refptr<base::SequencedTaskRunner> client_task_runner) { + DCHECK(url.is_valid()); + scoped_ptr<Interceptor> interceptor(new Interceptor(url, client_task_runner)); + base::WeakPtr<Interceptor> weak_reference = + interceptor->weak_ptr_factory_.GetWeakPtr(); + net::URLRequestFilter* filter = net::URLRequestFilter::GetInstance(); + filter->AddUrlInterceptor(url, interceptor.Pass()); + return weak_reference; +} + +void TestDownloadRequestHandler::Interceptor::Unregister() { + net::URLRequestFilter* filter = net::URLRequestFilter::GetInstance(); + filter->RemoveUrlHandler(url_); + // We are deleted now since the filter owned |this|. +} + +void TestDownloadRequestHandler::Interceptor::SetJobFactory( + const JobFactory& job_factory) { + job_factory_ = job_factory; +} + +void TestDownloadRequestHandler::Interceptor::GetAndResetCompletedRequests( + TestDownloadRequestHandler::CompletedRequests* requests) { + requests->clear(); + completed_requests_.swap(*requests); +} + +void TestDownloadRequestHandler::Interceptor::AddCompletedRequest( + const TestDownloadRequestHandler::CompletedRequest& request) { + completed_requests_.push_back(request); +} + +scoped_refptr<base::SequencedTaskRunner> +TestDownloadRequestHandler::Interceptor::GetClientTaskRunner() { + return client_task_runner_; +} + +TestDownloadRequestHandler::Interceptor::Interceptor( + const GURL& url, + scoped_refptr<base::SequencedTaskRunner> client_task_runner) + : url_(url), + client_task_runner_(client_task_runner), + weak_ptr_factory_(this) {} + +TestDownloadRequestHandler::Interceptor::~Interceptor() {} + +net::URLRequestJob* +TestDownloadRequestHandler::Interceptor::MaybeInterceptRequest( + net::URLRequest* request, + net::NetworkDelegate* network_delegate) const { + DVLOG(1) << "Intercepting request for " << request->url() + << " with headers:\n" << request->extra_request_headers().ToString(); + if (job_factory_.is_null()) + return nullptr; + return job_factory_.Run(request, network_delegate, + weak_ptr_factory_.GetWeakPtr()); +} + +TestDownloadRequestHandler::InjectedError::InjectedError(int64_t offset, + net::Error error) + : offset(offset), error(error) {} + +// static +TestDownloadRequestHandler::Parameters +TestDownloadRequestHandler::Parameters::WithSingleInterruption() { + Parameters parameters; + parameters.injected_errors.push( + InjectedError(parameters.size / 2, net::ERR_CONNECTION_RESET)); + return parameters; +} + +TestDownloadRequestHandler::Parameters::Parameters() + : etag("abcd"), + last_modified("Tue, 15 Nov 1994 12:45:26 GMT"), + content_type("application/octet-stream"), + size(102400), + pattern_generator_seed(1), + support_byte_ranges(true) {} + +// Copy and move constructors / assignment operators are all defaults. +TestDownloadRequestHandler::Parameters::Parameters(const Parameters&) = default; +TestDownloadRequestHandler::Parameters& TestDownloadRequestHandler::Parameters:: +operator=(const Parameters&) = default; + +TestDownloadRequestHandler::Parameters::Parameters(Parameters&& that) + : etag(std::move(that.etag)), + last_modified(std::move(that.last_modified)), + content_type(std::move(that.content_type)), + size(that.size), + pattern_generator_seed(that.pattern_generator_seed), + on_start_handler(that.on_start_handler), + injected_errors(std::move(that.injected_errors)) {} + +TestDownloadRequestHandler::Parameters& TestDownloadRequestHandler::Parameters:: +operator=(Parameters&& that) { + etag = std::move(that.etag); + last_modified = std::move(that.etag); + content_type = std::move(that.content_type); + size = that.size; + pattern_generator_seed = that.pattern_generator_seed; + on_start_handler = that.on_start_handler; + injected_errors.swap(that.injected_errors); + return *this; +} + +TestDownloadRequestHandler::Parameters::~Parameters() {} + +void TestDownloadRequestHandler::Parameters::ClearInjectedErrors() { + std::queue<InjectedError> empty_error_list; + injected_errors.swap(empty_error_list); +} + +TestDownloadRequestHandler::TestDownloadRequestHandler() + : TestDownloadRequestHandler(GetNextURLForDownloadInterceptor()) {} + +TestDownloadRequestHandler::TestDownloadRequestHandler(const GURL& url) + : url_(url) { + DCHECK(base::SequencedTaskRunnerHandle::IsSet()); + base::RunLoop run_loop; + BrowserThread::PostTaskAndReplyWithResult( + BrowserThread::IO, FROM_HERE, + base::Bind(&Interceptor::Register, url_, + base::SequencedTaskRunnerHandle::Get()), + base::Bind(&StoreValueAndInvokeClosure<base::WeakPtr<Interceptor>>, + run_loop.QuitClosure(), &interceptor_)); + run_loop.Run(); +} + +void TestDownloadRequestHandler::StartServing(const Parameters& parameters) { + DCHECK(CalledOnValidThread()); + Interceptor::JobFactory job_factory = + base::Bind(&PartialResponseJob::Factory, parameters); + // Interceptor, if valid, is already registered and serving requests. We just + // need to set the correct job factory for it to start serving using the new + // parameters. + BrowserThread::PostTask( + BrowserThread::IO, FROM_HERE, + base::Bind(&Interceptor::SetJobFactory, interceptor_, job_factory)); +} + +void TestDownloadRequestHandler::StartServingStaticResponse( + const base::StringPiece& headers) { + DCHECK(CalledOnValidThread()); + Parameters parameters; + parameters.on_start_handler = base::Bind( + &RespondToOnStartedCallbackWithStaticHeaders, headers.as_string()); + StartServing(parameters); +} + +// static +void TestDownloadRequestHandler::GetPatternBytes(int seed, + int64_t starting_offset, + int length, + char* buffer) { + int64_t seed_offset = starting_offset / sizeof(int64_t); + int64_t first_byte_position = starting_offset % sizeof(int64_t); + while (length > 0) { + uint64_t data = XorShift64StarWithIndex(seed, seed_offset); + int length_to_copy = + std::min(length, static_cast<int>(sizeof(data) - first_byte_position)); + memcpy(buffer, reinterpret_cast<char*>(&data) + first_byte_position, + length_to_copy); + buffer += length_to_copy; + length -= length_to_copy; + ++seed_offset; + first_byte_position = 0; + } +} + +TestDownloadRequestHandler::~TestDownloadRequestHandler() { + DCHECK(CalledOnValidThread()); + BrowserThread::PostTask(BrowserThread::IO, FROM_HERE, + base::Bind(&Interceptor::Unregister, interceptor_)); +} + +void TestDownloadRequestHandler::GetCompletedRequestInfo( + TestDownloadRequestHandler::CompletedRequests* requests) { + DCHECK(CalledOnValidThread()); + base::RunLoop run_loop; + BrowserThread::PostTaskAndReply( + BrowserThread::IO, FROM_HERE, + base::Bind(&Interceptor::GetAndResetCompletedRequests, interceptor_, + requests), + run_loop.QuitClosure()); + run_loop.Run(); +} + +} // namespace content
diff --git a/content/public/test/test_download_request_handler.h b/content/public/test/test_download_request_handler.h new file mode 100644 index 0000000..19209a2 --- /dev/null +++ b/content/public/test/test_download_request_handler.h
@@ -0,0 +1,306 @@ +// 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. + +#ifndef CONTENT_PUBLIC_TEST_TEST_DOWNLOAD_REQUEST_HANDLER_H_ +#define CONTENT_PUBLIC_TEST_TEST_DOWNLOAD_REQUEST_HANDLER_H_ + +#include <stdint.h> +#include <queue> + +#include "base/callback_forward.h" +#include "base/files/file.h" +#include "base/macros.h" +#include "base/memory/scoped_ptr.h" +#include "base/memory/weak_ptr.h" +#include "base/threading/non_thread_safe.h" +#include "net/base/completion_callback.h" +#include "net/base/net_errors.h" +#include "net/http/http_byte_range.h" +#include "net/http/http_response_headers.h" +#include "net/http/http_util.h" +#include "net/url_request/url_request_job.h" +#include "url/gurl.h" + +namespace content { + +// A request handler that can be used to mock the behavior of a URLRequestJob +// for a download. +// +// Testing of download interruption scenarios typically involve simulating +// errors that occur: +// 1. On the client, prior to the request being sent out, +// 2. On the network, between the client and the server, +// 3. On the server, +// 4. Back on the client, while writing the response to disk, +// 5. On the client, after the response has been written to disk. +// +// This test class is meant to help test failures in #2 and #3 above. The test +// implementation depends on content::BrowserThread and assumes that the +// thread identified by BrowserThread::IO is the network task runner thread. +// +// TestDownloadRequestHandler can be used on any thread as long as it is used +// and destroyed on the same thread it was constructed on. +// +// To use the test request handler: +// +// // Define the request handler. Note that initialization of the +// // TestDownloadRequestHandler object immediately registers it as well and is +// // a blocking operation. +// TestDownloadRequestHandler request_handler; +// +// // Set up parameters for the partial request handler. +// TestDownloadRequestHandler::Parameters parameters; +// +// // Inject an error at offset 100. +// parameters.injected_errors.push(TestDownloadRequestHandler::InjectedError( +// 100, net::ERR_CONNECTION_RESET)); +// +// // Start serving. +// request_handler.StartServing(parameters); +// +// At this point, you can initiate a URLRequest for request_handler.url(). The +// request will fail when offset 100 is reached with the error specified above. +class TestDownloadRequestHandler : public base::NonThreadSafe { + public: + // OnStartHandler can be used to intercept the Start() event of a new + // URLRequest. Set it as the |on_start_handler| member of Parameters below. + // + // The callback is invoked on the thread on which TestDownloadRequestHandler + // was created. Once the callback has a response ready, it can invoke the + // OnStartResponseCallback object. The latter can be invoked on any thread and + // will post back to the IO thread to continue with processing the Start() + // event. + // + // The parameters to the OnStartResponseCallback are: + // + // * a |const std::string&| containing the headers to be sent in response to + // the request. The headers should be formatted according to the + // requirements of net::HttpUtil::AssembleRawHeaders(). The headers are only + // used if the |net::Error| parameters is net::OK. + // + // * a |net::Error| indicating the result of the operation. If this parameters + // is not net::OK, then that error value is set as the result of the Start() + // operation. The headers are ignored in this case. + // + // If the error is net::OK, and the headers are empty, then the request is + // handled based on the remaining parameters in |Parameters|. + using OnStartResponseCallback = + base::Callback<void(const std::string&, net::Error)>; + + using OnStartHandler = base::Callback<void(const net::HttpRequestHeaders&, + const OnStartResponseCallback&)>; + + // An injected error. + struct InjectedError { + InjectedError(int64_t offset, net::Error error); + + int64_t offset; + net::Error error; + }; + + // Parameters used by StartServing(). + struct Parameters { + // Constructs a Parameters structure using the default constructor, but with + // the addition of a net::ERR_CONNECTION_RESET which will be triggered at + // byte offset (filesize / 2). + static Parameters WithSingleInterruption(); + + // The default constructor initializes the parameters for serving a 100 KB + // resource with no interruptions. The response contains an ETag and a + // Last-Modified header and the server supports byte range requests. + Parameters(); + + // Parameters is expected to be copyable and moveable. + Parameters(Parameters&&); + Parameters(const Parameters&); + Parameters& operator=(Parameters&&); + Parameters& operator=(const Parameters&); + ~Parameters(); + + // Clears the errors in injected_errors. + void ClearInjectedErrors(); + + // Contents of the ETag header field of the response. No Etag header is + // sent if this field is empty. + std::string etag; + + // Contents of the Last-Modified header field of the response. No + // Last-Modified header is sent if this field is empty. + std::string last_modified; + + // The Content-Type of the response. No Content-Type header is sent if this + // field is empty. + std::string content_type; + + // The total size of the entity. If the entire entity is requested, then + // this would be the same as the value returned in the Content-Length + // header. + int64_t size; + + // Seed for the pseudo-random sequence that defines the response body + // contents. The seed is with GetPatternBytes() to generate the body of the + // response. + int pattern_generator_seed; + + // If true, the response contains a 'Accept-Ranges: bytes' header. + bool support_byte_ranges; + + // If on_start_handler is valid, it will be invoked when a new request is + // received. See details about the OnStartHandler above. + OnStartHandler on_start_handler; + + // Errors to be injected. Each injected error is defined by an offset and an + // error. Request handler will successfully fulfil requests to read up to + // |offset|. An attempt to read the byte at |offset| will result in the + // error defined by the InjectErrors object. + // + // If a read spans the range containing |offset|, then the portion of the + // request preceding |offset| will succeed. The next read would start at + // |offset| and hence would result in an error. + // + // E.g.: injected_errors.push(InjectedError(100, ERR_CONNECTION_RESET)); + // + // A network read for 1024 bytes at offset 0 would result in successfully + // reading 100 bytes (bytes with offset 0-99). The next read would, + // therefore, start at offset 100 and would result in + // ERR_CONNECTION_RESET. + // + // Injected errors are processed in the order in which they appear in + // |injected_errors|. When handling a network request for the range [S,E] + // (inclusive), all events in |injected_errors| where |offset| is less than + // S will be ignored. The first event remaining will trigger an error once + // the sequence of reads proceeds to a point where its |offset| is included + // in [S,E]. + // + // This implies that |injected_errors| must be specified in increasing order + // of |offset|. I.e. |injected_errors| must be sorted by |offset|. + // + // Errors at relative offset 0 are ignored for a partial request. I.e. If + // the request is for the byte range 100-200, then an error at offset 100 + // will not trigger. This is done so that non-overlapping continuation + // attempts don't require resetting parameters to succeed. + // + // E.g.: If the caller injects an error at offset 100, then a request for + // the entire entity will fail after reading 100 bytes (offsets 0 through + // 99). A subsequent request for byte range "100-" (offsets 100 through EOF) + // will succeed since the error at offset 100 is ignored. + // + // Notes: + // + // * Distinctions about which read requests signal the error is often only + // important at the //net layer. From //content, it would appear that 100 + // bytes were read and then request failed with ERR_CONNECTION_RESET. + std::queue<InjectedError> injected_errors; + }; + + // Details about completed requests returned by GetCompletedRequestInfo(). + struct CompletedRequest { + // Count of bytes read by the client of the URLRequestJob. This counts the + // number of bytes of the entity that was transferred *after* content + // decoding is complete. + int64_t transferred_byte_count = -1; + + net::HttpRequestHeaders request_headers; + }; + + using CompletedRequests = std::vector<CompletedRequest>; + + // Registers a request handler at the default URL. Call url() to determine the + // URL. + // + // Notes: + // * This constructor is only meant to be used for convenience when the caller + // is not interested in the URL used for interception. The URL used is + // generated at run time and should not be assumed to be the same across + // different runs of the same test. + // + // * Initialization of the handler synchronously runs a task on the + // BrowserThread::IO thread using a nested message loop. Only construct an + // instance of this object after browser threads have been initialized. + TestDownloadRequestHandler(); + + // Similar to the default constructor, but registers the handler at |url|. + // + // Notes: + // * The behavior is undefined if more than one TestDownloadRequestHandler is + // registered for the same URL. + TestDownloadRequestHandler(const GURL& url); + + // Destroys and posts a task to the IO thread to dismantle the registered URL + // request interceptor. Does not wait for the task to return. + ~TestDownloadRequestHandler(); + + // Returns the URL that this instance is intercepting URLRequests for. + const GURL& url() const { return url_; } + + // Start responding to URLRequests for url() with responses based on + // |parameters|. + // + // This method invocation posts a task to the IO thread to update the + // URLRequestInterceptor with the new parameters and returns immediately. URL + // interception won't be updated until the posted task executes. The method + // returns without waiting for the posted task to complete. + // + // Calling this method does not affect URLRequests that have already started. + // The new parameters will only be used to respond to new URLRequests that are + // starting. + // + // StartServing() can be called multiple times to change the operating + // parameters of the current URL interceptor. + void StartServing(const Parameters& parameters); + + // Start responding to URLRequests for url() with a static response + // containing the headers in |headers|. + // + // The format of |headers| should comply with the requirements for + // net::HttpUtil::AssembleRawHeaders(). + void StartServingStaticResponse(const base::StringPiece& headers); + + // Get the list of requests that have already completed. + // + // This method posts a task to the IO thread to collect the list of completed + // requests and waits for the task to complete. + // + // Requests that are currently in progress will not be reflected in + // |requests|. + void GetCompletedRequestInfo(CompletedRequests* requests); + + // Generate a pseudo random pattern. + // + // |seed| is the seed for the pseudo random sequence. |offset| is the byte + // offset into the sequence. |length| is a count of bytes to generate. + // |data| receives the generated bytes and should be able to store |length| + // bytes. + // + // The pattern has the following properties: + // + // * For a given |seed|, the entire sequence of bytes is fixed. Any + // subsequence can be generated by specifying the |offset| and |length|. + // + // * The sequence is aperiodic (at least for the first 1M bytes). + // + // * |seed| is chaotic. Different seeds produce "very different" data. This + // means that there's no trivial mapping between sequences generated using + // two distinct seeds. + // + // These properties make the generated bytes useful for testing partial + // requests where the response may need to be built using a sequence of + // partial requests. + // + // Note: Don't use this function to generate a cryptographically secure + // pseudo-random sequence. + static void GetPatternBytes(int seed, int64 offset, int length, char* data); + + private: + class Interceptor; + class PartialResponseJob; + + GURL url_; + base::WeakPtr<Interceptor> interceptor_; + DISALLOW_COPY_AND_ASSIGN(TestDownloadRequestHandler); +}; + +} // namespace content + +#endif // CONTENT_PUBLIC_TEST_TEST_DOWNLOAD_REQUEST_HANDLER_H_
diff --git a/content/renderer/BUILD.gn b/content/renderer/BUILD.gn index bf1d4de..f009eeed 100644 --- a/content/renderer/BUILD.gn +++ b/content/renderer/BUILD.gn
@@ -77,12 +77,7 @@ ] if (use_aura) { - sources += [ - "render_widget_mus_connection.cc", - "render_widget_mus_connection.h", - "render_widget_window_tree_client_factory.cc", - "render_widget_window_tree_client_factory.h", - ] + deps += [ "//content/renderer/mus" ] } if (is_mac) {
diff --git a/content/renderer/browser_plugin/browser_plugin.cc b/content/renderer/browser_plugin/browser_plugin.cc index 7dc2756..0af3aa46 100644 --- a/content/renderer/browser_plugin/browser_plugin.cc +++ b/content/renderer/browser_plugin/browser_plugin.cc
@@ -561,16 +561,6 @@ void BrowserPlugin::didFailLoading(const blink::WebURLError& error) { } -void BrowserPlugin::didFinishLoadingFrameRequest(const blink::WebURL& url, - void* notify_data) { -} - -void BrowserPlugin::didFailLoadingFrameRequest( - const blink::WebURL& url, - void* notify_data, - const blink::WebURLError& error) { -} - bool BrowserPlugin::executeEditCommand(const blink::WebString& name) { BrowserPluginManager::Get()->Send(new BrowserPluginHostMsg_ExecuteEditCommand( browser_plugin_instance_id_,
diff --git a/content/renderer/browser_plugin/browser_plugin.h b/content/renderer/browser_plugin/browser_plugin.h index 70a61ee..5069e87b 100644 --- a/content/renderer/browser_plugin/browser_plugin.h +++ b/content/renderer/browser_plugin/browser_plugin.h
@@ -109,11 +109,6 @@ void didReceiveData(const char* data, int data_length) override; void didFinishLoading() override; void didFailLoading(const blink::WebURLError& error) override; - void didFinishLoadingFrameRequest(const blink::WebURL& url, - void* notify_data) override; - void didFailLoadingFrameRequest(const blink::WebURL& url, - void* notify_data, - const blink::WebURLError& error) override; bool executeEditCommand(const blink::WebString& name) override; bool executeEditCommand(const blink::WebString& name, const blink::WebString& value) override;
diff --git a/content/renderer/media/cdm/ppapi_decryptor.cc b/content/renderer/media/cdm/ppapi_decryptor.cc index a4b51bb..023c361 100644 --- a/content/renderer/media/cdm/ppapi_decryptor.cc +++ b/content/renderer/media/cdm/ppapi_decryptor.cc
@@ -161,6 +161,7 @@ const std::string& session_id, const std::vector<uint8_t>& response, scoped_ptr<media::SimpleCdmPromise> promise) { + DVLOG(2) << __FUNCTION__; DCHECK(render_task_runner_->BelongsToCurrentThread()); if (!CdmDelegate()) { @@ -172,6 +173,7 @@ void PpapiDecryptor::CloseSession(const std::string& session_id, scoped_ptr<media::SimpleCdmPromise> promise) { + DVLOG(2) << __FUNCTION__; DCHECK(render_task_runner_->BelongsToCurrentThread()); if (!CdmDelegate()) { @@ -185,6 +187,7 @@ void PpapiDecryptor::RemoveSession( const std::string& session_id, scoped_ptr<media::SimpleCdmPromise> promise) { + DVLOG(2) << __FUNCTION__; DCHECK(render_task_runner_->BelongsToCurrentThread()); if (!CdmDelegate()) { @@ -401,6 +404,7 @@ void PpapiDecryptor::OnSessionKeysChange(const std::string& session_id, bool has_additional_usable_key, media::CdmKeysInfo keys_info) { + DVLOG(2) << __FUNCTION__ << ": " << has_additional_usable_key; DCHECK(render_task_runner_->BelongsToCurrentThread()); // TODO(jrummell): Handling resume playback should be done in the media
diff --git a/content/renderer/media/rtc_video_decoder.cc b/content/renderer/media/rtc_video_decoder.cc index aebe9f28..1f43ba24 100644 --- a/content/renderer/media/rtc_video_decoder.cc +++ b/content/renderer/media/rtc_video_decoder.cc
@@ -674,7 +674,9 @@ DVLOG(1) << "Unsupported profile " << profile; } else { vda_ = factories_->CreateVideoDecodeAccelerator(); - if (vda_ && !vda_->Initialize(profile, this)) + + media::VideoDecodeAccelerator::Config config(profile); + if (vda_ && !vda_->Initialize(config, this)) vda_.release()->Destroy(); }
diff --git a/content/renderer/mus/BUILD.gn b/content/renderer/mus/BUILD.gn new file mode 100644 index 0000000..3c126bf --- /dev/null +++ b/content/renderer/mus/BUILD.gn
@@ -0,0 +1,22 @@ +# 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. + +source_set("mus") { + sources = [ + "compositor_mus_connection.cc", + "compositor_mus_connection.h", + "render_widget_mus_connection.cc", + "render_widget_mus_connection.h", + "render_widget_window_tree_client_factory.cc", + "render_widget_window_tree_client_factory.h", + ] + + deps = [ + "//base", + "//cc", + "//components/mus/public/interfaces", + "//mojo/converters/blink", + "//third_party/WebKit/public:blink", + ] +}
diff --git a/content/renderer/mus/OWNERS b/content/renderer/mus/OWNERS new file mode 100644 index 0000000..9c070a5 --- /dev/null +++ b/content/renderer/mus/OWNERS
@@ -0,0 +1 @@ +ben@chromium.org
diff --git a/content/renderer/mus/compositor_mus_connection.cc b/content/renderer/mus/compositor_mus_connection.cc new file mode 100644 index 0000000..9e0813e --- /dev/null +++ b/content/renderer/mus/compositor_mus_connection.cc
@@ -0,0 +1,139 @@ +// 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. + +#include "content/renderer/mus/compositor_mus_connection.h" + +#include "base/single_thread_task_runner.h" +#include "content/common/input/web_input_event_traits.h" +#include "content/renderer/input/input_handler_manager.h" +#include "content/renderer/mus/render_widget_mus_connection.h" +#include "mojo/converters/blink/blink_input_events_type_converters.h" +#include "ui/events/latency_info.h" + +namespace content { + +CompositorMusConnection::CompositorMusConnection( + int routing_id, + const scoped_refptr<base::SingleThreadTaskRunner>& main_task_runner, + const scoped_refptr<base::SingleThreadTaskRunner>& compositor_task_runner, + mojo::InterfaceRequest<mus::mojom::WindowTreeClient> request, + InputHandlerManager* input_handler_manager) + : routing_id_(routing_id), + root_(nullptr), + main_task_runner_(main_task_runner), + compositor_task_runner_(compositor_task_runner), + input_handler_manager_(input_handler_manager) { + DCHECK(main_task_runner_->BelongsToCurrentThread()); + compositor_task_runner_->PostTask( + FROM_HERE, base::Bind(&CompositorMusConnection:: + CreateWindowTreeConnectionOnCompositorThread, + this, base::Passed(std::move(request)))); +} + +void CompositorMusConnection::AttachSurfaceOnMainThread( + scoped_ptr<mus::WindowSurfaceBinding> surface_binding) { + DCHECK(main_task_runner_->BelongsToCurrentThread()); + compositor_task_runner_->PostTask( + FROM_HERE, + base::Bind(&CompositorMusConnection::AttachSurfaceOnCompositorThread, + this, base::Passed(std::move(surface_binding)))); +} + +CompositorMusConnection::~CompositorMusConnection() {} + +void CompositorMusConnection::AttachSurfaceOnCompositorThread( + scoped_ptr<mus::WindowSurfaceBinding> surface_binding) { + DCHECK(compositor_task_runner_->BelongsToCurrentThread()); + window_surface_binding_ = std::move(surface_binding); + if (root_) { + root_->AttachSurface(mus::mojom::SURFACE_TYPE_DEFAULT, + std::move(window_surface_binding_)); + } +} + +void CompositorMusConnection::CreateWindowTreeConnectionOnCompositorThread( + mojo::InterfaceRequest<mus::mojom::WindowTreeClient> request) { + DCHECK(compositor_task_runner_->BelongsToCurrentThread()); + mus::WindowTreeConnection::Create( + this, std::move(request), + mus::WindowTreeConnection::CreateType::DONT_WAIT_FOR_EMBED); +} + +void CompositorMusConnection::OnConnectionLostOnMainThread() { + DCHECK(main_task_runner_->BelongsToCurrentThread()); + RenderWidgetMusConnection* connection = + RenderWidgetMusConnection::Get(routing_id_); + if (!connection) + return; + connection->OnConnectionLost(); +} + +void CompositorMusConnection::OnWindowInputEventOnMainThread( + scoped_ptr<blink::WebInputEvent> web_event, + const base::Closure& ack) { + DCHECK(main_task_runner_->BelongsToCurrentThread()); + RenderWidgetMusConnection* connection = + RenderWidgetMusConnection::Get(routing_id_); + if (!connection) { + ack.Run(); + return; + } + connection->OnWindowInputEvent(std::move(web_event), ack); +} + +void CompositorMusConnection::OnWindowInputEventAckOnMainThread( + const base::Closure& ack) { + DCHECK(main_task_runner_->BelongsToCurrentThread()); + compositor_task_runner_->PostTask(FROM_HERE, ack); +} + +void CompositorMusConnection::OnConnectionLost( + mus::WindowTreeConnection* connection) { + DCHECK(compositor_task_runner_->BelongsToCurrentThread()); + main_task_runner_->PostTask( + FROM_HERE, + base::Bind(&CompositorMusConnection::OnConnectionLostOnMainThread, this)); +} + +void CompositorMusConnection::OnEmbed(mus::Window* root) { + DCHECK(compositor_task_runner_->BelongsToCurrentThread()); + root_ = root; + root_->AddObserver(this); + if (window_surface_binding_) { + root->AttachSurface(mus::mojom::SURFACE_TYPE_DEFAULT, + std::move(window_surface_binding_)); + } +} + +void CompositorMusConnection::OnWindowInputEvent( + mus::Window* window, + const mus::mojom::EventPtr& event) { + DCHECK(compositor_task_runner_->BelongsToCurrentThread()); + scoped_ptr<blink::WebInputEvent> web_event = + event.To<scoped_ptr<blink::WebInputEvent>>(); + // TODO(sad): We probably need to plumb LatencyInfo through Mus. + ui::LatencyInfo info; + InputEventAckState ack_state = input_handler_manager_->HandleInputEvent( + routing_id_, web_event.get(), &info); + if (ack_state != INPUT_EVENT_ACK_STATE_NOT_CONSUMED) + return; + // TODO(sad): Do something more useful once we can do async acks. + base::Closure ack = base::Bind(&base::DoNothing); + const bool send_ack = + WebInputEventTraits::WillReceiveAckFromRenderer(*web_event); + if (send_ack) { + // Ultimately, this ACK needs to go back to the Mus client lib which is not + // thread-safe and lives on the compositor thread. For ACKs that are passed + // to the main thread we pass them back to the compositor thread via + // OnWindowInputEventAckOnMainThread. + ack = base::Bind( + &CompositorMusConnection::OnWindowInputEventAckOnMainThread, this, ack); + } + main_task_runner_->PostTask( + FROM_HERE, + base::Bind(&CompositorMusConnection::OnWindowInputEventOnMainThread, this, + base::Passed(std::move(web_event)), ack)); +} + +} // namespace content
diff --git a/content/renderer/mus/compositor_mus_connection.h b/content/renderer/mus/compositor_mus_connection.h new file mode 100644 index 0000000..f7ee6be --- /dev/null +++ b/content/renderer/mus/compositor_mus_connection.h
@@ -0,0 +1,83 @@ +// 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. + +#ifndef CONTENT_RENDERER_MUS_COMPOSITOR_MUS_CONNECTION_H_ +#define CONTENT_RENDERER_MUS_COMPOSITOR_MUS_CONNECTION_H_ + +#include "base/bind.h" +#include "base/macros.h" +#include "components/mus/public/cpp/window.h" +#include "components/mus/public/cpp/window_observer.h" +#include "components/mus/public/cpp/window_tree_connection.h" +#include "components/mus/public/cpp/window_tree_delegate.h" +#include "third_party/WebKit/public/web/WebInputEvent.h" + +namespace content { + +class InputHandlerManager; + +// CompositorMusConnection manages the connection to the Mandoline UI Service +// (Mus) on the compositor thread. For operations that need to happen on the +// main thread, CompositorMusConnection deals with passing information across +// threads. CompositorMusConnection is constructed on the main thread. By +// default all other methods are assumed to run on the compositor thread unless +// explicited suffixed with OnMainThread. +class CompositorMusConnection + : public mus::WindowTreeDelegate, + public mus::WindowObserver, + public base::RefCountedThreadSafe<CompositorMusConnection> { + public: + // Created on main thread. + CompositorMusConnection( + int routing_id, + const scoped_refptr<base::SingleThreadTaskRunner>& main_task_runner, + const scoped_refptr<base::SingleThreadTaskRunner>& compositor_task_runner, + mojo::InterfaceRequest<mus::mojom::WindowTreeClient> request, + InputHandlerManager* input_handler_manager); + + // Attaches the provided |surface_binding| with the mus::Window for the + // renderer once it becomes available. + void AttachSurfaceOnMainThread( + scoped_ptr<mus::WindowSurfaceBinding> surface_binding); + + private: + friend class base::RefCountedThreadSafe<CompositorMusConnection>; + + ~CompositorMusConnection() override; + + void AttachSurfaceOnCompositorThread( + scoped_ptr<mus::WindowSurfaceBinding> surface_binding); + + void CreateWindowTreeConnectionOnCompositorThread( + mojo::InterfaceRequest<mus::mojom::WindowTreeClient> request); + + void OnConnectionLostOnMainThread(); + + void OnWindowInputEventOnMainThread( + scoped_ptr<blink::WebInputEvent> web_event, + const base::Closure& ack); + + void OnWindowInputEventAckOnMainThread(const base::Closure& ack); + + // WindowTreeDelegate implementation: + void OnConnectionLost(mus::WindowTreeConnection* connection) override; + void OnEmbed(mus::Window* root) override; + + // WindowObserver implementation: + void OnWindowInputEvent(mus::Window* window, + const mus::mojom::EventPtr& event) override; + + const int routing_id_; + mus::Window* root_; + scoped_refptr<base::SingleThreadTaskRunner> main_task_runner_; + scoped_refptr<base::SingleThreadTaskRunner> compositor_task_runner_; + InputHandlerManager* const input_handler_manager_; + scoped_ptr<mus::WindowSurfaceBinding> window_surface_binding_; + + DISALLOW_COPY_AND_ASSIGN(CompositorMusConnection); +}; + +} // namespace content + +#endif // CONTENT_RENDERER_MUS_COMPOSITOR_MUS_CONNECTION_H_
diff --git a/content/renderer/mus/render_widget_mus_connection.cc b/content/renderer/mus/render_widget_mus_connection.cc new file mode 100644 index 0000000..5eaaa1a6 --- /dev/null +++ b/content/renderer/mus/render_widget_mus_connection.cc
@@ -0,0 +1,111 @@ +// 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. + +#include "content/renderer/mus/render_widget_mus_connection.h" + +#include <map> + +#include "base/lazy_instance.h" +#include "base/macros.h" +#include "components/mus/public/cpp/context_provider.h" +#include "components/mus/public/cpp/output_surface.h" +#include "components/mus/public/interfaces/command_buffer.mojom.h" +#include "components/mus/public/interfaces/compositor_frame.mojom.h" +#include "components/mus/public/interfaces/gpu.mojom.h" +#include "components/mus/public/interfaces/window_tree.mojom.h" +#include "content/public/common/mojo_shell_connection.h" +#include "content/renderer/mus/compositor_mus_connection.h" +#include "content/renderer/render_thread_impl.h" +#include "content/renderer/render_view_impl.h" +#include "mojo/application/public/cpp/application_impl.h" +#include "mojo/converters/geometry/geometry_type_converters.h" +#include "mojo/converters/surfaces/surfaces_utils.h" + +namespace content { + +namespace { + +typedef std::map<int, RenderWidgetMusConnection*> ConnectionMap; +base::LazyInstance<ConnectionMap>::Leaky g_connections = + LAZY_INSTANCE_INITIALIZER; +} + +void RenderWidgetMusConnection::Bind( + mojo::InterfaceRequest<mus::mojom::WindowTreeClient> request) { + DCHECK(thread_checker_.CalledOnValidThread()); + RenderThreadImpl* render_thread = RenderThreadImpl::current(); + compositor_mus_connection_ = new CompositorMusConnection( + routing_id_, render_thread->GetCompositorMainThreadTaskRunner(), + render_thread->compositor_task_runner(), std::move(request), + render_thread->input_handler_manager()); + if (window_surface_binding_) { + compositor_mus_connection_->AttachSurfaceOnMainThread( + std::move(window_surface_binding_)); + } +} + +scoped_ptr<cc::OutputSurface> RenderWidgetMusConnection::CreateOutputSurface() { + DCHECK(thread_checker_.CalledOnValidThread()); + DCHECK(!window_surface_binding_); + mus::mojom::GpuPtr gpu_service; + MojoShellConnection::Get()->GetApplication()->ConnectToService("mojo:mus", + &gpu_service); + mus::mojom::CommandBufferPtr cb; + gpu_service->CreateOffscreenGLES2Context(GetProxy(&cb)); + scoped_refptr<cc::ContextProvider> context_provider( + new mus::ContextProvider(cb.PassInterface().PassHandle())); + scoped_ptr<cc::OutputSurface> surface(new mus::OutputSurface( + context_provider, mus::WindowSurface::Create(&window_surface_binding_))); + if (compositor_mus_connection_) { + compositor_mus_connection_->AttachSurfaceOnMainThread( + std::move(window_surface_binding_)); + } + return surface; +} + +// static +RenderWidgetMusConnection* RenderWidgetMusConnection::Get(int routing_id) { + auto it = g_connections.Get().find(routing_id); + if (it != g_connections.Get().end()) + return it->second; + return nullptr; +} + +// static +RenderWidgetMusConnection* RenderWidgetMusConnection::GetOrCreate( + int routing_id) { + RenderWidgetMusConnection* connection = Get(routing_id); + if (!connection) { + connection = new RenderWidgetMusConnection(routing_id); + g_connections.Get().insert(std::make_pair(routing_id, connection)); + } + return connection; +} + +RenderWidgetMusConnection::RenderWidgetMusConnection(int routing_id) + : routing_id_(routing_id) { + DCHECK(routing_id); +} + +RenderWidgetMusConnection::~RenderWidgetMusConnection() {} + +void RenderWidgetMusConnection::OnConnectionLost() { + DCHECK(thread_checker_.CalledOnValidThread()); + g_connections.Get().erase(routing_id_); + delete this; +} + +void RenderWidgetMusConnection::OnWindowInputEvent( + scoped_ptr<blink::WebInputEvent> input_event, + const base::Closure& ack) { + DCHECK(thread_checker_.CalledOnValidThread()); + // TODO(fsamuel): Implement this once the following is complete: + // 1. The Mus client lib supports manual event ACKing. + // 2. Mus supports event coalescing. + // 3. RenderWidget is refactored so that we don't send ACKs to the browser + // process. + ack.Run(); +} + +} // namespace content
diff --git a/content/renderer/mus/render_widget_mus_connection.h b/content/renderer/mus/render_widget_mus_connection.h new file mode 100644 index 0000000..234ce3a --- /dev/null +++ b/content/renderer/mus/render_widget_mus_connection.h
@@ -0,0 +1,55 @@ +// 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. + +#ifndef CONTENT_RENDERER_MUS_RENDER_WIDGET_MUS_CONNECTION_H_ +#define CONTENT_RENDERER_MUS_RENDER_WIDGET_MUS_CONNECTION_H_ + +#include "base/macros.h" +#include "base/threading/thread_checker.h" +#include "cc/output/output_surface.h" +#include "components/mus/public/cpp/window_surface.h" +#include "content/renderer/mus/compositor_mus_connection.h" + +namespace content { + +class InputHandlerManager; + +// Use on main thread. +class RenderWidgetMusConnection { + public: + // Bind to a WindowTreeClient request. + void Bind(mojo::InterfaceRequest<mus::mojom::WindowTreeClient> request); + + // Create a cc output surface. + scoped_ptr<cc::OutputSurface> CreateOutputSurface(); + + static RenderWidgetMusConnection* Get(int routing_id); + + // Get the connection from a routing_id, if the connection doesn't exist, + // a new connection will be created. + static RenderWidgetMusConnection* GetOrCreate(int routing_id); + + private: + friend class CompositorMusConnection; + + explicit RenderWidgetMusConnection(int routing_id); + ~RenderWidgetMusConnection(); + + void OnConnectionLost(); + void OnWindowInputEvent(scoped_ptr<blink::WebInputEvent> input_event, + const base::Closure& ack); + + const int routing_id_; + scoped_ptr<mus::WindowSurfaceBinding> window_surface_binding_; + scoped_refptr<CompositorMusConnection> compositor_mus_connection_; + + // Used to verify single threaded access. + base::ThreadChecker thread_checker_; + + DISALLOW_COPY_AND_ASSIGN(RenderWidgetMusConnection); +}; + +} // namespace content + +#endif // CONTENT_RENDERER_MUS_RENDER_WIDGET_MUS_CONNECTION_H_
diff --git a/content/renderer/render_widget_window_tree_client_factory.cc b/content/renderer/mus/render_widget_window_tree_client_factory.cc similarity index 90% rename from content/renderer/render_widget_window_tree_client_factory.cc rename to content/renderer/mus/render_widget_window_tree_client_factory.cc index 9aeb290..f2d1402 100644 --- a/content/renderer/render_widget_window_tree_client_factory.cc +++ b/content/renderer/mus/render_widget_window_tree_client_factory.cc
@@ -2,14 +2,14 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#include "content/renderer/render_widget_window_tree_client_factory.h" +#include "content/renderer/mus/render_widget_window_tree_client_factory.h" #include "base/logging.h" #include "base/macros.h" #include "components/mus/public/interfaces/window_tree.mojom.h" #include "content/common/render_widget_window_tree_client_factory.mojom.h" #include "content/public/common/mojo_shell_connection.h" -#include "content/renderer/render_widget_mus_connection.h" +#include "content/renderer/mus/render_widget_mus_connection.h" #include "mojo/application/public/cpp/application_connection.h" #include "mojo/application/public/cpp/interface_factory.h" #include "mojo/common/weak_binding_set.h" @@ -45,7 +45,7 @@ void Create(mojo::ApplicationConnection* connection, mojo::InterfaceRequest<mojom::RenderWidgetWindowTreeClientFactory> request) override { - bindings_.AddBinding(this, request.Pass()); + bindings_.AddBinding(this, std::move(request)); } // mojom::RenderWidgetWindowTreeClientFactory implementation. @@ -54,7 +54,7 @@ mojo::InterfaceRequest<mus::mojom::WindowTreeClient> request) override { RenderWidgetMusConnection* connection = RenderWidgetMusConnection::GetOrCreate(routing_id); - connection->Bind(request.Pass()); + connection->Bind(std::move(request)); } mojo::WeakBindingSet<mojom::RenderWidgetWindowTreeClientFactory> bindings_;
diff --git a/content/renderer/mus/render_widget_window_tree_client_factory.h b/content/renderer/mus/render_widget_window_tree_client_factory.h new file mode 100644 index 0000000..f3b3b73 --- /dev/null +++ b/content/renderer/mus/render_widget_window_tree_client_factory.h
@@ -0,0 +1,14 @@ +// 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. + +#ifndef CONTENT_RENDERER_MUS_RENDER_WIDGET_WINDOW_TREE_CLIENT_FACTORY_H_ +#define CONTENT_RENDERER_MUS_RENDER_WIDGET_WINDOW_TREE_CLIENT_FACTORY_H_ + +namespace content { + +void CreateRenderWidgetWindowTreeClientFactory(); + +} // namespace content + +#endif // CONTENT_RENDERER_MUS_RENDER_WIDGET_WINDOW_TREE_CLIENT_FACTORY_H_
diff --git a/content/renderer/npapi/webplugin_delegate_proxy.cc b/content/renderer/npapi/webplugin_delegate_proxy.cc index 054fa47d..a77e844 100644 --- a/content/renderer/npapi/webplugin_delegate_proxy.cc +++ b/content/renderer/npapi/webplugin_delegate_proxy.cc
@@ -96,26 +96,11 @@ class ResourceClientProxy : public WebPluginResourceClient { public: ResourceClientProxy(PluginChannelHost* channel, int instance_id) - : channel_(channel), instance_id_(instance_id), resource_id_(0), - multibyte_response_expected_(false) { + : channel_(channel), instance_id_(instance_id), resource_id_(0) { } ~ResourceClientProxy() override {} - void Initialize(unsigned long resource_id, const GURL& url, int notify_id) { - resource_id_ = resource_id; - channel_->Send(new PluginMsg_HandleURLRequestReply( - instance_id_, resource_id, url, notify_id)); - } - - void InitializeForSeekableStream(unsigned long resource_id, - int range_request_id) { - resource_id_ = resource_id; - multibyte_response_expected_ = true; - channel_->Send(new PluginMsg_HTTPRangeRequestReply( - instance_id_, resource_id, range_request_id)); - } - // PluginResourceClient implementation: void WillSendRequest(const GURL& url, int http_status_code) override { DCHECK(channel_.get() != NULL); @@ -173,19 +158,12 @@ base::MessageLoop::current()->DeleteSoon(FROM_HERE, this); } - bool IsMultiByteResponseExpected() override { - return multibyte_response_expected_; - } - int ResourceId() override { return resource_id_; } private: scoped_refptr<PluginChannelHost> channel_; int instance_id_; unsigned long resource_id_; - // Set to true if the response expected is a multibyte response. - // For e.g. response for a HTTP byte range request. - bool multibyte_response_expected_; }; } // namespace @@ -386,44 +364,6 @@ return channel_host_->Send(msg); } -void WebPluginDelegateProxy::SendJavaScriptStream(const GURL& url, - const std::string& result, - bool success, - int notify_id) { - Send(new PluginMsg_SendJavaScriptStream( - instance_id_, url, result, success, notify_id)); -} - -void WebPluginDelegateProxy::DidReceiveManualResponse( - const GURL& url, const std::string& mime_type, - const std::string& headers, uint32 expected_length, - uint32 last_modified) { - PluginMsg_DidReceiveResponseParams params; - params.id = 0; - params.mime_type = mime_type; - params.headers = headers; - params.expected_length = expected_length; - params.last_modified = last_modified; - Send(new PluginMsg_DidReceiveManualResponse(instance_id_, url, params)); -} - -void WebPluginDelegateProxy::DidReceiveManualData(const char* buffer, - int length) { - DCHECK_GT(length, 0); - std::vector<char> data; - data.resize(static_cast<size_t>(length)); - memcpy(&data.front(), buffer, length); - Send(new PluginMsg_DidReceiveManualData(instance_id_, data)); -} - -void WebPluginDelegateProxy::DidFinishManualLoading() { - Send(new PluginMsg_DidFinishManualLoading(instance_id_)); -} - -void WebPluginDelegateProxy::DidManualLoadFail() { - Send(new PluginMsg_DidManualLoadFail(instance_id_)); -} - bool WebPluginDelegateProxy::OnMessageReceived(const IPC::Message& msg) { GetContentClient()->SetActiveURL(page_url_); @@ -438,10 +378,7 @@ IPC_MESSAGE_HANDLER(PluginHostMsg_ResolveProxy, OnResolveProxy) IPC_MESSAGE_HANDLER(PluginHostMsg_SetCookie, OnSetCookie) IPC_MESSAGE_HANDLER(PluginHostMsg_GetCookies, OnGetCookies) - IPC_MESSAGE_HANDLER(PluginHostMsg_URLRequest, OnHandleURLRequest) IPC_MESSAGE_HANDLER(PluginHostMsg_CancelDocumentLoad, OnCancelDocumentLoad) - IPC_MESSAGE_HANDLER(PluginHostMsg_InitiateHTTPRangeRequest, - OnInitiateHTTPRangeRequest) IPC_MESSAGE_HANDLER(PluginHostMsg_DidStartLoading, OnDidStartLoading) IPC_MESSAGE_HANDLER(PluginHostMsg_DidStopLoading, OnDidStopLoading) IPC_MESSAGE_HANDLER(PluginHostMsg_DeferResourceLoading, @@ -742,12 +679,6 @@ return success; } -void WebPluginDelegateProxy::DidFinishLoadWithReason( - const GURL& url, NPReason reason, int notify_id) { - Send(new PluginMsg_DidFinishLoadWithReason( - instance_id_, url, reason, notify_id)); -} - void WebPluginDelegateProxy::SetFocus(bool focused) { Send(new PluginMsg_SetFocus(instance_id_, focused)); #if defined(OS_WIN) @@ -1066,75 +997,6 @@ transport_store_painted_.Union(rect); } -void WebPluginDelegateProxy::OnHandleURLRequest( - const PluginHostMsg_URLRequest_Params& params) { - const char* data = NULL; - if (params.buffer.size()) - data = ¶ms.buffer[0]; - - const char* target = NULL; - if (params.target.length()) - target = params.target.c_str(); - - plugin_->HandleURLRequest( - params.url.c_str(), params.method.c_str(), target, data, - static_cast<unsigned int>(params.buffer.size()), params.notify_id, - params.popups_allowed, params.notify_redirects); -} - -WebPluginResourceClient* WebPluginDelegateProxy::CreateResourceClient( - unsigned long resource_id, const GURL& url, int notify_id) { - if (!channel_host_.get()) - return NULL; - - ResourceClientProxy* proxy = - new ResourceClientProxy(channel_host_.get(), instance_id_); - proxy->Initialize(resource_id, url, notify_id); - return proxy; -} - -WebPluginResourceClient* WebPluginDelegateProxy::CreateSeekableResourceClient( - unsigned long resource_id, int range_request_id) { - if (!channel_host_.get()) - return NULL; - - ResourceClientProxy* proxy = - new ResourceClientProxy(channel_host_.get(), instance_id_); - proxy->InitializeForSeekableStream(resource_id, range_request_id); - return proxy; -} - -void WebPluginDelegateProxy::FetchURL(unsigned long resource_id, - int notify_id, - const GURL& url, - const GURL& first_party_for_cookies, - const std::string& method, - const char* buf, - unsigned int len, - const Referrer& referrer, - bool notify_redirects, - bool is_plugin_src_load, - int origin_pid, - int render_frame_id, - int render_view_id) { - PluginMsg_FetchURL_Params params; - params.resource_id = resource_id; - params.notify_id = notify_id; - params.url = url; - params.first_party_for_cookies = first_party_for_cookies; - params.method = method; - if (len) { - params.post_data.resize(len); - memcpy(¶ms.post_data.front(), buf, len); - } - params.referrer = referrer.url; - params.referrer_policy = referrer.policy; - params.notify_redirect = notify_redirects; - params.is_plugin_src_load = is_plugin_src_load; - params.render_frame_id = render_frame_id; - Send(new PluginMsg_FetchURL(instance_id_, params)); -} - #if defined(OS_MACOSX) void WebPluginDelegateProxy::OnFocusChanged(bool focused) { if (render_view_) @@ -1155,14 +1017,6 @@ plugin_->CancelDocumentLoad(); } -void WebPluginDelegateProxy::OnInitiateHTTPRangeRequest( - const std::string& url, - const std::string& range_info, - int range_request_id) { - plugin_->InitiateHTTPRangeRequest( - url.c_str(), range_info.c_str(), range_request_id); -} - void WebPluginDelegateProxy::OnDidStartLoading() { plugin_->DidStartLoading(); }
diff --git a/content/renderer/npapi/webplugin_delegate_proxy.h b/content/renderer/npapi/webplugin_delegate_proxy.h index 64eab9df..ad9a66b8 100644 --- a/content/renderer/npapi/webplugin_delegate_proxy.h +++ b/content/renderer/npapi/webplugin_delegate_proxy.h
@@ -67,9 +67,6 @@ NPObject* GetPluginScriptableObject() override; struct _NPP* GetPluginNPP() override; bool GetFormValue(base::string16* value) override; - void DidFinishLoadWithReason(const GURL& url, - NPReason reason, - int notify_id) override; void SetFocus(bool focused) override; bool HandleInputEvent(const blink::WebInputEvent& event, WebCursor::CursorInfo* cursor) override; @@ -111,39 +108,6 @@ // IPC::Sender implementation: bool Send(IPC::Message* msg) override; - void SendJavaScriptStream(const GURL& url, - const std::string& result, - bool success, - int notify_id) override; - - void DidReceiveManualResponse(const GURL& url, - const std::string& mime_type, - const std::string& headers, - uint32 expected_length, - uint32 last_modified) override; - void DidReceiveManualData(const char* buffer, int length) override; - void DidFinishManualLoading() override; - void DidManualLoadFail() override; - WebPluginResourceClient* CreateResourceClient(unsigned long resource_id, - const GURL& url, - int notify_id) override; - WebPluginResourceClient* CreateSeekableResourceClient( - unsigned long resource_id, - int range_request_id) override; - void FetchURL(unsigned long resource_id, - int notify_id, - const GURL& url, - const GURL& first_party_for_cookies, - const std::string& method, - const char* buf, - unsigned int len, - const Referrer& referrer, - bool notify_redirects, - bool is_plugin_src_load, - int origin_pid, - int render_frame_id, - int render_view_id) override; - gfx::PluginWindowHandle GetPluginWindowHandle(); protected:
diff --git a/content/renderer/npapi/webplugin_impl.cc b/content/renderer/npapi/webplugin_impl.cc index 91ffa938..1c9c7981 100644 --- a/content/renderer/npapi/webplugin_impl.cc +++ b/content/renderer/npapi/webplugin_impl.cc
@@ -362,23 +362,6 @@ delegate_->UpdateGeometry(new_geometry.window_rect, new_geometry.clip_rect); } - // Initiate a download on the plugin url. This should be done for the - // first update geometry sequence. We need to ensure that the plugin - // receives the geometry update before it starts receiving data. - if (first_geometry_update_) { - // An empty url corresponds to an EMBED tag with no src attribute. - if (!load_manually_ && plugin_url_.is_valid()) { - // The Flash plugin hangs for a while if it receives data before - // receiving valid plugin geometry. By valid geometry we mean the - // geometry received by a call to setFrameRect in the Webkit - // layout code path. To workaround this issue we download the - // plugin source url on a timer. - base::ThreadTaskRunnerHandle::Get()->PostTask( - FROM_HERE, base::Bind(&WebPluginImpl::OnDownloadPluginSrcUrl, - weak_factory_.GetWeakPtr())); - } - } - #if defined(OS_WIN) // Don't cache the geometry during the first geometry update. The first // geometry update sequence is received when Widget::setParent is called. @@ -439,58 +422,6 @@ : WebInputEventResult::NotHandled; } -void WebPluginImpl::didReceiveResponse(const WebURLResponse& response) { - ignore_response_error_ = false; - - ResponseInfo response_info; - GetResponseInfo(response, &response_info); - - delegate_->DidReceiveManualResponse( - response_info.url, - response_info.mime_type, - GetAllHeaders(response), - response_info.expected_length, - response_info.last_modified); -} - -void WebPluginImpl::didReceiveData(const char* data, int data_length) { - delegate_->DidReceiveManualData(data, data_length); -} - -void WebPluginImpl::didFinishLoading() { - delegate_->DidFinishManualLoading(); -} - -void WebPluginImpl::didFailLoading(const WebURLError& error) { - if (!ignore_response_error_) - delegate_->DidManualLoadFail(); -} - -void WebPluginImpl::didFinishLoadingFrameRequest( - const WebURL& url, void* notify_data) { - if (delegate_) { - // We're converting a void* into an arbitrary int id. Though - // these types are the same size on all the platforms we support, - // the compiler may complain as though they are different, so to - // make the casting gods happy go through an intptr_t (the union - // of void* and int) rather than converting straight across. - delegate_->DidFinishLoadWithReason( - url, NPRES_DONE, reinterpret_cast<intptr_t>(notify_data)); - } -} - -void WebPluginImpl::didFailLoadingFrameRequest( - const WebURL& url, void* notify_data, const WebURLError& error) { - if (!delegate_) - return; - - NPReason reason = - error.reason == net::ERR_ABORTED ? NPRES_USER_BREAK : NPRES_NETWORK_ERR; - // See comment in didFinishLoadingFrameRequest about the cast here. - delegate_->DidFinishLoadWithReason( - url, reason, reinterpret_cast<intptr_t>(notify_data)); -} - bool WebPluginImpl::isPlaceholder() { return false; } @@ -564,8 +495,7 @@ file_path_(file_path), mime_type_(base::ToLowerASCII(base::UTF16ToASCII( base::StringPiece16(params.mimeType)))), - loader_client_(this), - weak_factory_(this) { + loader_client_(this) { DCHECK_EQ(params.attributeNames.size(), params.attributeValues.size()); for (size_t i = 0; i < params.attributeNames.size(); ++i) { @@ -700,7 +630,6 @@ const char* target, const char* buf, unsigned int len, - int notify_id, ReferrerValue referrer_flag) { // If there is no target, there is nothing to do if (!target) @@ -764,8 +693,7 @@ } } - container_->loadFrameRequest( - request, target_str, notify_id != 0, reinterpret_cast<void*>(notify_id)); + container_->loadFrameRequest(request, target_str); return ROUTED; } @@ -903,12 +831,6 @@ container_->invalidateRect(rect); } -void WebPluginImpl::OnDownloadPluginSrcUrl() { - HandleURLRequestInternal( - plugin_url_.spec().c_str(), "GET", NULL, NULL, 0, 0, false, DOCUMENT_URL, - false, true); -} - WebPluginResourceClient* WebPluginImpl::GetClientFromLoader( WebURLLoader* loader) { ClientInfo* client_info = GetClientInfoFromLoader(loader); @@ -981,8 +903,6 @@ const WebURLResponse& response) { // TODO(jam): THIS LOGIC IS COPIED IN PluginURLFetcher::OnReceivedResponse // until kDirectNPAPIRequests is the default and we can remove this old path. - static const int kHttpPartialResponseStatusCode = 206; - static const int kHttpResponseSuccessStatusCode = 200; WebPluginResourceClient* client = GetClientFromLoader(loader); if (!client) @@ -994,64 +914,6 @@ if (!client_info) return; - bool request_is_seekable = true; - if (client->IsMultiByteResponseExpected()) { - if (response.httpStatusCode() == kHttpPartialResponseStatusCode) { - ClientInfo* client_info = GetClientInfoFromLoader(loader); - if (!client_info) - return; - if (HandleHttpMultipartResponse(response, client)) { - // Multiple ranges requested, data will be delivered by - // MultipartResponseDelegate. - client_info->data_offset = 0; - return; - } - int64 upper_bound = 0, instance_size = 0; - // Single range requested - go through original processing for - // non-multipart requests, but update data offset. - MultipartResponseDelegate::ReadContentRanges(response, - &client_info->data_offset, - &upper_bound, - &instance_size); - } else if (response.httpStatusCode() == kHttpResponseSuccessStatusCode) { - RenderThreadImpl::current()->RecordAction( - base::UserMetricsAction("Plugin_200ForByteRange")); - // If the client issued a byte range request and the server responds with - // HTTP 200 OK, it indicates that the server does not support byte range - // requests. - // We need to emulate Firefox behavior by doing the following:- - // 1. Destroy the plugin instance in the plugin process. Ensure that - // existing resource requests initiated for the plugin instance - // continue to remain valid. - // 2. Create a new plugin instance and notify it about the response - // received here. - if (!ReinitializePluginForResponse(loader)) { - NOTREACHED(); - return; - } - - // The server does not support byte range requests. No point in creating - // seekable streams. - request_is_seekable = false; - - delete client; - client = NULL; - - // Create a new resource client for this request. - for (size_t i = 0; i < clients_.size(); ++i) { - if (clients_[i].loader.get() == loader) { - WebPluginResourceClient* resource_client = - delegate_->CreateResourceClient(clients_[i].id, plugin_url_, 0); - clients_[i].client = resource_client; - client = resource_client; - break; - } - } - - DCHECK(client != NULL); - } - } - // Calling into a plugin could result in reentrancy if the plugin yields // control to the OS like entering a modal loop etc. Prevent this by // stopping further loading until the plugin notifies us that it is ready to @@ -1063,7 +925,7 @@ GetAllHeaders(response), response_info.expected_length, response_info.last_modified, - request_is_seekable); + true); // Bug http://b/issue?id=925559. The flash plugin would not handle the HTTP // error codes in the stream header and as a result, was unaware of the @@ -1161,121 +1023,6 @@ container_->allowScriptObjects(); } -void WebPluginImpl::HandleURLRequest(const char* url, - const char* method, - const char* target, - const char* buf, - unsigned int len, - int notify_id, - bool popups_allowed, - bool notify_redirects) { - // GetURL/PostURL requests initiated explicitly by plugins should specify the - // plugin SRC url as the referrer if it is available. - HandleURLRequestInternal( - url, method, target, buf, len, notify_id, popups_allowed, PLUGIN_SRC, - notify_redirects, false); -} - -void WebPluginImpl::HandleURLRequestInternal(const char* url, - const char* method, - const char* target, - const char* buf, - unsigned int len, - int notify_id, - bool popups_allowed, - ReferrerValue referrer_flag, - bool notify_redirects, - bool is_plugin_src_load) { - // For this request, we either route the output to a frame - // because a target has been specified, or we handle the request - // here, i.e. by executing the script if it is a javascript url - // or by initiating a download on the URL, etc. There is one special - // case in that the request is a javascript url and the target is "_self", - // in which case we route the output to the plugin rather than routing it - // to the plugin's frame. - bool is_javascript_url = - url::FindAndCompareScheme(url, strlen(url), url::kJavaScriptScheme, NULL); - RoutingStatus routing_status = RouteToFrame( - url, is_javascript_url, popups_allowed, method, target, buf, len, - notify_id, referrer_flag); - if (routing_status == ROUTED) - return; - - if (is_javascript_url) { - GURL gurl(url); - WebString result = container_->executeScriptURL(gurl, popups_allowed); - - // delegate_ could be NULL because executeScript caused the container to - // be deleted. - if (delegate_) { - delegate_->SendJavaScriptStream( - gurl, result.utf8(), !result.isNull(), notify_id); - } - - return; - } - - unsigned long resource_id = GetNextResourceId(); - if (!resource_id) - return; - - GURL complete_url = CompleteURL(url); - // Remove when flash bug is fixed. http://crbug.com/40016. - if (!WebPluginImpl::IsValidUrl(complete_url, referrer_flag)) - return; - - // If the RouteToFrame call returned a failure then inform the result - // back to the plugin asynchronously. - if ((routing_status == INVALID_URL) || - (routing_status == GENERAL_FAILURE)) { - WebPluginResourceClient* resource_client = delegate_->CreateResourceClient( - resource_id, complete_url, notify_id); - if (resource_client) - resource_client->DidFail(resource_id); - return; - } - - // CreateResourceClient() sends a synchronous IPC message so it's possible - // that TearDownPluginInstance() may have been called in the nested - // message loop. If so, don't start the request. - if (!delegate_) - return; - - if (!base::CommandLine::ForCurrentProcess()->HasSwitch( - switches::kDisableDirectNPAPIRequests)) { - // We got here either because the plugin called GetURL/PostURL, or because - // we're fetching the data for an embed tag. If we're in multi-process mode, - // we want to fetch the data in the plugin process as the renderer won't be - // able to request any origin when site isolation is in place. So bounce - // this request back to the plugin process which will use ResourceDispatcher - // to fetch the url. - - // TODO(jam): any better way of getting this? Can't find a way to get - // frame()->loader()->outgoingReferrer() which - // WebFrameImpl::setReferrerForRequest does. - WebURLRequest request(complete_url); - SetReferrer(&request, referrer_flag); - Referrer referrer( - GURL(request.httpHeaderField(WebString::fromUTF8("Referer"))), - request.referrerPolicy()); - - GURL first_party_for_cookies = webframe_->document().firstPartyForCookies(); - delegate_->FetchURL(resource_id, notify_id, complete_url, - first_party_for_cookies, method, buf, len, referrer, - notify_redirects, is_plugin_src_load, 0, - render_frame_->GetRoutingID(), - render_view_->GetRoutingID()); - } else { - WebPluginResourceClient* resource_client = delegate_->CreateResourceClient( - resource_id, complete_url, notify_id); - if (!resource_client) - return; - InitiateHTTPRequest(resource_id, resource_client, complete_url, method, buf, - len, NULL, referrer_flag, notify_redirects, - is_plugin_src_load); - } -} - unsigned long WebPluginImpl::GetNextResourceId() { if (!webframe_) return 0; @@ -1285,67 +1032,6 @@ return view->createUniqueIdentifierForRequest(); } -bool WebPluginImpl::InitiateHTTPRequest(unsigned long resource_id, - WebPluginResourceClient* client, - const GURL& url, - const char* method, - const char* buf, - int buf_len, - const char* range_info, - ReferrerValue referrer_flag, - bool notify_redirects, - bool is_plugin_src_load) { - if (!client) { - NOTREACHED(); - return false; - } - - ClientInfo info; - info.id = resource_id; - info.client = client; - info.request.initialize(); - info.request.setURL(url); - info.request.setFirstPartyForCookies( - webframe_->document().firstPartyForCookies()); - info.request.setRequestorProcessID(delegate_->GetProcessId()); - // TODO(mkwst): Is this a request for a plugin object itself - // (RequestContextObject), or a request that the plugin makes - // (RequestContextPlugin)? - info.request.setRequestContext(WebURLRequest::RequestContextPlugin); - info.request.setHTTPMethod(WebString::fromUTF8(method)); - // ServiceWorker is disabled for NPAPI. - info.request.setSkipServiceWorker(true); - info.pending_failure_notification = false; - info.notify_redirects = notify_redirects; - info.is_plugin_src_load = is_plugin_src_load; - info.data_offset = 0; - - if (range_info) { - info.request.addHTTPHeaderField(WebString::fromUTF8("Range"), - WebString::fromUTF8(range_info)); - } - - if (strcmp(method, "POST") == 0) { - // Adds headers or form data to a request. This must be called before - // we initiate the actual request. - SetPostData(&info.request, buf, buf_len); - } - - SetReferrer(&info.request, referrer_flag); - - WebURLLoaderOptions options; - options.allowCredentials = true; - options.crossOriginRequestPolicy = - WebURLLoaderOptions::CrossOriginRequestPolicyAllow; - info.loader.reset(webframe_->createAssociatedURLLoader(options)); - if (!info.loader.get()) - return false; - info.loader->loadAsynchronously(info.request, &loader_client_); - - clients_.push_back(info); - return true; -} - void WebPluginImpl::CancelDocumentLoad() { if (webframe_) { ignore_response_error_ = true; @@ -1353,25 +1039,6 @@ } } -void WebPluginImpl::InitiateHTTPRangeRequest( - const char* url, const char* range_info, int range_request_id) { - unsigned long resource_id = GetNextResourceId(); - if (!resource_id) - return; - - GURL complete_url = CompleteURL(url); - // Remove when flash bug is fixed. http://crbug.com/40016. - if (!WebPluginImpl::IsValidUrl(complete_url, - load_manually_ ? NO_REFERRER : PLUGIN_SRC)) - return; - - WebPluginResourceClient* resource_client = - delegate_->CreateSeekableResourceClient(resource_id, range_request_id); - InitiateHTTPRequest( - resource_id, resource_client, complete_url, "GET", NULL, 0, range_info, - load_manually_ ? NO_REFERRER : PLUGIN_SRC, false, false); -} - void WebPluginImpl::DidStartLoading() { if (render_view_.get()) { // TODO(darin): Make is_loading_ be a counter! @@ -1539,7 +1206,6 @@ // This needs to be called now and not in the destructor since the // webframe_ might not be valid anymore. webframe_ = NULL; - weak_factory_.InvalidateWeakPtrs(); } void WebPluginImpl::SetReferrer(blink::WebURLRequest* request,
diff --git a/content/renderer/npapi/webplugin_impl.h b/content/renderer/npapi/webplugin_impl.h index 3eb157eb..39e3226 100644 --- a/content/renderer/npapi/webplugin_impl.h +++ b/content/renderer/npapi/webplugin_impl.h
@@ -86,15 +86,10 @@ blink::WebInputEventResult handleInputEvent( const blink::WebInputEvent& event, blink::WebCursorInfo& cursor_info) override; - void didReceiveResponse(const blink::WebURLResponse& response) override; - void didReceiveData(const char* data, int data_length) override; - void didFinishLoading() override; - void didFailLoading(const blink::WebURLError& error) override; - void didFinishLoadingFrameRequest(const blink::WebURL& url, - void* notify_data) override; - void didFailLoadingFrameRequest(const blink::WebURL& url, - void* notify_data, - const blink::WebURLError& error) override; + void didReceiveResponse(const blink::WebURLResponse& response) override {} + void didReceiveData(const char* data, int data_length) override {} + void didFinishLoading() override {} + void didFailLoading(const blink::WebURLError& error) override {} bool isPlaceholder() override; // WebPlugin implementation: @@ -112,18 +107,7 @@ const std::string& cookie) override; std::string GetCookies(const GURL& url, const GURL& first_party_for_cookies) override; - void HandleURLRequest(const char* url, - const char* method, - const char* target, - const char* buf, - unsigned int len, - int notify_id, - bool popups_allowed, - bool notify_redirects) override; void CancelDocumentLoad() override; - void InitiateHTTPRangeRequest(const char* url, - const char* range_info, - int pending_request_id) override; void DidStartLoading() override; void DidStopLoading() override; bool IsOffTheRecord() override; @@ -175,26 +159,12 @@ const char* target, const char* buf, unsigned int len, - int notify_id, ReferrerValue referrer_flag); // Returns the next avaiable resource id. Returns 0 if the operation fails. // It may fail if the page has already been closed. unsigned long GetNextResourceId(); - // Initiates HTTP GET/POST requests. - // Returns true on success. - bool InitiateHTTPRequest(unsigned long resource_id, - WebPluginResourceClient* client, - const GURL& url, - const char* method, - const char* buf, - int len, - const char* range_info, - ReferrerValue referrer_flag, - bool notify_redirects, - bool check_mixed_scripting); - gfx::Rect GetWindowClipRect(const gfx::Rect& rect); // Sets the actual Widget for the plugin. @@ -239,24 +209,10 @@ bool HandleHttpMultipartResponse(const blink::WebURLResponse& response, WebPluginResourceClient* client); - void HandleURLRequestInternal(const char* url, - const char* method, - const char* target, - const char* buf, - unsigned int len, - int notify_id, - bool popups_allowed, - ReferrerValue referrer_flag, - bool notify_redirects, - bool check_mixed_scripting); - // Tears down the existing plugin instance and creates a new plugin instance // to handle the response identified by the loader parameter. bool ReinitializePluginForResponse(blink::WebURLLoader* loader); - // Delayed task for downloading the plugin source URL. - void OnDownloadPluginSrcUrl(); - struct ClientInfo; // Helper functions @@ -359,8 +315,6 @@ LoaderClient loader_client_; - base::WeakPtrFactory<WebPluginImpl> weak_factory_; - DISALLOW_COPY_AND_ASSIGN(WebPluginImpl); };
diff --git a/content/renderer/p2p/ipc_network_manager.cc b/content/renderer/p2p/ipc_network_manager.cc index f702e9e..1c9acb9 100644 --- a/content/renderer/p2p/ipc_network_manager.cc +++ b/content/renderer/p2p/ipc_network_manager.cc
@@ -80,10 +80,10 @@ if (!network_list_received_) network_list_received_ = true; - // Update the default local interfaces. - set_default_local_addresses( - jingle_glue::IPAddressNumberToIPAddress(default_ipv4_local_address), - jingle_glue::IPAddressNumberToIPAddress(default_ipv6_local_address)); + // Default addresses should be set only when they are in the filtered list of + // network addresses. + bool use_default_ipv4_address = false; + bool use_default_ipv6_address = false; // rtc::Network uses these prefix_length to compare network // interfaces discovered. @@ -102,6 +102,7 @@ rtc::InterfaceAddress iface_addr; if (it->address.size() == net::kIPv4AddressSize) { + use_default_ipv4_address |= (default_ipv4_local_address == it->address); iface_addr = rtc::InterfaceAddress(ip_address); } else { DCHECK(it->address.size() == net::kIPv6AddressSize); @@ -114,11 +115,26 @@ rtc::IPIsPrivate(iface_addr)) { continue; } + + use_default_ipv6_address |= (default_ipv6_local_address == it->address); } network->AddIP(iface_addr); networks.push_back(network.release()); } + // Update the default local addresses. + rtc::IPAddress ipv4_default; + rtc::IPAddress ipv6_defualt; + if (use_default_ipv4_address) { + ipv4_default = + jingle_glue::IPAddressNumberToIPAddress(default_ipv4_local_address); + } + if (use_default_ipv6_address) { + ipv6_defualt = + jingle_glue::IPAddressNumberToIPAddress(default_ipv6_local_address); + } + set_default_local_addresses(ipv4_default, ipv6_defualt); + if (base::CommandLine::ForCurrentProcess()->HasSwitch( switches::kAllowLoopbackInPeerConnection)) { std::string name_v4("loopback_ipv4");
diff --git a/content/renderer/pepper/pepper_plugin_instance_impl.cc b/content/renderer/pepper/pepper_plugin_instance_impl.cc index 811c107..d23f9f96 100644 --- a/content/renderer/pepper/pepper_plugin_instance_impl.cc +++ b/content/renderer/pepper/pepper_plugin_instance_impl.cc
@@ -3116,7 +3116,7 @@ WebString target_str = WebString::fromUTF8(target); blink::WebScopedUserGesture user_gesture(CurrentUserGestureToken()); - container_->loadFrameRequest(web_request, target_str, false, NULL); + container_->loadFrameRequest(web_request, target_str); return PP_OK; }
diff --git a/content/renderer/pepper/pepper_webplugin_impl.cc b/content/renderer/pepper/pepper_webplugin_impl.cc index e4bf44d6..0f53f2a8 100644 --- a/content/renderer/pepper/pepper_webplugin_impl.cc +++ b/content/renderer/pepper/pepper_webplugin_impl.cc
@@ -254,14 +254,6 @@ document_loader->didFail(NULL, error); } -void PepperWebPluginImpl::didFinishLoadingFrameRequest(const blink::WebURL& url, - void* notify_data) {} - -void PepperWebPluginImpl::didFailLoadingFrameRequest( - const blink::WebURL& url, - void* notify_data, - const blink::WebURLError& error) {} - bool PepperWebPluginImpl::hasSelection() const { return !selectionAsText().isEmpty(); }
diff --git a/content/renderer/pepper/pepper_webplugin_impl.h b/content/renderer/pepper/pepper_webplugin_impl.h index 6046406..5bfa988 100644 --- a/content/renderer/pepper/pepper_webplugin_impl.h +++ b/content/renderer/pepper/pepper_webplugin_impl.h
@@ -62,11 +62,6 @@ void didReceiveData(const char* data, int data_length) override; void didFinishLoading() override; void didFailLoading(const blink::WebURLError&) override; - void didFinishLoadingFrameRequest(const blink::WebURL& url, - void* notify_data) override; - void didFailLoadingFrameRequest(const blink::WebURL& url, - void* notify_data, - const blink::WebURLError& error) override; bool hasSelection() const override; blink::WebString selectionAsText() const override; blink::WebString selectionAsMarkup() const override;
diff --git a/content/renderer/pepper/video_decoder_shim.cc b/content/renderer/pepper/video_decoder_shim.cc index 84dd33a..9dab8b9 100644 --- a/content/renderer/pepper/video_decoder_shim.cc +++ b/content/renderer/pepper/video_decoder_shim.cc
@@ -868,18 +868,22 @@ base::Owned(decoder_impl_.release()))); } -bool VideoDecoderShim::Initialize( - media::VideoCodecProfile profile, - media::VideoDecodeAccelerator::Client* client) { +bool VideoDecoderShim::Initialize(const Config& vda_config, Client* client) { DCHECK_EQ(client, host_); DCHECK(RenderThreadImpl::current()); DCHECK_EQ(state_, UNINITIALIZED); + + if (vda_config.is_encrypted) { + NOTREACHED() << "Encrypted streams are not supported"; + return false; + } + media::VideoCodec codec = media::kUnknownVideoCodec; - if (profile <= media::H264PROFILE_MAX) + if (vda_config.profile <= media::H264PROFILE_MAX) codec = media::kCodecH264; - else if (profile <= media::VP8PROFILE_MAX) + else if (vda_config.profile <= media::VP8PROFILE_MAX) codec = media::kCodecVP8; - else if (profile <= media::VP9PROFILE_MAX) + else if (vda_config.profile <= media::VP9PROFILE_MAX) codec = media::kCodecVP9; DCHECK_NE(codec, media::kUnknownVideoCodec); @@ -889,8 +893,9 @@ if (!yuv_converter_->Initialize()) return false; - media::VideoDecoderConfig config( - codec, profile, media::PIXEL_FORMAT_YV12, media::COLOR_SPACE_UNSPECIFIED, + media::VideoDecoderConfig video_decoder_config( + codec, vda_config.profile, media::PIXEL_FORMAT_YV12, + media::COLOR_SPACE_UNSPECIFIED, gfx::Size(32, 24), // Small sizes that won't fail. gfx::Rect(32, 24), gfx::Size(32, 24), // TODO(bbudge): Verify extra data isn't needed. @@ -899,8 +904,7 @@ media_task_runner_->PostTask( FROM_HERE, base::Bind(&VideoDecoderShim::DecoderImpl::Initialize, - base::Unretained(decoder_impl_.get()), - config)); + base::Unretained(decoder_impl_.get()), video_decoder_config)); state_ = DECODING;
diff --git a/content/renderer/pepper/video_decoder_shim.h b/content/renderer/pepper/video_decoder_shim.h index deefdced..566a0de 100644 --- a/content/renderer/pepper/video_decoder_shim.h +++ b/content/renderer/pepper/video_decoder_shim.h
@@ -50,8 +50,7 @@ ~VideoDecoderShim() override; // media::VideoDecodeAccelerator implementation. - bool Initialize(media::VideoCodecProfile profile, - media::VideoDecodeAccelerator::Client* client) override; + bool Initialize(const Config& config, Client* client) override; void Decode(const media::BitstreamBuffer& bitstream_buffer) override; void AssignPictureBuffers( const std::vector<media::PictureBuffer>& buffers) override;
diff --git a/content/renderer/render_frame_impl.cc b/content/renderer/render_frame_impl.cc index 0db8f24e..860e3d5 100644 --- a/content/renderer/render_frame_impl.cc +++ b/content/renderer/render_frame_impl.cc
@@ -827,6 +827,7 @@ renderer_accessibility_(NULL), media_player_delegate_(NULL), is_using_lofi_(false), + is_pasting_(false), weak_factory_(this) { std::pair<RoutingIDFrameMap::iterator, bool> result = g_routing_id_frame_map.Get().insert(std::make_pair(routing_id_, this)); @@ -1242,6 +1243,7 @@ IPC_MESSAGE_HANDLER(FrameMsg_DidUpdateSandboxFlags, OnDidUpdateSandboxFlags) IPC_MESSAGE_HANDLER(FrameMsg_SetFrameOwnerProperties, OnSetFrameOwnerProperties) + IPC_MESSAGE_HANDLER(FrameMsg_AdvanceFocus, OnAdvanceFocus) IPC_MESSAGE_HANDLER(FrameMsg_SetTextTrackSettings, OnTextTrackSettingsChanged) IPC_MESSAGE_HANDLER(FrameMsg_PostMessageEvent, OnPostMessageEvent) @@ -1448,6 +1450,8 @@ // Internal request, forward to WebKit. context_menu_node_.reset(); } + + render_view()->webview()->didCloseContextMenu(); } void RenderFrameImpl::OnCustomContextMenuAction( @@ -1487,6 +1491,7 @@ void RenderFrameImpl::OnPaste() { base::AutoReset<bool> handling_select_range(&handling_select_range_, true); + base::AutoReset<bool> handling_paste(&is_pasting_, true); frame_->executeCommand(WebString::fromUTF8("Paste"), GetFocusedElement()); } @@ -1751,10 +1756,7 @@ if (!GetRenderWidget()->ShouldHandleImeEvent()) return; - DCHECK(!WebUserGestureIndicator::isProcessingUserGesture()); - ImeEventGuard guard(GetRenderWidget()); - blink::WebScopedUserGesture gesture_indicator; frame_->extendSelectionAndDelete(before, after); } @@ -1800,6 +1802,17 @@ frame_->setFrameOwnerProperties(frame_owner_properties); } +void RenderFrameImpl::OnAdvanceFocus(blink::WebFocusType type, + int32_t source_routing_id) { + RenderFrameProxy* source_frame = + RenderFrameProxy::FromRoutingID(source_routing_id); + if (!source_frame) + return; + + render_view_->webview()->advanceFocusAcrossFrames( + type, source_frame->web_frame(), frame_); +} + void RenderFrameImpl::OnTextTrackSettingsChanged( const FrameMsg_TextTrackSettings_Params& params) { DCHECK(!frame_->parent()); @@ -2160,6 +2173,10 @@ return is_using_lofi_; } +bool RenderFrameImpl::IsPasting() const { + return is_pasting_; +} + // blink::WebFrameClient implementation ---------------------------------------- blink::WebPlugin* RenderFrameImpl::createPlugin( @@ -3369,6 +3386,10 @@ void RenderFrameImpl::showContextMenu(const blink::WebContextMenuData& data) { ContextMenuParams params = ContextMenuParamsBuilder::Build(data); + blink::WebRect position_in_window(params.x, params.y, 0, 0); + GetRenderWidget()->convertViewportToWindow(&position_in_window); + params.x = position_in_window.x; + params.y = position_in_window.y; params.source_type = GetRenderWidget()->context_menu_source_type(); GetRenderWidget()->OnShowHostContextMenu(¶ms); if (GetRenderWidget()->has_host_context_menu_location()) { @@ -3723,16 +3744,6 @@ DidChangePerformanceTiming()); } -void RenderFrameImpl::didAbortLoading(blink::WebLocalFrame* frame) { - DCHECK(!frame_ || frame_ == frame); -#if defined(ENABLE_PLUGINS) - if (frame != render_view_->webview()->mainFrame()) - return; - PluginChannelHost::Broadcast( - new PluginHostMsg_DidAbortLoading(render_view_->GetRoutingID())); -#endif -} - void RenderFrameImpl::didCreateScriptContext(blink::WebLocalFrame* frame, v8::Local<v8::Context> context, int extension_group,
diff --git a/content/renderer/render_frame_impl.h b/content/renderer/render_frame_impl.h index 374e09d..bae9b33 100644 --- a/content/renderer/render_frame_impl.h +++ b/content/renderer/render_frame_impl.h
@@ -29,6 +29,7 @@ #include "media/blink/webmediaplayer_params.h" #include "mojo/application/public/interfaces/service_provider.mojom.h" #include "mojo/application/public/interfaces/shell.mojom.h" +#include "third_party/WebKit/public/platform/WebFocusType.h" #include "third_party/WebKit/public/platform/modules/app_banner/WebAppBannerClient.h" #include "third_party/WebKit/public/web/WebAXObject.h" #include "third_party/WebKit/public/web/WebDataSource.h" @@ -392,6 +393,7 @@ void AddMessageToConsole(ConsoleMessageLevel level, const std::string& message) override; bool IsUsingLoFi() const override; + bool IsPasting() const override; // blink::WebFrameClient implementation: blink::WebPlugin* createPlugin(blink::WebLocalFrame* frame, @@ -531,7 +533,6 @@ const blink::WebURL& main_resource_url, const blink::WebCString& main_resource_security_info) override; void didChangePerformanceTiming() override; - void didAbortLoading(blink::WebLocalFrame* frame) override; void didCreateScriptContext(blink::WebLocalFrame* frame, v8::Local<v8::Context> context, int extension_group, @@ -746,6 +747,7 @@ void OnDidUpdateSandboxFlags(blink::WebSandboxFlags flags); void OnSetFrameOwnerProperties( const blink::WebFrameOwnerProperties& frame_owner_properties); + void OnAdvanceFocus(blink::WebFocusType type, int32_t source_routing_id); void OnTextTrackSettingsChanged( const FrameMsg_TextTrackSettings_Params& params); void OnPostMessageEvent(const FrameMsg_PostMessage_Params& params); @@ -1111,6 +1113,9 @@ // Whether or not this RenderFrame is using Lo-Fi mode. bool is_using_lofi_; + // Whether or not this RenderFrame is currently pasting. + bool is_pasting_; + #if defined(ENABLE_WEBVR) // The VR dispatcher attached to the frame, lazily initialized. scoped_ptr<VRDispatcher> vr_dispatcher_;
diff --git a/content/renderer/render_frame_proxy.cc b/content/renderer/render_frame_proxy.cc index 600d478..f753af4 100644 --- a/content/renderer/render_frame_proxy.cc +++ b/content/renderer/render_frame_proxy.cc
@@ -444,4 +444,10 @@ Send(new FrameHostMsg_DidChangeOpener(routing_id_, opener_routing_id)); } +void RenderFrameProxy::advanceFocus(blink::WebFocusType type, + blink::WebLocalFrame* source) { + int source_routing_id = RenderFrameImpl::FromWebFrame(source)->GetRoutingID(); + Send(new FrameHostMsg_AdvanceFocus(routing_id_, type, source_routing_id)); +} + } // namespace
diff --git a/content/renderer/render_frame_proxy.h b/content/renderer/render_frame_proxy.h index d54e15e..1e4c288 100644 --- a/content/renderer/render_frame_proxy.h +++ b/content/renderer/render_frame_proxy.h
@@ -10,6 +10,7 @@ #include "content/common/content_export.h" #include "ipc/ipc_listener.h" #include "ipc/ipc_sender.h" +#include "third_party/WebKit/public/platform/WebFocusType.h" #include "third_party/WebKit/public/web/WebRemoteFrame.h" #include "third_party/WebKit/public/web/WebRemoteFrameClient.h" #include "url/origin.h" @@ -132,6 +133,8 @@ void forwardInputEvent(const blink::WebInputEvent* event) override; void frameRectsChanged(const blink::WebRect& frame_rect) override; void didChangeOpener(blink::WebFrame* opener) override; + void advanceFocus(blink::WebFocusType type, + blink::WebLocalFrame* source) override; // IPC handlers void OnDidStartLoading();
diff --git a/content/renderer/render_thread_impl.cc b/content/renderer/render_thread_impl.cc index 992825b..4bf3ebcf 100644 --- a/content/renderer/render_thread_impl.cc +++ b/content/renderer/render_thread_impl.cc
@@ -148,6 +148,7 @@ #include "third_party/WebKit/public/web/WebFrame.h" #include "third_party/WebKit/public/web/WebImageCache.h" #include "third_party/WebKit/public/web/WebKit.h" +#include "third_party/WebKit/public/web/WebMemoryPressureListener.h" #include "third_party/WebKit/public/web/WebNetworkStateNotifier.h" #include "third_party/WebKit/public/web/WebRuntimeFeatures.h" #include "third_party/WebKit/public/web/WebScriptController.h" @@ -203,7 +204,7 @@ #if defined(MOJO_SHELL_CLIENT) #include "content/public/common/mojo_shell_connection.h" -#include "content/renderer/render_widget_window_tree_client_factory.h" +#include "content/renderer/mus/render_widget_window_tree_client_factory.h" #endif using base::ThreadRestrictions; @@ -1854,7 +1855,7 @@ // Do not call into blink if it is not initialized. if (blink_platform_impl_) { - blink::WebCache::pruneAll(); + blink::WebMemoryPressureListener::onMemoryPressure(); if (blink::mainThreadIsolate()) { // Trigger full v8 garbage collection on memory pressure notifications.
diff --git a/content/renderer/render_view_browsertest.cc b/content/renderer/render_view_browsertest.cc index bcdc6afd..3e3c3364b 100644 --- a/content/renderer/render_view_browsertest.cc +++ b/content/renderer/render_view_browsertest.cc
@@ -366,7 +366,7 @@ class RenderViewImplBlinkSettingsTest : public RenderViewImplTest { public: - void DoSetUp() { + virtual void DoSetUp() { RenderViewImplTest::SetUp(); } @@ -384,6 +384,22 @@ void SetUp() override {} }; +class RenderViewImplScaleFactorTest : public RenderViewImplBlinkSettingsTest { + public: + void DoSetUp() override { + RenderViewImplBlinkSettingsTest::DoSetUp(); + + ViewMsg_Resize_Params params; + params.screen_info.deviceScaleFactor = 2.f; + params.new_size = gfx::Size(100, 100); + params.physical_backing_size = gfx::Size(200, 200); + params.visible_viewport_size = params.new_size; + params.needs_resize_ack = false; + view()->OnResize(params); + ASSERT_EQ(2.f, view()->device_scale_factor_); + } +}; + // Ensure that the main RenderFrame is deleted and cleared from the RenderView // after closing it. TEST_F(RenderViewImplTest, RenderFrameClearedAfterClose) { @@ -479,6 +495,7 @@ EXPECT_TRUE(render_thread_->sink().GetUniqueMessageMatching( ViewHostMsg_UpdateState::ID)); } + ProcessPendingMessages(); } TEST_F(RenderViewImplTest, OnNavigationHttpPost) { @@ -1072,6 +1089,7 @@ // message to activate IMEs. view()->UpdateTextInputState( RenderWidget::NO_SHOW_IME, RenderWidget::FROM_NON_IME); + ProcessPendingMessages(); const IPC::Message* msg = render_thread_->sink().GetMessageAt(0); EXPECT_TRUE(msg != NULL); EXPECT_EQ(ViewHostMsg_TextInputStateChanged::ID, msg->type()); @@ -2471,6 +2489,29 @@ EXPECT_TRUE(settings()->viewportEnabled()); } +TEST_F(RenderViewImplScaleFactorTest, ConverViewportToWindowWithoutZoomForDSF) { + DoSetUp(); + blink::WebRect rect(20, 10, 200, 100); + view()->convertViewportToWindow(&rect); + EXPECT_EQ(20, rect.x); + EXPECT_EQ(10, rect.y); + EXPECT_EQ(200, rect.width); + EXPECT_EQ(100, rect.height); +} + +TEST_F(RenderViewImplScaleFactorTest, ConverViewportToWindowWithZoomForDSF) { + base::CommandLine::ForCurrentProcess()->AppendSwitch( + switches::kEnableUseZoomForDSF); + DoSetUp(); + + blink::WebRect rect(20, 10, 200, 100); + view()->convertViewportToWindow(&rect); + EXPECT_EQ(10, rect.x); + EXPECT_EQ(5, rect.y); + EXPECT_EQ(100, rect.width); + EXPECT_EQ(50, rect.height); +} + TEST_F(DevToolsAgentTest, DevToolsResumeOnClose) { Attach(); EXPECT_FALSE(IsPaused());
diff --git a/content/renderer/render_view_impl.cc b/content/renderer/render_view_impl.cc index e71d180..a5aa817 100644 --- a/content/renderer/render_view_impl.cc +++ b/content/renderer/render_view_impl.cc
@@ -88,7 +88,6 @@ #include "content/renderer/mhtml_generator.h" #include "content/renderer/mojo_bindings_controller.h" #include "content/renderer/navigation_state_impl.h" -#include "content/renderer/net_info_helper.h" #include "content/renderer/render_frame_impl.h" #include "content/renderer/render_frame_proxy.h" #include "content/renderer/render_process.h" @@ -149,7 +148,6 @@ #include "third_party/WebKit/public/web/WebLocalFrame.h" #include "third_party/WebKit/public/web/WebMediaPlayerAction.h" #include "third_party/WebKit/public/web/WebNavigationPolicy.h" -#include "third_party/WebKit/public/web/WebNetworkStateNotifier.h" #include "third_party/WebKit/public/web/WebPageImportanceSignals.h" #include "third_party/WebKit/public/web/WebPlugin.h" #include "third_party/WebKit/public/web/WebPluginAction.h" @@ -274,7 +272,6 @@ using blink::WebView; using blink::WebWidget; using blink::WebWindowFeatures; -using blink::WebNetworkStateNotifier; using blink::WebRuntimeFeatures; using base::Time; using base::TimeDelta; @@ -989,8 +986,6 @@ settings->setAccelerated2dCanvasMSAASampleCount( prefs.accelerated_2d_canvas_msaa_sample_count); - settings->setAsynchronousSpellCheckingEnabled( - prefs.asynchronous_spell_checking_enabled); settings->setUnifiedTextCheckerEnabled(prefs.unified_textchecker_enabled); // Tabs to link is not part of the settings. WebCore calls @@ -1112,11 +1107,6 @@ settings->setMainFrameResizesAreOrientationChanges( prefs.main_frame_resizes_are_orientation_changes); - WebNetworkStateNotifier::setOnLine(prefs.is_online); - WebNetworkStateNotifier::setWebConnection( - NetConnectionTypeToWebConnectionType(prefs.net_info_connection_type), - prefs.net_info_max_bandwidth_mbps); - settings->setPinchOverlayScrollbarThickness( prefs.pinch_overlay_scrollbar_thickness); settings->setUseSolidColorScrollbars(prefs.use_solid_color_scrollbars); @@ -1941,7 +1931,9 @@ bool is_editable = false; if (!toNode.isNull() && toNode.isElementNode()) { WebElement element = const_cast<WebNode&>(toNode).to<WebElement>(); - node_bounds = gfx::Rect(element.boundsInViewport()); + blink::WebRect rect = element.boundsInViewport(); + convertViewportToWindow(&rect); + node_bounds = gfx::Rect(rect); is_editable = element.isEditable(); } Send(new ViewHostMsg_FocusedNodeChanged(routing_id_, is_editable, @@ -2136,6 +2128,10 @@ return renderer_preferences_.accept_languages; } +void RenderViewImpl::convertViewportToWindow(blink::WebRect* rect) { + RenderWidget::convertViewportToWindow(rect); +} + void RenderViewImpl::didChangeIcon(WebLocalFrame* frame, WebIconURL::Type icon_type) { if (frame->parent())
diff --git a/content/renderer/render_view_impl.h b/content/renderer/render_view_impl.h index 9ab5603..9a9d986 100644 --- a/content/renderer/render_view_impl.h +++ b/content/renderer/render_view_impl.h
@@ -450,6 +450,8 @@ TopControlsState current, bool animate) override; #endif + void convertViewportToWindow(blink::WebRect* rect) override; + bool uses_temporary_zoom_level() const { return uses_temporary_zoom_level_; } // Please do not add your stuff randomly to the end here. If there is an @@ -510,6 +512,7 @@ private: // For unit tests. friend class DevToolsAgentTest; + friend class RenderViewImplScaleFactorTest; friend class RenderViewImplTest; friend class RenderViewTest; friend class RendererAccessibilityTest; @@ -559,6 +562,8 @@ FRIEND_TEST_ALL_PREFIXES(RenderViewImplTest, SendCandidateWindowEvents); FRIEND_TEST_ALL_PREFIXES(RenderViewImplTest, RenderFrameClearedAfterClose); FRIEND_TEST_ALL_PREFIXES(RenderViewImplTest, PaintAfterSwapOut); + FRIEND_TEST_ALL_PREFIXES(RenderViewImplScaleFactorTest, + ConverViewportToScreenWithZoomForDSF); typedef std::map<GURL, double> HostZoomLevels;
diff --git a/content/renderer/render_widget.cc b/content/renderer/render_widget.cc index be6f8cb..cb094441 100644 --- a/content/renderer/render_widget.cc +++ b/content/renderer/render_widget.cc
@@ -96,7 +96,7 @@ #if defined(MOJO_SHELL_CLIENT) #include "content/public/common/mojo_shell_connection.h" -#include "content/renderer/render_widget_mus_connection.h" +#include "content/renderer/mus/render_widget_mus_connection.h" #endif #include "third_party/WebKit/public/web/WebWidget.h" @@ -246,6 +246,50 @@ } } +void LogPassiveLatency(int64 latency) { + UMA_HISTOGRAM_CUSTOM_COUNTS("Event.PassiveListeners.Latency", latency, 1, + 10000000, 100); +} + +void LogPassiveEventListenersUma(WebInputEventResult result, + bool passive, + bool cancelable, + double event_timestamp, + const ui::LatencyInfo& latency_info) { + enum { + PASSIVE_LISTENER_UMA_ENUM_PASSIVE, + PASSIVE_LISTENER_UMA_ENUM_UNCANCELABLE, + PASSIVE_LISTENER_UMA_ENUM_SUPPRESSED, + PASSIVE_LISTENER_UMA_ENUM_CANCELABLE, + PASSIVE_LISTENER_UMA_ENUM_CANCELABLE_AND_CANCELED, + PASSIVE_LISTENER_UMA_ENUM_COUNT + }; + + int enum_value; + if (passive) + enum_value = PASSIVE_LISTENER_UMA_ENUM_PASSIVE; + else if (!cancelable) + enum_value = PASSIVE_LISTENER_UMA_ENUM_UNCANCELABLE; + else if (result == WebInputEventResult::HandledApplication) + enum_value = PASSIVE_LISTENER_UMA_ENUM_CANCELABLE_AND_CANCELED; + else if (result == WebInputEventResult::HandledSuppressed) + enum_value = PASSIVE_LISTENER_UMA_ENUM_SUPPRESSED; + else + enum_value = PASSIVE_LISTENER_UMA_ENUM_CANCELABLE; + + UMA_HISTOGRAM_ENUMERATION("Event.PassiveListeners", enum_value, + PASSIVE_LISTENER_UMA_ENUM_COUNT); + + if (enum_value == PASSIVE_LISTENER_UMA_ENUM_CANCELABLE && + base::TimeTicks::IsHighResolution()) { + base::TimeTicks now = base::TimeTicks::Now(); + LogPassiveLatency(GetEventLatencyMicros(event_timestamp, now)); + for (size_t i = 0; i < latency_info.coalesced_events_size(); i++) + LogPassiveLatency(GetEventLatencyMicros( + latency_info.timestamps_of_coalesced_events()[i], now)); + } +} + } // namespace namespace content { @@ -1106,6 +1150,9 @@ const ui::LatencyInfo& latency_info) { if (!input_event) return; + + // TODO(dtapuska): Passive support not implemented yet crbug.com/489802 + bool passive = false; base::AutoReset<bool> handling_input_event_resetter(&handling_input_event_, true); base::AutoReset<WebInputEvent::Type> handling_event_type_resetter( @@ -1191,12 +1238,28 @@ prevent_default = prevent_default || WillHandleGestureEvent(gesture_event); } - bool processed = prevent_default; + WebInputEventResult processed = + prevent_default ? WebInputEventResult::HandledSuppressed + : WebInputEventResult::NotHandled; if (input_event->type != WebInputEvent::Char || !suppress_next_char_events_) { suppress_next_char_events_ = false; - if (!processed && webwidget_) - processed = webwidget_->handleInputEvent(*input_event) != - WebInputEventResult::NotHandled; + if (processed == WebInputEventResult::NotHandled && webwidget_) + processed = webwidget_->handleInputEvent(*input_event); + } + + // TODO(dtapuska): Use the input_event->timeStampSeconds as the start + // ideally this should be when the event was sent by the compositor to the + // renderer. crbug.com/565348 + if (input_event->type == WebInputEvent::TouchStart || + input_event->type == WebInputEvent::TouchMove || + input_event->type == WebInputEvent::TouchEnd) { + LogPassiveEventListenersUma( + processed, passive, + static_cast<const WebTouchEvent*>(input_event)->cancelable, + input_event->timeStampSeconds, latency_info); + } else if (input_event->type == WebInputEvent::MouseWheel) { + LogPassiveEventListenersUma(processed, passive, !passive, + input_event->timeStampSeconds, latency_info); } // If this RawKeyDown event corresponds to a browser keyboard shortcut and @@ -1205,12 +1268,14 @@ bool is_keyboard_shortcut = input_event->type == WebInputEvent::RawKeyDown && static_cast<const WebKeyboardEvent*>(input_event)->isBrowserShortcut; - if (!processed && is_keyboard_shortcut) + if (processed == WebInputEventResult::NotHandled && is_keyboard_shortcut) suppress_next_char_events_ = true; - InputEventAckState ack_result = processed ? - INPUT_EVENT_ACK_STATE_CONSUMED : INPUT_EVENT_ACK_STATE_NOT_CONSUMED; - if (!processed && input_event->type == WebInputEvent::TouchStart) { + InputEventAckState ack_result = processed == WebInputEventResult::NotHandled + ? INPUT_EVENT_ACK_STATE_NOT_CONSUMED + : INPUT_EVENT_ACK_STATE_CONSUMED; + if (processed == WebInputEventResult::NotHandled && + input_event->type == WebInputEvent::TouchStart) { const WebTouchEvent& touch_event = *static_cast<const WebTouchEvent*>(input_event); // Hit-test for all the pressed touch points. If there is a touch-handler @@ -1234,7 +1299,7 @@ static_cast<const WebMouseWheelEvent&>(*input_event), event_overscroll ? event_overscroll->latest_overscroll_delta : gfx::Vector2dF(), - processed); + processed != WebInputEventResult::NotHandled); } bool frame_pending = compositor_ && compositor_->BeginMainFrameRequested(); @@ -1301,13 +1366,16 @@ #if defined(OS_ANDROID) // Allow the IME to be shown when the focus changes as a consequence // of a processed touch end event. - if (input_event->type == WebInputEvent::TouchEnd && processed) + if (input_event->type == WebInputEvent::TouchEnd && + processed != WebInputEventResult::NotHandled) { UpdateTextInputState(SHOW_IME_IF_NEEDED, FROM_NON_IME); + } #elif defined(USE_AURA) // Show the virtual keyboard if enabled and a user gesture triggers a focus // change. - if (processed && (input_event->type == WebInputEvent::TouchEnd || - input_event->type == WebInputEvent::MouseUp)) { + if (processed != WebInputEventResult::NotHandled && + (input_event->type == WebInputEvent::TouchEnd || + input_event->type == WebInputEvent::MouseUp)) { UpdateTextInputState(SHOW_IME_IF_NEEDED, FROM_IME); } #endif @@ -1321,8 +1389,9 @@ // virtual keyboard. #if !defined(OS_ANDROID) // Virtual keyboard is not supported, so react to focus change immediately. - if (processed && (input_event->type == WebInputEvent::TouchEnd || - input_event->type == WebInputEvent::MouseUp)) { + if (processed != WebInputEventResult::NotHandled && + (input_event->type == WebInputEvent::TouchEnd || + input_event->type == WebInputEvent::MouseUp)) { FocusChangeComplete(); } #endif @@ -1778,6 +1847,20 @@ OnShowImeIfNeeded(); } +void RenderWidget::convertViewportToWindow(blink::WebRect* rect) { + if (IsUseZoomForDSFEnabled()) { + float reverse = 1 / device_scale_factor_; + // TODO(oshima): We may wait to allow pixel precision here as the the + // anchor element can be placed at half pixel. + gfx::Rect window_rect = + gfx::ScaleToEnclosedRect(gfx::Rect(*rect), reverse); + rect->x = window_rect.x(); + rect->y = window_rect.y(); + rect->width = window_rect.width(); + rect->height = window_rect.height(); + } +} + void RenderWidget::OnShowImeIfNeeded() { #if defined(OS_ANDROID) || defined(USE_AURA) UpdateTextInputState(SHOW_IME_IF_NEEDED, FROM_NON_IME);
diff --git a/content/renderer/render_widget.h b/content/renderer/render_widget.h index 1b2cbff..f9b2d4f1 100644 --- a/content/renderer/render_widget.h +++ b/content/renderer/render_widget.h
@@ -197,6 +197,10 @@ const blink::WebFloatSize& velocity) override; void showImeIfNeeded() override; + // Converts the |rect| from Viewport coordinates to Window coordinates. + // See RenderView::convertViewportToWindow for more details. + void convertViewportToWindow(blink::WebRect* rect); + #if defined(OS_ANDROID) // Notifies that a tap was not consumed, so showing a UI for the unhandled // tap may be needed.
diff --git a/content/renderer/render_widget_mus_connection.cc b/content/renderer/render_widget_mus_connection.cc deleted file mode 100644 index e0e81a5..0000000 --- a/content/renderer/render_widget_mus_connection.cc +++ /dev/null
@@ -1,99 +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. - -#include "content/renderer/render_widget_mus_connection.h" - -#include <map> - -#include "base/lazy_instance.h" -#include "components/mus/public/cpp/context_provider.h" -#include "components/mus/public/cpp/output_surface.h" -#include "components/mus/public/interfaces/command_buffer.mojom.h" -#include "components/mus/public/interfaces/compositor_frame.mojom.h" -#include "components/mus/public/interfaces/gpu.mojom.h" -#include "components/mus/public/interfaces/window_tree.mojom.h" -#include "content/public/common/mojo_shell_connection.h" -#include "mojo/application/public/cpp/application_impl.h" -#include "mojo/converters/geometry/geometry_type_converters.h" -#include "mojo/converters/surfaces/surfaces_utils.h" - -namespace content { - -namespace { - -typedef std::map<int, RenderWidgetMusConnection*> ConnectionMap; -base::LazyInstance<ConnectionMap>::Leaky g_connections = - LAZY_INSTANCE_INITIALIZER; -} - -RenderWidgetMusConnection::RenderWidgetMusConnection(int routing_id) - : routing_id_(routing_id), root_(nullptr) { - DCHECK(routing_id); -} - -RenderWidgetMusConnection::~RenderWidgetMusConnection() {} - -void RenderWidgetMusConnection::Bind( - mojo::InterfaceRequest<mus::mojom::WindowTreeClient> request) { - DCHECK(!root_); - mus::WindowTreeConnection::Create( - this, request.Pass(), - mus::WindowTreeConnection::CreateType::DONT_WAIT_FOR_EMBED); -} - -scoped_ptr<cc::OutputSurface> RenderWidgetMusConnection::CreateOutputSurface() { - DCHECK(!window_surface_binding_); - mus::mojom::GpuPtr gpu_service; - MojoShellConnection::Get()->GetApplication()->ConnectToService("mojo:mus", - &gpu_service); - mus::mojom::CommandBufferPtr cb; - gpu_service->CreateOffscreenGLES2Context(GetProxy(&cb)); - scoped_refptr<cc::ContextProvider> context_provider( - new mus::ContextProvider(cb.PassInterface().PassHandle())); - scoped_ptr<cc::OutputSurface> output_surface(new mus::OutputSurface( - context_provider, mus::WindowSurface::Create(&window_surface_binding_))); - if (root_) { - root_->AttachSurface(mus::mojom::SURFACE_TYPE_DEFAULT, - window_surface_binding_.Pass()); - } - return output_surface.Pass(); -} - -// static -RenderWidgetMusConnection* RenderWidgetMusConnection::GetOrCreate( - int routing_id) { - auto it = g_connections.Get().find(routing_id); - if (it != g_connections.Get().end()) - return it->second; - - RenderWidgetMusConnection* connection = - new RenderWidgetMusConnection(routing_id); - g_connections.Get().insert(std::make_pair(routing_id, connection)); - return connection; -} - -void RenderWidgetMusConnection::OnConnectionLost( - mus::WindowTreeConnection* connection) { - g_connections.Get().erase(routing_id_); - delete this; -} - -void RenderWidgetMusConnection::OnEmbed(mus::Window* root) { - root_ = root; - root_->AddObserver(this); - if (window_surface_binding_) { - root->AttachSurface(mus::mojom::SURFACE_TYPE_DEFAULT, - window_surface_binding_.Pass()); - } -} - -void RenderWidgetMusConnection::OnUnembed() {} - -void RenderWidgetMusConnection::OnWindowBoundsChanged( - mus::Window* window, - const gfx::Rect& old_bounds, - const gfx::Rect& new_bounds) { -} - -} // namespace content
diff --git a/content/renderer/render_widget_mus_connection.h b/content/renderer/render_widget_mus_connection.h deleted file mode 100644 index b3f4549..0000000 --- a/content/renderer/render_widget_mus_connection.h +++ /dev/null
@@ -1,53 +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. - -#ifndef CONTENT_RENDERER_RENDER_WIDGET_MUS_CONNECTION_H_ -#define CONTENT_RENDERER_RENDER_WIDGET_MUS_CONNECTION_H_ - -#include "base/macros.h" -#include "cc/output/output_surface.h" -#include "components/mus/public/cpp/window.h" -#include "components/mus/public/cpp/window_observer.h" -#include "components/mus/public/cpp/window_surface.h" -#include "components/mus/public/cpp/window_tree_connection.h" -#include "components/mus/public/cpp/window_tree_delegate.h" -#include "mojo/public/cpp/bindings/binding.h" - -namespace content { - -class RenderWidgetMusConnection : public mus::WindowTreeDelegate, - public mus::WindowObserver { - public: - explicit RenderWidgetMusConnection(int routing_id); - ~RenderWidgetMusConnection() override; - - // Connect to a WindowTreeClient request. - void Bind(mojo::InterfaceRequest<mus::mojom::WindowTreeClient> request); - - // Create a cc output surface. - scoped_ptr<cc::OutputSurface> CreateOutputSurface(); - - // Get the connection from a routing_id, if the connection doesn't exist, - // a new connection will be created. - static RenderWidgetMusConnection* GetOrCreate(int routing_id); - - private: - // WindowTreeDelegate implementation: - void OnConnectionLost(mus::WindowTreeConnection* connection) override; - void OnEmbed(mus::Window* root) override; - void OnUnembed() override; - void OnWindowBoundsChanged(mus::Window* window, - const gfx::Rect& old_bounds, - const gfx::Rect& new_bounds) override; - - const int routing_id_; - mus::Window* root_; - scoped_ptr<mus::WindowSurfaceBinding> window_surface_binding_; - - DISALLOW_COPY_AND_ASSIGN(RenderWidgetMusConnection); -}; - -} // namespace content - -#endif // CONTENT_RENDERER_RENDER_WIDGET_MUS_CONNECTION_H_
diff --git a/content/renderer/render_widget_window_tree_client_factory.h b/content/renderer/render_widget_window_tree_client_factory.h deleted file mode 100644 index 09eb36b98..0000000 --- a/content/renderer/render_widget_window_tree_client_factory.h +++ /dev/null
@@ -1,14 +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. - -#ifndef CONTENT_RENDERER_RENDER_WIDGET_WINDOW_TREE_CLIENT_FACTORY_H_ -#define CONTENT_RENDERER_RENDER_WIDGET_WINDOW_TREE_CLIENT_FACTORY_H_ - -namespace content { - -void CreateRenderWidgetWindowTreeClientFactory(); - -} // namespace content - -#endif // CONTENT_RENDERER_RENDER_WIDGET_WINDOW_TREE_CLIENT_FACTORY_H_
diff --git a/content/renderer/renderer_main_platform_delegate_win.cc b/content/renderer/renderer_main_platform_delegate_win.cc index aae8ea1..675961d 100644 --- a/content/renderer/renderer_main_platform_delegate_win.cc +++ b/content/renderer/renderer_main_platform_delegate_win.cc
@@ -87,9 +87,6 @@ // Cause advapi32 to load before the sandbox is turned on. unsigned int dummy_rand; rand_s(&dummy_rand); - // Warm up language subsystems before the sandbox is turned on. - ::GetUserDefaultLangID(); - ::GetUserDefaultLCID(); target_services->LowerToken(); return true;
diff --git a/content/shell/android/javatests/src/org/chromium/content_shell_apk/ContentShellTestBase.java b/content/shell/android/javatests/src/org/chromium/content_shell_apk/ContentShellTestBase.java index f002c553..d5e54857 100644 --- a/content/shell/android/javatests/src/org/chromium/content_shell_apk/ContentShellTestBase.java +++ b/content/shell/android/javatests/src/org/chromium/content_shell_apk/ContentShellTestBase.java
@@ -78,7 +78,7 @@ protected void startActivityWithTestUrl(String url) throws Throwable { launchContentShellWithUrl(UrlUtils.getIsolatedTestFileUrl(url)); assertNotNull(getActivity()); - assertTrue(waitForActiveShellToBeDoneLoading()); + waitForActiveShellToBeDoneLoading(); assertEquals(UrlUtils.getIsolatedTestFileUrl(url), getContentViewCore().getWebContents().getUrl()); } @@ -102,14 +102,13 @@ * WAIT_FOR_ACTIVE_SHELL_LOADING_TIMEOUT milliseconds and it shouldn't be used for long * loading pages. Instead it should be used more for test initialization. The proper way * to wait is to use a TestCallbackHelperContainer after the initial load is completed. - * @return Whether or not the Shell was actually finished loading. * @throws InterruptedException */ - protected boolean waitForActiveShellToBeDoneLoading() throws InterruptedException { + protected void waitForActiveShellToBeDoneLoading() throws InterruptedException { final ContentShellActivity activity = getActivity(); // Wait for the Content Shell to be initialized. - return CriteriaHelper.pollForUIThreadCriteria(new Criteria() { + CriteriaHelper.pollForUIThreadCriteria(new Criteria() { @Override public boolean isSatisfied() { Shell shell = activity.getActiveShell(); @@ -117,9 +116,19 @@ // The first is that we've just created a Shell and it isn't // loading because it has no URL set yet. The second is that // we've set a URL and it actually is loading. - if (shell == null) return false; - return !shell.isLoading() && !TextUtils.isEmpty(shell.getContentViewCore() - .getWebContents().getUrl()); + if (shell == null) { + updateFailureReason("Shell is null."); + return false; + } + if (shell.isLoading()) { + updateFailureReason("Shell is still loading."); + return false; + } + if (TextUtils.isEmpty(shell.getContentViewCore().getWebContents().getUrl())) { + updateFailureReason("Shell's URL is empty or null."); + return false; + } + return true; } }, WAIT_FOR_ACTIVE_SHELL_LOADING_TIMEOUT, CriteriaHelper.DEFAULT_POLLING_INTERVAL); } @@ -191,12 +200,12 @@ */ protected void assertWaitForPageScaleFactorMatch(final float expectedScale) throws InterruptedException { - assertTrue(CriteriaHelper.pollForCriteria(new Criteria() { + CriteriaHelper.pollForCriteria(new Criteria() { @Override public boolean isSatisfied() { return getContentViewCore().getScale() == expectedScale; } - })); + }); } /**
diff --git a/content/shell/browser/layout_test/layout_test_bluetooth_adapter_provider.cc b/content/shell/browser/layout_test/layout_test_bluetooth_adapter_provider.cc index d8f2d76..32f7d6368 100644 --- a/content/shell/browser/layout_test/layout_test_bluetooth_adapter_provider.cc +++ b/content/shell/browser/layout_test/layout_test_bluetooth_adapter_provider.cc
@@ -216,7 +216,7 @@ // matching the address provided if the device was added to the mock. ON_CALL(*adapter, GetDevice(_)).WillByDefault(GetMockDevice(adapter.get())); - return adapter.Pass(); + return adapter; } // static @@ -225,7 +225,7 @@ scoped_refptr<NiceMockBluetoothAdapter> adapter(GetBaseAdapter()); ON_CALL(*adapter, IsPresent()).WillByDefault(Return(true)); - return adapter.Pass(); + return adapter; } // static @@ -234,7 +234,7 @@ scoped_refptr<NiceMockBluetoothAdapter> adapter(GetBaseAdapter()); ON_CALL(*adapter, IsPresent()).WillByDefault(Return(false)); - return adapter.Pass(); + return adapter; } // static @@ -243,7 +243,7 @@ scoped_refptr<NiceMockBluetoothAdapter> adapter(GetPresentAdapter()); ON_CALL(*adapter, IsPowered()).WillByDefault(Return(true)); - return adapter.Pass(); + return adapter; } // static @@ -252,7 +252,7 @@ scoped_refptr<NiceMockBluetoothAdapter> adapter(GetPresentAdapter()); ON_CALL(*adapter, IsPowered()).WillByDefault(Return(false)); - return adapter.Pass(); + return adapter; } // static @@ -279,7 +279,7 @@ // We need to add a device otherwise requestDevice would reject. adapter->AddMockDevice(GetBatteryDevice(adapter.get())); - return adapter.Pass(); + return adapter; } // static @@ -290,7 +290,7 @@ ON_CALL(*adapter, StartDiscoverySessionWithFilterRaw(_, _, _)) .WillByDefault(RunCallback<2 /* error_callback */>()); - return adapter.Pass(); + return adapter; } // static @@ -302,7 +302,7 @@ .WillByDefault(RunCallbackWithResult<1 /* success_callback */>( []() { return GetDiscoverySession(); })); - return adapter.Pass(); + return adapter; } // static @@ -342,7 +342,7 @@ adapter->AddMockDevice(GetHeartRateDevice(adapter.get())); adapter->AddMockDevice(GetGlucoseDevice(adapter.get())); - return adapter.Pass(); + return adapter; } // static @@ -352,7 +352,7 @@ adapter->AddMockDevice(GetBaseDevice(adapter.get(), "❤❤❤❤❤❤❤❤❤")); - return adapter.Pass(); + return adapter; } // Adds a device to |adapter| and notifies all observers about that new device. @@ -396,7 +396,7 @@ adapter->AddMockDevice(GetHeartRateDevice(adapter.get())); - return adapter.Pass(); + return adapter; } // static @@ -417,7 +417,7 @@ device->AddMockService(heart_rate.Pass()); adapter->AddMockDevice(device.Pass()); - return adapter.Pass(); + return adapter; } // static @@ -462,7 +462,7 @@ adapter->AddMockDevice(device.Pass()); - return adapter.Pass(); + return adapter; } // static @@ -492,7 +492,7 @@ adapter.get(), static_cast<BluetoothDevice::ConnectErrorCode>(error))); } - return adapter.Pass(); + return adapter; } // static @@ -521,7 +521,7 @@ device->AddMockService(service.Pass()); adapter->AddMockDevice(device.Pass()); - return adapter.Pass(); + return adapter; } // Discovery Sessions @@ -535,7 +535,7 @@ ON_CALL(*discovery_session, Stop(_, _)) .WillByDefault(RunCallback<0 /* success_callback */>()); - return discovery_session.Pass(); + return discovery_session; } // Devices @@ -573,7 +573,7 @@ ON_CALL(*device, GetProductID()).WillByDefault(Return(1)); ON_CALL(*device, GetDeviceID()).WillByDefault(Return(2)); - return device.Pass(); + return device; } // static @@ -619,7 +619,7 @@ adapter, device_ptr->GetAddress())); })); - return device.Pass(); + return device; } // static @@ -637,7 +637,7 @@ ON_CALL(*device, CreateGattConnection(_, _)) .WillByDefault(RunCallback<1 /* error_callback */>(error_code)); - return device.Pass(); + return device; } // static @@ -670,7 +670,7 @@ .WillByDefault(Invoke(service.get(), &MockBluetoothGattService::GetMockCharacteristic)); - return service.Pass(); + return service; } // static @@ -731,7 +731,7 @@ notify_session->StartTestNotifications(adapter, measurement_ptr, rate); - return notify_session.Pass(); + return notify_session; })); // Body Sensor Location Characteristic @@ -800,7 +800,7 @@ ON_CALL(*characteristic, StartNotifySession(_, _)) .WillByDefault(RunCallback<1 /* error_callback */>(error_code)); - return characteristic.Pass(); + return characteristic; } // Notify sessions @@ -819,7 +819,7 @@ &MockBluetoothGattNotifySession::StopTestNotifications), RunCallback<0>())); - return session.Pass(); + return session; } // Helper functions
diff --git a/content/shell/renderer/layout_test/blink_test_helpers.cc b/content/shell/renderer/layout_test/blink_test_helpers.cc index 97b2b8a..8039179 100644 --- a/content/shell/renderer/layout_test/blink_test_helpers.cc +++ b/content/shell/renderer/layout_test/blink_test_helpers.cc
@@ -41,8 +41,6 @@ from.allow_display_of_insecure_content; to->allow_running_insecure_content = from.allow_running_of_insecure_content; to->should_respect_image_orientation = from.should_respect_image_orientation; - to->asynchronous_spell_checking_enabled = - from.asynchronous_spell_checking_enabled; to->allow_file_access_from_file_urls = from.allow_file_access_from_file_urls; to->javascript_can_open_windows_automatically = from.java_script_can_open_windows_automatically; @@ -98,7 +96,6 @@ prefs->sans_serif_font_family_map[kCommonScript] = base::ASCIIToUTF16("Helvetica"); prefs->minimum_logical_font_size = 9; - prefs->asynchronous_spell_checking_enabled = false; prefs->accelerated_2d_canvas_enabled = command_line.HasSwitch(switches::kEnableAccelerated2DCanvas); prefs->mock_scrollbars_enabled = false;
diff --git a/content/shell/tools/plugin/PluginTest.cpp b/content/shell/tools/plugin/PluginTest.cpp index d0a56c71..fa95d891 100644 --- a/content/shell/tools/plugin/PluginTest.cpp +++ b/content/shell/tools/plugin/PluginTest.cpp
@@ -135,16 +135,6 @@ // NPN functions. -NPError PluginTest::NPN_GetURL(const char* url, const char* target) { - return browser->geturl(m_npp, url, target); -} - -NPError PluginTest::NPN_GetURLNotify(const char* url, - const char* target, - void* notifyData) { - return browser->geturlnotify(m_npp, url, target, notifyData); -} - NPError PluginTest::NPN_GetValue(NPNVariable variable, void* value) { return browser->getvalue(m_npp, variable, value); }
diff --git a/content/shell/tools/plugin/PluginTest.h b/content/shell/tools/plugin/PluginTest.h index 82093ae3..5df0620 100644 --- a/content/shell/tools/plugin/PluginTest.h +++ b/content/shell/tools/plugin/PluginTest.h
@@ -98,10 +98,6 @@ virtual NPError NPP_SetValue(NPNVariable, void* value); // NPN functions. - NPError NPN_GetURL(const char* url, const char* target); - NPError NPN_GetURLNotify(const char* url, - const char* target, - void* notifyData); NPError NPN_GetValue(NPNVariable, void* value); void NPN_InvalidateRect(NPRect* invalidRect); bool NPN_Invoke(NPObject*,
diff --git a/content/shell/tools/plugin/Tests/DocumentOpenInDestroyStream.cpp b/content/shell/tools/plugin/Tests/DocumentOpenInDestroyStream.cpp deleted file mode 100644 index b4b2e8f..0000000 --- a/content/shell/tools/plugin/Tests/DocumentOpenInDestroyStream.cpp +++ /dev/null
@@ -1,59 +0,0 @@ -// Copyright 2014 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -/* - * Copyright (C) 2010 Apple 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: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. 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. - * - * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS 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 APPLE INC. OR ITS 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. - */ - -#include "PluginTest.h" - -using namespace std; - -extern bool testDocumentOpen(NPP npp); - -// Call document.open from NPP_DestroyStream. - -class DocumentOpenInDestroyStream : public PluginTest { -public: - DocumentOpenInDestroyStream(NPP npp, const string& identifier) - : PluginTest(npp, identifier) - , m_shouldOpen(true) - { - } - -private: - NPError NPP_DestroyStream(NPStream*, NPReason) override { - if (m_shouldOpen) { - testDocumentOpen(m_npp); - m_shouldOpen = false; - } - - return NPERR_NO_ERROR; - } - - bool m_shouldOpen; -}; - -static PluginTest::Register<DocumentOpenInDestroyStream> documentOpenInDestroyStream("document-open-in-destroy-stream");
diff --git a/content/shell/tools/plugin/Tests/GetURLNotifyWithURLThatFailsToLoad.cpp b/content/shell/tools/plugin/Tests/GetURLNotifyWithURLThatFailsToLoad.cpp deleted file mode 100644 index cfbc2cd..0000000 --- a/content/shell/tools/plugin/Tests/GetURLNotifyWithURLThatFailsToLoad.cpp +++ /dev/null
@@ -1,80 +0,0 @@ -// Copyright 2014 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -/* - * Copyright (C) 2011 Apple 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: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. 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. - * - * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS 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 APPLE INC. OR ITS 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. - */ - -#include "PluginTest.h" - -#include <string.h> - -using namespace std; - -// From NPP_New, call NPN_GetURLNotify with a URL that fails to load (NPP_NewStream won't be called). -// The plugin should still get a NPP_URLNotify indicating that the load failed. -static const char *urlThatFailsToLoad = "foo://bar/"; - -class GetURLNotifyWithURLThatFailsToLoad : public PluginTest { -public: - GetURLNotifyWithURLThatFailsToLoad(NPP npp, const string& identifier) - : PluginTest(npp, identifier) - { - } - -private: - NPError NPP_New(NPMIMEType pluginType, - uint16_t mode, - int16_t argc, - char* argn[], - char* argv[], - NPSavedData* saved) override { - NPN_GetURLNotify(urlThatFailsToLoad, 0, reinterpret_cast<void*>(0x12345678)); - return NPERR_NO_ERROR; - } - - bool NPP_URLNotify(const char* url, - NPReason reason, - void* notifyData) override { - bool didFail = false; - - if (strcmp(url, urlThatFailsToLoad)) - didFail = true; - - if (reason != NPRES_NETWORK_ERR) - didFail = true; - - if (notifyData != reinterpret_cast<void*>(0x12345678)) - didFail = true; - - if (!didFail) - executeScript("testSucceeded()"); - else - executeScript("notifyDone()"); - return true; - } -}; - -static PluginTest::Register<GetURLNotifyWithURLThatFailsToLoad> getURLWithJavaScriptURLDestroyingPlugin("get-url-notify-with-url-that-fails-to-load");
diff --git a/content/shell/tools/plugin/Tests/GetURLWithJavaScriptURL.cpp b/content/shell/tools/plugin/Tests/GetURLWithJavaScriptURL.cpp deleted file mode 100644 index 336a370..0000000 --- a/content/shell/tools/plugin/Tests/GetURLWithJavaScriptURL.cpp +++ /dev/null
@@ -1,122 +0,0 @@ -// Copyright 2014 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -/* - * Copyright (C) 2011 Apple 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: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. 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. - * - * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS 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 APPLE INC. OR ITS 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. - */ - -#include "PluginTest.h" - -#include <string.h> -#include <vector> - -using namespace std; - -const char *javaScriptURL = "javascript:'Hello, ' + 'World!'"; -const char *javaScriptResult = "Hello, World!"; - -// Test that evaluating a javascript: URL will send a stream with the result of the evaluation. -// Test that evaluating JavaScript using NPN_GetURL will a stream with result of the evaluation. -class GetURLWithJavaScriptURL : public PluginTest { -public: - GetURLWithJavaScriptURL(NPP npp, const string& identifier) - : PluginTest(npp, identifier) - , m_didFail(false) - { - } - -private: - NPError NPP_New(NPMIMEType pluginType, - uint16_t mode, - int16_t argc, - char* argn[], - char* argv[], - NPSavedData* saved) override { - NPN_GetURL(javaScriptURL, 0); - return NPERR_NO_ERROR; - } - - NPError NPP_NewStream(NPMIMEType type, - NPStream* stream, - NPBool seekable, - uint16_t* stype) override { - stream->pdata = this; - - if (strcmp(stream->url, javaScriptURL)) - m_didFail = true; - - if (stream->end != strlen(javaScriptResult)) - m_didFail = true; - - *stype = NP_NORMAL; - return NPERR_NO_ERROR; - } - - NPError NPP_DestroyStream(NPStream* stream, NPReason reason) override { - if (stream->pdata != this) - m_didFail = true; - - if (reason != NPRES_DONE) - m_didFail = true; - - if (m_data.size() != stream->end) - m_didFail = true; - - m_data.push_back('\0'); - - if (strcmp(&m_data[0], javaScriptResult)) - m_didFail = true; - - if (!m_didFail) - executeScript("testSucceeded()"); - else - executeScript("notifyDone()"); - - return NPERR_NO_ERROR; - } - - int32_t NPP_WriteReady(NPStream* stream) override { - if (stream->pdata != this) - m_didFail = true; - - return 2; - } - - int32_t NPP_Write(NPStream* stream, - int32_t offset, - int32_t len, - void* buffer) override { - if (stream->pdata != this) - m_didFail = true; - - m_data.insert(m_data.end(), static_cast<char*>(buffer), static_cast<char*>(buffer) + len); - return len; - } - - vector<char> m_data; - bool m_didFail; -}; - -static PluginTest::Register<GetURLWithJavaScriptURL> getURLWithJavaScriptURLDestroyingPlugin("get-url-with-javascript-url");
diff --git a/content/shell/tools/plugin/Tests/GetURLWithJavaScriptURLDestroyingPlugin.cpp b/content/shell/tools/plugin/Tests/GetURLWithJavaScriptURLDestroyingPlugin.cpp deleted file mode 100644 index 4e7470f..0000000 --- a/content/shell/tools/plugin/Tests/GetURLWithJavaScriptURLDestroyingPlugin.cpp +++ /dev/null
@@ -1,55 +0,0 @@ -// Copyright 2014 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -/* - * Copyright (C) 2011 Apple 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: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. 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. - * - * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS 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 APPLE INC. OR ITS 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. - */ - -#include "PluginTest.h" - -using namespace std; - -// From NPP_New, call NPN_GetURL to evaluate JavaScript that destroys the plugin. - -class GetURLWithJavaScriptURLDestroyingPlugin : public PluginTest { -public: - GetURLWithJavaScriptURLDestroyingPlugin(NPP npp, const string& identifier) - : PluginTest(npp, identifier) - { - } - -private: - NPError NPP_New(NPMIMEType pluginType, - uint16_t mode, - int16_t argc, - char* argn[], - char* argv[], - NPSavedData* saved) override { - NPN_GetURL("javascript:removePlugin()", 0); - return NPERR_NO_ERROR; - } -}; - -static PluginTest::Register<GetURLWithJavaScriptURLDestroyingPlugin> getURLWithJavaScriptURLDestroyingPlugin("get-url-with-javascript-url-destroying-plugin");
diff --git a/content/test/ct/OWNERS b/content/test/ct/OWNERS new file mode 100644 index 0000000..ba6979dc --- /dev/null +++ b/content/test/ct/OWNERS
@@ -0,0 +1,4 @@ +rmistry@chromium.org +benjaminwagner@chromium.org +borenet@chromium.org +jcgregorio@chromium.org
diff --git a/content/test/ct/run_ct_dm.py b/content/test/ct/run_ct_dm.py index 35cf3db..3b1e57e 100755 --- a/content/test/ct/run_ct_dm.py +++ b/content/test/ct/run_ct_dm.py
@@ -13,8 +13,10 @@ PARENT_DIR = os.path.dirname(os.path.realpath(__file__)) -SKIA_SRC_DIR = os.path.normpath(os.path.join( - PARENT_DIR, os.pardir, os.pardir, os.pardir, os.pardir, 'skia')) +REPOS_BASE_DIR = os.path.normpath(os.path.join( + PARENT_DIR, os.pardir, os.pardir, os.pardir, os.pardir)) + +SKIA_SRC_DIR = os.path.join(REPOS_BASE_DIR, 'skia') def main(): @@ -24,7 +26,7 @@ args = parser.parse_args() dm_path = os.path.join(SKIA_SRC_DIR, 'out', 'Debug', 'dm') - skps_dir = os.path.join(PARENT_DIR, 'slave%d' % args.slave_num, 'skps') + skps_dir = os.path.join(REPOS_BASE_DIR, 'skps', 'slave%d' % args.slave_num) resource_path = os.path.join(SKIA_SRC_DIR, 'resources') # TODO(rmistry): Double check the below DM configuration with mtklein@. We
diff --git a/content/test/data/accessibility/aria/aria-math-expected-mac.txt b/content/test/data/accessibility/aria/aria-math-expected-mac.txt index 70676613..af70c5b 100644 --- a/content/test/data/accessibility/aria/aria-math-expected-mac.txt +++ b/content/test/data/accessibility/aria/aria-math-expected-mac.txt
@@ -1,3 +1,2 @@ AXWebArea AXRoleDescription='HTML content' ++AXGroup AXSubrole=AXDocumentMath AXRoleDescription='math' -++++AXStaticText AXRoleDescription='text' AXValue='ARIA role math.'
diff --git a/content/test/data/accessibility/aria/aria-math-expected-win.txt b/content/test/data/accessibility/aria/aria-math-expected-win.txt index eb7d71c..41bb7b47 100644 --- a/content/test/data/accessibility/aria/aria-math-expected-win.txt +++ b/content/test/data/accessibility/aria/aria-math-expected-win.txt
@@ -1,3 +1,2 @@ ROLE_SYSTEM_DOCUMENT READONLY FOCUSABLE ++ROLE_SYSTEM_EQUATION xml-roles:math -++++ROLE_SYSTEM_STATICTEXT name='ARIA role math.'
diff --git a/content/test/data/accessibility/aria/aria-searchbox-expected-mac.txt b/content/test/data/accessibility/aria/aria-searchbox-expected-mac.txt index ad6b005..fe4bf976 100644 --- a/content/test/data/accessibility/aria/aria-searchbox-expected-mac.txt +++ b/content/test/data/accessibility/aria/aria-searchbox-expected-mac.txt
@@ -1,3 +1,2 @@ AXWebArea AXRoleDescription='HTML content' ++AXTextField AXSubrole=AXSearchField AXRoleDescription='search text field' AXValue='ARIA role searchbox.' -++++AXStaticText AXRoleDescription='text' AXValue='ARIA role searchbox.'
diff --git a/content/test/data/accessibility/aria/aria-searchbox-expected-win.txt b/content/test/data/accessibility/aria/aria-searchbox-expected-win.txt index 49831153..1b9c772 100644 --- a/content/test/data/accessibility/aria/aria-searchbox-expected-win.txt +++ b/content/test/data/accessibility/aria/aria-searchbox-expected-win.txt
@@ -1,3 +1,2 @@ ROLE_SYSTEM_DOCUMENT READONLY FOCUSABLE ia2_hypertext='<obj0>' n_selections=0 ++ROLE_SYSTEM_TEXT FOCUSABLE xml-roles:searchbox ia2_hypertext='ARIA role searchbox.' caret_offset=0 n_selections=0 -++++ROLE_SYSTEM_STATICTEXT name='ARIA role searchbox.' ia2_hypertext='ARIA role searchbox.' n_selections=0
diff --git a/content/test/data/accessibility/aria/aria-searchbox-with-selection-expected-mac.txt b/content/test/data/accessibility/aria/aria-searchbox-with-selection-expected-mac.txt index ad6b005..fe4bf976 100644 --- a/content/test/data/accessibility/aria/aria-searchbox-with-selection-expected-mac.txt +++ b/content/test/data/accessibility/aria/aria-searchbox-with-selection-expected-mac.txt
@@ -1,3 +1,2 @@ AXWebArea AXRoleDescription='HTML content' ++AXTextField AXSubrole=AXSearchField AXRoleDescription='search text field' AXValue='ARIA role searchbox.' -++++AXStaticText AXRoleDescription='text' AXValue='ARIA role searchbox.'
diff --git a/content/test/data/accessibility/aria/aria-searchbox-with-selection-expected-win.txt b/content/test/data/accessibility/aria/aria-searchbox-with-selection-expected-win.txt index 6d9618b..57ea7b64 100644 --- a/content/test/data/accessibility/aria/aria-searchbox-with-selection-expected-win.txt +++ b/content/test/data/accessibility/aria/aria-searchbox-with-selection-expected-win.txt
@@ -1,3 +1,2 @@ ROLE_SYSTEM_DOCUMENT READONLY FOCUSABLE ia2_hypertext='<obj0>' caret_offset=1 n_selections=1 selection_start=0 selection_end=1 ++ROLE_SYSTEM_TEXT FOCUSABLE xml-roles:searchbox ia2_hypertext='ARIA role searchbox.' caret_offset=20 n_selections=1 selection_start=0 selection_end=20 -++++ROLE_SYSTEM_STATICTEXT name='ARIA role searchbox.' ia2_hypertext='ARIA role searchbox.' caret_offset=20 n_selections=1 selection_start=0 selection_end=20
diff --git a/content/test/data/accessibility/aria/aria-searchbox.html b/content/test/data/accessibility/aria/aria-searchbox.html index 447fa07..2be4998 100644 --- a/content/test/data/accessibility/aria/aria-searchbox.html +++ b/content/test/data/accessibility/aria/aria-searchbox.html
@@ -12,7 +12,8 @@ <!DOCTYPE html> <html> <body> - <!-- There should be no caret because searchbox is not content editable. --> + <!-- There should be no selection on the document because the search box is + not content editable. --> <div id="searchbox" role="searchbox" tabindex="0">ARIA role searchbox.</div> <script> var searchbox = document.getElementById('searchbox');
diff --git a/content/test/data/accessibility/aria/aria-separator-expected-mac.txt b/content/test/data/accessibility/aria/aria-separator-expected-mac.txt index 502c447..b4cff15 100644 --- a/content/test/data/accessibility/aria/aria-separator-expected-mac.txt +++ b/content/test/data/accessibility/aria/aria-separator-expected-mac.txt
@@ -2,6 +2,5 @@ ++AXGroup AXRoleDescription='group' ++++AXStaticText AXRoleDescription='text' AXValue='Before' ++AXSplitter AXRoleDescription='splitter' -++++AXStaticText AXRoleDescription='text' AXValue='This is ARIA separator.' ++AXGroup AXRoleDescription='group' ++++AXStaticText AXRoleDescription='text' AXValue='After'
diff --git a/content/test/data/accessibility/aria/aria-separator-expected-win.txt b/content/test/data/accessibility/aria/aria-separator-expected-win.txt index b4c7f55..70a8bc6 100644 --- a/content/test/data/accessibility/aria/aria-separator-expected-win.txt +++ b/content/test/data/accessibility/aria/aria-separator-expected-win.txt
@@ -2,6 +2,5 @@ ++IA2_ROLE_SECTION ++++ROLE_SYSTEM_STATICTEXT name='Before' ++ROLE_SYSTEM_SEPARATOR xml-roles:separator -++++ROLE_SYSTEM_STATICTEXT name='This is ARIA separator.' ++IA2_ROLE_SECTION ++++ROLE_SYSTEM_STATICTEXT name='After'
diff --git a/content/test/data/accessibility/aria/aria-textbox.html b/content/test/data/accessibility/aria/aria-textbox.html index d3f1e85f..25bb225 100644 --- a/content/test/data/accessibility/aria/aria-textbox.html +++ b/content/test/data/accessibility/aria/aria-textbox.html
@@ -12,6 +12,8 @@ <!DOCTYPE html> <html> <body> + <!-- There should be no selection on the document because the textboxes are + not content editable. --> <div role="textbox">TextBox1</div> <div role="textbox" aria-multiline="true">TextBox2</div> </body>
diff --git a/content/test/data/accessibility/html/math-expected-mac.txt b/content/test/data/accessibility/html/math-expected-mac.txt index c99b0d23..b0f74f5 100644 --- a/content/test/data/accessibility/html/math-expected-mac.txt +++ b/content/test/data/accessibility/html/math-expected-mac.txt
@@ -1,8 +1,3 @@ AXWebArea AXRoleDescription='HTML content' ++AXGroup AXRoleDescription='group' ++++AXGroup AXSubrole=AXDocumentMath AXRoleDescription='math' -++++++AXStaticText AXRoleDescription='text' AXValue='a' -++++++AXStaticText AXRoleDescription='text' AXValue='2' -++++++AXStaticText AXRoleDescription='text' AXValue='+' -++++++AXStaticText AXRoleDescription='text' AXValue='b' -++++++AXStaticText AXRoleDescription='text' AXValue='2'
diff --git a/content/test/data/accessibility/html/math-expected-win.txt b/content/test/data/accessibility/html/math-expected-win.txt index fd6bdb0..99306aa4d 100644 --- a/content/test/data/accessibility/html/math-expected-win.txt +++ b/content/test/data/accessibility/html/math-expected-win.txt
@@ -1,8 +1,3 @@ ROLE_SYSTEM_DOCUMENT READONLY FOCUSABLE ++IA2_ROLE_SECTION ++++ROLE_SYSTEM_EQUATION -++++++ROLE_SYSTEM_STATICTEXT name='a' -++++++ROLE_SYSTEM_STATICTEXT name='2' -++++++ROLE_SYSTEM_STATICTEXT name='+' -++++++ROLE_SYSTEM_STATICTEXT name='b' -++++++ROLE_SYSTEM_STATICTEXT name='2'
diff --git a/content/test/layouttest_support.cc b/content/test/layouttest_support.cc index b33a505..68869aca 100644 --- a/content/test/layouttest_support.cc +++ b/content/test/layouttest_support.cc
@@ -362,7 +362,7 @@ render_process_host_impl->GetBluetoothDispatcherHost(); if (dispatcher_host != NULL) - dispatcher_host->SetBluetoothAdapterForTesting(adapter.Pass()); + dispatcher_host->SetBluetoothAdapterForTesting(std::move(adapter)); } void SetGeofencingMockProvider(bool service_available) {
diff --git a/content/test/web_contents_observer_sanity_checker.cc b/content/test/web_contents_observer_sanity_checker.cc index a27c96b..ce22bed 100644 --- a/content/test/web_contents_observer_sanity_checker.cc +++ b/content/test/web_contents_observer_sanity_checker.cc
@@ -54,6 +54,12 @@ static_cast<RenderFrameHostImpl*>(render_frame_host)->IsRenderFrameLive()) << "RenderFrameCreated called on for a RenderFrameHost that thinks it is " "not alive."; + + // Any child frame must be in the same BrowsingInstance as its parent. + if (render_frame_host->GetParent()) { + CHECK(render_frame_host->GetSiteInstance()->IsRelatedSiteInstance( + render_frame_host->GetParent()->GetSiteInstance())); + } } void WebContentsObserverSanityChecker::RenderFrameDeleted(
diff --git a/device/BUILD.gn b/device/BUILD.gn index 5c53606..1d0e641 100644 --- a/device/BUILD.gn +++ b/device/BUILD.gn
@@ -62,6 +62,7 @@ "//device/bluetooth", "//device/bluetooth:mocks", "//device/nfc", + "//mojo/common", "//mojo/environment:chromium", "//mojo/public/cpp/bindings", "//net", @@ -134,6 +135,7 @@ # UsbContext is a libusb-specific object. if (!is_android && !is_ios) { sources += [ "usb/usb_context_unittest.cc" ] + deps += [ "//third_party/libusb" ] } if (is_android) {
diff --git a/device/bluetooth/BUILD.gn b/device/bluetooth/BUILD.gn index aae32f6..4bfdaec 100644 --- a/device/bluetooth/BUILD.gn +++ b/device/bluetooth/BUILD.gn
@@ -116,10 +116,11 @@ deps = [ "//base", "//crypto", + "//device/bluetooth/strings", + "//device/bluetooth/uribeacon", + "//ipc", "//net", "//ui/base", - "strings", - "uribeacon", ] if (is_android) {
diff --git a/device/devices_app/BUILD.gn b/device/devices_app/BUILD.gn index 3b13142c..2601cf2 100644 --- a/device/devices_app/BUILD.gn +++ b/device/devices_app/BUILD.gn
@@ -20,6 +20,7 @@ "//device/core", "//device/devices_app/usb/public/interfaces", "//device/usb", + "//mojo/common", "//mojo/public/cpp/bindings", "//mojo/public/cpp/bindings:callback", "//net",
diff --git a/device/serial/BUILD.gn b/device/serial/BUILD.gn index f66cedfe..474317e 100644 --- a/device/serial/BUILD.gn +++ b/device/serial/BUILD.gn
@@ -49,6 +49,7 @@ ] deps = [ "//mojo/public/cpp/system", + "//net", "//third_party/re2", ] @@ -56,7 +57,10 @@ deps += [ "//device/udev_linux" ] } if (is_chromeos) { - deps += [ "//chromeos" ] + deps += [ + "//chromeos", + "//dbus", + ] } }
diff --git a/device/serial/serial_io_handler.cc b/device/serial/serial_io_handler.cc index 1cfb1cd..b9df970 100644 --- a/device/serial/serial_io_handler.cc +++ b/device/serial/serial_io_handler.cc
@@ -12,7 +12,7 @@ #if defined(OS_CHROMEOS) #include "chromeos/dbus/dbus_thread_manager.h" #include "chromeos/dbus/permission_broker_client.h" -#include "dbus/file_descriptor.h" +#include "dbus/file_descriptor.h" // nogncheck #endif // defined(OS_CHROMEOS) namespace device {
diff --git a/device/test/test_device_client.cc b/device/test/test_device_client.cc index f380c2c..ff6933e 100644 --- a/device/test/test_device_client.cc +++ b/device/test/test_device_client.cc
@@ -4,8 +4,12 @@ #include "device/test/test_device_client.h" -#include "device/hid/hid_service.h" -#include "device/usb/usb_service.h" +// This file unconditionally includes these headers despite conditionally +// depending on the corresponding targets. The code below needs the destructors +// of the classes defined even when the classes are never instantiated. +// TODO: This should probably be done more explicitly to avoid ambiguity. +#include "device/hid/hid_service.h" // nogncheck +#include "device/usb/usb_service.h" // nogncheck namespace device {
diff --git a/device/usb/usb_device_impl.cc b/device/usb/usb_device_impl.cc index e1fc4025..ab9bd4ae 100644 --- a/device/usb/usb_device_impl.cc +++ b/device/usb/usb_device_impl.cc
@@ -22,7 +22,7 @@ #if defined(OS_CHROMEOS) #include "chromeos/dbus/dbus_thread_manager.h" #include "chromeos/dbus/permission_broker_client.h" -#include "dbus/file_descriptor.h" +#include "dbus/file_descriptor.h" // nogncheck #endif // defined(OS_CHROMEOS) namespace device {
diff --git a/docs/clang.md b/docs/clang.md index 5b5ec90..516d6fb 100644 --- a/docs/clang.md +++ b/docs/clang.md
@@ -16,7 +16,7 @@ Get clang (happens automatically during `gclient runhooks` on Mac and Linux): - tools/clang/scripts/update.sh + tools/clang/scripts/update.py (Only needs to be run once per checkout, and clang will be automatically updated by `gclient runhooks`.) @@ -51,11 +51,17 @@ If you're working on the plugin, you can build it locally like so: -1. Run `./tools/clang/scripts/update.sh --force-local-build --without-android` +1. Run `./tools/clang/scripts/update.py --force-local-build --without-android` to build the plugin. -1. Build with clang like described above. +1. Run `ninja -C third_party/llvm-build/Release+Asserts/` to build incrementally. +1. Build with clang like described above, but, if you use goma, disable it. -TODO: writing_clang_plugins does not exist. +To test the FindBadConstructs plugin, run: + + (cd tools/clang/plugins/tests && \ + ./test.sh ../../../../third_party/llvm-build/Release+Asserts/bin/clang \ + ../../../../third_party/llvm-build/Release+Asserts/lib/libFindBadConstructs.so) + To run [other plugins](writing_clang_plugins.md), add these to your `GYP_DEFINES`: @@ -122,6 +128,6 @@ If your clang revision is very different from the one currently used in chromium -* Check `tools/clang/scripts/update.sh` to find chromium's clang revision +* Check `tools/clang/scripts/update.py` to find chromium's clang revision * You might have to tweak warning flags. Or you could set `werror=` in the line above to disable warnings as errors (but this only works on Linux).
diff --git a/extensions/browser/api/cast_channel/cast_framer.cc b/extensions/browser/api/cast_channel/cast_framer.cc index b69a65f9..3d208396 100644 --- a/extensions/browser/api/cast_channel/cast_framer.cc +++ b/extensions/browser/api/cast_channel/cast_framer.cc
@@ -6,6 +6,8 @@ #include <stdlib.h> +#include <limits> + #include "base/numerics/safe_conversions.h" #include "base/strings/string_number_conversions.h" #include "base/sys_byteorder.h" @@ -26,7 +28,7 @@ } void MessageFramer::MessageHeader::SetMessageSize(size_t size) { - DCHECK_LT(size, static_cast<size_t>(kuint32max)); + DCHECK_LT(size, static_cast<size_t>(std::numeric_limits<uint32_t>::max())); DCHECK_GT(size, 0U); message_size = size; } @@ -47,7 +49,7 @@ // if bit-for-bit compatible. void MessageFramer::MessageHeader::Deserialize(char* data, MessageHeader* header) { - uint32 message_size; + uint32_t message_size; memcpy(&message_size, data, header_size()); header->message_size = base::checked_cast<size_t>(base::NetToHost32(message_size)); @@ -55,7 +57,7 @@ // static size_t MessageFramer::MessageHeader::header_size() { - return sizeof(uint32); + return sizeof(uint32_t); } // static @@ -65,7 +67,7 @@ std::string MessageFramer::MessageHeader::ToString() { return "{message_size: " + - base::UintToString(static_cast<uint32>(message_size)) + "}"; + base::UintToString(static_cast<uint32_t>(message_size)) + "}"; } // static @@ -120,7 +122,7 @@ return scoped_ptr<CastMessage>(); } - DCHECK_EQ(base::checked_cast<int32>(message_bytes_received_), + DCHECK_EQ(base::checked_cast<int32_t>(message_bytes_received_), input_buffer_->offset()); CHECK_LE(num_bytes, BytesRequested()); message_bytes_received_ += num_bytes;
diff --git a/extensions/browser/api/cast_channel/cast_framer.h b/extensions/browser/api/cast_channel/cast_framer.h index 81c9f90..6a913ab 100644 --- a/extensions/browser/api/cast_channel/cast_framer.h +++ b/extensions/browser/api/cast_channel/cast_framer.h
@@ -5,9 +5,10 @@ #ifndef EXTENSIONS_BROWSER_API_CAST_CHANNEL_CAST_FRAMER_H_ #define EXTENSIONS_BROWSER_API_CAST_CHANNEL_CAST_FRAMER_H_ +#include <stdint.h> + #include <string> -#include "base/basictypes.h" #include "extensions/common/api/cast_channel.h" #include "net/base/io_buffer.h"
diff --git a/extensions/browser/api/guest_view/web_view/web_view_internal_api.cc b/extensions/browser/api/guest_view/web_view/web_view_internal_api.cc index b6a8ab607..ce1acc1 100644 --- a/extensions/browser/api/guest_view/web_view/web_view_internal_api.cc +++ b/extensions/browser/api/guest_view/web_view/web_view_internal_api.cc
@@ -287,9 +287,11 @@ if (!args_->GetString(1, &src)) return false; + // Set |guest_src_| here, but do not return false if it is invalid. + // Instead, let it continue with the normal page load sequence, + // which will result in the usual LOAD_ABORT event in the case where + // the URL is invalid. guest_src_ = GURL(src); - if (!guest_src_.is_valid()) - return false; base::DictionaryValue* details_value = NULL; if (!args_->GetDictionary(2, &details_value))
diff --git a/extensions/common/constants.cc b/extensions/common/constants.cc index ff10df9a..8d079b2 100644 --- a/extensions/common/constants.cc +++ b/extensions/common/constants.cc
@@ -75,15 +75,6 @@ const size_t kNumExtensionIconSizes = arraysize(kExtensionIconSizes); -const IconRepresentationInfo kExtensionActionIconSizes[] = { - { EXTENSION_ICON_ACTION, "19", ui::SCALE_FACTOR_100P }, - { 2 * EXTENSION_ICON_ACTION, "38", ui::SCALE_FACTOR_200P } -}; - -static_assert(kNumExtensionActionIconSizes == - arraysize(kExtensionActionIconSizes), - "num action icon sizes must be in sync with action icon sizes"); - const char kPdfExtensionId[] = "mhjfbmdgcfjbbpaeojofohoefgiehjai"; const char kQuickOfficeComponentExtensionId[] = "bpmcpldpdmajfigpchkicefoigmkfalc";
diff --git a/extensions/common/constants.h b/extensions/common/constants.h index 7af8701..8022896 100644 --- a/extensions/common/constants.h +++ b/extensions/common/constants.h
@@ -194,20 +194,6 @@ extern const int kExtensionIconSizes[]; extern const size_t kNumExtensionIconSizes; -struct IconRepresentationInfo { - // Size in pixels. - const int size; - // Size as a string that will be used to retrieve representation value from - // ExtensionAction SetIcon function arguments. - const char* const size_string; - // Scale factor for which the representation should be used. - const ui::ScaleFactor scale; -}; - -// The icon representations for extension actions. -extern const IconRepresentationInfo kExtensionActionIconSizes[]; -const size_t kNumExtensionActionIconSizes = 2u; - // The extension id of the PDF extension. extern const char kPdfExtensionId[];
diff --git a/extensions/common/manifest_handler_helpers.cc b/extensions/common/manifest_handler_helpers.cc index d3dfea6..7186321 100644 --- a/extensions/common/manifest_handler_helpers.cc +++ b/extensions/common/manifest_handler_helpers.cc
@@ -59,6 +59,27 @@ return true; } +bool LoadAllIconsFromDictionary(const base::DictionaryValue* icons_value, + ExtensionIconSet* icons, + base::string16* error) { + DCHECK(icons); + for (base::DictionaryValue::Iterator iterator(*icons_value); + !iterator.IsAtEnd(); iterator.Advance()) { + int size = 0; + std::string icon_path; + if (!base::StringToInt(iterator.key(), &size) || + !iterator.value().GetAsString(&icon_path) || + !NormalizeAndValidatePath(&icon_path)) { + *error = ErrorUtils::FormatErrorMessageUTF16(errors::kInvalidIconPath, + iterator.key()); + return false; + } + + icons->Add(size, icon_path); + } + return true; +} + } // namespace manifest_handler_helpers } // namespace extensions
diff --git a/extensions/common/manifest_handler_helpers.h b/extensions/common/manifest_handler_helpers.h index 01fe6cc..4f88174 100644 --- a/extensions/common/manifest_handler_helpers.h +++ b/extensions/common/manifest_handler_helpers.h
@@ -33,6 +33,11 @@ ExtensionIconSet* icons, base::string16* error); +// As above, but loads all icons in |icons_value|. +bool LoadAllIconsFromDictionary(const base::DictionaryValue* icons_value, + ExtensionIconSet* icons, + base::string16* error); + } // namespace manifest_handler_helpers } // namespace extensions
diff --git a/extensions/renderer/resources/media_router_bindings.js b/extensions/renderer/resources/media_router_bindings.js index 6bc357d86..7bf09d3 100644 --- a/extensions/renderer/resources/media_router_bindings.js +++ b/extensions/renderer/resources/media_router_bindings.js
@@ -29,6 +29,7 @@ function sinkToMojo_(sink) { return new mediaRouterMojom.MediaSink({ 'name': sink.friendlyName, + 'description': sink.description, 'sink_id': sink.id, 'icon_type': sinkIconTypeToMojo(sink.iconType), });
diff --git a/gin/modules/console.cc b/gin/modules/console.cc index 231d8fc..63fc41e 100644 --- a/gin/modules/console.cc +++ b/gin/modules/console.cc
@@ -4,7 +4,7 @@ #include "gin/modules/console.h" -#include <iostream> +#include <stdio.h> #include "base/strings/string_util.h" #include "gin/arguments.h" @@ -25,7 +25,7 @@ args->ThrowError(); return; } - std::cout << base::JoinString(messages, " ") << std::endl; + printf("%s\n", base::JoinString(messages, " ").c_str()); } WrapperInfo g_wrapper_info = { kEmbedderNativeGin };
diff --git a/gpu/BUILD.gn b/gpu/BUILD.gn index 7193022c..0462e45 100644 --- a/gpu/BUILD.gn +++ b/gpu/BUILD.gn
@@ -127,6 +127,7 @@ "command_buffer/tests/gl_copy_texture_CHROMIUM_unittest.cc", "command_buffer/tests/gl_cube_map_texture_unittest.cc", "command_buffer/tests/gl_depth_texture_unittest.cc", + "command_buffer/tests/gl_ext_blend_func_extended_unittest.cc", "command_buffer/tests/gl_ext_multisample_compatibility_unittest.cc", "command_buffer/tests/gl_ext_srgb_unittest.cc", "command_buffer/tests/gl_fence_sync_unittest.cc",
diff --git a/gpu/GLES2/extensions/CHROMIUM/CHROMIUM_ycbcr_420v_image.txt b/gpu/GLES2/extensions/CHROMIUM/CHROMIUM_ycbcr_420v_image.txt new file mode 100644 index 0000000..c83453ec --- /dev/null +++ b/gpu/GLES2/extensions/CHROMIUM/CHROMIUM_ycbcr_420v_image.txt
@@ -0,0 +1,48 @@ +Name + + CHROMIUM_ycbcr_420v_image + +Name Strings + + GL_CHROMIUM_ycbcr_420v_image + +Version + + Last Modifed Date: October 26, 2015 + +Dependencies + + OpenGL ES 2.0 is required. + + GL_CHROMIUM_image is required. + +Overview + + This extension provides a new internal image format to use when creating an + image from underlying '420v' buffers. + + This extension is useful in conjunction with CreateImageCHROMIUM and + CreateGpuMemoryBufferImageCHROMIUM to define the format of GpuMemoryBuffer + backing the image. + +New Procedures and Functions + + None. + +Errors + + None. + +New Tokens + + Accepted by the <internalformat> parameter of CreateImageCHROMIUM, and + <internalformat> parameter of CreateGpuMemoryBufferImageCHROMIUM: + GL_RGB_YCBCR_420V_CHROMIUM 0x78FC + +New State + + None. + +Revision History + + 10/26/2015 Documented the extension
diff --git a/gpu/GLES2/gl2chromium_autogen.h b/gpu/GLES2/gl2chromium_autogen.h index 0cea2ef..f01a448 100644 --- a/gpu/GLES2/gl2chromium_autogen.h +++ b/gpu/GLES2/gl2chromium_autogen.h
@@ -376,5 +376,9 @@ #define glBlendBarrierKHR GLES2_GET_FUN(BlendBarrierKHR) #define glApplyScreenSpaceAntialiasingCHROMIUM \ GLES2_GET_FUN(ApplyScreenSpaceAntialiasingCHROMIUM) +#define glBindFragDataLocationIndexedEXT \ + GLES2_GET_FUN(BindFragDataLocationIndexedEXT) +#define glBindFragDataLocationEXT GLES2_GET_FUN(BindFragDataLocationEXT) +#define glGetFragDataIndexEXT GLES2_GET_FUN(GetFragDataIndexEXT) #endif // GPU_GLES2_GL2CHROMIUM_AUTOGEN_H_
diff --git a/gpu/GLES2/gl2extchromium.h b/gpu/GLES2/gl2extchromium.h index f3c787f6..8118de0 100644 --- a/gpu/GLES2/gl2extchromium.h +++ b/gpu/GLES2/gl2extchromium.h
@@ -123,6 +123,10 @@ #define GL_RGB_YCBCR_422_CHROMIUM 0x78FB #endif +#ifndef GL_RGB_YCBCR_420V_CHROMIUM +#define GL_RGB_YCBCR_420V_CHROMIUM 0x78FC +#endif + #ifdef GL_GLEXT_PROTOTYPES GL_APICALL GLuint GL_APIENTRY glCreateGpuMemoryBufferImageCHROMIUM( GLsizei width, @@ -1165,12 +1169,47 @@ #endif /* GL_CHROMIUM_path_rendering */ + #ifndef GL_EXT_multisample_compatibility #define GL_EXT_multisample_compatibility 1 #define GL_MULTISAMPLE_EXT 0x809D #define GL_SAMPLE_ALPHA_TO_ONE_EXT 0x809F #endif /* GL_EXT_multisample_compatiblity */ +#ifndef GL_EXT_blend_func_extended +#define GL_EXT_blend_func_extended 1 + +#ifdef GL_GLEXT_PROTOTYPES +GL_APICALL void GL_APIENTRY glBindFragDataLocationIndexedEXT(GLuint program, + GLuint colorNumber, + GLuint index, + const char* name); +GL_APICALL void GL_APIENTRY glBindFragDataLocationEXT(GLuint program, + GLuint colorNumber, + const char* name); +GL_APICALL GLint GL_APIENTRY glGetFragDataIndexEXT(GLuint program, + const char* name); +#endif + +typedef void(GL_APIENTRYP PFNGLBINDFRAGDATALOCATIONINDEXEDEXT)( + GLuint program, + GLuint colorNumber, + GLuint index, + const char* name); +typedef void(GL_APIENTRYP PFNGLBINDFRAGDATALOCATIONEXT)(GLuint program, + GLuint colorNumber, + const char* name); +typedef GLint(GL_APIENTRYP PFNGLGETFRAGDATAINDEXEXT)(GLuint program, + const GLchar* name); + +#define GL_SRC_ALPHA_SATURATE_EXT 0x0308 +#define GL_SRC1_ALPHA_EXT 0x8589 // OpenGL 1.5 token value +#define GL_SRC1_COLOR_EXT 0x88F9 +#define GL_ONE_MINUS_SRC1_COLOR_EXT 0x88FA +#define GL_ONE_MINUS_SRC1_ALPHA_EXT 0x88FB +#define GL_MAX_DUAL_SOURCE_DRAW_BUFFERS_EXT 0x88FC +#endif /* GL_EXT_blend_func_extended */ + #ifdef __cplusplus } #endif
diff --git a/gpu/command_buffer/build_gles2_cmd_buffer.py b/gpu/command_buffer/build_gles2_cmd_buffer.py index 6b672b2..76708f5 100755 --- a/gpu/command_buffer/build_gles2_cmd_buffer.py +++ b/gpu/command_buffer/build_gles2_cmd_buffer.py
@@ -1949,6 +1949,7 @@ 'GL_RGB', 'GL_RGB_YUV_420_CHROMIUM', 'GL_RGB_YCBCR_422_CHROMIUM', + 'GL_RGB_YCBCR_420V_CHROMIUM', 'GL_RGBA', ], }, @@ -2863,6 +2864,16 @@ 'result': ['GLint'], 'error_return': -1, }, + 'GetFragDataIndexEXT': { + 'type': 'Custom', + 'data_transfer_methods': ['shm'], + 'cmd_args': + 'GLidProgram program, uint32_t name_bucket_id, GLint* index', + 'result': ['GLint'], + 'error_return': -1, + 'extension': 'EXT_blend_func_extended', + 'extension_flag': 'ext_blend_func_extended', + }, 'GetFragDataLocation': { 'type': 'Custom', 'data_transfer_methods': ['shm'], @@ -4016,6 +4027,22 @@ 'extension': True, 'chromium': True, }, + 'BindFragDataLocationEXT': { + 'type': 'GLchar', + 'data_transfer_methods': ['bucket'], + 'needs_size': True, + 'gl_test_func': 'DoBindFragDataLocationEXT', + 'extension': 'EXT_blend_func_extended', + 'extension_flag': 'ext_blend_func_extended', + }, + 'BindFragDataLocationIndexedEXT': { + 'type': 'GLchar', + 'data_transfer_methods': ['bucket'], + 'needs_size': True, + 'gl_test_func': 'DoBindFragDataLocationIndexedEXT', + 'extension': 'EXT_blend_func_extended', + 'extension_flag': 'ext_blend_func_extended', + }, 'BindUniformLocationCHROMIUM': { 'type': 'GLchar', 'extension': 'CHROMIUM_bind_uniform_location',
diff --git a/gpu/command_buffer/client/gles2_c_lib_autogen.h b/gpu/command_buffer/client/gles2_c_lib_autogen.h index b274a6b..8cb59a9 100644 --- a/gpu/command_buffer/client/gles2_c_lib_autogen.h +++ b/gpu/command_buffer/client/gles2_c_lib_autogen.h
@@ -1704,6 +1704,21 @@ void GL_APIENTRY GLES2ApplyScreenSpaceAntialiasingCHROMIUM() { gles2::GetGLContext()->ApplyScreenSpaceAntialiasingCHROMIUM(); } +void GL_APIENTRY GLES2BindFragDataLocationIndexedEXT(GLuint program, + GLuint colorNumber, + GLuint index, + const char* name) { + gles2::GetGLContext()->BindFragDataLocationIndexedEXT(program, colorNumber, + index, name); +} +void GL_APIENTRY GLES2BindFragDataLocationEXT(GLuint program, + GLuint colorNumber, + const char* name) { + gles2::GetGLContext()->BindFragDataLocationEXT(program, colorNumber, name); +} +GLint GL_APIENTRY GLES2GetFragDataIndexEXT(GLuint program, const char* name) { + return gles2::GetGLContext()->GetFragDataIndexEXT(program, name); +} namespace gles2 { @@ -2994,6 +3009,19 @@ glApplyScreenSpaceAntialiasingCHROMIUM), }, { + "glBindFragDataLocationIndexedEXT", + reinterpret_cast<GLES2FunctionPointer>( + glBindFragDataLocationIndexedEXT), + }, + { + "glBindFragDataLocationEXT", + reinterpret_cast<GLES2FunctionPointer>(glBindFragDataLocationEXT), + }, + { + "glGetFragDataIndexEXT", + reinterpret_cast<GLES2FunctionPointer>(glGetFragDataIndexEXT), + }, + { NULL, NULL, }, };
diff --git a/gpu/command_buffer/client/gles2_cmd_helper_autogen.h b/gpu/command_buffer/client/gles2_cmd_helper_autogen.h index b5cf24cd..b87750a 100644 --- a/gpu/command_buffer/client/gles2_cmd_helper_autogen.h +++ b/gpu/command_buffer/client/gles2_cmd_helper_autogen.h
@@ -3166,4 +3166,36 @@ } } +void BindFragDataLocationIndexedEXTBucket(GLuint program, + GLuint colorNumber, + GLuint index, + uint32_t name_bucket_id) { + gles2::cmds::BindFragDataLocationIndexedEXTBucket* c = + GetCmdSpace<gles2::cmds::BindFragDataLocationIndexedEXTBucket>(); + if (c) { + c->Init(program, colorNumber, index, name_bucket_id); + } +} + +void BindFragDataLocationEXTBucket(GLuint program, + GLuint colorNumber, + uint32_t name_bucket_id) { + gles2::cmds::BindFragDataLocationEXTBucket* c = + GetCmdSpace<gles2::cmds::BindFragDataLocationEXTBucket>(); + if (c) { + c->Init(program, colorNumber, name_bucket_id); + } +} + +void GetFragDataIndexEXT(GLuint program, + uint32_t name_bucket_id, + uint32_t index_shm_id, + uint32_t index_shm_offset) { + gles2::cmds::GetFragDataIndexEXT* c = + GetCmdSpace<gles2::cmds::GetFragDataIndexEXT>(); + if (c) { + c->Init(program, name_bucket_id, index_shm_id, index_shm_offset); + } +} + #endif // GPU_COMMAND_BUFFER_CLIENT_GLES2_CMD_HELPER_AUTOGEN_H_
diff --git a/gpu/command_buffer/client/gles2_implementation.cc b/gpu/command_buffer/client/gles2_implementation.cc index 9b52768..7c7f99d6 100644 --- a/gpu/command_buffer/client/gles2_implementation.cc +++ b/gpu/command_buffer/client/gles2_implementation.cc
@@ -1396,6 +1396,33 @@ CheckGLError(); } +void GLES2Implementation::BindFragDataLocationEXT(GLuint program, + GLuint colorName, + const char* name) { + GPU_CLIENT_SINGLE_THREAD_CHECK(); + GPU_CLIENT_LOG("[" << GetLogPrefix() << "] glBindFragDataLocationEXT(" + << program << ", " << colorName << ", " << name << ")"); + SetBucketAsString(kResultBucketId, name); + helper_->BindFragDataLocationEXTBucket(program, colorName, kResultBucketId); + helper_->SetBucketSize(kResultBucketId, 0); + CheckGLError(); +} + +void GLES2Implementation::BindFragDataLocationIndexedEXT(GLuint program, + GLuint colorName, + GLuint index, + const char* name) { + GPU_CLIENT_SINGLE_THREAD_CHECK(); + GPU_CLIENT_LOG("[" << GetLogPrefix() << "] glBindFragDataLocationEXT(" + << program << ", " << colorName << ", " << index << ", " + << name << ")"); + SetBucketAsString(kResultBucketId, name); + helper_->BindFragDataLocationIndexedEXTBucket(program, colorName, index, + kResultBucketId); + helper_->SetBucketSize(kResultBucketId, 0); + CheckGLError(); +} + void GLES2Implementation::BindUniformLocationCHROMIUM( GLuint program, GLint location, const char* name) { GPU_CLIENT_SINGLE_THREAD_CHECK(); @@ -1607,6 +1634,35 @@ return got_value; } +GLint GLES2Implementation::GetFragDataIndexEXTHelper(GLuint program, + const char* name) { + typedef cmds::GetFragDataIndexEXT::Result Result; + Result* result = GetResultAs<Result*>(); + if (!result) { + return -1; + } + *result = -1; + SetBucketAsCString(kResultBucketId, name); + helper_->GetFragDataIndexEXT(program, kResultBucketId, GetResultShmId(), + GetResultShmOffset()); + WaitForCmd(); + helper_->SetBucketSize(kResultBucketId, 0); + return *result; +} + +GLint GLES2Implementation::GetFragDataIndexEXT(GLuint program, + const char* name) { + GPU_CLIENT_SINGLE_THREAD_CHECK(); + GPU_CLIENT_LOG("[" << GetLogPrefix() << "] glGetFragDataIndexEXT(" << program + << ", " << name << ")"); + TRACE_EVENT0("gpu", "GLES2::GetFragDataIndexEXT"); + GLint loc = share_group_->program_info_manager()->GetFragDataIndex( + this, program, name); + GPU_CLIENT_LOG("returned " << loc); + CheckGLError(); + return loc; +} + GLint GLES2Implementation::GetFragDataLocationHelper( GLuint program, const char* name) { typedef cmds::GetFragDataLocation::Result Result; @@ -5572,6 +5628,7 @@ case GL_RGB: case GL_RGBA: case GL_RGB_YCBCR_422_CHROMIUM: + case GL_RGB_YCBCR_420V_CHROMIUM: case GL_BGRA_EXT: return true; default:
diff --git a/gpu/command_buffer/client/gles2_implementation.h b/gpu/command_buffer/client/gles2_implementation.h index 1c2eba9..1c55b83 100644 --- a/gpu/command_buffer/client/gles2_implementation.h +++ b/gpu/command_buffer/client/gles2_implementation.h
@@ -215,6 +215,7 @@ void GetProgramInfoCHROMIUMHelper(GLuint program, std::vector<int8>* result); GLint GetAttribLocationHelper(GLuint program, const char* name); GLint GetUniformLocationHelper(GLuint program, const char* name); + GLint GetFragDataIndexEXTHelper(GLuint program, const char* name); GLint GetFragDataLocationHelper(GLuint program, const char* name); bool GetActiveAttribHelper( GLuint program, GLuint index, GLsizei bufsize, GLsizei* length,
diff --git a/gpu/command_buffer/client/gles2_implementation_autogen.h b/gpu/command_buffer/client/gles2_implementation_autogen.h index 0a4f886..10ebcc3 100644 --- a/gpu/command_buffer/client/gles2_implementation_autogen.h +++ b/gpu/command_buffer/client/gles2_implementation_autogen.h
@@ -1184,4 +1184,15 @@ void ApplyScreenSpaceAntialiasingCHROMIUM() override; +void BindFragDataLocationIndexedEXT(GLuint program, + GLuint colorNumber, + GLuint index, + const char* name) override; + +void BindFragDataLocationEXT(GLuint program, + GLuint colorNumber, + const char* name) override; + +GLint GetFragDataIndexEXT(GLuint program, const char* name) override; + #endif // GPU_COMMAND_BUFFER_CLIENT_GLES2_IMPLEMENTATION_AUTOGEN_H_
diff --git a/gpu/command_buffer/client/gles2_interface_autogen.h b/gpu/command_buffer/client/gles2_interface_autogen.h index 77872e7a..374cb26 100644 --- a/gpu/command_buffer/client/gles2_interface_autogen.h +++ b/gpu/command_buffer/client/gles2_interface_autogen.h
@@ -885,4 +885,12 @@ virtual GLenum GetGraphicsResetStatusKHR() = 0; virtual void BlendBarrierKHR() = 0; virtual void ApplyScreenSpaceAntialiasingCHROMIUM() = 0; +virtual void BindFragDataLocationIndexedEXT(GLuint program, + GLuint colorNumber, + GLuint index, + const char* name) = 0; +virtual void BindFragDataLocationEXT(GLuint program, + GLuint colorNumber, + const char* name) = 0; +virtual GLint GetFragDataIndexEXT(GLuint program, const char* name) = 0; #endif // GPU_COMMAND_BUFFER_CLIENT_GLES2_INTERFACE_AUTOGEN_H_
diff --git a/gpu/command_buffer/client/gles2_interface_stub_autogen.h b/gpu/command_buffer/client/gles2_interface_stub_autogen.h index 5469525..489afa2 100644 --- a/gpu/command_buffer/client/gles2_interface_stub_autogen.h +++ b/gpu/command_buffer/client/gles2_interface_stub_autogen.h
@@ -859,4 +859,12 @@ GLenum GetGraphicsResetStatusKHR() override; void BlendBarrierKHR() override; void ApplyScreenSpaceAntialiasingCHROMIUM() override; +void BindFragDataLocationIndexedEXT(GLuint program, + GLuint colorNumber, + GLuint index, + const char* name) override; +void BindFragDataLocationEXT(GLuint program, + GLuint colorNumber, + const char* name) override; +GLint GetFragDataIndexEXT(GLuint program, const char* name) override; #endif // GPU_COMMAND_BUFFER_CLIENT_GLES2_INTERFACE_STUB_AUTOGEN_H_
diff --git a/gpu/command_buffer/client/gles2_interface_stub_impl_autogen.h b/gpu/command_buffer/client/gles2_interface_stub_impl_autogen.h index 867652f..148f3af 100644 --- a/gpu/command_buffer/client/gles2_interface_stub_impl_autogen.h +++ b/gpu/command_buffer/client/gles2_interface_stub_impl_autogen.h
@@ -1159,4 +1159,16 @@ } void GLES2InterfaceStub::BlendBarrierKHR() {} void GLES2InterfaceStub::ApplyScreenSpaceAntialiasingCHROMIUM() {} +void GLES2InterfaceStub::BindFragDataLocationIndexedEXT( + GLuint /* program */, + GLuint /* colorNumber */, + GLuint /* index */, + const char* /* name */) {} +void GLES2InterfaceStub::BindFragDataLocationEXT(GLuint /* program */, + GLuint /* colorNumber */, + const char* /* name */) {} +GLint GLES2InterfaceStub::GetFragDataIndexEXT(GLuint /* program */, + const char* /* name */) { + return 0; +} #endif // GPU_COMMAND_BUFFER_CLIENT_GLES2_INTERFACE_STUB_IMPL_AUTOGEN_H_
diff --git a/gpu/command_buffer/client/gles2_trace_implementation_autogen.h b/gpu/command_buffer/client/gles2_trace_implementation_autogen.h index 209215e..8347572 100644 --- a/gpu/command_buffer/client/gles2_trace_implementation_autogen.h +++ b/gpu/command_buffer/client/gles2_trace_implementation_autogen.h
@@ -859,4 +859,12 @@ GLenum GetGraphicsResetStatusKHR() override; void BlendBarrierKHR() override; void ApplyScreenSpaceAntialiasingCHROMIUM() override; +void BindFragDataLocationIndexedEXT(GLuint program, + GLuint colorNumber, + GLuint index, + const char* name) override; +void BindFragDataLocationEXT(GLuint program, + GLuint colorNumber, + const char* name) override; +GLint GetFragDataIndexEXT(GLuint program, const char* name) override; #endif // GPU_COMMAND_BUFFER_CLIENT_GLES2_TRACE_IMPLEMENTATION_AUTOGEN_H_
diff --git a/gpu/command_buffer/client/gles2_trace_implementation_impl_autogen.h b/gpu/command_buffer/client/gles2_trace_implementation_impl_autogen.h index 77c6ab6..5f67456d 100644 --- a/gpu/command_buffer/client/gles2_trace_implementation_impl_autogen.h +++ b/gpu/command_buffer/client/gles2_trace_implementation_impl_autogen.h
@@ -2475,4 +2475,27 @@ gl_->ApplyScreenSpaceAntialiasingCHROMIUM(); } +void GLES2TraceImplementation::BindFragDataLocationIndexedEXT( + GLuint program, + GLuint colorNumber, + GLuint index, + const char* name) { + TRACE_EVENT_BINARY_EFFICIENT0("gpu", + "GLES2Trace::BindFragDataLocationIndexedEXT"); + gl_->BindFragDataLocationIndexedEXT(program, colorNumber, index, name); +} + +void GLES2TraceImplementation::BindFragDataLocationEXT(GLuint program, + GLuint colorNumber, + const char* name) { + TRACE_EVENT_BINARY_EFFICIENT0("gpu", "GLES2Trace::BindFragDataLocationEXT"); + gl_->BindFragDataLocationEXT(program, colorNumber, name); +} + +GLint GLES2TraceImplementation::GetFragDataIndexEXT(GLuint program, + const char* name) { + TRACE_EVENT_BINARY_EFFICIENT0("gpu", "GLES2Trace::GetFragDataIndexEXT"); + return gl_->GetFragDataIndexEXT(program, name); +} + #endif // GPU_COMMAND_BUFFER_CLIENT_GLES2_TRACE_IMPLEMENTATION_IMPL_AUTOGEN_H_
diff --git a/gpu/command_buffer/client/mapped_memory.cc b/gpu/command_buffer/client/mapped_memory.cc index fcc9113..dcfead22 100644 --- a/gpu/command_buffer/client/mapped_memory.cc +++ b/gpu/command_buffer/client/mapped_memory.cc
@@ -56,9 +56,7 @@ this); CommandBuffer* cmd_buf = helper_->command_buffer(); - for (MemoryChunkVector::iterator iter = chunks_.begin(); - iter != chunks_.end(); ++iter) { - MemoryChunk* chunk = *iter; + for (auto& chunk : chunks_) { cmd_buf->DestroyTransferBuffer(chunk->shm_id()); } } @@ -70,8 +68,7 @@ if (size <= allocated_memory_) { size_t total_bytes_in_use = 0; // See if any of the chunks can satisfy this request. - for (size_t ii = 0; ii < chunks_.size(); ++ii) { - MemoryChunk* chunk = chunks_[ii]; + for (auto& chunk : chunks_) { chunk->FreeUnused(); total_bytes_in_use += chunk->bytes_in_use(); if (chunk->GetLargestFreeSizeWithoutWaiting() >= size) { @@ -89,8 +86,7 @@ if (max_free_bytes_ != kNoLimit && (allocated_memory_ - total_bytes_in_use) >= max_free_bytes_) { TRACE_EVENT0("gpu", "MappedMemoryManager::Alloc::wait"); - for (size_t ii = 0; ii < chunks_.size(); ++ii) { - MemoryChunk* chunk = chunks_[ii]; + for (auto& chunk : chunks_) { if (chunk->GetLargestFreeSizeWithWaiting() >= size) { void* mem = chunk->Alloc(size); DCHECK(mem); @@ -120,7 +116,7 @@ DCHECK(shm.get()); MemoryChunk* mc = new MemoryChunk(id, shm, helper_); allocated_memory_ += mc->GetSize(); - chunks_.push_back(mc); + chunks_.push_back(make_scoped_ptr(mc)); void* mem = mc->Alloc(size); DCHECK(mem); *shm_id = mc->shm_id(); @@ -129,8 +125,7 @@ } void MappedMemoryManager::Free(void* pointer) { - for (size_t ii = 0; ii < chunks_.size(); ++ii) { - MemoryChunk* chunk = chunks_[ii]; + for (auto& chunk : chunks_) { if (chunk->IsInChunk(pointer)) { chunk->Free(pointer); return; @@ -140,8 +135,7 @@ } void MappedMemoryManager::FreePendingToken(void* pointer, int32 token) { - for (size_t ii = 0; ii < chunks_.size(); ++ii) { - MemoryChunk* chunk = chunks_[ii]; + for (auto& chunk : chunks_) { if (chunk->IsInChunk(pointer)) { chunk->FreePendingToken(pointer, token); return; @@ -154,7 +148,7 @@ CommandBuffer* cmd_buf = helper_->command_buffer(); MemoryChunkVector::iterator iter = chunks_.begin(); while (iter != chunks_.end()) { - MemoryChunk* chunk = *iter; + MemoryChunk* chunk = (*iter).get(); chunk->FreeUnused(); if (!chunk->InUse()) { cmd_buf->DestroyTransferBuffer(chunk->shm_id());
diff --git a/gpu/command_buffer/client/mapped_memory.h b/gpu/command_buffer/client/mapped_memory.h index aad8647..8d312d8f 100644 --- a/gpu/command_buffer/client/mapped_memory.h +++ b/gpu/command_buffer/client/mapped_memory.h
@@ -189,8 +189,7 @@ size_t bytes_in_use() const { size_t bytes_in_use = 0; for (size_t ii = 0; ii < chunks_.size(); ++ii) { - MemoryChunk* chunk = chunks_[ii]; - bytes_in_use += chunk->bytes_in_use(); + bytes_in_use += chunks_[ii]->bytes_in_use(); } return bytes_in_use; } @@ -201,7 +200,7 @@ } private: - typedef ScopedVector<MemoryChunk> MemoryChunkVector; + typedef std::vector<scoped_ptr<MemoryChunk>> MemoryChunkVector; // size a chunk is rounded up to. unsigned int chunk_size_multiple_;
diff --git a/gpu/command_buffer/client/program_info_manager.cc b/gpu/command_buffer/client/program_info_manager.cc index 939473a..d047b57 100644 --- a/gpu/command_buffer/client/program_info_manager.cc +++ b/gpu/command_buffer/client/program_info_manager.cc
@@ -160,6 +160,19 @@ return GL_INVALID_INDEX; } +GLint ProgramInfoManager::Program::GetFragDataIndex( + const std::string& name) const { + auto iter = frag_data_indices_.find(name); + if (iter == frag_data_indices_.end()) + return -1; + return iter->second; +} + +void ProgramInfoManager::Program::CacheFragDataIndex(const std::string& name, + GLint index) { + frag_data_indices_[name] = index; +} + GLint ProgramInfoManager::Program::GetFragDataLocation( const std::string& name) const { base::hash_map<std::string, GLint>::const_iterator iter = @@ -725,6 +738,31 @@ return gl->GetUniformLocationHelper(program, name); } +GLint ProgramInfoManager::GetFragDataIndex(GLES2Implementation* gl, + GLuint program, + const char* name) { + // TODO(zmo): make FragData indexes part of the ProgramInfo that are + // fetched from the service side. See crbug.com/452104. + { + base::AutoLock auto_lock(lock_); + Program* info = GetProgramInfo(gl, program, kNone); + if (info) { + GLint possible_index = info->GetFragDataIndex(name); + if (possible_index != -1) + return possible_index; + } + } + GLint index = gl->GetFragDataIndexEXTHelper(program, name); + if (index != -1) { + base::AutoLock auto_lock(lock_); + Program* info = GetProgramInfo(gl, program, kNone); + if (info) { + info->CacheFragDataIndex(name, index); + } + } + return index; +} + GLint ProgramInfoManager::GetFragDataLocation( GLES2Implementation* gl, GLuint program, const char* name) { // TODO(zmo): make FragData locations part of the ProgramInfo that are
diff --git a/gpu/command_buffer/client/program_info_manager.h b/gpu/command_buffer/client/program_info_manager.h index fa74ea58..fbae19ae 100644 --- a/gpu/command_buffer/client/program_info_manager.h +++ b/gpu/command_buffer/client/program_info_manager.h
@@ -38,6 +38,10 @@ GLint GetUniformLocation( GLES2Implementation* gl, GLuint program, const char* name); + GLint GetFragDataIndex(GLES2Implementation* gl, + GLuint program, + const char* name); + GLint GetFragDataLocation( GLES2Implementation* gl, GLuint program, const char* name); @@ -166,6 +170,9 @@ bool GetUniformsiv( GLsizei count, const GLuint* indices, GLenum pname, GLint* params); + GLint GetFragDataIndex(const std::string& name) const; + void CacheFragDataIndex(const std::string& name, GLint index); + GLint GetFragDataLocation(const std::string& name) const; void CacheFragDataLocation(const std::string& name, GLint loc); @@ -232,6 +239,7 @@ std::vector<UniformES3> uniforms_es3_; base::hash_map<std::string, GLint> frag_data_locations_; + base::hash_map<std::string, GLint> frag_data_indices_; }; Program* GetProgramInfo(
diff --git a/gpu/command_buffer/cmd_buffer_functions.txt b/gpu/command_buffer/cmd_buffer_functions.txt index 42ed5f5e..8c9baf034 100644 --- a/gpu/command_buffer/cmd_buffer_functions.txt +++ b/gpu/command_buffer/cmd_buffer_functions.txt
@@ -352,3 +352,9 @@ // Extension GL_CHROMIUM_screen_space_antialiasing GL_APICALL void GL_APIENTRY glApplyScreenSpaceAntialiasingCHROMIUM (void); + +// Extension EXT_blend_func_extended +GL_APICALL void GL_APIENTRY glBindFragDataLocationIndexedEXT (GLidProgram program, GLuint colorNumber, GLuint index, const char* name); +GL_APICALL void GL_APIENTRY glBindFragDataLocationEXT (GLidProgram program, GLuint colorNumber, const char* name); +GL_APICALL GLint GL_APIENTRY glGetFragDataIndexEXT (GLidProgram program, const char* name); +
diff --git a/gpu/command_buffer/common/gles2_cmd_format_autogen.h b/gpu/command_buffer/common/gles2_cmd_format_autogen.h index b26cea0..ec3a09b 100644 --- a/gpu/command_buffer/common/gles2_cmd_format_autogen.h +++ b/gpu/command_buffer/common/gles2_cmd_format_autogen.h
@@ -15434,4 +15434,164 @@ offsetof(ApplyScreenSpaceAntialiasingCHROMIUM, header) == 0, "offset of ApplyScreenSpaceAntialiasingCHROMIUM header should be 0"); +struct BindFragDataLocationIndexedEXTBucket { + typedef BindFragDataLocationIndexedEXTBucket ValueType; + static const CommandId kCmdId = kBindFragDataLocationIndexedEXTBucket; + static const cmd::ArgFlags kArgFlags = cmd::kFixed; + static const uint8 cmd_flags = CMD_FLAG_SET_TRACE_LEVEL(3); + + static uint32_t ComputeSize() { + return static_cast<uint32_t>(sizeof(ValueType)); // NOLINT + } + + void SetHeader() { header.SetCmd<ValueType>(); } + + void Init(GLuint _program, + GLuint _colorNumber, + GLuint _index, + uint32_t _name_bucket_id) { + SetHeader(); + program = _program; + colorNumber = _colorNumber; + index = _index; + name_bucket_id = _name_bucket_id; + } + + void* Set(void* cmd, + GLuint _program, + GLuint _colorNumber, + GLuint _index, + uint32_t _name_bucket_id) { + static_cast<ValueType*>(cmd) + ->Init(_program, _colorNumber, _index, _name_bucket_id); + return NextCmdAddress<ValueType>(cmd); + } + + gpu::CommandHeader header; + uint32_t program; + uint32_t colorNumber; + uint32_t index; + uint32_t name_bucket_id; +}; + +static_assert(sizeof(BindFragDataLocationIndexedEXTBucket) == 20, + "size of BindFragDataLocationIndexedEXTBucket should be 20"); +static_assert( + offsetof(BindFragDataLocationIndexedEXTBucket, header) == 0, + "offset of BindFragDataLocationIndexedEXTBucket header should be 0"); +static_assert( + offsetof(BindFragDataLocationIndexedEXTBucket, program) == 4, + "offset of BindFragDataLocationIndexedEXTBucket program should be 4"); +static_assert( + offsetof(BindFragDataLocationIndexedEXTBucket, colorNumber) == 8, + "offset of BindFragDataLocationIndexedEXTBucket colorNumber should be 8"); +static_assert( + offsetof(BindFragDataLocationIndexedEXTBucket, index) == 12, + "offset of BindFragDataLocationIndexedEXTBucket index should be 12"); +static_assert(offsetof(BindFragDataLocationIndexedEXTBucket, name_bucket_id) == + 16, + "offset of BindFragDataLocationIndexedEXTBucket name_bucket_id " + "should be 16"); + +struct BindFragDataLocationEXTBucket { + typedef BindFragDataLocationEXTBucket ValueType; + static const CommandId kCmdId = kBindFragDataLocationEXTBucket; + static const cmd::ArgFlags kArgFlags = cmd::kFixed; + static const uint8 cmd_flags = CMD_FLAG_SET_TRACE_LEVEL(3); + + static uint32_t ComputeSize() { + return static_cast<uint32_t>(sizeof(ValueType)); // NOLINT + } + + void SetHeader() { header.SetCmd<ValueType>(); } + + void Init(GLuint _program, GLuint _colorNumber, uint32_t _name_bucket_id) { + SetHeader(); + program = _program; + colorNumber = _colorNumber; + name_bucket_id = _name_bucket_id; + } + + void* Set(void* cmd, + GLuint _program, + GLuint _colorNumber, + uint32_t _name_bucket_id) { + static_cast<ValueType*>(cmd)->Init(_program, _colorNumber, _name_bucket_id); + return NextCmdAddress<ValueType>(cmd); + } + + gpu::CommandHeader header; + uint32_t program; + uint32_t colorNumber; + uint32_t name_bucket_id; +}; + +static_assert(sizeof(BindFragDataLocationEXTBucket) == 16, + "size of BindFragDataLocationEXTBucket should be 16"); +static_assert(offsetof(BindFragDataLocationEXTBucket, header) == 0, + "offset of BindFragDataLocationEXTBucket header should be 0"); +static_assert(offsetof(BindFragDataLocationEXTBucket, program) == 4, + "offset of BindFragDataLocationEXTBucket program should be 4"); +static_assert( + offsetof(BindFragDataLocationEXTBucket, colorNumber) == 8, + "offset of BindFragDataLocationEXTBucket colorNumber should be 8"); +static_assert( + offsetof(BindFragDataLocationEXTBucket, name_bucket_id) == 12, + "offset of BindFragDataLocationEXTBucket name_bucket_id should be 12"); + +struct GetFragDataIndexEXT { + typedef GetFragDataIndexEXT ValueType; + static const CommandId kCmdId = kGetFragDataIndexEXT; + static const cmd::ArgFlags kArgFlags = cmd::kFixed; + static const uint8 cmd_flags = CMD_FLAG_SET_TRACE_LEVEL(3); + + typedef GLint Result; + + static uint32_t ComputeSize() { + return static_cast<uint32_t>(sizeof(ValueType)); // NOLINT + } + + void SetHeader() { header.SetCmd<ValueType>(); } + + void Init(GLuint _program, + uint32_t _name_bucket_id, + uint32_t _index_shm_id, + uint32_t _index_shm_offset) { + SetHeader(); + program = _program; + name_bucket_id = _name_bucket_id; + index_shm_id = _index_shm_id; + index_shm_offset = _index_shm_offset; + } + + void* Set(void* cmd, + GLuint _program, + uint32_t _name_bucket_id, + uint32_t _index_shm_id, + uint32_t _index_shm_offset) { + static_cast<ValueType*>(cmd) + ->Init(_program, _name_bucket_id, _index_shm_id, _index_shm_offset); + return NextCmdAddress<ValueType>(cmd); + } + + gpu::CommandHeader header; + uint32_t program; + uint32_t name_bucket_id; + uint32_t index_shm_id; + uint32_t index_shm_offset; +}; + +static_assert(sizeof(GetFragDataIndexEXT) == 20, + "size of GetFragDataIndexEXT should be 20"); +static_assert(offsetof(GetFragDataIndexEXT, header) == 0, + "offset of GetFragDataIndexEXT header should be 0"); +static_assert(offsetof(GetFragDataIndexEXT, program) == 4, + "offset of GetFragDataIndexEXT program should be 4"); +static_assert(offsetof(GetFragDataIndexEXT, name_bucket_id) == 8, + "offset of GetFragDataIndexEXT name_bucket_id should be 8"); +static_assert(offsetof(GetFragDataIndexEXT, index_shm_id) == 12, + "offset of GetFragDataIndexEXT index_shm_id should be 12"); +static_assert(offsetof(GetFragDataIndexEXT, index_shm_offset) == 16, + "offset of GetFragDataIndexEXT index_shm_offset should be 16"); + #endif // GPU_COMMAND_BUFFER_COMMON_GLES2_CMD_FORMAT_AUTOGEN_H_
diff --git a/gpu/command_buffer/common/gles2_cmd_format_test_autogen.h b/gpu/command_buffer/common/gles2_cmd_format_test_autogen.h index 95a8ab8..939ea4e 100644 --- a/gpu/command_buffer/common/gles2_cmd_format_test_autogen.h +++ b/gpu/command_buffer/common/gles2_cmd_format_test_autogen.h
@@ -5298,4 +5298,50 @@ CheckBytesWrittenMatchesExpectedSize(next_cmd, sizeof(cmd)); } +TEST_F(GLES2FormatTest, BindFragDataLocationIndexedEXTBucket) { + cmds::BindFragDataLocationIndexedEXTBucket& cmd = + *GetBufferAs<cmds::BindFragDataLocationIndexedEXTBucket>(); + void* next_cmd = + cmd.Set(&cmd, static_cast<GLuint>(11), static_cast<GLuint>(12), + static_cast<GLuint>(13), static_cast<uint32_t>(14)); + EXPECT_EQ( + static_cast<uint32_t>(cmds::BindFragDataLocationIndexedEXTBucket::kCmdId), + cmd.header.command); + EXPECT_EQ(sizeof(cmd), cmd.header.size * 4u); + EXPECT_EQ(static_cast<GLuint>(11), cmd.program); + EXPECT_EQ(static_cast<GLuint>(12), cmd.colorNumber); + EXPECT_EQ(static_cast<GLuint>(13), cmd.index); + EXPECT_EQ(static_cast<uint32_t>(14), cmd.name_bucket_id); + CheckBytesWrittenMatchesExpectedSize(next_cmd, sizeof(cmd)); +} + +TEST_F(GLES2FormatTest, BindFragDataLocationEXTBucket) { + cmds::BindFragDataLocationEXTBucket& cmd = + *GetBufferAs<cmds::BindFragDataLocationEXTBucket>(); + void* next_cmd = cmd.Set(&cmd, static_cast<GLuint>(11), + static_cast<GLuint>(12), static_cast<uint32_t>(13)); + EXPECT_EQ(static_cast<uint32_t>(cmds::BindFragDataLocationEXTBucket::kCmdId), + cmd.header.command); + EXPECT_EQ(sizeof(cmd), cmd.header.size * 4u); + EXPECT_EQ(static_cast<GLuint>(11), cmd.program); + EXPECT_EQ(static_cast<GLuint>(12), cmd.colorNumber); + EXPECT_EQ(static_cast<uint32_t>(13), cmd.name_bucket_id); + CheckBytesWrittenMatchesExpectedSize(next_cmd, sizeof(cmd)); +} + +TEST_F(GLES2FormatTest, GetFragDataIndexEXT) { + cmds::GetFragDataIndexEXT& cmd = *GetBufferAs<cmds::GetFragDataIndexEXT>(); + void* next_cmd = + cmd.Set(&cmd, static_cast<GLuint>(11), static_cast<uint32_t>(12), + static_cast<uint32_t>(13), static_cast<uint32_t>(14)); + EXPECT_EQ(static_cast<uint32_t>(cmds::GetFragDataIndexEXT::kCmdId), + cmd.header.command); + EXPECT_EQ(sizeof(cmd), cmd.header.size * 4u); + EXPECT_EQ(static_cast<GLuint>(11), cmd.program); + EXPECT_EQ(static_cast<uint32_t>(12), cmd.name_bucket_id); + EXPECT_EQ(static_cast<uint32_t>(13), cmd.index_shm_id); + EXPECT_EQ(static_cast<uint32_t>(14), cmd.index_shm_offset); + CheckBytesWrittenMatchesExpectedSize(next_cmd, sizeof(cmd)); +} + #endif // GPU_COMMAND_BUFFER_COMMON_GLES2_CMD_FORMAT_TEST_AUTOGEN_H_
diff --git a/gpu/command_buffer/common/gles2_cmd_ids_autogen.h b/gpu/command_buffer/common/gles2_cmd_ids_autogen.h index 22e5b0a..38dad791 100644 --- a/gpu/command_buffer/common/gles2_cmd_ids_autogen.h +++ b/gpu/command_buffer/common/gles2_cmd_ids_autogen.h
@@ -331,7 +331,10 @@ OP(BindFragmentInputLocationCHROMIUMBucket) /* 572 */ \ OP(ProgramPathFragmentInputGenCHROMIUM) /* 573 */ \ OP(BlendBarrierKHR) /* 574 */ \ - OP(ApplyScreenSpaceAntialiasingCHROMIUM) /* 575 */ + OP(ApplyScreenSpaceAntialiasingCHROMIUM) /* 575 */ \ + OP(BindFragDataLocationIndexedEXTBucket) /* 576 */ \ + OP(BindFragDataLocationEXTBucket) /* 577 */ \ + OP(GetFragDataIndexEXT) /* 578 */ enum CommandId { kStartPoint = cmd::kLastCommonId, // All GLES2 commands start after this.
diff --git a/gpu/command_buffer/common/gles2_cmd_utils_implementation_autogen.h b/gpu/command_buffer/common/gles2_cmd_utils_implementation_autogen.h index b84fbb0..af31a510 100644 --- a/gpu/command_buffer/common/gles2_cmd_utils_implementation_autogen.h +++ b/gpu/command_buffer/common/gles2_cmd_utils_implementation_autogen.h
@@ -643,6 +643,9 @@ 0x78FB, "GL_RGB_YCBCR_422_CHROMIUM", }, { + 0x78FC, "GL_RGB_YCBCR_420V_CHROMIUM", + }, + { 0x80000000, "GL_MULTISAMPLE_BUFFER_BIT7_QCOM", }, { @@ -1279,6 +1282,9 @@ 0x8576, "GL_CONSTANT_CHROMIUM", }, { + 0x8589, "GL_SRC1_ALPHA_EXT", + }, + { 0x85B5, "GL_VERTEX_ARRAY_BINDING_OES", }, { @@ -1555,6 +1561,18 @@ 0x88F0, "GL_DEPTH24_STENCIL8_OES", }, { + 0x88F9, "GL_SRC1_COLOR_EXT", + }, + { + 0x88FA, "GL_ONE_MINUS_SRC1_COLOR_EXT", + }, + { + 0x88FB, "GL_ONE_MINUS_SRC1_ALPHA_EXT", + }, + { + 0x88FC, "GL_MAX_DUAL_SOURCE_DRAW_BUFFERS_EXT", + }, + { 0x88FD, "GL_VERTEX_ATTRIB_ARRAY_INTEGER", }, { @@ -3956,6 +3974,7 @@ {GL_RGB, "GL_RGB"}, {GL_RGB_YUV_420_CHROMIUM, "GL_RGB_YUV_420_CHROMIUM"}, {GL_RGB_YCBCR_422_CHROMIUM, "GL_RGB_YCBCR_422_CHROMIUM"}, + {GL_RGB_YCBCR_420V_CHROMIUM, "GL_RGB_YCBCR_420V_CHROMIUM"}, {GL_RGBA, "GL_RGBA"}, }; return GLES2Util::GetQualifiedEnumString(string_table,
diff --git a/gpu/command_buffer/service/context_group.cc b/gpu/command_buffer/service/context_group.cc index aeae5c65..cdda09f4 100644 --- a/gpu/command_buffer/service/context_group.cc +++ b/gpu/command_buffer/service/context_group.cc
@@ -67,6 +67,7 @@ max_vertex_uniform_vectors_(0u), max_color_attachments_(1u), max_draw_buffers_(1u), + max_dual_source_draw_buffers_(0u), program_cache_(NULL), feature_info_(feature_info) { { @@ -139,6 +140,11 @@ if (max_draw_buffers_ < 1) max_draw_buffers_ = 1; } + if (feature_info_->feature_flags().ext_blend_func_extended) { + GetIntegerv(GL_MAX_DUAL_SOURCE_DRAW_BUFFERS_EXT, + &max_dual_source_draw_buffers_); + DCHECK(max_dual_source_draw_buffers_ >= 1); + } buffer_manager_.reset( new BufferManager(memory_tracker_.get(), feature_info_.get())); @@ -285,8 +291,9 @@ path_manager_.reset(new PathManager()); - program_manager_.reset(new ProgramManager( - program_cache_, max_varying_vectors_, feature_info_.get())); + program_manager_.reset( + new ProgramManager(program_cache_, max_varying_vectors_, + max_dual_source_draw_buffers_, feature_info_.get())); if (!texture_manager_->Initialize()) { LOG(ERROR) << "Context::Group::Initialize failed because texture manager "
diff --git a/gpu/command_buffer/service/context_group.h b/gpu/command_buffer/service/context_group.h index ad2c5df..fa9d3ac5 100644 --- a/gpu/command_buffer/service/context_group.h +++ b/gpu/command_buffer/service/context_group.h
@@ -123,6 +123,10 @@ return max_draw_buffers_; } + uint32 max_dual_source_draw_buffers() const { + return max_dual_source_draw_buffers_; + } + FeatureInfo* feature_info() { return feature_info_.get(); } @@ -271,6 +275,7 @@ uint32 max_vertex_uniform_vectors_; uint32 max_color_attachments_; uint32 max_draw_buffers_; + uint32 max_dual_source_draw_buffers_; ProgramCache* program_cache_;
diff --git a/gpu/command_buffer/service/disk_cache_proto.proto b/gpu/command_buffer/service/disk_cache_proto.proto index b1059a6..6d78f4b9 100644 --- a/gpu/command_buffer/service/disk_cache_proto.proto +++ b/gpu/command_buffer/service/disk_cache_proto.proto
@@ -27,11 +27,17 @@ optional bool is_invariant = 3; } +message ShaderOutputVariableProto { + optional ShaderVariableProto basic = 1; + optional int32 location = 2; +} + message ShaderProto { optional bytes sha = 1; repeated ShaderAttributeProto attribs = 2; repeated ShaderUniformProto uniforms = 3; repeated ShaderVaryingProto varyings = 4; + repeated ShaderOutputVariableProto output_variables = 5; } message GpuProgramProto {
diff --git a/gpu/command_buffer/service/feature_info.cc b/gpu/command_buffer/service/feature_info.cc index c55ad26..76494a6 100644 --- a/gpu/command_buffer/service/feature_info.cc +++ b/gpu/command_buffer/service/feature_info.cc
@@ -171,11 +171,13 @@ blend_equation_advanced(false), blend_equation_advanced_coherent(false), ext_texture_rg(false), + chromium_image_ycbcr_420v(false), chromium_image_ycbcr_422(false), enable_subscribe_uniform(false), emulate_primitive_restart_fixed_index(false), ext_render_buffer_format_bgra8888(false), - ext_multisample_compatibility(false) {} + ext_multisample_compatibility(false), + ext_blend_func_extended(false) {} FeatureInfo::Workarounds::Workarounds() : #define GPU_OP(type, name) name(false), @@ -225,7 +227,8 @@ // The shader translator is needed to translate from WebGL-conformant GLES SL // to normal GLES SL, enforce WebGL conformance, translate from GLES SL 1.0 to - // target context GLSL, etc. + // target context GLSL, implement emulation of OpenGL ES features on OpenGL, + // etc. // The flag here is for testing only. disable_shader_translator_ = command_line->HasSwitch(switches::kDisableGLSLTranslator); @@ -903,6 +906,8 @@ #if defined(OS_MACOSX) AddExtensionString("GL_CHROMIUM_iosurface"); + AddExtensionString("GL_CHROMIUM_ycbcr_420v_image"); + feature_flags_.chromium_image_ycbcr_420v = true; #endif if (extensions.Contains("GL_APPLE_ycbcr_422")) { @@ -1183,6 +1188,36 @@ } UMA_HISTOGRAM_BOOLEAN("GPU.TextureRG", feature_flags_.ext_texture_rg); + bool has_opengl_dual_source_blending = + gl_version_info_->IsAtLeastGL(3, 3) || + (gl_version_info_->IsAtLeastGL(3, 2) && + extensions.Contains("GL_ARB_blend_func_extended")); + if (!disable_shader_translator_ && + ((gl_version_info_->IsAtLeastGL(3, 2) && + has_opengl_dual_source_blending) || + (gl_version_info_->IsAtLeastGLES(3, 0) && + extensions.Contains("GL_EXT_blend_func_extended")))) { + // Note: to simplify the code, we do not expose EXT_blend_func_extended + // unless the service context supports ES 3.0. This means the theoretical ES + // 2.0 implementation with EXT_blend_func_extended is not sufficient. + feature_flags_.ext_blend_func_extended = true; + AddExtensionString("GL_EXT_blend_func_extended"); + + // NOTE: SRC_ALPHA_SATURATE is valid for ES2 src blend factor. + // SRC_ALPHA_SATURATE is valid for ES3 src and dst blend factor. + validators_.dst_blend_factor.AddValue(GL_SRC_ALPHA_SATURATE_EXT); + + validators_.src_blend_factor.AddValue(GL_SRC1_ALPHA_EXT); + validators_.dst_blend_factor.AddValue(GL_SRC1_ALPHA_EXT); + validators_.src_blend_factor.AddValue(GL_SRC1_COLOR_EXT); + validators_.dst_blend_factor.AddValue(GL_SRC1_COLOR_EXT); + validators_.src_blend_factor.AddValue(GL_ONE_MINUS_SRC1_COLOR_EXT); + validators_.dst_blend_factor.AddValue(GL_ONE_MINUS_SRC1_COLOR_EXT); + validators_.src_blend_factor.AddValue(GL_ONE_MINUS_SRC1_ALPHA_EXT); + validators_.dst_blend_factor.AddValue(GL_ONE_MINUS_SRC1_ALPHA_EXT); + validators_.g_l_state.AddValue(GL_MAX_DUAL_SOURCE_DRAW_BUFFERS_EXT); + } + #if !defined(OS_MACOSX) if (workarounds_.ignore_egl_sync_failures) { gfx::GLFenceEGL::SetIgnoreFailures();
diff --git a/gpu/command_buffer/service/feature_info.h b/gpu/command_buffer/service/feature_info.h index 3258bdf..f372f02 100644 --- a/gpu/command_buffer/service/feature_info.h +++ b/gpu/command_buffer/service/feature_info.h
@@ -81,11 +81,13 @@ bool blend_equation_advanced; bool blend_equation_advanced_coherent; bool ext_texture_rg; + bool chromium_image_ycbcr_420v; bool chromium_image_ycbcr_422; bool enable_subscribe_uniform; bool emulate_primitive_restart_fixed_index; bool ext_render_buffer_format_bgra8888; bool ext_multisample_compatibility; + bool ext_blend_func_extended; }; struct Workarounds {
diff --git a/gpu/command_buffer/service/gles2_cmd_decoder.cc b/gpu/command_buffer/service/gles2_cmd_decoder.cc index 34ddc02..1dec5cf 100644 --- a/gpu/command_buffer/service/gles2_cmd_decoder.cc +++ b/gpu/command_buffer/service/gles2_cmd_decoder.cc
@@ -294,13 +294,10 @@ return false; } -static bool StringIsValidForGLES(const char* str) { - for (; *str; ++str) { - if (!CharacterIsValidForGLES(*str)) { - return false; - } - } - return true; +static bool StringIsValidForGLES(const std::string& str) { + return str.length() == 0 || + std::find_if_not(str.begin(), str.end(), CharacterIsValidForGLES) == + str.end(); } // This class prevents any GL errors that occur when it is in scope from @@ -1200,9 +1197,22 @@ client_id, service_id, group_->max_vertex_attribs(), client_visible); } - void DoBindAttribLocation(GLuint client_id, GLuint index, const char* name); - void DoBindUniformLocationCHROMIUM( - GLuint client_id, GLint location, const char* name); + void DoBindAttribLocation(GLuint client_id, + GLuint index, + const std::string& name); + + error::Error DoBindFragDataLocation(GLuint program_id, + GLuint colorName, + const std::string& name); + + error::Error DoBindFragDataLocationIndexed(GLuint program_id, + GLuint colorName, + GLuint index, + const std::string& name); + + void DoBindUniformLocationCHROMIUM(GLuint client_id, + GLint location, + const std::string& name); error::Error GetAttribLocationHelper( GLuint client_id, uint32 location_shm_id, uint32 location_shm_offset, @@ -1216,6 +1226,11 @@ GLuint client_id, uint32 location_shm_id, uint32 location_shm_offset, const std::string& name_str); + error::Error GetFragDataIndexHelper(GLuint program_id, + uint32 index_shm_id, + uint32 index_shm_offset, + const std::string& name_str); + // Wrapper for glShaderSource. void DoShaderSource( GLuint client_id, GLsizei count, const char** data, const GLint* length); @@ -1859,7 +1874,8 @@ void DoBindFragmentInputLocationCHROMIUM(GLuint program_id, GLint location, - const char* name); + const std::string& name); + // Generate a member function prototype for each command in an automated and // typesafe way. #define GLES2_CMD_OP(name) \ @@ -3178,6 +3194,7 @@ resources.MaxDrawBuffers = group_->max_draw_buffers(); resources.MaxExpressionComplexity = 256; resources.MaxCallStackDepth = 256; + resources.MaxDualSourceDrawBuffers = group_->max_dual_source_draw_buffers(); GLint range[2] = { 0, 0 }; GLint precision = 0; @@ -3210,6 +3227,8 @@ features().ext_shader_texture_lod ? 1 : 0; resources.NV_draw_buffers = features().nv_draw_buffers ? 1 : 0; + resources.EXT_blend_func_extended = + features().ext_blend_func_extended ? 1 : 0; } ShShaderSpec shader_spec; @@ -5485,6 +5504,12 @@ params[0] = group_->bind_generates_resource() ? 1 : 0; } return true; + case GL_MAX_DUAL_SOURCE_DRAW_BUFFERS_EXT: + *num_written = 1; + if (params) { + params[0] = group_->max_dual_source_draw_buffers(); + } + return true; default: if (pname >= GL_DRAW_BUFFER0_ARB && pname < GL_DRAW_BUFFER0_ARB + group_->max_draw_buffers()) { @@ -5614,14 +5639,15 @@ &state_, target, pname, params); } -void GLES2DecoderImpl::DoBindAttribLocation( - GLuint program_id, GLuint index, const char* name) { +void GLES2DecoderImpl::DoBindAttribLocation(GLuint program_id, + GLuint index, + const std::string& name) { if (!StringIsValidForGLES(name)) { LOCAL_SET_GL_ERROR( GL_INVALID_VALUE, "glBindAttribLocation", "Invalid character"); return; } - if (ProgramManager::IsInvalidPrefix(name, strlen(name))) { + if (ProgramManager::HasBuiltInPrefix(name)) { LOCAL_SET_GL_ERROR( GL_INVALID_OPERATION, "glBindAttribLocation", "reserved prefix"); return; @@ -5643,7 +5669,7 @@ // Program::ExecuteBindAttribLocationCalls() right before link. program->SetAttribLocationBinding(name, static_cast<GLint>(index)); // TODO(zmo): Get rid of the following glBindAttribLocation call. - glBindAttribLocation(program->service_id(), index, name); + glBindAttribLocation(program->service_id(), index, name.c_str()); } error::Error GLES2DecoderImpl::HandleBindAttribLocationBucket( @@ -5661,19 +5687,121 @@ if (!bucket->GetAsString(&name_str)) { return error::kInvalidArguments; } - DoBindAttribLocation(program, index, name_str.c_str()); + DoBindAttribLocation(program, index, name_str); return error::kNoError; } -void GLES2DecoderImpl::DoBindUniformLocationCHROMIUM( - GLuint program_id, GLint location, const char* name) { +error::Error GLES2DecoderImpl::DoBindFragDataLocation(GLuint program_id, + GLuint colorName, + const std::string& name) { + const char kFunctionName[] = "glBindFragDataLocationEXT"; + if (!StringIsValidForGLES(name)) { + LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, kFunctionName, "invalid character"); + return error::kNoError; + } + if (ProgramManager::HasBuiltInPrefix(name)) { + LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION, kFunctionName, "reserved prefix"); + return error::kNoError; + } + if (colorName >= group_->max_draw_buffers()) { + LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, kFunctionName, + "colorName out of range"); + return error::kNoError; + } + Program* program = GetProgramInfoNotShader(program_id, kFunctionName); + if (!program) { + return error::kNoError; + } + program->SetProgramOutputLocationBinding(name, colorName); + return error::kNoError; +} + +error::Error GLES2DecoderImpl::HandleBindFragDataLocationEXTBucket( + uint32 immediate_data_size, + const void* cmd_data) { + if (!features().ext_blend_func_extended) { + return error::kUnknownCommand; + } + const gles2::cmds::BindFragDataLocationEXTBucket& c = + *static_cast<const gles2::cmds::BindFragDataLocationEXTBucket*>(cmd_data); + GLuint program = static_cast<GLuint>(c.program); + GLuint colorNumber = static_cast<GLuint>(c.colorNumber); + Bucket* bucket = GetBucket(c.name_bucket_id); + if (!bucket || bucket->size() == 0) { + return error::kInvalidArguments; + } + std::string name_str; + if (!bucket->GetAsString(&name_str)) { + return error::kInvalidArguments; + } + return DoBindFragDataLocation(program, colorNumber, name_str); +} + +error::Error GLES2DecoderImpl::DoBindFragDataLocationIndexed( + GLuint program_id, + GLuint colorName, + GLuint index, + const std::string& name) { + const char kFunctionName[] = "glBindFragDataLocationIndexEXT"; + if (!StringIsValidForGLES(name)) { + LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, kFunctionName, "invalid character"); + return error::kNoError; + } + if (ProgramManager::HasBuiltInPrefix(name)) { + LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION, kFunctionName, "reserved prefix"); + return error::kNoError; + } + if (index != 0 && index != 1) { + LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, kFunctionName, "index out of range"); + return error::kNoError; + } + if ((index == 0 && colorName >= group_->max_draw_buffers()) || + (index == 1 && colorName >= group_->max_dual_source_draw_buffers())) { + LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, kFunctionName, + "colorName out of range for the color index"); + return error::kNoError; + } + Program* program = GetProgramInfoNotShader(program_id, kFunctionName); + if (!program) { + return error::kNoError; + } + program->SetProgramOutputLocationIndexedBinding(name, colorName, index); + return error::kNoError; +} + +error::Error GLES2DecoderImpl::HandleBindFragDataLocationIndexedEXTBucket( + uint32 immediate_data_size, + const void* cmd_data) { + if (!features().ext_blend_func_extended) { + return error::kUnknownCommand; + } + const gles2::cmds::BindFragDataLocationIndexedEXTBucket& c = + *static_cast<const gles2::cmds::BindFragDataLocationIndexedEXTBucket*>( + cmd_data); + GLuint program = static_cast<GLuint>(c.program); + GLuint colorNumber = static_cast<GLuint>(c.colorNumber); + GLuint index = static_cast<GLuint>(c.index); + Bucket* bucket = GetBucket(c.name_bucket_id); + if (!bucket || bucket->size() == 0) { + return error::kInvalidArguments; + } + std::string name_str; + if (!bucket->GetAsString(&name_str)) { + return error::kInvalidArguments; + } + return DoBindFragDataLocationIndexed(program, colorNumber, index, name_str); +} + +void GLES2DecoderImpl::DoBindUniformLocationCHROMIUM(GLuint program_id, + GLint location, + const std::string& name) { if (!StringIsValidForGLES(name)) { LOCAL_SET_GL_ERROR( GL_INVALID_VALUE, "glBindUniformLocationCHROMIUM", "Invalid character"); return; } - if (ProgramManager::IsInvalidPrefix(name, strlen(name))) { + if (ProgramManager::HasBuiltInPrefix(name)) { LOCAL_SET_GL_ERROR( GL_INVALID_OPERATION, "glBindUniformLocationCHROMIUM", "reserved prefix"); @@ -5715,7 +5843,7 @@ if (!bucket->GetAsString(&name_str)) { return error::kInvalidArguments; } - DoBindUniformLocationCHROMIUM(program, location, name_str.c_str()); + DoBindUniformLocationCHROMIUM(program, location, name_str); return error::kNoError; } @@ -9360,7 +9488,7 @@ error::Error GLES2DecoderImpl::GetAttribLocationHelper( GLuint client_id, uint32 location_shm_id, uint32 location_shm_offset, const std::string& name_str) { - if (!StringIsValidForGLES(name_str.c_str())) { + if (!StringIsValidForGLES(name_str)) { LOCAL_SET_GL_ERROR( GL_INVALID_VALUE, "glGetAttribLocation", "Invalid character"); return error::kNoError; @@ -9408,7 +9536,7 @@ error::Error GLES2DecoderImpl::GetUniformLocationHelper( GLuint client_id, uint32 location_shm_id, uint32 location_shm_offset, const std::string& name_str) { - if (!StringIsValidForGLES(name_str.c_str())) { + if (!StringIsValidForGLES(name_str)) { LOCAL_SET_GL_ERROR( GL_INVALID_VALUE, "glGetUniformLocation", "Invalid character"); return error::kNoError; @@ -9508,6 +9636,7 @@ error::Error GLES2DecoderImpl::GetFragDataLocationHelper( GLuint client_id, uint32 location_shm_id, uint32 location_shm_offset, const std::string& name_str) { + const char kFunctionName[] = "glGetFragDataLocation"; GLint* location = GetSharedMemoryAs<GLint*>( location_shm_id, location_shm_offset, sizeof(GLint)); if (!location) { @@ -9517,12 +9646,17 @@ if (*location != -1) { return error::kInvalidArguments; } - Program* program = GetProgramInfoNotShader( - client_id, "glGetFragDataLocation"); + Program* program = GetProgramInfoNotShader(client_id, kFunctionName); if (!program) { return error::kNoError; } - *location = glGetFragDataLocation(program->service_id(), name_str.c_str()); + if (!program->IsValid()) { + LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION, kFunctionName, + "program not linked"); + return error::kNoError; + } + + *location = program->GetFragDataLocation(name_str); return error::kNoError; } @@ -9545,6 +9679,55 @@ c.program, c.location_shm_id, c.location_shm_offset, name_str); } +error::Error GLES2DecoderImpl::GetFragDataIndexHelper( + GLuint program_id, + uint32 index_shm_id, + uint32 index_shm_offset, + const std::string& name_str) { + const char kFunctionName[] = "glGetFragDataIndexEXT"; + GLint* index = + GetSharedMemoryAs<GLint*>(index_shm_id, index_shm_offset, sizeof(GLint)); + if (!index) { + return error::kOutOfBounds; + } + // Check that the client initialized the result. + if (*index != -1) { + return error::kInvalidArguments; + } + Program* program = GetProgramInfoNotShader(program_id, kFunctionName); + if (!program) { + return error::kNoError; + } + if (!program->IsValid()) { + LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION, kFunctionName, + "program not linked"); + return error::kNoError; + } + + *index = program->GetFragDataIndex(name_str); + return error::kNoError; +} + +error::Error GLES2DecoderImpl::HandleGetFragDataIndexEXT( + uint32 immediate_data_size, + const void* cmd_data) { + if (!features().ext_blend_func_extended) { + return error::kUnknownCommand; + } + const gles2::cmds::GetFragDataIndexEXT& c = + *static_cast<const gles2::cmds::GetFragDataIndexEXT*>(cmd_data); + Bucket* bucket = GetBucket(c.name_bucket_id); + if (!bucket) { + return error::kInvalidArguments; + } + std::string name_str; + if (!bucket->GetAsString(&name_str)) { + return error::kInvalidArguments; + } + return GetFragDataIndexHelper(c.program, c.index_shm_id, c.index_shm_offset, + name_str); +} + error::Error GLES2DecoderImpl::HandleGetUniformBlockIndex( uint32 immediate_data_size, const void* cmd_data) { if (!unsafe_es3_apis_enabled()) @@ -15288,23 +15471,24 @@ return error::kNoError; } -void GLES2DecoderImpl::DoBindFragmentInputLocationCHROMIUM(GLuint program_id, - GLint location, - const char* name) { +void GLES2DecoderImpl::DoBindFragmentInputLocationCHROMIUM( + GLuint program_id, + GLint location, + const std::string& name) { static const char kFunctionName[] = "glBindFragmentInputLocationCHROMIUM"; - Program* program = GetProgram(program_id); - if (!program || program->IsDeleted()) { - LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION, kFunctionName, "invalid program"); - return; - } if (!StringIsValidForGLES(name)) { LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, kFunctionName, "invalid character"); return; } - if (ProgramManager::IsInvalidPrefix(name, strlen(name))) { + if (ProgramManager::HasBuiltInPrefix(name)) { LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION, kFunctionName, "reserved prefix"); return; } + Program* program = GetProgram(program_id); + if (!program || program->IsDeleted()) { + LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION, kFunctionName, "invalid program"); + return; + } if (location < 0 || static_cast<uint32>(location) >= group_->max_varying_vectors() * 4) { LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, kFunctionName, @@ -15335,7 +15519,7 @@ if (!bucket->GetAsString(&name_str)) { return error::kInvalidArguments; } - DoBindFragmentInputLocationCHROMIUM(program, location, name_str.c_str()); + DoBindFragmentInputLocationCHROMIUM(program, location, name_str); return error::kNoError; }
diff --git a/gpu/command_buffer/service/gles2_cmd_decoder_unittest.cc b/gpu/command_buffer/service/gles2_cmd_decoder_unittest.cc index 3f6d20d..c09c658 100644 --- a/gpu/command_buffer/service/gles2_cmd_decoder_unittest.cc +++ b/gpu/command_buffer/service/gles2_cmd_decoder_unittest.cc
@@ -1533,6 +1533,17 @@ EXPECT_EQ(entries_per_cmd_ + cmds_[1].header.size, num_processed); } +void GLES3DecoderWithESSL3ShaderTest::SetUp() { + base::CommandLine command_line(0, nullptr); + command_line.AppendSwitch(switches::kEnableUnsafeES3APIs); + InitState init; + init.gl_version = "OpenGL ES 3.0"; + init.bind_generates_resource = true; + init.context_type = CONTEXT_TYPE_OPENGLES3; + InitDecoderWithCommandLine(init, &command_line); + SetupDefaultProgram(); +} + INSTANTIATE_TEST_CASE_P(Service, GLES2DecoderTest, ::testing::Bool()); INSTANTIATE_TEST_CASE_P(Service, GLES2DecoderWithShaderTest, ::testing::Bool()); @@ -1547,5 +1558,9 @@ INSTANTIATE_TEST_CASE_P(Service, GLES3DecoderTest, ::testing::Bool()); +INSTANTIATE_TEST_CASE_P(Service, + GLES3DecoderWithESSL3ShaderTest, + ::testing::Bool()); + } // namespace gles2 } // namespace gpu
diff --git a/gpu/command_buffer/service/gles2_cmd_decoder_unittest.h b/gpu/command_buffer/service/gles2_cmd_decoder_unittest.h index a57903c..4cab05c 100644 --- a/gpu/command_buffer/service/gles2_cmd_decoder_unittest.h +++ b/gpu/command_buffer/service/gles2_cmd_decoder_unittest.h
@@ -82,6 +82,12 @@ void SetUp() override; }; +class GLES3DecoderWithESSL3ShaderTest : public GLES2DecoderWithShaderTestBase { + public: + GLES3DecoderWithESSL3ShaderTest() { shader_language_version_ = 300; } + void SetUp() override; +}; + } // namespace gles2 } // namespace gpu
diff --git a/gpu/command_buffer/service/gles2_cmd_decoder_unittest_base.cc b/gpu/command_buffer/service/gles2_cmd_decoder_unittest_base.cc index c704c285..b149135 100644 --- a/gpu/command_buffer/service/gles2_cmd_decoder_unittest_base.cc +++ b/gpu/command_buffer/service/gles2_cmd_decoder_unittest_base.cc
@@ -120,7 +120,8 @@ cached_color_mask_alpha_(true), cached_depth_mask_(true), cached_stencil_front_mask_(static_cast<GLuint>(-1)), - cached_stencil_back_mask_(static_cast<GLuint>(-1)) { + cached_stencil_back_mask_(static_cast<GLuint>(-1)), + shader_language_version_(100) { memset(immediate_buffer_, 0xEE, sizeof(immediate_buffer_)); } @@ -1498,7 +1499,10 @@ const GLenum GLES2DecoderTestBase::kUniformCubemapType; const GLint GLES2DecoderTestBase::kInvalidUniformLocation; const GLint GLES2DecoderTestBase::kBadUniformIndex; - +const GLint GLES2DecoderTestBase::kOutputVariable1Size; +const GLenum GLES2DecoderTestBase::kOutputVariable1Type; +const GLuint GLES2DecoderTestBase::kOutputVariable1ColorName; +const GLuint GLES2DecoderTestBase::kOutputVariable1Index; #endif const char* GLES2DecoderTestBase::kAttrib1Name = "attrib1"; @@ -1512,6 +1516,9 @@ const char* GLES2DecoderTestBase::kUniform6Name = "uniform6"; const char* GLES2DecoderTestBase::kUniform7Name = "uniform7"; +const char* GLES2DecoderTestBase::kOutputVariable1Name = "gl_FragColor"; +const char* GLES2DecoderTestBase::kOutputVariable1NameESSL3 = "color"; + void GLES2DecoderTestBase::SetupDefaultProgram() { { static AttribInfo attribs[] = { @@ -1660,6 +1667,19 @@ GLuint program_client_id, GLuint program_service_id, GLuint vertex_shader_client_id, GLuint vertex_shader_service_id, GLuint fragment_shader_client_id, GLuint fragment_shader_service_id) { + static TestHelper::ProgramOutputInfo kProgramOutputsESSL1[] = {{ + kOutputVariable1Name, kOutputVariable1Size, kOutputVariable1Type, + kOutputVariable1ColorName, kOutputVariable1Index, + }}; + static TestHelper::ProgramOutputInfo kProgramOutputsESSL3[] = {{ + kOutputVariable1NameESSL3, kOutputVariable1Size, kOutputVariable1Type, + kOutputVariable1ColorName, kOutputVariable1Index, + }}; + TestHelper::ProgramOutputInfo* program_outputs = + shader_language_version_ == 100 ? kProgramOutputsESSL1 + : kProgramOutputsESSL3; + const size_t kNumProgramOutputs = 1; + { InSequence s; @@ -1671,9 +1691,11 @@ AttachShader(program_service_id, fragment_shader_service_id)) .Times(1) .RetiresOnSaturation(); - TestHelper::SetupShaderExpectations(gl_.get(), group_->feature_info(), - attribs, num_attribs, uniforms, - num_uniforms, program_service_id); + + TestHelper::SetupShaderExpectationsWithVaryings( + gl_.get(), group_->feature_info(), attribs, num_attribs, uniforms, + num_uniforms, nullptr, 0, program_outputs, kNumProgramOutputs, + program_service_id); } DoCreateShader( @@ -1682,10 +1704,20 @@ GL_FRAGMENT_SHADER, fragment_shader_client_id, fragment_shader_service_id); - TestHelper::SetShaderStates( - gl_.get(), GetShader(vertex_shader_client_id), true); - TestHelper::SetShaderStates( - gl_.get(), GetShader(fragment_shader_client_id), true); + TestHelper::SetShaderStates(gl_.get(), GetShader(vertex_shader_client_id), + true, nullptr, nullptr, &shader_language_version_, + nullptr, nullptr, nullptr, nullptr, nullptr, + nullptr); + + OutputVariableList frag_output_variable_list; + frag_output_variable_list.push_back(TestHelper::ConstructOutputVariable( + program_outputs[0].type, program_outputs[0].size, GL_MEDIUM_FLOAT, true, + program_outputs[0].name)); + + TestHelper::SetShaderStates(gl_.get(), GetShader(fragment_shader_client_id), + true, nullptr, nullptr, &shader_language_version_, + nullptr, nullptr, nullptr, nullptr, + &frag_output_variable_list, nullptr); cmds::AttachShader attach_cmd; attach_cmd.Init(program_client_id, vertex_shader_client_id);
diff --git a/gpu/command_buffer/service/gles2_cmd_decoder_unittest_base.h b/gpu/command_buffer/service/gles2_cmd_decoder_unittest_base.h index d19937d9..7746969 100644 --- a/gpu/command_buffer/service/gles2_cmd_decoder_unittest_base.h +++ b/gpu/command_buffer/service/gles2_cmd_decoder_unittest_base.h
@@ -584,6 +584,13 @@ static const GLint kInvalidUniformLocation = 30; static const GLint kBadUniformIndex = 1000; + static const GLint kOutputVariable1Size = 0; + static const GLenum kOutputVariable1Type = GL_FLOAT_VEC4; + static const GLuint kOutputVariable1ColorName = 7; + static const GLuint kOutputVariable1Index = 0; + static const char* kOutputVariable1Name; + static const char* kOutputVariable1NameESSL3; + // Use StrictMock to make 100% sure we know how GL will be called. scoped_ptr< ::testing::StrictMock< ::gfx::MockGLInterface> > gl_; scoped_refptr<gfx::GLSurfaceStub> surface_; @@ -642,6 +649,8 @@ EnableFlags enable_flags_; + int shader_language_version_; + private: class MockCommandBufferEngine : public CommandBufferEngine { public:
diff --git a/gpu/command_buffer/service/gles2_cmd_decoder_unittest_extensions.cc b/gpu/command_buffer/service/gles2_cmd_decoder_unittest_extensions.cc index c0b6de5..d295183 100644 --- a/gpu/command_buffer/service/gles2_cmd_decoder_unittest_extensions.cc +++ b/gpu/command_buffer/service/gles2_cmd_decoder_unittest_extensions.cc
@@ -520,6 +520,26 @@ GLES2DecoderTestWithEXTMultisampleCompatibility, ::testing::Bool()); +class GLES2DecoderTestWithBlendFuncExtended : public GLES2DecoderTest { + public: + GLES2DecoderTestWithBlendFuncExtended() {} + void SetUp() override { + InitState init; + init.gl_version = "opengl es 3.0"; + init.has_alpha = true; + init.has_depth = true; + init.request_alpha = true; + init.request_depth = true; + init.bind_generates_resource = true; + init.extensions = "GL_EXT_blend_func_extended"; + InitDecoder(init); + } +}; +INSTANTIATE_TEST_CASE_P(Service, + GLES2DecoderTestWithBlendFuncExtended, + ::testing::Bool()); + + TEST_P(GLES2DecoderTestWithCHROMIUMPathRendering, GenDeletePaths) { static GLuint kFirstClientID = client_path_id_ + 88; static GLsizei kPathCount = 58;
diff --git a/gpu/command_buffer/service/gles2_cmd_decoder_unittest_programs.cc b/gpu/command_buffer/service/gles2_cmd_decoder_unittest_programs.cc index 8d675375..cb49ae9 100644 --- a/gpu/command_buffer/service/gles2_cmd_decoder_unittest_programs.cc +++ b/gpu/command_buffer/service/gles2_cmd_decoder_unittest_programs.cc
@@ -2016,27 +2016,22 @@ EXPECT_NE(error::kNoError, ExecuteCmd(cmd)); } -TEST_P(GLES2DecoderWithShaderTest, GetFragDataLocation) { +TEST_P(GLES3DecoderWithESSL3ShaderTest, GetFragDataLocation) { const uint32 kBucketId = 123; - const GLint kLocation = 10; - const char* kName = "color"; typedef GetFragDataLocation::Result Result; Result* result = GetSharedMemoryAs<Result*>(); - SetBucketAsCString(kBucketId, kName); + SetBucketAsCString(kBucketId, kOutputVariable1NameESSL3); *result = -1; GetFragDataLocation cmd; cmd.Init(client_program_id_, kBucketId, kSharedMemoryId, kSharedMemoryOffset); - EXPECT_CALL(*gl_, GetFragDataLocation(kServiceProgramId, StrEq(kName))) - .WillOnce(Return(kLocation)) - .RetiresOnSaturation(); decoder_->set_unsafe_es3_apis_enabled(true); EXPECT_EQ(error::kNoError, ExecuteCmd(cmd)); - EXPECT_EQ(kLocation, *result); + EXPECT_EQ(static_cast<GLint>(kOutputVariable1ColorName), *result); decoder_->set_unsafe_es3_apis_enabled(false); EXPECT_EQ(error::kUnknownCommand, ExecuteCmd(cmd)); } -TEST_P(GLES2DecoderWithShaderTest, GetFragDataLocationInvalidArgs) { +TEST_P(GLES3DecoderWithESSL3ShaderTest, GetFragDataLocationInvalidArgs) { const uint32 kBucketId = 123; typedef GetFragDataLocation::Result Result; Result* result = GetSharedMemoryAs<Result*>();
diff --git a/gpu/command_buffer/service/gles2_cmd_validation_implementation_autogen.h b/gpu/command_buffer/service/gles2_cmd_validation_implementation_autogen.h index 981d100..7a201b7 100644 --- a/gpu/command_buffer/service/gles2_cmd_validation_implementation_autogen.h +++ b/gpu/command_buffer/service/gles2_cmd_validation_implementation_autogen.h
@@ -363,7 +363,11 @@ }; static const GLenum valid_image_internal_format_table[] = { - GL_RGB, GL_RGB_YUV_420_CHROMIUM, GL_RGB_YCBCR_422_CHROMIUM, GL_RGBA, + GL_RGB, + GL_RGB_YUV_420_CHROMIUM, + GL_RGB_YCBCR_422_CHROMIUM, + GL_RGB_YCBCR_420V_CHROMIUM, + GL_RGBA, }; static const GLenum valid_image_usage_table[] = {
diff --git a/gpu/command_buffer/service/memory_program_cache.cc b/gpu/command_buffer/service/memory_program_cache.cc index 74809a9..1841348 100644 --- a/gpu/command_buffer/service/memory_program_cache.cc +++ b/gpu/command_buffer/service/memory_program_cache.cc
@@ -40,12 +40,6 @@ namespace { -enum ShaderMapType { - ATTRIB_MAP = 0, - UNIFORM_MAP, - VARYING_MAP -}; - void FillShaderVariableProto( ShaderVariableProto* proto, const sh::ShaderVariable& variable) { proto->set_type(variable.type); @@ -79,6 +73,12 @@ proto->set_is_invariant(varying.isInvariant); } +void FillShaderOutputVariableProto(ShaderOutputVariableProto* proto, + const sh::OutputVariable& attrib) { + FillShaderVariableProto(proto->mutable_basic(), attrib); + proto->set_location(attrib.location); +} + void FillShaderProto(ShaderProto* proto, const char* sha, const Shader* shader) { proto->set_sha(sha, gpu::gles2::ProgramCache::kHashLength); @@ -97,6 +97,11 @@ ShaderVaryingProto* info = proto->add_varyings(); FillShaderVaryingProto(info, iter->second); } + for (auto iter = shader->output_variable_list().begin(); + iter != shader->output_variable_list().end(); ++iter) { + ShaderOutputVariableProto* info = proto->add_output_variables(); + FillShaderOutputVariableProto(info, *iter); + } } void RetrieveShaderVariableInfo( @@ -138,6 +143,14 @@ (*map)[proto.basic().mapped_name()] = varying; } +void RetrieveShaderOutputVariableInfo(const ShaderOutputVariableProto& proto, + OutputVariableList* list) { + sh::OutputVariable output_variable; + RetrieveShaderVariableInfo(proto.basic(), &output_variable); + output_variable.location = proto.location(); + list->push_back(output_variable); +} + void RunShaderCallback(const ShaderCacheCallback& callback, GpuProgramProto* proto, std::string sha_string) { @@ -213,9 +226,11 @@ shader_a->set_attrib_map(value->attrib_map_0()); shader_a->set_uniform_map(value->uniform_map_0()); shader_a->set_varying_map(value->varying_map_0()); + shader_a->set_output_variable_list(value->output_variable_list_0()); shader_b->set_attrib_map(value->attrib_map_1()); shader_b->set_uniform_map(value->uniform_map_1()); shader_b->set_varying_map(value->varying_map_1()); + shader_b->set_output_variable_list(value->output_variable_list_1()); if (!shader_callback.is_null() && !base::CommandLine::ForCurrentProcess()->HasSwitch( @@ -302,20 +317,14 @@ RunShaderCallback(shader_callback, proto.get(), sha_string); } - store_.Put(sha_string, - new ProgramCacheValue(length, - format, - binary.release(), - sha_string, - a_sha, - shader_a->attrib_map(), - shader_a->uniform_map(), - shader_a->varying_map(), - b_sha, - shader_b->attrib_map(), - shader_b->uniform_map(), - shader_b->varying_map(), - this)); + store_.Put( + sha_string, + new ProgramCacheValue( + length, format, binary.release(), sha_string, a_sha, + shader_a->attrib_map(), shader_a->uniform_map(), + shader_a->varying_map(), shader_a->output_variable_list(), b_sha, + shader_b->attrib_map(), shader_b->uniform_map(), + shader_b->varying_map(), shader_b->output_variable_list(), this)); UMA_HISTOGRAM_COUNTS("GPU.ProgramCache.MemorySizeAfterKb", curr_size_bytes_ / 1024); @@ -327,6 +336,7 @@ AttributeMap vertex_attribs; UniformMap vertex_uniforms; VaryingMap vertex_varyings; + OutputVariableList vertex_output_variables; for (int i = 0; i < proto->vertex_shader().attribs_size(); i++) { RetrieveShaderAttributeInfo(proto->vertex_shader().attribs(i), &vertex_attribs); @@ -339,10 +349,15 @@ RetrieveShaderVaryingInfo(proto->vertex_shader().varyings(i), &vertex_varyings); } + for (int i = 0; i < proto->vertex_shader().output_variables_size(); i++) { + RetrieveShaderOutputVariableInfo( + proto->vertex_shader().output_variables(i), &vertex_output_variables); + } AttributeMap fragment_attribs; UniformMap fragment_uniforms; VaryingMap fragment_varyings; + OutputVariableList fragment_output_variables; for (int i = 0; i < proto->fragment_shader().attribs_size(); i++) { RetrieveShaderAttributeInfo(proto->fragment_shader().attribs(i), &fragment_attribs); @@ -355,24 +370,24 @@ RetrieveShaderVaryingInfo(proto->fragment_shader().varyings(i), &fragment_varyings); } + for (int i = 0; i < proto->fragment_shader().output_variables_size(); i++) { + RetrieveShaderOutputVariableInfo( + proto->fragment_shader().output_variables(i), + &fragment_output_variables); + } scoped_ptr<char[]> binary(new char[proto->program().length()]); memcpy(binary.get(), proto->program().c_str(), proto->program().length()); - store_.Put(proto->sha(), - new ProgramCacheValue(proto->program().length(), - proto->format(), - binary.release(), - proto->sha(), - proto->vertex_shader().sha().c_str(), - vertex_attribs, - vertex_uniforms, - vertex_varyings, - proto->fragment_shader().sha().c_str(), - fragment_attribs, - fragment_uniforms, - fragment_varyings, - this)); + store_.Put( + proto->sha(), + new ProgramCacheValue( + proto->program().length(), proto->format(), binary.release(), + proto->sha(), proto->vertex_shader().sha().c_str(), vertex_attribs, + vertex_uniforms, vertex_varyings, vertex_output_variables, + proto->fragment_shader().sha().c_str(), fragment_attribs, + fragment_uniforms, fragment_varyings, fragment_output_variables, + this)); UMA_HISTOGRAM_COUNTS("GPU.ProgramCache.MemorySizeAfterKb", curr_size_bytes_ / 1024); @@ -390,10 +405,12 @@ const AttributeMap& attrib_map_0, const UniformMap& uniform_map_0, const VaryingMap& varying_map_0, + const OutputVariableList& output_variable_list_0, const char* shader_1_hash, const AttributeMap& attrib_map_1, const UniformMap& uniform_map_1, const VaryingMap& varying_map_1, + const OutputVariableList& output_variable_list_1, MemoryProgramCache* program_cache) : length_(length), format_(format), @@ -403,10 +420,12 @@ attrib_map_0_(attrib_map_0), uniform_map_0_(uniform_map_0), varying_map_0_(varying_map_0), + output_variable_list_0_(output_variable_list_0), shader_1_hash_(shader_1_hash, kHashLength), attrib_map_1_(attrib_map_1), uniform_map_1_(uniform_map_1), varying_map_1_(varying_map_1), + output_variable_list_1_(output_variable_list_1), program_cache_(program_cache) { program_cache_->curr_size_bytes_ += length_; program_cache_->LinkedProgramCacheSuccess(program_hash);
diff --git a/gpu/command_buffer/service/memory_program_cache.h b/gpu/command_buffer/service/memory_program_cache.h index 593625da..7e9b83dd 100644 --- a/gpu/command_buffer/service/memory_program_cache.h +++ b/gpu/command_buffer/service/memory_program_cache.h
@@ -57,10 +57,12 @@ const AttributeMap& attrib_map_0, const UniformMap& uniform_map_0, const VaryingMap& varying_map_0, + const OutputVariableList& output_variable_list_0, const char* shader_1_hash, const AttributeMap& attrib_map_1, const UniformMap& uniform_map_1, const VaryingMap& varying_map_1, + const OutputVariableList& output_variable_list_1, MemoryProgramCache* program_cache); GLsizei length() const { @@ -91,6 +93,10 @@ return varying_map_0_; } + const OutputVariableList& output_variable_list_0() const { + return output_variable_list_0_; + } + const std::string& shader_1_hash() const { return shader_1_hash_; } @@ -107,6 +113,10 @@ return varying_map_1_; } + const OutputVariableList& output_variable_list_1() const { + return output_variable_list_1_; + } + private: friend class base::RefCounted<ProgramCacheValue>; @@ -120,10 +130,12 @@ const AttributeMap attrib_map_0_; const UniformMap uniform_map_0_; const VaryingMap varying_map_0_; + const OutputVariableList output_variable_list_0_; const std::string shader_1_hash_; const AttributeMap attrib_map_1_; const UniformMap uniform_map_1_; const VaryingMap varying_map_1_; + const OutputVariableList output_variable_list_1_; MemoryProgramCache* const program_cache_; DISALLOW_COPY_AND_ASSIGN(ProgramCacheValue);
diff --git a/gpu/command_buffer/service/memory_program_cache_unittest.cc b/gpu/command_buffer/service/memory_program_cache_unittest.cc index a005db95..f92860f2 100644 --- a/gpu/command_buffer/service/memory_program_cache_unittest.cc +++ b/gpu/command_buffer/service/memory_program_cache_unittest.cc
@@ -100,9 +100,11 @@ AttributeMap vertex_attrib_map; UniformMap vertex_uniform_map; VaryingMap vertex_varying_map; + OutputVariableList vertex_output_variable_list; AttributeMap fragment_attrib_map; UniformMap fragment_uniform_map; VaryingMap fragment_varying_map; + OutputVariableList fragment_output_variable_list; vertex_attrib_map["a"] = TestHelper::ConstructAttribute( GL_FLOAT_VEC2, 34, GL_LOW_FLOAT, false, "a"); @@ -112,24 +114,28 @@ GL_FLOAT_VEC3, 3114, GL_HIGH_FLOAT, true, "b"); vertex_varying_map["c"] = TestHelper::ConstructVarying( GL_FLOAT_VEC4, 2, GL_HIGH_FLOAT, true, "c"); + vertex_output_variable_list.push_back(TestHelper::ConstructOutputVariable( + GL_FLOAT, 0, GL_HIGH_FLOAT, true, "d")); fragment_attrib_map["jjjbb"] = TestHelper::ConstructAttribute( GL_FLOAT_MAT4, 1114, GL_MEDIUM_FLOAT, false, "jjjbb"); fragment_uniform_map["k"] = TestHelper::ConstructUniform( GL_FLOAT_MAT2, 34413, GL_MEDIUM_FLOAT, true, "k"); fragment_varying_map["c"] = TestHelper::ConstructVarying( GL_FLOAT_VEC4, 2, GL_HIGH_FLOAT, true, "c"); + fragment_output_variable_list.push_back(TestHelper::ConstructOutputVariable( + GL_FLOAT, 0, GL_HIGH_FLOAT, true, "d")); vertex_shader_->set_source("bbbalsldkdkdkd"); fragment_shader_->set_source("bbbal sldkdkdkas 134 ad"); + TestHelper::SetShaderStates(gl_.get(), vertex_shader_, true, nullptr, + nullptr, nullptr, &vertex_attrib_map, + &vertex_uniform_map, &vertex_varying_map, + nullptr, &vertex_output_variable_list, nullptr); TestHelper::SetShaderStates( - gl_.get(), vertex_shader_, true, NULL, NULL, NULL, - &vertex_attrib_map, &vertex_uniform_map, &vertex_varying_map, - NULL, NULL); - TestHelper::SetShaderStates( - gl_.get(), fragment_shader_, true, NULL, NULL, NULL, + gl_.get(), fragment_shader_, true, nullptr, nullptr, nullptr, &fragment_attrib_map, &fragment_uniform_map, &fragment_varying_map, - NULL, NULL); + nullptr, &fragment_output_variable_list, nullptr); } void SetExpectationsForSaveLinkedProgram( @@ -254,17 +260,22 @@ AttributeMap vertex_attrib_map = vertex_shader_->attrib_map(); UniformMap vertex_uniform_map = vertex_shader_->uniform_map(); VaryingMap vertex_varying_map = vertex_shader_->varying_map(); + OutputVariableList vertex_output_variable_list = + vertex_shader_->output_variable_list(); AttributeMap fragment_attrib_map = fragment_shader_->attrib_map(); UniformMap fragment_uniform_map = fragment_shader_->uniform_map(); VaryingMap fragment_varying_map = fragment_shader_->varying_map(); + OutputVariableList fragment_output_variable_list = + fragment_shader_->output_variable_list(); vertex_shader_->set_attrib_map(AttributeMap()); vertex_shader_->set_uniform_map(UniformMap()); vertex_shader_->set_varying_map(VaryingMap()); + vertex_shader_->set_output_variable_list(OutputVariableList()); fragment_shader_->set_attrib_map(AttributeMap()); fragment_shader_->set_uniform_map(UniformMap()); fragment_shader_->set_varying_map(VaryingMap()); - + fragment_shader_->set_output_variable_list(OutputVariableList()); SetExpectationsForLoadLinkedProgram(kProgramId, &emulator); EXPECT_EQ(ProgramCache::PROGRAM_LOAD_SUCCESS, cache_->LoadLinkedProgram( @@ -283,9 +294,13 @@ EXPECT_EQ(vertex_attrib_map, vertex_shader_->attrib_map()); EXPECT_EQ(vertex_uniform_map, vertex_shader_->uniform_map()); EXPECT_EQ(vertex_varying_map, vertex_shader_->varying_map()); + EXPECT_EQ(vertex_output_variable_list, + vertex_shader_->output_variable_list()); EXPECT_EQ(fragment_attrib_map, fragment_shader_->attrib_map()); EXPECT_EQ(fragment_uniform_map, fragment_shader_->uniform_map()); EXPECT_EQ(fragment_varying_map, fragment_shader_->varying_map()); + EXPECT_EQ(fragment_output_variable_list, + fragment_shader_->output_variable_list()); #endif } @@ -309,16 +324,22 @@ AttributeMap vertex_attrib_map = vertex_shader_->attrib_map(); UniformMap vertex_uniform_map = vertex_shader_->uniform_map(); VaryingMap vertex_varying_map = vertex_shader_->varying_map(); + OutputVariableList vertex_output_variable_list = + vertex_shader_->output_variable_list(); AttributeMap fragment_attrib_map = fragment_shader_->attrib_map(); UniformMap fragment_uniform_map = fragment_shader_->uniform_map(); VaryingMap fragment_varying_map = fragment_shader_->varying_map(); + OutputVariableList fragment_output_variable_list = + fragment_shader_->output_variable_list(); vertex_shader_->set_attrib_map(AttributeMap()); vertex_shader_->set_uniform_map(UniformMap()); vertex_shader_->set_varying_map(VaryingMap()); + vertex_shader_->set_output_variable_list(OutputVariableList()); fragment_shader_->set_attrib_map(AttributeMap()); fragment_shader_->set_uniform_map(UniformMap()); fragment_shader_->set_varying_map(VaryingMap()); + fragment_shader_->set_output_variable_list(OutputVariableList()); SetExpectationsForLoadLinkedProgram(kProgramId, &emulator); @@ -341,9 +362,13 @@ EXPECT_EQ(vertex_attrib_map, vertex_shader_->attrib_map()); EXPECT_EQ(vertex_uniform_map, vertex_shader_->uniform_map()); EXPECT_EQ(vertex_varying_map, vertex_shader_->varying_map()); + EXPECT_EQ(vertex_output_variable_list, + vertex_shader_->output_variable_list()); EXPECT_EQ(fragment_attrib_map, fragment_shader_->attrib_map()); EXPECT_EQ(fragment_uniform_map, fragment_shader_->uniform_map()); EXPECT_EQ(fragment_varying_map, fragment_shader_->varying_map()); + EXPECT_EQ(fragment_output_variable_list, + fragment_shader_->output_variable_list()); #endif }
diff --git a/gpu/command_buffer/service/mocks.h b/gpu/command_buffer/service/mocks.h index 2ef657f..a9a7efba 100644 --- a/gpu/command_buffer/service/mocks.h +++ b/gpu/command_buffer/service/mocks.h
@@ -95,16 +95,17 @@ const ShBuiltInResources* resources, ShShaderOutput shader_output_language, ShCompileOptions driver_bug_workarounds)); - MOCK_CONST_METHOD9(Translate, bool( - const std::string& shader_source, - std::string* info_log, - std::string* translated_source, - int* shader_version, - AttributeMap* attrib_map, - UniformMap* uniform_map, - VaryingMap* varying_map, - InterfaceBlockMap* interface_block_map, - NameMap* name_map)); + MOCK_CONST_METHOD10(Translate, + bool(const std::string& shader_source, + std::string* info_log, + std::string* translated_source, + int* shader_version, + AttributeMap* attrib_map, + UniformMap* uniform_map, + VaryingMap* varying_map, + InterfaceBlockMap* interface_block_map, + OutputVariableList* output_variable_list, + NameMap* name_map)); MOCK_CONST_METHOD0( GetStringForOptionsThatWouldAffectCompilation, std::string()); private:
diff --git a/gpu/command_buffer/service/program_manager.cc b/gpu/command_buffer/service/program_manager.cc index bfff34c..45b0c55 100644 --- a/gpu/command_buffer/service/program_manager.cc +++ b/gpu/command_buffer/service/program_manager.cc
@@ -28,6 +28,7 @@ #include "gpu/command_buffer/service/program_cache.h" #include "gpu/command_buffer/service/shader_manager.h" #include "third_party/re2/re2/re2.h" +#include "ui/gl/gl_version_info.h" using base::TimeDelta; using base::TimeTicks; @@ -249,10 +250,9 @@ } Program::UniformInfo::~UniformInfo() {} -bool ProgramManager::IsInvalidPrefix(const char* name, size_t length) { - static const char kInvalidPrefix[] = { 'g', 'l', '_' }; - return (length >= sizeof(kInvalidPrefix) && - memcmp(name, kInvalidPrefix, sizeof(kInvalidPrefix)) == 0); +bool ProgramManager::HasBuiltInPrefix(const std::string& name) { + return name.length() >= 3 && name[0] == 'g' && name[1] == 'l' && + name[2] == '_'; } Program::Program(ProgramManager* manager, GLuint service_id) @@ -279,6 +279,7 @@ uniform_locations_.clear(); fragment_input_infos_.clear(); fragment_input_locations_.clear(); + program_output_infos_.clear(); sampler_indices_.clear(); attrib_location_to_index_map_.clear(); } @@ -519,6 +520,7 @@ #endif UpdateFragmentInputs(); + UpdateProgramOutputs(); valid_ = true; } @@ -563,8 +565,7 @@ GLint service_location = -1; // Force builtin uniforms (gl_DepthRange) to have invalid location. - if (!ProgramManager::IsInvalidPrefix(service_name.c_str(), - service_name.size())) { + if (!ProgramManager::HasBuiltInPrefix(service_name)) { service_location = glGetUniformLocation(service_id_, service_name.c_str()); } @@ -701,9 +702,9 @@ // A fragment shader can have gl_FragCoord, gl_FrontFacing or gl_PointCoord // built-ins as its input, as well as custom varyings. We are interested in // custom varyings, client is allowed to bind only them. - if (ProgramManager::IsInvalidPrefix(name_buffer.get(), name_length)) - continue; std::string service_name(name_buffer.get(), name_length); + if (ProgramManager::HasBuiltInPrefix(service_name)) + continue; // Unlike when binding uniforms, we expect the driver to give correct // names: "name" for simple variable, "name[0]" for an array. GLsizei query_length = 0; @@ -788,6 +789,55 @@ } } +void Program::UpdateProgramOutputs() { + if (!feature_info().gl_version_info().IsES3Capable() || + feature_info().disable_shader_translator()) + return; + + Shader* fragment_shader = + attached_shaders_[ShaderTypeToIndex(GL_FRAGMENT_SHADER)].get(); + + for (auto const& output_var : fragment_shader->output_variable_list()) { + const std::string& service_name = output_var.mappedName; + // A fragment shader can have gl_FragColor, gl_SecondaryFragColor, etc + // built-ins as its output, as well as custom varyings. We are interested + // only in custom varyings, client is allowed to bind only them. + if (ProgramManager::HasBuiltInPrefix(service_name)) + continue; + + std::string client_name = output_var.name; + if (output_var.arraySize == 0) { + GLint color_name = + glGetFragDataLocation(service_id_, service_name.c_str()); + if (color_name < 0) + continue; + GLint index = 0; + if (feature_info().feature_flags().ext_blend_func_extended) + index = glGetFragDataIndex(service_id_, service_name.c_str()); + if (index < 0) + continue; + program_output_infos_.push_back( + ProgramOutputInfo(color_name, index, client_name)); + } else { + for (size_t ii = 0; ii < output_var.arraySize; ++ii) { + std::string array_spec(std::string("[") + base::IntToString(ii) + "]"); + std::string service_element_name(service_name + array_spec); + GLint color_name = + glGetFragDataLocation(service_id_, service_element_name.c_str()); + if (color_name < 0) + continue; + GLint index = 0; + if (feature_info().feature_flags().ext_blend_func_extended) + index = glGetFragDataIndex(service_id_, service_element_name.c_str()); + if (index < 0) + continue; + program_output_infos_.push_back( + ProgramOutputInfo(color_name, index, client_name + array_spec)); + } + } + } +} + void Program::ExecuteBindAttribLocationCalls() { for (const auto& key_value : bind_attrib_location_map_) { const std::string* mapped_name = GetAttribMappedName(key_value.first); @@ -827,6 +877,96 @@ return true; } +void Program::ExecuteProgramOutputBindCalls() { + if (feature_info().disable_shader_translator()) { + return; + } + + Shader* fragment_shader = + attached_shaders_[ShaderTypeToIndex(GL_FRAGMENT_SHADER)].get(); + DCHECK(fragment_shader && fragment_shader->valid()); + + if (fragment_shader->shader_version() != 100) { + // ES SL 1.00 does not have mechanism for introducing variables that could + // be bound. This means that ES SL 1.00 binding calls would be to + // non-existing variable names. Binding calls are only executed with ES SL + // 3.00 and higher. + for (auto const& output_var : fragment_shader->output_variable_list()) { + size_t count = std::max(output_var.arraySize, 1u); + bool is_array = output_var.arraySize > 0; + + for (size_t jj = 0; jj < count; ++jj) { + std::string name = output_var.name; + std::string array_spec; + if (is_array) { + array_spec = std::string("[") + base::IntToString(jj) + "]"; + name += array_spec; + } + auto it = bind_program_output_location_index_map_.find(name); + if (it == bind_program_output_location_index_map_.end()) + continue; + + std::string mapped_name = output_var.mappedName; + if (is_array) { + mapped_name += array_spec; + } + const auto& binding = it->second; + if (binding.second == 0) { + // Handles the cases where client called glBindFragDataLocation as + // well as glBindFragDataLocationIndexed with index == 0. + glBindFragDataLocation(service_id_, binding.first, + mapped_name.c_str()); + } else { + DCHECK(feature_info().feature_flags().ext_blend_func_extended); + glBindFragDataLocationIndexed(service_id_, binding.first, + binding.second, mapped_name.c_str()); + } + } + } + return; + } + + // Support for EXT_blend_func_extended when used with ES SL 1.00 client + // shader. + + if (feature_info().gl_version_info().is_es || + !feature_info().feature_flags().ext_blend_func_extended) + return; + + // The underlying context does not support EXT_blend_func_extended + // natively, need to emulate it. + + // ES SL 1.00 is the only language which contains GLSL built-ins + // that need to be bound to color indices. If clients use other + // languages, they also bind the output variables themselves. + // Map gl_SecondaryFragColorEXT / gl_SecondaryFragDataEXT of + // EXT_blend_func_extended to real color indexes. + for (auto const& output_var : fragment_shader->output_variable_list()) { + const std::string& name = output_var.mappedName; + if (name == "gl_FragColor") { + DCHECK_EQ(-1, output_var.location); + DCHECK_EQ(0u, output_var.arraySize); + // We leave these unbound by not giving a binding name. The driver will + // bind this. + } else if (name == "gl_FragData") { + DCHECK_EQ(-1, output_var.location); + DCHECK_NE(0u, output_var.arraySize); + // We leave these unbound by not giving a binding name. The driver will + // bind this. + } else if (name == "gl_SecondaryFragColorEXT") { + DCHECK_EQ(-1, output_var.location); + DCHECK_EQ(0u, output_var.arraySize); + glBindFragDataLocationIndexed(service_id_, 0, 1, + "angle_SecondaryFragColor"); + } else if (name == "gl_SecondaryFragDataEXT") { + DCHECK_EQ(-1, output_var.location); + DCHECK_NE(0u, output_var.arraySize); + glBindFragDataLocationIndexed(service_id_, 0, 1, + "angle_SecondaryFragData"); + } + } +} + bool Program::Link(ShaderManager* manager, Program::VaryingsPackingOption varyings_packing_option, const ShaderCacheCallback& shader_callback) { @@ -905,6 +1045,10 @@ set_log_info("glBindFragmentInputLocationCHROMIUM() conflicts"); return false; } + if (DetectProgramOutputLocationBindingConflicts()) { + set_log_info("glBindFragDataLocation() conflicts"); + return false; + } if (DetectBuiltInInvariantConflicts()) { set_log_info("Invariant settings for certain built-in varyings " "have to match"); @@ -925,6 +1069,9 @@ if (!ExecuteTransformFeedbackVaryingsCall()) { return false; } + + ExecuteProgramOutputBindCalls(); + before_time = TimeTicks::Now(); if (cache && gfx::g_driver_gl.ext.b_GL_ARB_get_program_binary) { glProgramParameteri(service_id(), @@ -1148,6 +1295,20 @@ bind_fragment_input_location_map_[name + "[0]"] = location; } +void Program::SetProgramOutputLocationBinding(const std::string& name, + GLuint color_name) { + SetProgramOutputLocationIndexedBinding(name, color_name, 0); +} + +void Program::SetProgramOutputLocationIndexedBinding(const std::string& name, + GLuint color_name, + GLuint index) { + bind_program_output_location_index_map_[name] = + std::make_pair(color_name, index); + bind_program_output_location_index_map_[name + "[0]"] = + std::make_pair(color_name, index); +} + void Program::GetVertexAttribData( const std::string& name, std::string* original_name, GLenum* type) const { DCHECK(original_name); @@ -1541,6 +1702,42 @@ return false; } +bool Program::DetectProgramOutputLocationBindingConflicts() const { + if (feature_info().disable_shader_translator()) { + return false; + } + + Shader* shader = + attached_shaders_[ShaderTypeToIndex(GL_FRAGMENT_SHADER)].get(); + DCHECK(shader && shader->valid()); + + if (shader->shader_version() == 100) + return false; + + std::set<LocationIndexMap::mapped_type> location_binding_used; + for (auto const& output_var : shader->output_variable_list()) { + if (!output_var.staticUse) + continue; + + size_t count = std::max(output_var.arraySize, 1u); + bool is_array = output_var.arraySize > 0; + + for (size_t jj = 0; jj < count; ++jj) { + std::string name = output_var.name; + if (is_array) + name += std::string("[") + base::IntToString(jj) + "]"; + + auto it = bind_program_output_location_index_map_.find(name); + if (it == bind_program_output_location_index_map_.end()) + continue; + auto result = location_binding_used.insert(it->second); + if (!result.second) + return true; + } + } + return false; +} + bool Program::DetectBuiltInInvariantConflicts() const { DCHECK(attached_shaders_[0].get() && attached_shaders_[0]->shader_type() == GL_VERTEX_SHADER && @@ -2019,6 +2216,36 @@ return true; } +const Program::ProgramOutputInfo* Program::GetProgramOutputInfo( + const std::string& name) const { + for (const auto& info : program_output_infos_) { + if (info.name == name) { + return &info; + } + } + return nullptr; +} + +GLint Program::GetFragDataLocation(const std::string& original_name) const { + DCHECK(IsValid()); + const ProgramOutputInfo* info = GetProgramOutputInfo(original_name); + if (!info) + info = GetProgramOutputInfo(original_name + "[0]"); + if (!info) + return -1; + return info->color_name; +} + +GLint Program::GetFragDataIndex(const std::string& original_name) const { + DCHECK(IsValid()); + const ProgramOutputInfo* info = GetProgramOutputInfo(original_name); + if (!info) + info = GetProgramOutputInfo(original_name + "[0]"); + if (!info) + return -1; + return info->index; +} + void Program::TransformFeedbackVaryings(GLsizei count, const char* const* varyings, GLenum buffer_mode) { @@ -2041,11 +2268,13 @@ ProgramManager::ProgramManager(ProgramCache* program_cache, uint32 max_varying_vectors, + uint32 max_dual_source_draw_buffers, FeatureInfo* feature_info) : program_count_(0), have_context_(true), program_cache_(program_cache), max_varying_vectors_(max_varying_vectors), + max_dual_source_draw_buffers_(max_dual_source_draw_buffers), feature_info_(feature_info) {} ProgramManager::~ProgramManager() {
diff --git a/gpu/command_buffer/service/program_manager.h b/gpu/command_buffer/service/program_manager.h index 942659d..eb3be7c3 100644 --- a/gpu/command_buffer/service/program_manager.h +++ b/gpu/command_buffer/service/program_manager.h
@@ -20,6 +20,7 @@ namespace gpu { namespace gles2 { +class FeatureInfo; class ProgramCache; class ProgramManager; class Shader; @@ -69,6 +70,16 @@ GLenum type; GLuint location; }; + struct ProgramOutputInfo { + ProgramOutputInfo(GLuint _color_name, + GLuint _index, + const std::string& _name) + : color_name(_color_name), index(_index), name(_name) {} + ProgramOutputInfo() : color_name(0), index(0) {} + GLuint color_name; + GLuint index; + std::string name; + }; struct UniformInfo { UniformInfo(); @@ -144,8 +155,10 @@ typedef std::vector<FragmentInputInfo> FragmentInputInfoVector; typedef std::vector<ShaderVariableLocationEntry<FragmentInputInfo>> FragmentInputLocationVector; + typedef std::vector<ProgramOutputInfo> ProgramOutputInfoVector; typedef std::vector<int> SamplerIndices; typedef std::map<std::string, GLint> LocationMap; + typedef std::map<std::string, std::pair<GLuint, GLuint>> LocationIndexMap; typedef std::vector<std::string> StringVector; Program(ProgramManager* manager, GLuint service_id); @@ -209,6 +222,10 @@ // -1 for bound, non-existing uniform. bool IsInactiveUniformLocationByFakeLocation(GLint fake_location) const; + // Gets the ProgramOutputInfo of a fragment output by name. + const ProgramOutputInfo* GetProgramOutputInfo( + const std::string& original_name) const; + // Gets all the program info. void GetProgramInfo( ProgramManager* manager, CommonDecoder::Bucket* bucket) const; @@ -226,6 +243,14 @@ // glGetProgramInfoCHROMIUM. bool GetUniformsES3(CommonDecoder::Bucket* bucket) const; + // Returns the fragment shader output variable color name binding. + // Returns -1 if |original_name| is not an out variable or error. + GLint GetFragDataLocation(const std::string& original_name) const; + + // Returns the fragment shader output variable color index binding. + // Returns -1 if |original_name| is not an out variable or error. + GLint GetFragDataIndex(const std::string& original_name) const; + // Sets the sampler values for a uniform. // This is safe to call for any location. If the location is not // a sampler uniform nothing will happen. @@ -285,6 +310,15 @@ // glBindFragmentInputLocationCHROMIUM() call. void SetFragmentInputLocationBinding(const std::string& name, GLint location); + // Sets program output variable location. Also sets color index to zero. + void SetProgramOutputLocationBinding(const std::string& name, + GLuint colorName); + + // Sets program output variable location and color index. + void SetProgramOutputLocationIndexedBinding(const std::string& name, + GLuint colorName, + GLuint index); + // Detects if there are attribute location conflicts from // glBindAttribLocation() calls. // We only consider the declared attributes in the program. @@ -310,6 +344,11 @@ // We only consider the statically used fragment inputs in the program. bool DetectFragmentInputLocationBindingConflicts() const; + // Detects if there are program output location conflicts from + // glBindFragDataLocation and ..LocationIndexedEXT calls. + // We only consider the statically used program outputs in the program. + bool DetectProgramOutputLocationBindingConflicts() const; + // Return true if any built-in invariant matching rules are broken as in // GLSL ES spec 1.00.17, section 4.6.4, Invariance and Linkage. bool DetectBuiltInInvariantConflicts() const; @@ -372,6 +411,7 @@ void Update(); void UpdateUniforms(); void UpdateFragmentInputs(); + void UpdateProgramOutputs(); // Process the program log, replacing the hashed names with original names. std::string ProcessLogInfo(const std::string& log); @@ -405,6 +445,8 @@ // Returns false upon failure. bool ExecuteTransformFeedbackVaryingsCall(); + void ExecuteProgramOutputBindCalls(); + // Query VertexAttrib data returned by ANGLE translator by the mapped name. void GetVertexAttribData( const std::string& name, std::string* original_name, GLenum* type) const; @@ -447,6 +489,8 @@ FragmentInputInfoVector fragment_input_infos_; FragmentInputLocationVector fragment_input_locations_; + ProgramOutputInfoVector program_output_infos_; + // The program this Program is tracking. GLuint service_id_; @@ -482,6 +526,10 @@ // Fragment input-location binding map from // glBindFragmentInputLocationCHROMIUM() calls. LocationMap bind_fragment_input_location_map_; + + // output variable - (location,index) binding map from + // glBindFragDataLocation() and ..IndexedEXT() calls. + LocationIndexMap bind_program_output_location_index_map_; }; // Tracks the Programs. @@ -492,6 +540,7 @@ public: explicit ProgramManager(ProgramCache* program_cache, uint32 max_varying_vectors, + uint32 max_dual_source_draw_buffers, FeatureInfo* feature_info); ~ProgramManager(); @@ -522,8 +571,9 @@ // Clears the uniforms for this program. void ClearUniforms(Program* program); - // Returns true if prefix is invalid for gl. - static bool IsInvalidPrefix(const char* name, size_t length); + // Returns true if |name| has a prefix that is intended for GL built-in shader + // variables. + static bool HasBuiltInPrefix(const std::string& name); // Check if a Program is owned by this ProgramManager. bool IsOwned(Program* program) const; @@ -534,6 +584,10 @@ return max_varying_vectors_; } + uint32 max_dual_source_draw_buffers() const { + return max_dual_source_draw_buffers_; + } + private: friend class Program; @@ -560,6 +614,7 @@ ProgramCache* program_cache_; uint32 max_varying_vectors_; + uint32 max_dual_source_draw_buffers_; scoped_refptr<FeatureInfo> feature_info_;
diff --git a/gpu/command_buffer/service/program_manager_unittest.cc b/gpu/command_buffer/service/program_manager_unittest.cc index 404017f..8343e56e 100644 --- a/gpu/command_buffer/service/program_manager_unittest.cc +++ b/gpu/command_buffer/service/program_manager_unittest.cc
@@ -21,6 +21,7 @@ #include "gpu/command_buffer/service/test_helper.h" #include "testing/gtest/include/gtest/gtest.h" #include "ui/gl/gl_mock.h" +#include "ui/gl/gl_version_info.h" using ::testing::_; using ::testing::DoAll; @@ -38,6 +39,8 @@ namespace { const uint32 kMaxVaryingVectors = 8; +const uint32 kMaxDrawBuffers = 8; +const uint32 kMaxDualSourceDrawBuffers = 8; void ShaderCacheCb(const std::string& key, const std::string& shader) {} @@ -51,8 +54,9 @@ class ProgramManagerTestBase : public GpuServiceTest { protected: virtual void SetupProgramManager() { - manager_.reset( - new ProgramManager(NULL, kMaxVaryingVectors, feature_info_.get())); + manager_.reset(new ProgramManager(nullptr, kMaxVaryingVectors, + kMaxDualSourceDrawBuffers, + feature_info_.get())); } void SetUpBase(const char* gl_version, const char* gl_extensions, @@ -215,6 +219,13 @@ static const GLint kInvalidUniformLocation = 30; static const GLint kBadUniformIndex = 1000; + static const char* kOutputVariable1Name; + static const GLint kOutputVariable1Size = 1; + static const GLenum kOutputVariable1Precision = GL_MEDIUM_FLOAT; + static const bool kOutputVariable1StaticUse = true; + static const GLint kOutputVariable1Location = -1; + static const GLenum kOutputVariable1Type = GL_FLOAT_VEC4; + static const size_t kNumAttribs; static const size_t kNumUniforms; @@ -225,7 +236,8 @@ typedef enum { kVarUniform, kVarVarying, - kVarAttribute + kVarAttribute, + kVarOutput, } VarCategory; typedef struct { @@ -299,14 +311,16 @@ return (static_cast<bool>(link_status) == expected_link_status); } - Program* SetupShaderVariableTest(const VarInfo* vertex_variables, - size_t vertex_variable_size, - const VarInfo* fragment_variables, - size_t fragment_variable_size) { + Program* SetupProgramForVariables(const VarInfo* vertex_variables, + size_t vertex_variable_size, + const VarInfo* fragment_variables, + size_t fragment_variable_size, + const int* const shader_version = nullptr) { // Set up shader AttributeMap vertex_attrib_map; UniformMap vertex_uniform_map; VaryingMap vertex_varying_map; + OutputVariableList vertex_output_variable_list; for (size_t ii = 0; ii < vertex_variable_size; ++ii) { switch (vertex_variables[ii].category) { case kVarAttribute: @@ -336,6 +350,13 @@ vertex_variables[ii].static_use, vertex_variables[ii].name); break; + case kVarOutput: + vertex_output_variable_list.push_back( + TestHelper::ConstructOutputVariable( + vertex_variables[ii].type, vertex_variables[ii].size, + vertex_variables[ii].precision, + vertex_variables[ii].static_use, vertex_variables[ii].name)); + break; default: NOTREACHED(); } @@ -344,6 +365,7 @@ AttributeMap frag_attrib_map; UniformMap frag_uniform_map; VaryingMap frag_varying_map; + OutputVariableList frag_output_variable_list; for (size_t ii = 0; ii < fragment_variable_size; ++ii) { switch (fragment_variables[ii].category) { case kVarAttribute: @@ -373,6 +395,14 @@ fragment_variables[ii].static_use, fragment_variables[ii].name); break; + case kVarOutput: + frag_output_variable_list.push_back( + TestHelper::ConstructOutputVariable( + fragment_variables[ii].type, fragment_variables[ii].size, + fragment_variables[ii].precision, + fragment_variables[ii].static_use, + fragment_variables[ii].name)); + break; default: NOTREACHED(); } @@ -386,12 +416,14 @@ // Check shader got created. EXPECT_TRUE(vshader != NULL && fshader != NULL); // Set Status - TestHelper::SetShaderStates( - gl_.get(), vshader, true, NULL, NULL, NULL, &vertex_attrib_map, - &vertex_uniform_map, &vertex_varying_map, NULL, NULL); - TestHelper::SetShaderStates( - gl_.get(), fshader, true, NULL, NULL, NULL, - &frag_attrib_map, &frag_uniform_map, &frag_varying_map, NULL, NULL); + TestHelper::SetShaderStates(gl_.get(), vshader, true, nullptr, nullptr, + shader_version, &vertex_attrib_map, + &vertex_uniform_map, &vertex_varying_map, + nullptr, &vertex_output_variable_list, nullptr); + TestHelper::SetShaderStates(gl_.get(), fshader, true, nullptr, nullptr, + shader_version, &frag_attrib_map, + &frag_uniform_map, &frag_varying_map, nullptr, + &frag_output_variable_list, nullptr); // Set up program Program* program = @@ -502,6 +534,7 @@ const char* ProgramManagerWithShaderTest::kUniform3Name = "uniform3"; const char* ProgramManagerWithShaderTest::kUniform3NameWithArrayIndex = "uniform3[0]"; +const char* ProgramManagerWithShaderTest::kOutputVariable1Name = "outputVar1"; TEST_F(ProgramManagerWithShaderTest, GetAttribInfos) { const Program* program = SetupDefaultProgram(); @@ -805,6 +838,7 @@ AttributeMap attrib_map; UniformMap uniform_map; VaryingMap varying_map; + OutputVariableList output_variable_list; attrib_map[kAttrib1Name] = TestHelper::ConstructAttribute( kAttrib1Type, kAttrib1Size, kAttrib1Precision, kAttribStaticUse, kAttrib1Name); @@ -823,18 +857,22 @@ uniform_map[kUniform3Name] = TestHelper::ConstructUniform( kUniform3Type, kUniform3Size, kUniform3Precision, kUniform3StaticUse, kUniform3Name); + output_variable_list.push_back(TestHelper::ConstructOutputVariable( + kOutputVariable1Type, kOutputVariable1Size, kOutputVariable1Precision, + kOutputVariable1StaticUse, kOutputVariable1Name)); + Shader* vshader = shader_manager_.CreateShader( kVertexShaderClientId, kVertexShaderServiceId, GL_VERTEX_SHADER); ASSERT_TRUE(vshader != NULL); - TestHelper::SetShaderStates( - gl_.get(), vshader, true, NULL, NULL, NULL, - &attrib_map, &uniform_map, &varying_map, NULL, NULL); + TestHelper::SetShaderStates(gl_.get(), vshader, true, nullptr, nullptr, + nullptr, &attrib_map, &uniform_map, &varying_map, + nullptr, &output_variable_list, nullptr); Shader* fshader = shader_manager_.CreateShader( kFragmentShaderClientId, kFragmentShaderServiceId, GL_FRAGMENT_SHADER); ASSERT_TRUE(fshader != NULL); - TestHelper::SetShaderStates( - gl_.get(), fshader, true, NULL, NULL, NULL, - &attrib_map, &uniform_map, &varying_map, NULL, NULL); + TestHelper::SetShaderStates(gl_.get(), fshader, true, nullptr, nullptr, + nullptr, &attrib_map, &uniform_map, &varying_map, + nullptr, &output_variable_list, nullptr); static ProgramManagerWithShaderTest::AttribInfo kAttribs[] = { { kAttrib1Name, kAttrib1Size, kAttrib1Type, kAttrib1Location, }, { kAttrib2Name, kAttrib2Size, kAttrib2BadType, kAttrib2Location, }, @@ -1497,9 +1535,9 @@ // Check shader got created. ASSERT_TRUE(vshader != NULL && fshader != NULL); // Set Status - TestHelper::SetShaderStates( - gl_.get(), vshader, true, NULL, NULL, NULL, &attrib_map, NULL, NULL, - NULL, NULL); + TestHelper::SetShaderStates(gl_.get(), vshader, true, nullptr, nullptr, + nullptr, &attrib_map, nullptr, nullptr, nullptr, + nullptr, nullptr); // Check attrib infos got copied. for (AttributeMap::const_iterator it = attrib_map.begin(); it != attrib_map.end(); ++it) { @@ -1512,10 +1550,9 @@ EXPECT_EQ(it->second.staticUse, variable_info->staticUse); EXPECT_EQ(it->second.name, variable_info->name); } - TestHelper::SetShaderStates( - gl_.get(), fshader, true, NULL, NULL, NULL, &attrib_map, NULL, NULL, - NULL, NULL); - + TestHelper::SetShaderStates(gl_.get(), fshader, true, nullptr, nullptr, + nullptr, &attrib_map, nullptr, nullptr, nullptr, + nullptr, nullptr); // Set up program Program* program = manager_->CreateProgram(kClientProgramId, kServiceProgramId); @@ -1581,13 +1618,12 @@ // Check shader got created. ASSERT_TRUE(vshader != NULL && fshader != NULL); // Set Status - TestHelper::SetShaderStates( - gl_.get(), vshader, true, NULL, NULL, NULL, NULL, - &vertex_uniform_map, NULL, NULL, NULL); - TestHelper::SetShaderStates( - gl_.get(), fshader, true, NULL, NULL, NULL, NULL, - &frag_uniform_map, NULL, NULL, NULL); - + TestHelper::SetShaderStates(gl_.get(), vshader, true, nullptr, nullptr, + nullptr, nullptr, &vertex_uniform_map, nullptr, + nullptr, nullptr, nullptr); + TestHelper::SetShaderStates(gl_.get(), fshader, true, nullptr, nullptr, + nullptr, nullptr, &frag_uniform_map, nullptr, + nullptr, nullptr, nullptr); // Set up program Program* program = manager_->CreateProgram(kClientProgramId, kServiceProgramId); @@ -1609,8 +1645,8 @@ { GL_FLOAT_VEC3, 1, GL_MEDIUM_FLOAT, true, "a", kVarVarying }; const VarInfo kFragmentVarying = { GL_FLOAT_VEC4, 1, GL_MEDIUM_FLOAT, true, "a", kVarVarying }; - Program* program = SetupShaderVariableTest( - &kVertexVarying, 1, &kFragmentVarying, 1); + Program* program = + SetupProgramForVariables(&kVertexVarying, 1, &kFragmentVarying, 1); std::string conflicting_name; @@ -1626,8 +1662,8 @@ { GL_FLOAT, 2, GL_MEDIUM_FLOAT, true, "a", kVarVarying }; const VarInfo kFragmentVarying = { GL_FLOAT, 3, GL_MEDIUM_FLOAT, true, "a", kVarVarying }; - Program* program = SetupShaderVariableTest( - &kVertexVarying, 1, &kFragmentVarying, 1); + Program* program = + SetupProgramForVariables(&kVertexVarying, 1, &kFragmentVarying, 1); std::string conflicting_name; @@ -1643,8 +1679,8 @@ { GL_FLOAT, 2, GL_HIGH_FLOAT, true, "a", kVarVarying }; const VarInfo kFragmentVarying = { GL_FLOAT, 2, GL_MEDIUM_FLOAT, true, "a", kVarVarying }; - Program* program = SetupShaderVariableTest( - &kVertexVarying, 1, &kFragmentVarying, 1); + Program* program = + SetupProgramForVariables(&kVertexVarying, 1, &kFragmentVarying, 1); std::string conflicting_name; @@ -1658,8 +1694,7 @@ TEST_F(ProgramManagerWithShaderTest, VaryingMissing) { const VarInfo kFragmentVarying = { GL_FLOAT, 3, GL_MEDIUM_FLOAT, true, "a", kVarVarying }; - Program* program = SetupShaderVariableTest( - NULL, 0, &kFragmentVarying, 1); + Program* program = SetupProgramForVariables(nullptr, 0, &kFragmentVarying, 1); std::string conflicting_name; @@ -1674,8 +1709,7 @@ TEST_F(ProgramManagerWithShaderTest, InactiveVarying) { const VarInfo kFragmentVarying = { GL_FLOAT, 3, GL_MEDIUM_FLOAT, false, "a", kVarVarying }; - Program* program = SetupShaderVariableTest( - NULL, 0, &kFragmentVarying, 1); + Program* program = SetupProgramForVariables(nullptr, 0, &kFragmentVarying, 1); std::string conflicting_name; @@ -1692,8 +1726,8 @@ { GL_FLOAT_VEC4, 1, GL_MEDIUM_FLOAT, true, "a", kVarAttribute }; const VarInfo kFragmentUniform = { GL_FLOAT_VEC4, 1, GL_MEDIUM_FLOAT, true, "a", kVarUniform }; - Program* program = SetupShaderVariableTest( - &kVertexAttribute, 1, &kFragmentUniform, 1); + Program* program = + SetupProgramForVariables(&kVertexAttribute, 1, &kFragmentUniform, 1); std::string conflicting_name; @@ -1712,8 +1746,8 @@ { GL_FLOAT_VEC4, 4, GL_MEDIUM_FLOAT, true, "a", kVarVarying }, { GL_FLOAT_VEC4, 5, GL_MEDIUM_FLOAT, true, "b", kVarVarying } }; - Program* program = SetupShaderVariableTest( - kVertexVaryings, 2, kFragmentVaryings, 2); + Program* program = + SetupProgramForVariables(kVertexVaryings, 2, kFragmentVaryings, 2); EXPECT_FALSE( program->CheckVaryingsPacking(Program::kCountOnlyStaticallyUsed)); @@ -1730,8 +1764,8 @@ { GL_FLOAT_VEC4, 4, GL_MEDIUM_FLOAT, false, "a", kVarVarying }, { GL_FLOAT_VEC4, 5, GL_MEDIUM_FLOAT, true, "b", kVarVarying } }; - Program* program = SetupShaderVariableTest( - kVertexVaryings, 2, kFragmentVaryings, 2); + Program* program = + SetupProgramForVariables(kVertexVaryings, 2, kFragmentVaryings, 2); EXPECT_TRUE( program->CheckVaryingsPacking(Program::kCountOnlyStaticallyUsed)); @@ -1749,8 +1783,8 @@ { GL_FLOAT_VEC4, 4, GL_MEDIUM_FLOAT, false, "a", kVarVarying }, { GL_FLOAT_VEC4, 5, GL_MEDIUM_FLOAT, true, "b", kVarVarying } }; - Program* program = SetupShaderVariableTest( - kVertexVaryings, 2, kFragmentVaryings, 2); + Program* program = + SetupProgramForVariables(kVertexVaryings, 2, kFragmentVaryings, 2); EXPECT_FALSE(program->CheckVaryingsPacking(Program::kCountAll)); } @@ -1910,6 +1944,7 @@ protected: void SetupProgramManager() override { manager_.reset(new ProgramManager(cache_.get(), kMaxVaryingVectors, + kMaxDualSourceDrawBuffers, feature_info_.get())); } @@ -1931,10 +1966,12 @@ program_->AttachShader(&shader_manager_, vertex_shader_); program_->AttachShader(&shader_manager_, fragment_shader_); } + void TearDown() override { shader_manager_.Destroy(false); ProgramManagerTestBase::TearDown(); } + void SetShadersCompiled() { TestHelper::SetShaderStates(gl_.get(), vertex_shader_, true); TestHelper::SetShaderStates(gl_.get(), fragment_shader_, true); @@ -2019,9 +2056,9 @@ } void SetExpectationsForProgramLoadSuccess(GLuint service_program_id) { - TestHelper::SetupProgramSuccessExpectations(gl_.get(), feature_info_.get(), - nullptr, 0, nullptr, 0, nullptr, - 0, service_program_id); + TestHelper::SetupProgramSuccessExpectations( + gl_.get(), feature_info_.get(), nullptr, 0, nullptr, 0, nullptr, 0, + nullptr, 0, service_program_id); } void SetExpectationsForProgramLink() { @@ -2177,7 +2214,6 @@ const char* ProgramManagerWithPathRenderingTest::kFragmentInput2Name = "color2"; const char* ProgramManagerWithPathRenderingTest::kFragmentInput2GLName = "color2[0]"; - const char* ProgramManagerWithPathRenderingTest::kFragmentInput3Name = "color3"; const char* ProgramManagerWithPathRenderingTest::kFragmentInput3GLName = "color3[0]"; @@ -2205,10 +2241,10 @@ kFragmentInput3StaticUse, kFragmentInput3Name); TestHelper::SetShaderStates(gl_.get(), vshader, true, nullptr, nullptr, nullptr, nullptr, nullptr, &varying_map, nullptr, - nullptr); + nullptr, nullptr); TestHelper::SetShaderStates(gl_.get(), fshader, true, nullptr, nullptr, nullptr, nullptr, nullptr, &varying_map, nullptr, - nullptr); + nullptr, nullptr); Program* program = manager_->CreateProgram(kClientProgramId, kServiceProgramId); ASSERT_TRUE(program != NULL); @@ -2238,7 +2274,7 @@ TestHelper::SetupShaderExpectationsWithVaryings( gl_.get(), feature_info_.get(), nullptr, 0, nullptr, 0, kFragmentInputExpectationInfos, arraysize(kFragmentInputExpectationInfos), - kServiceProgramId); + nullptr, 0, kServiceProgramId); program->Link(NULL, Program::kCountOnlyStaticallyUsed, base::Bind(&ShaderCacheCb)); const Program::FragmentInputInfo* info1 = @@ -2273,5 +2309,90 @@ make_gl_ext_tuple("4.5", "GL_NV_path_rendering"), make_gl_ext_tuple("opengl es 3.1", "GL_NV_path_rendering"))); +class ProgramManagerDualSourceBlendingTest + : public ProgramManagerWithShaderTest, + public testing::WithParamInterface< + testing::tuple<const char*, const char*>> { + public: + ProgramManagerDualSourceBlendingTest() {} + + protected: + void SetUpWithFeatureInfo(FeatureInfo* feature_info) { + const char* gl_version = testing::get<0>(GetParam()); + const char* gl_extensions = testing::get<1>(GetParam()); + SetUpBase(gl_version, gl_extensions, feature_info); + } + + void SetUp() override { SetUpWithFeatureInfo(nullptr); } +}; + +class ProgramManagerDualSourceBlendingES2Test + : public ProgramManagerDualSourceBlendingTest {}; + +TEST_P(ProgramManagerDualSourceBlendingES2Test, UseSecondaryFragCoord) { + DCHECK(feature_info_->feature_flags().ext_blend_func_extended); + + const VarInfo kFragmentVaryings[] = { + {GL_FLOAT_VEC4, 0, GL_MEDIUM_FLOAT, true, "gl_SecondaryFragColorEXT", + kVarOutput}, + {GL_FLOAT_VEC4, 0, GL_MEDIUM_FLOAT, true, "gl_FragColor", kVarOutput}, + }; + + int shader_version = 100; + Program* program = + SetupProgramForVariables(nullptr, 0, kFragmentVaryings, + arraysize(kFragmentVaryings), &shader_version); + + const gfx::GLVersionInfo& gl_version = feature_info_->gl_version_info(); + if (!gl_version.is_es) { + // The call is expected only for OpenGL. OpenGL ES expects to + // output GLES SL 1.00, which does not bind. + EXPECT_CALL(*(gl_.get()), + BindFragDataLocationIndexed(kServiceProgramId, 0, 1, + StrEq("angle_SecondaryFragColor"))) + .Times(1) + .RetiresOnSaturation(); + } + + EXPECT_TRUE(LinkAsExpected(program, true)); +} + +TEST_P(ProgramManagerDualSourceBlendingES2Test, UseSecondaryFragData) { + const VarInfo kFragmentVaryings[] = { + {GL_FLOAT_VEC4, kMaxDualSourceDrawBuffers, GL_MEDIUM_FLOAT, true, + "gl_SecondaryFragDataEXT", kVarOutput}, + {GL_FLOAT_VEC4, kMaxDrawBuffers, GL_MEDIUM_FLOAT, true, "gl_FragData", + kVarOutput}, + }; + + int shader_version = 100; + Program* program = + SetupProgramForVariables(nullptr, 0, kFragmentVaryings, + arraysize(kFragmentVaryings), &shader_version); + + const gfx::GLVersionInfo& gl_version = feature_info_->gl_version_info(); + if (!gl_version.is_es) { + // The call is expected only for OpenGL. OpenGL ES expects to + // output GLES SL 1.00, which does not bind. + EXPECT_CALL(*(gl_.get()), + BindFragDataLocationIndexed(kServiceProgramId, 0, 1, + StrEq("angle_SecondaryFragData"))) + .Times(1) + .RetiresOnSaturation(); + } + + EXPECT_TRUE(LinkAsExpected(program, true)); +} + +INSTANTIATE_TEST_CASE_P( + SupportedContexts, + ProgramManagerDualSourceBlendingES2Test, + testing::Values( + make_gl_ext_tuple("3.2", + "GL_ARB_draw_buffers GL_ARB_blend_func_extended " + "GL_ARB_program_interface_query"), + make_gl_ext_tuple("opengl es 3.1", + "GL_EXT_draw_buffers GL_EXT_blend_func_extended"))); + } // namespace gles2 } // namespace gpu
diff --git a/gpu/command_buffer/service/shader_manager.cc b/gpu/command_buffer/service/shader_manager.cc index 342a476..22df5f7 100644 --- a/gpu/command_buffer/service/shader_manager.cc +++ b/gpu/command_buffer/service/shader_manager.cc
@@ -69,15 +69,10 @@ const char* source_for_driver = last_compiled_source_.c_str(); ShaderTranslatorInterface* translator = translator_.get(); if (translator) { - bool success = translator->Translate(last_compiled_source_, - &log_info_, - &translated_source_, - &shader_version_, - &attrib_map_, - &uniform_map_, - &varying_map_, - &interface_block_map_, - &name_map_); + bool success = translator->Translate( + last_compiled_source_, &log_info_, &translated_source_, + &shader_version_, &attrib_map_, &uniform_map_, &varying_map_, + &interface_block_map_, &output_variable_list_, &name_map_); if (!success) { return; } @@ -215,6 +210,15 @@ return NULL; } +const std::string* Shader::GetOutputVariableMappedName( + const std::string& original_name) const { + for (const auto& value : output_variable_list_) { + if (value.name == original_name) + return &value.mappedName; + } + return nullptr; +} + const std::string* Shader::GetOriginalNameFromHashedName( const std::string& hashed_name) const { NameMap::const_iterator it = name_map_.find(hashed_name); @@ -249,6 +253,18 @@ return it != interface_block_map_.end() ? &it->second : NULL; } +const sh::OutputVariable* Shader::GetOutputVariableInfo( + const std::string& name) const { + std::string mapped_name = GetTopVariableName(name); + // Number of output variables is expected to be so low that + // a linear search of a list should be faster than using a map. + for (const auto& value : output_variable_list_) { + if (value.mappedName == mapped_name) + return &value; + } + return nullptr; +} + ShaderManager::ShaderManager() {} ShaderManager::~ShaderManager() {
diff --git a/gpu/command_buffer/service/shader_manager.h b/gpu/command_buffer/service/shader_manager.h index 3288bff..1869371 100644 --- a/gpu/command_buffer/service/shader_manager.h +++ b/gpu/command_buffer/service/shader_manager.h
@@ -88,6 +88,8 @@ const sh::Varying* GetVaryingInfo(const std::string& name) const; const sh::InterfaceBlock* GetInterfaceBlockInfo( const std::string& name) const; + const sh::OutputVariable* GetOutputVariableInfo( + const std::string& name) const; // If the original_name is not found, return NULL. const std::string* GetAttribMappedName( @@ -105,6 +107,10 @@ const std::string* GetInterfaceBlockMappedName( const std::string& original_name) const; + // If the original_name is not found, return NULL. + const std::string* GetOutputVariableMappedName( + const std::string& original_name) const; + // If the hashed_name is not found, return NULL. const std::string* GetOriginalNameFromHashedName( const std::string& hashed_name) const; @@ -144,6 +150,10 @@ return varying_map_; } + const OutputVariableList& output_variable_list() const { + return output_variable_list_; + } + // Used by program cache. const InterfaceBlockMap& interface_block_map() const { return interface_block_map_; @@ -177,6 +187,12 @@ uniform_map_[uniform.mappedName] = uniform; } + void set_output_variable_list( + const OutputVariableList& output_variable_list) { + // copied because cache might be cleared + output_variable_list_ = output_variable_list; + } + private: friend class base::RefCounted<Shader>; friend class ShaderManager; @@ -237,6 +253,7 @@ UniformMap uniform_map_; VaryingMap varying_map_; InterfaceBlockMap interface_block_map_; + OutputVariableList output_variable_list_; // The name hashing info when the shader was last compiled. NameMap name_map_;
diff --git a/gpu/command_buffer/service/shader_manager_unittest.cc b/gpu/command_buffer/service/shader_manager_unittest.cc index c125cfe6..93471ec10 100644 --- a/gpu/command_buffer/service/shader_manager_unittest.cc +++ b/gpu/command_buffer/service/shader_manager_unittest.cc
@@ -126,6 +126,11 @@ const GLenum kVarying1Precision = GL_HIGH_FLOAT; const bool kVarying1StaticUse = false; const char* kVarying1Name = "varying1"; + const GLenum kOutputVariable1Type = GL_FLOAT_VEC4; + const GLint kOutputVariable1Size = 4; + const GLenum kOutputVariable1Precision = GL_MEDIUM_FLOAT; + const char* kOutputVariable1Name = "gl_FragColor"; + const bool kOutputVariable1StaticUse = true; // Check we can create shader. Shader* shader1 = manager_.CreateShader( @@ -187,10 +192,13 @@ varying_map[kVarying1Name] = TestHelper::ConstructVarying( kVarying1Type, kVarying1Size, kVarying1Precision, kVarying1StaticUse, kVarying1Name); - + OutputVariableList output_variable_list; + output_variable_list.push_back(TestHelper::ConstructOutputVariable( + kOutputVariable1Type, kOutputVariable1Size, kOutputVariable1Precision, + kOutputVariable1StaticUse, kOutputVariable1Name)); TestHelper::SetShaderStates( - gl_.get(), shader1, true, &kLog, &kTranslatedSource, NULL, - &attrib_map, &uniform_map, &varying_map, NULL, NULL); + gl_.get(), shader1, true, &kLog, &kTranslatedSource, nullptr, &attrib_map, + &uniform_map, &varying_map, nullptr, &output_variable_list, nullptr); EXPECT_TRUE(shader1->valid()); // When compilation succeeds, no log is recorded. EXPECT_STREQ("", shader1->log_info().c_str()); @@ -233,17 +241,33 @@ EXPECT_EQ(it->second.staticUse, variable_info->staticUse); EXPECT_STREQ(it->second.name.c_str(), variable_info->name.c_str()); } + // Check output variable infos got copied. + EXPECT_EQ(output_variable_list.size(), + shader1->output_variable_list().size()); + for (auto it = output_variable_list.begin(); it != output_variable_list.end(); + ++it) { + const sh::OutputVariable* variable_info = + shader1->GetOutputVariableInfo(it->mappedName); + ASSERT_TRUE(variable_info != nullptr); + EXPECT_EQ(it->type, variable_info->type); + EXPECT_EQ(it->arraySize, variable_info->arraySize); + EXPECT_EQ(it->precision, variable_info->precision); + EXPECT_EQ(it->staticUse, variable_info->staticUse); + EXPECT_STREQ(it->name.c_str(), variable_info->name.c_str()); + } // Compile failure case. - TestHelper::SetShaderStates( - gl_.get(), shader1, false, &kLog, &kTranslatedSource, NULL, - &attrib_map, &uniform_map, &varying_map, NULL, NULL); + TestHelper::SetShaderStates(gl_.get(), shader1, false, &kLog, + &kTranslatedSource, nullptr, &attrib_map, + &uniform_map, &varying_map, nullptr, + &output_variable_list, nullptr); EXPECT_FALSE(shader1->valid()); EXPECT_STREQ(kLog.c_str(), shader1->log_info().c_str()); EXPECT_STREQ("", shader1->translated_source().c_str()); EXPECT_TRUE(shader1->attrib_map().empty()); EXPECT_TRUE(shader1->uniform_map().empty()); EXPECT_TRUE(shader1->varying_map().empty()); + EXPECT_TRUE(shader1->output_variable_list().empty()); } TEST_F(ShaderManagerTest, ShaderInfoUseCount) {
diff --git a/gpu/command_buffer/service/shader_translator.cc b/gpu/command_buffer/service/shader_translator.cc index 92c7f9d..255caff 100644 --- a/gpu/command_buffer/service/shader_translator.cc +++ b/gpu/command_buffer/service/shader_translator.cc
@@ -71,6 +71,11 @@ (*var_map)[(*varyings)[ii].mappedName] = (*varyings)[ii]; } } +void GetOutputVariables(ShHandle compiler, OutputVariableList* var_list) { + if (!var_list) + return; + *var_list = *ShGetOutputVariables(compiler); +} void GetInterfaceBlocks(ShHandle compiler, InterfaceBlockMap* var_map) { if (!var_map) @@ -206,6 +211,7 @@ UniformMap* uniform_map, VaryingMap* varying_map, InterfaceBlockMap* interface_block_map, + OutputVariableList* output_variable_list, NameMap* name_map) const { // Make sure this instance is initialized. DCHECK(compiler_ != NULL); @@ -224,11 +230,12 @@ } // Get shader version. *shader_version = ShGetShaderVersion(compiler_); - // Get info for attribs, uniforms, and varyings. + // Get info for attribs, uniforms, varyings and output variables. GetAttributes(compiler_, attrib_map); GetUniforms(compiler_, uniform_map); GetVaryings(compiler_, varying_map); GetInterfaceBlocks(compiler_, interface_block_map); + GetOutputVariables(compiler_, output_variable_list); // Get info for name hashing. GetNameHashingInfo(compiler_, name_map); }
diff --git a/gpu/command_buffer/service/shader_translator.h b/gpu/command_buffer/service/shader_translator.h index 58ba69f..5a4914d9 100644 --- a/gpu/command_buffer/service/shader_translator.h +++ b/gpu/command_buffer/service/shader_translator.h
@@ -24,6 +24,7 @@ // Mapping between variable name and info. typedef base::hash_map<std::string, sh::Attribute> AttributeMap; +typedef std::vector<sh::OutputVariable> OutputVariableList; typedef base::hash_map<std::string, sh::Uniform> UniformMap; typedef base::hash_map<std::string, sh::Varying> VaryingMap; typedef base::hash_map<std::string, sh::InterfaceBlock> InterfaceBlockMap; @@ -58,6 +59,7 @@ UniformMap* uniform_map, VaryingMap* varying_map, InterfaceBlockMap* interface_block_map, + OutputVariableList* output_variable_list, NameMap* name_map) const = 0; // Return a string that is unique for a specfic set of options that would @@ -109,6 +111,7 @@ UniformMap* uniform_map, VaryingMap* varying_map, InterfaceBlockMap* interface_block_map, + OutputVariableList* output_variable_list, NameMap* name_map) const override; std::string GetStringForOptionsThatWouldAffectCompilation() const override;
diff --git a/gpu/command_buffer/service/shader_translator_unittest.cc b/gpu/command_buffer/service/shader_translator_unittest.cc index eff11c1ca..e5b3f6b 100644 --- a/gpu/command_buffer/service/shader_translator_unittest.cc +++ b/gpu/command_buffer/service/shader_translator_unittest.cc
@@ -98,16 +98,13 @@ UniformMap uniform_map; VaryingMap varying_map; InterfaceBlockMap interface_block_map; + OutputVariableList output_variable_list; NameMap name_map; - EXPECT_TRUE(vertex_translator_->Translate(shader, - &info_log, - &translated_source, - &shader_version, - &attrib_map, - &uniform_map, - &varying_map, - &interface_block_map, - &name_map)); + EXPECT_TRUE(vertex_translator_->Translate( + shader, &info_log, &translated_source, &shader_version, &attrib_map, + &uniform_map, &varying_map, &interface_block_map, &output_variable_list, + &name_map)); + // Info log must be NULL. EXPECT_TRUE(info_log.empty()); // Translated shader must be valid and non-empty. @@ -118,6 +115,7 @@ EXPECT_TRUE(uniform_map.empty()); EXPECT_TRUE(interface_block_map.empty()); EXPECT_EQ(1u, varying_map.size()); + EXPECT_TRUE(output_variable_list.empty()); // There should be no name mapping. EXPECT_TRUE(name_map.empty()); } @@ -136,16 +134,12 @@ UniformMap uniform_map; VaryingMap varying_map; InterfaceBlockMap interface_block_map; + OutputVariableList output_variable_list; NameMap name_map; - EXPECT_FALSE(vertex_translator_->Translate(bad_shader, - &info_log, - &translated_source, - &shader_version, - &attrib_map, - &uniform_map, - &varying_map, - &interface_block_map, - &name_map)); + EXPECT_FALSE(vertex_translator_->Translate( + bad_shader, &info_log, &translated_source, &shader_version, &attrib_map, + &uniform_map, &varying_map, &interface_block_map, &output_variable_list, + &name_map)); // Info log must be valid and non-empty. ASSERT_FALSE(info_log.empty()); // Translated shader must be NULL. @@ -156,19 +150,15 @@ EXPECT_TRUE(uniform_map.empty()); EXPECT_TRUE(varying_map.empty()); EXPECT_TRUE(interface_block_map.empty()); + EXPECT_TRUE(output_variable_list.empty()); EXPECT_TRUE(name_map.empty()); // Try a good shader after bad. info_log.clear(); - EXPECT_TRUE(vertex_translator_->Translate(good_shader, - &info_log, - &translated_source, - &shader_version, - &attrib_map, - &uniform_map, - &varying_map, - &interface_block_map, - &name_map)); + EXPECT_TRUE(vertex_translator_->Translate( + good_shader, &info_log, &translated_source, &shader_version, &attrib_map, + &uniform_map, &varying_map, &interface_block_map, &output_variable_list, + &name_map)); EXPECT_TRUE(info_log.empty()); EXPECT_FALSE(translated_source.empty()); EXPECT_TRUE(interface_block_map.empty()); @@ -187,16 +177,12 @@ UniformMap uniform_map; VaryingMap varying_map; InterfaceBlockMap interface_block_map; + OutputVariableList output_variable_list; NameMap name_map; - EXPECT_TRUE(fragment_translator_->Translate(shader, - &info_log, - &translated_source, - &shader_version, - &attrib_map, - &uniform_map, - &varying_map, - &interface_block_map, - &name_map)); + EXPECT_TRUE(fragment_translator_->Translate( + shader, &info_log, &translated_source, &shader_version, &attrib_map, + &uniform_map, &varying_map, &interface_block_map, &output_variable_list, + &name_map)); // Info log must be NULL. EXPECT_TRUE(info_log.empty()); // Translated shader must be valid and non-empty. @@ -208,6 +194,8 @@ EXPECT_TRUE(varying_map.empty()); EXPECT_TRUE(interface_block_map.empty()); EXPECT_TRUE(name_map.empty()); + // gl_FragColor. + EXPECT_EQ(1u, output_variable_list.size()); } TEST_F(ShaderTranslatorTest, InvalidFragmentShader) { @@ -219,17 +207,13 @@ UniformMap uniform_map; VaryingMap varying_map; InterfaceBlockMap interface_block_map; + OutputVariableList output_variable_list; NameMap name_map; // An invalid shader should fail. - EXPECT_FALSE(fragment_translator_->Translate(shader, - &info_log, - &translated_source, - &shader_version, - &attrib_map, - &uniform_map, - &varying_map, - &interface_block_map, - &name_map)); + EXPECT_FALSE(fragment_translator_->Translate( + shader, &info_log, &translated_source, &shader_version, &attrib_map, + &uniform_map, &varying_map, &interface_block_map, &output_variable_list, + &name_map)); // Info log must be valid and non-empty. EXPECT_FALSE(info_log.empty()); // Translated shader must be NULL. @@ -239,6 +223,7 @@ EXPECT_TRUE(attrib_map.empty()); EXPECT_TRUE(uniform_map.empty()); EXPECT_TRUE(varying_map.empty()); + EXPECT_TRUE(output_variable_list.empty()); EXPECT_TRUE(name_map.empty()); } @@ -255,16 +240,12 @@ UniformMap uniform_map; VaryingMap varying_map; InterfaceBlockMap interface_block_map; + OutputVariableList output_variable_list; NameMap name_map; - EXPECT_TRUE(vertex_translator_->Translate(shader, - &info_log, - &translated_source, - &shader_version, - &attrib_map, - &uniform_map, - &varying_map, - &interface_block_map, - &name_map)); + EXPECT_TRUE(vertex_translator_->Translate( + shader, &info_log, &translated_source, &shader_version, &attrib_map, + &uniform_map, &varying_map, &interface_block_map, &output_variable_list, + &name_map)); // Info log must be NULL. EXPECT_TRUE(info_log.empty()); // Translated shader must be valid and non-empty. @@ -303,16 +284,12 @@ UniformMap uniform_map; VaryingMap varying_map; InterfaceBlockMap interface_block_map; + OutputVariableList output_variable_list; NameMap name_map; - EXPECT_TRUE(fragment_translator_->Translate(shader, - &info_log, - &translated_source, - &shader_version, - &attrib_map, - &uniform_map, - &varying_map, - &interface_block_map, - &name_map)); + EXPECT_TRUE(fragment_translator_->Translate( + shader, &info_log, &translated_source, &shader_version, &attrib_map, + &uniform_map, &varying_map, &interface_block_map, &output_variable_list, + &name_map)); // Info log must be NULL. EXPECT_TRUE(info_log.empty()); // Translated shader must be valid and non-empty. @@ -344,6 +321,9 @@ EXPECT_EQ(1u, info->arraySize); EXPECT_STREQ("color", info->name.c_str()); EXPECT_STREQ("bar[1].foo.color[0]", original_name.c_str()); + EXPECT_EQ(1u, output_variable_list.size()); + ASSERT_TRUE(output_variable_list.size() > 0); + EXPECT_EQ(output_variable_list[0].mappedName, "gl_FragColor"); } @@ -372,16 +352,12 @@ UniformMap uniform_map; VaryingMap varying_map; InterfaceBlockMap interface_block_map; + OutputVariableList output_variable_list; NameMap name_map; - EXPECT_FALSE(fragment_translator_->Translate(shader, - &info_log, - &translated_source, - &shader_version, - &attrib_map, - &uniform_map, - &varying_map, - &interface_block_map, - &name_map)); + EXPECT_FALSE(fragment_translator_->Translate( + shader, &info_log, &translated_source, &shader_version, &attrib_map, + &uniform_map, &varying_map, &interface_block_map, &output_variable_list, + &name_map)); // Info log must be valid and non-empty. ASSERT_FALSE(info_log.empty()); // Translated shader must be NULL. @@ -415,16 +391,12 @@ UniformMap uniform_map; VaryingMap varying_map; InterfaceBlockMap interface_block_map; + OutputVariableList output_variable_list; NameMap name_map; - EXPECT_TRUE(fragment_translator_->Translate(shader, - &info_log, - &translated_source, - &shader_version, - &attrib_map, - &uniform_map, - &varying_map, - &interface_block_map, - &name_map)); + EXPECT_TRUE(fragment_translator_->Translate( + shader, &info_log, &translated_source, &shader_version, &attrib_map, + &uniform_map, &varying_map, &interface_block_map, &output_variable_list, + &name_map)); // Info log must be NULL. EXPECT_TRUE(info_log.empty()); // Translated shader must be valid and non-empty. @@ -509,7 +481,7 @@ int shader_version; EXPECT_TRUE(translator->Translate(kShader, nullptr, &translated_source, &shader_version, nullptr, nullptr, nullptr, - nullptr, nullptr)); + nullptr, nullptr, nullptr)); std::string expected_version_directive = testing::get<1>(GetParam()); if (expected_version_directive.empty()) {
diff --git a/gpu/command_buffer/service/test_helper.cc b/gpu/command_buffer/service/test_helper.cc index 2c8fc25..40c285a 100644 --- a/gpu/command_buffer/service/test_helper.cc +++ b/gpu/command_buffer/service/test_helper.cc
@@ -339,6 +339,16 @@ .WillOnce(SetArgumentPointee<1>(kMaxSamples)) .RetiresOnSaturation(); } + + if (gl_info.IsAtLeastGL(3, 3) || + (gl_info.IsAtLeastGL(3, 2) && + strstr(extensions, "GL_ARB_blend_func_extended")) || + (gl_info.is_es && strstr(extensions, "GL_EXT_blend_func_extended"))) { + EXPECT_CALL(*gl, GetIntegerv(GL_MAX_DUAL_SOURCE_DRAW_BUFFERS_EXT, _)) + .WillOnce(SetArgumentPointee<1>(8)) + .RetiresOnSaturation(); + } + EXPECT_CALL(*gl, GetIntegerv(GL_MAX_VERTEX_ATTRIBS, _)) .WillOnce(SetArgumentPointee<1>(kNumVertexAttribs)) .RetiresOnSaturation(); @@ -689,6 +699,8 @@ size_t num_uniforms, VaryingInfo* varyings, size_t num_varyings, + ProgramOutputInfo* program_outputs, + size_t num_program_outputs, GLuint service_id) { EXPECT_CALL(*gl, GetProgramiv(service_id, GL_LINK_STATUS, _)) @@ -724,7 +736,7 @@ SetArrayArgument<6>(info.name, info.name + strlen(info.name) + 1))) .RetiresOnSaturation(); - if (!ProgramManager::IsInvalidPrefix(info.name, strlen(info.name))) { + if (!ProgramManager::HasBuiltInPrefix(info.name)) { EXPECT_CALL(*gl, GetAttribLocation(service_id, StrEq(info.name))) .WillOnce(Return(info.location)) .RetiresOnSaturation(); @@ -799,7 +811,9 @@ SetArrayArgument<5>( info.name, info.name + strlen(info.name) + 1))) .RetiresOnSaturation(); - if (!ProgramManager::IsInvalidPrefix(info.name, strlen(info.name))) { + if (ProgramManager::HasBuiltInPrefix(info.name)) + continue; + static const GLenum kPropsArray[] = {GL_LOCATION, GL_TYPE, GL_ARRAY_SIZE}; static const size_t kPropsSize = arraysize(kPropsArray); @@ -818,6 +832,26 @@ })) .RetiresOnSaturation(); } + } + if (feature_info->gl_version_info().IsES3Capable() && + !feature_info->disable_shader_translator()) { + for (size_t ii = 0; ii < num_program_outputs; ++ii) { + ProgramOutputInfo& info = program_outputs[ii]; + if (ProgramManager::HasBuiltInPrefix(info.name)) + continue; + + EXPECT_CALL(*gl, GetFragDataLocation(service_id, StrEq(info.name))) + .WillOnce(Return(info.color_name)) + .RetiresOnSaturation(); + if (feature_info->feature_flags().ext_blend_func_extended) { + EXPECT_CALL(*gl, GetFragDataIndex(service_id, StrEq(info.name))) + .WillOnce(Return(info.index)) + .RetiresOnSaturation(); + } else { + // Test case must not use indices, or the context of the testcase has to + // support the dual source blending. + DCHECK(info.index == 0); + } } } } @@ -834,8 +868,8 @@ EXPECT_CALL(*gl, LinkProgram(service_id)).Times(1).RetiresOnSaturation(); SetupProgramSuccessExpectations(gl, feature_info, attribs, num_attribs, - uniforms, num_uniforms, nullptr, 0, - service_id); + uniforms, num_uniforms, nullptr, 0, nullptr, + 0, service_id); } void TestHelper::SetupShaderExpectationsWithVaryings( @@ -847,6 +881,8 @@ size_t num_uniforms, VaryingInfo* varyings, size_t num_varyings, + ProgramOutputInfo* program_outputs, + size_t num_program_outputs, GLuint service_id) { InSequence s; @@ -855,9 +891,9 @@ .Times(1) .RetiresOnSaturation(); - SetupProgramSuccessExpectations(gl, feature_info, attribs, num_attribs, - uniforms, num_uniforms, varyings, - num_varyings, service_id); + SetupProgramSuccessExpectations( + gl, feature_info, attribs, num_attribs, uniforms, num_uniforms, varyings, + num_varyings, program_outputs, num_program_outputs, service_id); } void TestHelper::DoBufferData( @@ -905,16 +941,18 @@ // static void TestHelper::SetShaderStates( - ::gfx::MockGLInterface* gl, Shader* shader, - bool expected_valid, - const std::string* const expected_log_info, - const std::string* const expected_translated_source, - const int* const expected_shader_version, - const AttributeMap* const expected_attrib_map, - const UniformMap* const expected_uniform_map, - const VaryingMap* const expected_varying_map, - const InterfaceBlockMap* const expected_interface_block_map, - const NameMap* const expected_name_map) { + ::gfx::MockGLInterface* gl, + Shader* shader, + bool expected_valid, + const std::string* const expected_log_info, + const std::string* const expected_translated_source, + const int* const expected_shader_version, + const AttributeMap* const expected_attrib_map, + const UniformMap* const expected_uniform_map, + const VaryingMap* const expected_varying_map, + const InterfaceBlockMap* const expected_interface_block_map, + const OutputVariableList* const expected_output_variable_list, + const NameMap* const expected_name_map) { const std::string empty_log_info; const std::string* log_info = (expected_log_info && !expected_valid) ? expected_log_info : &empty_log_info; @@ -938,6 +976,11 @@ const InterfaceBlockMap* interface_block_map = (expected_interface_block_map && expected_valid) ? expected_interface_block_map : &empty_interface_block_map; + const OutputVariableList empty_output_variable_list; + const OutputVariableList* output_variable_list = + (expected_output_variable_list && expected_valid) + ? expected_output_variable_list + : &empty_output_variable_list; const NameMap empty_name_map; const NameMap* name_map = (expected_name_map && expected_valid) ? expected_name_map : &empty_name_map; @@ -945,13 +988,14 @@ MockShaderTranslator* mock_translator = new MockShaderTranslator; scoped_refptr<ShaderTranslatorInterface> translator(mock_translator); EXPECT_CALL(*mock_translator, Translate(_, - NotNull(), // log_info - NotNull(), // translated_source - NotNull(), // shader_version - NotNull(), // attrib_map - NotNull(), // uniform_map - NotNull(), // varying_map - NotNull(), // interface_block_map + NotNull(), // log_info + NotNull(), // translated_source + NotNull(), // shader_version + NotNull(), // attrib_map + NotNull(), // uniform_map + NotNull(), // varying_map + NotNull(), // interface_block_map + NotNull(), // output_variable_list NotNull())) // name_map .WillOnce(DoAll(SetArgumentPointee<1>(*log_info), SetArgumentPointee<2>(*translated_source), @@ -960,8 +1004,8 @@ SetArgumentPointee<5>(*uniform_map), SetArgumentPointee<6>(*varying_map), SetArgumentPointee<7>(*interface_block_map), - SetArgumentPointee<8>(*name_map), - Return(expected_valid))) + SetArgumentPointee<8>(*output_variable_list), + SetArgumentPointee<9>(*name_map), Return(expected_valid))) .RetiresOnSaturation(); if (expected_valid) { EXPECT_CALL(*gl, ShaderSource(shader->service_id(), 1, _, NULL)) @@ -983,8 +1027,8 @@ // static void TestHelper::SetShaderStates( ::gfx::MockGLInterface* gl, Shader* shader, bool valid) { - SetShaderStates( - gl, shader, valid, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL); + SetShaderStates(gl, shader, valid, nullptr, nullptr, nullptr, nullptr, + nullptr, nullptr, nullptr, nullptr, nullptr); } // static @@ -1011,6 +1055,16 @@ type, array_size, precision, static_use, name); } +sh::OutputVariable TestHelper::ConstructOutputVariable( + GLenum type, + GLint array_size, + GLenum precision, + bool static_use, + const std::string& name) { + return ConstructShaderVariable<sh::OutputVariable>( + type, array_size, precision, static_use, name); +} + ScopedGLImplementationSetter::ScopedGLImplementationSetter( gfx::GLImplementation implementation) : old_implementation_(gfx::GetGLImplementation()) {
diff --git a/gpu/command_buffer/service/test_helper.h b/gpu/command_buffer/service/test_helper.h index 33c91fb..7072428e 100644 --- a/gpu/command_buffer/service/test_helper.h +++ b/gpu/command_buffer/service/test_helper.h
@@ -82,6 +82,13 @@ GLint real_location; GLint desired_location; }; + struct ProgramOutputInfo { + const char* name; + GLint size; + GLenum type; + GLint color_name; + GLuint index; + }; static void SetupContextGroupInitExpectations( ::gfx::MockGLInterface* gl, @@ -126,17 +133,22 @@ size_t num_uniforms, VaryingInfo* varyings, size_t num_varyings, + ProgramOutputInfo* program_outputs, + size_t num_program_outputs, GLuint service_id); - static void SetupProgramSuccessExpectations(::gfx::MockGLInterface* gl, - const FeatureInfo* feature_info, - AttribInfo* attribs, - size_t num_attribs, - UniformInfo* uniforms, - size_t num_uniforms, - VaryingInfo* varyings, - size_t num_varyings, - GLuint service_id); + static void SetupProgramSuccessExpectations( + ::gfx::MockGLInterface* gl, + const FeatureInfo* feature_info, + AttribInfo* attribs, + size_t num_attribs, + UniformInfo* uniforms, + size_t num_uniforms, + VaryingInfo* varyings, + size_t num_varyings, + ProgramOutputInfo* program_outputs, + size_t num_program_outputs, + GLuint service_id); static void DoBufferData( ::gfx::MockGLInterface* gl, MockErrorState* error_state, @@ -149,7 +161,8 @@ GLenum pname, GLint value, GLenum error); static void SetShaderStates( - ::gfx::MockGLInterface* gl, Shader* shader, + ::gfx::MockGLInterface* gl, + Shader* shader, bool expected_valid, const std::string* const expected_log_info, const std::string* const expected_translated_source, @@ -158,6 +171,7 @@ const UniformMap* const expected_uniform_map, const VaryingMap* const expected_varying_map, const InterfaceBlockMap* const expected_interface_block_map, + const OutputVariableList* const expected_output_variable_list, const NameMap* const expected_name_map); static void SetShaderStates( @@ -172,6 +186,11 @@ static sh::Varying ConstructVarying( GLenum type, GLint array_size, GLenum precision, bool static_use, const std::string& name); + static sh::OutputVariable ConstructOutputVariable(GLenum type, + GLint array_size, + GLenum precision, + bool static_use, + const std::string& name); private: static void SetupTextureInitializationExpectations(::gfx::MockGLInterface* gl,
diff --git a/gpu/command_buffer/tests/gl_ext_blend_func_extended_unittest.cc b/gpu/command_buffer/tests/gl_ext_blend_func_extended_unittest.cc new file mode 100644 index 0000000..d2f01ab --- /dev/null +++ b/gpu/command_buffer/tests/gl_ext_blend_func_extended_unittest.cc
@@ -0,0 +1,653 @@ +// Copyright (c) 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. + +#include <GLES2/gl2.h> +#include <GLES2/gl2ext.h> +#include <GLES2/gl2extchromium.h> +#include <GLES3/gl3.h> + +#include "base/command_line.h" +#include "base/strings/string_number_conversions.h" +#include "gpu/command_buffer/service/gpu_switches.h" +#include "gpu/command_buffer/tests/gl_manager.h" +#include "gpu/command_buffer/tests/gl_test_utils.h" +#include "testing/gmock/include/gmock/gmock.h" +#include "testing/gtest/include/gtest/gtest.h" +#include "ui/gl/gl_switches.h" + +#define SHADER(Src) #Src +#define BFE_SHADER(Src) "#extension GL_EXT_blend_func_extended : require\n" #Src + +namespace { +// Partial implementation of weight function for GLES 2 blend equation that +// is dual-source aware. +template <int factor, int index> +float Weight(float /*dst*/[4], float src[4], float src1[4]) { + if (factor == GL_SRC_COLOR) + return src[index]; + if (factor == GL_SRC_ALPHA) + return src[3]; + if (factor == GL_SRC1_COLOR_EXT) + return src1[index]; + if (factor == GL_SRC1_ALPHA_EXT) + return src1[3]; + if (factor == GL_ONE_MINUS_SRC1_COLOR_EXT) + return 1.0f - src1[index]; + if (factor == GL_ONE_MINUS_SRC1_ALPHA_EXT) + return 1.0f - src1[3]; + return 0.0f; +} + +// Implementation of GLES 2 blend equation that is dual-source aware. +template <int RGBs, int RGBd, int As, int Ad> +void BlendEquationFuncAdd(float dst[4], + float src[4], + float src1[4], + uint8 result[4]) { + float r[4]; + r[0] = src[0] * Weight<RGBs, 0>(dst, src, src1) + + dst[0] * Weight<RGBd, 0>(dst, src, src1); + r[1] = src[1] * Weight<RGBs, 1>(dst, src, src1) + + dst[1] * Weight<RGBd, 1>(dst, src, src1); + r[2] = src[2] * Weight<RGBs, 2>(dst, src, src1) + + dst[2] * Weight<RGBd, 2>(dst, src, src1); + r[3] = src[3] * Weight<As, 3>(dst, src, src1) + + dst[3] * Weight<Ad, 3>(dst, src, src1); + for (int i = 0; i < 4; ++i) { + result[i] = static_cast<uint8>( + std::floor(std::max(0.0f, std::min(1.0f, r[i])) * 255.0f)); + } +} + +} // namespace + +namespace gpu { + +class EXTBlendFuncExtendedTest : public testing::Test { + public: + protected: + void SetUp() override { gl_.Initialize(GLManager::Options()); } + + void TearDown() override { gl_.Destroy(); } + bool IsApplicable() const { + return GLTestHelper::HasExtension("GL_EXT_blend_func_extended"); + } + GLManager gl_; +}; + +TEST_F(EXTBlendFuncExtendedTest, TestMaxDualSourceDrawBuffers) { + if (!IsApplicable()) + return; + + GLint maxDualSourceDrawBuffers = 0; + glGetIntegerv(GL_MAX_DUAL_SOURCE_DRAW_BUFFERS_EXT, &maxDualSourceDrawBuffers); + EXPECT_GT(maxDualSourceDrawBuffers, 0); + EXPECT_EQ(static_cast<GLenum>(GL_NO_ERROR), glGetError()); +} + +class EXTBlendFuncExtendedDrawTest : public testing::TestWithParam<bool> { + public: + static const GLsizei kWidth = 100; + static const GLsizei kHeight = 100; + EXTBlendFuncExtendedDrawTest() : program_(0) {} + + protected: + void SetUp() override { + GLManager::Options options; + options.size = gfx::Size(kWidth, kHeight); + options.force_shader_name_hashing = GetParam(); + base::CommandLine command_line(*base::CommandLine::ForCurrentProcess()); + gl_.InitializeWithCommandLine(options, &command_line); + } + + bool IsApplicable() const { + return GLTestHelper::HasExtension("GL_EXT_blend_func_extended"); + } + + virtual const char* GetVertexShader() { + // clang-format off + static const char* kVertexShader = + SHADER( + attribute vec4 position; + void main() { + gl_Position = position; + }); + // clang-format on + return kVertexShader; + } + + void CreateProgramWithFragmentShader(const char* fragment_shader_str) { + GLuint vertex_shader = + GLTestHelper::LoadShader(GL_VERTEX_SHADER, GetVertexShader()); + GLuint fragment_shader = + GLTestHelper::LoadShader(GL_FRAGMENT_SHADER, fragment_shader_str); + ASSERT_NE(0u, vertex_shader); + ASSERT_NE(0u, fragment_shader); + program_ = glCreateProgram(); + ASSERT_NE(0u, program_); + glAttachShader(program_, vertex_shader); + glAttachShader(program_, fragment_shader); + glDeleteShader(vertex_shader); + glDeleteShader(fragment_shader); + } + + testing::AssertionResult LinkProgram() { + glLinkProgram(program_); + GLint linked = 0; + glGetProgramiv(program_, GL_LINK_STATUS, &linked); + if (linked == 0) { + char buffer[1024]; + GLsizei length = 0; + glGetProgramInfoLog(program_, sizeof(buffer), &length, buffer); + std::string log(buffer, length); + return testing::AssertionFailure() << "Error linking program: " << log; + } + glUseProgram(program_); + position_loc_ = glGetAttribLocation(program_, "position"); + src_loc_ = glGetUniformLocation(program_, "src"); + src1_loc_ = glGetUniformLocation(program_, "src1"); + return testing::AssertionSuccess(); + } + + void TearDown() override { + if (program_ != 0) + glDeleteProgram(program_); + gl_.Destroy(); + } + + void DrawAndVerify() { + float kDst[4] = {0.5f, 0.5f, 0.5f, 0.5f}; + float kSrc[4] = {1.0f, 1.0f, 1.0f, 1.0f}; + float kSrc1[4] = {0.3f, 0.6f, 0.9f, 0.7f}; + + glUniform4f(src_loc_, kSrc[0], kSrc[1], kSrc[2], kSrc[3]); + glUniform4f(src1_loc_, kSrc1[0], kSrc1[1], kSrc1[2], kSrc1[3]); + + GLTestHelper::SetupUnitQuad(position_loc_); + + glEnable(GL_BLEND); + glBlendEquation(GL_FUNC_ADD); + glBlendFuncSeparate(GL_SRC1_COLOR_EXT, GL_SRC_ALPHA, + GL_ONE_MINUS_SRC1_COLOR_EXT, + GL_ONE_MINUS_SRC1_ALPHA_EXT); + EXPECT_EQ(static_cast<GLenum>(GL_NO_ERROR), glGetError()); + + // Draw one triangle (bottom left half). + glViewport(0, 0, kWidth, kHeight); + glClearColor(kDst[0], kDst[1], kDst[2], kDst[3]); + glClear(GL_COLOR_BUFFER_BIT); + glDrawArrays(GL_TRIANGLES, 0, 6); + EXPECT_EQ(static_cast<GLenum>(GL_NO_ERROR), glGetError()); + // Verify. + uint8 color[4]; + BlendEquationFuncAdd<GL_SRC1_COLOR_EXT, GL_SRC_ALPHA, + GL_ONE_MINUS_SRC1_COLOR_EXT, + GL_ONE_MINUS_SRC1_ALPHA_EXT>(kDst, kSrc, kSrc1, color); + + EXPECT_TRUE(GLTestHelper::CheckPixels(kWidth / 4, (3 * kHeight) / 4, 1, 1, + 1, color)); + EXPECT_TRUE(GLTestHelper::CheckPixels(kWidth - 1, 0, 1, 1, 1, color)); + } + + protected: + GLuint program_; + GLuint position_loc_; + GLuint src_loc_; + GLuint src1_loc_; + GLManager gl_; +}; + +TEST_P(EXTBlendFuncExtendedDrawTest, ESSL1FragColor) { + if (!IsApplicable()) + return; + // clang-format off + static const char* kFragColorShader = + BFE_SHADER( + precision mediump float; + uniform vec4 src; + uniform vec4 src1; + void main() { + gl_FragColor = src; + gl_SecondaryFragColorEXT = src1; + }); + // clang-format on + CreateProgramWithFragmentShader(kFragColorShader); + LinkProgram(); + DrawAndVerify(); +} + +TEST_P(EXTBlendFuncExtendedDrawTest, ESSL1FragData) { + if (!IsApplicable()) + return; + // clang-format off + static const char* kFragDataShader = + BFE_SHADER( + precision mediump float; + uniform vec4 src; + uniform vec4 src1; + void main() { + gl_FragData[0] = src; + gl_SecondaryFragDataEXT[0] = src1; + }); + // clang-format on + CreateProgramWithFragmentShader(kFragDataShader); + LinkProgram(); + DrawAndVerify(); +} + +class EXTBlendFuncExtendedES3DrawTest : public EXTBlendFuncExtendedDrawTest { + protected: + void SetUp() override { + GLManager::Options options; + options.size = gfx::Size(kWidth, kHeight); + options.context_type = gles2::CONTEXT_TYPE_OPENGLES3; + options.force_shader_name_hashing = GetParam(); + base::CommandLine command_line(*base::CommandLine::ForCurrentProcess()); + command_line.AppendSwitch(switches::kEnableUnsafeES3APIs); + gl_.InitializeWithCommandLine(options, &command_line); + } + bool IsApplicable() const { + return gl_.IsInitialized() && EXTBlendFuncExtendedDrawTest::IsApplicable(); + } + const char* GetVertexShader() override { + // clang-format off + static const char* kVertexShader = + "#version 300 es\n" + SHADER( + in vec4 position; + void main() { + gl_Position = position; + }); + // clang-format on + return kVertexShader; + } +}; + +TEST_P(EXTBlendFuncExtendedES3DrawTest, ESSL3Var) { + if (!IsApplicable()) + return; + // clang-format off + static const char* kFragColorShader = + "#version 300 es\n" + BFE_SHADER( + precision mediump float; + uniform vec4 src; + uniform vec4 src1; + out vec4 FragColor; + out vec4 SecondaryFragColor; + void main() { + FragColor = src; + SecondaryFragColor = src1; + }); + // clang-format on + CreateProgramWithFragmentShader(kFragColorShader); + glBindFragDataLocationIndexedEXT(program_, 0, 1, "SecondaryFragColor"); + LinkProgram(); + DrawAndVerify(); +} + +TEST_P(EXTBlendFuncExtendedES3DrawTest, ESSL3BindArrayWithSimpleName) { + if (!IsApplicable()) + return; + // clang-format off + static const char* kFragDataShader = + "#version 300 es\n" + BFE_SHADER( + precision mediump float; + uniform vec4 src; + uniform vec4 src1; + out vec4 FragData[1]; + out vec4 SecondaryFragData[1]; + void main() { + FragData[0] = src; + SecondaryFragData[0] = src1; + }); + // clang-format on + CreateProgramWithFragmentShader(kFragDataShader); + glBindFragDataLocationEXT(program_, 0, "FragData"); + glBindFragDataLocationIndexedEXT(program_, 0, 1, "SecondaryFragData"); + LinkProgram(); + DrawAndVerify(); +} + +TEST_P(EXTBlendFuncExtendedES3DrawTest, ESSL3BindSimpleVarAsArrayNoBind) { + if (!IsApplicable()) + return; + // clang-format off + static const char* kFragDataShader = + "#version 300 es\n" + BFE_SHADER( + precision mediump float; + uniform vec4 src; + uniform vec4 src1; + out vec4 FragData; + out vec4 SecondaryFragData; + void main() { + FragData = src; + SecondaryFragData = src1; + }); + // clang-format on + CreateProgramWithFragmentShader(kFragDataShader); + glBindFragDataLocationEXT(program_, 0, "FragData[0]"); + glBindFragDataLocationIndexedEXT(program_, 0, 1, "SecondaryFragData[0]"); + // Does not fail, since FragData[0] and SecondaryFragData[0] do not exist. + EXPECT_TRUE(LinkProgram()); + + EXPECT_EQ(-1, glGetFragDataLocation(program_, "FragData[0]")); + EXPECT_EQ(0, glGetFragDataLocation(program_, "FragData")); + EXPECT_EQ(1, glGetFragDataLocation(program_, "SecondaryFragData")); + // Did not bind index. + EXPECT_EQ(0, glGetFragDataIndexEXT(program_, "SecondaryFragData")); + + glBindFragDataLocationEXT(program_, 0, "FragData"); + glBindFragDataLocationIndexedEXT(program_, 0, 1, "SecondaryFragData"); + EXPECT_TRUE(LinkProgram()); + DrawAndVerify(); +} + +TEST_P(EXTBlendFuncExtendedES3DrawTest, ESSL3BindArrayAsArray) { + if (!IsApplicable()) + return; + // clang-format off + static const char* kFragDataShader = + "#version 300 es\n" + BFE_SHADER( + precision mediump float; + uniform vec4 src; + uniform vec4 src1; + out vec4 FragData[1]; + out vec4 SecondaryFragData[1]; + void main() { + FragData[0] = src; + SecondaryFragData[0] = src1; + }); + // clang-format on + CreateProgramWithFragmentShader(kFragDataShader); + glBindFragDataLocationEXT(program_, 0, "FragData[0]"); + glBindFragDataLocationIndexedEXT(program_, 0, 1, "SecondaryFragData[0]"); + LinkProgram(); + DrawAndVerify(); +} + +TEST_P(EXTBlendFuncExtendedES3DrawTest, ES3Getters) { + if (!IsApplicable()) + return; + // clang-format off + static const char* kFragColorShader = + "#version 300 es\n" + BFE_SHADER( + precision mediump float; + uniform vec4 src; + uniform vec4 src1; + out vec4 FragColor; + out vec4 SecondaryFragColor; + void main() { + FragColor = src; + SecondaryFragColor = src1; + }); + // clang-format on + CreateProgramWithFragmentShader(kFragColorShader); + glBindFragDataLocationEXT(program_, 0, "FragColor"); + glBindFragDataLocationIndexedEXT(program_, 0, 1, "SecondaryFragColor"); + + // Getters return GL error before linking. + EXPECT_EQ(static_cast<GLenum>(GL_NO_ERROR), glGetError()); + GLint location = glGetFragDataLocation(program_, "FragColor"); + EXPECT_EQ(static_cast<GLenum>(GL_INVALID_OPERATION), glGetError()); + GLint index = glGetFragDataIndexEXT(program_, "FragColor"); + EXPECT_EQ(static_cast<GLenum>(GL_INVALID_OPERATION), glGetError()); + location = glGetFragDataLocation(program_, "SecondaryFragColor"); + EXPECT_EQ(static_cast<GLenum>(GL_INVALID_OPERATION), glGetError()); + index = glGetFragDataIndexEXT(program_, "SecondaryFragColor"); + EXPECT_EQ(static_cast<GLenum>(GL_INVALID_OPERATION), glGetError()); + LinkProgram(); + + // Getters return location and index after linking. Run twice to confirm that + // setters do not affect the getters until next link. + for (int i = 0; i < 2; ++i) { + SCOPED_TRACE(testing::Message() << "Testing getters after link, iteration " + << i); + + location = glGetFragDataLocation(program_, "FragColor"); + EXPECT_EQ(0, location); + EXPECT_EQ(static_cast<GLenum>(GL_NO_ERROR), glGetError()); + index = glGetFragDataIndexEXT(program_, "FragColor"); + EXPECT_EQ(0, index); + EXPECT_EQ(static_cast<GLenum>(GL_NO_ERROR), glGetError()); + location = glGetFragDataLocation(program_, "SecondaryFragColor"); + EXPECT_EQ(0, location); + EXPECT_EQ(static_cast<GLenum>(GL_NO_ERROR), glGetError()); + index = glGetFragDataIndexEXT(program_, "SecondaryFragColor"); + EXPECT_EQ(1, index); + EXPECT_EQ(static_cast<GLenum>(GL_NO_ERROR), glGetError()); + + // The calls should not affect the getters until re-linking. + glBindFragDataLocationEXT(program_, 0, "SecondaryFragColor"); + glBindFragDataLocationIndexedEXT(program_, 0, 1, "FragColor"); + } + + LinkProgram(); + + location = glGetFragDataLocation(program_, "FragColor"); + EXPECT_EQ(0, location); + EXPECT_EQ(static_cast<GLenum>(GL_NO_ERROR), glGetError()); + index = glGetFragDataIndexEXT(program_, "FragColor"); + EXPECT_EQ(1, index); + EXPECT_EQ(static_cast<GLenum>(GL_NO_ERROR), glGetError()); + location = glGetFragDataLocation(program_, "SecondaryFragColor"); + EXPECT_EQ(0, location); + EXPECT_EQ(static_cast<GLenum>(GL_NO_ERROR), glGetError()); + index = glGetFragDataIndexEXT(program_, "SecondaryFragColor"); + EXPECT_EQ(0, index); + EXPECT_EQ(static_cast<GLenum>(GL_NO_ERROR), glGetError()); + + // Unknown colors return location -1, index -1. + location = glGetFragDataLocation(program_, "UnknownColor"); + EXPECT_EQ(-1, location); + EXPECT_EQ(static_cast<GLenum>(GL_NO_ERROR), glGetError()); + index = glGetFragDataIndexEXT(program_, "UnknownColor"); + EXPECT_EQ(-1, index); + + // Reset the settings and verify that the driver gets them correct. + glBindFragDataLocationEXT(program_, 0, "FragColor"); + glBindFragDataLocationIndexedEXT(program_, 0, 1, "SecondaryFragColor"); + LinkProgram(); + DrawAndVerify(); +} + +// Test that tests glBindFragDataLocationEXT, glBindFragDataLocationIndexedEXT, +// glGetFragDataLocation, glGetFragDataIndexEXT work correctly with +// GLSL array output variables. The output variable can be bound by +// referring to the variable name with or without the first element array +// accessor. The getters can query location of the individual elements in +// the array. The test does not actually use the base test drawing, +// since the drivers at the time of writing do not support multiple +// buffers and dual source blending. +TEST_P(EXTBlendFuncExtendedES3DrawTest, ES3GettersArray) { + if (!IsApplicable()) + return; + const GLint kTestArraySize = 2; + const GLint kFragData0Location = 2; + const GLint kFragData1Location = 1; + const GLint kUnusedLocation = 5; + + // The test binds kTestArraySize -sized array to location 1 for test purposes. + // The GL_MAX_DRAW_BUFFERS must be > kTestArraySize, since an + // array will be bound to continuous locations, starting from the first + // location. + GLint maxDrawBuffers = 0; + glGetIntegerv(GL_MAX_DRAW_BUFFERS_EXT, &maxDrawBuffers); + EXPECT_LT(kTestArraySize, maxDrawBuffers); + + // clang-format off + static const char* kFragColorShader = + "#version 300 es\n" + BFE_SHADER( + precision mediump float; + uniform vec4 src; + uniform vec4 src1; + out vec4 FragData[2]; + void main() { + FragData[0] = src; + FragData[1] = src1; + }); + // clang-format on + CreateProgramWithFragmentShader(kFragColorShader); + + for (int testcase = 0; testcase < 4; ++testcase) { + if (testcase == 0) { + glBindFragDataLocationEXT(program_, kUnusedLocation, "FragData[0]"); + glBindFragDataLocationEXT(program_, kFragData0Location, "FragData"); + glBindFragDataLocationEXT(program_, kFragData1Location, "FragData[1]"); + } else if (testcase == 1) { + glBindFragDataLocationEXT(program_, kUnusedLocation, "FragData"); + glBindFragDataLocationEXT(program_, kFragData0Location, "FragData[0]"); + glBindFragDataLocationEXT(program_, kFragData1Location, "FragData[1]"); + } else if (testcase == 2) { + glBindFragDataLocationIndexedEXT(program_, kUnusedLocation, 0, + "FragData[0]"); + glBindFragDataLocationIndexedEXT(program_, kFragData0Location, 0, + "FragData"); + glBindFragDataLocationIndexedEXT(program_, kFragData1Location, 0, + "FragData[1]"); + } else if (testcase == 3) { + glBindFragDataLocationIndexedEXT(program_, kUnusedLocation, 0, + "FragData"); + glBindFragDataLocationIndexedEXT(program_, kFragData0Location, 0, + "FragData[0]"); + glBindFragDataLocationIndexedEXT(program_, kFragData1Location, 0, + "FragData[1]"); + } + + EXPECT_EQ(static_cast<GLenum>(GL_NO_ERROR), glGetError()); + LinkProgram(); + EXPECT_EQ(kFragData0Location, glGetFragDataLocation(program_, "FragData")); + EXPECT_EQ(0, glGetFragDataIndexEXT(program_, "FragData")); + EXPECT_EQ(kFragData0Location, + glGetFragDataLocation(program_, "FragData[0]")); + EXPECT_EQ(0, glGetFragDataIndexEXT(program_, "FragData[0]")); + EXPECT_EQ(kFragData1Location, + glGetFragDataLocation(program_, "FragData[1]")); + EXPECT_EQ(0, glGetFragDataIndexEXT(program_, "FragData[1]")); + + // Index bigger than the GLSL variable array length does not find anything. + EXPECT_EQ(-1, glGetFragDataLocation(program_, "FragData[3]")); + } +} + +// Test that tests glBindFragDataLocationEXT, glBindFragDataLocationIndexedEXT +// conflicts +// with GLSL output variables. +TEST_P(EXTBlendFuncExtendedES3DrawTest, ES3Conflicts) { + if (!IsApplicable()) + return; + const GLint kTestArraySize = 2; + const GLint kColorName0Location = 0; + const GLint kColorName1Location = 1; + GLint maxDrawBuffers = 0; + glGetIntegerv(GL_MAX_DRAW_BUFFERS_EXT, &maxDrawBuffers); + EXPECT_LT(kTestArraySize, maxDrawBuffers); + + // clang-format off + static const char* kFragColorShader = + "#version 300 es\n" + BFE_SHADER( + precision mediump float; + uniform vec4 src; + uniform vec4 src1; + out vec4 FragData0; + out vec4 FragData1; + void main() { + FragData0 = src; + FragData1 = src1; + }); + // clang-format on + CreateProgramWithFragmentShader(kFragColorShader); + + glBindFragDataLocationEXT(program_, kColorName0Location, "FragData0"); + glBindFragDataLocationEXT(program_, kColorName0Location, "FragData1"); + EXPECT_EQ(static_cast<GLenum>(GL_NO_ERROR), glGetError()); + EXPECT_FALSE(LinkProgram()); + + glBindFragDataLocationIndexedEXT(program_, kColorName0Location, 0, + "FragData0"); + glBindFragDataLocationIndexedEXT(program_, kColorName0Location, 0, + "FragData1"); + EXPECT_EQ(static_cast<GLenum>(GL_NO_ERROR), glGetError()); + EXPECT_FALSE(LinkProgram()); + + glBindFragDataLocationIndexedEXT(program_, kColorName0Location, 1, + "FragData0"); + glBindFragDataLocationIndexedEXT(program_, kColorName0Location, 1, + "FragData1"); + EXPECT_EQ(static_cast<GLenum>(GL_NO_ERROR), glGetError()); + EXPECT_FALSE(LinkProgram()); + + // Test that correct binding actually works. + glBindFragDataLocationEXT(program_, kColorName0Location, "FragData0"); + glBindFragDataLocationEXT(program_, kColorName1Location, "FragData1"); + EXPECT_EQ(static_cast<GLenum>(GL_NO_ERROR), glGetError()); + EXPECT_TRUE(LinkProgram()); + + glBindFragDataLocationIndexedEXT(program_, kColorName0Location, 0, + "FragData0"); + glBindFragDataLocationIndexedEXT(program_, kColorName0Location, 1, + "FragData1"); + EXPECT_EQ(static_cast<GLenum>(GL_NO_ERROR), glGetError()); + EXPECT_TRUE(LinkProgram()); +} + +// Test that tests glBindFragDataLocationEXT conflicts +// with GLSL array output variables. +TEST_P(EXTBlendFuncExtendedES3DrawTest, ES3ConflictsArray) { + if (!IsApplicable()) + return; + const GLint kTestArraySize = 2; + const GLint kColorName0Location = 0; + const GLint kColorName1Location = 1; + const GLint kUnusedLocation = 5; + GLint maxDrawBuffers = 0; + glGetIntegerv(GL_MAX_DRAW_BUFFERS_EXT, &maxDrawBuffers); + EXPECT_LT(kTestArraySize, maxDrawBuffers); + + // clang-format off + static const char* kFragColorShader = + "#version 300 es\n" + BFE_SHADER( + precision mediump float; + uniform vec4 src; + uniform vec4 src1; + out vec4 FragData[2]; + void main() { + FragData[0] = src; + FragData[1] = src1; + }); + // clang-format on + CreateProgramWithFragmentShader(kFragColorShader); + + glBindFragDataLocationEXT(program_, kColorName1Location, "FragData"); + glBindFragDataLocationEXT(program_, kColorName1Location, "FragData[1]"); + EXPECT_EQ(static_cast<GLenum>(GL_NO_ERROR), glGetError()); + EXPECT_FALSE(LinkProgram()); + glBindFragDataLocationEXT(program_, kUnusedLocation, "FragData"); + glBindFragDataLocationEXT(program_, kColorName1Location, "FragData[0]"); + glBindFragDataLocationEXT(program_, kColorName1Location, "FragData[1]"); + EXPECT_EQ(static_cast<GLenum>(GL_NO_ERROR), glGetError()); + EXPECT_FALSE(LinkProgram()); + // Test that binding actually works. + glBindFragDataLocationEXT(program_, kColorName0Location, "FragData[0]"); + glBindFragDataLocationEXT(program_, kColorName1Location, "FragData[1]"); + EXPECT_EQ(static_cast<GLenum>(GL_NO_ERROR), glGetError()); + EXPECT_TRUE(LinkProgram()); +} + +INSTANTIATE_TEST_CASE_P(TranslatorVariants, + EXTBlendFuncExtendedDrawTest, + ::testing::Bool()); + +INSTANTIATE_TEST_CASE_P(TranslatorVariants, + EXTBlendFuncExtendedES3DrawTest, + ::testing::Bool()); + +} // namespace gpu
diff --git a/gpu/config/gpu_info_collector.cc b/gpu/config/gpu_info_collector.cc index 2b7eaef..beda6fd 100644 --- a/gpu/config/gpu_info_collector.cc +++ b/gpu/config/gpu_info_collector.cc
@@ -18,6 +18,7 @@ #include "ui/gl/gl_context.h" #include "ui/gl/gl_implementation.h" #include "ui/gl/gl_surface.h" +#include "ui/gl/gl_version_info.h" namespace { @@ -102,8 +103,24 @@ gpu_info->gl_extensions = gfx::GetGLExtensionsFromCurrentContext(); gpu_info->gl_version = GetGLString(GL_VERSION); std::string glsl_version_string = GetGLString(GL_SHADING_LANGUAGE_VERSION); + + gfx::GLVersionInfo gl_info(gpu_info->gl_version.c_str(), + gpu_info->gl_renderer.c_str(), + gpu_info->gl_extensions.c_str()); GLint max_samples = 0; - glGetIntegerv(GL_MAX_SAMPLES, &max_samples); + if (gl_info.IsAtLeastGL(3, 0) || gl_info.IsAtLeastGLES(3, 0) || + gpu_info->gl_extensions.find("GL_ANGLE_framebuffer_multisample") != + std::string::npos || + gpu_info->gl_extensions.find("GL_APPLE_framebuffer_multisample") != + std::string::npos || + gpu_info->gl_extensions.find("GL_EXT_framebuffer_multisample") != + std::string::npos || + gpu_info->gl_extensions.find("GL_EXT_multisampled_render_to_texture") != + std::string::npos || + gpu_info->gl_extensions.find("GL_NV_framebuffer_multisample") != + std::string::npos) { + glGetIntegerv(GL_MAX_SAMPLES, &max_samples); + } gpu_info->max_msaa_samples = base::IntToString(max_samples); UMA_HISTOGRAM_SPARSE_SLOWLY("GPU.MaxMSAASampleCount", max_samples);
diff --git a/gpu/config/gpu_info_collector_unittest.cc b/gpu/config/gpu_info_collector_unittest.cc index 0f9b306..76fc31b2 100644 --- a/gpu/config/gpu_info_collector_unittest.cc +++ b/gpu/config/gpu_info_collector_unittest.cc
@@ -64,7 +64,7 @@ test_values_.gl_version = "OpenGL ES 2.0 V@14.0 AU@04.02 (CL@3206)"; test_values_.gl_extensions = "GL_OES_packed_depth_stencil GL_EXT_texture_format_BGRA8888 " - "GL_EXT_read_format_bgra"; + "GL_EXT_read_format_bgra GL_EXT_multisampled_render_to_texture"; gl_shading_language_version_ = "1.00"; break; } @@ -96,7 +96,7 @@ test_values_.gl_version = "2.1 NVIDIA-1.6.18"; test_values_.gl_extensions = "GL_OES_packed_depth_stencil GL_EXT_texture_format_BGRA8888 " - "GL_EXT_read_format_bgra"; + "GL_EXT_read_format_bgra GL_EXT_framebuffer_multisample"; gl_shading_language_version_ = "1.20 "; break; }
diff --git a/gpu/gpu.gyp b/gpu/gpu.gyp index 68aaaff..14c4ea31 100644 --- a/gpu/gpu.gyp +++ b/gpu/gpu.gyp
@@ -367,7 +367,8 @@ 'command_buffer/tests/gl_copy_texture_CHROMIUM_unittest.cc', 'command_buffer/tests/gl_cube_map_texture_unittest.cc', 'command_buffer/tests/gl_depth_texture_unittest.cc', - 'command_buffer/tests/gl_ext_multisample_compatibility_unittest.cc', + 'command_buffer/tests/gl_ext_blend_func_extended_unittest.cc', + 'command_buffer/tests/gl_ext_multisample_compatibility_unittest.cc', 'command_buffer/tests/gl_ext_srgb_unittest.cc', 'command_buffer/tests/gl_fence_sync_unittest.cc', 'command_buffer/tests/gl_gpu_memory_buffer_unittest.cc',
diff --git a/gpu/skia_bindings/gl_bindings_skia_cmd_buffer.cc b/gpu/skia_bindings/gl_bindings_skia_cmd_buffer.cc index 9afc900..0203d07 100644 --- a/gpu/skia_bindings/gl_bindings_skia_cmd_buffer.cc +++ b/gpu/skia_bindings/gl_bindings_skia_cmd_buffer.cc
@@ -143,6 +143,8 @@ glRenderbufferStorageMultisampleCHROMIUM; functions->fRenderbufferStorageMultisampleES2EXT = glRenderbufferStorageMultisampleEXT; + functions->fBindFragDataLocation = glBindFragDataLocationEXT; + functions->fBindFragDataLocationIndexed = glBindFragDataLocationIndexedEXT; functions->fBindUniformLocation = glBindUniformLocationCHROMIUM; functions->fBlitFramebuffer = glBlitFramebufferCHROMIUM; functions->fGenerateMipmap = glGenerateMipmap;
diff --git a/ios/chrome/browser/about_flags.mm b/ios/chrome/browser/about_flags.mm index 1d7b752c..81ddefc 100644 --- a/ios/chrome/browser/about_flags.mm +++ b/ios/chrome/browser/about_flags.mm
@@ -50,12 +50,12 @@ const flags_ui::FeatureEntry kFeatureEntries[] = { {"contextual-search", IDS_IOS_FLAGS_CONTEXTUAL_SEARCH, IDS_IOS_FLAGS_CONTEXTUAL_SEARCH_DESCRIPTION, - flags_ui::kOsIos | flags_ui::kOsIosAppleReview, + flags_ui::kOsIos, ENABLE_DISABLE_VALUE_TYPE(switches::kEnableContextualSearch, switches::kDisableContextualSearch)}, {"enhanced-bookmarks-experiment", IDS_FLAGS_ENHANCED_BOOKMARKS_NAME, IDS_FLAGS_ENHANCED_BOOKMARKS_DESCRIPTION, - flags_ui::kOsIos | flags_ui::kOsIosAppleReview, + flags_ui::kOsIos, ENABLE_DISABLE_VALUE_TYPE_AND_VALUE(switches::kEnhancedBookmarksExperiment, "1", switches::kEnhancedBookmarksExperiment,
diff --git a/ios/chrome/browser/experimental_flags.mm b/ios/chrome/browser/experimental_flags.mm index 0fd40ed..29ea735 100644 --- a/ios/chrome/browser/experimental_flags.mm +++ b/ios/chrome/browser/experimental_flags.mm
@@ -174,8 +174,10 @@ } bool AreKeyboardCommandsEnabled() { - return !base::CommandLine::ForCurrentProcess()->HasSwitch( - switches::kDisableKeyboardCommands); + const base::CommandLine* command_line = + base::CommandLine::ForCurrentProcess(); + return command_line && + !command_line->HasSwitch(switches::kDisableKeyboardCommands); } bool IsViewCopyPasswordsEnabled() {
diff --git a/ios/chrome/browser/prefs/browser_prefs.mm b/ios/chrome/browser/prefs/browser_prefs.mm index d9a0584..0bab9ac 100644 --- a/ios/chrome/browser/prefs/browser_prefs.mm +++ b/ios/chrome/browser/prefs/browser_prefs.mm
@@ -20,6 +20,7 @@ #include "components/rappor/rappor_service.h" #include "components/search_engines/template_url_prepopulate_data.h" #include "components/signin/core/common/signin_pref_names.h" +#include "components/ssl_config/ssl_config_service_manager.h" #include "components/sync_driver/sync_prefs.h" #include "components/translate/core/browser/translate_prefs.h" #include "components/translate/core/common/translate_pref_names.h" @@ -57,6 +58,7 @@ network_time::NetworkTimeTracker::RegisterPrefs(registry); PrefProxyConfigTrackerImpl::RegisterPrefs(registry); rappor::RapporService::RegisterPrefs(registry); + ssl_config::SSLConfigServiceManager::RegisterPrefs(registry); variations::VariationsService::RegisterPrefs(registry); web_resource::PromoResourceService::RegisterPrefs(registry); @@ -79,8 +81,6 @@ false); ApplicationContextImpl::RegisterPrefs(registry); - - ios::GetChromeBrowserProvider()->RegisterLocalState(registry); } void RegisterBrowserStatePrefs(user_prefs::PrefRegistrySyncable* registry) {
diff --git a/ios/chrome/browser/ui/uikit_ui_util.h b/ios/chrome/browser/ui/uikit_ui_util.h index 6fb26cd..2223a11 100644 --- a/ios/chrome/browser/ui/uikit_ui_util.h +++ b/ios/chrome/browser/ui/uikit_ui_util.h
@@ -51,6 +51,21 @@ // not have an alpha channel. The scale parameter is used as a scale factor // for the rendering context. Using 0.0 as scale will result in the device's // main screen scale to be used. +// The CaptureViewWithOption function can be used with the afterScreenUpdate +// parameter set to YES if some changes performed in the view and/or it's +// subtree that have not yet been part of a committed implicit transaction must +// be reflected in the snapshot. For example, it should be used if you just +// performed changes in the view or its subviews before calling that function +// and wants those changes to be reflected in the snapshot. +// The CaptureView function will perform better then the afterScreenUpdate +// version (when set to YES). If you only need to hide subviews consider +// selectively rendering subviews in a bitmap context using +// drawViewHierarchyInRect:afterScreenUpdates:NO. +// On iOS < 9 this function is slow and always behave as the +// CaptureViewWithOption function with afterScreenUpdate set to YES. +UIImage* CaptureViewWithOption(UIView* view, + CGFloat scale, + BOOL afterScreenUpdate); UIImage* CaptureView(UIView* view, CGFloat scale); // Converts input image and returns a grey scaled version.
diff --git a/ios/chrome/browser/ui/uikit_ui_util.mm b/ios/chrome/browser/ui/uikit_ui_util.mm index 133e0de..c1c2504 100644 --- a/ios/chrome/browser/ui/uikit_ui_util.mm +++ b/ios/chrome/browser/ui/uikit_ui_util.mm
@@ -150,11 +150,14 @@ CGPathRelease(path); } -UIImage* CaptureView(UIView* view, CGFloat scale) { +UIImage* CaptureViewWithOption(UIView* view, + CGFloat scale, + BOOL afterScreenUpdate) { UIGraphicsBeginImageContextWithOptions(view.bounds.size, YES /* opaque */, scale); - if (experimental_flags::IsWKWebViewEnabled()) { - [view drawViewHierarchyInRect:view.bounds afterScreenUpdates:NO]; + if (base::ios::IsRunningOnIOS9OrLater()) { + [view drawViewHierarchyInRect:view.bounds + afterScreenUpdates:afterScreenUpdate]; } else { CGContext* context = UIGraphicsGetCurrentContext(); [view.layer renderInContext:context]; @@ -164,6 +167,10 @@ return image; } +UIImage* CaptureView(UIView* view, CGFloat scale) { + return CaptureViewWithOption(view, scale, NO /* afterScreenUpdate */); +} + UIImage* GreyImage(UIImage* image) { DCHECK(image); // Grey images are always non-retina to improve memory performance.
diff --git a/ios/net/http_response_headers_util.mm b/ios/net/http_response_headers_util.mm index 64d86b5..5d6f716 100644 --- a/ios/net/http_response_headers_util.mm +++ b/ios/net/http_response_headers_util.mm
@@ -40,7 +40,7 @@ [NSString stringWithFormat:kHeaderLineFormat, header_name, value]; http_headers->AddHeader(base::SysNSStringToUTF8(header_line)); }]; - return http_headers.Pass(); + return http_headers; } } // namespae net
diff --git a/ios/public/provider/chrome/browser/browser_state/chrome_browser_state.cc b/ios/public/provider/chrome/browser/browser_state/chrome_browser_state.cc index 62a46ea..1041737a1 100644 --- a/ios/public/provider/chrome/browser/browser_state/chrome_browser_state.cc +++ b/ios/public/provider/chrome/browser/browser_state/chrome_browser_state.cc
@@ -4,6 +4,7 @@ #include "ios/public/provider/chrome/browser/browser_state/chrome_browser_state.h" +#include "base/files/file_path.h" #include "ios/public/provider/web/web_ui_ios.h" #include "ios/web/public/web_state/web_state.h" @@ -21,4 +22,15 @@ return FromBrowserState(web_ui->GetWebState()->GetBrowserState()); } +std::string ChromeBrowserState::GetDebugName() { + // The debug name is based on the state path of the original browser state + // to keep in sync with the meaning on other platforms. + std::string name = + GetOriginalChromeBrowserState()->GetStatePath().BaseName().MaybeAsASCII(); + if (name.empty()) { + name = "UnknownBrowserState"; + } + return name; +} + } // namespace ios
diff --git a/ios/public/provider/chrome/browser/browser_state/chrome_browser_state.h b/ios/public/provider/chrome/browser/browser_state/chrome_browser_state.h index 5a8b084a..ab7be32 100644 --- a/ios/public/provider/chrome/browser/browser_state/chrome_browser_state.h +++ b/ios/public/provider/chrome/browser/browser_state/chrome_browser_state.h
@@ -5,6 +5,8 @@ #ifndef IOS_PUBLIC_PROVIDER_CHROME_BROWSER_BROWSER_STATE_CHROME_BROWSER_STATE_H_ #define IOS_PUBLIC_PROVIDER_CHROME_BROWSER_BROWSER_STATE_CHROME_BROWSER_STATE_H_ +#include <string> + #include "base/basictypes.h" #include "base/callback_forward.h" #include "base/compiler_specific.h" @@ -79,6 +81,9 @@ virtual void ClearNetworkingHistorySince(base::Time time, const base::Closure& completion) = 0; + // Returns an identifier of the browser state for debugging. + std::string GetDebugName(); + protected: ChromeBrowserState() {}
diff --git a/ios/public/provider/chrome/browser/chrome_browser_provider.cc b/ios/public/provider/chrome/browser/chrome_browser_provider.cc index 285144b6..d0127165 100644 --- a/ios/public/provider/chrome/browser/chrome_browser_provider.cc +++ b/ios/public/provider/chrome/browser/chrome_browser_provider.cc
@@ -37,9 +37,6 @@ void ChromeBrowserProvider::AssertBrowserContextKeyedFactoriesBuilt() { } -void ChromeBrowserProvider::RegisterLocalState(PrefRegistrySimple* registry) { -} - void ChromeBrowserProvider::RegisterProfilePrefs( user_prefs::PrefRegistrySyncable* registry) { }
diff --git a/ios/public/provider/chrome/browser/chrome_browser_provider.h b/ios/public/provider/chrome/browser/chrome_browser_provider.h index 4509c50..008372a 100644 --- a/ios/public/provider/chrome/browser/chrome_browser_provider.h +++ b/ios/public/provider/chrome/browser/chrome_browser_provider.h
@@ -77,8 +77,6 @@ // Asserts all iOS-specific |BrowserContextKeyedServiceFactory| are built. virtual void AssertBrowserContextKeyedFactoriesBuilt(); - // Registers all prefs that will be used via the local state PrefService. - virtual void RegisterLocalState(PrefRegistrySimple* registry); // Registers all prefs that will be used via a PrefService attached to a // Profile. virtual void RegisterProfilePrefs(
diff --git a/ios/web/BUILD.gn b/ios/web/BUILD.gn index 92b7f9c..04a7511 100644 --- a/ios/web/BUILD.gn +++ b/ios/web/BUILD.gn
@@ -220,6 +220,8 @@ "web_state/js/crw_js_invoke_parameter_queue.mm", "web_state/js/crw_js_plugin_placeholder_manager.h", "web_state/js/crw_js_plugin_placeholder_manager.mm", + "web_state/js/crw_js_post_request_loader.h", + "web_state/js/crw_js_post_request_loader.h", "web_state/js/crw_js_window_id_manager.h", "web_state/js/crw_js_window_id_manager.mm", "web_state/js/page_script_util.h", @@ -432,6 +434,7 @@ "web_state/js/crw_js_early_script_manager_unittest.mm", "web_state/js/crw_js_injection_manager_unittest.mm", "web_state/js/crw_js_invoke_parameter_queue_unittest.mm", + "web_state/js/crw_js_post_request_loader_unittest.mm", "web_state/js/crw_js_window_id_manager_unittest.mm", "web_state/js/page_script_util_unittest.mm", "web_state/ui/crw_static_file_web_view_unittest.mm",
diff --git a/ios/web/ios_web.gyp b/ios/web/ios_web.gyp index dddf60a4..2aa9231 100644 --- a/ios/web/ios_web.gyp +++ b/ios/web/ios_web.gyp
@@ -237,6 +237,8 @@ 'web_state/js/credential_util.mm', 'web_state/js/crw_js_early_script_manager.h', 'web_state/js/crw_js_early_script_manager.mm', + 'web_state/js/crw_js_post_request_loader.h', + 'web_state/js/crw_js_post_request_loader.mm', 'web_state/js/crw_js_injection_manager.mm', 'web_state/js/crw_js_injection_receiver.mm', 'web_state/js/crw_js_invoke_parameter_queue.h', @@ -421,12 +423,14 @@ 'ios_web_js_bundle_wk', ], 'sources': [ + 'web_state/js/resources/post_request.js', 'web_state/js/resources/plugin_placeholder.js', 'web_state/js/resources/window_id.js', 'webui/resources/web_ui.js', ], 'link_settings': { 'mac_bundle_resources': [ + '<(SHARED_INTERMEDIATE_DIR)/post_request.js', '<(SHARED_INTERMEDIATE_DIR)/plugin_placeholder.js', '<(SHARED_INTERMEDIATE_DIR)/window_id.js', '<(SHARED_INTERMEDIATE_DIR)/web_ui.js',
diff --git a/ios/web/ios_web_unittests.gyp b/ios/web/ios_web_unittests.gyp index a88f34ae..69c03e9 100644 --- a/ios/web/ios_web_unittests.gyp +++ b/ios/web/ios_web_unittests.gyp
@@ -62,6 +62,7 @@ 'web_state/js/crw_js_early_script_manager_unittest.mm', 'web_state/js/crw_js_injection_manager_unittest.mm', 'web_state/js/crw_js_invoke_parameter_queue_unittest.mm', + 'web_state/js/crw_js_post_request_loader_unittest.mm', 'web_state/js/crw_js_window_id_manager_unittest.mm', 'web_state/js/page_script_util_unittest.mm', 'web_state/ui/crw_static_file_web_view_unittest.mm',
diff --git a/ios/web/net/cert_verifier_block_adapter.cc b/ios/web/net/cert_verifier_block_adapter.cc index a43429a..932604bd 100644 --- a/ios/web/net/cert_verifier_block_adapter.cc +++ b/ios/web/net/cert_verifier_block_adapter.cc
@@ -23,7 +23,7 @@ VerificationContext(scoped_refptr<net::X509Certificate> cert, net::NetLog* net_log) : request(nullptr), - cert(cert.Pass()), + cert(std::move(cert)), net_log(net::BoundNetLog::Make( net_log, net::NetLog::SOURCE_IOS_WEB_VIEW_CERT_VERIFIER)) {}
diff --git a/ios/web/net/crw_cert_verification_controller.mm b/ios/web/net/crw_cert_verification_controller.mm index 85b5a106..8089386 100644 --- a/ios/web/net/crw_cert_verification_controller.mm +++ b/ios/web/net/crw_cert_verification_controller.mm
@@ -426,8 +426,8 @@ return; } - web::CertVerifierBlockAdapter::Params params( - blockCert.Pass(), base::SysNSStringToUTF8(host)); + web::CertVerifierBlockAdapter::Params params(std::move(blockCert), + base::SysNSStringToUTF8(host)); params.flags = self.certVerifyFlags; // OCSP response is not provided by iOS API. // CRLSets are not used, as the OS is used to make load/no-load
diff --git a/ios/web/web_state/js/crw_js_post_request_loader.h b/ios/web/web_state/js/crw_js_post_request_loader.h new file mode 100644 index 0000000..ffcde3bc --- /dev/null +++ b/ios/web/web_state/js/crw_js_post_request_loader.h
@@ -0,0 +1,28 @@ +// 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. + +#ifndef IOS_WEB_WEB_STATE_JS_CRW_JS_POST_REQUEST_LOADER_H_ +#define IOS_WEB_WEB_STATE_JS_CRW_JS_POST_REQUEST_LOADER_H_ + +#import <WebKit/WebKit.h> + +@class CRWWKScriptMessageRouter; + +// Class to load POST requests in a provided web view via JavaScript. +@interface CRWJSPOSTRequestLoader : NSObject + +// Asynchronously loads a POST |request| in provided |webView|. +// It temporarily installs JavaScript message routers with |messageRouter| to +// handle HTTP errors. The |completionHandler| is called once the request has +// been executed. In case of successful request, the passed error is nil. +// The |completionHandler| must not be null. The |messageRouter| and |webView| +// must not be nil. The |request| must be a POST request. +- (void)loadPOSTRequest:(NSURLRequest*)request + inWebView:(WKWebView*)webView + messageRouter:(CRWWKScriptMessageRouter*)messageRouter + completionHandler:(void (^)(NSError*))completionHandler; + +@end + +#endif // IOS_WEB_WEB_STATE_JS_CRW_JS_POST_REQUEST_LOADER_H_
diff --git a/ios/web/web_state/js/crw_js_post_request_loader.mm b/ios/web/web_state/js/crw_js_post_request_loader.mm new file mode 100644 index 0000000..4c9eea1 --- /dev/null +++ b/ios/web/web_state/js/crw_js_post_request_loader.mm
@@ -0,0 +1,156 @@ +// 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. + +#import "ios/web/web_state/js/crw_js_post_request_loader.h" + +#include "base/json/string_escape.h" +#import "base/mac/scoped_nsobject.h" +#import "base/strings/sys_string_conversions.h" +#import "ios/web/web_state/js/page_script_util.h" +#import "ios/web/web_state/ui/crw_wk_script_message_router.h" + +namespace { + +// Escapes characters and encloses given string in quotes for use in JavaScript. +NSString* EscapeAndQuoteStringForJavaScript(NSString* unescapedString) { + std::string string = base::SysNSStringToUTF8(unescapedString); + return base::SysUTF8ToNSString(base::GetQuotedJSONString(string)); +} + +// JavaScript message handler name installed in WKWebView for request errors. +NSString* const kErrorHandlerName = @"POSTErrorHandler"; + +// JavaScript message handler name installed in WKWebView for successful +// request completion. +NSString* const kSuccessHandlerName = @"POSTSuccessHandler"; + +} // namespace + +@interface CRWJSPOSTRequestLoader () { + base::scoped_nsobject<NSString> _requestScript; +} + +// JavaScript used to execute POST requests. Lazily instantiated. +@property(nonatomic, copy, readonly) NSString* requestScript; + +// Handler for UIApplicationDidReceiveMemoryWarningNotification. +- (void)handleMemoryWarning; + +// Forms a JavaScript method call to |requestScript| that executes given +// |request|. +- (NSString*)scriptToExecutePOSTRequest:(NSURLRequest*)request; + +// Converts a dictionary of HTTP request headers to a JavaScript object. +- (NSString*)JSONForJavaScriptFromRequestHeaders:(NSDictionary*)headers; + +@end + +@implementation CRWJSPOSTRequestLoader + +- (instancetype)init { + self = [super init]; + if (self) { + [[NSNotificationCenter defaultCenter] + addObserver:self + selector:@selector(handleMemoryWarning) + name:UIApplicationDidReceiveMemoryWarningNotification + object:nil]; + } + return self; +} + +- (void)dealloc { + [[NSNotificationCenter defaultCenter] removeObserver:self]; + [super dealloc]; +} + +- (NSString*)requestScript { + if (!_requestScript) { + _requestScript.reset([web::GetPageScript(@"post_request") copy]); + } + return _requestScript; +} + +- (void)loadPOSTRequest:(NSURLRequest*)request + inWebView:(WKWebView*)webView + messageRouter:(CRWWKScriptMessageRouter*)messageRouter + completionHandler:(void (^)(NSError*))completionHandler { + DCHECK([request.HTTPMethod isEqualToString:@"POST"]); + DCHECK(webView); + DCHECK(messageRouter); + DCHECK(completionHandler); + + // Install error handling and success routers. + [messageRouter setScriptMessageHandler:^(WKScriptMessage* message) { + // Cleaning up script handlers. + [messageRouter removeScriptMessageHandlerForName:kErrorHandlerName + webView:webView]; + [messageRouter removeScriptMessageHandlerForName:kSuccessHandlerName + webView:webView]; + completionHandler(nil); + } + name:kSuccessHandlerName + webView:webView]; + + [messageRouter setScriptMessageHandler:^(WKScriptMessage* message) { + NSNumber* statusCode = message.body; + NSError* error = [NSError errorWithDomain:NSURLErrorDomain + code:statusCode.integerValue + userInfo:nil]; + [messageRouter removeScriptMessageHandlerForName:kErrorHandlerName + webView:webView]; + [messageRouter removeScriptMessageHandlerForName:kSuccessHandlerName + webView:webView]; + completionHandler(error); + } + name:kErrorHandlerName + webView:webView]; + + NSString* HTML = + [NSString stringWithFormat:@"<html><script>%@%@</script></html>", + self.requestScript, + [self scriptToExecutePOSTRequest:request]]; + [webView loadHTMLString:HTML baseURL:request.URL]; +} + +#pragma mark - Private methods. + +- (void)handleMemoryWarning { + // Request script can be recreated from file at any moment. + _requestScript.reset(); +} + +- (NSString*)scriptToExecutePOSTRequest:(NSURLRequest*)request { + NSDictionary* headers = [request allHTTPHeaderFields]; + NSString* headerString = [self JSONForJavaScriptFromRequestHeaders:headers]; + NSString* URLString = [[request URL] absoluteString]; + NSString* contentType = headers[@"Content-Type"]; + NSString* base64Data = [[request HTTPBody] base64EncodedStringWithOptions:0]; + + // Here |headerString| is already properly escaped when returned from + // -JSONForJavaScriptFromRequestHeaders:. + return + [NSString stringWithFormat: + @"__crPostRequestWorkaround.runPostRequest(%@, %@, %@, %@)", + EscapeAndQuoteStringForJavaScript(URLString), headerString, + EscapeAndQuoteStringForJavaScript(base64Data), + EscapeAndQuoteStringForJavaScript(contentType)]; +} + +- (NSString*)JSONForJavaScriptFromRequestHeaders:(NSDictionary*)headers { + if (headers) { + NSData* headerData = + [NSJSONSerialization dataWithJSONObject:headers options:0 error:nil]; + if (headerData) { + // This string is properly escaped by NSJSONSerialization. It needs to + // have no quotes since JavaScripts takes this parameter as an + // Object<string, string>. + return [[[NSString alloc] initWithData:headerData + encoding:NSUTF8StringEncoding] autorelease]; + } + } + return @"{}"; +} + +@end
diff --git a/ios/web/web_state/js/crw_js_post_request_loader_unittest.mm b/ios/web/web_state/js/crw_js_post_request_loader_unittest.mm new file mode 100644 index 0000000..aa6a4d0 --- /dev/null +++ b/ios/web/web_state/js/crw_js_post_request_loader_unittest.mm
@@ -0,0 +1,105 @@ +// 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. + +#import "ios/web/web_state/js/crw_js_post_request_loader.h" + +#import <WebKit/WebKit.h> + +#import "base/mac/foundation_util.h" +#import "base/mac/scoped_nsobject.h" +#include "base/strings/sys_string_conversions.h" +#import "base/test/ios/wait_util.h" +#include "ios/web/public/test/web_test_util.h" +#import "ios/web/public/web_view_creation_util.h" +#import "ios/web/test/web_test.h" +#import "ios/web/web_state/ui/crw_wk_script_message_router.h" +#import "testing/gtest_mac.h" +#import "third_party/ocmock/OCMock/OCMock.h" + +namespace base { +namespace { + +typedef web::WebTest CRWJSPOSTRequestLoaderTest; + +// This script takes a JavaScript blob and converts it to a base64-encoded +// string asynchronously, then is sent to XHRSendHandler message handler. +NSString* const kBlobToBase64StringScript = + @"var blobToBase64 = function(x) {" + " var reader = new window.FileReader();" + " reader.readAsDataURL(x);" + " reader.onloadend = function() {" + " base64data = reader.result;" + " window.webkit.messageHandlers.XHRSendHandler.postMessage(base64data);" + " };" + "};"; + +// Tests that the POST request is correctly executed through XMLHttpRequest. +TEST_F(CRWJSPOSTRequestLoaderTest, LoadsCorrectHTML) { + CR_TEST_REQUIRES_WK_WEB_VIEW(); + + // Set up necessary objects. + scoped_nsobject<CRWJSPOSTRequestLoader> loader( + [[CRWJSPOSTRequestLoader alloc] init]); + scoped_nsobject<WKWebView> web_view( + web::CreateWKWebView(CGRectZero, GetBrowserState())); + WKUserContentController* contentController = + web_view.get().configuration.userContentController; + scoped_nsobject<CRWWKScriptMessageRouter> messageRouter( + [[CRWWKScriptMessageRouter alloc] + initWithUserContentController:contentController]); + + // Override XMLHttpRequest.send() to call kBlobToBase64StringScript. + __block BOOL overrideSuccessfull = NO; + NSString* JS = [kBlobToBase64StringScript stringByAppendingString:@";\ + XMLHttpRequest.prototype.send = function(x) { blobToBase64(x); };"]; + [web_view evaluateJavaScript:JS + completionHandler:^(id, NSError*) { + overrideSuccessfull = YES; + }]; + base::test::ios::WaitUntilCondition(^bool { + return overrideSuccessfull; + }); + + NSString* post_body = @"123"; + + // Adds XHRSendHandler handler that checks that the POST request body is + // correct. Sets |complete| flag upon completion. + __block BOOL complete = NO; + void (^XHRSendHandler)(WKScriptMessage*) = ^(WKScriptMessage* message) { + NSString* body = base::mac::ObjCCast<NSString>(message.body); + NSArray* components = [body componentsSeparatedByString:@","]; + EXPECT_EQ(components.count, 2u); + EXPECT_NSEQ(components[0], @"data:;base64"); + NSData* expectedData = [post_body dataUsingEncoding:NSUTF8StringEncoding]; + EXPECT_NSEQ(components[1], [expectedData base64EncodedStringWithOptions:0]); + complete = YES; + }; + + [messageRouter setScriptMessageHandler:XHRSendHandler + name:@"XHRSendHandler" + webView:web_view]; + + // Construct and perform the POST request. + NSURL* url = [NSURL URLWithString:@"http://google.com"]; + NSMutableURLRequest* request = [NSMutableURLRequest requestWithURL:url]; + request.HTTPMethod = @"POST"; + request.HTTPBody = [post_body dataUsingEncoding:NSUTF8StringEncoding]; + [loader loadPOSTRequest:request + inWebView:web_view + messageRouter:messageRouter + completionHandler:^(NSError*){ + }]; + + // Wait until the JavaScript message handler is called. + base::test::ios::WaitUntilCondition(^bool { + return complete; + }); + + // Clean up installed script handler. + [messageRouter removeScriptMessageHandlerForName:@"XHRSendHandler" + webView:web_view]; +} + +} // namespace +} // namespace base
diff --git a/ios/web/web_state/js/resources/post_request.js b/ios/web/web_state/js/resources/post_request.js new file mode 100644 index 0000000..7f5ff25 --- /dev/null +++ b/ios/web/web_state/js/resources/post_request.js
@@ -0,0 +1,84 @@ +// 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. + +// Provides a way to implement POST requests via XMLHttpRequest. +// Works around https://bugs.webkit.org/show_bug.cgi?id=145410 on WKWebView. + +'use strict'; + +goog.provide('__crPostRequestWorkaround'); + +/** + * Namespace for this file. + */ +__crPostRequestWorkaround = {}; + +/** + * Executes a POST request with given parameters and replaces document body with + * the response. + * @param {string} url The url of the request. + * @param {Object<string,string>} headers Request headers to include in POST. + * Each header value must be expressed as a key-value pair in this object. + * @param {string} body Request body encoded with Base64. + * @param {string} contentType Content-Type header value. + */ +__crPostRequestWorkaround.runPostRequest = function( + url, headers, body, contentType) { + + /** + * Converts a Base64-encoded string to a blob. + * @param {string} byteCharacters Base64-encoded data string. + * @param {string} contentType Corresponding content type. + * @return {Blob} Binary representation of byteCharacters. + */ + var base64ToBlob = function(byteCharacters, contentType) { + contentType = contentType || ''; + var sliceSize = 512; + var byteArrays = []; + var byteCount = byteCharacters.length; + for (var offset = 0; offset < byteCount; offset += sliceSize) { + var slice = byteCharacters.slice(offset, offset + sliceSize); + var byteNumbers = new Array(slice.length); + for (var i = 0; i < slice.length; i++) { + byteNumbers[i] = slice.charCodeAt(i); + } + var byteArray = new Uint8Array(byteNumbers); + byteArrays.push(byteArray); + } + return new Blob(byteArrays, {type: contentType}); + } + + /** + * Creates and executes a POST request. + * @param {string} url The url of the request. + * @param {Object<string,string>} headers Request headers to include in POST. + * Each header value must be expressed as a key-value pair in this object. + * @param {string} body Request body encoded with Base64. + * @param {string} contentType Content-Type header value. + */ + var createAndSendPostRequest = function(url, headers, body, contentType) { + var request = new XMLHttpRequest(); + request.open('POST', url, false); + for (var key in headers) { + if (headers.hasOwnProperty(key)) { + request.setRequestHeader(key, headers[key]); + } + } + var blob = base64ToBlob(atob(body), contentType); + request.send(blob); + if (request.status != 200) { + throw request.status; + } + return request.responseText; + } + + document.open(); + try { + document.write(createAndSendPostRequest(url, headers, body, contentType)); + window.webkit.messageHandlers.POSTSuccessHandler.postMessage(""); + } catch(error) { + window.webkit.messageHandlers.POSTErrorHandler.postMessage(error); + } + document.close(); +}
diff --git a/ios/web/web_state/ui/crw_wk_script_message_router.mm b/ios/web/web_state/ui/crw_wk_script_message_router.mm index 5699abd..0e1dfbb 100644 --- a/ios/web/web_state/ui/crw_wk_script_message_router.mm +++ b/ios/web/web_state/ui/crw_wk_script_message_router.mm
@@ -100,8 +100,12 @@ - (void)tryRemoveScriptMessageHandlerForName:(NSString*)messageName webView:(WKWebView*)webView { NSMapTable* webViewToHandlerMap = [_handlers objectForKey:messageName]; - if (![webViewToHandlerMap objectForKey:webView]) + id handler = [webViewToHandlerMap objectForKey:webView]; + if (!handler) return; + // Extend the lifetime of |handler| so removeScriptMessageHandlerForName: can + // be called from inside of |handler|. + [[handler retain] autorelease]; if (webViewToHandlerMap.count == 1) { [_handlers removeObjectForKey:messageName]; [_userContentController removeScriptMessageHandlerForName:messageName];
diff --git a/ios/web/web_state/ui/crw_wk_web_view_web_controller.mm b/ios/web/web_state/ui/crw_wk_web_view_web_controller.mm index c680bac..0b2ca998 100644 --- a/ios/web/web_state/ui/crw_wk_web_view_web_controller.mm +++ b/ios/web/web_state/ui/crw_wk_web_view_web_controller.mm
@@ -10,7 +10,7 @@ #include "base/ios/ios_util.h" #include "base/ios/weak_nsobject.h" #include "base/json/json_reader.h" -#include "base/mac/objc_property_releaser.h" +#import "base/mac/objc_property_releaser.h" #import "base/mac/scoped_nsobject.h" #include "base/macros.h" #include "base/metrics/histogram_macros.h" @@ -39,6 +39,7 @@ #import "ios/web/web_state/crw_pass_kit_downloader.h" #import "ios/web/web_state/error_translation_util.h" #include "ios/web/web_state/frame_info.h" +#import "ios/web/web_state/js/crw_js_post_request_loader.h" #import "ios/web/web_state/js/crw_js_window_id_manager.h" #import "ios/web/web_state/ui/crw_web_controller+protected.h" #import "ios/web/web_state/ui/crw_wk_script_message_router.h" @@ -187,6 +188,9 @@ // Handles downloading PassKit data for WKWebView. Lazy initialized. base::scoped_nsobject<CRWPassKitDownloader> _passKitDownloader; + // Object for loading POST requests with body. + base::scoped_nsobject<CRWJSPOSTRequestLoader> _POSTRequestLoader; + // Whether the web page is currently performing window.history.pushState or // window.history.replaceState // Set to YES on window.history.willChangeState message. To NO on @@ -233,6 +237,15 @@ // Downloader for PassKit files. Lazy initialized. @property(nonatomic, readonly) CRWPassKitDownloader* passKitDownloader; +// Loads POST request with body in |_wkWebView| by constructing an HTML page +// that executes the request through JavaScript and replaces document with the +// result. +// Note that this approach includes multiple body encodings and decodings, plus +// the data is passed to |_wkWebView| on main thread. +// This is necessary because WKWebView ignores POST request body. +// Workaround for https://bugs.webkit.org/show_bug.cgi?id=145410 +- (void)loadPOSTRequest:(NSMutableURLRequest*)request; + // Returns the WKWebViewConfigurationProvider associated with the web // controller's BrowserState. - (web::WKWebViewConfigurationProvider&)webViewConfigurationProvider; @@ -557,20 +570,42 @@ - (void)loadRequestForCurrentNavigationItem { DCHECK(self.webView && !self.nativeController); + DCHECK([self currentSessionEntry]); + + web::WKBackForwardListItemHolder* holder = + [self currentBackForwardListItemHolder]; + BOOL isFormResubmission = + (holder->navigation_type() == WKNavigationTypeFormResubmitted || + holder->navigation_type() == WKNavigationTypeFormSubmitted); + web::NavigationItemImpl* currentItem = + [self currentSessionEntry].navigationItemImpl; + NSData* POSTData = currentItem->GetPostData(); + NSMutableURLRequest* request = [self requestForCurrentNavigationItem]; + + // If the request has POST data and is not a form resubmission, configure and + // run the POST request. + if (POSTData.length && !isFormResubmission) { + [request setHTTPMethod:@"POST"]; + [request setHTTPBody:POSTData]; + [request setAllHTTPHeaderFields:[self currentHTTPHeaders]]; + [self registerLoadRequest:[self currentNavigationURL] + referrer:[self currentSessionEntryReferrer] + transition:[self currentTransition]]; + [self loadPOSTRequest:request]; + return; + } ProceduralBlock defaultNavigationBlock = ^{ [self registerLoadRequest:[self currentNavigationURL] referrer:[self currentSessionEntryReferrer] transition:[self currentTransition]]; - [self loadRequest:[self requestForCurrentNavigationItem]]; + [self loadRequest:request]; }; // If there is no corresponding WKBackForwardListItem, or the item is not in // the current WKWebView's back-forward list, navigating using WKWebView API // is not possible. In this case, fall back to the default navigation // mechanism. - web::WKBackForwardListItemHolder* holder = - [self currentBackForwardListItemHolder]; if (!holder->back_forward_list_item() || ![self isBackForwardListItemValid:holder->back_forward_list_item()]) { defaultNavigationBlock(); @@ -594,10 +629,8 @@ // If the request is not a form submission or resubmission, or the user // doesn't need to confirm the load, then continue right away. - web::NavigationItemImpl* currentItem = - [self currentSessionEntry].navigationItemImpl; - if ((holder->navigation_type() != WKNavigationTypeFormResubmitted && - holder->navigation_type() != WKNavigationTypeFormSubmitted) || + + if (!isFormResubmission || currentItem->ShouldSkipResubmitDataConfirmation()) { webViewNavigationBlock(); return; @@ -605,6 +638,7 @@ // If the request is form submission or resubmission, then prompt the // user before proceeding. + DCHECK(isFormResubmission); [self.delegate webController:self onFormResubmissionForRequest:nil continueBlock:webViewNavigationBlock @@ -715,6 +749,25 @@ return self.webStateImpl->GetRequestTracker()->identifier(); } +- (void)loadPOSTRequest:(NSMutableURLRequest*)request { + if (!_POSTRequestLoader) { + _POSTRequestLoader.reset([[CRWJSPOSTRequestLoader alloc] init]); + } + + CRWWKScriptMessageRouter* messageRouter = + [self webViewConfigurationProvider].GetScriptMessageRouter(); + + [_POSTRequestLoader loadPOSTRequest:request + inWebView:_wkWebView + messageRouter:messageRouter + completionHandler:^(NSError* loadError) { + if (loadError) + [self handleLoadError:loadError inMainFrame:YES]; + else + self.webStateImpl->SetContentsMimeType("text/html"); + }]; +} + - (web::WKWebViewConfigurationProvider&)webViewConfigurationProvider { DCHECK(self.webStateImpl); web::BrowserState* browserState = self.webStateImpl->GetBrowserState();
diff --git a/ipc/attachment_broker_privileged.h b/ipc/attachment_broker_privileged.h index a82d581a..023927a 100644 --- a/ipc/attachment_broker_privileged.h +++ b/ipc/attachment_broker_privileged.h
@@ -85,6 +85,11 @@ // The broker did not have a channel of communication with the source // process. ERROR_SOURCE_NOT_FOUND = 12, + // The broker could not open the source or destination process with extra + // privileges. + ERROR_COULD_NOT_OPEN_SOURCE_OR_DEST = 13, + // The broker was asked to transfer a HANDLE with invalid permissions. + ERROR_INVALID_PERMISSIONS = 14, ERROR_MAX };
diff --git a/ipc/attachment_broker_privileged_win.cc b/ipc/attachment_broker_privileged_win.cc index ec849409..38b2e652 100644 --- a/ipc/attachment_broker_privileged_win.cc +++ b/ipc/attachment_broker_privileged_win.cc
@@ -82,6 +82,7 @@ // Another process is the destination. base::ProcessId dest = wire_format.destination_process; + base::AutoLock auto_lock(*get_lock()); Sender* sender = GetSenderWithProcessId(dest); if (!sender) { // Assuming that this message was not sent from a malicious process, the @@ -101,35 +102,41 @@ AttachmentBrokerPrivilegedWin::DuplicateWinHandle( const HandleWireFormat& wire_format, base::ProcessId source_pid) { + // If the source process is the destination process, then no additional work + // is required. + if (source_pid == wire_format.destination_process) + return wire_format; + base::Process source_process = base::Process::OpenWithExtraPrivileges(source_pid); base::Process dest_process = base::Process::OpenWithExtraPrivileges(wire_format.destination_process); - int new_wire_format_handle = 0; - if (source_process.Handle() && dest_process.Handle()) { - DWORD desired_access = 0; - DWORD options = 0; - switch (wire_format.permissions) { - case HandleWin::INVALID: - LOG(ERROR) << "Received invalid permissions for duplication."; - return CopyWireFormat(wire_format, 0); - case HandleWin::DUPLICATE: - options = DUPLICATE_SAME_ACCESS; - break; - case HandleWin::FILE_READ_WRITE: - desired_access = FILE_GENERIC_READ | FILE_GENERIC_WRITE; - break; - } - - HANDLE new_handle; - HANDLE original_handle = LongToHandle(wire_format.handle); - DWORD result = ::DuplicateHandle(source_process.Handle(), original_handle, - dest_process.Handle(), &new_handle, - desired_access, FALSE, options); - - new_wire_format_handle = (result != 0) ? HandleToLong(new_handle) : 0; + if (!source_process.Handle() || !dest_process.Handle()) { + LogError(ERROR_COULD_NOT_OPEN_SOURCE_OR_DEST); + return wire_format; } + DWORD desired_access = 0; + DWORD options = DUPLICATE_CLOSE_SOURCE; + switch (wire_format.permissions) { + case HandleWin::INVALID: + LogError(ERROR_INVALID_PERMISSIONS); + return CopyWireFormat(wire_format, 0); + case HandleWin::DUPLICATE: + options |= DUPLICATE_SAME_ACCESS; + break; + case HandleWin::FILE_READ_WRITE: + desired_access = FILE_GENERIC_READ | FILE_GENERIC_WRITE; + break; + } + + HANDLE new_handle; + HANDLE original_handle = LongToHandle(wire_format.handle); + DWORD result = ::DuplicateHandle(source_process.Handle(), original_handle, + dest_process.Handle(), &new_handle, + desired_access, FALSE, options); + + int new_wire_format_handle = (result != 0) ? HandleToLong(new_handle) : 0; return CopyWireFormat(wire_format, new_wire_format_handle); }
diff --git a/ipc/attachment_broker_privileged_win_unittest.cc b/ipc/attachment_broker_privileged_win_unittest.cc index b5e1e98..583050c 100644 --- a/ipc/attachment_broker_privileged_win_unittest.cc +++ b/ipc/attachment_broker_privileged_win_unittest.cc
@@ -115,6 +115,13 @@ return success; } +// Returns 0 on error. +DWORD GetCurrentProcessHandleCount() { + DWORD handle_count = 0; + BOOL success = ::GetProcessHandleCount(::GetCurrentProcess(), &handle_count); + return success ? handle_count : 0; +} + enum TestResult { RESULT_UNKNOWN, RESULT_SUCCESS, @@ -230,9 +237,14 @@ broker_->DesignateBrokerCommunicationChannel(channel()); ASSERT_TRUE(ConnectChannel()); ASSERT_TRUE(StartClient()); + + handle_count_ = GetCurrentProcessHandleCount(); + EXPECT_NE(handle_count_, 0u); } void CommonTearDown() { + EXPECT_EQ(handle_count_, handle_count_); + // Close the channel so the client's OnChannelError() gets fired. channel()->Close(); @@ -268,6 +280,7 @@ ProxyListener proxy_listener_; scoped_ptr<IPC::AttachmentBrokerUnprivilegedWin> broker_; MockObserver observer_; + DWORD handle_count_; }; // A broker which always sets the current process as the destination process @@ -288,7 +301,7 @@ // file HANDLE is sent to the privileged process using the attachment broker. // The privileged process dups the HANDLE into its own HANDLE table. This test // checks that the file has the same contents in the privileged process. -TEST_F(IPCAttachmentBrokerPrivilegedWinTest, DISABLED_SendHandle) { +TEST_F(IPCAttachmentBrokerPrivilegedWinTest, SendHandle) { Init("SendHandle"); CommonSetUp(); @@ -310,7 +323,7 @@ // Similar to SendHandle, except the file HANDLE attached to the message has // neither read nor write permissions. TEST_F(IPCAttachmentBrokerPrivilegedWinTest, - DISABLED_SendHandleWithoutPermissions) { + SendHandleWithoutPermissions) { Init("SendHandleWithoutPermissions"); CommonSetUp(); @@ -338,7 +351,7 @@ // Similar to SendHandle, except the attachment's destination process is this // process. This is an unrealistic scenario, but simulates an unprivileged // process sending an attachment to another unprivileged process. -TEST_F(IPCAttachmentBrokerPrivilegedWinTest, DISABLED_SendHandleToSelf) { +TEST_F(IPCAttachmentBrokerPrivilegedWinTest, SendHandleToSelf) { Init("SendHandleToSelf"); set_broker(new MockBroker); @@ -358,12 +371,11 @@ get_broker()->GetAttachmentWithId(*id, &received_attachment); ASSERT_NE(received_attachment.get(), nullptr); - // Check that it's a new entry in the HANDLE table. + // Check that it's the same entry in the HANDLE table. HANDLE h2 = GetHandleFromBrokeredAttachment(received_attachment); - EXPECT_NE(h2, h); - EXPECT_NE(h2, nullptr); + EXPECT_EQ(h2, h); - // But it still points to the same file. + // And still points to the same file. std::string contents = ReadFromFile(h); EXPECT_EQ(contents, std::string(kDataBuffer)); @@ -372,7 +384,7 @@ // Similar to SendHandle, but sends a message with two instances of the same // handle. -TEST_F(IPCAttachmentBrokerPrivilegedWinTest, DISABLED_SendTwoHandles) { +TEST_F(IPCAttachmentBrokerPrivilegedWinTest, SendTwoHandles) { Init("SendTwoHandles"); CommonSetUp(); @@ -380,8 +392,12 @@ get_proxy_listener()->set_listener(&result_listener); HANDLE h = CreateTempFile(); + HANDLE h2; + BOOL result = ::DuplicateHandle(GetCurrentProcess(), h, GetCurrentProcess(), + &h2, 0, FALSE, DUPLICATE_SAME_ACCESS); + ASSERT_TRUE(result); IPC::HandleWin handle_win1(h, IPC::HandleWin::FILE_READ_WRITE); - IPC::HandleWin handle_win2(h, IPC::HandleWin::FILE_READ_WRITE); + IPC::HandleWin handle_win2(h2, IPC::HandleWin::FILE_READ_WRITE); IPC::Message* message = new TestTwoHandleWinMsg(handle_win1, handle_win2); sender()->Send(message); base::MessageLoop::current()->Run(); @@ -395,7 +411,7 @@ } // Similar to SendHandle, but sends the same message twice. -TEST_F(IPCAttachmentBrokerPrivilegedWinTest, DISABLED_SendHandleTwice) { +TEST_F(IPCAttachmentBrokerPrivilegedWinTest, SendHandleTwice) { Init("SendHandleTwice"); CommonSetUp(); @@ -403,8 +419,12 @@ get_proxy_listener()->set_listener(&result_listener); HANDLE h = CreateTempFile(); + HANDLE h2; + BOOL result = ::DuplicateHandle(GetCurrentProcess(), h, GetCurrentProcess(), + &h2, 0, FALSE, DUPLICATE_SAME_ACCESS); + ASSERT_TRUE(result); SendMessageWithAttachment(h); - SendMessageWithAttachment(h); + SendMessageWithAttachment(h2); base::MessageLoop::current()->Run(); // Check the result.
diff --git a/ipc/attachment_broker_unprivileged_win.cc b/ipc/attachment_broker_unprivileged_win.cc index 9e9e7b21..9e01d89f 100644 --- a/ipc/attachment_broker_unprivileged_win.cc +++ b/ipc/attachment_broker_unprivileged_win.cc
@@ -21,12 +21,15 @@ base::ProcessId destination_process) { switch (attachment->GetBrokerableType()) { case BrokerableAttachment::WIN_HANDLE: { - const internal::HandleAttachmentWin* handle_attachment = - static_cast<const internal::HandleAttachmentWin*>(attachment.get()); + internal::HandleAttachmentWin* handle_attachment = + static_cast<internal::HandleAttachmentWin*>(attachment.get()); internal::HandleAttachmentWin::WireFormat format = handle_attachment->GetWireFormat(destination_process); - return get_sender()->Send( + bool success = get_sender()->Send( new AttachmentBrokerMsg_DuplicateWinHandle(format)); + if (success) + handle_attachment->reset_handle_ownership(); + return success; } case BrokerableAttachment::MACH_PORT: case BrokerableAttachment::PLACEHOLDER:
diff --git a/ipc/handle_attachment_win.cc b/ipc/handle_attachment_win.cc index c14adcb8..5afd7fa 100644 --- a/ipc/handle_attachment_win.cc +++ b/ipc/handle_attachment_win.cc
@@ -11,20 +11,22 @@ HandleAttachmentWin::HandleAttachmentWin(const HANDLE& handle, HandleWin::Permissions permissions) - : handle_(handle), permissions_(permissions) {} + : handle_(handle), permissions_(permissions), owns_handle_(true) {} HandleAttachmentWin::HandleAttachmentWin(const WireFormat& wire_format) : BrokerableAttachment(wire_format.attachment_id), handle_(LongToHandle(wire_format.handle)), - permissions_(wire_format.permissions) {} + permissions_(wire_format.permissions), owns_handle_(false) {} HandleAttachmentWin::HandleAttachmentWin( const BrokerableAttachment::AttachmentId& id) : BrokerableAttachment(id), handle_(INVALID_HANDLE_VALUE), - permissions_(HandleWin::INVALID) {} + permissions_(HandleWin::INVALID), owns_handle_(false) {} HandleAttachmentWin::~HandleAttachmentWin() { + if (handle_ != INVALID_HANDLE_VALUE && owns_handle_) + ::CloseHandle(handle_); } HandleAttachmentWin::BrokerableType HandleAttachmentWin::GetBrokerableType()
diff --git a/ipc/handle_attachment_win.h b/ipc/handle_attachment_win.h index 0888085..35807b4 100644 --- a/ipc/handle_attachment_win.h +++ b/ipc/handle_attachment_win.h
@@ -41,7 +41,7 @@ // The type is int32_t instead of HANDLE because HANDLE gets typedefed to // void*, whose size varies between 32 and 64-bit processes. Using a // int32_t means that 64-bit processes will need to perform both up-casting - // and down-casting. This is performed using the appropriate Windows apis. + // and down-casting. This is performed using the appropriate Windows APIs. // A value of 0 is equivalent to an invalid handle. int32_t handle; @@ -54,7 +54,12 @@ AttachmentId attachment_id; }; + // This constructor makes a copy of |handle| and takes ownership of the + // result. Should only be called by the sender of a Chrome IPC message. HandleAttachmentWin(const HANDLE& handle, HandleWin::Permissions permissions); + + // These constructors do not take ownership of the HANDLE, and should only be + // called by the receiver of a Chrome IPC message. explicit HandleAttachmentWin(const WireFormat& wire_format); explicit HandleAttachmentWin(const BrokerableAttachment::AttachmentId& id); @@ -65,10 +70,21 @@ HANDLE get_handle() const { return handle_; } + // The caller of this method has taken ownership of |handle_|. + void reset_handle_ownership() { owns_handle_ = false; } + private: ~HandleAttachmentWin() override; HANDLE handle_; HandleWin::Permissions permissions_; + + // In the sender process, the attachment owns the HANDLE of a newly created + // message. The attachment broker will eventually take ownership, and set + // this member to |false|. + // In the destination process, the attachment never owns the Mach port. The + // client code that receives the Chrome IPC message is always expected to take + // ownership. + bool owns_handle_; }; } // namespace internal
diff --git a/ipc/handle_win.cc b/ipc/handle_win.cc index 7032114..45fbae4 100644 --- a/ipc/handle_win.cc +++ b/ipc/handle_win.cc
@@ -4,6 +4,8 @@ #include "ipc/handle_win.h" +#include <utility> + #include "base/logging.h" #include "base/memory/ref_counted.h" #include "base/strings/string_number_conversions.h" @@ -23,7 +25,7 @@ scoped_refptr<IPC::internal::HandleAttachmentWin> attachment( new IPC::internal::HandleAttachmentWin(p.get_handle(), p.get_permissions())); - if (!m->WriteAttachment(attachment.Pass())) + if (!m->WriteAttachment(std::move(attachment))) NOTREACHED(); }
diff --git a/ipc/handle_win.h b/ipc/handle_win.h index 8c640f7..38cddae 100644 --- a/ipc/handle_win.h +++ b/ipc/handle_win.h
@@ -23,6 +23,10 @@ // HandleWin is a wrapper around a Windows HANDLE that can be transported // across Chrome IPC channels that support attachment brokering. The HANDLE will // be duplicated into the destination process. +// +// The ownership semantics for the underlying |handle_| are complex. See +// ipc/mach_port_mac.h (the OSX analog of this class) for an extensive +// discussion. class IPC_EXPORT HandleWin { public: enum Permissions {
diff --git a/ipc/ipc_channel_reader_unittest.cc b/ipc/ipc_channel_reader_unittest.cc index ee29072c8..b83f08cd 100644 --- a/ipc/ipc_channel_reader_unittest.cc +++ b/ipc/ipc_channel_reader_unittest.cc
@@ -16,7 +16,7 @@ // Whether IPC::Message::FindNext() can determine message size for // partial messages. The condition is from FindNext() implementation. -#if USE_ATTACHMENT_BROKER && defined(OS_MACOSX) && !defined(OS_IOS) +#if USE_ATTACHMENT_BROKER #define MESSAGE_FINDNEXT_PARTIAL 0 #else #define MESSAGE_FINDNEXT_PARTIAL 1
diff --git a/ipc/ipc_message.cc b/ipc/ipc_message.cc index d64c8028..d51cb65 100644 --- a/ipc/ipc_message.cc +++ b/ipc/ipc_message.cc
@@ -50,7 +50,7 @@ Message::Message() : base::Pickle(sizeof(Header)) { header()->routing = header()->type = 0; header()->flags = GetRefNumUpper24(); -#if defined(OS_MACOSX) +#if USE_ATTACHMENT_BROKER header()->num_brokered_attachments = 0; #endif #if defined(OS_POSIX) @@ -66,7 +66,7 @@ header()->type = type; DCHECK((priority & 0xffffff00) == 0); header()->flags = priority | GetRefNumUpper24(); -#if defined(OS_MACOSX) +#if USE_ATTACHMENT_BROKER header()->num_brokered_attachments = 0; #endif #if defined(OS_POSIX) @@ -180,7 +180,7 @@ bool have_entire_pickle = static_cast<size_t>(range_end - range_start) >= pickle_size; -#if USE_ATTACHMENT_BROKER && defined(OS_MACOSX) && !defined(OS_IOS) +#if USE_ATTACHMENT_BROKER // TODO(dskiba): determine message_size when entire pickle is not available if (!have_entire_pickle) @@ -252,7 +252,7 @@ // keep the current descriptor as extra decoding state when deserialising. WriteInt(static_cast<int>(index)); -#if USE_ATTACHMENT_BROKER && defined(OS_MACOSX) && !defined(OS_IOS) +#if USE_ATTACHMENT_BROKER if (brokerable) header()->num_brokered_attachments++; #endif
diff --git a/ipc/ipc_message.h b/ipc/ipc_message.h index 22d1c99..cace8d37 100644 --- a/ipc/ipc_message.h +++ b/ipc/ipc_message.h
@@ -13,6 +13,7 @@ #include "base/memory/ref_counted.h" #include "base/pickle.h" #include "base/trace_event/trace_event.h" +#include "ipc/attachment_broker.h" #include "ipc/brokerable_attachment.h" #include "ipc/ipc_export.h" @@ -268,7 +269,7 @@ int32_t routing; // ID of the view that this message is destined for uint32_t type; // specifies the user-defined message type uint32_t flags; // specifies control flags for the message -#if defined(OS_MACOSX) +#if USE_ATTACHMENT_BROKER // The number of brokered attachments included with this message. The // ids of the brokered attachment ids are sent immediately after the pickled // message, before the next pickled message is sent.
diff --git a/ipc/ipc_message_unittest.cc b/ipc/ipc_message_unittest.cc index bb133e57..1bd4df3 100644 --- a/ipc/ipc_message_unittest.cc +++ b/ipc/ipc_message_unittest.cc
@@ -149,7 +149,7 @@ // (but contains the message header) IPC::Message::FindNext(data_start, data_end - 1, &next); EXPECT_FALSE(next.message_found); -#if USE_ATTACHMENT_BROKER && defined(OS_MACOSX) && !defined(OS_IOS) +#if USE_ATTACHMENT_BROKER EXPECT_EQ(next.message_size, 0u); #else EXPECT_EQ(next.message_size, message.size()); @@ -185,7 +185,7 @@ message.header()->payload_size = static_cast<uint32_t>(-1); IPC::Message::FindNext(data_start, data_end, &next); EXPECT_FALSE(next.message_found); -#if USE_ATTACHMENT_BROKER && defined(OS_MACOSX) && !defined(OS_IOS) +#if USE_ATTACHMENT_BROKER EXPECT_EQ(next.message_size, 0u); #else if (sizeof(size_t) > sizeof(uint32_t)) { @@ -203,7 +203,7 @@ message.header()->payload_size = std::numeric_limits<int32_t>::max(); IPC::Message::FindNext(data_start, data_end, &next); EXPECT_FALSE(next.message_found); -#if USE_ATTACHMENT_BROKER && defined(OS_MACOSX) && !defined(OS_IOS) +#if USE_ATTACHMENT_BROKER EXPECT_EQ(next.message_size, 0u); #else EXPECT_EQ(next.message_size,
diff --git a/mandoline/app/android/BUILD.gn b/mandoline/app/android/BUILD.gn index 59bbcb4..e5e50b0b 100644 --- a/mandoline/app/android/BUILD.gn +++ b/mandoline/app/android/BUILD.gn
@@ -6,9 +6,6 @@ import("//build/config/android/config.gni") import("//build/config/android/rules.gni") -import("//mojo/generate_mojo_shell_assets_list.gni") - -mandoline_assets_dir = "$root_build_dir/mandoline_assets" group("android") { deps = [ @@ -54,49 +51,24 @@ ] } -copy_ex("copy_mandoline_assets") { - clear_dir = true - dest = mandoline_assets_dir +android_assets("mandoline_assets") { deps = [ - "//components/devtools_service", - "//components/html_viewer", - "//components/resource_provider", - "//mandoline/services/core_services", - "//mojo/runner:bootstrap", - "//mojo/runner:bootstrap_java", - "//mojo/services/network", - ] - sources = [ - "$root_out_dir/obj/mojo/runner/bootstrap_java.dex.jar", - "$root_shlib_dir/${shlib_prefix}bootstrap$shlib_extension", - ] - - # Directories can't be specified as sources so pass manually to the script. - args = [ - "--files=" + rebase_path("$root_out_dir/core_services", root_build_dir), - "--files=" + rebase_path("$root_out_dir/network_service", root_build_dir), - "--files=" + rebase_path("$root_out_dir/resource_provider", root_build_dir), - "--files=" + rebase_path("$root_out_dir/devtools_service", root_build_dir), - "--files=" + rebase_path("$root_out_dir/html_viewer", root_build_dir), + "//components/devtools_service:devtools_service_assets", + "//components/html_viewer:html_viewer_assets", + "//components/resource_provider:resource_provider_assets", + "//mandoline/services/core_services:core_services_assets", + "//mojo/runner:android_assets", + "//mojo/services/network:network_assets", ] if (use_aura) { - deps += [ "//mandoline/ui" ] - - args += [ - "--files=" + rebase_path("$root_out_dir/omnibox", root_build_dir), - "--files=" + rebase_path("$root_out_dir/phone_ui", root_build_dir), + deps += [ + "//mandoline/ui/desktop_ui:desktop_ui_assets", + "//mandoline/ui/omnibox:omnibox_assets", ] } } -generate_mojo_shell_assets_list("build_mandoline_assets") { - deps = [ - ":copy_mandoline_assets", - ] - dir = mandoline_assets_dir -} - android_library("java") { java_files = [ "apk/src/org/chromium/mandoline/MandolineActivity.java" ] @@ -122,16 +94,14 @@ apk_name = "Mandoline" android_manifest = "apk/AndroidManifest.xml" - native_libs = [ "${shlib_prefix}mandoline_runner$shlib_extension" ] - - asset_location = mandoline_assets_dir + write_asset_list = true deps = [ - ":build_mandoline_assets", ":copy_mandoline_runner", ":java", ":mandoline_apk_resources", + ":mandoline_assets", "//base:base_java", "//mojo/runner:java", "//mojo/runner:resources",
diff --git a/mash/BUILD.gn b/mash/BUILD.gn index 060bdc6..461ff4c 100644 --- a/mash/BUILD.gn +++ b/mash/BUILD.gn
@@ -9,8 +9,16 @@ testonly = true deps = [ - ":mash_unittests", + ":tests", "//mash/example", + ] +} + +group("tests") { + testonly = true + + deps = [ + ":mash_unittests", "//mash/wm:tests", ] }
diff --git a/mash/browser_driver/BUILD.gn b/mash/browser_driver/BUILD.gn new file mode 100644 index 0000000..a585925 --- /dev/null +++ b/mash/browser_driver/BUILD.gn
@@ -0,0 +1,25 @@ +# 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. + +import("//build/config/ui.gni") +import("//mojo/public/mojo_application.gni") +import("//mojo/public/tools/bindings/mojom.gni") +import("//tools/grit/repack.gni") + +mojo_native_application("browser_driver") { + sources = [ + "browser_driver_application_delegate.cc", + "browser_driver_application_delegate.h", + "main.cc", + ] + + deps = [ + "//base", + "//components/mus/public/cpp", + "//components/mus/public/interfaces", + "//mojo/application/public/cpp", + "//mojo/application/public/cpp:sources", + "//mojo/public/cpp/bindings", + ] +}
diff --git a/mash/browser_driver/browser_driver_application_delegate.cc b/mash/browser_driver/browser_driver_application_delegate.cc new file mode 100644 index 0000000..b5d95f50 --- /dev/null +++ b/mash/browser_driver/browser_driver_application_delegate.cc
@@ -0,0 +1,103 @@ +// 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. + +#include "mash/browser_driver/browser_driver_application_delegate.h" + +#include "base/bind.h" +#include "components/mus/public/cpp/event_matcher.h" +#include "mojo/application/public/cpp/application_connection.h" +#include "mojo/application/public/cpp/application_impl.h" + +namespace mash { +namespace browser_driver { +namespace { + +enum class Accelerator : uint32_t { + NewWindow, + NewTab, + NewIncognitoWindow, +}; + +struct AcceleratorSpec { + Accelerator id; + mus::mojom::KeyboardCode keyboard_code; + mus::mojom::EventFlags event_flags; +}; + +AcceleratorSpec g_spec[] = { + { Accelerator::NewWindow, + mus::mojom::KEYBOARD_CODE_N, + mus::mojom::EVENT_FLAGS_CONTROL_DOWN }, + { Accelerator::NewTab, + mus::mojom::KEYBOARD_CODE_T, + mus::mojom::EVENT_FLAGS_CONTROL_DOWN }, + { Accelerator::NewIncognitoWindow, + mus::mojom::KEYBOARD_CODE_N, + static_cast<mus::mojom::EventFlags>(mus::mojom::EVENT_FLAGS_CONTROL_DOWN | + mus::mojom::EVENT_FLAGS_SHIFT_DOWN) }, +}; + +void AssertTrue(bool success) { + DCHECK(success); +} + +} // namespace + +BrowserDriverApplicationDelegate::BrowserDriverApplicationDelegate() + : app_(nullptr), + binding_(this) {} + +BrowserDriverApplicationDelegate::~BrowserDriverApplicationDelegate() {} + +void BrowserDriverApplicationDelegate::Initialize(mojo::ApplicationImpl* app) { + app_ = app; + AddAccelerators(); +} + +bool BrowserDriverApplicationDelegate::ConfigureIncomingConnection( + mojo::ApplicationConnection* connection) { + return false; +} + +void BrowserDriverApplicationDelegate::OnAccelerator( + uint32_t id, mus::mojom::EventPtr event) { + switch (static_cast<Accelerator>(id)) { + case Accelerator::NewWindow: + case Accelerator::NewTab: + case Accelerator::NewIncognitoWindow: + app_->ConnectToApplication("exe:chrome"); + // TODO(beng): have Chrome export a service that allows it to be driven by + // this driver, e.g. to open new tabs, incognito windows, etc. + break; + default: + NOTREACHED(); + break; + } +} + +void BrowserDriverApplicationDelegate::AddAccelerators() { + // TODO(beng): find some other way to get the window manager. I don't like + // having to specify it by URL because it may differ per display. + mus::mojom::AcceleratorRegistrarPtr registrar; + app_->ConnectToService("mojo:desktop_wm", ®istrar); + + mus::mojom::AcceleratorHandlerPtr handler; + binding_.Bind(GetProxy(&handler)); + // If the window manager restarts, the handler pipe will close and we'll need + // to re-add our accelerators when the window manager comes back up. + binding_.set_connection_error_handler( + base::Bind(&BrowserDriverApplicationDelegate::AddAccelerators, + base::Unretained(this))); + registrar->SetHandler(std::move(handler)); + + for (const AcceleratorSpec& spec : g_spec) { + registrar->AddAccelerator( + static_cast<uint32_t>(spec.id), + mus::CreateKeyMatcher(spec.keyboard_code, spec.event_flags), + base::Bind(&AssertTrue)); + } +} + +} // namespace browser_driver +} // namespace main
diff --git a/mash/browser_driver/browser_driver_application_delegate.h b/mash/browser_driver/browser_driver_application_delegate.h new file mode 100644 index 0000000..df2a4b61 --- /dev/null +++ b/mash/browser_driver/browser_driver_application_delegate.h
@@ -0,0 +1,50 @@ +// 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. + +#ifndef MASH_BROWSER_DRIVER_BROWSER_DRIVER_APPLICATION_DELEGATE_H_ +#define MASH_BROWSER_DRIVER_BROWSER_DRIVER_APPLICATION_DELEGATE_H_ + +#include <map> + +#include "base/callback.h" +#include "base/macros.h" +#include "base/memory/scoped_ptr.h" +#include "components/mus/public/interfaces/accelerator_registrar.mojom.h" +#include "mojo/application/public/cpp/application_delegate.h" +#include "mojo/public/cpp/bindings/binding.h" + +namespace mojo { +class ApplicationConnection; +} + +namespace mash { +namespace browser_driver { + +class BrowserDriverApplicationDelegate : public mojo::ApplicationDelegate, + public mus::mojom::AcceleratorHandler { + public: + BrowserDriverApplicationDelegate(); + ~BrowserDriverApplicationDelegate() override; + + private: + // mojo::ApplicationDelegate: + void Initialize(mojo::ApplicationImpl* app) override; + bool ConfigureIncomingConnection( + mojo::ApplicationConnection* connection) override; + + // mus::mojom::AcceleratorHandler: + void OnAccelerator(uint32_t id, mus::mojom::EventPtr event) override; + + void AddAccelerators(); + + mojo::ApplicationImpl* app_; + mojo::Binding<mus::mojom::AcceleratorHandler> binding_; + + DISALLOW_COPY_AND_ASSIGN(BrowserDriverApplicationDelegate); +}; + +} // namespace browser_driver +} // namespace mash + +#endif // MASH_BROWSER_DRIVER_BROWSER_DRIVER_APPLICATION_DELEGATE_H_
diff --git a/mash/browser_driver/main.cc b/mash/browser_driver/main.cc new file mode 100644 index 0000000..514178cd --- /dev/null +++ b/mash/browser_driver/main.cc
@@ -0,0 +1,13 @@ +// 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. + +#include "mash/browser_driver/browser_driver_application_delegate.h" +#include "mojo/application/public/cpp/application_runner.h" +#include "mojo/public/c/system/main.h" + +MojoResult MojoMain(MojoHandle shell_handle) { + mojo::ApplicationRunner runner( + new mash::browser_driver::BrowserDriverApplicationDelegate); + return runner.Run(shell_handle); +}
diff --git a/mash/example/main/main_application_delegate.cc b/mash/example/main/main_application_delegate.cc index 3fc15ce4..da992b7 100644 --- a/mash/example/main/main_application_delegate.cc +++ b/mash/example/main/main_application_delegate.cc
@@ -16,7 +16,6 @@ connections_.push_back(app->ConnectToApplication("mojo:views_examples")); connections_.push_back( app->ConnectToApplication("exe:window_type_launcher_exe")); - connections_.push_back(app->ConnectToApplication("exe:chrome")); } bool MainApplicationDelegate::ConfigureIncomingConnection(
diff --git a/mash/shell/BUILD.gn b/mash/shell/BUILD.gn index d1ef272..6e629ba 100644 --- a/mash/shell/BUILD.gn +++ b/mash/shell/BUILD.gn
@@ -24,6 +24,7 @@ ] data_deps = [ + "//mash/browser_driver", "//mash/system_ui", "//mash/wm", ]
diff --git a/mash/shell/shell_application_delegate.cc b/mash/shell/shell_application_delegate.cc index 702adc4a..a958446 100644 --- a/mash/shell/shell_application_delegate.cc +++ b/mash/shell/shell_application_delegate.cc
@@ -17,6 +17,7 @@ void ShellApplicationDelegate::Initialize(mojo::ApplicationImpl* app) { app_ = app; + StartBrowserDriver(); StartWindowManager(); StartSystemUI(); } @@ -39,6 +40,13 @@ base::Unretained(this))); } +void ShellApplicationDelegate::StartBrowserDriver() { + StartRestartableService( + "mojo:browser_driver", + base::Bind(&ShellApplicationDelegate::StartBrowserDriver, + base::Unretained(this))); +} + void ShellApplicationDelegate::StartRestartableService( const std::string& url, const base::Closure& restart_callback) {
diff --git a/mash/shell/shell_application_delegate.h b/mash/shell/shell_application_delegate.h index 471f4a1..3bec26c 100644 --- a/mash/shell/shell_application_delegate.h +++ b/mash/shell/shell_application_delegate.h
@@ -32,6 +32,7 @@ void StartWindowManager(); void StartSystemUI(); + void StartBrowserDriver(); // Starts the application at |url|, running |restart_callback| if the // connection to the application is closed.
diff --git a/mash/wm/BUILD.gn b/mash/wm/BUILD.gn index 743307d..83e4296 100644 --- a/mash/wm/BUILD.gn +++ b/mash/wm/BUILD.gn
@@ -46,6 +46,8 @@ "property_util.h", "shadow.cc", "shadow.h", + "shadow_controller.cc", + "shadow_controller.h", "shelf_layout.cc", "shelf_layout.h", "window_layout.cc",
diff --git a/mash/wm/frame/non_client_frame_view_mash.cc b/mash/wm/frame/non_client_frame_view_mash.cc index 17af114e3..76cb630a 100644 --- a/mash/wm/frame/non_client_frame_view_mash.cc +++ b/mash/wm/frame/non_client_frame_view_mash.cc
@@ -292,7 +292,12 @@ void NonClientFrameViewMash::OnWindowClientAreaChanged( mus::Window* window, - const gfx::Insets& old_client_area) { + const gfx::Insets& old_client_area, + const std::vector<gfx::Rect>& old_additional_client_area) { + // Only the insets effect the rendering. + if (old_client_area == window->client_area()) + return; + Layout(); // NonClientView (our parent) positions the client view based on bounds from // us. We need to layout from parent to trigger a layout of the client view.
diff --git a/mash/wm/frame/non_client_frame_view_mash.h b/mash/wm/frame/non_client_frame_view_mash.h index f87ef2e6..e39f44d 100644 --- a/mash/wm/frame/non_client_frame_view_mash.h +++ b/mash/wm/frame/non_client_frame_view_mash.h
@@ -66,8 +66,10 @@ void PaintChildren(const ui::PaintContext& context) override; // mus::WindowObserver: - void OnWindowClientAreaChanged(mus::Window* window, - const gfx::Insets& old_client_area) override; + void OnWindowClientAreaChanged( + mus::Window* window, + const gfx::Insets& old_client_area, + const std::vector<gfx::Rect>& old_additional_client_area) override; void OnWindowDestroyed(mus::Window* window) override; // Get the view of the header.
diff --git a/mash/wm/non_client_frame_controller.cc b/mash/wm/non_client_frame_controller.cc index 4cd4027..ca8e9a63 100644 --- a/mash/wm/non_client_frame_controller.cc +++ b/mash/wm/non_client_frame_controller.cc
@@ -117,7 +117,8 @@ aura::WindowTreeHost* window_tree_host = GetNativeView()->GetHost(); // TODO(sky): shadow should be determined by window type. shadow_.reset(new Shadow); - shadow_->Init(Shadow::STYLE_ACTIVE); + shadow_->Init(Shadow::STYLE_INACTIVE); + SetShadow(window(), shadow_.get()); ContentWindowLayoutManager* layout_manager = new ContentWindowLayoutManager( window_tree_host->window(), ShadowStyle::NORMAL, shadow_.get()); window_tree_host->window()->SetLayoutManager(layout_manager);
diff --git a/mash/wm/property_util.cc b/mash/wm/property_util.cc index f08cf7a5..6295cd00 100644 --- a/mash/wm/property_util.cc +++ b/mash/wm/property_util.cc
@@ -7,11 +7,17 @@ #include "components/mus/public/cpp/property_type_converters.h" #include "components/mus/public/cpp/window.h" #include "components/mus/public/cpp/window_property.h" +#include "mash/wm/shadow.h" #include "ui/gfx/geometry/rect.h" #include "ui/gfx/geometry/size.h" namespace mash { namespace wm { +namespace { + +DEFINE_LOCAL_WINDOW_PROPERTY_KEY(Shadow*, kLocalShadowProperty, nullptr); + +} // namespace mus::mojom::ShowState GetWindowShowState(const mus::Window* window) { if (window->HasSharedProperty( @@ -88,5 +94,13 @@ return gfx::Rect(); } +void SetShadow(mus::Window* window, Shadow* shadow) { + window->SetLocalProperty(kLocalShadowProperty, shadow); +} + +Shadow* GetShadow(mus::Window* window) { + return window->GetLocalProperty(kLocalShadowProperty); +} + } // namespace wm } // namespace mash
diff --git a/mash/wm/property_util.h b/mash/wm/property_util.h index 104e870..4e7616b 100644 --- a/mash/wm/property_util.h +++ b/mash/wm/property_util.h
@@ -21,6 +21,8 @@ namespace mash { namespace wm { +class Shadow; + // Utility functions to read values from properties & convert them to the // appropriate types. @@ -39,6 +41,9 @@ void SetRestoreBounds(mus::Window* window, const gfx::Rect& bounds); gfx::Rect GetRestoreBounds(const mus::Window* window); +void SetShadow(mus::Window* window, Shadow* shadow); +Shadow* GetShadow(mus::Window* window); + } // namespace wm } // namespace mash
diff --git a/mash/wm/shadow_controller.cc b/mash/wm/shadow_controller.cc new file mode 100644 index 0000000..b7f91f1 --- /dev/null +++ b/mash/wm/shadow_controller.cc
@@ -0,0 +1,66 @@ +// 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. + +#include "mash/wm/shadow_controller.h" + +#include "components/mus/public/cpp/window.h" +#include "components/mus/public/cpp/window_tree_connection.h" +#include "mash/wm/property_util.h" +#include "mash/wm/shadow.h" + +namespace mash { +namespace wm { +namespace { + +// Returns the first ancestor of |from| (including |from|) that has a shadow. +mus::Window* FindAncestorWithShadow(mus::Window* from) { + mus::Window* result = from; + while (result && !GetShadow(result)) + result = result->parent(); + // Small shadows never change. + return result && GetShadow(result)->style() != Shadow::STYLE_SMALL ? result + : nullptr; +} + +} // namespace + +ShadowController::ShadowController(mus::WindowTreeConnection* window_tree) + : window_tree_(window_tree), active_window_(nullptr) { + window_tree_->AddObserver(this); + SetActiveWindow(FindAncestorWithShadow(window_tree_->GetFocusedWindow())); +} + +ShadowController::~ShadowController() { + window_tree_->RemoveObserver(this); + if (active_window_) + active_window_->RemoveObserver(this); +} + +void ShadowController::SetActiveWindow(mus::Window* window) { + if (window == active_window_) + return; + + if (active_window_) { + GetShadow(active_window_)->SetStyle(Shadow::STYLE_INACTIVE); + active_window_->RemoveObserver(this); + } + active_window_ = window; + if (active_window_) { + GetShadow(active_window_)->SetStyle(Shadow::STYLE_ACTIVE); + active_window_->AddObserver(this); + } +} + +void ShadowController::OnWindowTreeFocusChanged(mus::Window* gained_focus, + mus::Window* lost_focus) { + SetActiveWindow(FindAncestorWithShadow(gained_focus)); +} + +void ShadowController::OnWindowDestroying(mus::Window* window) { + DCHECK_EQ(window, active_window_); + SetActiveWindow(nullptr); +} + +} // namespace wm +} // namespace mash
diff --git a/mash/wm/shadow_controller.h b/mash/wm/shadow_controller.h new file mode 100644 index 0000000..cc11f4f --- /dev/null +++ b/mash/wm/shadow_controller.h
@@ -0,0 +1,44 @@ +// 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. + +#ifndef MASH_WM_SHADOW_CONTROLLER_H_ +#define MASH_WM_SHADOW_CONTROLLER_H_ + +#include "base/basictypes.h" +#include "components/mus/public/cpp/window_observer.h" +#include "components/mus/public/cpp/window_tree_connection_observer.h" + +namespace mus { +class WindowTreeConnection; +} + +namespace mash { +namespace wm { + +class ShadowController : public mus::WindowTreeConnectionObserver, + public mus::WindowObserver { + public: + explicit ShadowController(mus::WindowTreeConnection* window_tree); + ~ShadowController() override; + + private: + void SetActiveWindow(mus::Window* window); + + // mus::WindowTreeConnectionObserver: + void OnWindowTreeFocusChanged(mus::Window* gained_focus, + mus::Window* lost_focus) override; + + // mus::WindowObserver: + void OnWindowDestroying(mus::Window* window) override; + + mus::WindowTreeConnection* window_tree_; + mus::Window* active_window_; + + DISALLOW_COPY_AND_ASSIGN(ShadowController); +}; + +} // namespace wm +} // namespace mash + +#endif // MASH_WM_SHADOW_CONTROLLER_H_
diff --git a/mash/wm/window_manager_application.cc b/mash/wm/window_manager_application.cc index 3a211d5..ad0d4c6 100644 --- a/mash/wm/window_manager_application.cc +++ b/mash/wm/window_manager_application.cc
@@ -12,6 +12,7 @@ #include "components/mus/public/cpp/window_tree_host_factory.h" #include "mash/wm/accelerator_registrar_impl.h" #include "mash/wm/background_layout.h" +#include "mash/wm/shadow_controller.h" #include "mash/wm/shelf_layout.h" #include "mash/wm/window_layout.h" #include "mash/wm/window_manager_impl.h" @@ -130,12 +131,15 @@ for (auto request : requests_) window_manager_binding_.AddBinding(window_manager_.get(), request->Pass()); requests_.clear(); + + shadow_controller_.reset(new ShadowController(root->connection())); } void WindowManagerApplication::OnConnectionLost( mus::WindowTreeConnection* connection) { // TODO(sky): shutdown. NOTIMPLEMENTED(); + shadow_controller_.reset(); } void WindowManagerApplication::Create(
diff --git a/mash/wm/window_manager_application.h b/mash/wm/window_manager_application.h index 45916ea..7253d22 100644 --- a/mash/wm/window_manager_application.h +++ b/mash/wm/window_manager_application.h
@@ -37,6 +37,7 @@ class AcceleratorRegistrarImpl; class BackgroundLayout; +class ShadowController; class ShelfLayout; class WindowLayout; class WindowManagerImpl; @@ -123,6 +124,8 @@ scoped_ptr<ShelfLayout> shelf_layout_; scoped_ptr<WindowLayout> window_layout_; + scoped_ptr<ShadowController> shadow_controller_; + std::set<AcceleratorRegistrarImpl*> accelerator_registrars_; DISALLOW_COPY_AND_ASSIGN(WindowManagerApplication);
diff --git a/mash/wm/window_manager_apptest.cc b/mash/wm/window_manager_apptest.cc index 5e235fc..079af7b 100644 --- a/mash/wm/window_manager_apptest.cc +++ b/mash/wm/window_manager_apptest.cc
@@ -46,7 +46,8 @@ DISALLOW_COPY_AND_ASSIGN(WindowManagerAppTest); }; -TEST_F(WindowManagerAppTest, OpenWindow) { +// TODO(sky): flakey, http://crbug.com/559412 . +TEST_F(WindowManagerAppTest, DISABLED_OpenWindow) { mus::mojom::WindowManagerPtr connection; ConnectToWindowManager(&connection);
diff --git a/media/audio/audio_device_thread.cc b/media/audio/audio_device_thread.cc index 94472939..81dab87 100644 --- a/media/audio/audio_device_thread.cc +++ b/media/audio/audio_device_thread.cc
@@ -4,7 +4,10 @@ #include "media/audio/audio_device_thread.h" +#include <stdint.h> + #include <algorithm> +#include <limits> #include "base/bind.h" #include "base/logging.h" @@ -163,21 +166,22 @@ } void AudioDeviceThread::Thread::Run() { - uint32 buffer_index = 0; + uint32_t buffer_index = 0; while (true) { - uint32 pending_data = 0; + uint32_t pending_data = 0; size_t bytes_read = socket_.Receive(&pending_data, sizeof(pending_data)); if (bytes_read != sizeof(pending_data)) break; - // kuint32max is a special signal which is returned after the browser - // stops the output device in response to a renderer side request. + // std::numeric_limits<uint32_t>::max() is a special signal which is + // returned after the browser stops the output device in response to a + // renderer side request. // // Avoid running Process() for the paused signal, we still need to update // the buffer index if |synchronized_buffers_| is true though. // // See comments in AudioOutputController::DoPause() for details on why. - if (pending_data != kuint32max) { + if (pending_data != std::numeric_limits<uint32_t>::max()) { base::AutoLock auto_lock(callback_lock_); if (callback_) callback_->Process(pending_data);
diff --git a/media/audio/audio_device_thread.h b/media/audio/audio_device_thread.h index 1f63c21d..7e8e2bf 100644 --- a/media/audio/audio_device_thread.h +++ b/media/audio/audio_device_thread.h
@@ -5,7 +5,7 @@ #ifndef MEDIA_AUDIO_AUDIO_DEVICE_THREAD_H_ #define MEDIA_AUDIO_AUDIO_DEVICE_THREAD_H_ -#include "base/basictypes.h" +#include "base/macros.h" #include "base/memory/ref_counted.h" #include "base/memory/scoped_ptr.h" #include "base/memory/shared_memory.h"
diff --git a/media/audio/audio_output_controller.cc b/media/audio/audio_output_controller.cc index 8aa2b4f..f092496 100644 --- a/media/audio/audio_output_controller.cc +++ b/media/audio/audio_output_controller.cc
@@ -4,6 +4,10 @@ #include "media/audio/audio_output_controller.h" +#include <stdint.h> + +#include <limits> + #include "base/bind.h" #include "base/metrics/histogram_macros.h" #include "base/numerics/safe_conversions.h" @@ -213,7 +217,7 @@ // Let the renderer know we've stopped. Necessary to let PPAPI clients know // audio has been shutdown. TODO(dalecurtis): This stinks. PPAPI should have // a better way to know when it should exit PPB_Audio_Shared::Run(). - sync_reader_->UpdatePendingBytes(kuint32max); + sync_reader_->UpdatePendingBytes(std::numeric_limits<uint32_t>::max()); handler_->OnPaused(); } @@ -280,7 +284,7 @@ } int AudioOutputController::OnMoreData(AudioBus* dest, - uint32 total_bytes_delay) { + uint32_t total_bytes_delay) { TRACE_EVENT0("audio", "AudioOutputController::OnMoreData"); // Indicate that we haven't wedged (at least not indefinitely, WedgeCheck() @@ -293,7 +297,7 @@ sync_reader_->Read(dest); const int frames = dest->frames(); - sync_reader_->UpdatePendingBytes(base::saturated_cast<uint32>( + sync_reader_->UpdatePendingBytes(base::saturated_cast<uint32_t>( total_bytes_delay + frames * params_.GetBytesPerFrame())); if (will_monitor_audio_levels())
diff --git a/media/base/demuxer.h b/media/base/demuxer.h index 2324c87..1f136a0c 100644 --- a/media/base/demuxer.h +++ b/media/base/demuxer.h
@@ -87,8 +87,7 @@ // a null Time is returned. virtual base::Time GetTimelineOffset() const = 0; - // Returns the memory usage in bytes for the demuxer. May be called from any - // thread. + // Returns the memory usage in bytes for the demuxer. virtual int64_t GetMemoryUsage() const = 0; private:
diff --git a/media/base/video_types.cc b/media/base/video_types.cc index b6b041e..e2f137d 100644 --- a/media/base/video_types.cc +++ b/media/base/video_types.cc
@@ -72,4 +72,28 @@ return false; } +bool IsOpaque(VideoPixelFormat format) { + switch (format) { + case PIXEL_FORMAT_UNKNOWN: + case PIXEL_FORMAT_I420: + case PIXEL_FORMAT_YV12: + case PIXEL_FORMAT_YV16: + case PIXEL_FORMAT_YV24: + case PIXEL_FORMAT_NV12: + case PIXEL_FORMAT_NV21: + case PIXEL_FORMAT_UYVY: + case PIXEL_FORMAT_YUY2: + case PIXEL_FORMAT_XRGB: + case PIXEL_FORMAT_RGB24: + case PIXEL_FORMAT_MJPEG: + case PIXEL_FORMAT_MT21: + return true; + case PIXEL_FORMAT_YV12A: + case PIXEL_FORMAT_ARGB: + case PIXEL_FORMAT_RGB32: + break; + } + return false; +} + } // namespace media
diff --git a/media/base/video_types.h b/media/base/video_types.h index b40dfb4..7cf196e6 100644 --- a/media/base/video_types.h +++ b/media/base/video_types.h
@@ -69,6 +69,9 @@ // Returns true if |format| is a YUV format with multiple planes. MEDIA_EXPORT bool IsYuvPlanar(VideoPixelFormat format); +// Returns true if |format| has no Alpha channel (hence is always opaque). +MEDIA_EXPORT bool IsOpaque(VideoPixelFormat format); + } // namespace media #endif // MEDIA_BASE_VIDEO_TYPES_H_
diff --git a/media/blink/video_frame_compositor.cc b/media/blink/video_frame_compositor.cc index 073ec97..4c43c505 100644 --- a/media/blink/video_frame_compositor.cc +++ b/media/blink/video_frame_compositor.cc
@@ -16,31 +16,6 @@ // background rendering to keep the Render() callbacks moving. const int kBackgroundRenderingTimeoutMs = 250; -// Returns true if the format has no Alpha channel (hence is always opaque). -static bool IsOpaque(const scoped_refptr<VideoFrame>& frame) { - switch (frame->format()) { - case PIXEL_FORMAT_UNKNOWN: - case PIXEL_FORMAT_I420: - case PIXEL_FORMAT_YV12: - case PIXEL_FORMAT_YV16: - case PIXEL_FORMAT_YV24: - case PIXEL_FORMAT_NV12: - case PIXEL_FORMAT_NV21: - case PIXEL_FORMAT_UYVY: - case PIXEL_FORMAT_YUY2: - case PIXEL_FORMAT_XRGB: - case PIXEL_FORMAT_RGB24: - case PIXEL_FORMAT_MJPEG: - case PIXEL_FORMAT_MT21: - return true; - case PIXEL_FORMAT_YV12A: - case PIXEL_FORMAT_ARGB: - case PIXEL_FORMAT_RGB32: - break; - } - return false; -} - VideoFrameCompositor::VideoFrameCompositor( const scoped_refptr<base::SingleThreadTaskRunner>& compositor_task_runner, const base::Callback<void(gfx::Size)>& natural_size_changed_cb, @@ -213,8 +188,9 @@ natural_size_changed_cb_.Run(frame->natural_size()); } - if (!current_frame_ || IsOpaque(current_frame_) != IsOpaque(frame)) - opacity_changed_cb_.Run(IsOpaque(frame)); + if (!current_frame_ || + IsOpaque(current_frame_->format()) != IsOpaque(frame->format())) + opacity_changed_cb_.Run(IsOpaque(frame->format())); current_frame_ = frame; return true;
diff --git a/media/capture/webm_muxer.cc b/media/capture/webm_muxer.cc index 939cb397..3976c0f 100644 --- a/media/capture/webm_muxer.cc +++ b/media/capture/webm_muxer.cc
@@ -19,7 +19,7 @@ // See https://wiki.xiph.org/OggOpus#ID_Header. // Set magic signature. std::string label = "OpusHead"; - memcpy(header + OPUS_EXTRADATA_LABEL_OFFSET, &label, label.size()); + memcpy(header + OPUS_EXTRADATA_LABEL_OFFSET, label.c_str(), label.size()); // Set Opus version. header[OPUS_EXTRADATA_VERSION_OFFSET] = 1; // Set channel count. @@ -126,16 +126,20 @@ // http://crbug.com/528523 if (has_audio_ && !audio_track_index_) { DVLOG(1) << __FUNCTION__ << ": delaying until audio track ready."; + if (is_key_frame) { + most_recent_encoded_video_keyframe_ = std::move(encoded_data); + saved_keyframe_timestamp_ = timestamp; + } return; } - most_recent_timestamp_ = - std::max(most_recent_timestamp_, timestamp - first_frame_timestamp_); - segment_.AddFrame(reinterpret_cast<const uint8_t*>(encoded_data->data()), - encoded_data->size(), video_track_index_, - most_recent_timestamp_.InMicroseconds() * - base::Time::kNanosecondsPerMicrosecond, - is_key_frame); + // If have a saved keyframe, add it first. + if (most_recent_encoded_video_keyframe_.get()) + AddFrame(std::move(most_recent_encoded_video_keyframe_), video_track_index_, + saved_keyframe_timestamp_, true /* is_key_frame */); + + AddFrame(std::move(encoded_data), video_track_index_, timestamp, + is_key_frame); } void WebmMuxer::OnEncodedAudio(const media::AudioParameters& params, @@ -158,13 +162,13 @@ return; } - most_recent_timestamp_ = - std::max(most_recent_timestamp_, timestamp - first_frame_timestamp_); - segment_.AddFrame(reinterpret_cast<const uint8_t*>(encoded_data->data()), - encoded_data->size(), audio_track_index_, - most_recent_timestamp_.InMicroseconds() * - base::Time::kNanosecondsPerMicrosecond, - true /* is_key_frame -- always true for audio */); + // If have a saved keyframe, add it first. + if (most_recent_encoded_video_keyframe_.get()) + AddFrame(std::move(most_recent_encoded_video_keyframe_), video_track_index_, + saved_keyframe_timestamp_, true /* is_key_frame */); + + AddFrame(std::move(encoded_data), audio_track_index_, timestamp, + true /* is_key_frame -- always true for audio */); } void WebmMuxer::AddVideoTrack(const gfx::Size& frame_size, double frame_rate) { @@ -253,4 +257,22 @@ << "Can't go back in a live WebM stream."; } +void WebmMuxer::AddFrame(scoped_ptr<std::string> encoded_data, + uint8_t track_index, + base::TimeTicks timestamp, + bool is_key_frame) { + DCHECK(thread_checker_.CalledOnValidThread()); + DCHECK(!has_video_ || video_track_index_); + DCHECK(!has_audio_ || audio_track_index_); + + most_recent_timestamp_ = + std::max(most_recent_timestamp_, timestamp - first_frame_timestamp_); + + segment_.AddFrame(reinterpret_cast<const uint8_t*>(encoded_data->data()), + encoded_data->size(), track_index, + most_recent_timestamp_.InMicroseconds() * + base::Time::kNanosecondsPerMicrosecond, + is_key_frame); +} + } // namespace media
diff --git a/media/capture/webm_muxer.h b/media/capture/webm_muxer.h index f5171b8..9a4287f 100644 --- a/media/capture/webm_muxer.h +++ b/media/capture/webm_muxer.h
@@ -77,6 +77,12 @@ void ElementStartNotify(mkvmuxer::uint64 element_id, mkvmuxer::int64 position) override; + // Helper to simplify saving frames. + void AddFrame(scoped_ptr<std::string> encoded_data, + uint8_t track_index, + base::TimeTicks timestamp, + bool is_key_frame); + // Used to DCHECK that we are called on the correct thread. base::ThreadChecker thread_checker_; @@ -106,6 +112,10 @@ // The MkvMuxer active element. mkvmuxer::Segment segment_; + // Save the most recent video keyframe if we're waiting for audio to come in. + scoped_ptr<std::string> most_recent_encoded_video_keyframe_; + base::TimeTicks saved_keyframe_timestamp_; + DISALLOW_COPY_AND_ASSIGN(WebmMuxer); };
diff --git a/media/capture/webm_muxer_unittest.cc b/media/capture/webm_muxer_unittest.cc index 8b45e1df..a0754b58 100644 --- a/media/capture/webm_muxer_unittest.cc +++ b/media/capture/webm_muxer_unittest.cc
@@ -15,8 +15,14 @@ #include "testing/gtest/include/gtest/gtest.h" using ::testing::_; +using ::testing::AllOf; +using ::testing::AnyNumber; using ::testing::AtLeast; +using ::testing::Eq; +using ::testing::InSequence; using ::testing::Mock; +using ::testing::Not; +using ::testing::Sequence; using ::testing::TestWithParam; using ::testing::ValuesIn; using ::testing::WithArgs; @@ -87,7 +93,7 @@ // This test sends two frames and checks that the WriteCallback is called with // appropriate params in both cases. TEST_P(WebmMuxerTest, OnEncodedVideoTwoFrames) { - if (GetParam().num_video_tracks == 0) + if (GetParam().num_audio_tracks > 0) return; const gfx::Size frame_size(160, 80); @@ -97,8 +103,8 @@ EXPECT_CALL(*this, WriteCallback(_)) .Times(AtLeast(1)) - .WillRepeatedly(WithArgs<0>( - Invoke(this, &WebmMuxerTest::SaveEncodedDataLen))); + .WillRepeatedly( + WithArgs<0>(Invoke(this, &WebmMuxerTest::SaveEncodedDataLen))); webm_muxer_.OnEncodedVideo(video_frame, make_scoped_ptr(new std::string(encoded_data)), base::TimeTicks::Now(), @@ -114,8 +120,8 @@ const int64_t begin_of_second_block = accumulated_position_; EXPECT_CALL(*this, WriteCallback(_)) .Times(AtLeast(1)) - .WillRepeatedly(WithArgs<0>( - Invoke(this, &WebmMuxerTest::SaveEncodedDataLen))); + .WillRepeatedly( + WithArgs<0>(Invoke(this, &WebmMuxerTest::SaveEncodedDataLen))); webm_muxer_.OnEncodedVideo(video_frame, make_scoped_ptr(new std::string(encoded_data)), base::TimeTicks::Now(), @@ -132,7 +138,7 @@ } TEST_P(WebmMuxerTest, OnEncodedAudioTwoFrames) { - if (GetParam().num_audio_tracks == 0) + if (GetParam().num_video_tracks > 0) return; int sample_rate = 48000; @@ -179,11 +185,59 @@ accumulated_position_); } +// Currently, when WebmMuxer is told it will have both audio and video tracks, +// it drops data until it's receiving data for _both_ tracks, to avoid issues +// related to writing the webm header. +// This test verifies that when video data comes before audio data, we save the +// most recent video keyframe and add it to the video track as soon as audio +// data comes. +TEST_P(WebmMuxerTest, VideoKeyframeIsSaved) { + // This test is only relevant if we have both kinds of tracks. + if (GetParam().num_video_tracks == 0 || GetParam().num_audio_tracks == 0) + return; + + // First send a video keyframe + const gfx::Size frame_size(160, 80); + const scoped_refptr<VideoFrame> video_frame = + VideoFrame::CreateBlackFrame(frame_size); + const std::string encoded_video("thisisanencodedvideopacket"); + // Won't write anything. + webm_muxer_.OnEncodedVideo(video_frame, + make_scoped_ptr(new std::string(encoded_video)), + base::TimeTicks::Now(), true /* keyframe */); + + // Then send some audio. The header will be written and muxing will proceed + // normally. + int sample_rate = 48000; + int bits_per_sample = 16; + int frames_per_buffer = 480; + media::AudioParameters audio_params( + media::AudioParameters::Format::AUDIO_PCM_LOW_LATENCY, + media::CHANNEL_LAYOUT_MONO, sample_rate, bits_per_sample, + frames_per_buffer); + const std::string encoded_audio("thisisanencodedaudiopacket"); + + // We should first get the video keyframe, then the audio frame. + Sequence s; + EXPECT_CALL(*this, WriteCallback(Eq(encoded_video))).Times(1).InSequence(s); + EXPECT_CALL(*this, WriteCallback(Eq(encoded_audio))).Times(1).InSequence(s); + // We'll also get lots of other header-related stuff. + EXPECT_CALL(*this, WriteCallback( + AllOf(Not(Eq(encoded_video)), Not(Eq(encoded_audio))))) + .Times(AnyNumber()); + webm_muxer_.OnEncodedAudio(audio_params, + make_scoped_ptr(new std::string(encoded_audio)), + base::TimeTicks::Now()); +} + const kTestParams kTestCases[] = { // TODO: consider not enumerating every combination by hand. {kCodecVP8, 1 /* num_video_tracks */, 0 /*num_audio_tracks*/}, - {kCodecVP9, 1, 0}, {kCodecVP8, 0, 1}, + {kCodecVP8, 1, 1}, + {kCodecVP9, 1, 0}, + {kCodecVP9, 0, 1}, + {kCodecVP9, 1, 1}, }; INSTANTIATE_TEST_CASE_P(, WebmMuxerTest, ValuesIn(kTestCases));
diff --git a/media/cast/net/pacing/paced_sender.cc b/media/cast/net/pacing/paced_sender.cc index b8642b1..61166da 100644 --- a/media/cast/net/pacing/paced_sender.cc +++ b/media/cast/net/pacing/paced_sender.cc
@@ -31,10 +31,12 @@ DedupInfo::DedupInfo() : last_byte_acked_for_audio(0) {} // static -PacketKey PacedPacketSender::MakePacketKey(const base::TimeTicks& ticks, +PacketKey PacedPacketSender::MakePacketKey(PacketKey::PacketType packet_type, + uint32 frame_id, uint32 ssrc, uint16 packet_id) { - return std::make_pair(ticks, std::make_pair(ssrc, packet_id)); + PacketKey key{packet_type, frame_id, ssrc, packet_id}; + return key; } PacedSender::PacketSendRecord::PacketSendRecord() @@ -125,7 +127,7 @@ // packet Y sent just before X. Reject retransmission of X if ACK for // Y has not been received. // Only do this for video packets. - if (packet_key.second.first == video_ssrc_) { + if (packet_key.ssrc == video_ssrc_) { if (dedup_info.last_byte_acked_for_audio && it->second.last_byte_sent_for_audio && dedup_info.last_byte_acked_for_audio < @@ -169,9 +171,9 @@ bool PacedSender::SendRtcpPacket(uint32 ssrc, PacketRef packet) { if (state_ == State_TransportBlocked) { - priority_packet_list_[ - PacedPacketSender::MakePacketKey(base::TimeTicks(), ssrc, 0)] = - make_pair(PacketType_RTCP, packet); + PacketKey key = + PacedPacketSender::MakePacketKey(PacketKey::RTCP, 0, ssrc, 0); + priority_packet_list_[key] = make_pair(PacketType_RTCP, packet); } else { // We pass the RTCP packets straight through. if (!transport_->SendPacket( @@ -204,7 +206,7 @@ bool PacedSender::IsHighPriority(const PacketKey& packet_key) const { return std::find(priority_ssrcs_.begin(), priority_ssrcs_.end(), - packet_key.second.first) != priority_ssrcs_.end(); + packet_key.ssrc) != priority_ssrcs_.end(); } bool PacedSender::empty() const { @@ -298,7 +300,7 @@ send_record.last_byte_sent_for_audio = GetLastByteSentForSsrc(audio_ssrc_); send_history_[packet_key] = send_record; send_history_buffer_[packet_key] = send_record; - last_byte_sent_[packet_key.second.first] = send_record.last_byte_sent; + last_byte_sent_[packet_key.ssrc] = send_record.last_byte_sent; if (socket_blocked) { state_ = State_TransportBlocked;
diff --git a/media/cast/net/pacing/paced_sender.h b/media/cast/net/pacing/paced_sender.h index a5fcfd17..f37ebe7 100644 --- a/media/cast/net/pacing/paced_sender.h +++ b/media/cast/net/pacing/paced_sender.h
@@ -6,6 +6,7 @@ #define MEDIA_CAST_NET_PACING_PACED_SENDER_H_ #include <map> +#include <tuple> #include <vector> #include "base/basictypes.h" @@ -26,15 +27,26 @@ static const size_t kTargetBurstSize = 10; static const size_t kMaxBurstSize = 20; -// Use std::pair for free comparison operators. -// { capture_time, ssrc, packet_id } // The PacketKey is designed to meet two criteria: // 1. When we re-send the same packet again, we can use the packet key // to identify it so that we can de-duplicate packets in the queue. // 2. The sort order of the PacketKey determines the order that packets -// are sent out. Using the capture_time as the first member basically -// means that older packets are sent first. -typedef std::pair<base::TimeTicks, std::pair<uint32, uint16> > PacketKey; +// are sent out. +// 3. The PacketKey is unique for each RTP (frame) packet. +struct PacketKey { + enum PacketType { RTCP = 0, RTP = 1 }; + + PacketType packet_type; + uint32 frame_id; + uint32 ssrc; + uint16 packet_id; + + bool operator<(const PacketKey& key) const { + return std::tie(packet_type, frame_id, ssrc, packet_id) < + std::tie(key.packet_type, key.frame_id, key.ssrc, key.packet_id); + } +}; + typedef std::vector<std::pair<PacketKey, PacketRef> > SendPacketVector; // Information used to deduplicate retransmission packets. @@ -68,7 +80,8 @@ virtual ~PacedPacketSender() {} - static PacketKey MakePacketKey(const base::TimeTicks& ticks, + static PacketKey MakePacketKey(PacketKey::PacketType, + uint32 frame_id, uint32 ssrc, uint16 packet_id); };
diff --git a/media/cast/net/pacing/paced_sender_unittest.cc b/media/cast/net/pacing/paced_sender_unittest.cc index 13d5afd..1df7415 100644 --- a/media/cast/net/pacing/paced_sender_unittest.cc +++ b/media/cast/net/pacing/paced_sender_unittest.cc
@@ -57,7 +57,7 @@ class PacedSenderTest : public ::testing::Test { protected: - PacedSenderTest() { + PacedSenderTest() : frame_id_(0) { testing_clock_.Advance( base::TimeDelta::FromMilliseconds(kStartMillisecond)); task_runner_ = new test::FakeSingleThreadTaskRunner(&testing_clock_); @@ -77,14 +77,10 @@ bool audio) { DCHECK_GE(packet_size, 12u); SendPacketVector packets; - base::TimeTicks frame_tick = testing_clock_.NowTicks(); - // Advance the clock so that we don't get the same frame_tick - // next time this function is called. - testing_clock_.Advance(base::TimeDelta::FromMilliseconds(1)); for (int i = 0; i < num_of_packets_in_frame; ++i) { PacketKey key = PacedPacketSender::MakePacketKey( - frame_tick, - audio ? kAudioSsrc : kVideoSsrc, // ssrc + PacketKey::RTP, frame_id_, + audio ? kAudioSsrc : kVideoSsrc, // ssrc i); PacketRef packet(new base::RefCountedData<Packet>); @@ -102,6 +98,9 @@ CHECK(success); packets.push_back(std::make_pair(key, packet)); } + // Increase |frame_id_| so that we don't get the same key next time this + // function is called. + ++frame_id_; return packets; } @@ -124,6 +123,7 @@ TestPacketSender mock_transport_; scoped_refptr<test::FakeSingleThreadTaskRunner> task_runner_; scoped_ptr<PacedSender> paced_sender_; + uint32 frame_id_; DISALLOW_COPY_AND_ASSIGN(PacedSenderTest); };
diff --git a/media/cast/net/rtp/packet_storage_unittest.cc b/media/cast/net/rtp/packet_storage_unittest.cc index 7dc5a53a..699368f 100644 --- a/media/cast/net/rtp/packet_storage_unittest.cc +++ b/media/cast/net/rtp/packet_storage_unittest.cc
@@ -24,7 +24,6 @@ static void StoreFrames(size_t number_of_frames, uint32 first_frame_id, PacketStorage* storage) { - const base::TimeTicks kTicks; const int kSsrc = 1; for (size_t i = 0; i < number_of_frames; ++i) { SendPacketVector packets; @@ -32,10 +31,10 @@ const size_t kNumberOfPackets = i + 1; for (size_t j = 0; j < kNumberOfPackets; ++j) { Packet test_packet(1, 0); - packets.push_back( - std::make_pair(PacedPacketSender::MakePacketKey( - kTicks, kSsrc, base::checked_cast<uint16>(j)), - new base::RefCountedData<Packet>(test_packet))); + packets.push_back(std::make_pair( + PacedPacketSender::MakePacketKey(PacketKey::RTP, i, kSsrc, + base::checked_cast<uint16>(j)), + new base::RefCountedData<Packet>(test_packet))); } storage->StoreFrame(first_frame_id, packets); ++first_frame_id;
diff --git a/media/cast/net/rtp/rtp_packetizer.cc b/media/cast/net/rtp/rtp_packetizer.cc index ca9834c..6eb3230 100644 --- a/media/cast/net/rtp/rtp_packetizer.cc +++ b/media/cast/net/rtp/rtp_packetizer.cc
@@ -107,10 +107,8 @@ data_iter + payload_length); data_iter += payload_length; - const PacketKey key = - PacedPacketSender::MakePacketKey(frame.reference_time, - config_.ssrc, - packet_id_++); + const PacketKey key = PacedPacketSender::MakePacketKey( + PacketKey::RTP, frame.frame_id, config_.ssrc, packet_id_++); packets.push_back(make_pair(key, packet)); // Update stats.
diff --git a/media/cast/net/rtp/rtp_sender.cc b/media/cast/net/rtp/rtp_sender.cc index f24f346..bd822e8 100644 --- a/media/cast/net/rtp/rtp_sender.cc +++ b/media/cast/net/rtp/rtp_sender.cc
@@ -77,7 +77,7 @@ for (SendPacketVector::const_iterator it = stored_packets->begin(); it != stored_packets->end(); ++it) { const PacketKey& packet_key = it->first; - const uint16 packet_id = packet_key.second.second; + const uint16 packet_id = packet_key.packet_id; // Should we resend the packet? bool resend = resend_all;
diff --git a/media/cdm/cdm_helpers.cc b/media/cdm/cdm_helpers.cc new file mode 100644 index 0000000..f413dfa --- /dev/null +++ b/media/cdm/cdm_helpers.cc
@@ -0,0 +1,137 @@ +// 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. + +#include "media/cdm/cdm_helpers.h" + +#if defined(USE_PPAPI_CDM_ADAPTER) +// When building the ppapi adapter do not include any non-trivial base/ headers. +#include "ppapi/cpp/logging.h" +#define PLATFORM_DCHECK PP_DCHECK +#else +#include "base/logging.h" +#define PLATFORM_DCHECK DCHECK +#endif + +namespace media { + +DecryptedBlockImpl::DecryptedBlockImpl() : buffer_(nullptr), timestamp_(0) {} + +DecryptedBlockImpl::~DecryptedBlockImpl() { + if (buffer_) + buffer_->Destroy(); +} + +void DecryptedBlockImpl::SetDecryptedBuffer(cdm::Buffer* buffer) { + buffer_ = buffer; +} + +cdm::Buffer* DecryptedBlockImpl::DecryptedBuffer() { + return buffer_; +} + +void DecryptedBlockImpl::SetTimestamp(int64_t timestamp) { + timestamp_ = timestamp; +} + +int64_t DecryptedBlockImpl::Timestamp() const { + return timestamp_; +} + +VideoFrameImpl::VideoFrameImpl() + : format_(cdm::kUnknownVideoFormat), frame_buffer_(nullptr), timestamp_(0) { + for (uint32_t i = 0; i < kMaxPlanes; ++i) { + plane_offsets_[i] = 0; + strides_[i] = 0; + } +} + +VideoFrameImpl::~VideoFrameImpl() { + if (frame_buffer_) + frame_buffer_->Destroy(); +} + +void VideoFrameImpl::SetFormat(cdm::VideoFormat format) { + format_ = format; +} + +cdm::VideoFormat VideoFrameImpl::Format() const { + return format_; +} + +void VideoFrameImpl::SetSize(cdm::Size size) { + size_ = size; +} + +cdm::Size VideoFrameImpl::Size() const { + return size_; +} + +void VideoFrameImpl::SetFrameBuffer(cdm::Buffer* frame_buffer) { + frame_buffer_ = frame_buffer; +} + +cdm::Buffer* VideoFrameImpl::FrameBuffer() { + return frame_buffer_; +} + +void VideoFrameImpl::SetPlaneOffset(cdm::VideoFrame::VideoPlane plane, + uint32_t offset) { + PLATFORM_DCHECK(plane < kMaxPlanes); + plane_offsets_[plane] = offset; +} + +uint32_t VideoFrameImpl::PlaneOffset(VideoPlane plane) { + PLATFORM_DCHECK(plane < kMaxPlanes); + return plane_offsets_[plane]; +} + +void VideoFrameImpl::SetStride(VideoPlane plane, uint32_t stride) { + PLATFORM_DCHECK(plane < kMaxPlanes); + strides_[plane] = stride; +} + +uint32_t VideoFrameImpl::Stride(VideoPlane plane) { + PLATFORM_DCHECK(plane < kMaxPlanes); + return strides_[plane]; +} + +void VideoFrameImpl::SetTimestamp(int64_t timestamp) { + timestamp_ = timestamp; +} + +int64_t VideoFrameImpl::Timestamp() const { + return timestamp_; +} + +AudioFramesImpl::AudioFramesImpl() + : buffer_(nullptr), format_(cdm::kUnknownAudioFormat) {} + +AudioFramesImpl::~AudioFramesImpl() { + if (buffer_) + buffer_->Destroy(); +} + +void AudioFramesImpl::SetFrameBuffer(cdm::Buffer* buffer) { + buffer_ = buffer; +} + +cdm::Buffer* AudioFramesImpl::FrameBuffer() { + return buffer_; +} + +void AudioFramesImpl::SetFormat(cdm::AudioFormat format) { + format_ = format; +} + +cdm::AudioFormat AudioFramesImpl::Format() const { + return format_; +} + +cdm::Buffer* AudioFramesImpl::PassFrameBuffer() { + cdm::Buffer* temp_buffer = buffer_; + buffer_ = nullptr; + return temp_buffer; +} + +} // namespace media
diff --git a/media/cdm/cdm_helpers.h b/media/cdm/cdm_helpers.h new file mode 100644 index 0000000..a058f431 --- /dev/null +++ b/media/cdm/cdm_helpers.h
@@ -0,0 +1,96 @@ +// 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. + +#ifndef MEDIA_CDM_CDM_HELPERS_H_ +#define MEDIA_CDM_CDM_HELPERS_H_ + +#include "base/basictypes.h" +#include "media/cdm/api/content_decryption_module.h" + +namespace media { + +class DecryptedBlockImpl : public cdm::DecryptedBlock { + public: + DecryptedBlockImpl(); + ~DecryptedBlockImpl() final; + + // cdm::DecryptedBlock implementation. + void SetDecryptedBuffer(cdm::Buffer* buffer) final; + cdm::Buffer* DecryptedBuffer() final; + void SetTimestamp(int64_t timestamp) final; + int64_t Timestamp() const final; + + private: + cdm::Buffer* buffer_; + int64_t timestamp_; + + DISALLOW_COPY_AND_ASSIGN(DecryptedBlockImpl); +}; + +class VideoFrameImpl : public cdm::VideoFrame { + public: + VideoFrameImpl(); + ~VideoFrameImpl() final; + + // cdm::VideoFrame implementation. + void SetFormat(cdm::VideoFormat format) final; + cdm::VideoFormat Format() const final; + void SetSize(cdm::Size size) final; + cdm::Size Size() const final; + void SetFrameBuffer(cdm::Buffer* frame_buffer) final; + cdm::Buffer* FrameBuffer() final; + void SetPlaneOffset(cdm::VideoFrame::VideoPlane plane, uint32_t offset) final; + uint32_t PlaneOffset(VideoPlane plane) final; + void SetStride(VideoPlane plane, uint32_t stride) final; + uint32_t Stride(VideoPlane plane) final; + void SetTimestamp(int64_t timestamp) final; + int64_t Timestamp() const final; + + private: + // The video buffer format. + cdm::VideoFormat format_; + + // Width and height of the video frame. + cdm::Size size_; + + // The video frame buffer. + cdm::Buffer* frame_buffer_; + + // Array of data pointers to each plane in the video frame buffer. + uint32_t plane_offsets_[kMaxPlanes]; + + // Array of strides for each plane, typically greater or equal to the width + // of the surface divided by the horizontal sampling period. Note that + // strides can be negative. + uint32_t strides_[kMaxPlanes]; + + // Presentation timestamp in microseconds. + int64_t timestamp_; + + DISALLOW_COPY_AND_ASSIGN(VideoFrameImpl); +}; + +class AudioFramesImpl : public cdm::AudioFrames { + public: + AudioFramesImpl(); + ~AudioFramesImpl() final; + + // cdm::AudioFrames implementation. + void SetFrameBuffer(cdm::Buffer* buffer) final; + cdm::Buffer* FrameBuffer() final; + void SetFormat(cdm::AudioFormat format) final; + cdm::AudioFormat Format() const final; + + cdm::Buffer* PassFrameBuffer(); + + private: + cdm::Buffer* buffer_; + cdm::AudioFormat format_; + + DISALLOW_COPY_AND_ASSIGN(AudioFramesImpl); +}; + +} // namespace media + +#endif // MEDIA_CDM_CDM_HELPERS_H_
diff --git a/media/cdm/cdm_wrapper.h b/media/cdm/cdm_wrapper.h index f5aef43..eafd3d7 100644 --- a/media/cdm/cdm_wrapper.h +++ b/media/cdm/cdm_wrapper.h
@@ -321,4 +321,6 @@ } // namespace media +#undef PLATFORM_DCHECK + #endif // MEDIA_CDM_CDM_WRAPPER_H_
diff --git a/media/cdm/ppapi/cdm_helpers.h b/media/cdm/ppapi/cdm_helpers.h deleted file mode 100644 index 5d17fbc..0000000 --- a/media/cdm/ppapi/cdm_helpers.h +++ /dev/null
@@ -1,223 +0,0 @@ -// Copyright 2013 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef MEDIA_CDM_PPAPI_CDM_HELPERS_H_ -#define MEDIA_CDM_PPAPI_CDM_HELPERS_H_ - -#include <map> -#include <utility> - -#include "base/basictypes.h" -#include "base/compiler_specific.h" -#include "build/build_config.h" -#include "media/cdm/api/content_decryption_module.h" -#include "ppapi/c/pp_errors.h" -#include "ppapi/c/pp_stdint.h" -#include "ppapi/cpp/dev/buffer_dev.h" -#include "ppapi/cpp/instance.h" -#include "ppapi/cpp/logging.h" - -namespace media { - -class PpbBufferAllocator; - -// cdm::Buffer implementation that provides access to memory owned by a -// pp::Buffer_Dev. -// This class holds a reference to the Buffer_Dev throughout its lifetime. -// TODO(xhwang): Find a better name. It's confusing to have PpbBuffer, -// pp::Buffer_Dev and PPB_Buffer_Dev. -class PpbBuffer : public cdm::Buffer { - public: - static PpbBuffer* Create(const pp::Buffer_Dev& buffer, uint32_t buffer_id, - PpbBufferAllocator* allocator); - - // cdm::Buffer implementation. - void Destroy() override; - uint32_t Capacity() const override; - uint8_t* Data() override; - void SetSize(uint32_t size) override; - uint32_t Size() const override { return size_; } - - // Takes the |buffer_| from this class and returns it. - // Note: The caller must ensure |allocator->Release()| is called later so that - // the buffer can be reused by the allocator. - // Since pp::Buffer_Dev is ref-counted, the caller now holds one reference to - // the buffer and this class holds no reference. Note that other references - // may still exist. For example, PpbBufferAllocator always holds a reference - // to all allocated buffers. - pp::Buffer_Dev TakeBuffer(); - - uint32_t buffer_id() const { return buffer_id_; } - - private: - PpbBuffer(pp::Buffer_Dev buffer, - uint32_t buffer_id, - PpbBufferAllocator* allocator); - ~PpbBuffer() override; - - pp::Buffer_Dev buffer_; - uint32_t buffer_id_; - uint32_t size_; - PpbBufferAllocator* allocator_; - - DISALLOW_COPY_AND_ASSIGN(PpbBuffer); -}; - -class PpbBufferAllocator { - public: - explicit PpbBufferAllocator(pp::Instance* instance) - : instance_(instance), - next_buffer_id_(1) {} - ~PpbBufferAllocator() {} - - cdm::Buffer* Allocate(uint32_t capacity); - - // Releases the buffer with |buffer_id|. A buffer can be recycled after - // it is released. - void Release(uint32_t buffer_id); - - private: - typedef std::map<uint32_t, pp::Buffer_Dev> AllocatedBufferMap; - typedef std::multimap<uint32_t, std::pair<uint32_t, pp::Buffer_Dev> > - FreeBufferMap; - - pp::Buffer_Dev AllocateNewBuffer(uint32_t capacity); - - pp::Instance* const instance_; - uint32_t next_buffer_id_; - AllocatedBufferMap allocated_buffers_; - FreeBufferMap free_buffers_; - - DISALLOW_COPY_AND_ASSIGN(PpbBufferAllocator); -}; - -class DecryptedBlockImpl : public cdm::DecryptedBlock { - public: - DecryptedBlockImpl() : buffer_(NULL), timestamp_(0) {} - ~DecryptedBlockImpl() override { - if (buffer_) - buffer_->Destroy(); - } - - void SetDecryptedBuffer(cdm::Buffer* buffer) override { - buffer_ = static_cast<PpbBuffer*>(buffer); - } - cdm::Buffer* DecryptedBuffer() override { return buffer_; } - - void SetTimestamp(int64_t timestamp) override { - timestamp_ = timestamp; - } - int64_t Timestamp() const override { return timestamp_; } - - private: - PpbBuffer* buffer_; - int64_t timestamp_; - - DISALLOW_COPY_AND_ASSIGN(DecryptedBlockImpl); -}; - -class VideoFrameImpl : public cdm::VideoFrame { - public: - VideoFrameImpl(); - ~VideoFrameImpl() override; - - void SetFormat(cdm::VideoFormat format) override { - format_ = format; - } - cdm::VideoFormat Format() const override { return format_; } - - void SetSize(cdm::Size size) override { size_ = size; } - cdm::Size Size() const override { return size_; } - - void SetFrameBuffer(cdm::Buffer* frame_buffer) override { - frame_buffer_ = static_cast<PpbBuffer*>(frame_buffer); - } - cdm::Buffer* FrameBuffer() override { return frame_buffer_; } - - void SetPlaneOffset(cdm::VideoFrame::VideoPlane plane, - uint32_t offset) override { - PP_DCHECK(plane < kMaxPlanes); - plane_offsets_[plane] = offset; - } - uint32_t PlaneOffset(VideoPlane plane) override { - PP_DCHECK(plane < kMaxPlanes); - return plane_offsets_[plane]; - } - - void SetStride(VideoPlane plane, uint32_t stride) override { - PP_DCHECK(plane < kMaxPlanes); - strides_[plane] = stride; - } - uint32_t Stride(VideoPlane plane) override { - PP_DCHECK(plane < kMaxPlanes); - return strides_[plane]; - } - - void SetTimestamp(int64_t timestamp) override { - timestamp_ = timestamp; - } - int64_t Timestamp() const override { return timestamp_; } - - private: - // The video buffer format. - cdm::VideoFormat format_; - - // Width and height of the video frame. - cdm::Size size_; - - // The video frame buffer. - PpbBuffer* frame_buffer_; - - // Array of data pointers to each plane in the video frame buffer. - uint32_t plane_offsets_[kMaxPlanes]; - - // Array of strides for each plane, typically greater or equal to the width - // of the surface divided by the horizontal sampling period. Note that - // strides can be negative. - uint32_t strides_[kMaxPlanes]; - - // Presentation timestamp in microseconds. - int64_t timestamp_; - - DISALLOW_COPY_AND_ASSIGN(VideoFrameImpl); -}; - -class AudioFramesImpl : public cdm::AudioFrames { - public: - AudioFramesImpl() : buffer_(NULL), format_(cdm::kUnknownAudioFormat) {} - ~AudioFramesImpl() override { - if (buffer_) - buffer_->Destroy(); - } - - // AudioFrames implementation. - void SetFrameBuffer(cdm::Buffer* buffer) override { - buffer_ = static_cast<PpbBuffer*>(buffer); - } - cdm::Buffer* FrameBuffer() override { - return buffer_; - } - void SetFormat(cdm::AudioFormat format) override { - format_ = format; - } - cdm::AudioFormat Format() const override { - return format_; - } - - cdm::Buffer* PassFrameBuffer() { - PpbBuffer* temp_buffer = buffer_; - buffer_ = NULL; - return temp_buffer; - } - - private: - PpbBuffer* buffer_; - cdm::AudioFormat format_; - - DISALLOW_COPY_AND_ASSIGN(AudioFramesImpl); -}; - -} // namespace media - -#endif // MEDIA_CDM_PPAPI_CDM_HELPERS_H_
diff --git a/media/cdm/ppapi/ppapi_cdm_adapter.gni b/media/cdm/ppapi/ppapi_cdm_adapter.gni index e7cf90ff..b356db3f 100644 --- a/media/cdm/ppapi/ppapi_cdm_adapter.gni +++ b/media/cdm/ppapi/ppapi_cdm_adapter.gni
@@ -20,16 +20,18 @@ defines += [ "USE_PPAPI_CDM_ADAPTER" ] sources += [ "//media/cdm/api/content_decryption_module.h", + "//media/cdm/cdm_helpers.cc", + "//media/cdm/cdm_helpers.h", "//media/cdm/cdm_wrapper.h", "//media/cdm/ppapi/cdm_file_io_impl.cc", "//media/cdm/ppapi/cdm_file_io_impl.h", - "//media/cdm/ppapi/cdm_helpers.cc", - "//media/cdm/ppapi/cdm_helpers.h", "//media/cdm/ppapi/cdm_logging.cc", "//media/cdm/ppapi/cdm_logging.h", "//media/cdm/ppapi/linked_ptr.h", "//media/cdm/ppapi/ppapi_cdm_adapter.cc", "//media/cdm/ppapi/ppapi_cdm_adapter.h", + "//media/cdm/ppapi/ppapi_cdm_buffer.cc", + "//media/cdm/ppapi/ppapi_cdm_buffer.h", "//media/cdm/supported_cdm_versions.cc", "//media/cdm/supported_cdm_versions.h", ]
diff --git a/media/cdm/ppapi/ppapi_cdm_adapter.h b/media/cdm/ppapi/ppapi_cdm_adapter.h index 470bc9a5..989bd456 100644 --- a/media/cdm/ppapi/ppapi_cdm_adapter.h +++ b/media/cdm/ppapi/ppapi_cdm_adapter.h
@@ -12,9 +12,10 @@ #include "base/compiler_specific.h" #include "build/build_config.h" #include "media/cdm/api/content_decryption_module.h" +#include "media/cdm/cdm_helpers.h" #include "media/cdm/cdm_wrapper.h" -#include "media/cdm/ppapi/cdm_helpers.h" #include "media/cdm/ppapi/linked_ptr.h" +#include "media/cdm/ppapi/ppapi_cdm_buffer.h" #include "ppapi/c/pp_stdint.h" #include "ppapi/c/private/pp_content_decryptor.h" #include "ppapi/cpp/completion_callback.h"
diff --git a/media/cdm/ppapi/cdm_helpers.cc b/media/cdm/ppapi/ppapi_cdm_buffer.cc similarity index 90% rename from media/cdm/ppapi/cdm_helpers.cc rename to media/cdm/ppapi/ppapi_cdm_buffer.cc index 00e7595a..3d34512 100644 --- a/media/cdm/ppapi/cdm_helpers.cc +++ b/media/cdm/ppapi/ppapi_cdm_buffer.cc
@@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#include "media/cdm/ppapi/cdm_helpers.h" +#include "media/cdm/ppapi/ppapi_cdm_buffer.h" #include <algorithm> @@ -56,8 +56,7 @@ PpbBuffer::PpbBuffer(pp::Buffer_Dev buffer, uint32_t buffer_id, PpbBufferAllocator* allocator) - : buffer_(buffer), buffer_id_(buffer_id), size_(0), allocator_(allocator) { -} + : buffer_(buffer), buffer_id_(buffer_id), size_(0), allocator_(allocator) {} PpbBuffer::~PpbBuffer() { PP_DCHECK(!buffer_id_ == buffer_.is_null()); @@ -130,19 +129,4 @@ return pp::Buffer_Dev(instance_, capacity + kBufferPadding); } -VideoFrameImpl::VideoFrameImpl() - : format_(cdm::kUnknownVideoFormat), - frame_buffer_(NULL), - timestamp_(0) { - for (uint32_t i = 0; i < kMaxPlanes; ++i) { - plane_offsets_[i] = 0; - strides_[i] = 0; - } -} - -VideoFrameImpl::~VideoFrameImpl() { - if (frame_buffer_) - frame_buffer_->Destroy(); -} - } // namespace media
diff --git a/media/cdm/ppapi/ppapi_cdm_buffer.h b/media/cdm/ppapi/ppapi_cdm_buffer.h new file mode 100644 index 0000000..2335a004 --- /dev/null +++ b/media/cdm/ppapi/ppapi_cdm_buffer.h
@@ -0,0 +1,97 @@ +// Copyright 2013 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef MEDIA_CDM_PPAPI_PPAPI_CDM_BUFFER_H_ +#define MEDIA_CDM_PPAPI_PPAPI_CDM_BUFFER_H_ + +#include <map> +#include <utility> + +#include "base/basictypes.h" +#include "base/compiler_specific.h" +#include "build/build_config.h" +#include "media/cdm/api/content_decryption_module.h" +#include "ppapi/c/pp_errors.h" +#include "ppapi/c/pp_stdint.h" +#include "ppapi/cpp/dev/buffer_dev.h" +#include "ppapi/cpp/instance.h" +#include "ppapi/cpp/logging.h" + +namespace media { + +class PpbBufferAllocator; + +// cdm::Buffer implementation that provides access to memory owned by a +// pp::Buffer_Dev. +// This class holds a reference to the Buffer_Dev throughout its lifetime. +// TODO(xhwang): Find a better name. It's confusing to have PpbBuffer, +// pp::Buffer_Dev and PPB_Buffer_Dev. +class PpbBuffer : public cdm::Buffer { + public: + static PpbBuffer* Create(const pp::Buffer_Dev& buffer, + uint32_t buffer_id, + PpbBufferAllocator* allocator); + + // cdm::Buffer implementation. + void Destroy() override; + uint32_t Capacity() const override; + uint8_t* Data() override; + void SetSize(uint32_t size) override; + uint32_t Size() const override { return size_; } + + // Takes the |buffer_| from this class and returns it. + // Note: The caller must ensure |allocator->Release()| is called later so that + // the buffer can be reused by the allocator. + // Since pp::Buffer_Dev is ref-counted, the caller now holds one reference to + // the buffer and this class holds no reference. Note that other references + // may still exist. For example, PpbBufferAllocator always holds a reference + // to all allocated buffers. + pp::Buffer_Dev TakeBuffer(); + + uint32_t buffer_id() const { return buffer_id_; } + + private: + PpbBuffer(pp::Buffer_Dev buffer, + uint32_t buffer_id, + PpbBufferAllocator* allocator); + ~PpbBuffer() override; + + pp::Buffer_Dev buffer_; + uint32_t buffer_id_; + uint32_t size_; + PpbBufferAllocator* allocator_; + + DISALLOW_COPY_AND_ASSIGN(PpbBuffer); +}; + +class PpbBufferAllocator { + public: + explicit PpbBufferAllocator(pp::Instance* instance) + : instance_(instance), next_buffer_id_(1) {} + ~PpbBufferAllocator() {} + + cdm::Buffer* Allocate(uint32_t capacity); + + // Releases the buffer with |buffer_id|. A buffer can be recycled after + // it is released. + void Release(uint32_t buffer_id); + + private: + typedef std::map<uint32_t, pp::Buffer_Dev> AllocatedBufferMap; + typedef std::multimap<uint32_t, std::pair<uint32_t, pp::Buffer_Dev>> + FreeBufferMap; + + pp::Buffer_Dev AllocateNewBuffer(uint32_t capacity); + + pp::Instance* const instance_; + uint32_t next_buffer_id_; + AllocatedBufferMap allocated_buffers_; + FreeBufferMap free_buffers_; + + DISALLOW_COPY_AND_ASSIGN(PpbBufferAllocator); +}; + +} // namespace media + +#endif // MEDIA_CDM_PPAPI_PPAPI_CDM_BUFFER_H_
diff --git a/media/filters/decrypting_video_decoder.cc b/media/filters/decrypting_video_decoder.cc index 9ec48c9..953826c0 100644 --- a/media/filters/decrypting_video_decoder.cc +++ b/media/filters/decrypting_video_decoder.cc
@@ -42,7 +42,8 @@ const SetCdmReadyCB& set_cdm_ready_cb, const InitCB& init_cb, const OutputCB& output_cb) { - DVLOG(2) << "Initialize()"; + DVLOG(2) << __FUNCTION__ << ": " << config.AsHumanReadableString(); + DCHECK(task_runner_->BelongsToCurrentThread()); DCHECK(state_ == kUninitialized || state_ == kIdle ||
diff --git a/media/filters/ffmpeg_demuxer.cc b/media/filters/ffmpeg_demuxer.cc index f7a3f48..f041bb6c 100644 --- a/media/filters/ffmpeg_demuxer.cc +++ b/media/filters/ffmpeg_demuxer.cc
@@ -748,7 +748,6 @@ text_enabled_(false), duration_known_(false), encrypted_media_init_data_cb_(encrypted_media_init_data_cb), - stream_memory_usage_(0), weak_factory_(this) { DCHECK(task_runner_.get()); DCHECK(data_source_); @@ -925,8 +924,12 @@ } int64_t FFmpegDemuxer::GetMemoryUsage() const { - base::AutoLock locker(stream_memory_usage_lock_); - return stream_memory_usage_; + int64_t allocation_size = 0; + for (const auto& stream : streams_) { + if (stream) + allocation_size += stream->MemoryUsage(); + } + return allocation_size; } // Helper for calculating the bitrate of the media based on information stored @@ -1379,15 +1382,10 @@ return; } - // Max allowed memory usage, all streams combined. - const int64_t kDemuxerMemoryLimit = 150 * 1024 * 1024; - const bool is_max_memory_usage_reached = - UpdateMemoryUsage() > kDemuxerMemoryLimit; - // Consider the stream as ended if: // - either underlying ffmpeg returned an error // - or FFMpegDemuxer reached the maximum allowed memory usage. - if (result < 0 || is_max_memory_usage_reached) { + if (result < 0 || IsMaxMemoryUsageReached()) { // Update the duration based on the highest elapsed time across all streams // if it was previously unknown. if (!duration_known_) { @@ -1453,16 +1451,24 @@ return false; } -int64_t FFmpegDemuxer::UpdateMemoryUsage() { +bool FFmpegDemuxer::IsMaxMemoryUsageReached() const { DCHECK(task_runner_->BelongsToCurrentThread()); - base::AutoLock locker(stream_memory_usage_lock_); - stream_memory_usage_ = 0; - for (const auto& stream : streams_) { - if (stream) - stream_memory_usage_ += stream->MemoryUsage(); + // Max allowed memory usage, all streams combined. + const size_t kDemuxerMemoryLimit = 150 * 1024 * 1024; + + size_t memory_left = kDemuxerMemoryLimit; + for (StreamVector::const_iterator iter = streams_.begin(); + iter != streams_.end(); ++iter) { + if (!(*iter)) + continue; + + size_t stream_memory_usage = (*iter)->MemoryUsage(); + if (stream_memory_usage > memory_left) + return true; + memory_left -= stream_memory_usage; } - return stream_memory_usage_; + return false; } void FFmpegDemuxer::StreamHasEnded() {
diff --git a/media/filters/ffmpeg_demuxer.h b/media/filters/ffmpeg_demuxer.h index 154ff05e..c527b74 100644 --- a/media/filters/ffmpeg_demuxer.h +++ b/media/filters/ffmpeg_demuxer.h
@@ -233,9 +233,8 @@ // go over capacity depending on how the file is muxed. bool StreamsHaveAvailableCapacity(); - // Updates |stream_memory_usage_| to the memory usage in bytes of all - // FFmpegDemuxerStreams. Returns the current memory usage. - int64_t UpdateMemoryUsage(); + // Returns true if the maximum allowed memory usage has been reached. + bool IsMaxMemoryUsageReached() const; // Signal all FFmpegDemuxerStreams that the stream has ended. void StreamHasEnded(); @@ -324,10 +323,6 @@ const EncryptedMediaInitDataCB encrypted_media_init_data_cb_; - // Last stream size as calculated by UpdateMemoryUsage(). - mutable base::Lock stream_memory_usage_lock_; - int64_t stream_memory_usage_; - // NOTE: Weak pointers must be invalidated before all other member variables. base::WeakPtrFactory<FFmpegDemuxer> weak_factory_;
diff --git a/media/filters/ffmpeg_demuxer_unittest.cc b/media/filters/ffmpeg_demuxer_unittest.cc index 1e915b943d..f0386488 100644 --- a/media/filters/ffmpeg_demuxer_unittest.cc +++ b/media/filters/ffmpeg_demuxer_unittest.cc
@@ -981,7 +981,8 @@ event.RunAndWaitForStatus(PIPELINE_OK); // Verify that seeking to the end read only a small portion of the file. - // Slow that read sequentially up to the seek point will fail this check. + // Slow seeks that read sequentially up to the seek point will read too many + // bytes and fail this check. int64 file_size = 0; ASSERT_TRUE(data_source_->GetSize(&file_size)); EXPECT_LT(data_source_->bytes_read_for_testing(), (file_size * .25));
diff --git a/media/filters/gpu_video_decoder.cc b/media/filters/gpu_video_decoder.cc index b7229f0..1185b967 100644 --- a/media/filters/gpu_video_decoder.cc +++ b/media/filters/gpu_video_decoder.cc
@@ -174,7 +174,10 @@ } vda_ = factories_->CreateVideoDecodeAccelerator().Pass(); - if (!vda_ || !vda_->Initialize(config.profile(), this)) { + + VideoDecodeAccelerator::Config vda_config(config); + + if (!vda_ || !vda_->Initialize(vda_config, this)) { DVLOG(1) << "VDA initialization failed."; bound_init_cb.Run(false); return; @@ -455,8 +458,10 @@ DCHECK(decoder_texture_target_); + bool opaque = IsOpaque(config_.format()); + scoped_refptr<VideoFrame> frame(VideoFrame::WrapNativeTexture( - PIXEL_FORMAT_ARGB, + opaque ? PIXEL_FORMAT_XRGB : PIXEL_FORMAT_ARGB, gpu::MailboxHolder(pb.texture_mailbox(), gpu::SyncToken(), decoder_texture_target_), BindToCurrentLoop(base::Bind(
diff --git a/media/media_cdm_adapter.gyp b/media/media_cdm_adapter.gyp index 876f884..4049b362 100644 --- a/media/media_cdm_adapter.gyp +++ b/media/media_cdm_adapter.gyp
@@ -26,13 +26,15 @@ ], 'sources': [ 'cdm/api/content_decryption_module.h', + 'cdm/cdm_helpers.cc', + 'cdm/cdm_helpers.h', 'cdm/cdm_wrapper.h', 'cdm/ppapi/ppapi_cdm_adapter.cc', 'cdm/ppapi/ppapi_cdm_adapter.h', + 'cdm/ppapi/ppapi_cdm_buffer.cc', + 'cdm/ppapi/ppapi_cdm_buffer.h', 'cdm/ppapi/cdm_file_io_impl.cc', 'cdm/ppapi/cdm_file_io_impl.h', - 'cdm/ppapi/cdm_helpers.cc', - 'cdm/ppapi/cdm_helpers.h', 'cdm/ppapi/cdm_logging.cc', 'cdm/ppapi/cdm_logging.h', 'cdm/ppapi/linked_ptr.h',
diff --git a/media/mojo/services/media_type_converters.cc b/media/mojo/services/media_type_converters.cc index fc733aa..a4a9ead 100644 --- a/media/mojo/services/media_type_converters.cc +++ b/media/mojo/services/media_type_converters.cc
@@ -648,7 +648,7 @@ memcpy(frame->data(media::VideoFrame::kVPlane), input->v_data.storage().data(), input->v_data.storage().size()); - return frame.Pass(); + return frame; } } // namespace mojo
diff --git a/media/renderers/skcanvas_video_renderer.cc b/media/renderers/skcanvas_video_renderer.cc index d2f25d63..aa9321a 100644 --- a/media/renderers/skcanvas_video_renderer.cc +++ b/media/renderers/skcanvas_video_renderer.cc
@@ -147,6 +147,7 @@ VideoFrame* video_frame, const Context3D& context_3d) { DCHECK(PIXEL_FORMAT_ARGB == video_frame->format() || + PIXEL_FORMAT_XRGB == video_frame->format() || PIXEL_FORMAT_NV12 == video_frame->format() || PIXEL_FORMAT_UYVY == video_frame->format());
diff --git a/media/test/pipeline_integration_test.cc b/media/test/pipeline_integration_test.cc index 43bb528..255d5eb 100644 --- a/media/test/pipeline_integration_test.cc +++ b/media/test/pipeline_integration_test.cc
@@ -1229,6 +1229,65 @@ EXPECT_HASH_EQ("1.30,2.72,4.56,5.08,3.74,2.03,", GetAudioHash()); } +class Mp3FastSeekParams { + public: + Mp3FastSeekParams(const char* filename, const char* hash) + : filename(filename), hash(hash) {} + const char* filename; + const char* hash; +}; + +class Mp3FastSeekIntegrationTest + : public PipelineIntegrationTest, + public testing::WithParamInterface<Mp3FastSeekParams> {}; + +TEST_P(Mp3FastSeekIntegrationTest, FastSeekAccuracy_MP3) { + Mp3FastSeekParams config = GetParam(); + ASSERT_EQ(PIPELINE_OK, Start(config.filename, kHashed)); + + // The XING TOC is inaccurate. We don't use it for CBR, we tolerate it for VBR + // (best option for fast seeking; see Mp3SeekFFmpegDemuxerTest). The chosen + // seek time exposes inaccuracy in TOC such that the hash will change if seek + // logic is regressed. See https://crbug.com/545914. + // + // Quick TOC design (not pretty!): + // - All MP3 TOCs are 100 bytes + // - Each byte is read as a uint8; value between 0 - 255. + // - The index into this array is the numerator in the ratio: index / 100. + // This fraction represents a playback time as a percentage of duration. + // - The value at the given index is the numerator in the ratio: value / 256. + // This fraction represents a byte offset as a percentage of the file size. + // + // For CBR files, each frame is the same size, so the offset for time of + // (0.98 * duration) should be around (0.98 * file size). This is 250.88 / 256 + // but the numerator will be truncated in the TOC as 250, losing precision. + base::TimeDelta seek_time(0.98 * pipeline_->GetMediaDuration()); + + ASSERT_TRUE(Seek(seek_time)); + Play(); + ASSERT_TRUE(WaitUntilOnEnded()); + + EXPECT_HASH_EQ(config.hash, GetAudioHash()); +} + +// CBR seeks should always be fast and accurate. +INSTANTIATE_TEST_CASE_P( + CBRSeeks, + Mp3FastSeekIntegrationTest, + ::testing::Values(Mp3FastSeekParams("bear-audio-10s-CBR-has-TOC.mp3", + "-0.71,0.36,2.96,2.68,2.10,-1.08,"), + Mp3FastSeekParams("bear-audio-10s-CBR-no-TOC.mp3", + "0.95,0.56,1.34,0.47,1.77,0.84,"))); + +// VBR seeks can be fast *OR* accurate, but not both. We chose fast. +INSTANTIATE_TEST_CASE_P( + VBRSeeks, + Mp3FastSeekIntegrationTest, + ::testing::Values(Mp3FastSeekParams("bear-audio-10s-VBR-has-TOC.mp3", + "-0.15,-0.83,0.54,1.00,1.94,0.93,"), + Mp3FastSeekParams("bear-audio-10s-VBR-no-TOC.mp3", + "-0.22,0.80,1.19,0.73,-0.31,-1.12,"))); + TEST_F(PipelineIntegrationTest, MediaSource_MP3) { MockMediaSource source("sfx.mp3", kMP3, kAppendWholeFile); StartHashedPipelineWithMediaSource(&source);
diff --git a/media/video/mock_video_decode_accelerator.h b/media/video/mock_video_decode_accelerator.h index f8bb6da8..87a5953 100644 --- a/media/video/mock_video_decode_accelerator.h +++ b/media/video/mock_video_decode_accelerator.h
@@ -24,7 +24,7 @@ MockVideoDecodeAccelerator(); virtual ~MockVideoDecodeAccelerator(); - MOCK_METHOD2(Initialize, bool(VideoCodecProfile profile, Client* client)); + MOCK_METHOD2(Initialize, bool(const Config& config, Client* client)); MOCK_METHOD1(Decode, void(const BitstreamBuffer& bitstream_buffer)); MOCK_METHOD1(AssignPictureBuffers, void(const std::vector<PictureBuffer>& buffers));
diff --git a/media/video/video_decode_accelerator.cc b/media/video/video_decode_accelerator.cc index 7449a2ae..d1df010 100644 --- a/media/video/video_decode_accelerator.cc +++ b/media/video/video_decode_accelerator.cc
@@ -9,6 +9,14 @@ namespace media { +VideoDecodeAccelerator::Config::Config(VideoCodecProfile video_codec_profile) + : profile(video_codec_profile) {} + +VideoDecodeAccelerator::Config::Config( + const VideoDecoderConfig& video_decoder_config) + : profile(video_decoder_config.profile()), + is_encrypted(video_decoder_config.is_encrypted()) {} + void VideoDecodeAccelerator::Client::NotifyCdmAttached(bool success) { NOTREACHED() << "By default CDM is not supported."; }
diff --git a/media/video/video_decode_accelerator.h b/media/video/video_decode_accelerator.h index e2bcdf6..da184ee 100644 --- a/media/video/video_decode_accelerator.h +++ b/media/video/video_decode_accelerator.h
@@ -53,6 +53,19 @@ LARGEST_ERROR_ENUM, }; + // Config structure contains parameters required for the VDA initialization. + struct MEDIA_EXPORT Config { + Config() = default; + Config(VideoCodecProfile profile); + Config(const VideoDecoderConfig& video_decoder_config); + + // |profile| combines the information about the codec and its profile. + VideoCodecProfile profile = VIDEO_CODEC_PROFILE_UNKNOWN; + + // The flag indicating whether the stream is encrypted. + bool is_encrypted = false; + }; + // Interface for collaborating with picture interface to provide memory for // output picture and blitting them. These callbacks will not be made unless // Initialize() has returned successfully. @@ -111,10 +124,10 @@ // attached can we start to decode. // // Parameters: - // |profile| is the video stream's format profile. + // |config| contains the initialization parameters. // |client| is the client of this video decoder. Does not take ownership of // |client| which must be valid until Destroy() is called. - virtual bool Initialize(VideoCodecProfile profile, Client* client) = 0; + virtual bool Initialize(const Config& config, Client* client) = 0; // Sets a CDM to be used by the decoder to decode encrypted buffers. // Client::NotifyCdmAttached() will then be called to indicate whether the CDM
diff --git a/mojo/converters/blink/BUILD.gn b/mojo/converters/blink/BUILD.gn new file mode 100644 index 0000000..f5486f05 --- /dev/null +++ b/mojo/converters/blink/BUILD.gn
@@ -0,0 +1,24 @@ +# 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. + +component("blink") { + output_name = "mojo_blink_lib" + + sources = [ + "blink_input_events_type_converters.cc", + "blink_input_events_type_converters.h", + "mojo_blink_export.h", + ] + + defines = [ "MOJO_CONVERTERS_BLINK_IMPLEMENTATION" ] + + deps = [ + "//base", + "//components/mus/public/interfaces", + "//mojo/environment:chromium", + "//mojo/public/c/system:for_component", + "//third_party/WebKit/public:blink", + "//ui/events", + ] +}
diff --git a/mojo/converters/blink/DEPS b/mojo/converters/blink/DEPS new file mode 100644 index 0000000..95de851 --- /dev/null +++ b/mojo/converters/blink/DEPS
@@ -0,0 +1,6 @@ +include_rules = [ + "+base", + "+components/mus/public", + "+third_party/WebKit/public", + "+ui/events" +]
diff --git a/components/html_viewer/blink_input_events_type_converters.cc b/mojo/converters/blink/blink_input_events_type_converters.cc similarity index 96% rename from components/html_viewer/blink_input_events_type_converters.cc rename to mojo/converters/blink/blink_input_events_type_converters.cc index 5b36a77..eca9fac 100644 --- a/components/html_viewer/blink_input_events_type_converters.cc +++ b/mojo/converters/blink/blink_input_events_type_converters.cc
@@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#include "components/html_viewer/blink_input_events_type_converters.h" +#include "mojo/converters/blink/blink_input_events_type_converters.h" #include "base/logging.h" #include "base/time/time.h" @@ -117,8 +117,9 @@ switch (event->action) { case mus::mojom::EVENT_TYPE_KEY_PRESSED: - web_event->type = event->key_data->is_char ? blink::WebInputEvent::Char : - blink::WebInputEvent::RawKeyDown; + web_event->type = event->key_data->is_char + ? blink::WebInputEvent::Char + : blink::WebInputEvent::RawKeyDown; break; case mus::mojom::EVENT_TYPE_KEY_RELEASED: web_event->type = blink::WebInputEvent::KeyUp; @@ -204,7 +205,8 @@ if (event->pointer_data && event->pointer_data->kind == mus::mojom::POINTER_KIND_MOUSE) { return BuildWebMouseEventFrom(event); - } + } + return nullptr; case mus::mojom::EVENT_TYPE_WHEEL: return BuildWebMouseWheelEventFrom(event); case mus::mojom::EVENT_TYPE_KEY_PRESSED:
diff --git a/mojo/converters/blink/blink_input_events_type_converters.h b/mojo/converters/blink/blink_input_events_type_converters.h new file mode 100644 index 0000000..bb1dce1 --- /dev/null +++ b/mojo/converters/blink/blink_input_events_type_converters.h
@@ -0,0 +1,27 @@ +// Copyright 2014 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef MOJO_CONVERTERS_BLINK_BLINK_INPUT_EVENTS_TYPE_CONVERTERS_H_ +#define MOJO_CONVERTERS_BLINK_BLINK_INPUT_EVENTS_TYPE_CONVERTERS_H_ + +#include "base/memory/scoped_ptr.h" +#include "components/mus/public/interfaces/input_events.mojom.h" +#include "mojo/converters/blink/mojo_blink_export.h" + +namespace blink { +class WebInputEvent; +} + +namespace mojo { + +template <> +struct MOJO_BLINK_EXPORT + TypeConverter<scoped_ptr<blink::WebInputEvent>, mus::mojom::EventPtr> { + static scoped_ptr<blink::WebInputEvent> Convert( + const mus::mojom::EventPtr& input); +}; + +} // namespace mojo + +#endif // MOJO_CONVERTERS_BLINK_BLINK_INPUT_EVENTS_TYPE_CONVERTERS_H_
diff --git a/mojo/converters/blink/mojo_blink_export.h b/mojo/converters/blink/mojo_blink_export.h new file mode 100644 index 0000000..1a77184 --- /dev/null +++ b/mojo/converters/blink/mojo_blink_export.h
@@ -0,0 +1,32 @@ +// 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. + +#ifndef MOJO_CONVERTERS_BLINK_MOJO_BLINK_EXPORT_H_ +#define MOJO_CONVERTERS_BLINK_MOJO_BLINK_EXPORT_H_ + +#if defined(COMPONENT_BUILD) + +#if defined(WIN32) + +#if defined(MOJO_CONVERTERS_BLINK_IMPLEMENTATION) +#define MOJO_BLINK_EXPORT __declspec(dllexport) +#else +#define MOJO_BLINK_EXPORT __declspec(dllimport) +#endif + +#else // !defined(WIN32) + +#if defined(MOJO_CONVERTERS_BLINK_IMPLEMENTATION) +#define MOJO_BLINK_EXPORT __attribute__((visibility("default"))) +#else +#define MOJO_BLINK_EXPORT +#endif + +#endif // defined(WIN32) + +#else // !defined(COMPONENT_BUILD) +#define MOJO_BLINK_EXPORT +#endif + +#endif // MOJO_CONVERTERS_BLINK_MOJO_BLINK_EXPORT_H_
diff --git a/mojo/edk/embedder/embedder.cc b/mojo/edk/embedder/embedder.cc index f9b5c9daa..eb572c57 100644 --- a/mojo/edk/embedder/embedder.cc +++ b/mojo/edk/embedder/embedder.cc
@@ -28,25 +28,10 @@ namespace mojo { namespace edk { -// TODO(jam): move into annonymous namespace. Keep outside for debugging in VS -// temporarily. -int g_channel_count = 0; -bool g_wait_for_no_more_channels = false; -base::TaskRunner* g_delegate_task_runner = nullptr; // Used at shutdown. - namespace { // Note: Called on the I/O thread. -void ShutdownIPCSupportHelper(bool wait_for_no_more_channels) { - if (wait_for_no_more_channels && g_channel_count) { - g_wait_for_no_more_channels = true; - return; - } - - g_delegate_task_runner->PostTask( - FROM_HERE, base::Bind(&ProcessDelegate::OnShutdownComplete, - base::Unretained(internal::g_process_delegate))); - g_delegate_task_runner = nullptr; +void ShutdownIPCSupportHelper() { } } // namespace @@ -65,23 +50,6 @@ return g_core; } -void ChannelStarted() { - DCHECK(g_io_thread_task_runner->RunsTasksOnCurrentThread()); - g_channel_count++; -} - -void ChannelShutdown() { - DCHECK(g_io_thread_task_runner->RunsTasksOnCurrentThread()); - DCHECK_GT(g_channel_count, 0); - g_channel_count--; - if (!g_channel_count && g_wait_for_no_more_channels) { - // Reset g_wait_for_no_more_channels for unit tests which initialize and - // tear down multiple times in a process. - g_wait_for_no_more_channels = false; - ShutdownIPCSupportHelper(false); - } -} - } // namespace internal void SetMaxMessageSize(size_t bytes) { @@ -188,15 +156,11 @@ } void ShutdownIPCSupport() { - g_delegate_task_runner = base::MessageLoop::current()->task_runner().get(); - internal::g_io_thread_task_runner->PostTask( - FROM_HERE, base::Bind(&ShutdownIPCSupportHelper, false)); -} - -void ShutdownIPCSupportAndWaitForNoChannels() { - g_delegate_task_runner = base::MessageLoop::current()->task_runner().get(); - internal::g_io_thread_task_runner->PostTask( - FROM_HERE, base::Bind(&ShutdownIPCSupportHelper, true)); + internal::g_io_thread_task_runner->PostTaskAndReply( + FROM_HERE, + base::Bind(&ShutdownIPCSupportHelper), + base::Bind(&ProcessDelegate::OnShutdownComplete, + base::Unretained(internal::g_process_delegate))); } ScopedMessagePipeHandle CreateMessagePipe(
diff --git a/mojo/edk/embedder/embedder.h b/mojo/edk/embedder/embedder.h index 5ba2449..a96c610 100644 --- a/mojo/edk/embedder/embedder.h +++ b/mojo/edk/embedder/embedder.h
@@ -115,11 +115,6 @@ // |OnShutdownComplete()|. MOJO_SYSTEM_IMPL_EXPORT void ShutdownIPCSupport(); -// Like above, but doesn't call |OnShutdownComplete| until all channels are -// gone. -// TODO(jam): this should be the default behavior. -MOJO_SYSTEM_IMPL_EXPORT void ShutdownIPCSupportAndWaitForNoChannels(); - // Creates a message pipe from a platform handle. Safe to call from any thread. MOJO_SYSTEM_IMPL_EXPORT ScopedMessagePipeHandle CreateMessagePipe(ScopedPlatformHandle platform_handle);
diff --git a/mojo/edk/embedder/embedder_internal.h b/mojo/edk/embedder/embedder_internal.h index 99ea3927..a6fb2b1 100644 --- a/mojo/edk/embedder/embedder_internal.h +++ b/mojo/edk/embedder/embedder_internal.h
@@ -43,9 +43,6 @@ // TODO(use_chrome_edk): temporary until we have only one SDK. MOJO_SYSTEM_IMPL_EXPORT Core* GetCore(); -// Called on the IO thread. -void ChannelStarted(); -void ChannelShutdown(); } // namespace internal } // namepace edk
diff --git a/mojo/edk/system/multiprocess_message_pipe_unittest.cc b/mojo/edk/system/multiprocess_message_pipe_unittest.cc index 4abac12..4bb3f133 100644 --- a/mojo/edk/system/multiprocess_message_pipe_unittest.cc +++ b/mojo/edk/system/multiprocess_message_pipe_unittest.cc
@@ -166,12 +166,6 @@ nullptr, 0u, MOJO_WRITE_MESSAGE_FLAG_NONE)); } - const std::string quitquitquit("quitquitquit"); - ASSERT_EQ(MOJO_RESULT_OK, - MojoWriteMessage(mp.get().value(), quitquitquit.data(), - static_cast<uint32_t>(quitquitquit.size()), - nullptr, 0u, MOJO_WRITE_MESSAGE_FLAG_NONE)); - for (size_t i = 0; i < kNumMessages; i++) { HandleSignalsState hss; ASSERT_EQ(MOJO_RESULT_OK, @@ -194,6 +188,12 @@ ASSERT_EQ(std::string(i * 2, 'A' + (i % 26)), read_buffer); } + const std::string quitquitquit("quitquitquit"); + ASSERT_EQ(MOJO_RESULT_OK, + MojoWriteMessage(mp.get().value(), quitquitquit.data(), + static_cast<uint32_t>(quitquitquit.size()), + nullptr, 0u, MOJO_WRITE_MESSAGE_FLAG_NONE)); + // Wait for it to become readable, which should fail (since we sent // "quitquitquit"). HandleSignalsState hss;
diff --git a/mojo/edk/system/raw_channel.cc b/mojo/edk/system/raw_channel.cc index a7faead..b60438e 100644 --- a/mojo/edk/system/raw_channel.cc +++ b/mojo/edk/system/raw_channel.cc
@@ -221,7 +221,6 @@ if (initialized_) return; initialized_ = true; - internal::ChannelStarted(); base::MessageLoop::current()->AddDestructionObserver(this); OnInit(); @@ -288,7 +287,6 @@ } if (initialized_) { - internal::ChannelShutdown(); base::MessageLoop::current()->RemoveDestructionObserver(this); } delete this;
diff --git a/mojo/edk/system/raw_channel_win.cc b/mojo/edk/system/raw_channel_win.cc index fa968a4..51a8e684 100644 --- a/mojo/edk/system/raw_channel_win.cc +++ b/mojo/edk/system/raw_channel_win.cc
@@ -124,6 +124,7 @@ RawChannelIOHandler(RawChannelWin* owner, ScopedPlatformHandle handle) : handle_(handle.Pass()), + io_task_runner_(internal::g_io_thread_task_runner), owner_(owner), suppress_self_destruct_(false), pending_read_(false), @@ -465,7 +466,7 @@ // that that is always a pointer to a valid RawChannelIOHandler. RawChannelIOHandler* that = static_cast<RawChannelIOHandler*>(param); that->read_event_signalled_ = true; - internal::g_io_thread_task_runner->PostTask( + that->io_task_runner_->PostTask( FROM_HERE, base::Bind(&RawChannelIOHandler::OnObjectSignaled, that->this_weakptr_, that->read_event_.Get())); @@ -477,7 +478,7 @@ // that that is always a pointer to a valid RawChannelIOHandler. RawChannelIOHandler* that = static_cast<RawChannelIOHandler*>(param); that->write_event_signalled_ = true; - internal::g_io_thread_task_runner->PostTask( + that->io_task_runner_->PostTask( FROM_HERE, base::Bind(&RawChannelIOHandler::OnObjectSignaled, that->this_weakptr_, that->write_event_.Get())); @@ -485,6 +486,10 @@ ScopedPlatformHandle handle_; + // We cache this because ReadCompleted and WriteCompleted might get fired + // after ShutdownIPCSupport is called. + scoped_refptr<base::TaskRunner> io_task_runner_; + // |owner_| is reset on the I/O thread under |owner_->write_lock()|. // Therefore, it may be used on any thread under lock; or on the I/O thread // without locking.
diff --git a/mojo/edk/system/run_all_unittests.cc b/mojo/edk/system/run_all_unittests.cc index 71e1465..b68fd83 100644 --- a/mojo/edk/system/run_all_unittests.cc +++ b/mojo/edk/system/run_all_unittests.cc
@@ -26,10 +26,11 @@ mojo::edk::PreInitializeChildProcess(); } - mojo::edk::Init(); // TODO(use_chrome_edk): temporary to force new EDK. base::CommandLine::ForCurrentProcess()->AppendSwitch("--use-new-edk"); + mojo::edk::Init(); + return base::LaunchUnitTests( argc, argv, base::Bind(&base::TestSuite::Run, base::Unretained(&test_suite)));
diff --git a/mojo/edk/system/shared_buffer_dispatcher.cc b/mojo/edk/system/shared_buffer_dispatcher.cc index 1f15ea2..85732cf 100644 --- a/mojo/edk/system/shared_buffer_dispatcher.cc +++ b/mojo/edk/system/shared_buffer_dispatcher.cc
@@ -5,6 +5,7 @@ #include "mojo/edk/system/shared_buffer_dispatcher.h" #include <limits> +#include <utility> #include "base/logging.h" #include "base/memory/scoped_ptr.h" @@ -76,7 +77,7 @@ if (!shared_buffer) return MOJO_RESULT_RESOURCE_EXHAUSTED; - *result = CreateInternal(shared_buffer.Pass()); + *result = CreateInternal(std::move(shared_buffer)); return MOJO_RESULT_OK; } @@ -129,7 +130,7 @@ return nullptr; } - return CreateInternal(shared_buffer.Pass()); + return CreateInternal(std::move(shared_buffer)); } SharedBufferDispatcher::SharedBufferDispatcher( @@ -183,7 +184,7 @@ SharedBufferDispatcher::CreateEquivalentDispatcherAndCloseImplNoLock() { lock().AssertAcquired(); DCHECK(shared_buffer_); - return CreateInternal(shared_buffer_.Pass()); + return CreateInternal(std::move(shared_buffer_)); } MojoResult SharedBufferDispatcher::DuplicateBufferHandleImplNoLock(
diff --git a/mojo/edk/system/shared_buffer_dispatcher.h b/mojo/edk/system/shared_buffer_dispatcher.h index f3fc9e80c..90755603 100644 --- a/mojo/edk/system/shared_buffer_dispatcher.h +++ b/mojo/edk/system/shared_buffer_dispatcher.h
@@ -5,6 +5,8 @@ #ifndef MOJO_EDK_SYSTEM_SHARED_BUFFER_DISPATCHER_H_ #define MOJO_EDK_SYSTEM_SHARED_BUFFER_DISPATCHER_H_ +#include <utility> + #include "mojo/edk/embedder/platform_shared_buffer.h" #include "mojo/edk/system/simple_dispatcher.h" #include "mojo/edk/system/system_impl_export.h" @@ -58,7 +60,8 @@ private: static scoped_refptr<SharedBufferDispatcher> CreateInternal( scoped_refptr<PlatformSharedBuffer> shared_buffer) { - return make_scoped_refptr(new SharedBufferDispatcher(shared_buffer.Pass())); + return make_scoped_refptr( + new SharedBufferDispatcher(std::move(shared_buffer))); } explicit SharedBufferDispatcher(
diff --git a/mojo/edk/test/scoped_ipc_support.cc b/mojo/edk/test/scoped_ipc_support.cc index 6e9c11c..68e7ac2fa 100644 --- a/mojo/edk/test/scoped_ipc_support.cc +++ b/mojo/edk/test/scoped_ipc_support.cc
@@ -4,6 +4,8 @@ #include "mojo/edk/test/scoped_ipc_support.h" +#include <utility> + #include "base/message_loop/message_loop.h" #include "mojo/edk/embedder/embedder.h" @@ -21,7 +23,7 @@ base::MessageLoop::current()->task_runner() == io_thread_task_runner_) { ShutdownIPCSupportOnIOThread(); } else { - ShutdownIPCSupportAndWaitForNoChannels(); + ShutdownIPCSupport(); run_loop_.Run(); } } @@ -41,7 +43,7 @@ ScopedIPCSupport::ScopedIPCSupport( scoped_refptr<base::TaskRunner> io_thread_task_runner) { - helper_.Init(this, io_thread_task_runner.Pass()); + helper_.Init(this, std::move(io_thread_task_runner)); } ScopedIPCSupport::~ScopedIPCSupport() {
diff --git a/mojo/generate_mojo_shell_assets_list.gni b/mojo/generate_mojo_shell_assets_list.gni deleted file mode 100644 index a8c7cb8..0000000 --- a/mojo/generate_mojo_shell_assets_list.gni +++ /dev/null
@@ -1,25 +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. - -# Used to generate an assets_list file. To use supply the argument 'dir', which -# is where the assets can be found. -# TODO(sky): Perhaps combine this with the copy step? -template("generate_mojo_shell_assets_list") { - action(target_name) { - script = "//mojo/tools/generate_mojo_shell_assets_list.py" - args = [ - "--dir", - rebase_path(invoker.dir, root_build_dir), - ] - outputs = [ - invoker.dir + "/assets_list", - ] - if (defined(invoker.deps)) { - deps = invoker.deps - } - if (defined(invoker.testonly)) { - testonly = invoker.testonly - } - } -}
diff --git a/mojo/gpu/mojo_gles2_impl_autogen.cc b/mojo/gpu/mojo_gles2_impl_autogen.cc index 8f817e3b..2b2538a 100644 --- a/mojo/gpu/mojo_gles2_impl_autogen.cc +++ b/mojo/gpu/mojo_gles2_impl_autogen.cc
@@ -1909,5 +1909,22 @@ MojoGLES2MakeCurrent(context_); glApplyScreenSpaceAntialiasingCHROMIUM(); } +void MojoGLES2Impl::BindFragDataLocationIndexedEXT(GLuint program, + GLuint colorNumber, + GLuint index, + const char* name) { + MojoGLES2MakeCurrent(context_); + glBindFragDataLocationIndexedEXT(program, colorNumber, index, name); +} +void MojoGLES2Impl::BindFragDataLocationEXT(GLuint program, + GLuint colorNumber, + const char* name) { + MojoGLES2MakeCurrent(context_); + glBindFragDataLocationEXT(program, colorNumber, name); +} +GLint MojoGLES2Impl::GetFragDataIndexEXT(GLuint program, const char* name) { + MojoGLES2MakeCurrent(context_); + return glGetFragDataIndexEXT(program, name); +} } // namespace mojo
diff --git a/mojo/gpu/mojo_gles2_impl_autogen.h b/mojo/gpu/mojo_gles2_impl_autogen.h index e207ca49..c00372dd 100644 --- a/mojo/gpu/mojo_gles2_impl_autogen.h +++ b/mojo/gpu/mojo_gles2_impl_autogen.h
@@ -888,6 +888,14 @@ GLenum GetGraphicsResetStatusKHR() override; void BlendBarrierKHR() override; void ApplyScreenSpaceAntialiasingCHROMIUM() override; + void BindFragDataLocationIndexedEXT(GLuint program, + GLuint colorNumber, + GLuint index, + const char* name) override; + void BindFragDataLocationEXT(GLuint program, + GLuint colorNumber, + const char* name) override; + GLint GetFragDataIndexEXT(GLuint program, const char* name) override; private: MojoGLES2Context context_;
diff --git a/mojo/public/c/gles2/gles2_call_visitor_chromium_extension_autogen.h b/mojo/public/c/gles2/gles2_call_visitor_chromium_extension_autogen.h index a6c8585..c0668d3c 100644 --- a/mojo/public/c/gles2/gles2_call_visitor_chromium_extension_autogen.h +++ b/mojo/public/c/gles2/gles2_call_visitor_chromium_extension_autogen.h
@@ -568,3 +568,16 @@ VISIT_GL_CALL(GetGraphicsResetStatusKHR, GLenum, (), ()) VISIT_GL_CALL(BlendBarrierKHR, void, (), ()) VISIT_GL_CALL(ApplyScreenSpaceAntialiasingCHROMIUM, void, (), ()) +VISIT_GL_CALL( + BindFragDataLocationIndexedEXT, + void, + (GLuint program, GLuint colorNumber, GLuint index, const char* name), + (program, colorNumber, index, name)) +VISIT_GL_CALL(BindFragDataLocationEXT, + void, + (GLuint program, GLuint colorNumber, const char* name), + (program, colorNumber, name)) +VISIT_GL_CALL(GetFragDataIndexEXT, + GLint, + (GLuint program, const char* name), + (program, name))
diff --git a/mojo/public/cpp/bindings/lib/bindings_serialization.cc b/mojo/public/cpp/bindings/lib/bindings_serialization.cc index 22733c26..d9ced4c3 100644 --- a/mojo/public/cpp/bindings/lib/bindings_serialization.cc +++ b/mojo/public/cpp/bindings/lib/bindings_serialization.cc
@@ -90,7 +90,7 @@ SerializationContext::SerializationContext( scoped_refptr<MultiplexRouter> in_router) - : router(in_router.Pass()) {} + : router(std::move(in_router)) {} SerializationContext::~SerializationContext() {}
diff --git a/mojo/public/cpp/bindings/lib/multiplex_router.cc b/mojo/public/cpp/bindings/lib/multiplex_router.cc index c09fc17..69defac 100644 --- a/mojo/public/cpp/bindings/lib/multiplex_router.cc +++ b/mojo/public/cpp/bindings/lib/multiplex_router.cc
@@ -4,6 +4,8 @@ #include "mojo/public/cpp/bindings/lib/multiplex_router.h" +#include <utility> + #include "base/bind.h" #include "base/message_loop/message_loop.h" #include "base/stl_util.h" @@ -49,7 +51,7 @@ void set_task_runner( scoped_refptr<base::SingleThreadTaskRunner> task_runner) { router_lock_->AssertAcquired(); - task_runner_ = task_runner.Pass(); + task_runner_ = std::move(task_runner); } InterfaceEndpointClient* client() const { return client_; }
diff --git a/mojo/public/cpp/bindings/lib/scoped_interface_endpoint_handle.cc b/mojo/public/cpp/bindings/lib/scoped_interface_endpoint_handle.cc index 6f30c94..dfe4e234 100644 --- a/mojo/public/cpp/bindings/lib/scoped_interface_endpoint_handle.cc +++ b/mojo/public/cpp/bindings/lib/scoped_interface_endpoint_handle.cc
@@ -17,7 +17,7 @@ InterfaceId id, bool is_local, scoped_refptr<MultiplexRouter> router) - : id_(id), is_local_(is_local), router_(router.Pass()) { + : id_(id), is_local_(is_local), router_(std::move(router)) { DCHECK(!IsValidInterfaceId(id) || router_); }
diff --git a/mojo/public/cpp/bindings/lib/scoped_interface_endpoint_handle.h b/mojo/public/cpp/bindings/lib/scoped_interface_endpoint_handle.h index 09ee7ca7..c4527d0 100644 --- a/mojo/public/cpp/bindings/lib/scoped_interface_endpoint_handle.h +++ b/mojo/public/cpp/bindings/lib/scoped_interface_endpoint_handle.h
@@ -7,6 +7,7 @@ #include "base/macros.h" #include "base/memory/ref_counted.h" +#include "base/move.h" #include "mojo/public/cpp/bindings/lib/interface_id.h" namespace mojo {
diff --git a/mojo/public/cpp/system/macros.h b/mojo/public/cpp/system/macros.h index 7f0fcd7..b565f12 100644 --- a/mojo/public/cpp/system/macros.h +++ b/mojo/public/cpp/system/macros.h
@@ -35,8 +35,8 @@ // to tell that this type is move-only. #define MOJO_MOVE_ONLY_TYPE(type) \ private: \ - type(type&); \ - void operator=(type&); \ + type(const type&) = delete; \ + void operator=(const type&) = delete; \ \ public: \ type&& Pass() MOJO_WARN_UNUSED_RESULT { return static_cast<type&&>(*this); } \
diff --git a/mojo/public/java/BUILD.gn b/mojo/public/java/BUILD.gn index d543394a..dd819cf 100644 --- a/mojo/public/java/BUILD.gn +++ b/mojo/public/java/BUILD.gn
@@ -25,6 +25,8 @@ android_library("bindings") { java_files = [ + "bindings/src/org/chromium/mojo/bindings/AssociatedInterfaceNotSupported.java", + "bindings/src/org/chromium/mojo/bindings/AssociatedInterfaceRequestNotSupported.java", "bindings/src/org/chromium/mojo/bindings/AutoCloseableRouter.java", "bindings/src/org/chromium/mojo/bindings/BindingsHelper.java", "bindings/src/org/chromium/mojo/bindings/Callbacks.java",
diff --git a/mojo/public/java/bindings/src/org/chromium/mojo/bindings/AssociatedInterfaceNotSupported.java b/mojo/public/java/bindings/src/org/chromium/mojo/bindings/AssociatedInterfaceNotSupported.java new file mode 100644 index 0000000..ee8f631 --- /dev/null +++ b/mojo/public/java/bindings/src/org/chromium/mojo/bindings/AssociatedInterfaceNotSupported.java
@@ -0,0 +1,11 @@ +// 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.mojo.bindings; + +/** + * Associated interface is not supported yet. + */ +public class AssociatedInterfaceNotSupported { +}
diff --git a/mojo/public/java/bindings/src/org/chromium/mojo/bindings/AssociatedInterfaceRequestNotSupported.java b/mojo/public/java/bindings/src/org/chromium/mojo/bindings/AssociatedInterfaceRequestNotSupported.java new file mode 100644 index 0000000..1b07cd1 --- /dev/null +++ b/mojo/public/java/bindings/src/org/chromium/mojo/bindings/AssociatedInterfaceRequestNotSupported.java
@@ -0,0 +1,11 @@ +// 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.mojo.bindings; + +/** + * Associated interface is not supported yet. + */ +public class AssociatedInterfaceRequestNotSupported { +}
diff --git a/mojo/public/java/bindings/src/org/chromium/mojo/bindings/Decoder.java b/mojo/public/java/bindings/src/org/chromium/mojo/bindings/Decoder.java index 868eab6..6e4eba6 100644 --- a/mojo/public/java/bindings/src/org/chromium/mojo/bindings/Decoder.java +++ b/mojo/public/java/bindings/src/org/chromium/mojo/bindings/Decoder.java
@@ -494,6 +494,22 @@ } /** + * Deserializes an associated interface at the given offset. Not yet supported. + */ + public AssociatedInterfaceNotSupported readAssociatedServiceInterfaceNotSupported(int offset, + boolean nullable) { + return null; + } + + /** + * Deserializes an associated interface request at the given offset. Not yet supported. + */ + public AssociatedInterfaceRequestNotSupported readAssociatedInterfaceRequestNotSupported( + int offset, boolean nullable) { + return null; + } + + /** * Deserializes a string at the given offset. */ public String readString(int offset, boolean nullable) {
diff --git a/mojo/public/java/bindings/src/org/chromium/mojo/bindings/Encoder.java b/mojo/public/java/bindings/src/org/chromium/mojo/bindings/Encoder.java index 3541f21..7532736 100644 --- a/mojo/public/java/bindings/src/org/chromium/mojo/bindings/Encoder.java +++ b/mojo/public/java/bindings/src/org/chromium/mojo/bindings/Encoder.java
@@ -304,6 +304,18 @@ } /** + * Encode an associated interface. Not yet supported. + */ + public void encode(AssociatedInterfaceNotSupported v, int offset, boolean nullable) { + } + + /** + * Encode an associated interface request. Not yet supported. + */ + public void encode(AssociatedInterfaceRequestNotSupported v, int offset, boolean nullable) { + } + + /** * Returns an {@link Encoder} suitable for encoding an array of pointer of the given length. */ public Encoder encodePointerArray(int length, int offset, int expectedLength) {
diff --git a/mojo/public/tools/bindings/generators/cpp_templates/interface_definition.tmpl b/mojo/public/tools/bindings/generators/cpp_templates/interface_definition.tmpl index 267872a..9889f8b 100644 --- a/mojo/public/tools/bindings/generators/cpp_templates/interface_definition.tmpl +++ b/mojo/public/tools/bindings/generators/cpp_templates/interface_definition.tmpl
@@ -16,7 +16,7 @@ {%- macro pass_params(parameters) %} {%- for param in parameters %} {%- if param.kind|is_move_only_kind -%} -p_{{param.name}}.Pass() +std::move(p_{{param.name}}) {%- else -%} p_{{param.name}} {%- endif -%} @@ -56,7 +56,7 @@ {{class_name}}_{{method.name}}_ForwardToCallback( const {{class_name}}::{{method.name}}Callback& callback, scoped_refptr<mojo::internal::MultiplexRouter> router) - : callback_(callback), serialization_context_(router.Pass()) { + : callback_(callback), serialization_context_(std::move(router)) { } bool Accept(mojo::Message* message) override; private:
diff --git a/mojo/runner/BUILD.gn b/mojo/runner/BUILD.gn index 1496e4e..64ba3f87 100644 --- a/mojo/runner/BUILD.gn +++ b/mojo/runner/BUILD.gn
@@ -2,7 +2,6 @@ # Use of this source code is governed by a BSD-style license that can be # found in the LICENSE file. -import("//mojo/generate_mojo_shell_assets_list.gni") import("//mojo/public/mojo_application.gni") import("//mojo/public/tools/bindings/mojom.gni") import("//testing/test.gni") @@ -268,12 +267,21 @@ custom_package = "org.chromium.mojo.shell" } - android_assets("mojo_runner_apptests_assets") { - testonly = true - + android_assets("android_assets") { deps = [ ":bootstrap", ":bootstrap_java", + ] + sources = [ + "$root_out_dir/obj/mojo/runner/bootstrap_java.dex.jar", + "$root_shlib_dir/${shlib_prefix}bootstrap$shlib_extension", + ] + } + + android_assets("mojo_runner_apptests_assets") { + testonly = true + deps = [ + ":android_assets", "//components/clipboard:apptests_assets", "//components/clipboard:clipboard_assets", "//components/mus/ws:apptests_assets", @@ -283,11 +291,6 @@ "//mojo/services/network:network_assets", "//third_party/icu:icu_assets", ] - - sources = [ - "$root_out_dir/obj/mojo/runner/bootstrap_java.dex.jar", - "$root_shlib_dir/${shlib_prefix}bootstrap$shlib_extension", - ] } copy("copy_mojo_runner") {
diff --git a/mojo/runner/host/BUILD.gn b/mojo/runner/host/BUILD.gn index 713251e..3bfd5aa 100644 --- a/mojo/runner/host/BUILD.gn +++ b/mojo/runner/host/BUILD.gn
@@ -2,7 +2,6 @@ # Use of this source code is governed by a BSD-style license that can be # found in the LICENSE file. -import("//mojo/generate_mojo_shell_assets_list.gni") import("//mojo/public/mojo_application.gni") import("//mojo/public/tools/bindings/mojom.gni") import("//testing/test.gni")
diff --git a/mojo/tools/data/apptests b/mojo/tools/data/apptests index c51c5cf..27b077a 100644 --- a/mojo/tools/data/apptests +++ b/mojo/tools/data/apptests
@@ -46,7 +46,6 @@ # 'test': 'mojo:runner_apptests', # 'type': 'gtest_isolated', #}, - mus_apptests, ] # TODO(msw): Get these tests passing on Android too. http://crbug.com/486220 @@ -77,18 +76,21 @@ 'test': 'mojo:mandoline_browser_apptests', 'type': 'gtest_isolated', }, - { - 'test': 'mojo:mash_wm_apptests', - 'type': 'gtest_isolated', - 'args': ['--use-x11-test-config', - '--override-use-gl-with-osmesa-for-tests'] - }, + # TODO(sky): flakey, http://crbug.com/559412 . + # { + # 'test': 'mojo:mash_wm_apptests', + # 'type': 'gtest_isolated', + # 'args': ['--use-x11-test-config', + # '--override-use-gl-with-osmesa-for-tests'] + # }, # TODO(xhwang): Fix and enable mojo:media_pipeline_integration_apptests. # http://crbug.com/501417 { 'test': 'mojo:media_apptests', 'type': 'gtest_isolated', }, + # TODO(crbug.com/560626): Fix and enable mus_apptests on Android. + mus_apptests, { 'test': 'mojo:sql_apptests', 'type': 'gtest_isolated',
diff --git a/mojo/tools/generate_mojo_shell_assets_list.py b/mojo/tools/generate_mojo_shell_assets_list.py deleted file mode 100755 index 1018e943..0000000 --- a/mojo/tools/generate_mojo_shell_assets_list.py +++ /dev/null
@@ -1,46 +0,0 @@ -#!/usr/bin/env python -# -# Copyright 2015 The Chromium Authors. All rights reserved. -# Use of this source code is governed by a BSD-style license that can be -# found in the LICENSE file. - -'''Generates the assets_list file from a directory.''' - -import argparse -import os -import sys - -def main(): - parser = argparse.ArgumentParser(usage='--dir <directory>') - - parser.add_argument('--dir', help='Directory read files from.', required=True) - - options, _ = parser.parse_known_args() - - if not os.path.exists(options.dir) or not os.path.isdir(options.dir): - print 'Directory does not exist, or path is not a directory', options.dir - return -1 - - root_dir = os.path.abspath(options.dir) - all_files = [] - for current_root, _, files in os.walk(options.dir): - current_root_absolute = os.path.abspath(current_root) - if len(current_root_absolute) < len(root_dir): - print 'unexpected directory', current_root_absolute - return -1 - rel_root = current_root_absolute[len(root_dir):] - if len(rel_root) and rel_root.startswith(os.sep): - rel_root = rel_root[len(os.sep):] - if len(rel_root) and not rel_root.endswith(os.sep): - rel_root += os.sep - all_files.extend([rel_root + f for f in files]) - - with open(os.path.join(options.dir, 'assets_list'), 'w') as f: - for a_file in all_files: - f.write(a_file + '\n') - - return 0 - -if __name__ == '__main__': - sys.exit(main()) -
diff --git a/net/BUILD.gn b/net/BUILD.gn index f0081df..8623889 100644 --- a/net/BUILD.gn +++ b/net/BUILD.gn
@@ -573,6 +573,7 @@ "cookies/cookie_store_test_callbacks.h", "cookies/cookie_store_test_helpers.cc", "cookies/cookie_store_test_helpers.h", + "cookies/cookie_store_unittest.h", "disk_cache/disk_cache_test_base.cc", "disk_cache/disk_cache_test_base.h", "disk_cache/disk_cache_test_util.cc",
diff --git a/net/base/hash_value.cc b/net/base/hash_value.cc index 2a751cd2..7f2e479e 100644 --- a/net/base/hash_value.cc +++ b/net/base/hash_value.cc
@@ -31,6 +31,15 @@ return memcmp(data, other.data, sizeof(data)) == 0; } +HashValue::HashValue(const SHA1HashValue& hash) : HashValue(HASH_VALUE_SHA1) { + fingerprint.sha1 = hash; +} + +HashValue::HashValue(const SHA256HashValue& hash) + : HashValue(HASH_VALUE_SHA256) { + fingerprint.sha256 = hash; +} + bool HashValue::Equals(const HashValue& other) const { if (tag != other.tag) return false;
diff --git a/net/base/hash_value.h b/net/base/hash_value.h index a9e0b63..f2d217f 100644 --- a/net/base/hash_value.h +++ b/net/base/hash_value.h
@@ -36,6 +36,8 @@ class NET_EXPORT HashValue { public: + explicit HashValue(const SHA1HashValue& hash); + explicit HashValue(const SHA256HashValue& hash); explicit HashValue(HashValueTag tag) : tag(tag) {} HashValue() : tag(HASH_VALUE_SHA1) {}
diff --git a/net/base/ip_address.cc b/net/base/ip_address.cc new file mode 100644 index 0000000..99078b8 --- /dev/null +++ b/net/base/ip_address.cc
@@ -0,0 +1,67 @@ +// Copyright (c) 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. + +#include "net/base/ip_address.h" + +#include "net/base/ip_address_number.h" +#include "url/gurl.h" +#include "url/url_canon_ip.h" + +namespace net { + +const size_t IPAddress::kIPv4AddressSize = 4; +const size_t IPAddress::kIPv6AddressSize = 16; + +IPAddress::IPAddress() {} + +IPAddress::~IPAddress() {} + +IPAddress::IPAddress(const uint8_t* address, size_t address_len) + : ip_address_(address, address + address_len) {} + +bool IPAddress::IsIPv4() const { + return ip_address_.size() == kIPv4AddressSize; +} + +bool IPAddress::IsIPv6() const { + return ip_address_.size() == kIPv6AddressSize; +} + +bool IPAddress::IsReserved() const { + return IsIPAddressReserved(ip_address_); +} + +bool IPAddress::IsIPv4Mapped() const { + return net::IsIPv4Mapped(ip_address_); +} + +std::string IPAddress::ToString() const { + return IPAddressToString(ip_address_); +} + +// static +bool IPAddress::FromIPLiteral(const base::StringPiece& ip_literal, + IPAddress* ip_address) { + std::vector<uint8_t> number; + if (!ParseIPLiteralToNumber(ip_literal, &number)) + return false; + + std::swap(number, ip_address->ip_address_); + return true; +} + +bool IPAddress::operator==(const IPAddress& that) const { + return ip_address_ == that.ip_address_; +} + +bool IPAddress::operator<(const IPAddress& that) const { + // Sort IPv4 before IPv6. + if (ip_address_.size() != that.ip_address_.size()) { + return ip_address_.size() < that.ip_address_.size(); + } + + return ip_address_ < that.ip_address_; +} + +} // namespace net
diff --git a/net/base/ip_address.h b/net/base/ip_address.h new file mode 100644 index 0000000..37a5ab6 --- /dev/null +++ b/net/base/ip_address.h
@@ -0,0 +1,71 @@ +// Copyright (c) 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. + +#ifndef NET_BASE_IP_ADDRESS_NET_H_ +#define NET_BASE_IP_ADDRESS_NET_H_ + +#include <vector> + +#include "base/basictypes.h" +#include "base/compiler_specific.h" +#include "base/strings/string_piece.h" +#include "net/base/net_export.h" + +namespace net { + +class NET_EXPORT IPAddress { + public: + static const size_t kIPv4AddressSize; + static const size_t kIPv6AddressSize; + + // Creates a zero-sized, invalid address. + IPAddress(); + + // Copies the input address to |ip_address_|. The input is expected to be in + // network byte order. + IPAddress(const uint8_t* address, size_t address_len); + ~IPAddress(); + + // Returns true if the IP has |kIPv4AddressSize| elements. + bool IsIPv4() const; + + // Returns true if the IP has |kIPv6AddressSize| elements. + bool IsIPv6() const; + + // Returns true if an IP address hostname is in a range reserved by the IANA. + // Works with both IPv4 and IPv6 addresses, and only compares against a given + // protocols's reserved ranges. + bool IsReserved() const; + + // Returns true if |ip_address_| is an IPv4-mapped IPv6 address. + bool IsIPv4Mapped() const; + + // The size in bytes of |ip_address_|. + size_t size() const { return ip_address_.size(); } + + // Returns the canonical string representation of an IP address. + // For example: "192.168.0.1" or "::1". The IP address must be + // valid, calling this on an invalid address will result in a crash. + std::string ToString() const; + + // Parses an IP address literal (either IPv4 or IPv6) to its numeric value. + // Returns true on success and fills |ip_address| with the numeric value. + static bool FromIPLiteral(const base::StringPiece& ip_literal, + IPAddress* ip_address) WARN_UNUSED_RESULT; + + // Returns the underlying byte vector. + const std::vector<uint8_t>& bytes() const { return ip_address_; }; + + bool operator==(const IPAddress& that) const; + bool operator<(const IPAddress& that) const; + + private: + // IPv4 addresses will have length kIPv4AddressSize, whereas IPv6 address + // will have length kIPv6AddressSize. + std::vector<uint8_t> ip_address_; +}; + +} // namespace net + +#endif // NET_BASE_IP_ADDRESS_NET_H_
diff --git a/net/base/ip_address_number.h b/net/base/ip_address_number.h index b105875..bce3c980 100644 --- a/net/base/ip_address_number.h +++ b/net/base/ip_address_number.h
@@ -19,6 +19,10 @@ // network byte ordering. // // IPv4 addresses will have length 4, whereas IPv6 address will have length 16. +// +// TODO(Martijnc): Remove the IPAddressNumber typedef. New code should use +// IPAddress instead and existing code should be switched over. +// https://crbug.com/496258 typedef std::vector<unsigned char> IPAddressNumber; // This is also duplicated in net_util.h typedef std::vector<IPAddressNumber> IPAddressList;
diff --git a/net/base/ip_address_unittest.cc b/net/base/ip_address_unittest.cc new file mode 100644 index 0000000..d977b22 --- /dev/null +++ b/net/base/ip_address_unittest.cc
@@ -0,0 +1,134 @@ +// Copyright (c) 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. + +#include "net/base/ip_address.h" + +#include <vector> + +#include "base/strings/string_number_conversions.h" +#include "testing/gtest/include/gtest/gtest.h" + +namespace net { + +namespace { + +// Helper to stringize an IP number (used to define expectations). +std::string DumpIPAddress(const IPAddress& v) { + std::string out; + for (size_t i = 0; i < v.bytes().size(); ++i) { + if (i != 0) + out.append(","); + out.append(base::UintToString(v.bytes()[i])); + } + return out; +} + +template <size_t N> +IPAddress ArrayToIPAdress(const uint8_t(&address)[N]) { + return IPAddress(address, N); +} + +TEST(IPAddressTest, IsIPVersion) { + uint8_t addr1[4] = {192, 168, 0, 1}; + IPAddress ip_address1 = ArrayToIPAdress(addr1); + EXPECT_TRUE(ip_address1.IsIPv4()); + EXPECT_FALSE(ip_address1.IsIPv6()); + + uint8_t addr2[16] = {0xFE, 0xDC, 0xBA, 0x98}; + IPAddress ip_address2 = ArrayToIPAdress(addr2); + EXPECT_TRUE(ip_address2.IsIPv6()); + EXPECT_FALSE(ip_address2.IsIPv4()); + + IPAddress ip_address3 = IPAddress(); + EXPECT_FALSE(ip_address3.IsIPv6()); + EXPECT_FALSE(ip_address3.IsIPv4()); +} + +TEST(IPAddressTest, ToString) { + uint8_t addr1[4] = {0, 0, 0, 0}; + IPAddress ip_address1 = ArrayToIPAdress(addr1); + EXPECT_EQ("0.0.0.0", ip_address1.ToString()); + + uint8_t addr2[4] = {192, 168, 0, 1}; + IPAddress ip_address2 = ArrayToIPAdress(addr2); + EXPECT_EQ("192.168.0.1", ip_address2.ToString()); + + uint8_t addr3[16] = {0xFE, 0xDC, 0xBA, 0x98}; + IPAddress ip_address3 = ArrayToIPAdress(addr3); + EXPECT_EQ("fedc:ba98::", ip_address3.ToString()); +} + +// Test that invalid IP literals fail to parse. +TEST(IPAddressTest, FromIPLiteral_FailParse) { + IPAddress address; + + EXPECT_FALSE(IPAddress::FromIPLiteral("bad value", &address)); + EXPECT_FALSE(IPAddress::FromIPLiteral("bad:value", &address)); + EXPECT_FALSE(IPAddress::FromIPLiteral(std::string(), &address)); + EXPECT_FALSE(IPAddress::FromIPLiteral("192.168.0.1:30", &address)); + EXPECT_FALSE(IPAddress::FromIPLiteral(" 192.168.0.1 ", &address)); + EXPECT_FALSE(IPAddress::FromIPLiteral("[::1]", &address)); +} + +// Test parsing an IPv4 literal. +TEST(IPAddressTest, FromIPLiteral_IPv4) { + IPAddress address; + EXPECT_TRUE(IPAddress::FromIPLiteral("192.168.0.1", &address)); + EXPECT_EQ("192,168,0,1", DumpIPAddress(address)); + EXPECT_EQ("192.168.0.1", address.ToString()); +} + +// Test parsing an IPv6 literal. +TEST(IPAddressTest, FromIPLiteral_IPv6) { + IPAddress address; + EXPECT_TRUE(IPAddress::FromIPLiteral("1:abcd::3:4:ff", &address)); + EXPECT_EQ("0,1,171,205,0,0,0,0,0,0,0,3,0,4,0,255", DumpIPAddress(address)); + EXPECT_EQ("1:abcd::3:4:ff", address.ToString()); +} + +TEST(IPAddressTest, IsIPv4Mapped) { + IPAddress ipv4_address; + EXPECT_TRUE(IPAddress::FromIPLiteral("192.168.0.1", &ipv4_address)); + EXPECT_FALSE(ipv4_address.IsIPv4Mapped()); + + IPAddress ipv6_address; + EXPECT_TRUE(IPAddress::FromIPLiteral("::1", &ipv4_address)); + EXPECT_FALSE(ipv6_address.IsIPv4Mapped()); + + IPAddress ipv4mapped_address; + EXPECT_TRUE(IPAddress::FromIPLiteral("::ffff:0101:1", &ipv4mapped_address)); + EXPECT_TRUE(ipv4mapped_address.IsIPv4Mapped()); +} + +TEST(IPAddressTest, IsEqual) { + IPAddress ip_address1; + EXPECT_TRUE(IPAddress::FromIPLiteral("127.0.0.1", &ip_address1)); + IPAddress ip_address2; + EXPECT_TRUE(IPAddress::FromIPLiteral("2001:db8:0::42", &ip_address2)); + IPAddress ip_address3; + EXPECT_TRUE(IPAddress::FromIPLiteral("127.0.0.1", &ip_address3)); + + EXPECT_FALSE(ip_address1 == ip_address2); + EXPECT_TRUE(ip_address1 == ip_address3); +} + +TEST(IPAddressTest, LessThan) { + // IPv4 vs IPv6 + IPAddress ip_address1; + EXPECT_TRUE(IPAddress::FromIPLiteral("127.0.0.1", &ip_address1)); + IPAddress ip_address2; + EXPECT_TRUE(IPAddress::FromIPLiteral("2001:db8:0::42", &ip_address2)); + EXPECT_TRUE(ip_address1 < ip_address2); + EXPECT_FALSE(ip_address2 < ip_address1); + + // Compare equivalent addresses. + IPAddress ip_address3; + EXPECT_TRUE(IPAddress::FromIPLiteral("127.0.0.1", &ip_address3)); + EXPECT_FALSE(ip_address1 < ip_address3); + EXPECT_FALSE(ip_address3 < ip_address1); +} + +} // anonymous namespace + +} // namespace net
diff --git a/net/base/stale_while_revalidate_experiment_domains.gperf b/net/base/stale_while_revalidate_experiment_domains.gperf index 24bf21a..06917432 100644 --- a/net/base/stale_while_revalidate_experiment_domains.gperf +++ b/net/base/stale_while_revalidate_experiment_domains.gperf
@@ -1,117 +1,116 @@ %{ -// List of top 98 domains* which are expected to benefit from the implementation -// of the stale-while-revalidate Cache-Control directive. The list is derived -// from public information (the HTTPArchive) and ordered by ranking. This list +// List of top 100 domains which are expected to benefit from the implementation +// of the stale-while-revalidate Cache-Control directive. This list // is only used to generate histograms to measure the effectiveness of the // feature. These domains are given no special treatment. // // This file is temporary for the duration of the evaluation of the -// stale-while-revalidate feature. +// stale-while-revalidate feature. crbug.com/564517 // This file is converted to a DAFSA by make_dafsa.py. -// *Two domains appear in effective_tld_names.dat and so were manually removed. - %} %% -blogspot.com, 0 -wordpress.com, 0 -blogspot.in, 0 -tumblr.com, 0 -blogspot.com.br, 0 -myshopify.com, 0 -blogspot.gr, 0 -altervista.org, 0 -weebly.com, 0 -blogspot.com.es, 0 -blogspot.it, 0 -uol.com.br, 0 -blogspot.pt, 0 -blogspot.co.uk, 0 -blogspot.mx, 0 -appspot.com, 0 -blogspot.fr, 0 -blogspot.com.tr, 0 -blog.pl, 0 -squarespace.com, 0 -blogspot.com.ar, 0 -jimdo.com, 0 -blogspot.ca, 0 -mybigcommerce.com, 0 -blogspot.sg, 0 -typepad.com, 0 -blogspot.com.au, 0 -esy.es, 0 -sapo.pt, 0 -over-blog.com, 0 -blogspot.ro, 0 -ucoz.ru, 0 -webnode.com, 0 -livejournal.com, 0 -16mb.com, 0 -blogspot.nl, 0 -narod.ru, 0 -sextgem.com, 0 -us.com, 0 -ecwid.com, 0 -ucoz.com, 0 -tripod.com, 0 -n.nu, 0 -ning.com, 0 -free.fr, 0 -webs.com, 0 -sitew.com, 0 -onclickads.net, 0 -diply.com, 0 -adcash.com, 0 +123rf.com, 0 +academia.edu, 0 +avclub.com, 0 +baixaki.com.br, 0 +bgr.com, 0 +britannica.com, 0 +buenastareas.com, 0 +buscape.com.br, 0 +cbslocal.com, 0 +cbssports.com, 0 +ccm.net, 0 +chegg.com, 0 +clarin.com, 0 +commentcamarche.net, 0 +coursehero.com, 0 +crunchbase.com, 0 +deadline.com, 0 +dicionarioinformal.com.br, 0 +digitaltrends.com, 0 dropbox.com, 0 -directrev.com, 0 -weather.com, 0 -deviantart.com, 0 -terraclicks.com, 0 -taboola.com, 0 -abs-cbnnews.com, 0 -wordpress.org, 0 -w3schools.com, 0 -mediafire.com, 0 -mystart.com, 0 -doublepimp.com, 0 -ndtv.com, 0 -youm7.com, 0 -addthis.com, 0 -popcash.net, 0 -sourceforge.net, 0 -likes.com, 0 -chinatimes.com, 0 -speedtest.net, 0 -kaskus.co.id, 0 -stumbleupon.com, 0 -reimageplus.com, 0 -conservativetribune.com, 0 -hootsuite.com, 0 -slickdeals.net, 0 -samsung.com, 0 -buzzfil.net, 0 -elmogaz.com, 0 -bhaskar.com, 0 -wow.com, 0 -marca.com, 0 -kompas.com, 0 -xda-developers.com, 0 -naukri.com, 0 -flirchi.com, 0 -bookmyshow.com, 0 -independent.co.uk, 0 -urdupoint.com, 0 -exoclick.com, 0 -slack.com, 0 -moneycontrol.com, 0 -pof.com, 0 -onedio.com, 0 -nasa.gov, 0 +encyclopedia.com, 0 +enotes.com, 0 +eonline.com, 0 +express.co.uk, 0 +extradeportes.net, 0 +firstpost.com, 0 +food.com, 0 +foxnews.com, 0 +giphy.com, 0 +gmailblog.blogspot.com, 0 +goodreads.com, 0 +googleapps.com, 0 +googleblog.blogspot.com, 0 +guiamais.com.br, 0 +gumtree.com, 0 +haberler.com, 0 +heavy.com, 0 +history.com, 0 +hollywoodlife.com, 0 +howtogeek.com, 0 +ibtimes.co.in, 0 +ilpost.it, 0 +iltalehti.fi, 0 +iltasanomat.fi, 0 instructables.com, 0 -savefrom.net, 0 -issuu.com, 0 +journaldesfemmes.com, 0 +kekanto.com.br, 0 +lavanguardia.com, 0 +legacy.com, 0 +liberoquotidiano.it, 0 +linternaute.com, 0 +livescience.com, 0 +lolking.net, 0 +marmiton.org, 0 +meinestadt.de, 0 +merriam-webster.com, 0 +miniclip.com, 0 +mmajunkie.com, 0 +mobile01.com, 0 +moviepilot.de, 0 +mymovies.it, 0 +naszemiasto.pl, 0 +natemat.pl, 0 +ndtv.com, 0 +nesn.com, 0 +paginegialle.it, 0 +parismatch.com, 0 +popsugar.com, 0 +prezi.com, 0 +programme-tv.net, 0 +purepeople.com, 0 +qz.com, 0 +radaronline.com, 0 +shmoop.com, 0 +slate.fr, 0 +sondakika.com, 0 +songtexte.com, 0 +study.com, 0 +superpages.com, 0 +techtimes.com, 0 +tecmundo.com.br, 0 +telegraaf.nl, 0 +tf1.fr, 0 +tv.com, 0 +tvline.com, 0 +variety.com, 0 +venturebeat.com, 0 +vocabulary.com, 0 +wattpad.com, 0 +weather.com, 0 +weebly.com, 0 +whitepages.com, 0 +wordpress.com, 0 +wordpress.org, 0 +xda-developers.com, 0 +yourdictionary.com, 0 +zadane.pl, 0 +zillow.com, 0 +znanija.com, 0 +zoopla.co.uk, 0 %%
diff --git a/net/base/stale_while_revalidate_experiment_domains_unittest.cc b/net/base/stale_while_revalidate_experiment_domains_unittest.cc index 05f0d1af..9b6b844 100644 --- a/net/base/stale_while_revalidate_experiment_domains_unittest.cc +++ b/net/base/stale_while_revalidate_experiment_domains_unittest.cc
@@ -20,7 +20,7 @@ bool result; } kExpectations[] = { {"wordpress.com", true}, - {"issuu.com", true}, + {"tf1.fr", true}, {"wordpress.com.", true}, {"www.wordpress.com", true}, {"www.wordpress.com.", true},
diff --git a/net/cert/ct_log_verifier_unittest.cc b/net/cert/ct_log_verifier_unittest.cc index bc6e61cd..fd15b1e 100644 --- a/net/cert/ct_log_verifier_unittest.cc +++ b/net/cert/ct_log_verifier_unittest.cc
@@ -20,7 +20,7 @@ void SetUp() override { log_ = CTLogVerifier::Create(ct::GetTestPublicKey(), "testlog", - "https://ct.example.com").Pass(); + "https://ct.example.com"); ASSERT_TRUE(log_); ASSERT_EQ(log_->key_id(), ct::GetTestPublicKeyId());
diff --git a/net/cert/ct_objects_extractor_unittest.cc b/net/cert/ct_objects_extractor_unittest.cc index 864686a..5bb59ba 100644 --- a/net/cert/ct_objects_extractor_unittest.cc +++ b/net/cert/ct_objects_extractor_unittest.cc
@@ -32,7 +32,7 @@ der_test_cert.length()); log_ = CTLogVerifier::Create(ct::GetTestPublicKey(), "testlog", - "https://ct.example.com").Pass(); + "https://ct.example.com"); ASSERT_TRUE(log_); }
diff --git a/net/disk_cache/blockfile/backend_impl.cc b/net/disk_cache/blockfile/backend_impl.cc index 97f3520..f54128f 100644 --- a/net/disk_cache/blockfile/backend_impl.cc +++ b/net/disk_cache/blockfile/backend_impl.cc
@@ -4,6 +4,8 @@ #include "net/disk_cache/blockfile/backend_impl.h" +#include <limits> + #include "base/bind.h" #include "base/bind_helpers.h" #include "base/files/file.h" @@ -53,7 +55,7 @@ // Avoid trimming the cache for the first 5 minutes (10 timer ticks). const int kTrimDelay = 10; -int DesiredIndexTableLen(int32 storage_size) { +int DesiredIndexTableLen(int32_t storage_size) { if (storage_size <= k64kEntriesStore) return kBaseTableLen; if (storage_size <= k64kEntriesStore * 2) @@ -63,7 +65,7 @@ if (storage_size <= k64kEntriesStore * 8) return kBaseTableLen * 8; - // The biggest storage_size for int32 requires a 4 MB table. + // The biggest storage_size for int32_t requires a 4 MB table. return kBaseTableLen * 16; } @@ -139,7 +141,7 @@ BackendImpl::BackendImpl( const base::FilePath& path, - uint32 mask, + uint32_t mask, const scoped_refptr<base::SingleThreadTaskRunner>& cache_thread, net::NetLog* net_log) : background_queue_(this, cache_thread), @@ -161,8 +163,7 @@ user_load_(false), net_log_(net_log), done_(true, false), - ptr_factory_(this) { -} + ptr_factory_(this) {} BackendImpl::~BackendImpl() { if (user_flags_ & kNoRandom) { @@ -458,7 +459,7 @@ if (disabled_) return; - uint32 hash = base::Hash(key); + uint32_t hash = base::Hash(key); bool error; EntryImpl* cache_entry = MatchEntry(key, hash, false, Addr(), &error); if (cache_entry) { @@ -474,7 +475,7 @@ return NULL; TimeTicks start = TimeTicks::Now(); - uint32 hash = base::Hash(key); + uint32_t hash = base::Hash(key); Trace("Open hash 0x%x", hash); bool error; @@ -489,9 +490,9 @@ } int current_size = data_->header.num_bytes / (1024 * 1024); - int64 total_hours = stats_.GetCounter(Stats::TIMER) / 120; - int64 no_use_hours = stats_.GetCounter(Stats::LAST_REPORT_TIMER) / 120; - int64 use_hours = total_hours - no_use_hours; + int64_t total_hours = stats_.GetCounter(Stats::TIMER) / 120; + int64_t no_use_hours = stats_.GetCounter(Stats::LAST_REPORT_TIMER) / 120; + int64_t use_hours = total_hours - no_use_hours; if (!cache_entry) { CACHE_UMA(AGE_MS, "OpenTime.Miss", 0, start); @@ -525,7 +526,7 @@ return NULL; TimeTicks start = TimeTicks::Now(); - uint32 hash = base::Hash(key); + uint32_t hash = base::Hash(key); Trace("Create hash 0x%x", hash); scoped_refptr<EntryImpl> parent; @@ -697,8 +698,11 @@ return true; // Avoid a DCHECK later on. - if (max_bytes >= kint32max - kint32max / 10) - max_bytes = kint32max - kint32max / 10 - 1; + if (max_bytes >= std::numeric_limits<int32_t>::max() - + std::numeric_limits<int32_t>::max() / 10) { + max_bytes = std::numeric_limits<int32_t>::max() - + std::numeric_limits<int32_t>::max() / 10 - 1; + } user_flags_ |= kMaxSize; max_size_ = max_bytes; @@ -792,7 +796,7 @@ return; } - uint32 hash = cache_entry->GetHash(); + uint32_t hash = cache_entry->GetHash(); cache_entry->Release(); // Anything on the table means that this entry is there. @@ -804,7 +808,7 @@ } void BackendImpl::InternalDoomEntry(EntryImpl* entry) { - uint32 hash = entry->GetHash(); + uint32_t hash = entry->GetHash(); std::string key = entry->GetKey(); Addr entry_addr = entry->entry()->address(); bool error; @@ -851,7 +855,7 @@ void BackendImpl::NotLinked(EntryImpl* entry) { Addr entry_addr = entry->entry()->address(); - uint32 i = entry->GetHash() & mask_; + uint32_t i = entry->GetHash() & mask_; Addr address(data_->table[i]); if (!address.is_initialized()) return; @@ -906,7 +910,7 @@ return NULL; } -int32 BackendImpl::GetCurrentEntryId() const { +int32_t BackendImpl::GetCurrentEntryId() const { return data_->header.this_id; } @@ -914,7 +918,7 @@ return cache_type() == net::PNACL_CACHE ? max_size_ : max_size_ / 8; } -void BackendImpl::ModifyStorageSize(int32 old_size, int32 new_size) { +void BackendImpl::ModifyStorageSize(int32_t old_size, int32_t new_size) { if (disabled_ || old_size == new_size) return; if (old_size > new_size) @@ -928,7 +932,7 @@ stats_.ModifyStorageStats(old_size, new_size); } -void BackendImpl::TooMuchStorageRequested(int32 size) { +void BackendImpl::TooMuchStorageRequested(int32_t size) { stats_.ModifyStorageStats(0, size); } @@ -977,7 +981,7 @@ return uma_report_ == 2; uma_report_++; - int64 last_report = stats_.GetCounter(Stats::LAST_REPORT); + int64_t last_report = stats_.GetCounter(Stats::LAST_REPORT); Time last_time = Time::FromInternalValue(last_report); if (!last_report || (Time::Now() - last_time).InDays() >= 7) { stats_.SetCounter(Stats::LAST_REPORT, Time::Now().ToInternalValue()); @@ -995,7 +999,7 @@ Time create_time = Time::FromInternalValue(data_->header.create_time); CACHE_UMA(AGE, "FillupAge", 0, create_time); - int64 use_time = stats_.GetCounter(Stats::TIMER); + int64_t use_time = stats_.GetCounter(Stats::TIMER); CACHE_UMA(HOURS, "FillupTime", 0, static_cast<int>(use_time / 120)); CACHE_UMA(PERCENTAGE, "FirstHitRatio", 0, stats_.GetHitRatio()); @@ -1059,14 +1063,14 @@ stats_.OnEvent(an_event); } -void BackendImpl::OnRead(int32 bytes) { +void BackendImpl::OnRead(int32_t bytes) { DCHECK_GE(bytes, 0); byte_count_ += bytes; if (byte_count_ < 0) - byte_count_ = kint32max; + byte_count_ = std::numeric_limits<int32_t>::max(); } -void BackendImpl::OnWrite(int32 bytes) { +void BackendImpl::OnWrite(int32_t bytes) { // We use the same implementation as OnRead... just log the number of bytes. OnRead(bytes); } @@ -1076,13 +1080,13 @@ return; stats_.OnEvent(Stats::TIMER); - int64 time = stats_.GetCounter(Stats::TIMER); - int64 current = stats_.GetCounter(Stats::OPEN_ENTRIES); + int64_t time = stats_.GetCounter(Stats::TIMER); + int64_t current = stats_.GetCounter(Stats::OPEN_ENTRIES); // OPEN_ENTRIES is a sampled average of the number of open entries, avoiding // the bias towards 0. if (num_refs_ && (current != num_refs_)) { - int64 diff = (num_refs_ - current) / 50; + int64_t diff = (num_refs_ - current) / 50; if (!diff) diff = num_refs_ > current ? 1 : -1; current = current + diff; @@ -1137,7 +1141,7 @@ new_eviction_ = true; } -void BackendImpl::SetFlags(uint32 flags) { +void BackendImpl::SetFlags(uint32_t flags) { user_flags_ |= flags; } @@ -1205,12 +1209,12 @@ return cache_type_; } -int32 BackendImpl::GetEntryCount() const { +int32_t BackendImpl::GetEntryCount() const { if (!index_.get() || disabled_) return 0; // num_entries includes entries already evicted. - int32 not_deleted = data_->header.num_entries - - data_->header.lru.sizes[Rankings::DELETED]; + int32_t not_deleted = + data_->header.num_entries - data_->header.lru.sizes[Rankings::DELETED]; if (not_deleted < 0) { NOTREACHED(); @@ -1402,7 +1406,7 @@ DCHECK(!table_len || data_->header.magic); // The user is not setting the size, let's figure it out. - int64 available = base::SysInfo::AmountOfFreeDiskSpace(path_); + int64_t available = base::SysInfo::AmountOfFreeDiskSpace(path_); if (available < 0) { max_size_ = kDefaultCacheSize; return; @@ -1481,10 +1485,10 @@ } void BackendImpl::RestartCache(bool failure) { - int64 errors = stats_.GetCounter(Stats::FATAL_ERROR); - int64 full_dooms = stats_.GetCounter(Stats::DOOM_CACHE); - int64 partial_dooms = stats_.GetCounter(Stats::DOOM_RECENT); - int64 last_report = stats_.GetCounter(Stats::LAST_REPORT); + int64_t errors = stats_.GetCounter(Stats::FATAL_ERROR); + int64_t full_dooms = stats_.GetCounter(Stats::DOOM_CACHE); + int64_t partial_dooms = stats_.GetCounter(Stats::DOOM_RECENT); + int64_t last_report = stats_.GetCounter(Stats::LAST_REPORT); PrepareForRestart(); if (failure) { @@ -1603,8 +1607,10 @@ return 0; } -EntryImpl* BackendImpl::MatchEntry(const std::string& key, uint32 hash, - bool find_parent, Addr entry_addr, +EntryImpl* BackendImpl::MatchEntry(const std::string& key, + uint32_t hash, + bool find_parent, + Addr entry_addr, bool* match_error) { Addr address(data_->table[hash & mask_]); scoped_refptr<EntryImpl> cache_entry, parent_entry; @@ -1808,12 +1814,12 @@ stats_.OnEvent(Stats::INVALID_ENTRY); } -void BackendImpl::AddStorageSize(int32 bytes) { +void BackendImpl::AddStorageSize(int32_t bytes) { data_->header.num_bytes += bytes; DCHECK_GE(data_->header.num_bytes, 0); } -void BackendImpl::SubstractStorageSize(int32 bytes) { +void BackendImpl::SubstractStorageSize(int32_t bytes) { data_->header.num_bytes -= bytes; DCHECK_GE(data_->header.num_bytes, 0); } @@ -1893,7 +1899,7 @@ if (age) CACHE_UMA(HOURS, "FilesAge", 0, age); - int64 total_hours = stats_.GetCounter(Stats::TIMER) / 120; + int64_t total_hours = stats_.GetCounter(Stats::TIMER) / 120; if (!data_->header.create_time || !data_->header.lru.filled) { int cause = data_->header.create_time ? 0 : 1; if (!data_->header.lru.filled) @@ -1913,7 +1919,7 @@ if (base::RandInt(0, 99) < hit_ratio_as_percentage) CACHE_UMA(HOURS, "HitRatioByTotalTime", 0, static_cast<int>(total_hours)); - int64 use_hours = stats_.GetCounter(Stats::LAST_REPORT_TIMER) / 120; + int64_t use_hours = stats_.GetCounter(Stats::LAST_REPORT_TIMER) / 120; stats_.SetCounter(Stats::LAST_REPORT_TIMER, stats_.GetCounter(Stats::TIMER)); // We may see users with no use_hours at this point if this is the first time @@ -1932,7 +1938,7 @@ CACHE_UMA(HOURS, "HitRatioByUseTime", 0, static_cast<int>(use_hours)); CACHE_UMA(PERCENTAGE, "HitRatio", 0, hit_ratio_as_percentage); - int64 trim_rate = stats_.GetCounter(Stats::TRIM_ENTRY) / use_hours; + int64_t trim_rate = stats_.GetCounter(Stats::TRIM_ENTRY) / use_hours; CACHE_UMA(COUNTS, "TrimRate", 0, static_cast<int>(trim_rate)); int avg_size = data_->header.num_bytes / GetEntryCount(); @@ -2016,7 +2022,7 @@ #if !defined(NET_BUILD_STRESS_CACHE) if (data_->header.num_bytes < 0 || - (max_size_ < kint32max - kDefaultCacheSize && + (max_size_ < std::numeric_limits<int32_t>::max() - kDefaultCacheSize && data_->header.num_bytes > max_size_ + kDefaultCacheSize)) { LOG(ERROR) << "Invalid cache (current) size"; return false; @@ -2038,7 +2044,7 @@ int BackendImpl::CheckAllEntries() { int num_dirty = 0; int num_entries = 0; - DCHECK(mask_ < kuint32max); + DCHECK(mask_ < std::numeric_limits<uint32_t>::max()); for (unsigned int i = 0; i <= mask_; i++) { Addr address(data_->table[i]); if (!address.is_initialized()) @@ -2094,7 +2100,7 @@ } int BackendImpl::MaxBuffersSize() { - static int64 total_memory = base::SysInfo::AmountOfPhysicalMemory(); + static int64_t total_memory = base::SysInfo::AmountOfPhysicalMemory(); static bool done = false; if (!done) {
diff --git a/net/disk_cache/blockfile/backend_impl.h b/net/disk_cache/blockfile/backend_impl.h index f888468..c5177a2 100644 --- a/net/disk_cache/blockfile/backend_impl.h +++ b/net/disk_cache/blockfile/backend_impl.h
@@ -7,6 +7,8 @@ #ifndef NET_DISK_CACHE_BLOCKFILE_BACKEND_IMPL_H_ #define NET_DISK_CACHE_BLOCKFILE_BACKEND_IMPL_H_ +#include <stdint.h> + #include "base/containers/hash_tables.h" #include "base/files/file_path.h" #include "base/memory/ref_counted.h" @@ -54,7 +56,7 @@ net::NetLog* net_log); // mask can be used to limit the usable size of the hash table, for testing. BackendImpl(const base::FilePath& path, - uint32 mask, + uint32_t mask, const scoped_refptr<base::SingleThreadTaskRunner>& cache_thread, net::NetLog* net_log); ~BackendImpl() override; @@ -149,16 +151,16 @@ EntryImpl* GetOpenEntry(CacheRankingsBlock* rankings) const; // Returns the id being used on this run of the cache. - int32 GetCurrentEntryId() const; + int32_t GetCurrentEntryId() const; // Returns the maximum size for a file to reside on the cache. int MaxFileSize() const; // A user data block is being created, extended or truncated. - void ModifyStorageSize(int32 old_size, int32 new_size); + void ModifyStorageSize(int32_t old_size, int32_t new_size); // Logs requests that are denied due to being too big. - void TooMuchStorageRequested(int32 size); + void TooMuchStorageRequested(int32_t size); // Returns true if a temporary buffer is allowed to be extended. bool IsAllocAllowed(int current_size, int new_size); @@ -228,7 +230,7 @@ void SetNewEviction(); // Sets an explicit set of BackendFlags. - void SetFlags(uint32 flags); + void SetFlags(uint32_t flags); // Clears the counter of references to test handling of corruptions. void ClearRefCountForTest(); @@ -261,7 +263,7 @@ // Backend implementation. net::CacheType GetCacheType() const override; - int32 GetEntryCount() const override; + int32_t GetEntryCount() const override; int OpenEntry(const std::string& key, Entry** entry, const CompletionCallback& callback) override; @@ -316,8 +318,11 @@ // if it doesn't match the entry on the index, we know that it was replaced // with a new entry; in this case |*match_error| will be set to true and the // return value will be NULL. - EntryImpl* MatchEntry(const std::string& key, uint32 hash, bool find_parent, - Addr entry_addr, bool* match_error); + EntryImpl* MatchEntry(const std::string& key, + uint32_t hash, + bool find_parent, + Addr entry_addr, + bool* match_error); // Opens the next or previous entry on a single list. If successful, // |from_entry| will be updated to point to the new entry, otherwise it will @@ -335,8 +340,8 @@ void DestroyInvalidEntry(EntryImpl* entry); // Handles the used storage count. - void AddStorageSize(int32 bytes); - void SubstractStorageSize(int32 bytes); + void AddStorageSize(int32_t bytes); + void SubstractStorageSize(int32_t bytes); // Update the number of referenced cache entries. void IncreaseNumRefs(); @@ -371,8 +376,8 @@ Index* data_; // Pointer to the index data. BlockFiles block_files_; // Set of files used to store all data. Rankings rankings_; // Rankings to be able to trim the cache. - uint32 mask_; // Binary mask to map a hash to the hash table. - int32 max_size_; // Maximum data size for this instance. + uint32_t mask_; // Binary mask to map a hash to the hash table. + int32_t max_size_; // Maximum data size for this instance. Eviction eviction_; // Handler of the eviction algorithm. EntriesMap open_entries_; // Map of open entries. int num_refs_; // Number of referenced cache entries. @@ -384,7 +389,7 @@ int up_ticks_; // The number of timer ticks received (OnStatsTimer). net::CacheType cache_type_; int uma_report_; // Controls transmission of UMA data. - uint32 user_flags_; // Flags set by the user. + uint32_t user_flags_; // Flags set by the user. bool init_; // controls the initialization of the system. bool restarted_; bool unit_test_;
diff --git a/net/disk_cache/blockfile/backend_impl_v3.cc b/net/disk_cache/blockfile/backend_impl_v3.cc index fe944e8..ae90bd96 100644 --- a/net/disk_cache/blockfile/backend_impl_v3.cc +++ b/net/disk_cache/blockfile/backend_impl_v3.cc
@@ -4,6 +4,8 @@ #include "net/disk_cache/blockfile/backend_impl_v3.h" +#include <limits> + #include "base/bind.h" #include "base/bind_helpers.h" #include "base/files/file_path.h" @@ -100,8 +102,11 @@ return true; // Avoid a DCHECK later on. - if (max_bytes >= kint32max - kint32max / 10) - max_bytes = kint32max - kint32max / 10 - 1; + if (max_bytes >= std::numeric_limits<int32_t>::max() - + std::numeric_limits<int32_t>::max() / 10) { + max_bytes = std::numeric_limits<int32_t>::max() - + std::numeric_limits<int32_t>::max() / 10 - 1; + } user_flags_ |= MAX_SIZE; max_size_ = max_bytes; @@ -126,7 +131,7 @@ } void BackendImplV3::InternalDoomEntry(EntryImplV3* entry) { - uint32 hash = entry->GetHash(); + uint32_t hash = entry->GetHash(); std::string key = entry->GetKey(); Addr entry_addr = entry->entry()->address(); bool error; @@ -184,7 +189,7 @@ return max_size_ / 8; } -void BackendImplV3::ModifyStorageSize(int32 old_size, int32 new_size) { +void BackendImplV3::ModifyStorageSize(int32_t old_size, int32_t new_size) { if (disabled_ || old_size == new_size) return; if (old_size > new_size) @@ -196,7 +201,7 @@ stats_.ModifyStorageStats(old_size, new_size); } -void BackendImplV3::TooMuchStorageRequested(int32 size) { +void BackendImplV3::TooMuchStorageRequested(int32_t size) { stats_.ModifyStorageStats(0, size); } @@ -247,7 +252,7 @@ return uma_report_ == 2; uma_report_++; - int64 last_report = stats_.GetCounter(Stats::LAST_REPORT); + int64_t last_report = stats_.GetCounter(Stats::LAST_REPORT); Time last_time = Time::FromInternalValue(last_report); if (!last_report || (Time::Now() - last_time).InDays() >= 7) { stats_.SetCounter(Stats::LAST_REPORT, Time::Now().ToInternalValue()); @@ -267,7 +272,7 @@ Time create_time = Time::FromInternalValue(header->create_time); CACHE_UMA(AGE, "FillupAge", create_time); - int64 use_time = stats_.GetCounter(Stats::TIMER); + int64_t use_time = stats_.GetCounter(Stats::TIMER); CACHE_UMA(HOURS, "FillupTime", static_cast<int>(use_time / 120)); CACHE_UMA(PERCENTAGE, "FirstHitRatio", stats_.GetHitRatio()); @@ -302,27 +307,27 @@ stats_.OnEvent(an_event); } -void BackendImplV3::OnRead(int32 bytes) { +void BackendImplV3::OnRead(int32_t bytes) { DCHECK_GE(bytes, 0); byte_count_ += bytes; if (byte_count_ < 0) - byte_count_ = kint32max; + byte_count_ = std::numeric_limits<int32_t>::max(); } -void BackendImplV3::OnWrite(int32 bytes) { +void BackendImplV3::OnWrite(int32_t bytes) { // We use the same implementation as OnRead... just log the number of bytes. OnRead(bytes); } void BackendImplV3::OnTimerTick() { stats_.OnEvent(Stats::TIMER); - int64 time = stats_.GetCounter(Stats::TIMER); - int64 current = stats_.GetCounter(Stats::OPEN_ENTRIES); + int64_t time = stats_.GetCounter(Stats::TIMER); + int64_t current = stats_.GetCounter(Stats::OPEN_ENTRIES); // OPEN_ENTRIES is a sampled average of the number of open entries, avoiding // the bias towards 0. if (num_refs_ && (current != num_refs_)) { - int64 diff = (num_refs_ - current) / 50; + int64_t diff = (num_refs_ - current) / 50; if (!diff) diff = num_refs_ > current ? 1 : -1; current = current + diff; @@ -368,7 +373,7 @@ lru_eviction_ = false; } -void BackendImplV3::SetFlags(uint32 flags) { +void BackendImplV3::SetFlags(uint32_t flags) { user_flags_ |= flags; } @@ -417,7 +422,7 @@ return cache_type_; } -int32 BackendImplV3::GetEntryCount() const { +int32_t BackendImplV3::GetEntryCount() const { if (disabled_) return 0; DCHECK(init_); @@ -430,7 +435,7 @@ return NULL; TimeTicks start = TimeTicks::Now(); - uint32 hash = base::Hash(key); + uint32_t hash = base::Hash(key); Trace("Open hash 0x%x", hash); bool error; @@ -442,9 +447,9 @@ } int current_size = data_->header.num_bytes / (1024 * 1024); - int64 total_hours = stats_.GetCounter(Stats::TIMER) / 120; - int64 no_use_hours = stats_.GetCounter(Stats::LAST_REPORT_TIMER) / 120; - int64 use_hours = total_hours - no_use_hours; + int64_t total_hours = stats_.GetCounter(Stats::TIMER) / 120; + int64_t no_use_hours = stats_.GetCounter(Stats::LAST_REPORT_TIMER) / 120; + int64_t use_hours = total_hours - no_use_hours; if (!cache_entry) { CACHE_UMA(AGE_MS, "OpenTime.Miss", 0, start); @@ -717,7 +722,7 @@ if (disabled_) return; - uint32 hash = base::Hash(key); + uint32_t hash = base::Hash(key); bool error; EntryImpl* cache_entry = MatchEntry(key, hash, false, Addr(), &error); if (cache_entry) { @@ -740,7 +745,7 @@ DCHECK(!table_len || data_->header.magic); // The user is not setting the size, let's figure it out. - int64 available = base::SysInfo::AmountOfFreeDiskSpace(path_); + int64_t available = base::SysInfo::AmountOfFreeDiskSpace(path_); if (available < 0) { max_size_ = kDefaultCacheSize; return; @@ -822,10 +827,10 @@ } void BackendImplV3::RestartCache(bool failure) { - int64 errors = stats_.GetCounter(Stats::FATAL_ERROR); - int64 full_dooms = stats_.GetCounter(Stats::DOOM_CACHE); - int64 partial_dooms = stats_.GetCounter(Stats::DOOM_RECENT); - int64 last_report = stats_.GetCounter(Stats::LAST_REPORT); + int64_t errors = stats_.GetCounter(Stats::FATAL_ERROR); + int64_t full_dooms = stats_.GetCounter(Stats::DOOM_CACHE); + int64_t partial_dooms = stats_.GetCounter(Stats::DOOM_RECENT); + int64_t last_report = stats_.GetCounter(Stats::LAST_REPORT); PrepareForRestart(); if (failure) { @@ -965,12 +970,12 @@ return 0; } -void BackendImplV3::AddStorageSize(int32 bytes) { +void BackendImplV3::AddStorageSize(int32_t bytes) { data_->header.num_bytes += bytes; DCHECK_GE(data_->header.num_bytes, 0); } -void BackendImplV3::SubstractStorageSize(int32 bytes) { +void BackendImplV3::SubstractStorageSize(int32_t bytes) { data_->header.num_bytes -= bytes; DCHECK_GE(data_->header.num_bytes, 0); } @@ -1262,7 +1267,7 @@ stats_.SetCounter(Stats::DOOM_CACHE, 0); stats_.SetCounter(Stats::DOOM_RECENT, 0); - int64 total_hours = stats_.GetCounter(Stats::TIMER) / 120; + int64_t total_hours = stats_.GetCounter(Stats::TIMER) / 120; if (!(header->flags & CACHE_EVICTED)) { CACHE_UMA(HOURS, "TotalTimeNotFull", static_cast<int>(total_hours)); return; @@ -1273,7 +1278,7 @@ CACHE_UMA(HOURS, "TotalTime", static_cast<int>(total_hours)); - int64 use_hours = stats_.GetCounter(Stats::LAST_REPORT_TIMER) / 120; + int64_t use_hours = stats_.GetCounter(Stats::LAST_REPORT_TIMER) / 120; stats_.SetCounter(Stats::LAST_REPORT_TIMER, stats_.GetCounter(Stats::TIMER)); // We may see users with no use_hours at this point if this is the first time @@ -1286,7 +1291,7 @@ CACHE_UMA(HOURS, "UseTime", static_cast<int>(use_hours)); - int64 trim_rate = stats_.GetCounter(Stats::TRIM_ENTRY) / use_hours; + int64_t trim_rate = stats_.GetCounter(Stats::TRIM_ENTRY) / use_hours; CACHE_UMA(COUNTS, "TrimRate", static_cast<int>(trim_rate)); int avg_size = header->num_bytes / GetEntryCount(); @@ -1368,7 +1373,7 @@ #if !defined(NET_BUILD_STRESS_CACHE) if (data_->header.num_bytes < 0 || - (max_size_ < kint32max - kDefaultCacheSize && + (max_size_ < std::numeric_limits<int32_t>::max() - kDefaultCacheSize && data_->header.num_bytes > max_size_ + kDefaultCacheSize)) { LOG(ERROR) << "Invalid cache (current) size"; return false; @@ -1391,7 +1396,7 @@ int BackendImplV3::CheckAllEntries() { int num_dirty = 0; int num_entries = 0; - DCHECK(mask_ < kuint32max); + DCHECK(mask_ < std::numeric_limits<uint32_t>::max()); for (unsigned int i = 0; i <= mask_; i++) { Addr address(data_->table[i]); if (!address.is_initialized()) @@ -1447,7 +1452,7 @@ } int BackendImplV3::MaxBuffersSize() { - static int64 total_memory = base::SysInfo::AmountOfPhysicalMemory(); + static int64_t total_memory = base::SysInfo::AmountOfPhysicalMemory(); static bool done = false; if (!done) { @@ -1474,7 +1479,7 @@ return cache_type_; } -int32 BackendImplV3::GetEntryCount() const { +int32_t BackendImplV3::GetEntryCount() const { return 0; }
diff --git a/net/disk_cache/blockfile/backend_impl_v3.h b/net/disk_cache/blockfile/backend_impl_v3.h index 7cc4648..d935a9db 100644 --- a/net/disk_cache/blockfile/backend_impl_v3.h +++ b/net/disk_cache/blockfile/backend_impl_v3.h
@@ -7,6 +7,8 @@ #ifndef NET_DISK_CACHE_BLOCKFILE_BACKEND_IMPL_V3_H_ #define NET_DISK_CACHE_BLOCKFILE_BACKEND_IMPL_V3_H_ +#include <stdint.h> + #include "base/containers/hash_tables.h" #include "base/files/file_path.h" #include "base/memory/ref_counted.h" @@ -86,16 +88,16 @@ EntryImplV3* GetOpenEntry(Addr address) const; // Returns the id being used on this run of the cache. - int32 GetCurrentEntryId() const; + int32_t GetCurrentEntryId() const; // Returns the maximum size for a file to reside on the cache. int MaxFileSize() const; // A user data block is being created, extended or truncated. - void ModifyStorageSize(int32 old_size, int32 new_size); + void ModifyStorageSize(int32_t old_size, int32_t new_size); // Logs requests that are denied due to being too big. - void TooMuchStorageRequested(int32 size); + void TooMuchStorageRequested(int32_t size); // Returns true if a temporary buffer is allowed to be extended. bool IsAllocAllowed(int current_size, int new_size); @@ -154,7 +156,7 @@ void SetNewEviction(); // Sets an explicit set of BackendFlags. - void SetFlags(uint32 flags); + void SetFlags(uint32_t flags); // Sends a dummy operation through the operation queue, for unit tests. int FlushQueueForTest(const CompletionCallback& callback); @@ -173,7 +175,7 @@ // Backend implementation. net::CacheType GetCacheType() const override; - int32 GetEntryCount() const override; + int32_t GetEntryCount() const override; int OpenEntry(const std::string& key, Entry** entry, const CompletionCallback& callback) override; @@ -216,8 +218,8 @@ int NewEntry(Addr address, EntryImplV3** entry); // Handles the used storage count. - void AddStorageSize(int32 bytes); - void SubstractStorageSize(int32 bytes); + void AddStorageSize(int32_t bytes); + void SubstractStorageSize(int32_t bytes); // Update the number of referenced cache entries. void IncreaseNumRefs(); @@ -249,7 +251,7 @@ IndexTable index_; base::FilePath path_; // Path to the folder used as backing storage. BlockBitmaps block_files_; - int32 max_size_; // Maximum data size for this instance. + int32_t max_size_; // Maximum data size for this instance. EvictionV3 eviction_; // Handler of the eviction algorithm. EntriesMap open_entries_; int num_refs_; // Number of referenced cache entries. @@ -260,7 +262,7 @@ int up_ticks_; // The number of timer ticks received (OnTimerTick). net::CacheType cache_type_; int uma_report_; // Controls transmission of UMA data. - uint32 user_flags_; // Flags set by the user. + uint32_t user_flags_; // Flags set by the user. bool init_; // controls the initialization of the system. bool restarted_; bool read_only_; // Prevents updates of the rankings data (used by tools).
diff --git a/net/disk_cache/blockfile/file_ios.cc b/net/disk_cache/blockfile/file_ios.cc index 3ffb5a5..b00c246 100644 --- a/net/disk_cache/blockfile/file_ios.cc +++ b/net/disk_cache/blockfile/file_ios.cc
@@ -4,6 +4,10 @@ #include "net/disk_cache/blockfile/file.h" +#include <stdint.h> + +#include <limits> + #include "base/bind.h" #include "base/location.h" #include "base/logging.h" @@ -188,8 +192,8 @@ bool File::Read(void* buffer, size_t buffer_len, size_t offset) { DCHECK(base_file_.IsValid()); - if (buffer_len > static_cast<size_t>(kint32max) || - offset > static_cast<size_t>(kint32max)) { + if (buffer_len > static_cast<size_t>(std::numeric_limits<int32_t>::max()) || + offset > static_cast<size_t>(std::numeric_limits<int32_t>::max())) { return false; } @@ -199,8 +203,8 @@ bool File::Write(const void* buffer, size_t buffer_len, size_t offset) { DCHECK(base_file_.IsValid()); - if (buffer_len > static_cast<size_t>(kint32max) || - offset > static_cast<size_t>(kint32max)) { + if (buffer_len > static_cast<size_t>(std::numeric_limits<int32_t>::max()) || + offset > static_cast<size_t>(std::numeric_limits<int32_t>::max())) { return false; } @@ -244,7 +248,7 @@ bool File::SetLength(size_t length) { DCHECK(base_file_.IsValid()); - if (length > kuint32max) + if (length > std::numeric_limits<uint32_t>::max()) return false; return base_file_.SetLength(length); @@ -252,10 +256,10 @@ size_t File::GetLength() { DCHECK(base_file_.IsValid()); - int64 len = base_file_.GetLength(); + int64_t len = base_file_.GetLength(); - if (len > static_cast<int64>(kuint32max)) - return kuint32max; + if (len > static_cast<int64_t>(std::numeric_limits<uint32_t>::max())) + return std::numeric_limits<uint32_t>::max(); return static_cast<size_t>(len); }
diff --git a/net/disk_cache/blockfile/file_posix.cc b/net/disk_cache/blockfile/file_posix.cc index 828673f9..26067fb 100644 --- a/net/disk_cache/blockfile/file_posix.cc +++ b/net/disk_cache/blockfile/file_posix.cc
@@ -4,6 +4,10 @@ #include "net/disk_cache/blockfile/file.h" +#include <stdint.h> + +#include <limits> + #include "base/bind.h" #include "base/lazy_instance.h" #include "base/location.h" @@ -56,8 +60,8 @@ bool File::Read(void* buffer, size_t buffer_len, size_t offset) { DCHECK(base_file_.IsValid()); - if (buffer_len > static_cast<size_t>(kint32max) || - offset > static_cast<size_t>(kint32max)) { + if (buffer_len > static_cast<size_t>(std::numeric_limits<int32_t>::max()) || + offset > static_cast<size_t>(std::numeric_limits<int32_t>::max())) { return false; } @@ -67,8 +71,8 @@ bool File::Write(const void* buffer, size_t buffer_len, size_t offset) { DCHECK(base_file_.IsValid()); - if (buffer_len > static_cast<size_t>(kint32max) || - offset > static_cast<size_t>(kint32max)) { + if (buffer_len > static_cast<size_t>(std::numeric_limits<int32_t>::max()) || + offset > static_cast<size_t>(std::numeric_limits<int32_t>::max())) { return false; } @@ -86,8 +90,8 @@ return Read(buffer, buffer_len, offset); } - if (buffer_len > static_cast<size_t>(kint32max) || - offset > static_cast<size_t>(kint32max)) { + if (buffer_len > static_cast<size_t>(std::numeric_limits<int32_t>::max()) || + offset > static_cast<size_t>(std::numeric_limits<int32_t>::max())) { return false; } @@ -109,8 +113,8 @@ return Write(buffer, buffer_len, offset); } - if (buffer_len > static_cast<size_t>(kint32max) || - offset > static_cast<size_t>(kint32max)) { + if (buffer_len > static_cast<size_t>(std::numeric_limits<int32_t>::max()) || + offset > static_cast<size_t>(std::numeric_limits<int32_t>::max())) { return false; } @@ -125,7 +129,7 @@ bool File::SetLength(size_t length) { DCHECK(base_file_.IsValid()); - if (length > kuint32max) + if (length > std::numeric_limits<uint32_t>::max()) return false; return base_file_.SetLength(length); @@ -133,10 +137,10 @@ size_t File::GetLength() { DCHECK(base_file_.IsValid()); - int64 len = base_file_.GetLength(); + int64_t len = base_file_.GetLength(); - if (len > static_cast<int64>(kuint32max)) - return kuint32max; + if (len > static_cast<int64_t>(std::numeric_limits<uint32_t>::max())) + return std::numeric_limits<uint32_t>::max(); return static_cast<size_t>(len); }
diff --git a/net/dns/dns_response.cc b/net/dns/dns_response.cc index 663ae0e..c11b8a9c 100644 --- a/net/dns/dns_response.cc +++ b/net/dns/dns_response.cc
@@ -4,6 +4,8 @@ #include "net/dns/dns_response.h" +#include <limits> + #include "base/big_endian.h" #include "base/strings/string_util.h" #include "base/sys_byteorder.h" @@ -61,19 +63,19 @@ // either a direct length or a pointer to the remainder of the name. switch (*p & dns_protocol::kLabelMask) { case dns_protocol::kLabelPointer: { - if (p + sizeof(uint16) > end) + if (p + sizeof(uint16_t) > end) return 0; if (consumed == 0) { - consumed = p - pos + sizeof(uint16); + consumed = p - pos + sizeof(uint16_t); if (!out) return consumed; // If name is not stored, that's all we need. } - seen += sizeof(uint16); + seen += sizeof(uint16_t); // If seen the whole packet, then we must be in a loop. if (seen > length_) return 0; - uint16 offset; - base::ReadBigEndian<uint16>(p, &offset); + uint16_t offset; + base::ReadBigEndian<uint16_t>(p, &offset); offset &= dns_protocol::kOffsetMask; p = packet_ + offset; if (p >= end) @@ -81,7 +83,7 @@ break; } case dns_protocol::kLabelDirect: { - uint8 label_len = *p; + uint8_t label_len = *p; ++p; // Note: root domain (".") is NOT included. if (label_len == 0) { @@ -115,7 +117,7 @@ return false; base::BigEndianReader reader(cur_ + consumed, packet_ + length_ - (cur_ + consumed)); - uint16 rdlen; + uint16_t rdlen; if (reader.ReadU16(&out->type) && reader.ReadU16(&out->klass) && reader.ReadU32(&out->ttl) && @@ -132,7 +134,7 @@ if (!consumed) return false; - const char* next = cur_ + consumed + 2 * sizeof(uint16); // QTYPE + QCLASS + const char* next = cur_ + consumed + 2 * sizeof(uint16_t); // QTYPE + QCLASS if (next > packet_ + length_) return false; @@ -216,12 +218,12 @@ return parser_.IsValid(); } -uint16 DnsResponse::flags() const { +uint16_t DnsResponse::flags() const { DCHECK(parser_.IsValid()); return base::NetToHost16(header()->flags) & ~(dns_protocol::kRcodeMask); } -uint8 DnsResponse::rcode() const { +uint8_t DnsResponse::rcode() const { DCHECK(parser_.IsValid()); return base::NetToHost16(header()->flags) & dns_protocol::kRcodeMask; } @@ -240,18 +242,19 @@ DCHECK(parser_.IsValid()); // The response is HEADER QNAME QTYPE QCLASS ANSWER. // |parser_| is positioned at the beginning of ANSWER, so the end of QNAME is - // two uint16s before it. + // two uint16_ts before it. const size_t hdr_size = sizeof(dns_protocol::Header); - const size_t qname_size = parser_.GetOffset() - 2 * sizeof(uint16) - hdr_size; + const size_t qname_size = + parser_.GetOffset() - 2 * sizeof(uint16_t) - hdr_size; return base::StringPiece(io_buffer_->data() + hdr_size, qname_size); } -uint16 DnsResponse::qtype() const { +uint16_t DnsResponse::qtype() const { DCHECK(parser_.IsValid()); // QTYPE starts where QNAME ends. - const size_t type_offset = parser_.GetOffset() - 2 * sizeof(uint16); - uint16 type; - base::ReadBigEndian<uint16>(io_buffer_->data() + type_offset, &type); + const size_t type_offset = parser_.GetOffset() - 2 * sizeof(uint16_t); + uint16_t type; + base::ReadBigEndian<uint16_t>(io_buffer_->data() + type_offset, &type); return type; } @@ -282,14 +285,14 @@ // Expected owner of record. No trailing dot. std::string expected_name = GetDottedName(); - uint16 expected_type = qtype(); + uint16_t expected_type = qtype(); DCHECK(expected_type == dns_protocol::kTypeA || expected_type == dns_protocol::kTypeAAAA); size_t expected_size = (expected_type == dns_protocol::kTypeAAAA) ? kIPv6AddressSize : kIPv4AddressSize; - uint32 ttl_sec = kuint32max; + uint32_t ttl_sec = std::numeric_limits<uint32_t>::max(); IPAddressList ip_addresses; DnsRecordParser parser = Parser(); DnsResourceRecord record;
diff --git a/net/dns/dns_response.h b/net/dns/dns_response.h index 6e67b5dea..24071ca 100644 --- a/net/dns/dns_response.h +++ b/net/dns/dns_response.h
@@ -5,9 +5,11 @@ #ifndef NET_DNS_DNS_RESPONSE_H_ #define NET_DNS_DNS_RESPONSE_H_ +#include <stdint.h> + #include <string> -#include "base/basictypes.h" +#include "base/macros.h" #include "base/memory/ref_counted.h" #include "base/strings/string_piece.h" #include "base/time/time.h" @@ -29,9 +31,9 @@ ~DnsResourceRecord(); std::string name; // in dotted form - uint16 type; - uint16 klass; - uint32 ttl; + uint16_t type; + uint16_t klass; + uint32_t ttl; base::StringPiece rdata; // points to the original response buffer }; @@ -127,15 +129,15 @@ // All of the methods below are valid only if the response is valid. // Accessors for the header. - uint16 flags() const; // excluding rcode - uint8 rcode() const; + uint16_t flags() const; // excluding rcode + uint8_t rcode() const; unsigned answer_count() const; unsigned additional_answer_count() const; // Accessors to the question. The qname is unparsed. base::StringPiece qname() const; - uint16 qtype() const; + uint16_t qtype() const; // Returns qname in dotted format. std::string GetDottedName() const;
diff --git a/net/http/http_network_transaction_unittest.cc b/net/http/http_network_transaction_unittest.cc index 8ff5a2fa..26011a8 100644 --- a/net/http/http_network_transaction_unittest.cc +++ b/net/http/http_network_transaction_unittest.cc
@@ -5882,12 +5882,8 @@ }; MockRead data_reads[] = { - MockRead("HTTP/1.1 200 OK\r\n"), - MockRead("Content-Length: 11\r\n\r\n"), - MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ), - MockRead("hello world"), - MockRead(ASYNC, 0, 0) // EOF - }; + MockRead("HTTP/1.1 200 OK\r\n"), MockRead("Content-Length: 11\r\n\r\n"), + MockRead("hello world"), MockRead(ASYNC, ERR_CONNECTION_CLOSED)}; SSLSocketDataProvider ssl(ASYNC, OK); SSLSocketDataProvider ssl2(ASYNC, OK);
diff --git a/net/http/http_response_headers_unittest.cc b/net/http/http_response_headers_unittest.cc index df1b76d..1bc99bb 100644 --- a/net/http/http_response_headers_unittest.cc +++ b/net/http/http_response_headers_unittest.cc
@@ -23,8 +23,9 @@ struct TestData { const char* raw_headers; const char* expected_headers; - int expected_response_code; HttpVersion expected_version; + int expected_response_code; + const char* expected_status_text; }; class HttpResponseHeadersTest : public testing::Test { @@ -110,14 +111,13 @@ EXPECT_EQ(expected_headers, headers); - EXPECT_EQ(test.expected_response_code, parsed->response_code()); - EXPECT_TRUE(test.expected_version == parsed->GetHttpVersion()); + EXPECT_EQ(test.expected_response_code, parsed->response_code()); + EXPECT_EQ(test.expected_status_text, parsed->GetStatusText()); } TestData response_headers_tests[] = { - {// Normalise whitespace. - + {// Normalize whitespace. "HTTP/1.1 202 Accepted \n" "Content-TYPE : text/html; charset=utf-8 \n" "Set-Cookie: a \n" @@ -127,10 +127,8 @@ "Content-TYPE: text/html; charset=utf-8\n" "Set-Cookie: a, b\n", - 202, - HttpVersion(1, 1)}, + HttpVersion(1, 1), 202, "Accepted"}, {// Normalize leading whitespace. - "HTTP/1.1 202 Accepted \n" // Starts with space -- will be skipped as invalid. " Content-TYPE : text/html; charset=utf-8 \n" @@ -140,10 +138,14 @@ "HTTP/1.1 202 Accepted\n" "Set-Cookie: a, b\n", - 202, - HttpVersion(1, 1)}, - {// Normalize blank headers. + HttpVersion(1, 1), 202, "Accepted"}, + {// Keep whitespace within status text. + "HTTP/1.0 404 Not found \n", + "HTTP/1.0 404 Not found\n", + + HttpVersion(1, 0), 404, "Not found"}, + {// Normalize blank headers. "HTTP/1.1 200 OK\n" "Header1 : \n" "Header2: \n" @@ -157,66 +159,58 @@ "Header3: \n" "Header5: \n", - 200, - HttpVersion(1, 1)}, + HttpVersion(1, 1), 200, "OK"}, {// Don't believe the http/0.9 version if there are headers! - "hTtP/0.9 201\n" "Content-TYPE: text/html; charset=utf-8\n", "HTTP/1.0 201\n" "Content-TYPE: text/html; charset=utf-8\n", - 201, - HttpVersion(1, 0)}, + HttpVersion(1, 0), 201, ""}, {// Accept the HTTP/0.9 version number if there are no headers. // This is how HTTP/0.9 responses get constructed from // HttpNetworkTransaction. - "hTtP/0.9 200 OK\n", "HTTP/0.9 200 OK\n", - 200, - HttpVersion(0, 9)}, + HttpVersion(0, 9), 200, "OK"}, {// Do not add missing status text. - "HTTP/1.1 201\n" "Content-TYPE: text/html; charset=utf-8\n", "HTTP/1.1 201\n" "Content-TYPE: text/html; charset=utf-8\n", - 201, - HttpVersion(1, 1)}, + HttpVersion(1, 1), 201, ""}, {// Normalize bad status line. - "SCREWED_UP_STATUS_LINE\n" "Content-TYPE: text/html; charset=utf-8\n", "HTTP/1.0 200 OK\n" "Content-TYPE: text/html; charset=utf-8\n", - 200, - HttpVersion(1, 0)}, - {// Normalize invalid status code. + HttpVersion(1, 0), 200, "OK"}, + {// Normalize bad status line. + "Foo bar.", + "HTTP/1.0 200\n", + + HttpVersion(1, 0), 200, ""}, + {// Normalize invalid status code. "HTTP/1.1 -1 Unknown\n", "HTTP/1.1 200\n", - 200, - HttpVersion(1, 1)}, + HttpVersion(1, 1), 200, ""}, {// Normalize empty header. - "", "HTTP/1.0 200 OK\n", - 200, - HttpVersion(1, 0)}, + HttpVersion(1, 0), 200, "OK"}, {// Normalize headers that start with a colon. - "HTTP/1.1 202 Accepted \n" "foo: bar\n" ": a \n" @@ -227,10 +221,8 @@ "foo: bar\n" "baz: blat\n", - 202, - HttpVersion(1, 1)}, + HttpVersion(1, 1), 202, "Accepted"}, {// Normalize headers that end with a colon. - "HTTP/1.1 202 Accepted \n" "foo: \n" "bar:\n" @@ -243,18 +235,14 @@ "baz: blat\n" "zip: \n", - 202, - HttpVersion(1, 1)}, + HttpVersion(1, 1), 202, "Accepted"}, {// Normalize whitespace headers. - "\n \n", "HTTP/1.0 200 OK\n", - 200, - HttpVersion(1, 0)}, + HttpVersion(1, 0), 200, "OK"}, {// Consolidate Set-Cookie headers. - "HTTP/1.1 200 OK\n" "Set-Cookie: x=1\n" "Set-Cookie: y=2\n", @@ -262,27 +250,22 @@ "HTTP/1.1 200 OK\n" "Set-Cookie: x=1, y=2\n", - 200, - HttpVersion(1, 1)}, + HttpVersion(1, 1), 200, "OK"}, + {// Consolidate cache-control headers. + "HTTP/1.1 200 OK\n" + "Cache-control: private\n" + "cache-Control: no-store\n", + + "HTTP/1.1 200 OK\n" + "Cache-control: private, no-store\n", + + HttpVersion(1, 1), 200, "OK"}, }; INSTANTIATE_TEST_CASE_P(HttpResponseHeaders, CommonHttpResponseHeadersTest, testing::ValuesIn(response_headers_tests)); -TEST(HttpResponseHeadersTest, GetNormalizedHeader) { - std::string headers = - "HTTP/1.1 200 OK\n" - "Cache-control: private\n" - "cache-Control: no-store\n"; - HeadersToRaw(&headers); - scoped_refptr<HttpResponseHeaders> parsed(new HttpResponseHeaders(headers)); - - std::string value; - EXPECT_TRUE(parsed->GetNormalizedHeader("cache-control", &value)); - EXPECT_EQ("private, no-store", value); -} - struct PersistData { HttpResponseHeaders::PersistOptions options; const char* raw_headers; @@ -1651,37 +1634,6 @@ HasStrongValidatorsTest, testing::ValuesIn(strong_validators_tests)); -TEST(HttpResponseHeadersTest, GetStatusText) { - std::string headers("HTTP/1.1 404 Not Found"); - HeadersToRaw(&headers); - scoped_refptr<HttpResponseHeaders> parsed(new HttpResponseHeaders(headers)); - EXPECT_EQ(std::string("Not Found"), parsed->GetStatusText()); -} - -TEST(HttpResponseHeadersTest, GetStatusTextMissing) { - std::string headers("HTTP/1.1 404"); - HeadersToRaw(&headers); - scoped_refptr<HttpResponseHeaders> parsed(new HttpResponseHeaders(headers)); - EXPECT_EQ(std::string("HTTP/1.1 404"), parsed->GetStatusLine()); - EXPECT_TRUE(parsed->GetStatusText().empty()); -} - -TEST(HttpResponseHeadersTest, GetStatusTextMultiSpace) { - std::string headers("HTTP/1.0 404 Not Found"); - HeadersToRaw(&headers); - scoped_refptr<HttpResponseHeaders> parsed(new HttpResponseHeaders(headers)); - EXPECT_EQ(std::string("Not Found"), parsed->GetStatusText()); -} - -TEST(HttpResponseHeadersTest, GetStatusBadStatusLine) { - std::string headers("Foo bar."); - HeadersToRaw(&headers); - scoped_refptr<HttpResponseHeaders> parsed(new HttpResponseHeaders(headers)); - // The bad status line should be rewritten. - EXPECT_EQ(std::string("HTTP/1.0 200"), parsed->GetStatusLine()); - EXPECT_TRUE(parsed->GetStatusText().empty()); -} - struct AddHeaderTestData { const char* orig_headers; const char* new_header;
diff --git a/net/http/http_security_headers.cc b/net/http/http_security_headers.cc index b99b206..ecb8e57 100644 --- a/net/http/http_security_headers.cc +++ b/net/http/http_security_headers.cc
@@ -2,8 +2,9 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. +#include <limits> + #include "base/base64.h" -#include "base/basictypes.h" #include "base/strings/string_number_conversions.h" #include "base/strings/string_piece.h" #include "base/strings/string_tokenizer.h" @@ -18,36 +19,36 @@ enum MaxAgeParsing { REQUIRE_MAX_AGE, DO_NOT_REQUIRE_MAX_AGE }; -static_assert(kMaxHSTSAgeSecs <= kuint32max, "kMaxHSTSAgeSecs too large"); +static_assert(kMaxHSTSAgeSecs <= UINT32_MAX, "kMaxHSTSAgeSecs too large"); // MaxAgeToInt converts a string representation of a "whole number" of -// seconds into a uint32. The string may contain an arbitrarily large number, +// seconds into a uint32_t. The string may contain an arbitrarily large number, // which will be clipped to kMaxHSTSAgeSecs and which is guaranteed to fit // within a 32-bit unsigned integer. False is returned on any parse error. bool MaxAgeToInt(std::string::const_iterator begin, std::string::const_iterator end, - uint32* result) { + uint32_t* result) { const base::StringPiece s(begin, end); if (s.empty()) return false; - int64 i = 0; + int64_t i = 0; - // Return false on any StringToInt64 parse errors *except* for - // int64 overflow. StringToInt64 is used, rather than StringToUint64, - // in order to properly handle and reject negative numbers - // (StringToUint64 does not return false on negative numbers). - // For values too large to be stored in an int64, StringToInt64 will - // return false with i set to kint64max, so this case is detected - // by the immediately following if-statement and allowed to fall - // through so that i gets clipped to kMaxHSTSAgeSecs. - if (!base::StringToInt64(s, &i) && i != kint64max) + // Return false on any StringToInt64 parse errors *except* for int64_t + // overflow. StringToInt64 is used, rather than StringToUint64, in order to + // properly handle and reject negative numbers (StringToUint64 does not return + // false on negative numbers). For values too large to be stored in an + // int64_t, StringToInt64 will return false with i set to + // std::numeric_limits<int64_t>::max(), so this case is detected by the + // immediately following if-statement and allowed to fall through so that i + // gets clipped to kMaxHSTSAgeSecs. + if (!base::StringToInt64(s, &i) && i != std::numeric_limits<int64_t>::max()) return false; if (i < 0) return false; if (i > kMaxHSTSAgeSecs) i = kMaxHSTSAgeSecs; - *result = (uint32)i; + *result = (uint32_t)i; return true; } @@ -128,7 +129,7 @@ GURL* report_uri) { bool parsed_max_age = false; bool include_subdomains_candidate = false; - uint32 max_age_candidate = 0; + uint32_t max_age_candidate = 0; GURL parsed_report_uri; HashValueVector pins; bool require_max_age = max_age_status == REQUIRE_MAX_AGE; @@ -224,7 +225,7 @@ bool ParseHSTSHeader(const std::string& value, base::TimeDelta* max_age, bool* include_subdomains) { - uint32 max_age_candidate = 0; + uint32_t max_age_candidate = 0; bool include_subdomains_candidate = false; // We must see max-age exactly once.
diff --git a/net/http/http_security_headers.h b/net/http/http_security_headers.h index f54df69..af90430 100644 --- a/net/http/http_security_headers.h +++ b/net/http/http_security_headers.h
@@ -5,9 +5,10 @@ #ifndef NET_HTTP_HTTP_SECURITY_HEADERS_H_ #define NET_HTTP_HTTP_SECURITY_HEADERS_H_ +#include <stdint.h> + #include <string> -#include "base/basictypes.h" #include "base/time/time.h" #include "base/values.h" #include "net/base/hash_value.h" @@ -17,7 +18,7 @@ namespace net { -const int64 kMaxHSTSAgeSecs = 86400 * 365; // 1 year +const int64_t kMaxHSTSAgeSecs = 86400 * 365; // 1 year // Parses |value| as a Strict-Transport-Security header value. If successful, // returns true and sets |*max_age| and |*include_subdomains|.
diff --git a/net/http/http_stream_parser.cc b/net/http/http_stream_parser.cc index 9ddae48..4e4b6b6 100644 --- a/net/http/http_stream_parser.cc +++ b/net/http/http_stream_parser.cc
@@ -1078,7 +1078,7 @@ return false; if (!response_->headers || !response_->headers->IsKeepAlive()) return false; - return connection_->socket() && connection_->socket()->IsConnectedAndIdle(); + return connection_->socket() && connection_->socket()->IsConnected(); } void HttpStreamParser::GetSSLInfo(SSLInfo* ssl_info) {
diff --git a/net/http/http_stream_parser.h b/net/http/http_stream_parser.h index f56e7de..f8700c4 100644 --- a/net/http/http_stream_parser.h +++ b/net/http/http_stream_parser.h
@@ -79,7 +79,8 @@ // The connection can be reused if: // * It's still connected. // * The response headers indicate the connection can be kept alive. - // * The end of the response can be found. + // * The end of the response can be found, though it may not have yet been + // received. // // Note that if response headers have yet to be received, this will return // false.
diff --git a/net/http/transport_security_state_static.certs b/net/http/transport_security_state_static.certs index 012b352..9d8f2a6c 100644 --- a/net/http/transport_security_state_static.certs +++ b/net/http/transport_security_state_static.certs
@@ -7,7 +7,8 @@ # details. # Each entry consists of a line containing the name of the pin followed either -# by a hash in the format "sha256/" + base64(hash), or a PEM encoded certificate. +# by a hash in the format "sha256/" + base64(hash), a PEM encoded certificate, +# or a PEM encoded public key. TestSPKI sha256/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=
diff --git a/net/net.gyp b/net/net.gyp index f4c9894e2..32dbf4cc 100644 --- a/net/net.gyp +++ b/net/net.gyp
@@ -527,6 +527,7 @@ 'cookies/cookie_store_test_callbacks.h', 'cookies/cookie_store_test_helpers.cc', 'cookies/cookie_store_test_helpers.h', + 'cookies/cookie_store_unittest.h', 'disk_cache/disk_cache_test_base.cc', 'disk_cache/disk_cache_test_base.h', 'disk_cache/disk_cache_test_util.cc',
diff --git a/net/net.gypi b/net/net.gypi index 9d5c3c5..e38f2e33 100644 --- a/net/net.gypi +++ b/net/net.gypi
@@ -30,6 +30,8 @@ 'base/io_buffer.h', 'base/ip_address_number.cc', 'base/ip_address_number.h', + 'base/ip_address.cc', + 'base/ip_address.h', 'base/ip_endpoint.cc', 'base/ip_endpoint.h', 'base/load_timing_info.cc', @@ -1290,6 +1292,7 @@ 'base/host_port_pair_unittest.cc', 'base/int128_unittest.cc', 'base/ip_address_number_unittest.cc', + 'base/ip_address_unittest.cc', 'base/ip_endpoint_unittest.cc', 'base/ip_pattern_unittest.cc', 'base/keygen_handler_unittest.cc', @@ -1353,7 +1356,6 @@ 'cookies/canonical_cookie_unittest.cc', 'cookies/cookie_constants_unittest.cc', 'cookies/cookie_monster_unittest.cc', - 'cookies/cookie_store_unittest.h', 'cookies/cookie_util_unittest.cc', 'cookies/parsed_cookie_unittest.cc', 'der/input_unittest.cc',
diff --git a/net/proxy/multi_threaded_proxy_resolver.cc b/net/proxy/multi_threaded_proxy_resolver.cc index 7f03bbf..e03eb28 100644 --- a/net/proxy/multi_threaded_proxy_resolver.cc +++ b/net/proxy/multi_threaded_proxy_resolver.cc
@@ -5,6 +5,7 @@ #include "net/proxy/multi_threaded_proxy_resolver.h" #include <deque> +#include <utility> #include <vector> #include "base/bind.h" @@ -576,8 +577,8 @@ int error = OK; if (executor->resolver()) { resolver_out_->reset(new MultiThreadedProxyResolver( - resolver_factory_.Pass(), max_num_threads_, script_data_.Pass(), - executor_)); + std::move(resolver_factory_), max_num_threads_, + std::move(script_data_), executor_)); } else { error = ERR_PAC_SCRIPT_FAILED; executor_->Destroy();
diff --git a/net/quic/crypto/quic_crypto_client_config_test.cc b/net/quic/crypto/quic_crypto_client_config_test.cc index 238011f..418f6c4 100644 --- a/net/quic/crypto/quic_crypto_client_config_test.cc +++ b/net/quic/crypto/quic_crypto_client_config_test.cc
@@ -346,43 +346,9 @@ EXPECT_EQ(2u, cleared_cache->generation_counter()); } -// Creates a minimal dummy reject message that will pass the client-config -// validation tests. -void FillInDummyReject(CryptoHandshakeMessage* rej, bool reject_is_stateless) { - if (reject_is_stateless) { - rej->set_tag(kSREJ); - } else { - rej->set_tag(kREJ); - } - - // Minimum SCFG that passes config validation checks. - // clang-format off - unsigned char scfg[] = { - // SCFG - 0x53, 0x43, 0x46, 0x47, - // num entries - 0x01, 0x00, - // padding - 0x00, 0x00, - // EXPY - 0x45, 0x58, 0x50, 0x59, - // EXPY end offset - 0x08, 0x00, 0x00, 0x00, - // Value - '1', '2', '3', '4', - '5', '6', '7', '8' - }; - // clang-format on - rej->SetValue(kSCFG, scfg); - rej->SetStringPiece(kServerNonceTag, "SERVER_NONCE"); - vector<QuicTag> reject_reasons; - reject_reasons.push_back(CLIENT_NONCE_INVALID_FAILURE); - rej->SetVector(kRREJ, reject_reasons); -} - TEST(QuicCryptoClientConfigTest, ProcessReject) { CryptoHandshakeMessage rej; - FillInDummyReject(&rej, /* stateless */ false); + CryptoTestUtils::FillInDummyReject(&rej, /* stateless */ false); // Now process the rejection. QuicCryptoClientConfig::CachedState cached; @@ -400,7 +366,7 @@ TEST(QuicCryptoClientConfigTest, ProcessStatelessReject) { // Create a dummy reject message and mark it as stateless. CryptoHandshakeMessage rej; - FillInDummyReject(&rej, /* stateless */ true); + CryptoTestUtils::FillInDummyReject(&rej, /* stateless */ true); const QuicConnectionId kConnectionId = 0xdeadbeef; const string server_nonce = "SERVER_NONCE"; rej.SetValue(kRCID, kConnectionId); @@ -424,7 +390,7 @@ // Create a dummy reject message and mark it as stateless. Do not // add an server-designated connection-id. CryptoHandshakeMessage rej; - FillInDummyReject(&rej, /* stateless */ true); + CryptoTestUtils::FillInDummyReject(&rej, /* stateless */ true); // Now process the rejection. QuicCryptoClientConfig::CachedState cached;
diff --git a/net/quic/quic_crypto_client_stream.cc b/net/quic/quic_crypto_client_stream.cc index 2c2a98c..668cff9 100644 --- a/net/quic/quic_crypto_client_stream.cc +++ b/net/quic/quic_crypto_client_stream.cc
@@ -255,6 +255,7 @@ // Send the client hello in plaintext. session()->connection()->SetDefaultEncryptionLevel(ENCRYPTION_NONE); + encryption_established_ = false; if (num_client_hellos_ > kMaxClientHellos) { CloseConnection(QUIC_CRYPTO_TOO_MANY_REJECTS); return;
diff --git a/net/quic/quic_flags.cc b/net/quic/quic_flags.cc index b63a0e5..8d45f32e 100644 --- a/net/quic/quic_flags.cc +++ b/net/quic/quic_flags.cc
@@ -118,3 +118,7 @@ // If true, allow each quic stream to write 16k blocks rather than doing a round // robin of one packet per session when ack clocked or paced. bool FLAGS_quic_batch_writes = true; + +// If true, QUIC sessions will write block streams that attempt to write +// unencrypted data. +bool FLAGS_quic_block_unencrypted_writes = true;
diff --git a/net/quic/quic_flags.h b/net/quic/quic_flags.h index 8f4ee24..78c5c50 100644 --- a/net/quic/quic_flags.h +++ b/net/quic/quic_flags.h
@@ -38,4 +38,6 @@ NET_EXPORT_PRIVATE extern bool FLAGS_quic_set_client_hello_cb_nullptr; NET_EXPORT_PRIVATE extern bool FLAGS_quic_track_single_retransmission; NET_EXPORT_PRIVATE extern bool FLAGS_quic_batch_writes; +NET_EXPORT_PRIVATE extern bool FLAGS_quic_block_unencrypted_writes; + #endif // NET_QUIC_QUIC_FLAGS_H_
diff --git a/net/quic/quic_session.cc b/net/quic/quic_session.cc index fc8e42f..ca11f6ba 100644 --- a/net/quic/quic_session.cc +++ b/net/quic/quic_session.cc
@@ -292,6 +292,12 @@ bool fin, FecProtection fec_protection, QuicAckListenerInterface* ack_notifier_delegate) { + if (FLAGS_quic_block_unencrypted_writes && !IsEncryptionEstablished() && + id != kCryptoStreamId) { + // Do not let streams write without encryption. The calling stream will end + // up write blocked until OnCanWrite is next called. + return QuicConsumedData(0, false); + } QuicConsumedData data = connection_->SendStreamData( id, iov, offset, fin, fec_protection, ack_notifier_delegate); write_blocked_streams_.UpdateBytesForStream(id, data.bytes_consumed); @@ -517,12 +523,20 @@ // TODO(satyamshekhar): Move the logic of setting the encrypter/decrypter // to QuicSession since it is the glue. case ENCRYPTION_FIRST_ESTABLISHED: + // Given any streams blocked by encryption a chance to write. + if (FLAGS_quic_block_unencrypted_writes) { + OnCanWrite(); + } break; case ENCRYPTION_REESTABLISHED: // Retransmit originally packets that were sent, since they can't be // decrypted by the peer. connection_->RetransmitUnackedPackets(ALL_INITIAL_RETRANSMISSION); + // Given any streams blocked by encryption a chance to write. + if (FLAGS_quic_block_unencrypted_writes) { + OnCanWrite(); + } break; case HANDSHAKE_CONFIRMED:
diff --git a/net/quic/quic_session_test.cc b/net/quic/quic_session_test.cc index 35473da..7299c40 100644 --- a/net/quic/quic_session_test.cc +++ b/net/quic/quic_session_test.cc
@@ -505,6 +505,10 @@ } TEST_P(QuicSessionTestServer, OnCanWriteBundlesStreams) { + // Encryption needs to be established before data can be sent. + CryptoHandshakeMessage msg; + session_.GetCryptoStream()->OnHandshakeMessage(msg); + // Drive congestion control manually. MockSendAlgorithm* send_algorithm = new StrictMock<MockSendAlgorithm>; QuicConnectionPeer::SetSendAlgorithm(session_.connection(), send_algorithm);
diff --git a/net/quic/test_tools/crypto_test_utils.cc b/net/quic/test_tools/crypto_test_utils.cc index 7c3e8b9..ed34502 100644 --- a/net/quic/test_tools/crypto_test_utils.cc +++ b/net/quic/test_tools/crypto_test_utils.cc
@@ -355,6 +355,40 @@ return new class MockCommonCertSets(cert, hash, index); } +// static +void CryptoTestUtils::FillInDummyReject(CryptoHandshakeMessage* rej, + bool reject_is_stateless) { + if (reject_is_stateless) { + rej->set_tag(kSREJ); + } else { + rej->set_tag(kREJ); + } + + // Minimum SCFG that passes config validation checks. + // clang-format off + unsigned char scfg[] = { + // SCFG + 0x53, 0x43, 0x46, 0x47, + // num entries + 0x01, 0x00, + // padding + 0x00, 0x00, + // EXPY + 0x45, 0x58, 0x50, 0x59, + // EXPY end offset + 0x08, 0x00, 0x00, 0x00, + // Value + '1', '2', '3', '4', + '5', '6', '7', '8' + }; + // clang-format on + rej->SetValue(kSCFG, scfg); + rej->SetStringPiece(kServerNonceTag, "SERVER_NONCE"); + vector<QuicTag> reject_reasons; + reject_reasons.push_back(CLIENT_NONCE_INVALID_FAILURE); + rej->SetVector(kRREJ, reject_reasons); +} + void CryptoTestUtils::CompareClientAndServerKeys( QuicCryptoClientStream* client, QuicCryptoServerStream* server) {
diff --git a/net/quic/test_tools/crypto_test_utils.h b/net/quic/test_tools/crypto_test_utils.h index b823c61..56b07507 100644 --- a/net/quic/test_tools/crypto_test_utils.h +++ b/net/quic/test_tools/crypto_test_utils.h
@@ -156,6 +156,12 @@ uint64 hash, uint32 index); + // Creates a minimal dummy reject message that will pass the client-config + // validation tests. This will include a server config, but no certs, proof + // source address token, or server nonce. + static void FillInDummyReject(CryptoHandshakeMessage* rej, + bool reject_is_stateless); + // ParseTag returns a QuicTag from parsing |tagstr|. |tagstr| may either be // in the format "EXMP" (i.e. ASCII format), or "#11223344" (an explicit hex // format). It CHECK fails if there's a parse error.
diff --git a/net/quic/test_tools/quic_packet_creator_peer.cc b/net/quic/test_tools/quic_packet_creator_peer.cc index 0d20315..a310121f 100644 --- a/net/quic/test_tools/quic_packet_creator_peer.cc +++ b/net/quic/test_tools/quic_packet_creator_peer.cc
@@ -117,5 +117,11 @@ return creator->rtt_multiplier_for_fec_timeout_; } +// static +EncryptionLevel QuicPacketCreatorPeer::GetEncryptionLevel( + QuicPacketCreator* creator) { + return creator->encryption_level_; +} + } // namespace test } // namespace net
diff --git a/net/quic/test_tools/quic_packet_creator_peer.h b/net/quic/test_tools/quic_packet_creator_peer.h index ca62f36..b871c40 100644 --- a/net/quic/test_tools/quic_packet_creator_peer.h +++ b/net/quic/test_tools/quic_packet_creator_peer.h
@@ -51,6 +51,7 @@ static QuicTime::Delta GetFecTimeout(QuicPacketCreator* creator); // TODO(rtenneti): Delete this code after the 0.25 RTT FEC experiment. static float GetRttMultiplierForFecTimeout(QuicPacketCreator* creator); + static EncryptionLevel GetEncryptionLevel(QuicPacketCreator* creator); private: DISALLOW_COPY_AND_ASSIGN(QuicPacketCreatorPeer);
diff --git a/net/socket/ssl_client_socket_unittest.cc b/net/socket/ssl_client_socket_unittest.cc index c048bea..dce9f0a 100644 --- a/net/socket/ssl_client_socket_unittest.cc +++ b/net/socket/ssl_client_socket_unittest.cc
@@ -690,7 +690,9 @@ const AddressList& addr() const { return addr_; } // The SpawnedTestServer object, after calling StartTestServer(). - const SpawnedTestServer* test_server() const { return test_server_.get(); } + const SpawnedTestServer* spawned_test_server() const { + return spawned_test_server_.get(); + } void SetCTVerifier(CTVerifier* ct_verifier) { context_.cert_transparency_verifier = ct_verifier; @@ -699,14 +701,14 @@ // Starts the test server with SSL configuration |ssl_options|. Returns true // on success. bool StartTestServer(const SpawnedTestServer::SSLOptions& ssl_options) { - test_server_.reset(new SpawnedTestServer( + spawned_test_server_.reset(new SpawnedTestServer( SpawnedTestServer::TYPE_HTTPS, ssl_options, base::FilePath())); - if (!test_server_->Start()) { + if (!spawned_test_server_->Start()) { LOG(ERROR) << "Could not start SpawnedTestServer"; return false; } - if (!test_server_->GetAddressList(&addr_)) { + if (!spawned_test_server_->GetAddressList(&addr_)) { LOG(ERROR) << "Could not get SpawnedTestServer address list"; return false; } @@ -741,8 +743,8 @@ return false; } - sock_ = CreateSSLClientSocket(transport.Pass(), - test_server_->host_port_pair(), ssl_config); + sock_ = CreateSSLClientSocket( + transport.Pass(), spawned_test_server_->host_port_pair(), ssl_config); EXPECT_FALSE(sock_->IsConnected()); *result = callback_.GetResult(sock_->Connect(callback_.callback())); @@ -757,7 +759,7 @@ TestNetLog log_; private: - scoped_ptr<SpawnedTestServer> test_server_; + scoped_ptr<SpawnedTestServer> spawned_test_server_; TestCompletionCallback callback_; AddressList addr_; }; @@ -769,13 +771,13 @@ // the SSLCertRequestInfo reported by the socket. scoped_refptr<SSLCertRequestInfo> GetCertRequest( SpawnedTestServer::SSLOptions ssl_options) { - SpawnedTestServer test_server( - SpawnedTestServer::TYPE_HTTPS, ssl_options, base::FilePath()); - if (!test_server.Start()) + SpawnedTestServer spawned_test_server(SpawnedTestServer::TYPE_HTTPS, + ssl_options, base::FilePath()); + if (!spawned_test_server.Start()) return NULL; AddressList addr; - if (!test_server.GetAddressList(&addr)) + if (!spawned_test_server.GetAddressList(&addr)) return NULL; TestCompletionCallback callback; @@ -786,7 +788,7 @@ EXPECT_EQ(OK, rv); scoped_ptr<SSLClientSocket> sock(CreateSSLClientSocket( - transport.Pass(), test_server.host_port_pair(), SSLConfig())); + transport.Pass(), spawned_test_server.host_port_pair(), SSLConfig())); EXPECT_FALSE(sock->IsConnected()); rv = callback.GetResult(sock->Connect(callback.callback())); @@ -796,8 +798,8 @@ sock->GetSSLCertRequestInfo(request_info.get()); sock->Disconnect(); EXPECT_FALSE(sock->IsConnected()); - EXPECT_TRUE( - test_server.host_port_pair().Equals(request_info->host_and_port)); + EXPECT_TRUE(spawned_test_server.host_port_pair().Equals( + request_info->host_and_port)); return request_info; } @@ -823,7 +825,7 @@ TestCompletionCallback* callback, FakeBlockingStreamSocket** out_raw_transport, scoped_ptr<SSLClientSocket>* out_sock) { - CHECK(test_server()); + CHECK(spawned_test_server()); scoped_ptr<StreamSocket> real_transport( new TCPClientSocket(addr(), NULL, NetLog::Source())); @@ -834,7 +836,8 @@ FakeBlockingStreamSocket* raw_transport = transport.get(); scoped_ptr<SSLClientSocket> sock = CreateSSLClientSocket( - transport.Pass(), test_server()->host_port_pair(), client_config); + transport.Pass(), spawned_test_server()->host_port_pair(), + client_config); // Connect. Stop before the client processes the first server leg // (ServerHello, etc.) @@ -949,7 +952,7 @@ EXPECT_EQ(OK, rv); scoped_ptr<SSLClientSocket> sock(CreateSSLClientSocket( - transport.Pass(), test_server()->host_port_pair(), SSLConfig())); + transport.Pass(), spawned_test_server()->host_port_pair(), SSLConfig())); EXPECT_FALSE(sock->IsConnected()); @@ -1096,7 +1099,7 @@ EXPECT_EQ(OK, rv); scoped_ptr<SSLClientSocket> sock(CreateSSLClientSocket( - transport.Pass(), test_server()->host_port_pair(), SSLConfig())); + transport.Pass(), spawned_test_server()->host_port_pair(), SSLConfig())); EXPECT_EQ(0, sock->GetTotalReceivedBytes()); rv = callback.GetResult(sock->Connect(callback.callback())); @@ -1157,7 +1160,7 @@ SynchronousErrorStreamSocket* raw_transport = transport.get(); scoped_ptr<SSLClientSocket> sock(CreateSSLClientSocket( - transport.Pass(), test_server()->host_port_pair(), ssl_config)); + transport.Pass(), spawned_test_server()->host_port_pair(), ssl_config)); raw_transport->SetNextWriteError(ERR_CONNECTION_RESET); @@ -1187,7 +1190,7 @@ SynchronousErrorStreamSocket* raw_transport = transport.get(); scoped_ptr<SSLClientSocket> sock(CreateSSLClientSocket( - transport.Pass(), test_server()->host_port_pair(), ssl_config)); + transport.Pass(), spawned_test_server()->host_port_pair(), ssl_config)); rv = callback.GetResult(sock->Connect(callback.callback())); EXPECT_EQ(OK, rv); @@ -1241,7 +1244,7 @@ ssl_config.false_start_enabled = false; scoped_ptr<SSLClientSocket> sock(CreateSSLClientSocket( - transport.Pass(), test_server()->host_port_pair(), ssl_config)); + transport.Pass(), spawned_test_server()->host_port_pair(), ssl_config)); rv = callback.GetResult(sock->Connect(callback.callback())); EXPECT_EQ(OK, rv); @@ -1307,7 +1310,8 @@ ssl_config.false_start_enabled = false; scoped_ptr<SSLClientSocket> sock(CreateSSLClientSocket( - counting_socket.Pass(), test_server()->host_port_pair(), ssl_config)); + counting_socket.Pass(), spawned_test_server()->host_port_pair(), + ssl_config)); rv = callback.GetResult(sock->Connect(callback.callback())); ASSERT_EQ(OK, rv); @@ -1407,7 +1411,7 @@ ssl_config.false_start_enabled = false; scoped_ptr<SSLClientSocket> sock = CreateSSLClientSocket( - transport.Pass(), test_server()->host_port_pair(), ssl_config); + transport.Pass(), spawned_test_server()->host_port_pair(), ssl_config); rv = callback.GetResult(sock->Connect(callback.callback())); EXPECT_EQ(OK, rv); @@ -1515,7 +1519,7 @@ ssl_config.false_start_enabled = false; scoped_ptr<SSLClientSocket> sock(CreateSSLClientSocket( - transport.Pass(), test_server()->host_port_pair(), ssl_config)); + transport.Pass(), spawned_test_server()->host_port_pair(), ssl_config)); rv = callback.GetResult(sock->Connect(callback.callback())); EXPECT_EQ(OK, rv); @@ -1601,7 +1605,7 @@ SynchronousErrorStreamSocket* raw_transport = transport.get(); scoped_ptr<SSLClientSocket> sock(CreateSSLClientSocket( - transport.Pass(), test_server()->host_port_pair(), SSLConfig())); + transport.Pass(), spawned_test_server()->host_port_pair(), SSLConfig())); raw_transport->SetNextReadError(0); @@ -1630,7 +1634,7 @@ SynchronousErrorStreamSocket* raw_transport = transport.get(); scoped_ptr<SSLClientSocket> sock(CreateSSLClientSocket( - transport.Pass(), test_server()->host_port_pair(), ssl_config)); + transport.Pass(), spawned_test_server()->host_port_pair(), ssl_config)); rv = callback.GetResult(sock->Connect(callback.callback())); EXPECT_EQ(OK, rv); @@ -1665,7 +1669,7 @@ ssl_config.false_start_enabled = false; scoped_ptr<SSLClientSocket> sock(CreateSSLClientSocket( - transport.Pass(), test_server()->host_port_pair(), ssl_config)); + transport.Pass(), spawned_test_server()->host_port_pair(), ssl_config)); rv = callback.GetResult(sock->Connect(callback.callback())); EXPECT_EQ(OK, rv); @@ -1738,7 +1742,7 @@ ASSERT_EQ(OK, rv); scoped_ptr<SSLClientSocket> sock(CreateSSLClientSocket( - transport.Pass(), test_server()->host_port_pair(), SSLConfig())); + transport.Pass(), spawned_test_server()->host_port_pair(), SSLConfig())); rv = callback.GetResult(sock->Connect(callback.callback())); ASSERT_EQ(OK, rv); @@ -1805,7 +1809,7 @@ EXPECT_EQ(OK, rv); scoped_ptr<SSLClientSocket> sock(CreateSSLClientSocket( - transport.Pass(), test_server()->host_port_pair(), SSLConfig())); + transport.Pass(), spawned_test_server()->host_port_pair(), SSLConfig())); rv = callback.GetResult(sock->Connect(callback.callback())); EXPECT_EQ(OK, rv); @@ -1873,7 +1877,7 @@ EXPECT_EQ(OK, rv); scoped_ptr<SSLClientSocket> sock(CreateSSLClientSocket( - transport.Pass(), test_server()->host_port_pair(), SSLConfig())); + transport.Pass(), spawned_test_server()->host_port_pair(), SSLConfig())); rv = callback.GetResult(sock->Connect(callback.callback())); EXPECT_EQ(ERR_SSL_PROTOCOL_ERROR, rv); @@ -1920,8 +1924,8 @@ socket_handle->SetSocket(transport.Pass()); scoped_ptr<SSLClientSocket> sock(socket_factory_->CreateSSLClientSocket( - socket_handle.Pass(), test_server()->host_port_pair(), SSLConfig(), - context_)); + socket_handle.Pass(), spawned_test_server()->host_port_pair(), + SSLConfig(), context_)); EXPECT_FALSE(sock->IsConnected()); rv = callback.GetResult(sock->Connect(callback.callback())); @@ -2356,7 +2360,7 @@ ASSERT_EQ(OK, callback.GetResult(transport->Connect(callback.callback()))); scoped_ptr<SSLClientSocket> sock(CreateSSLClientSocket( - transport.Pass(), test_server()->host_port_pair(), SSLConfig())); + transport.Pass(), spawned_test_server()->host_port_pair(), SSLConfig())); ASSERT_EQ(OK, callback.GetResult(sock->Connect(callback.callback()))); // Block any application data from reaching the network.
diff --git a/net/spdy/hpack/hpack_huffman_table_test.cc b/net/spdy/hpack/hpack_huffman_table_test.cc index a48ccb4..fe2420e 100644 --- a/net/spdy/hpack/hpack_huffman_table_test.cc +++ b/net/spdy/hpack/hpack_huffman_table_test.cc
@@ -4,7 +4,10 @@ #include "net/spdy/hpack/hpack_huffman_table.h" +#include <stdint.h> + #include <bitset> +#include <limits> #include <string> #include "base/logging.h" @@ -32,8 +35,8 @@ explicit HpackHuffmanTablePeer(const HpackHuffmanTable& table) : table_(table) {} - const std::vector<uint32>& code_by_id() const { return table_.code_by_id_; } - const std::vector<uint8>& length_by_id() const { + const std::vector<uint32_t>& code_by_id() const { return table_.code_by_id_; } + const std::vector<uint8_t>& length_by_id() const { return table_.length_by_id_; } const std::vector<DecodeTable>& decode_tables() const { @@ -43,7 +46,7 @@ // Cast to match signed-ness of bits8(). return static_cast<char>(table_.pad_bits_); } - uint16 failed_symbol_id() const { return table_.failed_symbol_id_; } + uint16_t failed_symbol_id() const { return table_.failed_symbol_id_; } std::vector<DecodeEntry> decode_entries(const DecodeTable& decode_table) { std::vector<DecodeEntry>::const_iterator begin = table_.decode_entries_.begin() + decode_table.entries_offset; @@ -82,7 +85,7 @@ lhs.length == rhs.length && lhs.symbol_id == rhs.symbol_id; } -uint32 bits32(const string& bitstring) { +uint32_t bits32(const string& bitstring) { return std::bitset<32>(bitstring).to_ulong(); } char bits8(const string& bitstring) { @@ -239,7 +242,8 @@ EXPECT_EQ(expect, buffer_in); string buffer_out; - HpackInputStream input_stream(kuint32max, buffer_in); + HpackInputStream input_stream(std::numeric_limits<uint32_t>::max(), + buffer_in); EXPECT_TRUE(table_.DecodeString(&input_stream, input.size(), &buffer_out)); EXPECT_EQ(buffer_out, input); } @@ -304,7 +308,7 @@ char input_storage[] = {bits8("00010001"), bits8("00110100")}; StringPiece input(input_storage, arraysize(input_storage)); - HpackInputStream input_stream(kuint32max, input); + HpackInputStream input_stream(std::numeric_limits<uint32_t>::max(), input); EXPECT_TRUE(table_.DecodeString(&input_stream, capacity, &buffer)); EXPECT_EQ(buffer, "\x02\x03\x02\x06"); } @@ -314,7 +318,7 @@ char input_storage[] = {bits8("00010001"), bits8("01000111")}; StringPiece input(input_storage, arraysize(input_storage)); - HpackInputStream input_stream(kuint32max, input); + HpackInputStream input_stream(std::numeric_limits<uint32_t>::max(), input); EXPECT_FALSE(table_.DecodeString(&input_stream, capacity, &buffer)); EXPECT_EQ(buffer, "\x02\x03\x02"); } @@ -323,7 +327,7 @@ std::vector<char> input_storage(1 + capacity / 4, '\0'); StringPiece input(&input_storage[0], input_storage.size()); - HpackInputStream input_stream(kuint32max, input); + HpackInputStream input_stream(std::numeric_limits<uint32_t>::max(), input); EXPECT_FALSE(table_.DecodeString(&input_stream, capacity, &buffer)); std::vector<char> expected(capacity, '\x02'); @@ -336,7 +340,7 @@ char input_storage[] = {bits8("10011010"), bits8("01110000")}; StringPiece input(input_storage, arraysize(input_storage)); - HpackInputStream input_stream(kuint32max, input); + HpackInputStream input_stream(std::numeric_limits<uint32_t>::max(), input); EXPECT_FALSE(table_.DecodeString(&input_stream, capacity, &buffer)); EXPECT_EQ(buffer, "\x06"); } @@ -361,7 +365,8 @@ for (size_t i = 0; i != arraysize(test_table); i += 2) { const string& encodedFixture(test_table[i]); const string& decodedFixture(test_table[i + 1]); - HpackInputStream input_stream(kuint32max, encodedFixture); + HpackInputStream input_stream(std::numeric_limits<uint32_t>::max(), + encodedFixture); EXPECT_TRUE( table_.DecodeString(&input_stream, decodedFixture.size(), &buffer)); @@ -392,7 +397,8 @@ for (size_t i = 0; i != arraysize(test_table); i += 2) { const string& encodedFixture(test_table[i]); const string& decodedFixture(test_table[i + 1]); - HpackInputStream input_stream(kuint32max, encodedFixture); + HpackInputStream input_stream(std::numeric_limits<uint32_t>::max(), + encodedFixture); EXPECT_TRUE( table_.DecodeString(&input_stream, decodedFixture.size(), &buffer)); @@ -414,7 +420,8 @@ string buffer_in = EncodeString(input); string buffer_out; - HpackInputStream input_stream(kuint32max, buffer_in); + HpackInputStream input_stream(std::numeric_limits<uint32_t>::max(), + buffer_in); EXPECT_TRUE(table_.DecodeString(&input_stream, input.size(), &buffer_out)); EXPECT_EQ(input, buffer_out); } @@ -434,7 +441,8 @@ string buffer_in = EncodeString(input); string buffer_out; - HpackInputStream input_stream(kuint32max, buffer_in); + HpackInputStream input_stream(std::numeric_limits<uint32_t>::max(), + buffer_in); EXPECT_TRUE(table_.DecodeString(&input_stream, input.size(), &buffer_out)); EXPECT_EQ(input, buffer_out); }
diff --git a/net/ssl/client_key_store.cc b/net/ssl/client_key_store.cc index 5001703..87dafec1 100644 --- a/net/ssl/client_key_store.cc +++ b/net/ssl/client_key_store.cc
@@ -5,6 +5,7 @@ #include "net/ssl/client_key_store.h" #include <algorithm> +#include <utility> #include "net/cert/x509_certificate.h" #include "net/ssl/ssl_private_key.h" @@ -45,7 +46,7 @@ for (const auto& provider : providers_) { scoped_refptr<SSLPrivateKey> key; if (provider->GetCertificateKey(certificate, &key)) - return key.Pass(); + return key; } return nullptr; }
diff --git a/net/ssl/ssl_platform_key_task_runner.cc b/net/ssl/ssl_platform_key_task_runner.cc index 963b6d7..7611d60 100644 --- a/net/ssl/ssl_platform_key_task_runner.cc +++ b/net/ssl/ssl_platform_key_task_runner.cc
@@ -25,7 +25,7 @@ LAZY_INSTANCE_INITIALIZER; scoped_refptr<base::SequencedTaskRunner> GetSSLPlatformKeyTaskRunner() { - return g_platform_key_task_runner.Get().task_runner().Pass(); + return g_platform_key_task_runner.Get().task_runner(); } } // namespace net
diff --git a/net/ssl/threaded_ssl_private_key.cc b/net/ssl/threaded_ssl_private_key.cc index c96598f..11698620 100644 --- a/net/ssl/threaded_ssl_private_key.cc +++ b/net/ssl/threaded_ssl_private_key.cc
@@ -5,6 +5,7 @@ #include "net/ssl/threaded_ssl_private_key.h" #include <string> +#include <utility> #include "base/bind.h" #include "base/location.h" @@ -50,10 +51,9 @@ ThreadedSSLPrivateKey::ThreadedSSLPrivateKey( scoped_ptr<ThreadedSSLPrivateKey::Delegate> delegate, scoped_refptr<base::TaskRunner> task_runner) - : core_(new Core(delegate.Pass())), - task_runner_(task_runner.Pass()), - weak_factory_(this) { -} + : core_(new Core(std::move(delegate))), + task_runner_(std::move(task_runner)), + weak_factory_(this) {} SSLPrivateKey::Type ThreadedSSLPrivateKey::GetType() { return core_->delegate()->GetType();
diff --git a/net/test/embedded_test_server/default_handlers.cc b/net/test/embedded_test_server/default_handlers.cc index b1fe69d4..f2e1acc3 100644 --- a/net/test/embedded_test_server/default_handlers.cc +++ b/net/test/embedded_test_server/default_handlers.cc
@@ -623,7 +623,6 @@ // TODO(svaldez): HandleDownload // TODO(svaldez): HandleDownloadFinish // TODO(svaldez): HandleZipFile - // TODO(svaldez): HandleRangeReset // TODO(svaldez): HandleSSLManySmallRecords // TODO(svaldez): HandleChunkedServer // TODO(svaldez): HandleGetSSLSessionCache
diff --git a/net/tools/quic/quic_client_session_test.cc b/net/tools/quic/quic_client_session_test.cc index ec0770a..7ee0c16 100644 --- a/net/tools/quic/quic_client_session_test.cc +++ b/net/tools/quic/quic_client_session_test.cc
@@ -10,6 +10,8 @@ #include "net/quic/crypto/aes_128_gcm_12_encrypter.h" #include "net/quic/quic_flags.h" #include "net/quic/test_tools/crypto_test_utils.h" +#include "net/quic/test_tools/quic_connection_peer.h" +#include "net/quic/test_tools/quic_packet_creator_peer.h" #include "net/quic/test_tools/quic_spdy_session_peer.h" #include "net/quic/test_tools/quic_test_utils.h" #include "net/tools/quic/quic_spdy_client_stream.h" @@ -22,6 +24,8 @@ using net::test::MockConnection; using net::test::MockConnectionHelper; using net::test::PacketSavingConnection; +using net::test::QuicConnectionPeer; +using net::test::QuicPacketCreatorPeer; using net::test::QuicSpdySessionPeer; using net::test::SupportedVersions; using net::test::TestPeerIPAddress; @@ -44,20 +48,23 @@ : public ::testing::TestWithParam<QuicVersion> { protected: ToolsQuicClientSessionTest() - : crypto_config_(CryptoTestUtils::ProofVerifierForTesting()), - connection_(new PacketSavingConnection(&helper_, - Perspective::IS_CLIENT, - SupportedVersions(GetParam()))), - session_(new QuicClientSession( - DefaultQuicConfig(), - connection_, - QuicServerId(kServerHostname, kPort, PRIVACY_MODE_DISABLED), - &crypto_config_)) { - session_->Initialize(); + : crypto_config_(CryptoTestUtils::ProofVerifierForTesting()) { + Initialize(); // Advance the time, because timers do not like uninitialized times. connection_->AdvanceTime(QuicTime::Delta::FromSeconds(1)); } + void Initialize() { + session_.reset(); + connection_ = new PacketSavingConnection(&helper_, Perspective::IS_CLIENT, + SupportedVersions(GetParam())); + session_.reset(new QuicClientSession( + DefaultQuicConfig(), connection_, + QuicServerId(kServerHostname, kPort, PRIVACY_MODE_DISABLED), + &crypto_config_)); + session_->Initialize(); + } + void CompleteCryptoHandshake() { session_->CryptoConnect(); QuicCryptoClientStream* stream = @@ -80,6 +87,45 @@ CompleteCryptoHandshake(); } +TEST_P(ToolsQuicClientSessionTest, NoEncryptionAfterInitialEncryption) { + ValueRestore<bool> old_flag(&FLAGS_quic_block_unencrypted_writes, true); + // Complete a handshake in order to prime the crypto config for 0-RTT. + CompleteCryptoHandshake(); + + // Now create a second session using the same crypto config. + Initialize(); + + // Starting the handshake should move immediately to encryption + // established and will allow streams to be created. + session_->CryptoConnect(); + EXPECT_TRUE(session_->IsEncryptionEstablished()); + QuicSpdyClientStream* stream = session_->CreateOutgoingDynamicStream(); + DCHECK_NE(kCryptoStreamId, stream->id()); + EXPECT_TRUE(stream != nullptr); + + // Process an "inchoate" REJ from the server which will cause + // an inchoate CHLO to be sent and will leave the encryption level + // at NONE. + CryptoHandshakeMessage rej; + CryptoTestUtils::FillInDummyReject(&rej, /* stateless */ false); + EXPECT_TRUE(session_->IsEncryptionEstablished()); + session_->GetCryptoStream()->OnHandshakeMessage(rej); + EXPECT_FALSE(session_->IsEncryptionEstablished()); + EXPECT_EQ(ENCRYPTION_NONE, + QuicPacketCreatorPeer::GetEncryptionLevel( + QuicConnectionPeer::GetPacketCreator(connection_))); + // Verify that no new streams may be created. + EXPECT_TRUE(session_->CreateOutgoingDynamicStream() == nullptr); + // Verify that no data may be send on existing streams. + char data[] = "hello world"; + struct iovec iov = {data, arraysize(data)}; + QuicIOVector iovector(&iov, 1, iov.iov_len); + QuicConsumedData consumed = session_->WritevData( + stream->id(), iovector, 0, false, MAY_FEC_PROTECT, nullptr); + EXPECT_FALSE(consumed.fin_consumed); + EXPECT_EQ(0u, consumed.bytes_consumed); +} + TEST_P(ToolsQuicClientSessionTest, MaxNumStreamsWithNoFinOrRst) { EXPECT_CALL(*connection_, SendRstStream(_, _, _)).Times(AnyNumber());
diff --git a/net/tools/testserver/testserver.py b/net/tools/testserver/testserver.py index 10ade37..1531765 100755 --- a/net/tools/testserver/testserver.py +++ b/net/tools/testserver/testserver.py
@@ -343,7 +343,6 @@ self.GetClientCert, self.ClientCipherListHandler, self.CloseSocketHandler, - self.RangeResetHandler, self.DefaultResponseHandler] post_handlers = [ self.EchoTitleHandler, @@ -1560,153 +1559,6 @@ self.wfile.close() return True - def RangeResetHandler(self): - """Send data broken up by connection resets every N (default 4K) bytes. - Support range requests. If the data requested doesn't straddle a reset - boundary, it will all be sent. Used for testing resuming downloads.""" - - def DataForRange(start, end): - """Data to be provided for a particular range of bytes.""" - # Offset and scale to avoid too obvious (and hence potentially - # collidable) data. - return ''.join([chr(y % 256) - for y in range(start * 2 + 15, end * 2 + 15, 2)]) - - if not self._ShouldHandleRequest('/rangereset'): - return False - - # HTTP/1.1 is required for ETag and range support. - self.protocol_version = 'HTTP/1.1' - _, _, url_path, _, query, _ = urlparse.urlparse(self.path) - - # Defaults - size = 8000 - # Note that the rst is sent just before sending the rst_boundary byte. - rst_boundary = 4000 - respond_to_range = True - hold_for_signal = False - rst_limit = -1 - token = 'DEFAULT' - fail_precondition = 0 - send_verifiers = True - - # Parse the query - qdict = urlparse.parse_qs(query, True) - if 'size' in qdict: - size = int(qdict['size'][0]) - if 'rst_boundary' in qdict: - rst_boundary = int(qdict['rst_boundary'][0]) - if 'token' in qdict: - # Identifying token for stateful tests. - token = qdict['token'][0] - if 'rst_limit' in qdict: - # Max number of rsts for a given token. - rst_limit = int(qdict['rst_limit'][0]) - if 'bounce_range' in qdict: - respond_to_range = False - if 'hold' in qdict: - # Note that hold_for_signal will not work with null range requests; - # see TODO below. - hold_for_signal = True - if 'no_verifiers' in qdict: - send_verifiers = False - if 'fail_precondition' in qdict: - fail_precondition = int(qdict['fail_precondition'][0]) - - # Record already set information, or set it. - rst_limit = TestPageHandler.rst_limits.setdefault(token, rst_limit) - if rst_limit != 0: - TestPageHandler.rst_limits[token] -= 1 - fail_precondition = TestPageHandler.fail_precondition.setdefault( - token, fail_precondition) - if fail_precondition != 0: - TestPageHandler.fail_precondition[token] -= 1 - - first_byte = 0 - last_byte = size - 1 - - # Does that define what we want to return, or do we need to apply - # a range? - range_response = False - range_header = self.headers.getheader('range') - - if fail_precondition and self.headers.getheader('If-Range'): - # Failing a precondition for an If-Range just means that we are going to - # return the entire entity ignoring the Range header. - respond_to_range = False - - if range_header and respond_to_range: - mo = re.match("bytes=(\d*)-(\d*)", range_header) - if mo.group(1): - first_byte = int(mo.group(1)) - if mo.group(2): - last_byte = int(mo.group(2)) - if last_byte > size - 1: - last_byte = size - 1 - range_response = True - if last_byte < first_byte: - return False - - if range_response: - self.send_response(206) - self.send_header('Content-Range', - 'bytes %d-%d/%d' % (first_byte, last_byte, size)) - else: - self.send_response(200) - self.send_header('Content-Type', 'application/octet-stream') - self.send_header('Content-Length', last_byte - first_byte + 1) - if send_verifiers: - # If fail_precondition is non-zero, then the ETag for each request will be - # different. - etag = "%s%d" % (token, fail_precondition) - self.send_header('ETag', etag) - self.send_header('Last-Modified', 'Tue, 19 Feb 2013 14:32 EST') - self.end_headers() - - if hold_for_signal: - # TODO(rdsmith/phajdan.jr): http://crbug.com/169519: Without writing - # a single byte, the self.server.handle_request() below hangs - # without processing new incoming requests. - self.wfile.write(DataForRange(first_byte, first_byte + 1)) - first_byte = first_byte + 1 - # handle requests until one of them clears this flag. - self.server.wait_for_download = True - while self.server.wait_for_download: - self.server.handle_request() - - possible_rst = ((first_byte / rst_boundary) + 1) * rst_boundary - if possible_rst >= last_byte or rst_limit == 0: - # No RST has been requested in this range, so we don't need to - # do anything fancy; just write the data and let the python - # infrastructure close the connection. - self.wfile.write(DataForRange(first_byte, last_byte + 1)) - self.wfile.flush() - return True - - # We're resetting the connection part way in; go to the RST - # boundary and then send an RST. - # Because socket semantics do not guarantee that all the data will be - # sent when using the linger semantics to hard close a socket, - # we send the data and then wait for our peer to release us - # before sending the reset. - data = DataForRange(first_byte, possible_rst) - self.wfile.write(data) - self.wfile.flush() - self.server.wait_for_download = True - while self.server.wait_for_download: - self.server.handle_request() - l_onoff = 1 # Linger is active. - l_linger = 0 # Seconds to linger for. - self.connection.setsockopt(socket.SOL_SOCKET, socket.SO_LINGER, - struct.pack('ii', l_onoff, l_linger)) - - # Close all duplicates of the underlying socket to force the RST. - self.wfile.close() - self.rfile.close() - self.connection.close() - - return True - def DefaultResponseHandler(self): """This is the catch-all response handler for requests that aren't handled by one of the special handlers above.
diff --git a/net/url_request/url_request_job.cc b/net/url_request/url_request_job.cc index 1b5c8f2a..140ab80 100644 --- a/net/url_request/url_request_job.cc +++ b/net/url_request/url_request_job.cc
@@ -436,21 +436,22 @@ bool defer_redirect = false; request_->NotifyReceivedRedirect(redirect_info, &defer_redirect); - // Ensure that the request wasn't detached or destroyed in - // NotifyReceivedRedirect - if (!request_ || !request_->has_delegate()) - return; - - // If we were not cancelled, then maybe follow the redirect. - if (request_->status().is_success()) { - if (defer_redirect) { - deferred_redirect_info_ = redirect_info; - } else { - FollowRedirect(redirect_info); - } + // Ensure that the request wasn't detached, destroyed, or canceled in + // NotifyReceivedRedirect. + if (!request_ || !request_->has_delegate() || + !request_->status().is_success()) { return; } - } else if (NeedsAuth()) { + + if (defer_redirect) { + deferred_redirect_info_ = redirect_info; + } else { + FollowRedirect(redirect_info); + } + return; + } + + if (NeedsAuth()) { scoped_refptr<AuthChallengeInfo> auth_info; GetAuthChallengeInfo(&auth_info);
diff --git a/net/url_request/url_request_test_util.cc b/net/url_request/url_request_test_util.cc index f98894a..31450c1 100644 --- a/net/url_request/url_request_test_util.cc +++ b/net/url_request/url_request_test_util.cc
@@ -276,6 +276,11 @@ // It doesn't make sense for the request to have IO pending at this point. DCHECK(!request->status().is_io_pending()); + // If the request was cancelled in a redirect, it should not signal + // OnReadCompleted. Note that |cancel_in_rs_| may be true due to + // https://crbug.com/564848. + EXPECT_FALSE(cancel_in_rr_); + if (response_started_count_ == 0) received_data_before_response_ = true;
diff --git a/ppapi/native_client/src/untrusted/pnacl_support_extension/BUILD.gn b/ppapi/native_client/src/untrusted/pnacl_support_extension/BUILD.gn index 34f826c..dfe412e 100644 --- a/ppapi/native_client/src/untrusted/pnacl_support_extension/BUILD.gn +++ b/ppapi/native_client/src/untrusted/pnacl_support_extension/BUILD.gn
@@ -31,14 +31,7 @@ deps = [ shim_target_tc_label, ] - shim_lib_path = - rebase_path(get_label_info(shim_target_tc_label, "target_out_dir") + - "/$src_shim_name", - root_build_dir) - shim_override_args = [ - "--lib_override", - "$target_cpu,$shim_lib_path,$desired_shim_name", - ] + shim_cpu = target_cpu output_prefix = "$root_out_dir/pnacl/pnacl_public_" outputs = [ @@ -55,51 +48,43 @@ "libpnacl_irt_shim_a", "pnacl_llc_nexe", ] - if (target_cpu == "arm") { - foreach(output_elem, outputs_from_toolchain) { - outputs += [ output_prefix + "arm_" + output_elem ] - } - } else if (target_cpu == "mipsel") { - foreach(output_elem, outputs_from_toolchain) { - outputs += [ output_prefix + "mips32_" + output_elem ] - } - } else if (target_cpu == "x86") { - foreach(output_elem, outputs_from_toolchain) { - outputs += [ output_prefix + "x86_32_" + output_elem ] - } + if (target_cpu == "arm") { + output_cpu = "arm" + } else if (target_cpu == "mipsel") { + output_cpu = "mips32" + } else if (target_cpu == "x64") { + output_cpu = "x86_64" + } else if (target_cpu == "x86") { + output_cpu = "x86_32" + } else { + assert(false, "unhandled target_cpu") + } + + foreach(output_elem, outputs_from_toolchain) { + outputs += [ output_prefix + output_cpu + "_" + output_elem ] + } + + if (is_win && target_cpu == "x86") { # On Windows, for offline testing (i.e., without component updater # selecting the platform-specific files with multi-CRXes), we need # to stage both x86-32 and x86-64 (because 32-bit chrome on 64-bit # windows will need 64-bit nexes). - if (is_win) { - foreach(output_elem, outputs_from_toolchain) { - outputs += [ output_prefix + "x86_64_" + output_elem ] - } - shim_target_tc_x64_label = - "$shim_target_label(${shim_toolchain_base}x64)" - deps += [ shim_target_tc_x64_label ] - shim_lib_x64_path = - rebase_path(get_label_info(shim_target_tc_x64_label, - "target_out_dir") + "/$src_shim_name", - root_build_dir) - shim_override_args = [ - "--lib_override", - "x64,$shim_lib_x64_path,$desired_shim_name", - ] - } - } else if (target_cpu == "x64") { + + shim_target_tc_label = "$shim_target_label(${shim_toolchain_base}x64)" + deps += [ shim_target_tc_label ] + + shim_cpu = "x64" + foreach(output_elem, outputs_from_toolchain) { outputs += [ output_prefix + "x86_64_" + output_elem ] } - } else { - assert(false, "unhandled target_cpu") } - args = [ - "--dest", - rebase_path("$root_out_dir/pnacl", root_build_dir), - ] - args += shim_override_args + + shim_lib_path = + rebase_path(get_label_info(shim_target_tc_label, "target_out_dir") + + "/$src_shim_name", + root_build_dir) if (current_os == "chromeos") { toolchain_os = "linux" @@ -107,19 +92,29 @@ toolchain_os = current_os } - args += [ + args = [ + "--dest", + rebase_path("$root_out_dir/pnacl", root_build_dir), + + "--lib_override", + "$shim_cpu,$shim_lib_path,$desired_shim_name", + "--target_arch", target_cpu, + "--info_template_path", rebase_path("//native_client/pnacl/driver/pnacl_info_template.json", root_build_dir), + "--pnacl_translator_path", rebase_path( "//native_client/toolchain/${toolchain_os}_x86/pnacl_translator", root_build_dir), + "--package_version_path", rebase_path("//native_client/build/package_version/package_version.py", root_build_dir), + "--pnacl_package_name", "pnacl_translator",
diff --git a/printing/emf_win.cc b/printing/emf_win.cc index d5e1888..8ee1d84 100644 --- a/printing/emf_win.cc +++ b/printing/emf_win.cc
@@ -11,7 +11,7 @@ #include "base/win/scoped_gdi_object.h" #include "base/win/scoped_hdc.h" #include "base/win/scoped_select_object.h" -#include "skia/ext/platform_device.h" +#include "skia/ext/skia_utils_win.h" #include "third_party/skia/include/core/SkBitmap.h" #include "ui/gfx/codec/jpeg_codec.h" #include "ui/gfx/codec/png_codec.h"
diff --git a/printing/image_win.cc b/printing/image_win.cc index 1411e16..398fb22 100644 --- a/printing/image_win.cc +++ b/printing/image_win.cc
@@ -8,7 +8,7 @@ #include "base/win/scoped_hdc.h" #include "base/win/scoped_select_object.h" #include "printing/metafile.h" -#include "skia/ext/platform_device.h" +#include "skia/ext/skia_utils_win.h" #include "ui/gfx/gdi_util.h" // EMF support #include "ui/gfx/geometry/rect.h"
diff --git a/printing/printed_document_win.cc b/printing/printed_document_win.cc index ddba4ca..e980039f 100644 --- a/printing/printed_document_win.cc +++ b/printing/printed_document_win.cc
@@ -9,7 +9,7 @@ #include "printing/printed_pages_source.h" #include "printing/printed_page.h" #include "printing/units.h" -#include "skia/ext/platform_device.h" +#include "skia/ext/skia_utils_win.h" namespace {
diff --git a/printing/printing_context_system_dialog_win.cc b/printing/printing_context_system_dialog_win.cc index aaa5b68..d2e2b05 100644 --- a/printing/printing_context_system_dialog_win.cc +++ b/printing/printing_context_system_dialog_win.cc
@@ -8,7 +8,7 @@ #include "base/message_loop/message_loop.h" #include "printing/backend/win_helper.h" #include "printing/print_settings_initializer_win.h" -#include "skia/ext/platform_device.h" +#include "skia/ext/skia_utils_win.h" namespace printing {
diff --git a/printing/printing_context_win.cc b/printing/printing_context_win.cc index e46e861a..4eff7228 100644 --- a/printing/printing_context_win.cc +++ b/printing/printing_context_win.cc
@@ -16,7 +16,7 @@ #include "printing/printing_context_system_dialog_win.h" #include "printing/printing_utils.h" #include "printing/units.h" -#include "skia/ext/platform_device.h" +#include "skia/ext/skia_utils_win.h" #include "ui/aura/remote_window_tree_host_win.h" #include "ui/aura/window.h"
diff --git a/remoting/remoting_android.gypi b/remoting/remoting_android.gypi index 59c12a4..738e40e 100644 --- a/remoting/remoting_android.gypi +++ b/remoting/remoting_android.gypi
@@ -173,8 +173,6 @@ ], 'variables': { 'apk_name': 'Chromoting', - 'android_app_version_name': '<(version_full)', - 'android_app_version_code': '<!(python tools/android_version.py <(android_app_version_name))', 'android_manifest_path': '<(SHARED_INTERMEDIATE_DIR)/remoting/android/AndroidManifest.xml', 'java_in_dir': '<(remoting_apk_java_in_dir)', 'native_lib_target': 'libremoting_client_jni',
diff --git a/remoting/tools/android_version.py b/remoting/tools/android_version.py deleted file mode 100755 index da28bb1..0000000 --- a/remoting/tools/android_version.py +++ /dev/null
@@ -1,28 +0,0 @@ -#!/usr/bin/env python -# Copyright 2014 The Chromium Authors. All rights reserved. -# Use of this source code is governed by a BSD-style license that can be -# found in the LICENSE file. - -"""Converts a dotted-quad version string to a single numeric value suitable for -an Android package's internal version number.""" - -import sys - -def main(): - if len(sys.argv) != 2: - print "Usage: %s version-string" % sys.argv[0] - exit(1) - - version_string = sys.argv[1] - version_components = version_string.split('.') - if len(version_components) != 4: - print "Expected 4 components." - exit(1) - - branch = int(version_components[2]) - patch = int(version_components[3]) - print branch * 1000 + patch - - -if __name__ == '__main__': - main()
diff --git a/sandbox/win/BUILD.gn b/sandbox/win/BUILD.gn index 129f065a..22508699 100644 --- a/sandbox/win/BUILD.gn +++ b/sandbox/win/BUILD.gn
@@ -196,6 +196,7 @@ "src/handle_policy_test.cc", "src/integrity_level_test.cc", "src/ipc_ping_test.cc", + "src/lpc_policy_test.cc", "src/named_pipe_policy_test.cc", "src/policy_target_test.cc", "src/process_mitigations_test.cc",
diff --git a/sandbox/win/sandbox_win.gypi b/sandbox/win/sandbox_win.gypi index 08d512a..ae8b51c3 100644 --- a/sandbox/win/sandbox_win.gypi +++ b/sandbox/win/sandbox_win.gypi
@@ -219,6 +219,7 @@ 'src/handle_closer_test.cc', 'src/integrity_level_test.cc', 'src/ipc_ping_test.cc', + 'src/lpc_policy_test.cc', 'src/named_pipe_policy_test.cc', 'src/policy_target_test.cc', 'src/process_mitigations_test.cc',
diff --git a/sandbox/win/src/crosscall_client.h b/sandbox/win/src/crosscall_client.h index 5b1bce7..777bab74 100644 --- a/sandbox/win/src/crosscall_client.h +++ b/sandbox/win/src/crosscall_client.h
@@ -20,7 +20,7 @@ // // The general interface of CrossCall is: // ResultCode CrossCall(IPCProvider& ipc_provider, -// uint32 tag, +// uint32_t tag, // const Par1& p1, const Par2& p2,...pn // CrossCallReturn* answer) // @@ -40,7 +40,7 @@ // this is the assumed channel size. This can be overridden in a given // IPC implementation. -const uint32 kIPCChannelSize = 1024; +const uint32_t kIPCChannelSize = 1024; // The copy helper uses templates to deduce the appropriate copy function to // copy the input parameters in the buffer that is going to be send across the @@ -67,9 +67,7 @@ } // Returns the size of the input in bytes. - uint32 GetSize() const { - return sizeof(T); - } + uint32_t GetSize() const { return sizeof(T); } // Returns true if the current type is used as an In or InOut parameter. bool IsInOut() { @@ -78,7 +76,7 @@ // Returns this object's type. ArgType GetType() { - static_assert(sizeof(T) == sizeof(uint32), "specialization needed"); + static_assert(sizeof(T) == sizeof(uint32_t), "specialization needed"); return UINT32_TYPE; } @@ -106,9 +104,7 @@ } // Returns the size of the input in bytes. - uint32 GetSize() const { - return sizeof(t_); - } + uint32_t GetSize() const { return sizeof(t_); } // Returns true if the current type is used as an In or InOut parameter. bool IsInOut() { @@ -147,12 +143,13 @@ // Returns the size of the string in bytes. We define a NULL string to // be of zero length. - uint32 GetSize() const { + uint32_t GetSize() const { __try { - return (!t_) ? 0 : static_cast<uint32>(StringLength(t_) * sizeof(t_[0])); + return (!t_) ? 0 + : static_cast<uint32_t>(StringLength(t_) * sizeof(t_[0])); } __except(EXCEPTION_EXECUTE_HANDLER) { - return kuint32max; + return UINT32_MAX; } } @@ -194,9 +191,7 @@ return Base::Update(buffer); } - uint32 GetSize() const { - return Base::GetSize(); - } + uint32_t GetSize() const { return Base::GetSize(); } bool IsInOut() { return Base::IsInOut(); @@ -224,9 +219,7 @@ return Base::Update(buffer); } - uint32 GetSize() const { - return Base::GetSize(); - } + uint32_t GetSize() const { return Base::GetSize(); } bool IsInOut() { return Base::IsInOut(); @@ -242,7 +235,8 @@ // parameters. class InOutCountedBuffer : public CountedBuffer { public: - InOutCountedBuffer(void* buffer, uint32 size) : CountedBuffer(buffer, size) {} + InOutCountedBuffer(void* buffer, uint32_t size) + : CountedBuffer(buffer, size) {} }; // This copy helper template specialization catches the cases where the @@ -272,9 +266,7 @@ // Returns the size of the string in bytes. We define a NULL string to // be of zero length. - uint32 GetSize() const { - return t_.Size(); - } + uint32_t GetSize() const { return t_.Size(); } // Returns true if the current type is used as an In or InOut parameter. bool IsInOut() { @@ -317,7 +309,9 @@ // CrossCall template with one input parameter template <typename IPCProvider, typename Par1> -ResultCode CrossCall(IPCProvider& ipc_provider, uint32 tag, const Par1& p1, +ResultCode CrossCall(IPCProvider& ipc_provider, + uint32_t tag, + const Par1& p1, CrossCallReturn* answer) { XCALL_GEN_PARAMS_OBJ(1, call_params); XCALL_GEN_COPY_PARAM(1, call_params); @@ -334,8 +328,11 @@ // CrossCall template with two input parameters. template <typename IPCProvider, typename Par1, typename Par2> -ResultCode CrossCall(IPCProvider& ipc_provider, uint32 tag, const Par1& p1, - const Par2& p2, CrossCallReturn* answer) { +ResultCode CrossCall(IPCProvider& ipc_provider, + uint32_t tag, + const Par1& p1, + const Par2& p2, + CrossCallReturn* answer) { XCALL_GEN_PARAMS_OBJ(2, call_params); XCALL_GEN_COPY_PARAM(1, call_params); XCALL_GEN_COPY_PARAM(2, call_params); @@ -352,8 +349,12 @@ // CrossCall template with three input parameters. template <typename IPCProvider, typename Par1, typename Par2, typename Par3> -ResultCode CrossCall(IPCProvider& ipc_provider, uint32 tag, const Par1& p1, - const Par2& p2, const Par3& p3, CrossCallReturn* answer) { +ResultCode CrossCall(IPCProvider& ipc_provider, + uint32_t tag, + const Par1& p1, + const Par2& p2, + const Par3& p3, + CrossCallReturn* answer) { XCALL_GEN_PARAMS_OBJ(3, call_params); XCALL_GEN_COPY_PARAM(1, call_params); XCALL_GEN_COPY_PARAM(2, call_params); @@ -371,10 +372,17 @@ } // CrossCall template with four input parameters. -template <typename IPCProvider, typename Par1, typename Par2, typename Par3, +template <typename IPCProvider, + typename Par1, + typename Par2, + typename Par3, typename Par4> -ResultCode CrossCall(IPCProvider& ipc_provider, uint32 tag, const Par1& p1, - const Par2& p2, const Par3& p3, const Par4& p4, +ResultCode CrossCall(IPCProvider& ipc_provider, + uint32_t tag, + const Par1& p1, + const Par2& p2, + const Par3& p3, + const Par4& p4, CrossCallReturn* answer) { XCALL_GEN_PARAMS_OBJ(4, call_params); XCALL_GEN_COPY_PARAM(1, call_params); @@ -395,11 +403,20 @@ } // CrossCall template with five input parameters. -template <typename IPCProvider, typename Par1, typename Par2, typename Par3, - typename Par4, typename Par5> -ResultCode CrossCall(IPCProvider& ipc_provider, uint32 tag, const Par1& p1, - const Par2& p2, const Par3& p3, const Par4& p4, - const Par5& p5, CrossCallReturn* answer) { +template <typename IPCProvider, + typename Par1, + typename Par2, + typename Par3, + typename Par4, + typename Par5> +ResultCode CrossCall(IPCProvider& ipc_provider, + uint32_t tag, + const Par1& p1, + const Par2& p2, + const Par3& p3, + const Par4& p4, + const Par5& p5, + CrossCallReturn* answer) { XCALL_GEN_PARAMS_OBJ(5, call_params); XCALL_GEN_COPY_PARAM(1, call_params); XCALL_GEN_COPY_PARAM(2, call_params); @@ -421,11 +438,22 @@ } // CrossCall template with six input parameters. -template <typename IPCProvider, typename Par1, typename Par2, typename Par3, - typename Par4, typename Par5, typename Par6> -ResultCode CrossCall(IPCProvider& ipc_provider, uint32 tag, const Par1& p1, - const Par2& p2, const Par3& p3, const Par4& p4, - const Par5& p5, const Par6& p6, CrossCallReturn* answer) { +template <typename IPCProvider, + typename Par1, + typename Par2, + typename Par3, + typename Par4, + typename Par5, + typename Par6> +ResultCode CrossCall(IPCProvider& ipc_provider, + uint32_t tag, + const Par1& p1, + const Par2& p2, + const Par3& p3, + const Par4& p4, + const Par5& p5, + const Par6& p6, + CrossCallReturn* answer) { XCALL_GEN_PARAMS_OBJ(6, call_params); XCALL_GEN_COPY_PARAM(1, call_params); XCALL_GEN_COPY_PARAM(2, call_params); @@ -449,11 +477,23 @@ } // CrossCall template with seven input parameters. -template <typename IPCProvider, typename Par1, typename Par2, typename Par3, - typename Par4, typename Par5, typename Par6, typename Par7> -ResultCode CrossCall(IPCProvider& ipc_provider, uint32 tag, const Par1& p1, - const Par2& p2, const Par3& p3, const Par4& p4, - const Par5& p5, const Par6& p6, const Par7& p7, +template <typename IPCProvider, + typename Par1, + typename Par2, + typename Par3, + typename Par4, + typename Par5, + typename Par6, + typename Par7> +ResultCode CrossCall(IPCProvider& ipc_provider, + uint32_t tag, + const Par1& p1, + const Par2& p2, + const Par3& p3, + const Par4& p4, + const Par5& p5, + const Par6& p6, + const Par7& p7, CrossCallReturn* answer) { XCALL_GEN_PARAMS_OBJ(7, call_params); XCALL_GEN_COPY_PARAM(1, call_params);
diff --git a/sandbox/win/src/crosscall_params.h b/sandbox/win/src/crosscall_params.h index 7adb918..a601fc7 100644 --- a/sandbox/win/src/crosscall_params.h +++ b/sandbox/win/src/crosscall_params.h
@@ -7,6 +7,7 @@ #include <windows.h> #include <lmaccess.h> +#include <stdint.h> #include <memory> @@ -14,10 +15,10 @@ #include "sandbox/win/src/internal_types.h" #include "sandbox/win/src/sandbox_types.h" -// Increases |value| until there is no need for padding given an int64 +// Increases |value| until there is no need for padding given an int64_t // alignment. Returns the increased value. -inline uint32 Align(uint32 value) { - uint32 alignment = sizeof(int64); +inline uint32_t Align(uint32_t value) { + uint32_t alignment = sizeof(int64_t); return ((value + alignment - 1) / alignment) * alignment; } @@ -27,7 +28,7 @@ // parameters of an IPC call and CrossCallReturn models the output params and // the return value. // -// An IPC call is defined by its 'tag' which is a (uint32) unique identifier +// An IPC call is defined by its 'tag' which is a (uint32_t) unique identifier // that is used to route the IPC call to the proper server. Every tag implies // a complete call signature including the order and type of each parameter. // @@ -36,7 +37,7 @@ // them are not supported. // // Another limitation of CrossCall is that the return value and output -// parameters can only be uint32 integers. Returning complex structures or +// parameters can only be uint32_t integers. Returning complex structures or // strings is not supported. namespace sandbox { @@ -47,7 +48,7 @@ // Union of multiple types to be used as extended results // in the CrossCallReturn. union MultiType { - uint32 unsigned_int; + uint32_t unsigned_int; void* pointer; HANDLE handle; ULONG_PTR ulong_ptr; @@ -63,8 +64,8 @@ // Contains the information about a parameter in the ipc buffer. struct ParamInfo { ArgType type_; - uint32 offset_; - uint32 size_; + uint32_t offset_; + uint32_t size_; }; // Models the return value and the return parameters of an IPC call @@ -73,7 +74,7 @@ // might have to use other integer types. struct CrossCallReturn { // the IPC tag. It should match the original IPC tag. - uint32 tag; + uint32_t tag; // The result of the IPC operation itself. ResultCode call_outcome; // the result of the IPC call as executed in the server. The interpretation @@ -83,7 +84,7 @@ DWORD win32_result; }; // Number of extended return values. - uint32 extended_count; + uint32_t extended_count; // for calls that should return a windows handle. It is found here. HANDLE handle; // The array of extended values. @@ -104,9 +105,7 @@ class CrossCallParams { public: // Returns the tag (ipc unique id) associated with this IPC. - uint32 GetTag() const { - return tag_; - } + uint32_t GetTag() const { return tag_; } // Returns the beggining of the buffer where the IPC params can be stored. // prior to an IPC call @@ -115,9 +114,7 @@ } // Returns how many parameter this IPC call should have. - const uint32 GetParamsCount() const { - return params_count_; - } + const uint32_t GetParamsCount() const { return params_count_; } // Returns a pointer to the CrossCallReturn structure. CrossCallReturn* GetCallReturn() { @@ -139,14 +136,14 @@ protected: // constructs the IPC call params. Called only from the derived classes - CrossCallParams(uint32 tag, uint32 params_count) + CrossCallParams(uint32_t tag, uint32_t params_count) : tag_(tag), is_in_out_(0), params_count_(params_count) {} private: - uint32 tag_; - uint32 is_in_out_; + uint32_t tag_; + uint32_t is_in_out_; CrossCallReturn call_return; - const uint32 params_count_; + const uint32_t params_count_; DISALLOW_COPY_AND_ASSIGN(CrossCallParams); }; @@ -192,37 +189,40 @@ class ActualCallParams : public CrossCallParams { public: // constructor. Pass the ipc unique tag as input - explicit ActualCallParams(uint32 tag) + explicit ActualCallParams(uint32_t tag) : CrossCallParams(tag, NUMBER_PARAMS) { param_info_[0].offset_ = - static_cast<uint32>(parameters_ - reinterpret_cast<char*>(this)); + static_cast<uint32_t>(parameters_ - reinterpret_cast<char*>(this)); } // Testing-only constructor. Allows setting the |number_params| to a // wrong value. - ActualCallParams(uint32 tag, uint32 number_params) + ActualCallParams(uint32_t tag, uint32_t number_params) : CrossCallParams(tag, number_params) { param_info_[0].offset_ = - static_cast<uint32>(parameters_ - reinterpret_cast<char*>(this)); + static_cast<uint32_t>(parameters_ - reinterpret_cast<char*>(this)); } // Testing-only method. Allows setting the apparent size to a wrong value. // returns the previous size. - uint32 OverrideSize(uint32 new_size) { - uint32 previous_size = param_info_[NUMBER_PARAMS].offset_; + uint32_t OverrideSize(uint32_t new_size) { + uint32_t previous_size = param_info_[NUMBER_PARAMS].offset_; param_info_[NUMBER_PARAMS].offset_ = new_size; return previous_size; } // Copies each paramter into the internal buffer. For each you must supply: // index: 0 for the first param, 1 for the next an so on - bool CopyParamIn(uint32 index, const void* parameter_address, uint32 size, - bool is_in_out, ArgType type) { + bool CopyParamIn(uint32_t index, + const void* parameter_address, + uint32_t size, + bool is_in_out, + ArgType type) { if (index >= NUMBER_PARAMS) { return false; } - if (kuint32max == size) { + if (UINT32_MAX == size) { // Memory error while getting the size. return false; } @@ -267,9 +267,7 @@ // Returns the total size of the buffer. Only valid once all the paramters // have been copied in with CopyParamIn. - uint32 GetSize() const { - return param_info_[NUMBER_PARAMS].offset_; - } + uint32_t GetSize() const { return param_info_[NUMBER_PARAMS].offset_; } protected: ActualCallParams() : CrossCallParams(0, NUMBER_PARAMS) { }
diff --git a/sandbox/win/src/crosscall_server.cc b/sandbox/win/src/crosscall_server.cc index 6f8bd74..f0e1183a 100644 --- a/sandbox/win/src/crosscall_server.cc +++ b/sandbox/win/src/crosscall_server.cc
@@ -26,7 +26,7 @@ // Returns the actual size for the parameters in an IPC buffer. Returns // zero if the |param_count| is zero or too big. -uint32 GetActualBufferSize(uint32 param_count, void* buffer_base) { +uint32_t GetActualBufferSize(uint32_t param_count, void* buffer_base) { // The template types are used to calculate the maximum expected size. typedef ActualCallParams<1, kMaxBufferSize> ActualCP1; typedef ActualCallParams<2, kMaxBufferSize> ActualCP2; @@ -66,8 +66,9 @@ } // Verifies that the declared sizes of an IPC buffer are within range. -bool IsSizeWithinRange(uint32 buffer_size, uint32 min_declared_size, - uint32 declared_size) { +bool IsSizeWithinRange(uint32_t buffer_size, + uint32_t min_declared_size, + uint32_t declared_size) { if ((buffer_size < min_declared_size) || (sizeof(CrossCallParamsEx) > min_declared_size)) { // Minimal computed size bigger than existing buffer or param_count @@ -104,8 +105,8 @@ // have destructors or else you get Compiler Error C2712. So no DCHECKs // inside this function. CrossCallParamsEx* CrossCallParamsEx::CreateFromBuffer(void* buffer_base, - uint32 buffer_size, - uint32* output_size) { + uint32_t buffer_size, + uint32_t* output_size) { // IMPORTANT: Everything inside buffer_base and derived from it such // as param_count and declared_size is untrusted. if (NULL == buffer_base) { @@ -119,9 +120,9 @@ } char* backing_mem = NULL; - uint32 param_count = 0; - uint32 declared_size; - uint32 min_declared_size; + uint32_t param_count = 0; + uint32_t declared_size; + uint32_t min_declared_size; CrossCallParamsEx* copied_params = NULL; // Touching the untrusted buffer is done under a SEH try block. This @@ -176,8 +177,8 @@ // Verify here that all and each parameters make sense. This is done in the // local copy. - for (uint32 ix =0; ix != param_count; ++ix) { - uint32 size = 0; + for (uint32_t ix = 0; ix != param_count; ++ix) { + uint32_t size = 0; ArgType type; char* address = reinterpret_cast<char*>( copied_params->GetRawParameter(ix, &size, &type)); @@ -198,7 +199,8 @@ } // Accessors to the parameters in the raw buffer. -void* CrossCallParamsEx::GetRawParameter(uint32 index, uint32* size, +void* CrossCallParamsEx::GetRawParameter(uint32_t index, + uint32_t* size, ArgType* type) { if (index >= GetParamsCount()) { return NULL; @@ -212,20 +214,20 @@ } // Covers common case for 32 bit integers. -bool CrossCallParamsEx::GetParameter32(uint32 index, uint32* param) { - uint32 size = 0; +bool CrossCallParamsEx::GetParameter32(uint32_t index, uint32_t* param) { + uint32_t size = 0; ArgType type; void* start = GetRawParameter(index, &size, &type); if ((NULL == start) || (4 != size) || (UINT32_TYPE != type)) { return false; } // Copy the 4 bytes. - *(reinterpret_cast<uint32*>(param)) = *(reinterpret_cast<uint32*>(start)); + *(reinterpret_cast<uint32_t*>(param)) = *(reinterpret_cast<uint32_t*>(start)); return true; } -bool CrossCallParamsEx::GetParameterVoidPtr(uint32 index, void** param) { - uint32 size = 0; +bool CrossCallParamsEx::GetParameterVoidPtr(uint32_t index, void** param) { + uint32_t size = 0; ArgType type; void* start = GetRawParameter(index, &size, &type); if ((NULL == start) || (sizeof(void*) != size) || (VOIDPTR_TYPE != type)) { @@ -237,8 +239,9 @@ // Covers the common case of reading a string. Note that the string is not // scanned for invalid characters. -bool CrossCallParamsEx::GetParameterStr(uint32 index, base::string16* string) { - uint32 size = 0; +bool CrossCallParamsEx::GetParameterStr(uint32_t index, + base::string16* string) { + uint32_t size = 0; ArgType type; void* start = GetRawParameter(index, &size, &type); if (WCHAR_TYPE != type) { @@ -258,9 +261,10 @@ return true; } -bool CrossCallParamsEx::GetParameterPtr(uint32 index, uint32 expected_size, +bool CrossCallParamsEx::GetParameterPtr(uint32_t index, + uint32_t expected_size, void** pointer) { - uint32 size = 0; + uint32_t size = 0; ArgType type; void* start = GetRawParameter(index, &size, &type);
diff --git a/sandbox/win/src/crosscall_server.h b/sandbox/win/src/crosscall_server.h index 824b63e..9779c11f 100644 --- a/sandbox/win/src/crosscall_server.h +++ b/sandbox/win/src/crosscall_server.h
@@ -7,8 +7,9 @@ #include <string> #include <vector> -#include "base/basictypes.h" + #include "base/callback.h" +#include "base/macros.h" #include "base/strings/string16.h" #include "sandbox/win/src/crosscall_params.h" @@ -94,31 +95,31 @@ // 1) validate the IPC buffer. returns NULL is the IPCbuffer is malformed. // 2) make a copy of the IPCbuffer (parameter capture) static CrossCallParamsEx* CreateFromBuffer(void* buffer_base, - uint32 buffer_size, - uint32* output_size); + uint32_t buffer_size, + uint32_t* output_size); // Provides IPCinput parameter raw access: // index : the parameter to read; 0 is the first parameter // returns NULL if the parameter is non-existent. If it exists it also // returns the size in *size - void* GetRawParameter(uint32 index, uint32* size, ArgType* type); + void* GetRawParameter(uint32_t index, uint32_t* size, ArgType* type); // Gets a parameter that is four bytes in size. // Returns false if the parameter does not exist or is not 32 bits wide. - bool GetParameter32(uint32 index, uint32* param); + bool GetParameter32(uint32_t index, uint32_t* param); // Gets a parameter that is void pointer in size. // Returns false if the parameter does not exist or is not void pointer sized. - bool GetParameterVoidPtr(uint32 index, void** param); + bool GetParameterVoidPtr(uint32_t index, void** param); // Gets a parameter that is a string. Returns false if the parameter does not // exist. - bool GetParameterStr(uint32 index, base::string16* string); + bool GetParameterStr(uint32_t index, base::string16* string); // Gets a parameter that is an in/out buffer. Returns false is the parameter // does not exist or if the size of the actual parameter is not equal to the // expected size. - bool GetParameterPtr(uint32 index, uint32 expected_size, void** pointer); + bool GetParameterPtr(uint32_t index, uint32_t expected_size, void** pointer); // Frees the memory associated with the IPC parameters. static void operator delete(void* raw_memory) throw();
diff --git a/sandbox/win/src/ipc_unittest.cc b/sandbox/win/src/ipc_unittest.cc index 0dc9571..e8b0b81 100644 --- a/sandbox/win/src/ipc_unittest.cc +++ b/sandbox/win/src/ipc_unittest.cc
@@ -2,7 +2,8 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#include "base/basictypes.h" +#include <stdint.h> + #include "sandbox/win/src/crosscall_client.h" #include "sandbox/win/src/crosscall_server.h" #include "sandbox/win/src/sharedmem_ipc_client.h" @@ -158,7 +159,7 @@ SharedMemIPCClient client(mem); CrossCallReturn answer; - uint32 tag1 = 666; + uint32_t tag1 = 666; const wchar_t *text = L"98765 - 43210"; base::string16 copied_text; CrossCallParamsEx* actual_params; @@ -171,13 +172,13 @@ EXPECT_STREQ(text, copied_text.c_str()); // Check with an empty string. - uint32 tag2 = 777; + uint32_t tag2 = 777; const wchar_t* null_text = NULL; CrossCall(client, tag2, null_text, &answer); actual_params = reinterpret_cast<CrossCallParamsEx*>(client.GetBuffer()); EXPECT_EQ(1, actual_params->GetParamsCount()); EXPECT_EQ(tag2, actual_params->GetTag()); - uint32 param_size = 1; + uint32_t param_size = 1; ArgType type = INVALID_TYPE; void* param_addr = actual_params->GetRawParameter(0, ¶m_size, &type); EXPECT_TRUE(NULL != param_addr); @@ -185,7 +186,7 @@ EXPECT_EQ(WCHAR_TYPE, type); EXPECT_TRUE(actual_params->GetParameterStr(0, &copied_text)); - uint32 tag3 = 888; + uint32_t tag3 = 888; param_size = 1; copied_text.clear(); @@ -233,8 +234,8 @@ client_control->server_alive = HANDLE(1); FixChannels(client_control, base_start, kIPCChannelSize, FIX_PONG_READY); - uint32 tag1 = 999; - uint32 tag2 = 111; + uint32_t tag1 = 999; + uint32_t tag2 = 111; const wchar_t *text = L"godzilla"; CrossCallParamsEx* actual_params; @@ -248,7 +249,7 @@ EXPECT_EQ(1, actual_params->GetParamsCount()); EXPECT_EQ(tag2, actual_params->GetTag()); ArgType type = INVALID_TYPE; - uint32 param_size = 1; + uint32_t param_size = 1; void* param_addr = actual_params->GetRawParameter(0, ¶m_size, &type); ASSERT_EQ(sizeof(dw), param_size); EXPECT_EQ(UINT32_TYPE, type); @@ -299,13 +300,13 @@ TEST(IPCTest, CrossCallValidation) { // First a sanity test with a well formed parameter object. unsigned long value = 124816; - const uint32 kTag = 33; - const uint32 kBufferSize = 256; + const uint32_t kTag = 33; + const uint32_t kBufferSize = 256; ActualCallParams<1, kBufferSize> params_1(kTag); params_1.CopyParamIn(0, &value, sizeof(value), false, UINT32_TYPE); void* buffer = const_cast<void*>(params_1.GetBuffer()); - uint32 out_size = 0; + uint32_t out_size = 0; CrossCallParamsEx* ccp = 0; ccp = CrossCallParamsEx::CreateFromBuffer(buffer, params_1.GetSize(), &out_size); @@ -318,9 +319,9 @@ // Test that we handle integer overflow on the number of params // correctly. We use a test-only ctor for ActualCallParams that // allows to create malformed cross-call buffers. - const int32 kPtrDiffSz = sizeof(ptrdiff_t); - for (int32 ix = -1; ix != 3; ++ix) { - uint32 fake_num_params = (kuint32max / kPtrDiffSz) + ix; + const int32_t kPtrDiffSz = sizeof(ptrdiff_t); + for (int32_t ix = -1; ix != 3; ++ix) { + uint32_t fake_num_params = (UINT32_MAX / kPtrDiffSz) + ix; ActualCallParams<1, kBufferSize> params_2(kTag, fake_num_params); params_2.CopyParamIn(0, &value, sizeof(value), false, UINT32_TYPE); buffer = const_cast<void*>(params_2.GetBuffer()); @@ -337,7 +338,7 @@ buffer = const_cast<void*>(params_3.GetBuffer()); EXPECT_TRUE(NULL != buffer); - uint32 correct_size = params_3.OverrideSize(1); + uint32_t correct_size = params_3.OverrideSize(1); ccp = CrossCallParamsEx::CreateFromBuffer(buffer, kBufferSize, &out_size); EXPECT_TRUE(NULL == ccp); @@ -389,9 +390,8 @@ class CrossCallParamsMock : public CrossCallParams { public: - CrossCallParamsMock(uint32 tag, uint32 params_count) - : CrossCallParams(tag, params_count) { - } + CrossCallParamsMock(uint32_t tag, uint32_t params_count) + : CrossCallParams(tag, params_count) {} }; void FakeOkAnswerInChannel(void* channel) { @@ -436,7 +436,7 @@ EXPECT_EQ(0, client_control->channels[1].ipc_tag); - uint32 tag = 7654; + uint32_t tag = 7654; CrossCallReturn answer; CrossCallParamsMock* params1 = new(buff1) CrossCallParamsMock(tag, 1); FakeOkAnswerInChannel(buff1); @@ -535,7 +535,7 @@ ::Sleep(1); void* buff0 = client.GetBuffer(); - uint32 tag = 4321; + uint32_t tag = 4321; CrossCallReturn answer; CrossCallParamsMock* params1 = new(buff0) CrossCallParamsMock(tag, 1); FakeOkAnswerInChannel(buff0); @@ -570,15 +570,13 @@ } private: - bool CallOneHandler(IPCInfo* ipc, HANDLE p1, uint32 p2) { + bool CallOneHandler(IPCInfo* ipc, HANDLE p1, uint32_t p2) { ipc->return_info.extended[0].handle = p1; ipc->return_info.extended[1].unsigned_int = p2; return true; } - bool CallTwoHandler(IPCInfo* ipc, HANDLE p1, uint32 p2) { - return true; - } + bool CallTwoHandler(IPCInfo* ipc, HANDLE p1, uint32_t p2) { return true; } }; UnitTestIPCDispatcher::UnitTestIPCDispatcher() {
diff --git a/sandbox/win/src/lpc_policy_test.cc b/sandbox/win/src/lpc_policy_test.cc new file mode 100644 index 0000000..ac7b39f3 --- /dev/null +++ b/sandbox/win/src/lpc_policy_test.cc
@@ -0,0 +1,156 @@ +// 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. + +// These tests have been added to specifically tests issues arising from (A)LPC +// lock down. + +#include <algorithm> +#include <cctype> + +#include <windows.h> +#include <winioctl.h> + +#include "base/win/windows_version.h" +#include "sandbox/win/src/sandbox.h" +#include "sandbox/win/src/sandbox_factory.h" +#include "sandbox/win/src/sandbox_policy.h" +#include "sandbox/win/tests/common/controller.h" +#include "sandbox/win/tests/common/test_utils.h" +#include "testing/gtest/include/gtest/gtest.h" + +namespace sandbox { + +// Converts LCID to std::wstring for passing to sbox tests. +std::wstring LcidToWString(LCID lcid) { + wchar_t buff[10] = {0}; + int res = swprintf_s(buff, sizeof(buff) / sizeof(buff[0]), L"%08x", lcid); + if (-1 != res) { + return std::wstring(buff); + } + return std::wstring(); +} + +// Converts LANGID to std::wstring for passing to sbox tests. +std::wstring LangidToWString(LANGID langid) { + wchar_t buff[10] = {0}; + int res = swprintf_s(buff, sizeof(buff) / sizeof(buff[0]), L"%04x", langid); + if (-1 != res) { + return std::wstring(buff); + } + return std::wstring(); +} + +SBOX_TESTS_COMMAND int Lpc_GetUserDefaultLangID(int argc, wchar_t** argv) { + if (argc != 1) + return SBOX_TEST_FAILED_TO_EXECUTE_COMMAND; + std::wstring expected_langid_string(argv[0]); + + // This will cause an exception if not warmed up suitably. + LANGID langid = ::GetUserDefaultLangID(); + + std::wstring langid_string = LangidToWString(langid); + if (0 == wcsncmp(langid_string.c_str(), expected_langid_string.c_str(), 4)) { + return SBOX_TEST_SUCCEEDED; + } + return SBOX_TEST_FAILED; +} + +TEST(LpcPolicyTest, GetUserDefaultLangID) { + LANGID langid = ::GetUserDefaultLangID(); + std::wstring cmd = L"Lpc_GetUserDefaultLangID " + LangidToWString(langid); + TestRunner runner; + EXPECT_EQ(SBOX_TEST_SUCCEEDED, runner.RunTest(cmd.c_str())); +} + +SBOX_TESTS_COMMAND int Lpc_GetUserDefaultLCID(int argc, wchar_t** argv) { + if (argc != 1) + return SBOX_TEST_FAILED_TO_EXECUTE_COMMAND; + std::wstring expected_lcid_string(argv[0]); + + // This will cause an exception if not warmed up suitably. + LCID lcid = ::GetUserDefaultLCID(); + + std::wstring lcid_string = LcidToWString(lcid); + if (0 == wcsncmp(lcid_string.c_str(), expected_lcid_string.c_str(), 8)) { + return SBOX_TEST_SUCCEEDED; + } + return SBOX_TEST_FAILED; +} + +TEST(LpcPolicyTest, GetUserDefaultLCID) { + LCID lcid = ::GetUserDefaultLCID(); + std::wstring cmd = L"Lpc_GetUserDefaultLCID " + LcidToWString(lcid); + TestRunner runner; + EXPECT_EQ(SBOX_TEST_SUCCEEDED, runner.RunTest(cmd.c_str())); +} + +// GetUserDefaultLocaleName is not available on WIN XP. So we'll +// load it on-the-fly. +const wchar_t kKernel32DllName[] = L"kernel32.dll"; +typedef int(WINAPI* GetUserDefaultLocaleNameFunction)(LPWSTR lpLocaleName, + int cchLocaleName); + +SBOX_TESTS_COMMAND int Lpc_GetUserDefaultLocaleName(int argc, wchar_t** argv) { + if (argc != 1) + return SBOX_TEST_FAILED_TO_EXECUTE_COMMAND; + std::wstring expected_locale_name(argv[0]); + static GetUserDefaultLocaleNameFunction GetUserDefaultLocaleName_func = NULL; + if (!GetUserDefaultLocaleName_func) { + // GetUserDefaultLocaleName is not available on WIN XP. So we'll + // load it on-the-fly. + HMODULE kernel32_dll = ::GetModuleHandle(kKernel32DllName); + if (!kernel32_dll) { + return SBOX_TEST_FAILED; + } + GetUserDefaultLocaleName_func = + reinterpret_cast<GetUserDefaultLocaleNameFunction>( + GetProcAddress(kernel32_dll, "GetUserDefaultLocaleName")); + if (!GetUserDefaultLocaleName_func) { + return SBOX_TEST_FAILED; + } + } + wchar_t locale_name[LOCALE_NAME_MAX_LENGTH] = {0}; + // This will cause an exception if not warmed up suitably. + int ret = GetUserDefaultLocaleName_func( + locale_name, LOCALE_NAME_MAX_LENGTH * sizeof(wchar_t)); + if (!ret) { + return SBOX_TEST_FAILED; + } + if (!wcsnlen(locale_name, LOCALE_NAME_MAX_LENGTH)) { + return SBOX_TEST_FAILED; + } + if (0 == wcsncmp(locale_name, expected_locale_name.c_str(), + LOCALE_NAME_MAX_LENGTH)) { + return SBOX_TEST_SUCCEEDED; + } + return SBOX_TEST_FAILED; +} + +TEST(LpcPolicyTest, GetUserDefaultLocaleName) { + // GetUserDefaultLocaleName is not available before Vista. + if (base::win::GetVersion() < base::win::VERSION_VISTA) { + return; + } + static GetUserDefaultLocaleNameFunction GetUserDefaultLocaleName_func = NULL; + if (!GetUserDefaultLocaleName_func) { + // GetUserDefaultLocaleName is not available on WIN XP. So we'll + // load it on-the-fly. + HMODULE kernel32_dll = ::GetModuleHandle(kKernel32DllName); + EXPECT_NE(NULL, int(kernel32_dll)); + GetUserDefaultLocaleName_func = + reinterpret_cast<GetUserDefaultLocaleNameFunction>( + GetProcAddress(kernel32_dll, "GetUserDefaultLocaleName")); + EXPECT_NE(NULL, int(GetUserDefaultLocaleName_func)); + } + wchar_t locale_name[LOCALE_NAME_MAX_LENGTH] = {0}; + EXPECT_NE(0, GetUserDefaultLocaleName_func( + locale_name, LOCALE_NAME_MAX_LENGTH * sizeof(wchar_t))); + EXPECT_NE(0U, wcsnlen(locale_name, LOCALE_NAME_MAX_LENGTH)); + std::wstring cmd = + L"Lpc_GetUserDefaultLocaleName " + std::wstring(locale_name); + TestRunner runner; + EXPECT_EQ(SBOX_TEST_SUCCEEDED, runner.RunTest(cmd.c_str())); +} + +} // namespace sandbox
diff --git a/sandbox/win/src/sandbox_policy.h b/sandbox/win/src/sandbox_policy.h index c1af857..0c3e847 100644 --- a/sandbox/win/src/sandbox_policy.h +++ b/sandbox/win/src/sandbox_policy.h
@@ -80,7 +80,7 @@ // not compatible with AppContainer, see SetAppContainer. // lockdown: the security level for the token that comes into force after the // process calls TargetServices::LowerToken() or the process calls - // ReverToSelf(). See the explanation of each level in the TokenLevel + // RevertToSelf(). See the explanation of each level in the TokenLevel // definition. // Return value: SBOX_ALL_OK if the setting succeeds and false otherwise. // Returns false if the lockdown value is more permissive than the initial
diff --git a/sandbox/win/src/sandbox_types.h b/sandbox/win/src/sandbox_types.h index 3e531be4..b749b9c 100644 --- a/sandbox/win/src/sandbox_types.h +++ b/sandbox/win/src/sandbox_types.h
@@ -54,13 +54,14 @@ // If the sandbox cannot create a secure environment for the target, the // target will be forcibly terminated. These are the process exit codes. enum TerminationCodes { - SBOX_FATAL_INTEGRITY = 7006, // Could not set the integrity level. - SBOX_FATAL_DROPTOKEN = 7007, // Could not lower the token. - SBOX_FATAL_FLUSHANDLES = 7008, // Failed to flush registry handles. - SBOX_FATAL_CACHEDISABLE = 7009, // Failed to forbid HCKU caching. - SBOX_FATAL_CLOSEHANDLES = 7010, // Failed to close pending handles. - SBOX_FATAL_MITIGATION = 7011, // Could not set the mitigation policy. - SBOX_FATAL_MEMORY_EXCEEDED = 7012, // Exceeded the job memory limit. + SBOX_FATAL_INTEGRITY = 7006, // Could not set the integrity level. + SBOX_FATAL_DROPTOKEN = 7007, // Could not lower the token. + SBOX_FATAL_FLUSHANDLES = 7008, // Failed to flush registry handles. + SBOX_FATAL_CACHEDISABLE = 7009, // Failed to forbid HCKU caching. + SBOX_FATAL_CLOSEHANDLES = 7010, // Failed to close pending handles. + SBOX_FATAL_MITIGATION = 7011, // Could not set the mitigation policy. + SBOX_FATAL_MEMORY_EXCEEDED = 7012, // Exceeded the job memory limit. + SBOX_FATAL_WARMUP = 7013, // Failed to warmup. SBOX_FATAL_LAST };
diff --git a/sandbox/win/src/target_services.cc b/sandbox/win/src/target_services.cc index 116f0c92..e10f7ca 100644 --- a/sandbox/win/src/target_services.cc +++ b/sandbox/win/src/target_services.cc
@@ -59,6 +59,44 @@ return true; } +// GetUserDefaultLocaleName is not available on WIN XP. So we'll +// load it on-the-fly. +const wchar_t kKernel32DllName[] = L"kernel32.dll"; +typedef decltype(GetUserDefaultLocaleName)* GetUserDefaultLocaleNameFunction; + +// Warm up language subsystems before the sandbox is turned on. +// Tested on Win8.1 x64: +// This needs to happen after RevertToSelf() is called, because (at least) in +// the case of GetUserDefaultLCID() it checks the TEB to see if the process is +// impersonating (TEB!IsImpersonating). If it is, the cached locale information +// is not used, nor is it set. Therefore, calls after RevertToSelf() will not +// have warmed-up values to use. +bool WarmupWindowsLocales() { + // NOTE(liamjm): When last checked (Win 8.1 x64) it wasn't necessary to + // warmup all of these functions, but let's not assume that. + ::GetUserDefaultLangID(); + ::GetUserDefaultLCID(); + if (base::win::GetVersion() >= base::win::VERSION_VISTA) { + static GetUserDefaultLocaleNameFunction GetUserDefaultLocaleName_func = + NULL; + if (!GetUserDefaultLocaleName_func) { + HMODULE kernel32_dll = ::GetModuleHandle(kKernel32DllName); + if (!kernel32_dll) { + return false; + } + GetUserDefaultLocaleName_func = + reinterpret_cast<GetUserDefaultLocaleNameFunction>( + GetProcAddress(kernel32_dll, "GetUserDefaultLocaleName")); + if (!GetUserDefaultLocaleName_func) { + return false; + } + } + wchar_t localeName[LOCALE_NAME_MAX_LENGTH] = {0}; + return (0 != GetUserDefaultLocaleName_func( + localeName, LOCALE_NAME_MAX_LENGTH * sizeof(wchar_t))); + } + return true; +} // Used as storage for g_target_services, because other allocation facilities // are not available early. We can't use a regular function static because on @@ -97,6 +135,8 @@ ::TerminateProcess(::GetCurrentProcess(), SBOX_FATAL_FLUSHANDLES); if (ERROR_SUCCESS != ::RegDisablePredefinedCache()) ::TerminateProcess(::GetCurrentProcess(), SBOX_FATAL_CACHEDISABLE); + if (!WarmupWindowsLocales()) + ::TerminateProcess(::GetCurrentProcess(), SBOX_FATAL_WARMUP); bool is_csrss_connected = true; if (!CloseOpenHandles(&is_csrss_connected)) ::TerminateProcess(::GetCurrentProcess(), SBOX_FATAL_CLOSEHANDLES);
diff --git a/skia/ext/bitmap_platform_device_win.cc b/skia/ext/bitmap_platform_device_win.cc index 9cd3d70..f600b96d 100644 --- a/skia/ext/bitmap_platform_device_win.cc +++ b/skia/ext/bitmap_platform_device_win.cc
@@ -10,6 +10,7 @@ #include "base/win/win_util.h" #include "skia/ext/bitmap_platform_device_win.h" #include "skia/ext/platform_canvas.h" +#include "skia/ext/skia_utils_win.h" #include "third_party/skia/include/core/SkMatrix.h" #include "third_party/skia/include/core/SkRefCnt.h" #include "third_party/skia/include/core/SkRegion.h"
diff --git a/skia/ext/platform_device.h b/skia/ext/platform_device.h index 5b718d2..628732b 100644 --- a/skia/ext/platform_device.h +++ b/skia/ext/platform_device.h
@@ -38,12 +38,6 @@ PlatformDevice* platform_device); SK_API PlatformDevice* GetPlatformDevice(SkBaseDevice* device); - -#if defined(OS_WIN) -// Initializes the default settings and colors in a device context. -SK_API void InitializeDC(HDC context); -#endif - // A SkBitmapDevice is basically a wrapper around SkBitmap that provides a // surface for SkCanvas to draw into. PlatformDevice provides a surface // Windows can also write to. It also provides functionality to play well
diff --git a/skia/ext/platform_device_win.cc b/skia/ext/platform_device_win.cc index 79b2c30b..d1b37ef 100644 --- a/skia/ext/platform_device_win.cc +++ b/skia/ext/platform_device_win.cc
@@ -11,45 +11,6 @@ namespace skia { -void InitializeDC(HDC context) { - // Enables world transformation. - // If the GM_ADVANCED graphics mode is set, GDI always draws arcs in the - // counterclockwise direction in logical space. This is equivalent to the - // statement that, in the GM_ADVANCED graphics mode, both arc control points - // and arcs themselves fully respect the device context's world-to-device - // transformation. - BOOL res = SetGraphicsMode(context, GM_ADVANCED); - SkASSERT(res != 0); - - // Enables dithering. - res = SetStretchBltMode(context, HALFTONE); - SkASSERT(res != 0); - // As per SetStretchBltMode() documentation, SetBrushOrgEx() must be called - // right after. - res = SetBrushOrgEx(context, 0, 0, NULL); - SkASSERT(res != 0); - - // Sets up default orientation. - res = SetArcDirection(context, AD_CLOCKWISE); - SkASSERT(res != 0); - - // Sets up default colors. - res = SetBkColor(context, RGB(255, 255, 255)); - SkASSERT(res != CLR_INVALID); - res = SetTextColor(context, RGB(0, 0, 0)); - SkASSERT(res != CLR_INVALID); - res = SetDCBrushColor(context, RGB(255, 255, 255)); - SkASSERT(res != CLR_INVALID); - res = SetDCPenColor(context, RGB(0, 0, 0)); - SkASSERT(res != CLR_INVALID); - - // Sets up default transparency. - res = SetBkMode(context, OPAQUE); - SkASSERT(res != 0); - res = SetROP2(context, R2_COPYPEN); - SkASSERT(res != 0); -} - PlatformSurface PlatformDevice::BeginPlatformPaint() { return 0; }
diff --git a/skia/ext/refptr.h b/skia/ext/refptr.h index a7ba7ffb..93f12204 100644 --- a/skia/ext/refptr.h +++ b/skia/ext/refptr.h
@@ -6,8 +6,8 @@ #define SKIA_EXT_REFPTR_H_ #include <algorithm> +#include <cstddef> -#include "base/move.h" #include "third_party/skia/include/core/SkRefCnt.h" namespace skia { @@ -52,23 +52,29 @@ // for you. template<typename T> class RefPtr { - TYPE_WITH_MOVE_CONSTRUCTOR_FOR_CPP_03(RefPtr) public: RefPtr() : ptr_(nullptr) {} - RefPtr(decltype(nullptr)) : ptr_(nullptr) {} + RefPtr(std::nullptr_t) : ptr_(nullptr) {} + // Copy constructor. RefPtr(const RefPtr& other) : ptr_(other.get()) { SkSafeRef(ptr_); } + // Copy conversion constructor. template<typename U> RefPtr(const RefPtr<U>& other) : ptr_(other.get()) { SkSafeRef(ptr_); } + // Move constructor. This is required in addition to the conversion + // constructor below in order for clang to warn about pessimizing moves. + RefPtr(RefPtr&& other) : ptr_(other.get()) { other.ptr_ = nullptr; } + + // Move conversion constructor. template <typename U> RefPtr(RefPtr<U>&& other) : ptr_(other.get()) { @@ -79,7 +85,7 @@ clear(); } - RefPtr& operator=(decltype(nullptr)) { + RefPtr& operator=(std::nullptr_t) { clear(); return *this; } @@ -97,7 +103,7 @@ template <typename U> RefPtr& operator=(RefPtr<U>&& other) { - RefPtr<T> temp(other.Pass()); + RefPtr<T> temp(std::move(other)); std::swap(ptr_, temp.ptr_); return *this; }
diff --git a/skia/ext/refptr_unittest.cc b/skia/ext/refptr_unittest.cc index a356a64..237f439 100644 --- a/skia/ext/refptr_unittest.cc +++ b/skia/ext/refptr_unittest.cc
@@ -180,11 +180,11 @@ TEST(RefPtrTest, PassIntoArguments) { // No ref count changes when passing an argument with Pass(). RefPtr<RefCountCounter> object = skia::AdoptRef(new RefCountCounter); - RefPtr<RefCountCounter> object2 = object.Pass(); + RefPtr<RefCountCounter> object2 = std::move(object); auto lambda = [](RefPtr<RefCountCounter> arg) { EXPECT_EQ(0, arg->ref_count_changes()); }; - lambda(object2.Pass()); + lambda(std::move(object2)); } class DestructionNotifier : public SkRefCnt { @@ -196,15 +196,6 @@ bool* flag_; }; -TEST(RefPtrTest, PassIntoSelf) { - bool is_destroyed = false; - RefPtr<DestructionNotifier> object = - skia::AdoptRef(new DestructionNotifier(&is_destroyed)); - object = object.Pass(); - ASSERT_FALSE(is_destroyed); - EXPECT_TRUE(object->unique()); -} - TEST(RefPtrTest, Nullptr) { RefPtr<SkRefCnt> null(nullptr); EXPECT_FALSE(null);
diff --git a/skia/ext/skia_utils_win.cc b/skia/ext/skia_utils_win.cc index 3089b24..9873373 100644 --- a/skia/ext/skia_utils_win.cc +++ b/skia/ext/skia_utils_win.cc
@@ -58,5 +58,44 @@ #endif } +void InitializeDC(HDC context) { + // Enables world transformation. + // If the GM_ADVANCED graphics mode is set, GDI always draws arcs in the + // counterclockwise direction in logical space. This is equivalent to the + // statement that, in the GM_ADVANCED graphics mode, both arc control points + // and arcs themselves fully respect the device context's world-to-device + // transformation. + BOOL res = SetGraphicsMode(context, GM_ADVANCED); + SkASSERT(res != 0); + + // Enables dithering. + res = SetStretchBltMode(context, HALFTONE); + SkASSERT(res != 0); + // As per SetStretchBltMode() documentation, SetBrushOrgEx() must be called + // right after. + res = SetBrushOrgEx(context, 0, 0, NULL); + SkASSERT(res != 0); + + // Sets up default orientation. + res = SetArcDirection(context, AD_CLOCKWISE); + SkASSERT(res != 0); + + // Sets up default colors. + res = SetBkColor(context, RGB(255, 255, 255)); + SkASSERT(res != CLR_INVALID); + res = SetTextColor(context, RGB(0, 0, 0)); + SkASSERT(res != CLR_INVALID); + res = SetDCBrushColor(context, RGB(255, 255, 255)); + SkASSERT(res != CLR_INVALID); + res = SetDCPenColor(context, RGB(0, 0, 0)); + SkASSERT(res != CLR_INVALID); + + // Sets up default transparency. + res = SetBkMode(context, OPAQUE); + SkASSERT(res != 0); + res = SetROP2(context, R2_COPYPEN); + SkASSERT(res != 0); +} + } // namespace skia
diff --git a/skia/ext/skia_utils_win.h b/skia/ext/skia_utils_win.h index 379cba12..b116efe 100644 --- a/skia/ext/skia_utils_win.h +++ b/skia/ext/skia_utils_win.h
@@ -7,6 +7,9 @@ #include "third_party/skia/include/core/SkColor.h" +#include "build/build_config.h" +#include <windows.h> + struct SkIRect; struct SkPoint; struct SkRect; @@ -43,6 +46,9 @@ // Converts ARGB to COLORREFs (0BGR). SK_API COLORREF SkColorToCOLORREF(SkColor color); +// Initializes the default settings and colors in a device context. +SK_API void InitializeDC(HDC context); + } // namespace skia #endif // SKIA_EXT_SKIA_UTILS_WIN_H_
diff --git a/styleguide/c++/c++11.html b/styleguide/c++/c++11.html index b11ff54..85ff363 100644 --- a/styleguide/c++/c++11.html +++ b/styleguide/c++/c++11.html
@@ -303,7 +303,7 @@ <td><code>v.data()</code></td> <td>Returns a pointer to a <code>std::vector</code>'s underlying data, accounting for empty vectors.</td> <td><a href="http://en.cppreference.com/w/cpp/container/vector/data">std::vector::data</a></td> -<td><a href="https://groups.google.com/a/chromium.org/forum/#!topic/cxx/16V7fmtbzok">Discussion thread</a>.</td> +<td><a href="https://groups.google.com/a/chromium.org/forum/#!topic/cxx/16V7fmtbzok">Discussion thread</a></td> </tr> <tr> @@ -319,6 +319,14 @@ </tr> <tr> +<td>Conditional Type Selection</td> +<td><code>std::enable_if</code> and <code>std::conditional</code></td> +<td>Enables compile-time conditional type selection</td> +<td><a href="http://en.cppreference.com/w/cpp/types/enable_if">std::enable_if</a> and <a href="http://en.cppreference.com/w/cpp/types/conditional">conditional</a></td> +<td>Usage should be rare. <a href='https://groups.google.com/a/chromium.org/forum/#!topic/cxx/vCxo4tZNd_M'>Discussion thread</a></td> +</tr> + +<tr> <td>Containers containing movable types</td> <td><code>vector<scoped_ptr></code></td> <td>Enables containers that contain move-only types like <code>scoped_ptr</code></td> @@ -335,23 +343,19 @@ </tr> <tr> -<td>Move Semantics</td> -<td><code>std::move()</code></td> -<td>Facilitates efficient move operations</td> -<td><a href="http://en.cppreference.com/w/cpp/utility/move"> -<code>std::move</code> reference</a></td> -<td>Note: std::move() is allowed but writing your own move constructors is still only allowed in exceptional cases for now, see 'Rvalue References (and Move Semantics)'. <a href='https://groups.google.com/a/chromium.org/forum/#!topic/cxx/x_dWFxJFdbM'>Discussion thread</a></td> +<td>Move Iterator Adaptor</td> +<td><code>std::make_move_iterator()</code></td> +<td>Wraps an iterator so that it moves objects instead of copying them.</td> +<td><a href="http://en.cppreference.com/w/cpp/iterator/make_move_iterator">std::make_move_iterator</a></td> +<td>Useful to move objects between containers that contain move-only types like <code>scoped_ptr</code>. <a href="https://groups.google.com/a/chromium.org/forum/#!topic/cxx/lccnUljOHQU">Discussion thread</a></td> </tr> <tr> -<td>Conditional Type Selection</td> -<td><code>std::enable_if</code> and <code>std::conditional</code></td> -<td>Enables compile-time conditional type selection</td> -<td><a href="http://en.cppreference.com/w/cpp/types/enable_if"> -std::enable_if</a> and -<a href="http://en.cppreference.com/w/cpp/types/conditional"> -conditional</a></td> -<td>Usage should be rare.<a href='https://groups.google.com/a/chromium.org/forum/#!topic/cxx/vCxo4tZNd_M'>Discussion thread</a></td> +<td>Move Semantics</td> +<td><code>std::move()</code></td> +<td>Facilitates efficient move operations</td> +<td><a href="http://en.cppreference.com/w/cpp/utility/move"><code>std::move</code> reference</a></td> +<td>Note: std::move() is allowed but writing your own move constructors is still only allowed in exceptional cases for now, see 'Rvalue References (and Move Semantics)'. <a href='https://groups.google.com/a/chromium.org/forum/#!topic/cxx/x_dWFxJFdbM'>Discussion thread</a></td> </tr> <tr> @@ -363,6 +367,14 @@ <td>Note that not all type traits are available on all platforms (eg std::underlying_type doesn't work in libstdc++4.6). Use judiciously. <a href='https://groups.google.com/a/chromium.org/forum/#!topic/cxx/vCxo4tZNd_M'>Discussion thread</a></td> </tr> +<tr> +<td>Types, functions, and constants from <code><cmath></code></td> +<td><code>std::round()</code>, <code>std::isnan()</code>, and others</td> +<td>Useful for math-related code</td> +<td><a href="http://en.cppreference.com/w/cpp/header/cmath"><code><cmath></code></a></td> +<td>Anything in <code><cmath></code> is allowed. <a href="https://groups.google.com/a/chromium.org/forum/#!topic/cxx/P-1bFBXMeUk">Discussion thread</a></td> +</tr> + </tbody> </table> @@ -825,14 +837,6 @@ </tr> <tr> -<td>Is Nan</td> -<td><code>std::isnan()</code></td> -<td>Determines if a floating point value is not-a-number</td> -<td><a href="http://en.cppreference.com/w/cpp/numeric/math/isnan">std::isnan</a></td> -<td></td> -</tr> - -<tr> <td>Iterator Operators</td> <td><code>std::next()</code> and <code>std::prev()</code></td> <td>Copies an iterator and increments or decrements the copy by
diff --git a/sync/BUILD.gn b/sync/BUILD.gn index edeaf34dd..2f0f730 100644 --- a/sync/BUILD.gn +++ b/sync/BUILD.gn
@@ -212,6 +212,8 @@ "internal_api/public/base_transaction.h", "internal_api/public/change_record.h", "internal_api/public/configure_reason.h", + "internal_api/public/data_batch_impl.cc", + "internal_api/public/data_batch_impl.h", "internal_api/public/data_type_association_stats.cc", "internal_api/public/data_type_association_stats.h", "internal_api/public/data_type_debug_info_listener.cc", @@ -268,8 +270,6 @@ "internal_api/public/shutdown_reason.h", "internal_api/public/simple_metadata_change_list.cc", "internal_api/public/simple_metadata_change_list.h", - "internal_api/public/specifics_only_data_batch.cc", - "internal_api/public/specifics_only_data_batch.h", "internal_api/public/sync_auth_provider.h", "internal_api/public/sync_context.h", "internal_api/public/sync_context_proxy.h", @@ -554,12 +554,14 @@ static_library("test_support_sync_internal_api") { testonly = true sources = [ + "internal_api/public/test/fake_model_type_service.h", "internal_api/public/test/fake_sync_manager.h", "internal_api/public/test/null_sync_context_proxy.h", "internal_api/public/test/sync_manager_factory_for_profile_sync_test.h", "internal_api/public/test/test_entry_factory.h", "internal_api/public/test/test_internal_components_factory.h", "internal_api/public/test/test_user_share.h", + "internal_api/test/fake_model_type_service.cc", "internal_api/test/fake_sync_manager.cc", "internal_api/test/null_sync_context_proxy.cc", "internal_api/test/sync_manager_factory_for_profile_sync_test.cc", @@ -664,6 +666,7 @@ "internal_api/public/base/ordinal_unittest.cc", "internal_api/public/base/unique_position_unittest.cc", "internal_api/public/change_record_unittest.cc", + "internal_api/public/data_batch_impl_unittest.cc", "internal_api/public/engine/model_safe_worker_unittest.cc", "internal_api/public/sessions/sync_session_snapshot_unittest.cc", "internal_api/public/util/immutable_unittest.cc",
diff --git a/sync/api/data_batch.h b/sync/api/data_batch.h index f66b5960..68d68e0 100644 --- a/sync/api/data_batch.h +++ b/sync/api/data_batch.h
@@ -5,15 +5,31 @@ #ifndef SYNC_API_DATA_BATCH_H_ #define SYNC_API_DATA_BATCH_H_ +#include <algorithm> +#include <string> +#include <utility> + +#include "base/memory/scoped_ptr.h" +#include "sync/api/entity_data.h" #include "sync/base/sync_export.h" namespace syncer_v2 { +typedef std::pair<std::string, scoped_ptr<EntityData>> KeyAndData; + // Interface used by the processor to read data requested from the service. class SYNC_EXPORT DataBatch { public: DataBatch() {} virtual ~DataBatch() {} + + // Returns if the data batch has another pair or not. + virtual bool HasNext() const = 0; + + // Returns a pair of storage key and owned entity data object. Invoking this + // method will remove the pair from the batch, and should not be called if + // HasNext() returns false. + virtual KeyAndData Next() = 0; }; } // namespace syncer_v2
diff --git a/sync/api/entity_data.cc b/sync/api/entity_data.cc index 8b10b352..0914022 100644 --- a/sync/api/entity_data.cc +++ b/sync/api/entity_data.cc
@@ -28,7 +28,7 @@ EntityDataPtr EntityData::Pass() { EntityDataPtr target; target.swap_value(this); - return target.Pass(); + return target; } void EntityDataTraits::SwapValue(EntityData* dest, EntityData* src) {
diff --git a/sync/api/model_type_service.h b/sync/api/model_type_service.h index 6ae8bd3f..f7ad9cdd 100644 --- a/sync/api/model_type_service.h +++ b/sync/api/model_type_service.h
@@ -13,12 +13,9 @@ #include "sync/api/entity_change.h" #include "sync/api/entity_data.h" #include "sync/api/model_type_change_processor.h" +#include "sync/api/sync_error.h" #include "sync/base/sync_export.h" -namespace syncer { -class SyncError; -} // namespace syncer - namespace syncer_v2 { class DataBatch;
diff --git a/sync/api/model_type_store.cc b/sync/api/model_type_store.cc index 72af0467..17afffc 100644 --- a/sync/api/model_type_store.cc +++ b/sync/api/model_type_store.cc
@@ -13,6 +13,14 @@ ModelTypeStoreImpl::CreateInMemoryStoreForTest(callback); } +// static +void ModelTypeStore::CreateStore( + const std::string& path, + scoped_refptr<base::SequencedTaskRunner> blocking_task_runner, + const InitCallback& callback) { + ModelTypeStoreImpl::CreateStore(path, blocking_task_runner, callback); +} + ModelTypeStore::~ModelTypeStore() {} ModelTypeStore::WriteBatch::WriteBatch() {}
diff --git a/sync/api/model_type_store.h b/sync/api/model_type_store.h index c37eddd..51ddca6 100644 --- a/sync/api/model_type_store.h +++ b/sync/api/model_type_store.h
@@ -12,6 +12,10 @@ #include "base/macros.h" #include "sync/base/sync_export.h" +namespace base { +class SequencedTaskRunner; +} // namespace base + namespace syncer_v2 { // ModelTypeStore is leveldb backed store for model type's data, metadata and @@ -85,6 +89,21 @@ const std::string& global_metadata)> ReadMetadataCallback; + // CreateStore takes |path| and |blocking_task_runner|. Here is how to get + // task runner in production code: + // + // base::SequencedWorkerPool* worker_pool = + // content::BrowserThread::GetBlockingPool(); + // scoped_refptr<base::SequencedTaskRunner> blocking_task_runner( + // worker_pool->GetSequencedTaskRunnerWithShutdownBehavior( + // worker_pool->GetSequenceToken(), + // base::SequencedWorkerPool::SKIP_ON_SHUTDOWN)); + // + // In test get task runner from MessageLoop::task_runner(). + static void CreateStore( + const std::string& path, + scoped_refptr<base::SequencedTaskRunner> blocking_task_runner, + const InitCallback& callback); // Creates store object backed by in-memory leveldb database. It is used in // tests. static void CreateInMemoryStoreForTest(const InitCallback& callback);
diff --git a/sync/engine/sync_scheduler_impl.cc b/sync/engine/sync_scheduler_impl.cc index f40158b..4353be0 100644 --- a/sync/engine/sync_scheduler_impl.cc +++ b/sync/engine/sync_scheduler_impl.cc
@@ -51,6 +51,7 @@ case MIGRATION_DONE: case THROTTLED: case TRANSIENT_ERROR: + case PARTIAL_FAILURE: return false; case NOT_MY_BIRTHDAY: case CLIENT_DATA_OBSOLETE: @@ -67,12 +68,13 @@ // The notification for this is handled by PostAndProcessHeaders|. // Server does no have to send any action for this. return true; - // Make the default a NOTREACHED. So if a new error is introduced we - // think about its expected functionality. - default: + // Make UNKNOWN_ERROR a NOTREACHED. All the other error should be explicitly + // handled. + case UNKNOWN_ERROR: NOTREACHED(); return false; } + return false; } bool IsActionableError(
diff --git a/sync/internal_api/model_type_store_impl.cc b/sync/internal_api/model_type_store_impl.cc index ba55ef9..fa5a6b7 100644 --- a/sync/internal_api/model_type_store_impl.cc +++ b/sync/internal_api/model_type_store_impl.cc
@@ -7,6 +7,7 @@ #include "base/bind.h" #include "base/location.h" #include "base/logging.h" +#include "base/sequenced_task_runner.h" #include "base/task_runner_util.h" #include "base/thread_task_runner_handle.h" #include "sync/internal_api/public/model_type_store_backend.h" @@ -48,7 +49,7 @@ ModelTypeStoreImpl::ModelTypeStoreImpl( scoped_ptr<ModelTypeStoreBackend> backend, - scoped_refptr<base::TaskRunner> backend_task_runner) + scoped_refptr<base::SequencedTaskRunner> backend_task_runner) : backend_(backend.Pass()), backend_task_runner_(backend_task_runner), weak_ptr_factory_(this) { @@ -63,6 +64,28 @@ } // static +void ModelTypeStoreImpl::CreateStore( + const std::string& path, + scoped_refptr<base::SequencedTaskRunner> blocking_task_runner, + const InitCallback& callback) { + DCHECK(!callback.is_null()); + + scoped_ptr<ModelTypeStoreBackend> backend(new ModelTypeStoreBackend()); + + scoped_ptr<ModelTypeStoreImpl> store( + new ModelTypeStoreImpl(backend.Pass(), blocking_task_runner)); + + auto task = + base::Bind(&ModelTypeStoreBackend::Init, + base::Unretained(store->backend_.get()), path, nullptr); + auto reply = base::Bind(&ModelTypeStoreImpl::BackendInitDone, callback, + base::Passed(&store)); + + base::PostTaskAndReplyWithResult(blocking_task_runner.get(), FROM_HERE, task, + reply); +} + +// static void ModelTypeStoreImpl::CreateInMemoryStoreForTest( const InitCallback& callback) { DCHECK(!callback.is_null()); @@ -77,7 +100,7 @@ backend->TakeEnvOwnership(env.Pass()); // In-memory store backend works on the same thread as test. - scoped_refptr<base::TaskRunner> task_runner = + scoped_refptr<base::SequencedTaskRunner> task_runner = base::ThreadTaskRunnerHandle::Get(); scoped_ptr<ModelTypeStoreImpl> store( new ModelTypeStoreImpl(backend.Pass(), task_runner));
diff --git a/sync/internal_api/public/data_batch_impl.cc b/sync/internal_api/public/data_batch_impl.cc new file mode 100644 index 0000000..2a614a8 --- /dev/null +++ b/sync/internal_api/public/data_batch_impl.cc
@@ -0,0 +1,27 @@ +// 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. + +#include "sync/internal_api/public/data_batch_impl.h" + +namespace syncer_v2 { + +DataBatchImpl::DataBatchImpl() {} + +DataBatchImpl::~DataBatchImpl() {} + +void DataBatchImpl::Put(const std::string& client_key, + scoped_ptr<EntityData> specifics) { + key_data_pairs_.push_back(KeyAndData(client_key, std::move(specifics))); +} + +bool DataBatchImpl::HasNext() const { + return key_data_pairs_.size() > read_index_; +} + +KeyAndData DataBatchImpl::Next() { + DCHECK(HasNext()); + return std::move(key_data_pairs_[read_index_++]); +} + +} // namespace syncer_v2
diff --git a/sync/internal_api/public/data_batch_impl.h b/sync/internal_api/public/data_batch_impl.h new file mode 100644 index 0000000..8b369ba --- /dev/null +++ b/sync/internal_api/public/data_batch_impl.h
@@ -0,0 +1,47 @@ +// 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. + +#ifndef SYNC_INTERNAL_API_PUBLIC_DATA_BATCH_IMPL_H_ +#define SYNC_INTERNAL_API_PUBLIC_DATA_BATCH_IMPL_H_ + +#include <string> +#include <utility> +#include <vector> + +#include "base/macros.h" +#include "base/memory/scoped_ptr.h" +#include "sync/api/data_batch.h" +#include "sync/api/entity_data.h" + +namespace syncer_v2 { + +// An implementation of DataBatch that's purpose is to transfer ownership of +// EntityData objects. As soon as this batch recieves the EntityData, it owns +// them until Next() is invoked, when it gives up ownerhsip. Because a vector +// is used internally, this impl is unaware when duplcate client_keys are used, +// and it is the caller's job to avoid this. +class SYNC_EXPORT DataBatchImpl : public DataBatch { + public: + DataBatchImpl(); + ~DataBatchImpl() override; + + // Takes ownership of the data tied to a given key used for storage. Put + // should be called at most once for any given client_key. Data will be + // readable in the same order that they are put into the batch. + void Put(const std::string& client_key, scoped_ptr<EntityData> entity_data); + + // DataBatch implementation. + bool HasNext() const override; + KeyAndData Next() override; + + private: + std::vector<KeyAndData> key_data_pairs_; + size_t read_index_ = 0; + + DISALLOW_COPY_AND_ASSIGN(DataBatchImpl); +}; + +} // namespace syncer_v2 + +#endif // SYNC_INTERNAL_API_PUBLIC_DATA_BATCH_IMPL_H_
diff --git a/sync/internal_api/public/data_batch_impl_unittest.cc b/sync/internal_api/public/data_batch_impl_unittest.cc new file mode 100644 index 0000000..11be98a --- /dev/null +++ b/sync/internal_api/public/data_batch_impl_unittest.cc
@@ -0,0 +1,90 @@ +// 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. + +#include "sync/internal_api/public/data_batch_impl.h" + +#include "testing/gtest/include/gtest/gtest.h" + +namespace syncer_v2 { + +TEST(DataBatchImplTest, PutAndNextWithReuse) { + EntityData* entity1 = new EntityData(); + EntityData* entity2 = new EntityData(); + + DataBatchImpl batch; + EXPECT_FALSE(batch.HasNext()); + + batch.Put("one", make_scoped_ptr(entity1)); + EXPECT_TRUE(batch.HasNext()); + + const KeyAndData& pair1 = batch.Next(); + EXPECT_FALSE(batch.HasNext()); + EXPECT_EQ("one", pair1.first); + EXPECT_EQ(entity1, pair1.second.get()); + + batch.Put("two", make_scoped_ptr(entity2)); + EXPECT_TRUE(batch.HasNext()); + + const KeyAndData& pair2 = batch.Next(); + EXPECT_FALSE(batch.HasNext()); + EXPECT_EQ("two", pair2.first); + EXPECT_EQ(entity2, pair2.second.get()); +} + +TEST(DataBatchImplTest, PutAndNextInterleaved) { + EntityData* entity1 = new EntityData(); + EntityData* entity2 = new EntityData(); + EntityData* entity3 = new EntityData(); + + DataBatchImpl batch; + EXPECT_FALSE(batch.HasNext()); + + batch.Put("one", make_scoped_ptr(entity1)); + EXPECT_TRUE(batch.HasNext()); + batch.Put("two", make_scoped_ptr(entity2)); + EXPECT_TRUE(batch.HasNext()); + + const KeyAndData& pair1 = batch.Next(); + EXPECT_TRUE(batch.HasNext()); + EXPECT_EQ("one", pair1.first); + EXPECT_EQ(entity1, pair1.second.get()); + + batch.Put("three", make_scoped_ptr(entity3)); + EXPECT_TRUE(batch.HasNext()); + + const KeyAndData& pair2 = batch.Next(); + EXPECT_TRUE(batch.HasNext()); + EXPECT_EQ("two", pair2.first); + EXPECT_EQ(entity2, pair2.second.get()); + + const KeyAndData& pair3 = batch.Next(); + EXPECT_FALSE(batch.HasNext()); + EXPECT_EQ("three", pair3.first); + EXPECT_EQ(entity3, pair3.second.get()); +} + +TEST(DataBatchImplTest, PutAndNextSharedKey) { + EntityData* entity1 = new EntityData(); + EntityData* entity2 = new EntityData(); + + DataBatchImpl batch; + EXPECT_FALSE(batch.HasNext()); + + batch.Put("same", make_scoped_ptr(entity1)); + EXPECT_TRUE(batch.HasNext()); + batch.Put("same", make_scoped_ptr(entity2)); + EXPECT_TRUE(batch.HasNext()); + + const KeyAndData& pair1 = batch.Next(); + EXPECT_TRUE(batch.HasNext()); + EXPECT_EQ("same", pair1.first); + EXPECT_EQ(entity1, pair1.second.get()); + + const KeyAndData& pair2 = batch.Next(); + EXPECT_FALSE(batch.HasNext()); + EXPECT_EQ("same", pair2.first); + EXPECT_EQ(entity2, pair2.second.get()); +} + +} // namespace syncer_v2
diff --git a/sync/internal_api/public/model_type_store_impl.h b/sync/internal_api/public/model_type_store_impl.h index d9d0255..227afa0 100644 --- a/sync/internal_api/public/model_type_store_impl.h +++ b/sync/internal_api/public/model_type_store_impl.h
@@ -10,7 +10,6 @@ #include "base/memory/ref_counted.h" #include "base/memory/scoped_ptr.h" #include "base/memory/weak_ptr.h" -#include "base/task_runner.h" #include "base/threading/non_thread_safe.h" #include "sync/api/model_type_store.h" @@ -29,6 +28,10 @@ public: ~ModelTypeStoreImpl() override; + static void CreateStore( + const std::string& path, + scoped_refptr<base::SequencedTaskRunner> blocking_task_runner, + const InitCallback& callback); static void CreateInMemoryStoreForTest(const InitCallback& callback); // ModelTypeStore implementation. @@ -69,8 +72,9 @@ static leveldb::WriteBatch* GetLeveldbWriteBatch(WriteBatch* write_batch); - ModelTypeStoreImpl(scoped_ptr<ModelTypeStoreBackend> backend, - scoped_refptr<base::TaskRunner> backend_task_runner); + ModelTypeStoreImpl( + scoped_ptr<ModelTypeStoreBackend> backend, + scoped_refptr<base::SequencedTaskRunner> backend_task_runner); // Callbacks for different calls to ModelTypeStoreBackend. void ReadDataDone(const ReadDataCallback& callback, @@ -95,7 +99,7 @@ // accomplish this store's dtor posts task to backend thread passing backend // ownership to task parameter. scoped_ptr<ModelTypeStoreBackend> backend_; - scoped_refptr<base::TaskRunner> backend_task_runner_; + scoped_refptr<base::SequencedTaskRunner> backend_task_runner_; base::WeakPtrFactory<ModelTypeStoreImpl> weak_ptr_factory_; };
diff --git a/sync/internal_api/public/shared_model_type_processor.h b/sync/internal_api/public/shared_model_type_processor.h index a7d8f0f..00e914a 100644 --- a/sync/internal_api/public/shared_model_type_processor.h +++ b/sync/internal_api/public/shared_model_type_processor.h
@@ -12,6 +12,7 @@ #include "base/memory/weak_ptr.h" #include "base/threading/non_thread_safe.h" #include "sync/api/model_type_change_processor.h" +#include "sync/api/model_type_service.h" #include "sync/api/sync_error.h" #include "sync/base/sync_export.h" #include "sync/internal_api/public/base/model_type.h" @@ -23,7 +24,6 @@ struct ActivationContext; class CommitQueue; class ModelTypeEntity; -class ModelTypeStore; // A sync component embedded on the synced type's thread that helps to handle // communication between sync and model type threads. @@ -32,8 +32,7 @@ public ModelTypeChangeProcessor, base::NonThreadSafe { public: - SharedModelTypeProcessor(syncer::ModelType type, - base::WeakPtr<ModelTypeStore> store); + SharedModelTypeProcessor(syncer::ModelType type, ModelTypeService* service); ~SharedModelTypeProcessor() override; typedef base::Callback<void(syncer::SyncError, scoped_ptr<ActivationContext>)> @@ -134,10 +133,10 @@ // them across restarts, and keep them in sync with our progress markers. UpdateMap pending_updates_map_; - // Store is supplied by model type implementation. SharedModelTypeProcessor - // uses store for persisting sync related data (entity state and data type - // state). - base::WeakPtr<ModelTypeStore> store_; + // ModelTypeService linked to this processor. + // The service owns this processor instance so the pointer should never + // become invalid. + ModelTypeService* const service_; // We use two different WeakPtrFactories because we want the pointers they // issue to have different lifetimes. When asked to disconnect from the sync
diff --git a/sync/internal_api/public/specifics_only_data_batch.cc b/sync/internal_api/public/specifics_only_data_batch.cc deleted file mode 100644 index 37896a7..0000000 --- a/sync/internal_api/public/specifics_only_data_batch.cc +++ /dev/null
@@ -1,15 +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. - -#include "sync/internal_api/public/specifics_only_data_batch.h" - -namespace syncer_v2 { - -void SpecificsOnlyDataBatch::Put( - const std::string& client_key, - scoped_ptr<sync_pb::EntitySpecifics> specifics) { - // TODO(skym): Implementation. -} - -} // namespace syncer_v2
diff --git a/sync/internal_api/public/specifics_only_data_batch.h b/sync/internal_api/public/specifics_only_data_batch.h deleted file mode 100644 index bb3aa19..0000000 --- a/sync/internal_api/public/specifics_only_data_batch.h +++ /dev/null
@@ -1,29 +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. - -#ifndef SYNC_INTERNAL_API_PUBLIC_SPECIFICS_ONLY_DATA_BATCH_H_ -#define SYNC_INTERNAL_API_PUBLIC_SPECIFICS_ONLY_DATA_BATCH_H_ - -#include <string> - -#include "base/memory/scoped_ptr.h" -#include "sync/api/data_batch.h" -#include "sync/protocol/sync.pb.h" - -namespace syncer_v2 { - -// An implementation of DataBatch that only takes the simplest data from the -// service. The processor may need to help populate some fields. -class SpecificsOnlyDataBatch : public DataBatch { - public: - // Takes ownership of the specifics tied to a given key used for storage. Put - // should be called at most once for any given client_key. Multiple uses of - // the same client_key is currently undefined. - void Put(const std::string& client_key, - scoped_ptr<sync_pb::EntitySpecifics> specifics); -}; - -} // namespace syncer_v2 - -#endif // SYNC_INTERNAL_API_PUBLIC_SPECIFICS_ONLY_DATA_BATCH_H_
diff --git a/sync/internal_api/public/test/fake_model_type_service.h b/sync/internal_api/public/test/fake_model_type_service.h new file mode 100644 index 0000000..b64ed5d --- /dev/null +++ b/sync/internal_api/public/test/fake_model_type_service.h
@@ -0,0 +1,43 @@ +// 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. + +#ifndef SYNC_INTERNAL_API_PUBLIC_TEST_FAKE_MODEL_TYPE_SERVICE_H_ +#define SYNC_INTERNAL_API_PUBLIC_TEST_FAKE_MODEL_TYPE_SERVICE_H_ + +#include "sync/api/data_batch.h" +#include "sync/api/metadata_batch.h" +#include "sync/api/metadata_change_list.h" +#include "sync/api/model_type_service.h" + +namespace syncer_v2 { + +// A non-functional implementation of ModelTypeService for +// testing purposes. +class FakeModelTypeService : public ModelTypeService { + public: + FakeModelTypeService(); + ~FakeModelTypeService() override; + + scoped_ptr<MetadataChangeList> CreateMetadataChangeList() override; + + syncer::SyncError MergeSyncData( + scoped_ptr<MetadataChangeList> metadata_change_list, + EntityDataList entity_data_list) override; + + syncer::SyncError ApplySyncChanges( + scoped_ptr<MetadataChangeList> metadata_change_list, + EntityChangeList entity_changes) override; + + void LoadMetadata(MetadataCallback callback) override; + + void GetData(ClientKeyList client_keys, DataCallback callback) override; + + void GetAllData(DataCallback callback) override; + + std::string GetClientTag(const EntityData& entity_data) override; +}; + +} // namespace syncer_v2 + +#endif // SYNC_INTERNAL_API_PUBLIC_TEST_FAKE_MODEL_TYPE_SERVICE_H_
diff --git a/sync/internal_api/public/util/proto_value_ptr.h b/sync/internal_api/public/util/proto_value_ptr.h index a4f4fc0..164f2db 100644 --- a/sync/internal_api/public/util/proto_value_ptr.h +++ b/sync/internal_api/public/util/proto_value_ptr.h
@@ -53,8 +53,6 @@ // value. template <typename T, typename Traits = DefaultProtoValuePtrTraits<T>> class ProtoValuePtr { - TYPE_WITH_MOVE_CONSTRUCTOR_FOR_CPP_03(ProtoValuePtr) - private: // Immutable shareable ref-counted wrapper that embeds the value. class Wrapper : public base::RefCountedThreadSafe<Wrapper> {
diff --git a/sync/internal_api/shared_model_type_processor.cc b/sync/internal_api/shared_model_type_processor.cc index db511dfa..97cf8e5 100644 --- a/sync/internal_api/shared_model_type_processor.cc +++ b/sync/internal_api/shared_model_type_processor.cc
@@ -69,15 +69,16 @@ } // namespace -SharedModelTypeProcessor::SharedModelTypeProcessor( - syncer::ModelType type, - base::WeakPtr<ModelTypeStore> store) +SharedModelTypeProcessor::SharedModelTypeProcessor(syncer::ModelType type, + ModelTypeService* service) : type_(type), is_enabled_(false), is_connected_(false), - store_(store), + service_(service), weak_ptr_factory_for_ui_(this), - weak_ptr_factory_for_sync_(this) {} + weak_ptr_factory_for_sync_(this) { + DCHECK(service); +} SharedModelTypeProcessor::~SharedModelTypeProcessor() {} @@ -272,8 +273,8 @@ ModelTypeEntity* entity = nullptr; EntityMap::const_iterator it = entities_.find(client_tag_hash); if (it == entities_.end()) { - // TODO(stanisc): crbug/561821: Get client_tag from the service. - std::string client_tag = client_tag_hash; + // Let the service define |client_tag| based on the entity data. + std::string client_tag = service_->GetClientTag(data); scoped_ptr<ModelTypeEntity> scoped_entity = ModelTypeEntity::CreateNew( client_tag, client_tag_hash, data.id, data.creation_time);
diff --git a/sync/internal_api/shared_model_type_processor_unittest.cc b/sync/internal_api/shared_model_type_processor_unittest.cc index 2cc99981..6bbed17 100644 --- a/sync/internal_api/shared_model_type_processor_unittest.cc +++ b/sync/internal_api/shared_model_type_processor_unittest.cc
@@ -11,6 +11,7 @@ #include "sync/internal_api/public/activation_context.h" #include "sync/internal_api/public/base/model_type.h" #include "sync/internal_api/public/non_blocking_sync_common.h" +#include "sync/internal_api/public/test/fake_model_type_service.h" #include "sync/protocol/sync.pb.h" #include "sync/syncable/syncable_util.h" #include "sync/test/engine/mock_commit_queue.h" @@ -41,7 +42,8 @@ // - Writes to permanent storage. (TODO) // - Callbacks into the model. (TODO) // - Requests to the sync thread. Tested with MockCommitQueue. -class SharedModelTypeProcessorTest : public ::testing::Test { +class SharedModelTypeProcessorTest : public ::testing::Test, + public FakeModelTypeService { public: SharedModelTypeProcessorTest(); ~SharedModelTypeProcessorTest() override; @@ -129,6 +131,9 @@ void StartDone(syncer::SyncError error, scoped_ptr<ActivationContext> context); + // FakeModelTypeService overrides. + std::string GetClientTag(const EntityData& entity_data) override; + // This sets ThreadTaskRunnerHandle on the current thread, which the type // processor will pick up as the sync task runner. base::MessageLoop sync_loop_; @@ -145,9 +150,7 @@ SharedModelTypeProcessorTest::SharedModelTypeProcessorTest() : mock_queue_(new MockCommitQueue()), mock_queue_ptr_(mock_queue_), - type_processor_( - new SharedModelTypeProcessor(kModelType, - base::WeakPtr<ModelTypeStore>())) {} + type_processor_(new SharedModelTypeProcessor(kModelType, this)) {} SharedModelTypeProcessorTest::~SharedModelTypeProcessorTest() {} @@ -338,6 +341,12 @@ return specifics; } +std::string SharedModelTypeProcessorTest::GetClientTag( + const EntityData& entity_data) { + // The tag is the preference name - see GenerateSpecifics. + return entity_data.specifics.preference().name(); +} + size_t SharedModelTypeProcessorTest::GetNumCommitRequestLists() { return mock_queue_->GetNumCommitRequestLists(); }
diff --git a/sync/internal_api/sync_context_proxy_impl_unittest.cc b/sync/internal_api/sync_context_proxy_impl_unittest.cc index 880bb0b..171d9b2 100644 --- a/sync/internal_api/sync_context_proxy_impl_unittest.cc +++ b/sync/internal_api/sync_context_proxy_impl_unittest.cc
@@ -11,6 +11,7 @@ #include "sync/internal_api/public/base/model_type.h" #include "sync/internal_api/public/shared_model_type_processor.h" #include "sync/internal_api/public/sync_context.h" +#include "sync/internal_api/public/test/fake_model_type_service.h" #include "sync/internal_api/sync_context_proxy_impl.h" #include "sync/sessions/model_type_registry.h" #include "sync/test/engine/mock_nudge_handler.h" @@ -19,7 +20,7 @@ namespace syncer_v2 { -class SyncContextProxyImplTest : public ::testing::Test { +class SyncContextProxyImplTest : public ::testing::Test, FakeModelTypeService { public: SyncContextProxyImplTest() : sync_task_runner_(base::ThreadTaskRunnerHandle::Get()), @@ -54,8 +55,7 @@ } scoped_ptr<SharedModelTypeProcessor> CreateModelTypeProcessor() { - return make_scoped_ptr(new SharedModelTypeProcessor( - syncer::THEMES, base::WeakPtr<ModelTypeStore>())); + return make_scoped_ptr(new SharedModelTypeProcessor(syncer::THEMES, this)); } private:
diff --git a/sync/internal_api/test/fake_model_type_service.cc b/sync/internal_api/test/fake_model_type_service.cc new file mode 100644 index 0000000..d31388f --- /dev/null +++ b/sync/internal_api/test/fake_model_type_service.cc
@@ -0,0 +1,41 @@ +// 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. + +#include "sync/internal_api/public/test/fake_model_type_service.h" + +namespace syncer_v2 { + +FakeModelTypeService::FakeModelTypeService() {} + +FakeModelTypeService::~FakeModelTypeService() {} + +scoped_ptr<MetadataChangeList> +FakeModelTypeService::CreateMetadataChangeList() { + return scoped_ptr<MetadataChangeList>(); +} + +syncer::SyncError FakeModelTypeService::MergeSyncData( + scoped_ptr<MetadataChangeList> metadata_change_list, + EntityDataList entity_data_list) { + return syncer::SyncError(); +} + +syncer::SyncError FakeModelTypeService::ApplySyncChanges( + scoped_ptr<MetadataChangeList> metadata_change_list, + EntityChangeList entity_changes) { + return syncer::SyncError(); +} + +void FakeModelTypeService::LoadMetadata(MetadataCallback callback) {} + +void FakeModelTypeService::GetData(ClientKeyList client_keys, + DataCallback callback) {} + +void FakeModelTypeService::GetAllData(DataCallback callback) {} + +std::string FakeModelTypeService::GetClientTag(const EntityData& entity_data) { + return std::string(); +} + +} // namespace syncer_v2
diff --git a/sync/protocol/sync_protocol_error.cc b/sync/protocol/sync_protocol_error.cc index 163f64f0..992f6ac 100644 --- a/sync/protocol/sync_protocol_error.cc +++ b/sync/protocol/sync_protocol_error.cc
@@ -19,7 +19,6 @@ ENUM_CASE(THROTTLED); ENUM_CASE(CLEAR_PENDING); ENUM_CASE(TRANSIENT_ERROR); - ENUM_CASE(NON_RETRIABLE_ERROR); ENUM_CASE(MIGRATION_DONE); ENUM_CASE(INVALID_CREDENTIAL); ENUM_CASE(DISABLED_BY_ADMIN);
diff --git a/sync/protocol/sync_protocol_error.h b/sync/protocol/sync_protocol_error.h index 47c4f84e..d65fd243 100644 --- a/sync/protocol/sync_protocol_error.h +++ b/sync/protocol/sync_protocol_error.h
@@ -28,10 +28,6 @@ // Server cannot service the request now. TRANSIENT_ERROR, - // Server does not wish the client to retry any more until the action has - // been taken. - NON_RETRIABLE_ERROR, - // Indicates the datatypes have been migrated and the client should resync // them to get the latest progress markers. MIGRATION_DONE,
diff --git a/sync/sessions/model_type_registry_unittest.cc b/sync/sessions/model_type_registry_unittest.cc index 6db266ae..30ffbff 100644 --- a/sync/sessions/model_type_registry_unittest.cc +++ b/sync/sessions/model_type_registry_unittest.cc
@@ -9,6 +9,7 @@ #include "sync/internal_api/public/activation_context.h" #include "sync/internal_api/public/base/model_type.h" #include "sync/internal_api/public/shared_model_type_processor.h" +#include "sync/internal_api/public/test/fake_model_type_service.h" #include "sync/sessions/model_type_registry.h" #include "sync/test/engine/fake_model_worker.h" #include "sync/test/engine/mock_nudge_handler.h" @@ -17,17 +18,8 @@ namespace syncer { -namespace { - -scoped_ptr<syncer_v2::SharedModelTypeProcessor> MakeModelTypeProcessor( - ModelType type) { - return make_scoped_ptr(new syncer_v2::SharedModelTypeProcessor( - type, base::WeakPtr<syncer_v2::ModelTypeStore>())); -} - -} // namespace - -class ModelTypeRegistryTest : public ::testing::Test { +class ModelTypeRegistryTest : public ::testing::Test, + syncer_v2::FakeModelTypeService { public: ModelTypeRegistryTest(); void SetUp() override; @@ -54,6 +46,12 @@ return context.Pass(); } + protected: + scoped_ptr<syncer_v2::SharedModelTypeProcessor> MakeModelTypeProcessor( + ModelType type) { + return make_scoped_ptr(new syncer_v2::SharedModelTypeProcessor(type, this)); + } + private: syncable::Directory* directory();
diff --git a/sync/sync.gyp b/sync/sync.gyp index 2de3160..e9f991d 100644 --- a/sync/sync.gyp +++ b/sync/sync.gyp
@@ -265,6 +265,8 @@ 'internal_api/public/change_record.h', 'internal_api/public/configure_reason.h', 'internal_api/public/connection_status.h', + 'internal_api/public/data_batch_impl.h', + 'internal_api/public/data_batch_impl.cc', 'internal_api/public/data_type_association_stats.cc', 'internal_api/public/data_type_association_stats.h', 'internal_api/public/data_type_debug_info_listener.cc', @@ -321,8 +323,6 @@ 'internal_api/public/shutdown_reason.h', 'internal_api/public/simple_metadata_change_list.cc', 'internal_api/public/simple_metadata_change_list.h', - 'internal_api/public/specifics_only_data_batch.h', - 'internal_api/public/specifics_only_data_batch.cc', 'internal_api/public/sync_auth_provider.h', 'internal_api/public/sync_context.h', 'internal_api/public/sync_context_proxy.h',
diff --git a/sync/sync_tests.gypi b/sync/sync_tests.gypi index bc0c307..079812c 100644 --- a/sync/sync_tests.gypi +++ b/sync/sync_tests.gypi
@@ -183,12 +183,14 @@ 'test_support_sync_core', ], 'sources': [ + 'internal_api/public/test/fake_model_type_service.h', 'internal_api/public/test/fake_sync_manager.h', 'internal_api/public/test/null_sync_context_proxy.h', 'internal_api/public/test/sync_manager_factory_for_profile_sync_test.h', 'internal_api/public/test/test_entry_factory.h', 'internal_api/public/test/test_internal_components_factory.h', 'internal_api/public/test/test_user_share.h', + 'internal_api/test/fake_model_type_service.cc', 'internal_api/test/fake_sync_manager.cc', 'internal_api/test/null_sync_context_proxy.cc', 'internal_api/test/sync_manager_factory_for_profile_sync_test.cc', @@ -310,6 +312,7 @@ 'internal_api/public/base/ordinal_unittest.cc', 'internal_api/public/base/unique_position_unittest.cc', 'internal_api/public/change_record_unittest.cc', + 'internal_api/public/data_batch_impl_unittest.cc', 'internal_api/public/engine/model_safe_worker_unittest.cc', 'internal_api/public/sessions/sync_session_snapshot_unittest.cc', 'internal_api/public/util/immutable_unittest.cc',
diff --git a/testing/android/driver/java/AndroidManifest.xml b/testing/android/driver/java/AndroidManifest.xml index d67f9cd..16c70e20 100644 --- a/testing/android/driver/java/AndroidManifest.xml +++ b/testing/android/driver/java/AndroidManifest.xml
@@ -11,6 +11,7 @@ android:versionName="1.0"> <uses-sdk android:minSdkVersion="16" android:targetSdkVersion="23" /> + <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/> <application android:label="OnDeviceInstrumentationDriver" /> @@ -18,6 +19,4 @@ android:targetPackage="org.chromium.test.driver" android:label="OnDeviceInstrumentationDriver"/> - <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/> - </manifest>
diff --git a/testing/android/native_test/java/src/org/chromium/native_test/NativeTestActivity.java b/testing/android/native_test/java/src/org/chromium/native_test/NativeTestActivity.java index ebe0ce3..bdba1e0 100644 --- a/testing/android/native_test/java/src/org/chromium/native_test/NativeTestActivity.java +++ b/testing/android/native_test/java/src/org/chromium/native_test/NativeTestActivity.java
@@ -60,8 +60,10 @@ private void parseArgumentsFromIntent(Intent intent) { Log.i(TAG, "Extras:"); Bundle extras = intent.getExtras(); - for (String s : extras.keySet()) { - Log.i(TAG, " %s", s); + if (extras != null) { + for (String s : extras.keySet()) { + Log.i(TAG, " %s", s); + } } mCommandLineFilePath = intent.getStringExtra(EXTRA_COMMAND_LINE_FILE);
diff --git a/testing/buildbot/chromium.fyi.json b/testing/buildbot/chromium.fyi.json index 76b7dcc..c54c5a356 100644 --- a/testing/buildbot/chromium.fyi.json +++ b/testing/buildbot/chromium.fyi.json
@@ -5702,7 +5702,7 @@ { "args": [ "--site-per-process", - "--gtest_filter=-BrowserTest.InterstitialCancelsGuestViewDialogs:BrowserTest.OtherRedirectsDontForkProcess:BrowserTest.WindowOpenClose:ChromeRenderProcessHostTest.*:ChromeRenderProcessHostTestWithCommandLine.*:ErrorPageTest.*:ExtensionApiTest.ContentScriptOtherExtensions:ExtensionApiTest.Tabs2:ExtensionApiTest.TabsOnUpdated:ExtensionOptionsApiTest.ExtensionCanEmbedOwnOptions:IsolatedAppTest.*:MimeHandlerViewTest.*:*PDFExtensionTest.*:PhishingDOMFeatureExtractorTest.SubFrames:PrerenderBrowserTest.*:ProcessManagementTest.*:RedirectTest.ClientEmptyReferer:ReferrerPolicyTest.HttpsRedirect:*.RestoreWebUISettings:SSLUITest.TestGoodFrameNavigation:SSLUITest.TestMarkNonSecureAs:WebNavigationApiTest.CrossProcessFragment:WebNavigationApiTest.ServerRedirectSingleProcess:WebNavigationApiTest.CrossProcessHistory:WebViewDPITest.*:WebViewPluginTest.*:WebViewTest.AcceptTouchEvents:WebViewTest.IndexedDBIsolation:WebViewTest.ScreenCoordinates:WebViewTest.ContextMenusAPI_PreventDefault:WebViewTest.TestContextMenu:WebViewTest.NestedGuestContainerBounds:WebViewFocusTest.*:WebViewNewWindowTest.*:WebViewVisibilityTest.*:*.NavigateFromNTPToOptionsInSameTab:*.TabMove:*.WhitelistedExtension:*.NewTabPageURL:*.HomepageLocation:RestoreOnStartupPolicyTestInstance/RestoreOnStartupPolicyTest.RunTest*:PhishingClassifierDelegateTest.*:WebUIWebViewBrowserTest*:WebRtcBrowserTest.RunsAudioVideoWebRTCCallInTwoTabs:SingleProcessTracingBrowserTest.TestMemoryInfra" + "--gtest_filter=-BrowserTest.InterstitialCancelsGuestViewDialogs:BrowserTest.OtherRedirectsDontForkProcess:BrowserTest.WindowOpenClose:ChromeRenderProcessHostTest.*:ChromeRenderProcessHostTestWithCommandLine.*:ErrorPageTest.*:ExtensionApiTest.Tabs2:ExtensionApiTest.TabsOnUpdated:ExtensionOptionsApiTest.ExtensionCanEmbedOwnOptions:IsolatedAppTest.*:MimeHandlerViewTest.*:*PDFExtensionTest.*:PhishingDOMFeatureExtractorTest.SubFrames:PrerenderBrowserTest.*:ProcessManagementTest.*:RedirectTest.ClientEmptyReferer:ReferrerPolicyTest.HttpsRedirect:*.RestoreWebUISettings:SSLUITest.TestGoodFrameNavigation:SSLUITest.TestMarkNonSecureAs:WebNavigationApiTest.CrossProcessFragment:WebNavigationApiTest.ServerRedirectSingleProcess:WebNavigationApiTest.CrossProcessHistory:WebViewDPITest.*:WebViewPluginTest.*:WebViewTest.AcceptTouchEvents:WebViewTest.IndexedDBIsolation:WebViewTest.ScreenCoordinates:WebViewTest.ContextMenusAPI_PreventDefault:WebViewTest.TestContextMenu:WebViewTest.NestedGuestContainerBounds:WebViewFocusTest.*:WebViewNewWindowTest.*:WebViewVisibilityTest.*:*.NavigateFromNTPToOptionsInSameTab:*.TabMove:*.WhitelistedExtension:*.NewTabPageURL:*.HomepageLocation:RestoreOnStartupPolicyTestInstance/RestoreOnStartupPolicyTest.RunTest*:PhishingClassifierDelegateTest.*:WebUIWebViewBrowserTest*:WebRtcBrowserTest.RunsAudioVideoWebRTCCallInTwoTabs:SingleProcessTracingBrowserTest.TestMemoryInfra" ], "test": "browser_tests" }, @@ -5733,7 +5733,7 @@ { "args": [ "--site-per-process", - "--gtest_filter=-BrowserTest.InterstitialCancelsGuestViewDialogs:BrowserTest.OtherRedirectsDontForkProcess:BrowserTest.WindowOpenClose:ChromeRenderProcessHostTest.*:ChromeRenderProcessHostTestWithCommandLine.*:ErrorPageTest.*:ExtensionApiTest.ContentScriptOtherExtensions:ExtensionApiTest.Tabs2:ExtensionApiTest.TabsOnUpdated:ExtensionOptionsApiTest.ExtensionCanEmbedOwnOptions:IsolatedAppTest.*:MimeHandlerViewTest.*:*PDFExtensionTest.*:PhishingDOMFeatureExtractorTest.SubFrames:PrerenderBrowserTest.*:ProcessManagementTest.*:RedirectTest.ClientEmptyReferer:ReferrerPolicyTest.HttpsRedirect:*.RestoreWebUISettings:SSLUITest.TestGoodFrameNavigation:SSLUITest.TestMarkNonSecureAs:WebNavigationApiTest.CrossProcessFragment:WebNavigationApiTest.ServerRedirectSingleProcess:WebNavigationApiTest.CrossProcessHistory:WebViewDPITest.*:WebViewPluginTest.*:WebViewTest.AcceptTouchEvents:WebViewTest.IndexedDBIsolation:WebViewTest.ScreenCoordinates:WebViewTest.ContextMenusAPI_PreventDefault:WebViewTest.TestContextMenu:WebViewTest.NestedGuestContainerBounds:WebViewFocusTest.*:WebViewNewWindowTest.*:WebViewVisibilityTest.*:*.NavigateFromNTPToOptionsInSameTab:*.TabMove:*.WhitelistedExtension:*.NewTabPageURL:*.HomepageLocation:RestoreOnStartupPolicyTestInstance/RestoreOnStartupPolicyTest.RunTest*:PhishingClassifierDelegateTest.*:WebUIWebViewBrowserTest*:WebRtcBrowserTest.RunsAudioVideoWebRTCCallInTwoTabs:SingleProcessTracingBrowserTest.TestMemoryInfra" + "--gtest_filter=-BrowserTest.InterstitialCancelsGuestViewDialogs:BrowserTest.OtherRedirectsDontForkProcess:BrowserTest.WindowOpenClose:ChromeRenderProcessHostTest.*:ChromeRenderProcessHostTestWithCommandLine.*:ErrorPageTest.*:ExtensionApiTest.Tabs2:ExtensionApiTest.TabsOnUpdated:ExtensionOptionsApiTest.ExtensionCanEmbedOwnOptions:IsolatedAppTest.*:MimeHandlerViewTest.*:*PDFExtensionTest.*:PhishingDOMFeatureExtractorTest.SubFrames:PrerenderBrowserTest.*:ProcessManagementTest.*:RedirectTest.ClientEmptyReferer:ReferrerPolicyTest.HttpsRedirect:*.RestoreWebUISettings:SSLUITest.TestGoodFrameNavigation:SSLUITest.TestMarkNonSecureAs:WebNavigationApiTest.CrossProcessFragment:WebNavigationApiTest.ServerRedirectSingleProcess:WebNavigationApiTest.CrossProcessHistory:WebViewDPITest.*:WebViewPluginTest.*:WebViewTest.AcceptTouchEvents:WebViewTest.IndexedDBIsolation:WebViewTest.ScreenCoordinates:WebViewTest.ContextMenusAPI_PreventDefault:WebViewTest.TestContextMenu:WebViewTest.NestedGuestContainerBounds:WebViewFocusTest.*:WebViewNewWindowTest.*:WebViewVisibilityTest.*:*.NavigateFromNTPToOptionsInSameTab:*.TabMove:*.WhitelistedExtension:*.NewTabPageURL:*.HomepageLocation:RestoreOnStartupPolicyTestInstance/RestoreOnStartupPolicyTest.RunTest*:PhishingClassifierDelegateTest.*:WebUIWebViewBrowserTest*:WebRtcBrowserTest.RunsAudioVideoWebRTCCallInTwoTabs:SingleProcessTracingBrowserTest.TestMemoryInfra" ], "test": "browser_tests" },
diff --git a/testing/libfuzzer/fuzzers/BUILD.gn b/testing/libfuzzer/fuzzers/BUILD.gn index e36175e..3d52292 100644 --- a/testing/libfuzzer/fuzzers/BUILD.gn +++ b/testing/libfuzzer/fuzzers/BUILD.gn
@@ -227,3 +227,18 @@ "//third_party/zlib", ] } + +test("pdfium_fuzzer") { + sources = [ + "pdfium_fuzzer.cc", + ] + deps = [ + "//testing/libfuzzer:libfuzzer_main", + "//third_party/pdfium", + "//third_party/pdfium:test_support", + "//v8", + "//v8:v8_libplatform", + ] + configs += [ "//third_party/pdfium:pdfium_config" ] + configs += [ "//v8:external_config" ] +}
diff --git a/testing/libfuzzer/fuzzers/pdfium_fuzzer.cc b/testing/libfuzzer/fuzzers/pdfium_fuzzer.cc new file mode 100644 index 0000000..9a735f5 --- /dev/null +++ b/testing/libfuzzer/fuzzers/pdfium_fuzzer.cc
@@ -0,0 +1,189 @@ +// Copyright (c) 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. + +// This fuzzer is simplified & cleaned up pdfium/samples/pdfium_test.cc + +#include <limits.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> + +#include <list> +#include <sstream> +#include <string> +#include <utility> +#include <vector> + +#include "third_party/pdfium/public/fpdf_dataavail.h" +#include "third_party/pdfium/public/fpdf_ext.h" +#include "third_party/pdfium/public/fpdf_formfill.h" +#include "third_party/pdfium/public/fpdf_text.h" +#include "third_party/pdfium/public/fpdfview.h" +#include "third_party/pdfium/testing/test_support.h" + +#include "v8/include/v8.h" + +static int ExampleAppAlert(IPDF_JSPLATFORM*, FPDF_WIDESTRING, FPDF_WIDESTRING, + int, int) { + return 0; +} + +static void ExampleDocGotoPage(IPDF_JSPLATFORM*, int pageNumber) { } + +static void ExampleUnsupportedHandler(UNSUPPORT_INFO*, int type) { } + + +FPDF_BOOL Is_Data_Avail(FX_FILEAVAIL* pThis, size_t offset, size_t size) { + return true; +} + +static void Add_Segment(FX_DOWNLOADHINTS* pThis, size_t offset, size_t size) { } + +static bool RenderPage(const FPDF_DOCUMENT& doc, + const FPDF_FORMHANDLE& form, + const int page_index) { + FPDF_PAGE page = FPDF_LoadPage(doc, page_index); + if (!page) { + return false; + } + FPDF_TEXTPAGE text_page = FPDFText_LoadPage(page); + FORM_OnAfterLoadPage(page, form); + FORM_DoPageAAction(page, form, FPDFPAGE_AACTION_OPEN); + + double scale = 1.0; + int width = static_cast<int>(FPDF_GetPageWidth(page) * scale); + int height = static_cast<int>(FPDF_GetPageHeight(page) * scale); + + FPDF_BITMAP bitmap = FPDFBitmap_Create(width, height, 0); + if (!bitmap) { + return false; + } + + FPDFBitmap_FillRect(bitmap, 0, 0, width, height, 0xFFFFFFFF); + FPDF_RenderPageBitmap(bitmap, page, 0, 0, width, height, 0, 0); + + FPDF_FFLDraw(form, bitmap, page, 0, 0, width, height, 0, 0); + + FPDFBitmap_Destroy(bitmap); + FORM_DoPageAAction(page, form, FPDFPAGE_AACTION_CLOSE); + FORM_OnBeforeClosePage(page, form); + FPDFText_ClosePage(text_page); + FPDF_ClosePage(page); + return true; +} + +static void RenderPdf(const char* pBuf, size_t len) { + IPDF_JSPLATFORM platform_callbacks; + memset(&platform_callbacks, '\0', sizeof(platform_callbacks)); + platform_callbacks.version = 3; + platform_callbacks.app_alert = ExampleAppAlert; + platform_callbacks.Doc_gotoPage = ExampleDocGotoPage; + + FPDF_FORMFILLINFO form_callbacks; + memset(&form_callbacks, '\0', sizeof(form_callbacks)); + form_callbacks.version = 1; + form_callbacks.m_pJsPlatform = &platform_callbacks; + + TestLoader loader(pBuf, len); + FPDF_FILEACCESS file_access; + memset(&file_access, '\0', sizeof(file_access)); + file_access.m_FileLen = static_cast<unsigned long>(len); + file_access.m_GetBlock = TestLoader::GetBlock; + file_access.m_Param = &loader; + + FX_FILEAVAIL file_avail; + memset(&file_avail, '\0', sizeof(file_avail)); + file_avail.version = 1; + file_avail.IsDataAvail = Is_Data_Avail; + + FX_DOWNLOADHINTS hints; + memset(&hints, '\0', sizeof(hints)); + hints.version = 1; + hints.AddSegment = Add_Segment; + + FPDF_DOCUMENT doc; + int nRet = PDF_DATA_NOTAVAIL; + bool bIsLinearized = false; + FPDF_AVAIL pdf_avail = FPDFAvail_Create(&file_avail, &file_access); + + if (FPDFAvail_IsLinearized(pdf_avail) == PDF_LINEARIZED) { + doc = FPDFAvail_GetDocument(pdf_avail, nullptr); + if (doc) { + while (nRet == PDF_DATA_NOTAVAIL) { + nRet = FPDFAvail_IsDocAvail(pdf_avail, &hints); + } + if (nRet == PDF_DATA_ERROR) { + return; + } + nRet = FPDFAvail_IsFormAvail(pdf_avail, &hints); + if (nRet == PDF_FORM_ERROR || nRet == PDF_FORM_NOTAVAIL) { + return; + } + bIsLinearized = true; + } + } else { + doc = FPDF_LoadCustomDocument(&file_access, nullptr); + } + + if (!doc) { + FPDFAvail_Destroy(pdf_avail); + return; + } + + (void)FPDF_GetDocPermissions(doc); + + FPDF_FORMHANDLE form = FPDFDOC_InitFormFillEnvironment(doc, &form_callbacks); + FPDF_SetFormFieldHighlightColor(form, 0, 0xFFE4DD); + FPDF_SetFormFieldHighlightAlpha(form, 100); + + FORM_DoDocumentJSAction(form); + FORM_DoDocumentOpenAction(form); + + int page_count = FPDF_GetPageCount(doc); + + for (int i = 0; i < page_count; ++i) { + if (bIsLinearized) { + nRet = PDF_DATA_NOTAVAIL; + while (nRet == PDF_DATA_NOTAVAIL) { + nRet = FPDFAvail_IsPageAvail(pdf_avail, i, &hints); + } + if (nRet == PDF_DATA_ERROR) { + return; + } + } + RenderPage(doc, form, i); + } + + FORM_DoDocumentAAction(form, FPDFDOC_AACTION_WC); + FPDFDOC_ExitFormFillEnvironment(form); + FPDF_CloseDocument(doc); + FPDFAvail_Destroy(pdf_avail); +} + +static v8::Platform* Init() { + v8::Platform* platform; + InitializeV8ForPDFium(&platform); + + auto config = new FPDF_LIBRARY_CONFIG(); + config->version = 2; + config->m_pUserFontPaths = nullptr; + config->m_pIsolate = nullptr; + config->m_v8EmbedderSlot = 0; + FPDF_InitLibraryWithConfig(config); + + auto unsuppored_info = new UNSUPPORT_INFO(); + memset(unsuppored_info, '\0', sizeof(*unsuppored_info)); + unsuppored_info->version = 1; + unsuppored_info->FSDK_UnSupport_Handler = ExampleUnsupportedHandler; + FSDK_SetUnSpObjProcessHandler(unsuppored_info); + + return platform; +} + +static v8::Platform* platform = Init(); + +extern "C" int LLVMFuzzerTestOneInput(const unsigned char* data, size_t size) { + RenderPdf(reinterpret_cast<const char*>(data), size); + return 0; +}
diff --git a/testing/scripts/mojo_apptests.py b/testing/scripts/mojo_apptests.py index 49b855da2..70f32c80 100755 --- a/testing/scripts/mojo_apptests.py +++ b/testing/scripts/mojo_apptests.py
@@ -34,7 +34,7 @@ def main_compile_targets(args): - json.dump(['mandoline:tests'], args.output) + json.dump(['mandoline:tests', 'mash/wm:tests'], args.output) if __name__ == '__main__':
diff --git a/third_party/WebKit/LayoutTests/NeverFixTests b/third_party/WebKit/LayoutTests/NeverFixTests index 5c4da0a..10c6dda 100644 --- a/third_party/WebKit/LayoutTests/NeverFixTests +++ b/third_party/WebKit/LayoutTests/NeverFixTests
@@ -145,7 +145,6 @@ # Chrome Linux doesn't support NPAPI plugins anymore. [ Linux ] http/tests/plugins/interrupted-get-url.html [ WontFix ] -[ Linux ] http/tests/plugins/third-party-cookie-accept-policy.html [ WontFix ] [ Linux ] plugins/mouse-click-plugin-clears-selection.html [ WontFix ] # Missing Chrome Mac support, will start working when we move to harfbuzz on mac.
diff --git a/third_party/WebKit/LayoutTests/SlowTests b/third_party/WebKit/LayoutTests/SlowTests index 10edb315..8560bd0d 100644 --- a/third_party/WebKit/LayoutTests/SlowTests +++ b/third_party/WebKit/LayoutTests/SlowTests
@@ -9,7 +9,7 @@ crbug.com/24182 [ Debug ] storage/indexeddb/objectstore-cursor.html [ Slow ] crbug.com/24182 storage/indexeddb/mozilla/test_objectStore_openKeyCursor.html [ Slow ] -crbug.com/24182 [ Linux Win Debug ] editing/selection/move-by-word-visually-mac.html [ Slow ] +crbug.com/24182 editing/selection/move-by-word-visually-mac.html [ Slow ] crbug.com/24182 editing/selection/move-by-word-visually-multi-line.html [ Slow ] crbug.com/24182 [ Win ] virtual/gpu/fast/canvas/webgl/canvas-test.html [ Slow ] crbug.com/24182 [ Win ] virtual/gpu/fast/canvas/webgl/framebuffer-object-attachment.html [ Slow ]
diff --git a/third_party/WebKit/LayoutTests/TestExpectations b/third_party/WebKit/LayoutTests/TestExpectations index 399b6a37..4238e835 100644 --- a/third_party/WebKit/LayoutTests/TestExpectations +++ b/third_party/WebKit/LayoutTests/TestExpectations
@@ -134,12 +134,10 @@ crbug.com/520612 [ Linux ] fullscreen/anonymous-block-merge-crash.html [ Pass Timeout ] crbug.com/520613 http/tests/cache/freshness-header.html [ Failure Pass ] crbug.com/520614 http/tests/w3c/webperf/submission/Intel/resource-timing/test_resource_timing_buffer_size_restriction.html [ Failure Pass ] -crbug.com/520617 [ Mac ] webaudio/audiochannelmerger-disconnect.html [ Failure Pass ] crbug.com/520619 [ Android Mac Linux XP Win7 ] webexposed/global-interface-listing.html [ Pass Timeout ] crbug.com/520194 http/tests/xmlhttprequest/timeout/xmlhttprequest-timeout-worker-overridesexpires.html [ Failure Pass ] crbug.com/520199 [ Mac ] plugins/plugin-initiate-popup-window.html [ Failure Pass ] crbug.com/520200 [ XP ] svg/batik/text/smallFonts.svg [ Failure Timeout ] -crbug.com/520203 webaudio/audiobuffersource-late-start.html [ Failure Pass Timeout ] crbug.com/518967 [ Win7 ] http/tests/htmlimports/csp-import-block-but-nonce-nested.html [ Failure Pass Timeout ] crbug.com/448461 http/tests/loading/simple-subframe.html [ Failure Pass Timeout ] crbug.com/339597 http/tests/navigation/back-to-redirect-with-frame.php [ Pass Timeout ] @@ -180,7 +178,6 @@ crbug.com/519001 storage/indexeddb/pending-version-change-stuck-works-with-terminate.html [ Pass Timeout ] crbug.com/519002 storage/indexeddb/pending-version-change-stuck.html [ Pass Timeout ] crbug.com/519003 [ Mac ] svg/batik/text/xmlSpace.svg [ Failure Pass ] -crbug.com/519005 webaudio/stereopannernode-no-glitch.html [ Pass Timeout ] crbug.com/410949 http/tests/security/local-image-from-remote-whitelisted.html [ Failure Pass ] crbug.com/356828 fast/dom/gc-dom-tree-lifetime.html [ Pass Timeout ] crbug.com/518902 accessibility/AccessibilityScrollbar-leak.html [ Failure Pass ] @@ -544,7 +541,6 @@ crbug.com/318978 [ Linux ] http/tests/security/contentSecurityPolicy/object-src-none-allowed.html [ Skip ] crbug.com/318978 [ Linux ] http/tests/security/contentSecurityPolicy/object-src-url-blocked.html [ Skip ] crbug.com/318978 [ Linux ] http/tests/security/contentSecurityPolicy/plugin-in-iframe-with-csp.html [ Skip ] -crbug.com/318978 [ Linux ] http/tests/security/frameNavigation/xss-DENIED-plugin-navigation.html [ Skip ] crbug.com/318978 [ Linux ] permissionclient/plugin-permission.html [ Skip ] crbug.com/318978 [ Linux ] plugins/ [ Skip ] @@ -806,7 +802,8 @@ crbug.com/390377 [ Release ] fast/dom/private_script_unittest.html [ Skip ] -crbug.com/546512 http/tests/security/w3c/cross-origin-objects.html [ NeedsManualRebaseline ] +# TODO(jkummerow): Re-enable after V8-side patch rolls in. +crbug.com/565934 http/tests/security/cross-frame-access-enumeration.html [ Skip ] crbug.com/357427 http/tests/workers/terminate-during-sync-operation-file.html [ Crash Pass Slow Timeout ] crbug.com/357427 http/tests/workers/terminate-during-sync-operation-filesystem.html [ Crash Pass Slow Timeout ] @@ -1306,8 +1303,6 @@ # The Win10 result for fast/text/emoji-font-fallback-win.html does not match the description crbug.com/527044 [ Win10 ] fast/text/emoji-font-fallback-win.html [ Failure ] -crbug.com/525065 webaudio/audionode-disconnect-audioparam.html [ Failure Pass ] - crbug.com/525296 fast/css/font-load-while-styleresolver-missing.html [ Crash Failure Pass ] crbug.com/240576 fullscreen/api/element-ready-check-containing-iframe.html [ Timeout Failure Pass ]
diff --git a/third_party/WebKit/LayoutTests/accessibility/description-calc-inputs.html b/third_party/WebKit/LayoutTests/accessibility/description-calc-inputs.html index e82530d..44c70e2 100644 --- a/third_party/WebKit/LayoutTests/accessibility/description-calc-inputs.html +++ b/third_party/WebKit/LayoutTests/accessibility/description-calc-inputs.html
@@ -108,6 +108,25 @@ }, "placeholder overrides title as the accessible description."); </script> +<div class="container"> + <input id="text8" type="text" aria-describedby="describedby8"> + <p id="describedby8"> + Described + <br> + By + </p> +</div> + +<script> +test(function(t) { + var axTextInput8 = accessibilityController.accessibleElementById("text8"); + assert_equals(axTextInput8.name, ""); + assert_equals(axTextInput8.nameFrom, ""); + assert_equals(axTextInput8.description, "Described By"); + assert_equals(axTextInput8.descriptionFrom, "relatedElement"); +}, "aria-describedby does not include newlines."); +</script> + <script> if (window.testRunner) document.body.className = "hideAllContainers";
diff --git a/third_party/WebKit/LayoutTests/accessibility/display-none-change.html b/third_party/WebKit/LayoutTests/accessibility/display-none-change.html index 9697088..8b247767e 100644 --- a/third_party/WebKit/LayoutTests/accessibility/display-none-change.html +++ b/third_party/WebKit/LayoutTests/accessibility/display-none-change.html
@@ -13,7 +13,7 @@ // Ensure that it's valid. var axLabel = axButton.nameElementAtIndex(0); assert_equals(axLabel.isValid, true); - assert_equals(axLabel.name, 'AriaLabel'); + assert_equals(axLabel.role, 'AXRole: AXLabel'); // Now un-hide the label. var label = document.getElementById('label'); @@ -36,7 +36,7 @@ assert_equals(axLabel.isValid, false); assert_equals(axLabel2.isValid, false); assert_equals(axLabel3.isValid, true); - assert_equals(axLabel3.name, 'AriaLabel'); + assert_equals(axLabel3.role, 'AXRole: AXLabel'); assert_equals(axLabel.isEqual(axLabel3), false); assert_equals(axLabel2.isEqual(axLabel3), false); }, "Accessibility objects for display:none elements");
diff --git a/third_party/WebKit/LayoutTests/accessibility/element-role-mapping-normal-expected.txt b/third_party/WebKit/LayoutTests/accessibility/element-role-mapping-normal-expected.txt index b486e5f..22929f9 100644 --- a/third_party/WebKit/LayoutTests/accessibility/element-role-mapping-normal-expected.txt +++ b/third_party/WebKit/LayoutTests/accessibility/element-role-mapping-normal-expected.txt
@@ -130,7 +130,9 @@ AXRole: AXStaticText "Text that appears under aside" AXRole: AXInlineTextBox "Text that appears under aside" AXRole: AXPre - AXRole: AXStaticText "Text in a pre element " + AXRole: AXStaticText "Text in a pre +element +" AXRole: AXInlineTextBox "Text in a pre" AXRole: AXInlineTextBox " "
diff --git a/third_party/WebKit/LayoutTests/accessibility/img-alt-tag-only-whitespace-expected.txt b/third_party/WebKit/LayoutTests/accessibility/img-alt-tag-only-whitespace-expected.txt index b9b8cc0..52170f7 100644 --- a/third_party/WebKit/LayoutTests/accessibility/img-alt-tag-only-whitespace-expected.txt +++ b/third_party/WebKit/LayoutTests/accessibility/img-alt-tag-only-whitespace-expected.txt
@@ -1,4 +1,4 @@ -CONSOLE MESSAGE: line 26: Image description: Image +CONSOLE MESSAGE: line 26: Image description: Image
diff --git a/third_party/WebKit/LayoutTests/accessibility/name-calc-visibility.html b/third_party/WebKit/LayoutTests/accessibility/name-calc-visibility.html new file mode 100644 index 0000000..00bab2e --- /dev/null +++ b/third_party/WebKit/LayoutTests/accessibility/name-calc-visibility.html
@@ -0,0 +1,102 @@ +<!DOCTYPE HTML> +<script src="../resources/testharness.js"></script> +<script src="../resources/testharnessreport.js"></script> + +<style> +.hideAllContainers .container { + display: none; +} +</style> + +<div id="link1" class="container" tabIndex=0 role="link"> + <p>1</p> + <table> + <tr><td>2</td></tr> + <tr><td style="visibility: hidden">3</td></tr> + <tr><td style="display:none">4</td></tr> + <tr style="visibility: hidden"><td>5</td></tr> + <tr style="display: none"><td>6</td></tr> + </table> + <p>7</p> +</div> + +<script> +test(function(t) { + var axLink1 = accessibilityController.accessibleElementById("link1"); + assert_equals(axLink1.name, "1 2 7"); +}, "Visibility: 'hidden' and display: 'none' inside ARIA link"); +</script> + +<div class="container"> + <input id="input2" aria-labelledby="label2"> + + <div id="label2"> + <p>1</p> + <table> + <tr><td>2</td></tr> + <tr><td style="visibility: hidden">3</td></tr> + <tr><td style="display:none">4</td></tr> + <tr style="visibility: hidden"><td>5</td></tr> + <tr style="display: none"><td>6</td></tr> + </table> + <p>7</p> + </div> +</div> + +<script> +test(function(t) { + var axInput2 = accessibilityController.accessibleElementById("input2"); + assert_equals(axInput2.name, "1 2 7"); +}, "Visibility: 'hidden' and display: 'none' inside aria-labelledby label subtree"); +</script> + +<div class="container"> + <input id="input3" aria-labelledby="3a 3b 3c 3d 3e 3f 3g"> + + <p id="3a">1</p> + <table> + <tr><td id="3b">2</td></tr> + <tr><td id="3c" style="visibility: hidden">3</td></tr> + <tr><td id="3d" style="display:none">4</td></tr> + <tr id="3e" style="visibility: hidden"><td>5</td></tr> + <tr id="3f" style="display: none"><td>6</td></tr> + </table> + <p id="3g">7</p> +</div> + +<script> +test(function(t) { + var axInput3 = accessibilityController.accessibleElementById("input3"); + assert_equals(axInput3.name, "1 2 3 4 6 7"); +}, "Visibility: 'hidden' and display: 'none' referenced directly by aria-labelledby"); +</script> + +<div class="container"> + <input id="input4" aria-labelledby="label4"> + + <div style="display: none"> + <div id="label4"> + <p>1</p> + <table> + <tr><td>2</td></tr> + <tr><td style="visibility: hidden">3</td></tr> + <tr><td style="display:none">4</td></tr> + <tr style="visibility: hidden"><td>5</td></tr> + <tr style="display: none"><td>6</td></tr> + </table> + <p>7</p> + </div> + </div> +</div> + +<script> +test(function(t) { + var axInput4 = accessibilityController.accessibleElementById("input4"); + assert_equals(axInput4.name, " 1 2 7 "); +}, "Visibility: 'hidden' and display: 'none' inside aria-labelledby label subtree, where entire label subtree is display: 'none'"); +</script> + +<script> +if (window.testRunner) + document.body.className = "hideAllContainers"; +</script>
diff --git a/third_party/WebKit/LayoutTests/fast/borders/border-image-inherits-with-border-expected.html b/third_party/WebKit/LayoutTests/fast/borders/border-image-inherits-with-border-expected.html new file mode 100644 index 0000000..78537d9c --- /dev/null +++ b/third_party/WebKit/LayoutTests/fast/borders/border-image-inherits-with-border-expected.html
@@ -0,0 +1,25 @@ +<!DOCTYPE html> +<style> + #parent { + border: solid; + border-image-source: url('resources/border-image.png'); + border-image-slice: 10%; + border-image-width: 2; + border-image-outset: 1; + border-image-repeat: repeat; + + } + + #child { + border: inherit; + border-image-source: inherit; + border-image-slice: inherit; + border-image-width: inherit; + border-image-outset: inherit; + border-image-repeat: inherit; + } +</style> +<div id="parent"> + <p>Parent with border-image</p> + <span id="child">Child - should inherit border-image</span> +</div>
diff --git a/third_party/WebKit/LayoutTests/fast/borders/border-image-inherits-with-border.html b/third_party/WebKit/LayoutTests/fast/borders/border-image-inherits-with-border.html new file mode 100644 index 0000000..e08d229 --- /dev/null +++ b/third_party/WebKit/LayoutTests/fast/borders/border-image-inherits-with-border.html
@@ -0,0 +1,19 @@ +<!DOCTYPE html> +<style> + #parent { + border: solid; + border-image-source: url('resources/border-image.png'); + border-image-slice: 10%; + border-image-width: 2; + border-image-outset: 1; + border-image-repeat: repeat; + } + + #child { + border: inherit; + } +</style> +<div id="parent"> + <p>Parent with border-image</p> + <span id="child">Child - should inherit border-image</span> +</div>
diff --git a/third_party/WebKit/LayoutTests/fast/css/containment/contain-parse-and-apply-expected.txt b/third_party/WebKit/LayoutTests/fast/css/containment/contain-parse-and-apply-expected.txt new file mode 100644 index 0000000..04212e1 --- /dev/null +++ b/third_party/WebKit/LayoutTests/fast/css/containment/contain-parse-and-apply-expected.txt
@@ -0,0 +1,26 @@ +PASS getContainValue('#none') is "none" +PASS getContainValue('#style') is "style" +PASS getContainValue('#layout') is "layout" +PASS getContainValue('#paint') is "paint" +PASS getContainValue('#strict') is "strict" +PASS computedContainValue(children[i]) is "none" +PASS computedContainValue(children[i]) is "none" +PASS computedContainValue(children[i]) is "none" +PASS computedContainValue(children[i]) is "none" +PASS computedContainValue(children[i]) is "none" +PASS getContainValue('#test') is "strict" +PASS getContainValue('#test') is "layout paint" +PASS getContainValue('#test') is "strict" +PASS getContainValue('#test') is "none" +PASS getContainValue('#test') is "none" +PASS getContainValue('#test') is "none" +PASS getContainValue('#test') is "none" +PASS getContainValue('#test') is "none" +PASS getContainValue('#test') is "style paint" +PASS getContainValue('#test') is "style paint" +PASS getContainValue('#test') is "style paint" +PASS getContainValue('#test') is "style paint" +PASS successfullyParsed is true + +TEST COMPLETE +
diff --git a/third_party/WebKit/LayoutTests/fast/css/containment/contain-parse-and-apply.html b/third_party/WebKit/LayoutTests/fast/css/containment/contain-parse-and-apply.html new file mode 100644 index 0000000..5c1bd257 --- /dev/null +++ b/third_party/WebKit/LayoutTests/fast/css/containment/contain-parse-and-apply.html
@@ -0,0 +1,75 @@ +<!DOCTYPE html> +<style> +#none { contain: none; } +#style { contain: style; } +#layout { contain: layout; } +#paint { contain: paint; } +#strict { contain: strict; } +</style> +<body> +<div id="none"><div></div></div> +<div id="style"><div></div></div> +<div id="layout"><div></div></div> +<div id="paint"><div></div></div> +<div id="strict"><div></div></div> +<div id="test"></div> +<script src="../../../resources/js-test.js"></script> +<script> +function computedContainValue(element) { + return window.getComputedStyle(element).contain; +} +function getContainValue(query) +{ + var element = document.querySelector(query); + return computedContainValue(element); +} + +shouldBeEqualToString("getContainValue('#none')", "none"); +shouldBeEqualToString("getContainValue('#style')", "style"); +shouldBeEqualToString("getContainValue('#layout')", "layout"); +shouldBeEqualToString("getContainValue('#paint')", "paint"); +shouldBeEqualToString("getContainValue('#strict')", "strict"); + +var children = document.querySelectorAll("div > div"); +for (var i = 0; i < children.length; i++) { + shouldBeEqualToString("computedContainValue(children[i])", "none"); +} + +var test = document.querySelector('#test'); + +test.style.setProperty("contain", "layout paint style"); +shouldBeEqualToString("getContainValue('#test')", "strict"); + +test.style.setProperty("contain", "layout paint"); +shouldBeEqualToString("getContainValue('#test')", "layout paint"); + +test.style.setProperty("contain", "strict"); +shouldBeEqualToString("getContainValue('#test')", "strict"); + +test.style.setProperty("contain", "none"); +shouldBeEqualToString("getContainValue('#test')", "none"); + +test.style.setProperty("contain", "layout layout"); +shouldBeEqualToString("getContainValue('#test')", "none"); + +test.style.setProperty("contain", "strict layout"); +shouldBeEqualToString("getContainValue('#test')", "none"); + +test.style.setProperty("contain", "paint strict"); +shouldBeEqualToString("getContainValue('#test')", "none"); + +test.style.setProperty("contain", "paint layout style paint"); +shouldBeEqualToString("getContainValue('#test')", "none"); + +test.style.setProperty("contain", "style paint"); +shouldBeEqualToString("getContainValue('#test')", "style paint"); + +test.style.setProperty("contain", "none strict"); +shouldBeEqualToString("getContainValue('#test')", "style paint"); + +test.style.setProperty("contain", "strict strict"); +shouldBeEqualToString("getContainValue('#test')", "style paint"); + +test.style.setProperty("contain", "strict none"); +shouldBeEqualToString("getContainValue('#test')", "style paint"); +</script> \ No newline at end of file
diff --git a/third_party/WebKit/LayoutTests/fast/css/invalidation/add-first-line-style-expected.html b/third_party/WebKit/LayoutTests/fast/css/invalidation/add-first-line-style-expected.html new file mode 100644 index 0000000..5d83472 --- /dev/null +++ b/third_party/WebKit/LayoutTests/fast/css/invalidation/add-first-line-style-expected.html
@@ -0,0 +1,4 @@ +<!DOCTYPE html> +<!-- This expectation is wrong because of crbug.com/564239. + Correct expectation should be with style="color: green". --> +<div>This text should be green.</div>
diff --git a/third_party/WebKit/LayoutTests/fast/css/invalidation/add-first-line-style.html b/third_party/WebKit/LayoutTests/fast/css/invalidation/add-first-line-style.html new file mode 100644 index 0000000..fb7a62b7 --- /dev/null +++ b/third_party/WebKit/LayoutTests/fast/css/invalidation/add-first-line-style.html
@@ -0,0 +1,14 @@ +<!DOCTYPE html> +<style id="style"> +#target::first-line { color: green } +</style> +<script> +document.getElementById('style').disabled = true; +</script> +<div id="target">This text should be green.</div> +<script src="../../../resources/run-after-layout-and-paint.js"></script> +<script> +runAfterLayoutAndPaint(function() { + document.getElementById('style').disabled = false; +}, true); +</script>
diff --git a/third_party/WebKit/LayoutTests/fast/css/invalidation/first-line-change-inline-color-expected.html b/third_party/WebKit/LayoutTests/fast/css/invalidation/first-line-change-inline-color-expected.html new file mode 100644 index 0000000..09c518e --- /dev/null +++ b/third_party/WebKit/LayoutTests/fast/css/invalidation/first-line-change-inline-color-expected.html
@@ -0,0 +1,4 @@ +<!DOCTYPE html> +<!-- This expectation is wrong because of crbug.com/562418. + The inner span should have style="color: green". --> +<p style="color: red">Red <span>This text should be green.</span> Red</p>
diff --git a/third_party/WebKit/LayoutTests/fast/css/invalidation/first-line-change-inline-color-inherited-expected.html b/third_party/WebKit/LayoutTests/fast/css/invalidation/first-line-change-inline-color-inherited-expected.html new file mode 100644 index 0000000..09c518e --- /dev/null +++ b/third_party/WebKit/LayoutTests/fast/css/invalidation/first-line-change-inline-color-inherited-expected.html
@@ -0,0 +1,4 @@ +<!DOCTYPE html> +<!-- This expectation is wrong because of crbug.com/562418. + The inner span should have style="color: green". --> +<p style="color: red">Red <span>This text should be green.</span> Red</p>
diff --git a/third_party/WebKit/LayoutTests/fast/css/invalidation/first-line-change-inline-color-inherited.html b/third_party/WebKit/LayoutTests/fast/css/invalidation/first-line-change-inline-color-inherited.html new file mode 100644 index 0000000..917847a --- /dev/null +++ b/third_party/WebKit/LayoutTests/fast/css/invalidation/first-line-change-inline-color-inherited.html
@@ -0,0 +1,17 @@ +<!DOCTYPE html> +<style> + #block { color: green; } + #block::first-line { color: red; } + .green { color: green; } +</style> +<div id="block"> + <div> + <p>Red <span id="t"><span>This text should be green.<span></span> Red</p> + </div> +</div> +<script src="../../resources/run-after-layout-and-paint.js"></script> +<script> +runAfterLayoutAndPaint(function() { + document.getElementById('t').className = 'green'; +}, true); +</script>
diff --git a/third_party/WebKit/LayoutTests/fast/css/invalidation/first-line-change-inline-color.html b/third_party/WebKit/LayoutTests/fast/css/invalidation/first-line-change-inline-color.html new file mode 100644 index 0000000..c147ad6b --- /dev/null +++ b/third_party/WebKit/LayoutTests/fast/css/invalidation/first-line-change-inline-color.html
@@ -0,0 +1,17 @@ +<!DOCTYPE html> +<style> + #block { color: green; } + #block::first-line { color: red; } + .green { color: green; } +</style> +<div id="block"> + <div> + <p>Red <span id="t">This text should be green.</span> Red</p> + </div> +</div> +<script src="../../resources/run-after-layout-and-paint.js"></script> +<script> +runAfterLayoutAndPaint(function() { + document.getElementById('t').className = 'green'; +}, true); +</script>
diff --git a/third_party/WebKit/LayoutTests/fast/css/invalidation/remove-first-line-style-expected.html b/third_party/WebKit/LayoutTests/fast/css/invalidation/remove-first-line-style-expected.html new file mode 100644 index 0000000..a8463d6 --- /dev/null +++ b/third_party/WebKit/LayoutTests/fast/css/invalidation/remove-first-line-style-expected.html
@@ -0,0 +1,4 @@ +<!DOCTYPE html> +<!-- This expectation is wrong because of crbug.com/564239. + Correct expectation should be style="color: green". --> +<div style="color: red">This text should be green.</div>
diff --git a/third_party/WebKit/LayoutTests/fast/css/invalidation/remove-first-line-style.html b/third_party/WebKit/LayoutTests/fast/css/invalidation/remove-first-line-style.html new file mode 100644 index 0000000..9d3455c --- /dev/null +++ b/third_party/WebKit/LayoutTests/fast/css/invalidation/remove-first-line-style.html
@@ -0,0 +1,11 @@ +<!DOCTYPE html> +<style id="style"> +#target::first-line { color: red } +</style> +<div id="target" style="color: green">This text should be green.</div> +<script src="../../../resources/run-after-layout-and-paint.js"></script> +<script> +runAfterLayoutAndPaint(function() { + document.getElementById('style').disabled = true; +}, true); +</script>
diff --git a/third_party/WebKit/LayoutTests/fast/css/parsing-object-position-expected.txt b/third_party/WebKit/LayoutTests/fast/css/parsing-object-position-expected.txt index 9e0f568..97c6918 100644 --- a/third_party/WebKit/LayoutTests/fast/css/parsing-object-position-expected.txt +++ b/third_party/WebKit/LayoutTests/fast/css/parsing-object-position-expected.txt
@@ -13,29 +13,29 @@ PASS testComputedStyle("object-position: bottom 20px right 12px;") is "calc(-12px + 100%) calc(-20px + 100%)" PASS test("object-position: inherit;") is "inherit" PASS test("object-position: initial;") is "initial" -PASS test("object-position: left;") is "0% 50%" -PASS test("object-position: top;") is "50% 0%" -PASS test("object-position: top right;") is "100% 0%" -PASS test("object-position: right top;") is "100% 0%" -PASS test("object-position: center center;") is "50% 50%" -PASS test("object-position: center;") is "50% 50%" -PASS test("object-position: bottom center;") is "50% 100%" -PASS test("object-position: left center;") is "0% 50%" -PASS test("object-position: bottom center;") is "50% 100%" -PASS test("object-position: center left;") is "0% 50%" -PASS test("object-position: center bottom;") is "50% 100%" -PASS test("object-position: 100px;") is "100px 50%" +PASS test("object-position: left;") is "left center" +PASS test("object-position: top;") is "center top" +PASS test("object-position: top right;") is "right top" +PASS test("object-position: right top;") is "right top" +PASS test("object-position: center center;") is "center center" +PASS test("object-position: center;") is "center center" +PASS test("object-position: bottom center;") is "center bottom" +PASS test("object-position: left center;") is "left center" +PASS test("object-position: bottom center;") is "center bottom" +PASS test("object-position: center left;") is "left center" +PASS test("object-position: center bottom;") is "center bottom" +PASS test("object-position: 100px;") is "100px center" PASS test("object-position: 100px 100px;") is "100px 100px" PASS test("object-position: 100px 200px;") is "100px 200px" PASS test("object-position: -50% 0;") is "-50% 0px" PASS test("object-position: 3em 0;") is "3em 0px" -PASS test("object-position: left 33px;") is "0% 33px" -PASS test("object-position: center 33px;") is "50% 33px" -PASS test("object-position: 33px center;") is "33px 50%" -PASS test("object-position: 33px bottom;") is "33px 100%" +PASS test("object-position: left 33px;") is "left 33px" +PASS test("object-position: center 33px;") is "center 33px" +PASS test("object-position: 33px center;") is "33px center" +PASS test("object-position: 33px bottom;") is "33px bottom" PASS test("object-position: 1vh 1vw;") is "1vh 1vw" -PASS test("object-position: left 20px center;") is "left 20px top 50%" -PASS test("object-position: center bottom 25%;") is "left 50% bottom 25%" +PASS test("object-position: left 20px center;") is "left 20px center" +PASS test("object-position: center bottom 25%;") is "center bottom 25%" PASS test("object-position: bottom 20px right 12px;") is "right 12px bottom 20px" PASS test("object-position: 100px 100px 100px;") is "" PASS test("object-position: 100px 100px 200px 200px;") is ""
diff --git a/third_party/WebKit/LayoutTests/fast/css/parsing-object-position.html b/third_party/WebKit/LayoutTests/fast/css/parsing-object-position.html index b4a32af..41c72c1 100644 --- a/third_party/WebKit/LayoutTests/fast/css/parsing-object-position.html +++ b/third_party/WebKit/LayoutTests/fast/css/parsing-object-position.html
@@ -40,29 +40,29 @@ shouldBeEqualToString('test("object-position: inherit;")', 'inherit'); shouldBeEqualToString('test("object-position: initial;")', 'initial'); - shouldBeEqualToString('test("object-position: left;")', '0% 50%'); - shouldBeEqualToString('test("object-position: top;")', '50% 0%'); - shouldBeEqualToString('test("object-position: top right;")', '100% 0%'); - shouldBeEqualToString('test("object-position: right top;")', '100% 0%'); - shouldBeEqualToString('test("object-position: center center;")', '50% 50%'); - shouldBeEqualToString('test("object-position: center;")', '50% 50%'); - shouldBeEqualToString('test("object-position: bottom center;")', '50% 100%'); - shouldBeEqualToString('test("object-position: left center;")', '0% 50%'); - shouldBeEqualToString('test("object-position: bottom center;")', '50% 100%'); - shouldBeEqualToString('test("object-position: center left;")', '0% 50%'); - shouldBeEqualToString('test("object-position: center bottom;")', '50% 100%'); - shouldBeEqualToString('test("object-position: 100px;")', '100px 50%'); + shouldBeEqualToString('test("object-position: left;")', 'left center'); + shouldBeEqualToString('test("object-position: top;")', 'center top'); + shouldBeEqualToString('test("object-position: top right;")', 'right top'); + shouldBeEqualToString('test("object-position: right top;")', 'right top'); + shouldBeEqualToString('test("object-position: center center;")', 'center center'); + shouldBeEqualToString('test("object-position: center;")', 'center center'); + shouldBeEqualToString('test("object-position: bottom center;")', 'center bottom'); + shouldBeEqualToString('test("object-position: left center;")', 'left center'); + shouldBeEqualToString('test("object-position: bottom center;")', 'center bottom'); + shouldBeEqualToString('test("object-position: center left;")', 'left center'); + shouldBeEqualToString('test("object-position: center bottom;")', 'center bottom'); + shouldBeEqualToString('test("object-position: 100px;")', '100px center'); shouldBeEqualToString('test("object-position: 100px 100px;")', '100px 100px'); shouldBeEqualToString('test("object-position: 100px 200px;")', '100px 200px'); shouldBeEqualToString('test("object-position: -50% 0;")', '-50% 0px'); shouldBeEqualToString('test("object-position: 3em 0;")', '3em 0px'); - shouldBeEqualToString('test("object-position: left 33px;")', '0% 33px'); - shouldBeEqualToString('test("object-position: center 33px;")', '50% 33px'); - shouldBeEqualToString('test("object-position: 33px center;")', '33px 50%'); - shouldBeEqualToString('test("object-position: 33px bottom;")', '33px 100%'); + shouldBeEqualToString('test("object-position: left 33px;")', 'left 33px'); + shouldBeEqualToString('test("object-position: center 33px;")', 'center 33px'); + shouldBeEqualToString('test("object-position: 33px center;")', '33px center'); + shouldBeEqualToString('test("object-position: 33px bottom;")', '33px bottom'); shouldBeEqualToString('test("object-position: 1vh 1vw;")', '1vh 1vw'); - shouldBeEqualToString('test("object-position: left 20px center;")', 'left 20px top 50%'); - shouldBeEqualToString('test("object-position: center bottom 25%;")', 'left 50% bottom 25%'); + shouldBeEqualToString('test("object-position: left 20px center;")', 'left 20px center'); + shouldBeEqualToString('test("object-position: center bottom 25%;")', 'center bottom 25%'); shouldBeEqualToString('test("object-position: bottom 20px right 12px;")', 'right 12px bottom 20px'); shouldBeEqualToString('test("object-position: 100px 100px 100px;")', '');
diff --git a/third_party/WebKit/LayoutTests/fast/css/variables/matched-properties-cache-is-disabled.html b/third_party/WebKit/LayoutTests/fast/css/variables/matched-properties-cache-is-disabled.html new file mode 100644 index 0000000..4f85b082 --- /dev/null +++ b/third_party/WebKit/LayoutTests/fast/css/variables/matched-properties-cache-is-disabled.html
@@ -0,0 +1,26 @@ +<!DOCTYPE html> +<script src="../../../resources/testharness.js"></script> +<script src="../../../resources/testharnessreport.js"></script> +<style> +header { + --x: black; +} + +main { + --x: green; +} + +button { + background: var(--x); +} +</style> + +<header><button id='a'></button></header> +<main><button id='b'></button></header> +<script> +test(function() { + assert_equals(getComputedStyle(a).backgroundColor, 'rgb(0, 0, 0)'); + assert_equals(getComputedStyle(b).backgroundColor, 'rgb(0, 128, 0)'); +}, "uninherited properties don't reuse values when set to variables."); + +</script>
diff --git a/third_party/WebKit/LayoutTests/fast/dom/HTMLLinkElement/link-preload-validity-expected.txt b/third_party/WebKit/LayoutTests/fast/dom/HTMLLinkElement/link-preload-validity-expected.txt index 80eca1b..e0f262e 100644 --- a/third_party/WebKit/LayoutTests/fast/dom/HTMLLinkElement/link-preload-validity-expected.txt +++ b/third_party/WebKit/LayoutTests/fast/dom/HTMLLinkElement/link-preload-validity-expected.txt
@@ -1,4 +1,4 @@ -CONSOLE WARNING: line 10: <link rel=preload> must have a valid `as` value +CONSOLE DEBUG: line 10: Preload triggered for prefetch.wut.com.test/1.gif CONSOLE WARNING: line 11: <link rel=preload> has an invalid `href` value CONSOLE WARNING: line 12: <link rel=preload> has an invalid `href` value CONSOLE WARNING: line 13: <link rel=preload> has an invalid `href` value
diff --git a/third_party/WebKit/LayoutTests/fast/dom/XMLSerializer.html b/third_party/WebKit/LayoutTests/fast/dom/XMLSerializer.html index 1e274a5..d41cb53 100644 --- a/third_party/WebKit/LayoutTests/fast/dom/XMLSerializer.html +++ b/third_party/WebKit/LayoutTests/fast/dom/XMLSerializer.html
@@ -44,6 +44,10 @@ test(function() { var attr = child2.getAttributeNode('attr'); assert_equals(serializer.serializeToString(attr), 'an attribute'); + + var element = doc.createElement('foo'); + element.setAttribute('attr1', ' abc\ndef\tghi\r'); + assert_equals(serializer.serializeToString(element), '<foo attr1=" abc def	ghi "/>'); }, 'Check Attr serializiation.'); </script> </body>
diff --git a/third_party/WebKit/LayoutTests/fast/files/url-null-expected.txt b/third_party/WebKit/LayoutTests/fast/files/url-null-expected.txt index b55d73a9..681eb428 100644 --- a/third_party/WebKit/LayoutTests/fast/files/url-null-expected.txt +++ b/third_party/WebKit/LayoutTests/fast/files/url-null-expected.txt
@@ -1,9 +1,11 @@ -Test URL methods with null arguments. +Test URL methods with null and undefined arguments. On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE". -PASS URL.createObjectURL(null) is null -URL.revokeObjectURL(null) +PASS URL.createObjectURL(null) threw exception TypeError: Failed to execute 'createObjectURL' on 'URL': No function was found that matched the signature provided.. +PASS URL.createObjectURL(undefined) threw exception TypeError: Failed to execute 'createObjectURL' on 'URL': No function was found that matched the signature provided.. +PASS URL.revokeObjectURL(null) did not throw exception. +PASS URL.revokeObjectURL(undefined) did not throw exception. PASS successfullyParsed is true TEST COMPLETE
diff --git a/third_party/WebKit/LayoutTests/fast/files/url-null.html b/third_party/WebKit/LayoutTests/fast/files/url-null.html index 744a833..95dd3e06 100644 --- a/third_party/WebKit/LayoutTests/fast/files/url-null.html +++ b/third_party/WebKit/LayoutTests/fast/files/url-null.html
@@ -7,10 +7,12 @@ <div id="description"></div> <div id="console"></div> <script> -description("Test URL methods with null arguments."); +description("Test URL methods with null and undefined arguments."); -shouldBe("URL.createObjectURL(null)", "null"); -evalAndLog("URL.revokeObjectURL(null)"); +shouldThrow("URL.createObjectURL(null)"); +shouldThrow("URL.createObjectURL(undefined)"); +shouldNotThrow("URL.revokeObjectURL(null)"); +shouldNotThrow("URL.revokeObjectURL(undefined)"); var successfullyParsed = true; </script>
diff --git a/third_party/WebKit/LayoutTests/fast/forms/select/option-defaultselected-expected.txt b/third_party/WebKit/LayoutTests/fast/forms/select/option-defaultselected-expected.txt index b9fd965..c24bb4b 100644 --- a/third_party/WebKit/LayoutTests/fast/forms/select/option-defaultselected-expected.txt +++ b/third_party/WebKit/LayoutTests/fast/forms/select/option-defaultselected-expected.txt
@@ -13,7 +13,7 @@ PASS selectionMap(select1) is "100" PASS select1[2].defaultSelected = true; selectionMap(select1) is "001" PASS select1[1].defaultSelected = true; selectionMap(select1) is "010" -PASS select1[1].defaultSelected = false; selectionMap(select1) is "010" +PASS select1[1].defaultSelected = false; selectionMap(select1) is "100" PASS select1[2].selected = true; selectionMap(select1) is "001" PASS successfullyParsed is true
diff --git a/third_party/WebKit/LayoutTests/fast/forms/select/option-defaultselected.html b/third_party/WebKit/LayoutTests/fast/forms/select/option-defaultselected.html index 4557bbc..91f72a32 100644 --- a/third_party/WebKit/LayoutTests/fast/forms/select/option-defaultselected.html +++ b/third_party/WebKit/LayoutTests/fast/forms/select/option-defaultselected.html
@@ -27,7 +27,7 @@ shouldBeEqualToString('select1[2].defaultSelected = true; selectionMap(select1)', '001'); shouldBeEqualToString('select1[1].defaultSelected = true; selectionMap(select1)', '010'); -shouldBeEqualToString('select1[1].defaultSelected = false; selectionMap(select1)', '010'); +shouldBeEqualToString('select1[1].defaultSelected = false; selectionMap(select1)', '100'); shouldBeEqualToString('select1[2].selected = true; selectionMap(select1)', '001'); </script> </body>
diff --git a/third_party/WebKit/LayoutTests/fast/input/placeholder-wrongly-placed-if-too-tall-expected.txt b/third_party/WebKit/LayoutTests/fast/input/placeholder-wrongly-placed-if-too-tall-expected.txt new file mode 100644 index 0000000..43431cf --- /dev/null +++ b/third_party/WebKit/LayoutTests/fast/input/placeholder-wrongly-placed-if-too-tall-expected.txt
@@ -0,0 +1,7 @@ +Both inputs should be of the same size and the placeholder should be at the same place. +PASS rect0.top is rect1.top +PASS rect0.height is rect1.height +PASS successfullyParsed is true + +TEST COMPLETE +
diff --git a/third_party/WebKit/LayoutTests/fast/input/placeholder-wrongly-placed-if-too-tall.html b/third_party/WebKit/LayoutTests/fast/input/placeholder-wrongly-placed-if-too-tall.html new file mode 100644 index 0000000..523f5691 --- /dev/null +++ b/third_party/WebKit/LayoutTests/fast/input/placeholder-wrongly-placed-if-too-tall.html
@@ -0,0 +1,35 @@ +<!DOCTYPE html> +<style> +input { + height: 26px; + line-height: 29px; + padding: 0 5px; + border: none; + border-bottom: 1px solid #888; + outline: none; +} +</style> +<div>Both inputs should be of the same size and the placeholder should be at the same place.</div> +<div id="console"></div> +<input type="text" placeholder="placeholder"> +<input type="text" placeholder="placeholder"> +<script> +window.jsTestIsAsync = true; + +var inputs = document.getElementsByTagName("input"); + +function checkInputs() +{ + rect0 = inputs[0].getBoundingClientRect(); + rect1 = inputs[1].getBoundingClientRect(); + shouldBe("rect0.top", "rect1.top"); + shouldBe("rect0.height", "rect1.height"); + + finishJSTest(); +} + +inputs[1].focus(); +// Forcing a layout in this frame makes the issue disappear. +window.requestAnimationFrame(checkInputs); +</script> +<script src="../../resources/js-test.js"></script>
diff --git a/third_party/WebKit/LayoutTests/fast/media/mq-width-on-zoom-expected.txt b/third_party/WebKit/LayoutTests/fast/media/mq-width-on-zoom-expected.txt index 080182be..43809869 100644 --- a/third_party/WebKit/LayoutTests/fast/media/mq-width-on-zoom-expected.txt +++ b/third_party/WebKit/LayoutTests/fast/media/mq-width-on-zoom-expected.txt
@@ -1,18 +1,33 @@ -PASS window.matchMedia('(width: 960px)').matches is true -PASS window.matchMedia('(width: 1152px)').matches is true -PASS window.matchMedia('(width: 1382px)').matches is true -PASS window.matchMedia('(width: 1658px)').matches is true -PASS window.matchMedia('(width: 1990px)').matches is true -PASS window.matchMedia('(width: 1658px)').matches is true -PASS window.matchMedia('(width: 1382px)').matches is true -PASS window.matchMedia('(width: 1152px)').matches is true -PASS window.matchMedia('(width: 960px)').matches is true -PASS window.matchMedia('(width: 800px)').matches is true -PASS window.matchMedia('(width: 667px)').matches is true -PASS window.matchMedia('(width: 555px)').matches is true -PASS window.matchMedia('(width: 463px)').matches is true -PASS window.matchMedia('(width: 386px)').matches is true -PASS window.matchMedia('(width: 321px)').matches is true +PASS window.matchMedia('(min-width: 959px)').matches is true +PASS window.matchMedia('(max-width: 961px)').matches is true +PASS window.matchMedia('(min-width: 1151px)').matches is true +PASS window.matchMedia('(max-width: 1153px)').matches is true +PASS window.matchMedia('(min-width: 1381px)').matches is true +PASS window.matchMedia('(max-width: 1383px)').matches is true +PASS window.matchMedia('(min-width: 1657px)').matches is true +PASS window.matchMedia('(max-width: 1659px)').matches is true +PASS window.matchMedia('(min-width: 1989px)').matches is true +PASS window.matchMedia('(max-width: 1991px)').matches is true +PASS window.matchMedia('(min-width: 1657px)').matches is true +PASS window.matchMedia('(max-width: 1659px)').matches is true +PASS window.matchMedia('(min-width: 1381px)').matches is true +PASS window.matchMedia('(max-width: 1383px)').matches is true +PASS window.matchMedia('(min-width: 1151px)').matches is true +PASS window.matchMedia('(max-width: 1153px)').matches is true +PASS window.matchMedia('(min-width: 959px)').matches is true +PASS window.matchMedia('(max-width: 961px)').matches is true +PASS window.matchMedia('(min-width: 799px)').matches is true +PASS window.matchMedia('(max-width: 801px)').matches is true +PASS window.matchMedia('(min-width: 666px)').matches is true +PASS window.matchMedia('(max-width: 668px)').matches is true +PASS window.matchMedia('(min-width: 554px)').matches is true +PASS window.matchMedia('(max-width: 556px)').matches is true +PASS window.matchMedia('(min-width: 462px)').matches is true +PASS window.matchMedia('(max-width: 464px)').matches is true +PASS window.matchMedia('(min-width: 385px)').matches is true +PASS window.matchMedia('(max-width: 387px)').matches is true +PASS window.matchMedia('(min-width: 320px)').matches is true +PASS window.matchMedia('(max-width: 322px)').matches is true PASS successfullyParsed is true TEST COMPLETE
diff --git a/third_party/WebKit/LayoutTests/fast/media/mq-width-on-zoom.html b/third_party/WebKit/LayoutTests/fast/media/mq-width-on-zoom.html index 6456ca5a..ad4f5e1 100644 --- a/third_party/WebKit/LayoutTests/fast/media/mq-width-on-zoom.html +++ b/third_party/WebKit/LayoutTests/fast/media/mq-width-on-zoom.html
@@ -11,24 +11,11 @@ // eventSender.zoomPageOut/In zooms with a fixed factor of 1.2 instead // of the zoom levels of the actual browser. - function printMatch(match) { - return (match > 0) ? "matches " + match + "px." : "doesn't match tested values."; - } - function test() { - shouldBeTrue("window.matchMedia('(width: " + window.innerWidth + "px)').matches"); - if (window.matchMedia("(width: " + window.innerWidth + "px)").matches) - return; - - var matches = 0 - for (var j = 0; j < window.innerWidth + 100; j++) { - if (window.matchMedia("(width: " + j + "px)").matches) { - matches = j; - break; - } - } - - debug("window.innerWidth is " + window.innerWidth + "px, but width MQ feature " + printMatch(j)); + var minWidth = window.innerWidth - 1; + var maxWidth = window.innerWidth + 1; + shouldBeTrue("window.matchMedia('(min-width: " + minWidth + "px)').matches"); + shouldBeTrue("window.matchMedia('(max-width: " + maxWidth + "px)').matches"); } if (window.eventSender) {
diff --git a/third_party/WebKit/LayoutTests/fast/mediastream/RTCPeerConnection-createOffer-expected.txt b/third_party/WebKit/LayoutTests/fast/mediastream/RTCPeerConnection-createOffer-expected.txt index 84dc3a14..5fac49e 100644 --- a/third_party/WebKit/LayoutTests/fast/mediastream/RTCPeerConnection-createOffer-expected.txt +++ b/third_party/WebKit/LayoutTests/fast/mediastream/RTCPeerConnection-createOffer-expected.txt
@@ -7,6 +7,11 @@ PASS sessionDescription.type is "offer" PASS requestFailed was called. PASS errorReason is "TEST_ERROR" +PASS pc.createOffer(dummy, dummy); did not throw exception. +PASS pc.createOffer(dummy, dummy, {}); did not throw exception. +PASS pc.createOffer(dummy, dummy, {voiceActivityDetection:false}); did not throw exception. +PASS pc.createOffer(dummy, dummy, {iceRestart:true}); did not throw exception. +PASS pc.createOffer(dummy, dummy, {voiceActivityDetection:false, iceRestart:true}); did not throw exception. PASS pc.createOffer(dummy, dummy, {offerToReceiveVideo:-1, offerToReceiveAudio:0}); threw exception TypeError: Failed to execute 'createOffer' on 'RTCPeerConnection': Invalid offerToReceiveVideo. PASS pc.createOffer(dummy, dummy, {offerToReceiveVideo:0, offerToReceiveAudio:-1}); threw exception TypeError: Failed to execute 'createOffer' on 'RTCPeerConnection': Invalid offerToReceiveAudio. PASS pc.createOffer(dummy, dummy, {offerToReceiveVideo:1, offerToReceiveAudio:0, voiceActivityDetection:false, iceRestart:true}); did not throw exception.
diff --git a/third_party/WebKit/LayoutTests/fast/mediastream/RTCPeerConnection-createOffer.html b/third_party/WebKit/LayoutTests/fast/mediastream/RTCPeerConnection-createOffer.html index 55e310e9..38258b1 100644 --- a/third_party/WebKit/LayoutTests/fast/mediastream/RTCPeerConnection-createOffer.html +++ b/third_party/WebKit/LayoutTests/fast/mediastream/RTCPeerConnection-createOffer.html
@@ -7,6 +7,10 @@ <script> description("Tests RTCPeerConnection createOffer."); +// Note: createOffer() calls in the test runner are successful if the +// voiceActivityDetection and iceRestart options are passed with a value of true. +// In all other cases, createOffer() fails in the test runner. + var pc = null; function dummy() {} @@ -18,6 +22,13 @@ errorReason = reason; shouldBe('errorReason', '"TEST_ERROR"'); + shouldNotThrow("pc.createOffer(dummy, dummy);"); + shouldNotThrow("pc.createOffer(dummy, dummy, {});"); + shouldNotThrow("pc.createOffer(dummy, dummy, {voiceActivityDetection:false});"); + shouldNotThrow("pc.createOffer(dummy, dummy, {iceRestart:true});"); + shouldNotThrow("pc.createOffer(dummy, dummy, {voiceActivityDetection:false, iceRestart:true});"); + + // Deprecated. shouldThrow("pc.createOffer(dummy, dummy, {offerToReceiveVideo:-1, offerToReceiveAudio:0});"); shouldThrow("pc.createOffer(dummy, dummy, {offerToReceiveVideo:0, offerToReceiveAudio:-1});"); shouldNotThrow("pc.createOffer(dummy, dummy, {offerToReceiveVideo:1, offerToReceiveAudio:0, voiceActivityDetection:false, iceRestart:true});"); @@ -44,11 +55,11 @@ sessionDescription = sd; shouldBe('sessionDescription.type', '"offer"'); - pc.createOffer(requestSucceeded2, requestFailed2, {mandatory:{"succeed":false}}); + pc.createOffer(requestSucceeded2, requestFailed2); } -pc = new webkitRTCPeerConnection(null, null); -pc.createOffer(requestSucceeded1, requestFailed1, {mandatory:{"succeed":true}}); +pc = new webkitRTCPeerConnection(null); +pc.createOffer(requestSucceeded1, requestFailed1, {voiceActivityDetection:true, iceRestart:true}); window.jsTestIsAsync = true; window.successfullyParsed = true;
diff --git a/third_party/WebKit/LayoutTests/fast/mediastream/RTCPeerConnection-expected.txt b/third_party/WebKit/LayoutTests/fast/mediastream/RTCPeerConnection-expected.txt index 123515ea..e5b6598b8 100644 --- a/third_party/WebKit/LayoutTests/fast/mediastream/RTCPeerConnection-expected.txt +++ b/third_party/WebKit/LayoutTests/fast/mediastream/RTCPeerConnection-expected.txt
@@ -4,35 +4,32 @@ PASS new webkitRTCPeerConnection(null); did not throw exception. -PASS new webkitRTCPeerConnection(null, null); did not throw exception. PASS new webkitRTCPeerConnection(undefined); did not throw exception. -PASS new webkitRTCPeerConnection(undefined, undefined); did not throw exception. PASS new webkitRTCPeerConnection(); threw exception TypeError: Failed to construct 'RTCPeerConnection': 1 argument required, but only 0 present.. PASS new webkitRTCPeerConnection(''); threw exception TypeError: Failed to construct 'RTCPeerConnection': parameter 1 ('rtcConfiguration') is not an object.. -PASS new webkitRTCPeerConnection(null, ''); threw exception TypeError: Failed to construct 'RTCPeerConnection': parameter 2 ('mediaConstraints') is not an object.. -PASS new webkitRTCPeerConnection({iceServers:[]}, null); did not throw exception. -PASS new webkitRTCPeerConnection({iceServers:[{url:'stun:foo.com'}]}, null); did not throw exception. -PASS new webkitRTCPeerConnection({iceServers:[{url:'turn:foo.com', credential:'x'}]}, null); did not throw exception. -PASS new webkitRTCPeerConnection({iceServers:[{url:'turn:foo.com', credential:'x'},{url:'stun:bar.com'}]}, null); did not throw exception. -PASS new webkitRTCPeerConnection({iceServers:[{urls:'stun:foo.com'}]}, null); did not throw exception. -PASS new webkitRTCPeerConnection({iceServers:[{urls:['stun:foo.com', 'turn:foo.com']}]}, null); did not throw exception. -PASS new webkitRTCPeerConnection({fooServers:[]}, null); threw exception TypeError: Failed to construct 'RTCPeerConnection': Malformed RTCConfiguration. -PASS new webkitRTCPeerConnection({iceServers:true}, null); threw exception TypeError: Failed to construct 'RTCPeerConnection': Malformed RTCConfiguration. -PASS new webkitRTCPeerConnection({iceServers:[1, 2, 3]}, null); threw exception TypeError: Failed to construct 'RTCPeerConnection': Malformed RTCIceServer. -PASS new webkitRTCPeerConnection({iceServers:[{}]}, null); threw exception TypeError: Failed to construct 'RTCPeerConnection': Malformed RTCIceServer. -PASS new webkitRTCPeerConnection({iceServers:[{url:'foo'}]}, null); threw exception TypeError: Failed to construct 'RTCPeerConnection': Malformed URL. -PASS new webkitRTCPeerConnection({iceServers:[{urls:[1, 'turn:foo.com']}]}, null); threw exception TypeError: Failed to construct 'RTCPeerConnection': Malformed URL. -PASS new webkitRTCPeerConnection({iceServers:[], iceTransports:'none'}, null); did not throw exception. -PASS new webkitRTCPeerConnection({iceServers:[], iceTransports:'relay'}, null); did not throw exception. -PASS new webkitRTCPeerConnection({iceServers:[], iceTransports:'all'}, null); did not throw exception. -PASS new webkitRTCPeerConnection({iceServers:[], iceTransports:'foo'}, null); threw exception TypeError: Failed to construct 'RTCPeerConnection': Malformed RTCIceTransports. -PASS new webkitRTCPeerConnection({iceServers:[], bundlePolicy:'balanced'}, null); did not throw exception. -PASS new webkitRTCPeerConnection({iceServers:[], bundlePolicy:'max-bundle'}, null); did not throw exception. -PASS new webkitRTCPeerConnection({iceServers:[], bundlePolicy:'max-compat'}, null); did not throw exception. -PASS new webkitRTCPeerConnection({iceServers:[], bundlePolicy:'foo'}, null); threw exception TypeError: Failed to construct 'RTCPeerConnection': Malformed RTCBundlePolicy. -PASS new webkitRTCPeerConnection({iceServers:[], rtcpMuxPolicy:'negotiate'}, null); did not throw exception. -PASS new webkitRTCPeerConnection({iceServers:[], rtcpMuxPolicy:'require'}, null); did not throw exception. -PASS new webkitRTCPeerConnection({iceServers:[], rtcpMuxPolicy:'foo'}, null); threw exception TypeError: Failed to construct 'RTCPeerConnection': Malformed RTCRtcpMuxPolicy. +PASS new webkitRTCPeerConnection({iceServers:[]}); did not throw exception. +PASS new webkitRTCPeerConnection({iceServers:[{url:'stun:foo.com'}]}); did not throw exception. +PASS new webkitRTCPeerConnection({iceServers:[{url:'turn:foo.com', credential:'x'}]}); did not throw exception. +PASS new webkitRTCPeerConnection({iceServers:[{url:'turn:foo.com', credential:'x'},{url:'stun:bar.com'}]}); did not throw exception. +PASS new webkitRTCPeerConnection({iceServers:[{urls:'stun:foo.com'}]}); did not throw exception. +PASS new webkitRTCPeerConnection({iceServers:[{urls:['stun:foo.com', 'turn:foo.com']}]}); did not throw exception. +PASS new webkitRTCPeerConnection({fooServers:[]}); threw exception TypeError: Failed to construct 'RTCPeerConnection': Malformed RTCConfiguration. +PASS new webkitRTCPeerConnection({iceServers:true}); threw exception TypeError: Failed to construct 'RTCPeerConnection': Malformed RTCConfiguration. +PASS new webkitRTCPeerConnection({iceServers:[1, 2, 3]}); threw exception TypeError: Failed to construct 'RTCPeerConnection': Malformed RTCIceServer. +PASS new webkitRTCPeerConnection({iceServers:[{}]}); threw exception TypeError: Failed to construct 'RTCPeerConnection': Malformed RTCIceServer. +PASS new webkitRTCPeerConnection({iceServers:[{url:'foo'}]}); threw exception TypeError: Failed to construct 'RTCPeerConnection': Malformed URL. +PASS new webkitRTCPeerConnection({iceServers:[{urls:[1, 'turn:foo.com']}]}); threw exception TypeError: Failed to construct 'RTCPeerConnection': Malformed URL. +PASS new webkitRTCPeerConnection({iceServers:[], iceTransports:'none'}); did not throw exception. +PASS new webkitRTCPeerConnection({iceServers:[], iceTransports:'relay'}); did not throw exception. +PASS new webkitRTCPeerConnection({iceServers:[], iceTransports:'all'}); did not throw exception. +PASS new webkitRTCPeerConnection({iceServers:[], iceTransports:'foo'}); threw exception TypeError: Failed to construct 'RTCPeerConnection': Malformed RTCIceTransports. +PASS new webkitRTCPeerConnection({iceServers:[], bundlePolicy:'balanced'}); did not throw exception. +PASS new webkitRTCPeerConnection({iceServers:[], bundlePolicy:'max-bundle'}); did not throw exception. +PASS new webkitRTCPeerConnection({iceServers:[], bundlePolicy:'max-compat'}); did not throw exception. +PASS new webkitRTCPeerConnection({iceServers:[], bundlePolicy:'foo'}); threw exception TypeError: Failed to construct 'RTCPeerConnection': Malformed RTCBundlePolicy. +PASS new webkitRTCPeerConnection({iceServers:[], rtcpMuxPolicy:'negotiate'}); did not throw exception. +PASS new webkitRTCPeerConnection({iceServers:[], rtcpMuxPolicy:'require'}); did not throw exception. +PASS new webkitRTCPeerConnection({iceServers:[], rtcpMuxPolicy:'foo'}); threw exception TypeError: Failed to construct 'RTCPeerConnection': Malformed RTCRtcpMuxPolicy. PASS new webkitRTCPeerConnection(null, {mandatory:{valid_and_supported_1:1}}); did not throw exception. PASS new webkitRTCPeerConnection(null, {mandatory:{valid_and_supported_1:1, valid_and_supported_2:1}}); did not throw exception. PASS new webkitRTCPeerConnection(null, {optional:[{valid_and_supported_1:0}]}); did not throw exception. @@ -48,10 +45,10 @@ PASS new webkitRTCPeerConnection(null, {valid_and_supported_1:1}); threw exception TypeError: Failed to construct 'RTCPeerConnection': Malformed constraints object.. PASS new webkitRTCPeerConnection(null, {valid_but_unsupported_1:1}); threw exception TypeError: Failed to construct 'RTCPeerConnection': Malformed constraints object.. PASS new webkitRTCPeerConnection(null, {valid_and_supported_2:1, mandatory:{valid_and_supported_1:1}}); threw exception TypeError: Failed to construct 'RTCPeerConnection': Malformed constraints object.. -PASS new webkitRTCPeerConnection({iceServers:[], certificates:null}, null); did not throw exception. -PASS new webkitRTCPeerConnection({iceServers:[], certificates:[]}, null); did not throw exception. -PASS new webkitRTCPeerConnection({iceServers:[], certificates:[null]}, null); threw exception TypeError: Failed to construct 'RTCPeerConnection': Malformed sequence<RTCCertificate>. -PASS new webkitRTCPeerConnection({iceServers:[], certificates:[1337]}, null); threw exception TypeError: Failed to construct 'RTCPeerConnection': Malformed sequence<RTCCertificate>. +PASS new webkitRTCPeerConnection({iceServers:[], certificates:null}); did not throw exception. +PASS new webkitRTCPeerConnection({iceServers:[], certificates:[]}); did not throw exception. +PASS new webkitRTCPeerConnection({iceServers:[], certificates:[null]}); threw exception TypeError: Failed to construct 'RTCPeerConnection': Malformed sequence<RTCCertificate>. +PASS new webkitRTCPeerConnection({iceServers:[], certificates:[1337]}); threw exception TypeError: Failed to construct 'RTCPeerConnection': Malformed sequence<RTCCertificate>. PASS new webkitRTCPeerConnection({iceServers:[], certificates:[certRSA]}, null); did not throw exception. PASS new webkitRTCPeerConnection({iceServers:[], certificates:[certECDSA]}, null); did not throw exception. PASS successfullyParsed is true
diff --git a/third_party/WebKit/LayoutTests/fast/mediastream/RTCPeerConnection.html b/third_party/WebKit/LayoutTests/fast/mediastream/RTCPeerConnection.html index 0026c14..13da900 100644 --- a/third_party/WebKit/LayoutTests/fast/mediastream/RTCPeerConnection.html +++ b/third_party/WebKit/LayoutTests/fast/mediastream/RTCPeerConnection.html
@@ -8,41 +8,39 @@ description("Tests the RTCPeerConnection constructor."); shouldNotThrow("new webkitRTCPeerConnection(null);"); -shouldNotThrow("new webkitRTCPeerConnection(null, null);"); shouldNotThrow("new webkitRTCPeerConnection(undefined);"); -shouldNotThrow("new webkitRTCPeerConnection(undefined, undefined);"); shouldThrow("new webkitRTCPeerConnection();"); shouldThrow("new webkitRTCPeerConnection('');"); -shouldThrow("new webkitRTCPeerConnection(null, '');"); -shouldNotThrow("new webkitRTCPeerConnection({iceServers:[]}, null);"); -shouldNotThrow("new webkitRTCPeerConnection({iceServers:[{url:'stun:foo.com'}]}, null);"); -shouldNotThrow("new webkitRTCPeerConnection({iceServers:[{url:'turn:foo.com', credential:'x'}]}, null);"); -shouldNotThrow("new webkitRTCPeerConnection({iceServers:[{url:'turn:foo.com', credential:'x'},{url:'stun:bar.com'}]}, null);"); -shouldNotThrow("new webkitRTCPeerConnection({iceServers:[{urls:'stun:foo.com'}]}, null);"); -shouldNotThrow("new webkitRTCPeerConnection({iceServers:[{urls:['stun:foo.com', 'turn:foo.com']}]}, null);"); +shouldNotThrow("new webkitRTCPeerConnection({iceServers:[]});"); +shouldNotThrow("new webkitRTCPeerConnection({iceServers:[{url:'stun:foo.com'}]});"); +shouldNotThrow("new webkitRTCPeerConnection({iceServers:[{url:'turn:foo.com', credential:'x'}]});"); +shouldNotThrow("new webkitRTCPeerConnection({iceServers:[{url:'turn:foo.com', credential:'x'},{url:'stun:bar.com'}]});"); +shouldNotThrow("new webkitRTCPeerConnection({iceServers:[{urls:'stun:foo.com'}]});"); +shouldNotThrow("new webkitRTCPeerConnection({iceServers:[{urls:['stun:foo.com', 'turn:foo.com']}]});"); -shouldThrow("new webkitRTCPeerConnection({fooServers:[]}, null);"); -shouldThrow("new webkitRTCPeerConnection({iceServers:true}, null);"); -shouldThrow("new webkitRTCPeerConnection({iceServers:[1, 2, 3]}, null);"); -shouldThrow("new webkitRTCPeerConnection({iceServers:[{}]}, null);"); -shouldThrow("new webkitRTCPeerConnection({iceServers:[{url:'foo'}]}, null);"); -shouldThrow("new webkitRTCPeerConnection({iceServers:[{urls:[1, 'turn:foo.com']}]}, null);"); +shouldThrow("new webkitRTCPeerConnection({fooServers:[]});"); +shouldThrow("new webkitRTCPeerConnection({iceServers:true});"); +shouldThrow("new webkitRTCPeerConnection({iceServers:[1, 2, 3]});"); +shouldThrow("new webkitRTCPeerConnection({iceServers:[{}]});"); +shouldThrow("new webkitRTCPeerConnection({iceServers:[{url:'foo'}]});"); +shouldThrow("new webkitRTCPeerConnection({iceServers:[{urls:[1, 'turn:foo.com']}]});"); -shouldNotThrow("new webkitRTCPeerConnection({iceServers:[], iceTransports:'none'}, null);"); -shouldNotThrow("new webkitRTCPeerConnection({iceServers:[], iceTransports:'relay'}, null);"); -shouldNotThrow("new webkitRTCPeerConnection({iceServers:[], iceTransports:'all'}, null);"); -shouldThrow("new webkitRTCPeerConnection({iceServers:[], iceTransports:'foo'}, null);"); +shouldNotThrow("new webkitRTCPeerConnection({iceServers:[], iceTransports:'none'});"); +shouldNotThrow("new webkitRTCPeerConnection({iceServers:[], iceTransports:'relay'});"); +shouldNotThrow("new webkitRTCPeerConnection({iceServers:[], iceTransports:'all'});"); +shouldThrow("new webkitRTCPeerConnection({iceServers:[], iceTransports:'foo'});"); -shouldNotThrow("new webkitRTCPeerConnection({iceServers:[], bundlePolicy:'balanced'}, null);"); -shouldNotThrow("new webkitRTCPeerConnection({iceServers:[], bundlePolicy:'max-bundle'}, null);"); -shouldNotThrow("new webkitRTCPeerConnection({iceServers:[], bundlePolicy:'max-compat'}, null);"); -shouldThrow("new webkitRTCPeerConnection({iceServers:[], bundlePolicy:'foo'}, null);"); +shouldNotThrow("new webkitRTCPeerConnection({iceServers:[], bundlePolicy:'balanced'});"); +shouldNotThrow("new webkitRTCPeerConnection({iceServers:[], bundlePolicy:'max-bundle'});"); +shouldNotThrow("new webkitRTCPeerConnection({iceServers:[], bundlePolicy:'max-compat'});"); +shouldThrow("new webkitRTCPeerConnection({iceServers:[], bundlePolicy:'foo'});"); -shouldNotThrow("new webkitRTCPeerConnection({iceServers:[], rtcpMuxPolicy:'negotiate'}, null);"); -shouldNotThrow("new webkitRTCPeerConnection({iceServers:[], rtcpMuxPolicy:'require'}, null);"); -shouldThrow("new webkitRTCPeerConnection({iceServers:[], rtcpMuxPolicy:'foo'}, null);"); +shouldNotThrow("new webkitRTCPeerConnection({iceServers:[], rtcpMuxPolicy:'negotiate'});"); +shouldNotThrow("new webkitRTCPeerConnection({iceServers:[], rtcpMuxPolicy:'require'});"); +shouldThrow("new webkitRTCPeerConnection({iceServers:[], rtcpMuxPolicy:'foo'});"); +// Deprecated. shouldNotThrow("new webkitRTCPeerConnection(null, {mandatory:{valid_and_supported_1:1}});"); shouldNotThrow("new webkitRTCPeerConnection(null, {mandatory:{valid_and_supported_1:1, valid_and_supported_2:1}});"); shouldNotThrow("new webkitRTCPeerConnection(null, {optional:[{valid_and_supported_1:0}]});"); @@ -60,10 +58,10 @@ shouldThrow("new webkitRTCPeerConnection(null, {valid_and_supported_2:1, mandatory:{valid_and_supported_1:1}});"); // Construct with certificates. -shouldNotThrow("new webkitRTCPeerConnection({iceServers:[], certificates:null}, null);"); -shouldNotThrow("new webkitRTCPeerConnection({iceServers:[], certificates:[]}, null);"); -shouldThrow("new webkitRTCPeerConnection({iceServers:[], certificates:[null]}, null);"); -shouldThrow("new webkitRTCPeerConnection({iceServers:[], certificates:[1337]}, null);"); +shouldNotThrow("new webkitRTCPeerConnection({iceServers:[], certificates:null});"); +shouldNotThrow("new webkitRTCPeerConnection({iceServers:[], certificates:[]});"); +shouldThrow("new webkitRTCPeerConnection({iceServers:[], certificates:[null]});"); +shouldThrow("new webkitRTCPeerConnection({iceServers:[], certificates:[1337]});"); // Global certificate variables so that the "should..." methods can evaluate them. var certRSA = null; var certECDSA = null;
diff --git a/third_party/WebKit/LayoutTests/fast/multicol/span/in-nested-multicol-with-hard-breaks-expected.html b/third_party/WebKit/LayoutTests/fast/multicol/span/in-nested-multicol-with-hard-breaks-expected.html new file mode 100644 index 0000000..33f4c7c --- /dev/null +++ b/third_party/WebKit/LayoutTests/fast/multicol/span/in-nested-multicol-with-hard-breaks-expected.html
@@ -0,0 +1,4 @@ +<!DOCTYPE html> +<p>Test that forced outer fragmentainer breaks work inside spanners in nested multicol.</p> +<p>There should be a blue square below.</p> +<div style="width:60px; height:60px; background:blue;"></div>
diff --git a/third_party/WebKit/LayoutTests/fast/multicol/span/in-nested-multicol-with-hard-breaks.html b/third_party/WebKit/LayoutTests/fast/multicol/span/in-nested-multicol-with-hard-breaks.html new file mode 100644 index 0000000..fe8f9ed --- /dev/null +++ b/third_party/WebKit/LayoutTests/fast/multicol/span/in-nested-multicol-with-hard-breaks.html
@@ -0,0 +1,24 @@ +<!DOCTYPE html> +<style> + .breakAfter { -webkit-column-break-after:always; } + .breakBefore { -webkit-column-break-before:always; } + .piece { background:blue; } +</style> +<p>Test that forced outer fragmentainer breaks work inside spanners in nested multicol.</p> +<p>There should be a blue square below.</p> +<div style="-webkit-columns:4; -webkit-column-gap:0; column-fill:auto; width:60px; line-height:30px; height:135px; overflow:hidden;"> + <div style="-webkit-columns:2; -webkit-column-gap:0;"> + <div style="-webkit-column-span:all;"> + <div class="piece breakBefore"><br></div> + <div class="piece breakAfter"><br></div> + <div class="piece"><br></div> + <div class="piece"><br></div> + <div class="piece breakBefore"><br></div> + <div class="piece"><br></div> + <br> + <br> + <div class="piece breakBefore"><br></div> + <div class="piece breakAfter"><br></div> + </div> + </div> +</div>
diff --git a/third_party/WebKit/LayoutTests/fast/multicol/span/in-nested-multicol-with-soft-breaks-inside-expected.html b/third_party/WebKit/LayoutTests/fast/multicol/span/in-nested-multicol-with-soft-breaks-inside-expected.html new file mode 100644 index 0000000..a77955b2 --- /dev/null +++ b/third_party/WebKit/LayoutTests/fast/multicol/span/in-nested-multicol-with-soft-breaks-inside-expected.html
@@ -0,0 +1,30 @@ +<!DOCTYPE html> +<style> + .line { clear:both; } + .fakeColumn { float:left; width:1em; } + .fakeSpan { float:left; width:2em; } + .first { color:green; } + .second { color:blue; } +</style> +<p>Test that a column-span:all in an inner multicol container breaks nicely within the outer + multicol container.</p> +<p>There should be two lines with letters below, with large letter spacing. The first line should + have green letters. The second line should have blue letters.</p> +<div style="font:16px/30px monospace;"> + <div class="line first"> + <div class="fakeColumn">C</div> + <div class="fakeColumn">A</div> + <div class="fakeSpan">N</div> + <div class="fakeSpan">I</div> + <div class="fakeColumn">B</div> + <div class="fakeColumn">E</div> + </div> + <div class="line second"> + <div class="fakeSpan">M</div> + <div class="fakeSpan">R</div> + <div class="fakeColumn">B</div> + <div class="fakeColumn">E</div> + <div class="fakeColumn">E</div> + <div class="fakeColumn">R</div> + </div> +</div>
diff --git a/third_party/WebKit/LayoutTests/fast/multicol/span/in-nested-multicol-with-soft-breaks-inside.html b/third_party/WebKit/LayoutTests/fast/multicol/span/in-nested-multicol-with-soft-breaks-inside.html new file mode 100644 index 0000000..8886efd --- /dev/null +++ b/third_party/WebKit/LayoutTests/fast/multicol/span/in-nested-multicol-with-soft-breaks-inside.html
@@ -0,0 +1,27 @@ +<!DOCTYPE html> +<style> + .first { color:green; } + .second { color:blue; } +</style> +<p>Test that a column-span:all in an inner multicol container breaks nicely within the outer + multicol container.</p> +<p>There should be two lines with letters below, with large letter spacing. The first line should + have green letters. The second line should have blue letters.</p> +<div style="-webkit-columns:4; -webkit-column-gap:0; column-fill:auto; width:8em; height:70px; font:16px/30px monospace;"> + <div style="-webkit-columns:2; -webkit-column-gap:0;"> + <span class="first">C<br></span> + <span class="first">A<br></span> + <div style="-webkit-column-span:all;"> + <span class="second">M<br></span> + <span class="first">N<br></span> + <span class="second">R<br></span> + <span class="first">I<br></span> + </div> + <span class="second">B<br></span> + <span class="second">E<br></span> + <span class="first">B<br></span> + <span class="second">E<br></span> + <span class="first">E<br></span> + <span class="second">R<br></span> + </div> +</div>
diff --git a/third_party/WebKit/LayoutTests/http/tests/inspector/compiler-script-mapping-expected.txt b/third_party/WebKit/LayoutTests/http/tests/inspector/compiler-script-mapping-expected.txt index 6b5d734..899732c 100644 --- a/third_party/WebKit/LayoutTests/http/tests/inspector/compiler-script-mapping-expected.txt +++ b/third_party/WebKit/LayoutTests/http/tests/inspector/compiler-script-mapping-expected.txt
@@ -147,3 +147,9 @@ 0 === 0 0 === 0 +Running: testNameClash +example.js === example.js [sm] +0 === 0 +9 === 9 +source line 0 has no mappings. +
diff --git a/third_party/WebKit/LayoutTests/http/tests/inspector/compiler-script-mapping.html b/third_party/WebKit/LayoutTests/http/tests/inspector/compiler-script-mapping.html index 71999c1f..841bdc6 100644 --- a/third_party/WebKit/LayoutTests/http/tests/inspector/compiler-script-mapping.html +++ b/third_party/WebKit/LayoutTests/http/tests/inspector/compiler-script-mapping.html
@@ -87,7 +87,7 @@ "mappings":"AAASA,QAAAA,IAAG,CAACC,CAAD,CAAaC,CAAb,CACZ,CACI,MAAOD,EAAP,CAAoBC,CADxB,CAIA,IAAIC,OAAS;A", "sources":["example.js"] }; - var mapping = new WebInspector.SourceMap("source-map.json", mappingPayload); + var mapping = new WebInspector.SourceMap("compiled.js", "source-map.json", mappingPayload); checkMapping(0, 9, "example.js", 0, 9, mapping); checkMapping(0, 13, "example.js", 0, 13, mapping); @@ -112,7 +112,7 @@ "mappings":"AAAA,C,CAAE;", "sources":["example.js"] }; - var mapping = new WebInspector.SourceMap("source-map.json", mappingPayload); + var mapping = new WebInspector.SourceMap("compiled.js", "source-map.json", mappingPayload); checkMapping(0, 0, "example.js", 0, 0, mapping); var entry = mapping.findEntry(0, 1); InspectorTest.assertTrue(!entry.sourceURL); @@ -126,7 +126,7 @@ "mappings":"AAAA;;;CACA", "sources":["example.js"] }; - var mapping = new WebInspector.SourceMap("source-map.json", mappingPayload); + var mapping = new WebInspector.SourceMap("compiled.js", "source-map.json", mappingPayload); checkMapping(0, 0, "example.js", 0, 0, mapping); checkReverseMapping(3, 1, "example.js", 1, mapping); next(); @@ -149,7 +149,7 @@ } } ]}; - var mapping = new WebInspector.SourceMap("source-map.json", mappingPayload); + var mapping = new WebInspector.SourceMap("compiled.js", "source-map.json", mappingPayload); InspectorTest.assertEquals(2, mapping.sources().length); checkMapping(0, 0, "source1.js", 0, 0, mapping); checkMapping(0, 1, "source1.js", 2, 1, mapping); @@ -458,11 +458,24 @@ "sources":["example.js"], "sourceRoot":"/" }; - var mapping = new WebInspector.SourceMap("source-map.json", mappingPayload); + var mapping = new WebInspector.SourceMap("compiled.js", "source-map.json", mappingPayload); checkMapping(0, 9, "/example.js", 0, 9, mapping); checkReverseMapping(0, 0, "/example.js", 0, mapping); next(); }, + + function testNameClash(next) + { + var mappingPayload = { + "mappings":"AAASA,QAAAA,IAAG,CAACC,CAAD,CAAaC,CAAb,CACZ,CACI,MAAOD,EAAP,CAAoBC,CADxB,CAIA,IAAIC,OAAS;", + "sources":["example.js"], + "sourcesContent":["var i = 0;"] + }; + var mapping = new WebInspector.SourceMap("example.js", "source-map.json",mappingPayload); + checkMapping(0, 9, "example.js", 0, 9, mapping); + checkReverseMapping(0, 0, "example.js", 0, mapping); + next(); + } ]); };
diff --git a/third_party/WebKit/LayoutTests/http/tests/inspector/debugger-test.js b/third_party/WebKit/LayoutTests/http/tests/inspector/debugger-test.js index 5cca2aa8..b2992a5 100644 --- a/third_party/WebKit/LayoutTests/http/tests/inspector/debugger-test.js +++ b/third_party/WebKit/LayoutTests/http/tests/inspector/debugger-test.js
@@ -373,7 +373,7 @@ function dumpNavigatorTreeElement(prefix, treeElement) { - InspectorTest.addResult(prefix + treeElement.titleText); + InspectorTest.addResult(prefix + treeElement.nodeTitle()); var children = treeElement.children(); for (var i = 0; i < children.length; ++i) dumpNavigatorTreeElement(prefix + " ", children[i]);
diff --git a/third_party/WebKit/LayoutTests/http/tests/inspector/filesystem/request-metadata-expected.txt b/third_party/WebKit/LayoutTests/http/tests/inspector/filesystem/request-metadata-expected.txt deleted file mode 100644 index 28dbfa4..0000000 --- a/third_party/WebKit/LayoutTests/http/tests/inspector/filesystem/request-metadata-expected.txt +++ /dev/null
@@ -1,23 +0,0 @@ -Tests requestMetadata command. - -errorCode: 2 -metadata: (null) - -errorCode: 5 -metadata: (null) - -errorCode: 0 -metadata: - modificationTime: (exists) - size: 4 - -errorCode: 0 -metadata: - modificationTime: (exists) - size: 0 - -errorCode: 1 -metadata: (null) - -All tests have done. -
diff --git a/third_party/WebKit/LayoutTests/http/tests/inspector/filesystem/request-metadata.html b/third_party/WebKit/LayoutTests/http/tests/inspector/filesystem/request-metadata.html deleted file mode 100644 index 95c6385..0000000 --- a/third_party/WebKit/LayoutTests/http/tests/inspector/filesystem/request-metadata.html +++ /dev/null
@@ -1,78 +0,0 @@ -<!DOCTYPE html> -<html> -<head> -<meta charset="UTF-8"> -<script src="../inspector-test.js"></script> -<script src="filesystem-test.js"></script> -<script> -document.addEventListener("DOMContentLoaded", runTest); -function test() -{ - var fileSystemModel = new WebInspector.FileSystemModel(WebInspector.targetManager.mainTarget()); - - var testStep = [ - function() - { - InspectorTest.writeFile("/hoge", "fuga", testStep.shift()); - }, - - function() - { - fileSystemModel.requestMetadata(new InspectorTest.MockEntry("InvalidURL"), testStep.shift()); - }, - - function(errorCode, metadata) - { - InspectorTest.dumpMetadataRequestResult(errorCode, metadata); - fileSystemModel.requestMetadata(new InspectorTest.MockEntry("filesystem:http://127.0.0.1:8000/InvalidType"), testStep.shift()); - }, - - function(errorCode, metadata) - { - InspectorTest.dumpMetadataRequestResult(errorCode, metadata); - fileSystemModel.requestMetadata(new InspectorTest.MockEntry("filesystem:http://127.0.0.1:8000/temporary/hoge"), testStep.shift()); - }, - - function(errorCode, metadata) - { - InspectorTest.dumpMetadataRequestResult(errorCode, metadata); - InspectorTest.createDirectory("/piyo", testStep.shift()); - }, - - function() - { - fileSystemModel.requestMetadata(new InspectorTest.MockEntry("filesystem:http://127.0.0.1:8000/temporary/piyo"), testStep.shift()); - }, - - function(errorCode, metadata) - { - InspectorTest.dumpMetadataRequestResult(errorCode, metadata); - fileSystemModel.requestMetadata(new InspectorTest.MockEntry("filesystem:http://127.0.0.1:8000/temporary/foo"), testStep.shift()); - }, - - function(errorCode, metadata) - { - InspectorTest.dumpMetadataRequestResult(errorCode, metadata); - fileSystemModel.requestMetadata(new InspectorTest.MockEntry("filesystem:http://example.com/temporary/bar"), testStep.shift()); - }, - - function(errorCode) - { - InspectorTest.clearFileSystem(testStep.shift()); - }, - - function() - { - InspectorTest.addResult("All tests have done."); - InspectorTest.completeTest(); - } - ]; - - InspectorTest.clearFileSystem(testStep.shift()); -} -</script> -</head> -<body> -<p>Tests requestMetadata command.</p> -</body> -</html>
diff --git a/third_party/WebKit/LayoutTests/http/tests/plugins/get-url-expected.txt b/third_party/WebKit/LayoutTests/http/tests/plugins/get-url-expected.txt deleted file mode 100644 index 7beb442..0000000 --- a/third_party/WebKit/LayoutTests/http/tests/plugins/get-url-expected.txt +++ /dev/null
@@ -1 +0,0 @@ -This tests that NPN_GetURLNotify works as expected and does not ASSERT intermittently in debug builds.
diff --git a/third_party/WebKit/LayoutTests/http/tests/plugins/get-url-notify-on-removal-expected.txt b/third_party/WebKit/LayoutTests/http/tests/plugins/get-url-notify-on-removal-expected.txt deleted file mode 100644 index 113aa4c..0000000 --- a/third_party/WebKit/LayoutTests/http/tests/plugins/get-url-notify-on-removal-expected.txt +++ /dev/null
@@ -1,4 +0,0 @@ -ALERT: Request completed -This tests that NPP_URLNotify gets called exactly once for canceled streams on plugin removal. -SUCCESS -
diff --git a/third_party/WebKit/LayoutTests/http/tests/plugins/get-url-notify-on-removal.html b/third_party/WebKit/LayoutTests/http/tests/plugins/get-url-notify-on-removal.html deleted file mode 100644 index d2a01bd8..0000000 --- a/third_party/WebKit/LayoutTests/http/tests/plugins/get-url-notify-on-removal.html +++ /dev/null
@@ -1,40 +0,0 @@ -<html> -<body> -This tests that NPP_URLNotify gets called exactly once for canceled streams on plugin removal. -<div id="result">FAILURE</div> -<embed name="plg" type="application/x-webkit-test-netscape"></embed> -<script> - var callbackRun = false; - function callback() - { - if (callbackRun) { - result.textContent = "FAILURE - callback run twice"; - return; - } - - callbackRun = true; - result.textContent = "SUCCESS"; - // Force the plugin to spin a nested event loop. - alert("Request completed"); - // Don't stop the test until a small delay, in case callback is called again. - setTimeout(notify, 50); - } - function notify() - { - if (window.testRunner) - testRunner.notifyDone(); - } - if (window.testRunner) { - testRunner.dumpAsText(); - testRunner.waitUntilDone(); - } - - plg.getURLNotify("resources/slow-resource.pl", null, "callback"); - // Remove the plugin after a short delay (to give the resource time to - // propagate through the system to the browser). - setTimeout(function() { - plg.parentNode.removeChild(plg); - }, 50); -</script> -</body> -</html>
diff --git a/third_party/WebKit/LayoutTests/http/tests/plugins/get-url.html b/third_party/WebKit/LayoutTests/http/tests/plugins/get-url.html deleted file mode 100644 index 7b0e0a28..0000000 --- a/third_party/WebKit/LayoutTests/http/tests/plugins/get-url.html +++ /dev/null
@@ -1,19 +0,0 @@ -<html> -<body> -This tests that NPN_GetURLNotify works as expected and does not ASSERT intermittently in debug builds. -<embed name="plg" type="application/x-webkit-test-netscape"></embed> -<script> - function notify() - { - if (window.testRunner) - testRunner.notifyDone(); - } - if (window.testRunner) { - testRunner.dumpAsText(); - testRunner.waitUntilDone(); - } - - plg.getURLNotify("resources/load-me-1.txt", null, "notify"); -</script> -</body> -</html>
diff --git a/third_party/WebKit/LayoutTests/http/tests/plugins/geturlnotify-from-npp-destroystream-expected.txt b/third_party/WebKit/LayoutTests/http/tests/plugins/geturlnotify-from-npp-destroystream-expected.txt deleted file mode 100644 index 8076e599..0000000 --- a/third_party/WebKit/LayoutTests/http/tests/plugins/geturlnotify-from-npp-destroystream-expected.txt +++ /dev/null
@@ -1,2 +0,0 @@ -This tests that a plugin that calls NPP_GetURLNotify from its NPP_DestroyStream during teardown will not cause a crash. -SUCCESS! Did not crash!
diff --git a/third_party/WebKit/LayoutTests/http/tests/plugins/geturlnotify-from-npp-destroystream.html b/third_party/WebKit/LayoutTests/http/tests/plugins/geturlnotify-from-npp-destroystream.html deleted file mode 100644 index e2f6dc9..0000000 --- a/third_party/WebKit/LayoutTests/http/tests/plugins/geturlnotify-from-npp-destroystream.html +++ /dev/null
@@ -1,27 +0,0 @@ -<html> -<script> -function streamDestroyed() -{ - plg.getURL("data:text/html,Stream data"); -} - -function runTest() { - plg.getURL("/plugins/resources/slow-resource.pl"); - - if (window.testRunner) { - testRunner.dumpAsText(); - testRunner.waitUntilDone(); - } - - var url = 'data:text/html,<scri' + 'pt>if (window.testRunner) testRunner.notifyDone();</scri' + 'pt>'; - url += '<div>This tests that a plugin that calls NPP_GetURLNotify from its NPP_DestroyStream during teardown ' - url += 'will not cause a crash.</div><div>SUCCESS! Did not crash!</div>'; - - setTimeout(function() { window.location.href = url; }, 100); -} - -</script> -<body onload="runTest()"> -<embed name="plg" type="application/x-webkit-test-netscape" onstreamdestroy="streamDestroyed()"></embed> -</body> -</html>
diff --git a/third_party/WebKit/LayoutTests/http/tests/plugins/local-geturl-from-remote-expected.txt b/third_party/WebKit/LayoutTests/http/tests/plugins/local-geturl-from-remote-expected.txt deleted file mode 100644 index 3a3ca13..0000000 --- a/third_party/WebKit/LayoutTests/http/tests/plugins/local-geturl-from-remote-expected.txt +++ /dev/null
@@ -1,4 +0,0 @@ -CONSOLE ERROR: Not allowed to load local resource: tmp.html -This tests that a plugin in a remote document can't access local files using NPN_GetURL - -FAILURE
diff --git a/third_party/WebKit/LayoutTests/http/tests/plugins/local-geturl-from-remote.html b/third_party/WebKit/LayoutTests/http/tests/plugins/local-geturl-from-remote.html deleted file mode 100644 index d90c5f9..0000000 --- a/third_party/WebKit/LayoutTests/http/tests/plugins/local-geturl-from-remote.html +++ /dev/null
@@ -1,36 +0,0 @@ -<html> -<head> -<script> -function notify() -{ - if (window.testRunner) - testRunner.notifyDone(); -} - -function runTest() -{ - if (window.testRunner) { - testRunner.dumpAsText(); - testRunner.waitUntilDone(); - } - - // No need to let this point to a real file. - - - var result = plg.getURL('file:///tmp.html', '_self'); - if (result == 1) - document.getElementById('result').innerHTML = "SUCCESS"; - else - document.getElementById('result').innerHTML = "FAILURE"; - - // Round-trip to the plugin once more, so errors can propagate. - plg.getURLNotify("resources/load-me-1.txt", null, "notify"); -} -</script> -</head> -<body onload="runTest()"> -<div>This tests that a plugin in a remote document can't access local files using NPN_GetURL</div> -<embed name="plg" type="application/x-webkit-test-netscape"></embed> -<div id="result">FAILURE</div> -</body> -</html>
diff --git a/third_party/WebKit/LayoutTests/http/tests/plugins/npapi-response-headers-expected.txt b/third_party/WebKit/LayoutTests/http/tests/plugins/npapi-response-headers-expected.txt deleted file mode 100644 index 27920cc..0000000 --- a/third_party/WebKit/LayoutTests/http/tests/plugins/npapi-response-headers-expected.txt +++ /dev/null
@@ -1,16 +0,0 @@ - -Test for bug 13029: Permit NPAPI plugins to see HTTP response headers. - -Expected result below is two HTTP response extracts, one for the initial stream specified in the "src" attribute, the other for an NPN_GetURLNotify request. Each block should contain the URL; the status line, which should say "HTTP 200 OK"; and the MIME-type, which should say "Content-Type: text/plain". - ----------- - -http://[varies, not being tested]/plugins/resources/load-me-1.txt -HTTP 200 OK -Content-Type: text/plain - ----------- - -http://[varies, not being tested]/plugins/resources/load-me-2.txt -HTTP 200 OK -Content-Type: text/plain
diff --git a/third_party/WebKit/LayoutTests/http/tests/plugins/npapi-response-headers.html b/third_party/WebKit/LayoutTests/http/tests/plugins/npapi-response-headers.html deleted file mode 100644 index 7eb7460b..0000000 --- a/third_party/WebKit/LayoutTests/http/tests/plugins/npapi-response-headers.html +++ /dev/null
@@ -1,108 +0,0 @@ -<html> -<head> -<script> -if (window.testRunner) { - testRunner.dumpAsText(); - testRunner.waitUntilDone(); -} - -loadedFirstURL = false; - -var res1, res2; - -function test() -{ - try { - res1 = document.getElementById("result1"); - res2 = document.getElementById("result2"); - } catch (ex) { - showErr("Exception: " + ex.description); - if (window.testRunner) - testRunner.notifyDone(); - } -} - -function streamLoaded() -{ - if (loadedFirstURL) - return; - - loadedFirstURL = true; - plg.getURLNotify("/plugins/resources/load-me-2.txt", null, "callback"); -} - -function callback(errCode, streamDump) -{ - var parse = parseStreamDump(streamDump); - if (parse.err) - showErr(parse.err); - else { - res1.innerHTML = newlinesToHTML(parse.res1); - res2.innerHTML = newlinesToHTML(parse.res2); - } - - if (window.testRunner) - testRunner.notifyDone(); -} - -// Format passed by plugin: four fields separated by \n\n: -// First URL; first header block; last URL; last header block. -function parseStreamDump(streamDump) -{ - var rtn = {}; - - if (typeof streamDump == "string" || ((typeof streamDump == "object") && (streamDump.constructor == String))) { - var parts = streamDump.split("\n\n"); - if (parts.length >= 4) { - rtn.res1 = genericURL(parts[0]) + "\n" + parseHeaders(parts[1]); - rtn.res2 = genericURL(parts[2]) + "\n" + parseHeaders(parts[3]); - } else - rtn.err = "streamDump from plugin does not have expected format"; - } else - rtn.err = "streamDump from plugin is not a string: " + streamDump; - - return rtn; -} - -function showErr(err) -{ - res1.innerHTML = "FAILED - " + err; - res2.innerHTML = ""; -} - -function newlinesToHTML(str) -{ - return str.replace(/\n/g, "<br>"); -} - -function genericURL(url) -{ - return url.replace(/^(http:\/\/)[^\/]+/, "$1[varies, not being tested]"); -} - -function parseHeaders(hdrs) -{ - var parts = hdrs.split("\n"); - var rtn = parts[0] + "\n"; - - for (var i = 0; i < parts.length; i++) - if (parts[i].match(/^Content-Type:/)) - rtn += parts[i]; - - return rtn; -} -</script> -</head> -<body onload="test()"> -<embed name="plg" type="application/x-webkit-test-netscape" src="/plugins/resources/load-me-1.txt" onstreamload="streamLoaded()"></embed> -<p>Test for <a href="https://bugs.webkit.org/show_bug.cgi?id=13029">bug 13029<a/>: -Permit NPAPI plugins to see HTTP response headers.</p> -<p>Expected result below is two HTTP response extracts, one for the initial stream specified in the "src" -attribute, the other for an NPN_GetURLNotify request. Each block should contain the URL; the status line, -which should say "HTTP 200 OK"; and the MIME-type, which should say "Content-Type: text/plain".</p> -<p>----------</p> -<p id="result1">Running test, result should appear here in a very short time...</p> -<p>----------</p> -<p id="result2">Running test, result should appear here in a very short time...</p> -</body> -</html>
diff --git a/third_party/WebKit/LayoutTests/http/tests/plugins/third-party-cookie-accept-policy-expected.txt b/third_party/WebKit/LayoutTests/http/tests/plugins/third-party-cookie-accept-policy-expected.txt deleted file mode 100644 index 97b5ec85..0000000 --- a/third_party/WebKit/LayoutTests/http/tests/plugins/third-party-cookie-accept-policy-expected.txt +++ /dev/null
@@ -1,6 +0,0 @@ -CONSOLE WARNING: Synchronous XMLHttpRequest on the main thread is deprecated because of its detrimental effects to the end user's experience. For more help, check https://xhr.spec.whatwg.org/. -ALERT: Cookies should be clear, and are: '' -ALERT: About to set a cookie, but on localhost instead of 127.0.0.1, which is our main document domain - This should fail. -ALERT: Cookies should still be clear, and are: '' -This tests that plugins cannot set cookies in violation of the 3rd party cookie policy. -
diff --git a/third_party/WebKit/LayoutTests/http/tests/plugins/third-party-cookie-accept-policy.html b/third_party/WebKit/LayoutTests/http/tests/plugins/third-party-cookie-accept-policy.html deleted file mode 100644 index 89c71fb..0000000 --- a/third_party/WebKit/LayoutTests/http/tests/plugins/third-party-cookie-accept-policy.html +++ /dev/null
@@ -1,18 +0,0 @@ -<html> -<head> -<script src="../cookies/resources/resetCookies.js"></script> -<script> -resetCookies(); - -if (window.testRunner) { - testRunner.dumpAsText(); - testRunner.waitUntilDone(); -} - -</script> -<body> -This tests that plugins cannot set cookies in violation of the 3rd party cookie policy.<br> -<iframe src="http://localhost:8000/plugins/resources/third-party-cookie-accept-policy-iframe.html"></iframe> - -</body> -</html>
diff --git a/third_party/WebKit/LayoutTests/http/tests/security/contentSecurityPolicy/1.1/report-uri-effective-directive-expected.txt b/third_party/WebKit/LayoutTests/http/tests/security/contentSecurityPolicy/1.1/report-uri-effective-directive-expected.txt index 54e537e7..69c4de6 100644 --- a/third_party/WebKit/LayoutTests/http/tests/security/contentSecurityPolicy/1.1/report-uri-effective-directive-expected.txt +++ b/third_party/WebKit/LayoutTests/http/tests/security/contentSecurityPolicy/1.1/report-uri-effective-directive-expected.txt
@@ -5,4 +5,4 @@ HTTP_REFERER: http://127.0.0.1:8000/security/contentSecurityPolicy/1.1/report-uri-effective-directive.html REQUEST_METHOD: POST === POST DATA === -{"csp-report":{"document-uri":"http://127.0.0.1:8000/security/contentSecurityPolicy/1.1/report-uri-effective-directive.html","referrer":"","violated-directive":"default-src 'self'","effective-directive":"script-src","original-policy":"default-src 'self'; report-uri ../resources/save-report.php?test=report-uri-effective-directive.html","blocked-uri":"","status-code":200}} +{"csp-report":{"document-uri":"http://127.0.0.1:8000/security/contentSecurityPolicy/1.1/report-uri-effective-directive.html","referrer":"","violated-directive":"default-src 'self'","effective-directive":"script-src","original-policy":"default-src 'self'; report-uri ../resources/save-report.php?test=report-uri-effective-directive.html","blocked-uri":"inline","status-code":200}}
diff --git a/third_party/WebKit/LayoutTests/http/tests/security/contentSecurityPolicy/eval-allowed-in-report-only-mode-and-sends-report-expected.txt b/third_party/WebKit/LayoutTests/http/tests/security/contentSecurityPolicy/eval-allowed-in-report-only-mode-and-sends-report-expected.txt index 62d866c..7c2dc6e 100644 --- a/third_party/WebKit/LayoutTests/http/tests/security/contentSecurityPolicy/eval-allowed-in-report-only-mode-and-sends-report-expected.txt +++ b/third_party/WebKit/LayoutTests/http/tests/security/contentSecurityPolicy/eval-allowed-in-report-only-mode-and-sends-report-expected.txt
@@ -6,4 +6,4 @@ HTTP_REFERER: http://127.0.0.1:8000/security/contentSecurityPolicy/eval-allowed-in-report-only-mode-and-sends-report.html REQUEST_METHOD: POST === POST DATA === -{"csp-report":{"document-uri":"http://127.0.0.1:8000/security/contentSecurityPolicy/eval-allowed-in-report-only-mode-and-sends-report.html","referrer":"","violated-directive":"script-src 'self' 'unsafe-inline'","effective-directive":"script-src","original-policy":"script-src 'self' 'unsafe-inline'; report-uri resources/save-report.php?test=eval-allowed-in-report-only-mode-and-sends-report.html","blocked-uri":"","source-file":"http://127.0.0.1:8000/security/contentSecurityPolicy/eval-allowed-in-report-only-mode-and-sends-report.html","line-number":13,"column-number":13,"status-code":200}} +{"csp-report":{"document-uri":"http://127.0.0.1:8000/security/contentSecurityPolicy/eval-allowed-in-report-only-mode-and-sends-report.html","referrer":"","violated-directive":"script-src 'self' 'unsafe-inline'","effective-directive":"script-src","original-policy":"script-src 'self' 'unsafe-inline'; report-uri resources/save-report.php?test=eval-allowed-in-report-only-mode-and-sends-report.html","blocked-uri":"eval","source-file":"http://127.0.0.1:8000/security/contentSecurityPolicy/eval-allowed-in-report-only-mode-and-sends-report.html","line-number":13,"column-number":13,"status-code":200}}
diff --git a/third_party/WebKit/LayoutTests/http/tests/security/contentSecurityPolicy/eval-blocked-and-sends-report-expected.txt b/third_party/WebKit/LayoutTests/http/tests/security/contentSecurityPolicy/eval-blocked-and-sends-report-expected.txt index 9f27ba1..8ecb2be 100644 --- a/third_party/WebKit/LayoutTests/http/tests/security/contentSecurityPolicy/eval-blocked-and-sends-report-expected.txt +++ b/third_party/WebKit/LayoutTests/http/tests/security/contentSecurityPolicy/eval-blocked-and-sends-report-expected.txt
@@ -6,4 +6,4 @@ HTTP_REFERER: http://127.0.0.1:8000/security/contentSecurityPolicy/eval-blocked-and-sends-report.html REQUEST_METHOD: POST === POST DATA === -{"csp-report":{"document-uri":"http://127.0.0.1:8000/security/contentSecurityPolicy/eval-blocked-and-sends-report.html","referrer":"","violated-directive":"script-src 'self' 'unsafe-inline'","effective-directive":"script-src","original-policy":"script-src 'self' 'unsafe-inline'; report-uri resources/save-report.php?test=eval-blocked-and-sends-report.html","blocked-uri":"","source-file":"http://127.0.0.1:8000/security/contentSecurityPolicy/eval-blocked-and-sends-report.html","line-number":9,"column-number":13,"status-code":200}} +{"csp-report":{"document-uri":"http://127.0.0.1:8000/security/contentSecurityPolicy/eval-blocked-and-sends-report.html","referrer":"","violated-directive":"script-src 'self' 'unsafe-inline'","effective-directive":"script-src","original-policy":"script-src 'self' 'unsafe-inline'; report-uri resources/save-report.php?test=eval-blocked-and-sends-report.html","blocked-uri":"eval","source-file":"http://127.0.0.1:8000/security/contentSecurityPolicy/eval-blocked-and-sends-report.html","line-number":9,"column-number":13,"status-code":200}}
diff --git a/third_party/WebKit/LayoutTests/http/tests/security/contentSecurityPolicy/report-and-enforce-expected.txt b/third_party/WebKit/LayoutTests/http/tests/security/contentSecurityPolicy/report-and-enforce-expected.txt index a1063a7..7af0548 100644 --- a/third_party/WebKit/LayoutTests/http/tests/security/contentSecurityPolicy/report-and-enforce-expected.txt +++ b/third_party/WebKit/LayoutTests/http/tests/security/contentSecurityPolicy/report-and-enforce-expected.txt
@@ -9,4 +9,4 @@ HTTP_REFERER: http://127.0.0.1:8000/security/contentSecurityPolicy/report-and-enforce.html REQUEST_METHOD: POST === POST DATA === -{"csp-report":{"document-uri":"http://127.0.0.1:8000/security/contentSecurityPolicy/report-and-enforce.html","referrer":"","violated-directive":"script-src 'self'","effective-directive":"script-src","original-policy":"script-src 'self'; report-uri resources/save-report.php?test=report-and-enforce.html","blocked-uri":"","status-code":200}} +{"csp-report":{"document-uri":"http://127.0.0.1:8000/security/contentSecurityPolicy/report-and-enforce.html","referrer":"","violated-directive":"script-src 'self'","effective-directive":"script-src","original-policy":"script-src 'self'; report-uri resources/save-report.php?test=report-and-enforce.html","blocked-uri":"inline","status-code":200}}
diff --git a/third_party/WebKit/LayoutTests/http/tests/security/contentSecurityPolicy/report-only-expected.txt b/third_party/WebKit/LayoutTests/http/tests/security/contentSecurityPolicy/report-only-expected.txt index b27176f..5a3c440f 100644 --- a/third_party/WebKit/LayoutTests/http/tests/security/contentSecurityPolicy/report-only-expected.txt +++ b/third_party/WebKit/LayoutTests/http/tests/security/contentSecurityPolicy/report-only-expected.txt
@@ -7,4 +7,4 @@ HTTP_REFERER: http://127.0.0.1:8000/security/contentSecurityPolicy/report-only.html REQUEST_METHOD: POST === POST DATA === -{"csp-report":{"document-uri":"http://127.0.0.1:8000/security/contentSecurityPolicy/report-only.html","referrer":"","violated-directive":"script-src 'self'","effective-directive":"script-src","original-policy":"script-src 'self'; report-uri resources/save-report.php?test=report-only.html","blocked-uri":"","status-code":200}} +{"csp-report":{"document-uri":"http://127.0.0.1:8000/security/contentSecurityPolicy/report-only.html","referrer":"","violated-directive":"script-src 'self'","effective-directive":"script-src","original-policy":"script-src 'self'; report-uri resources/save-report.php?test=report-only.html","blocked-uri":"inline","status-code":200}}
diff --git a/third_party/WebKit/LayoutTests/http/tests/security/contentSecurityPolicy/report-only-from-header-expected.txt b/third_party/WebKit/LayoutTests/http/tests/security/contentSecurityPolicy/report-only-from-header-expected.txt index 15bd2fb..22fdca9 100644 --- a/third_party/WebKit/LayoutTests/http/tests/security/contentSecurityPolicy/report-only-from-header-expected.txt +++ b/third_party/WebKit/LayoutTests/http/tests/security/contentSecurityPolicy/report-only-from-header-expected.txt
@@ -6,4 +6,4 @@ HTTP_REFERER: http://127.0.0.1:8000/security/contentSecurityPolicy/report-only-from-header.php REQUEST_METHOD: POST === POST DATA === -{"csp-report":{"document-uri":"http://127.0.0.1:8000/security/contentSecurityPolicy/report-only-from-header.php","referrer":"","violated-directive":"script-src 'self'","effective-directive":"script-src","original-policy":"script-src 'self'; report-uri resources/save-report.php?test=report-only-from-header.php","blocked-uri":"","status-code":200}} +{"csp-report":{"document-uri":"http://127.0.0.1:8000/security/contentSecurityPolicy/report-only-from-header.php","referrer":"","violated-directive":"script-src 'self'","effective-directive":"script-src","original-policy":"script-src 'self'; report-uri resources/save-report.php?test=report-only-from-header.php","blocked-uri":"inline","status-code":200}}
diff --git a/third_party/WebKit/LayoutTests/http/tests/security/contentSecurityPolicy/report-uri-expected.txt b/third_party/WebKit/LayoutTests/http/tests/security/contentSecurityPolicy/report-uri-expected.txt index b5c28f34..270c7e3 100644 --- a/third_party/WebKit/LayoutTests/http/tests/security/contentSecurityPolicy/report-uri-expected.txt +++ b/third_party/WebKit/LayoutTests/http/tests/security/contentSecurityPolicy/report-uri-expected.txt
@@ -6,4 +6,4 @@ HTTP_REFERER: http://127.0.0.1:8000/security/contentSecurityPolicy/report-uri.html REQUEST_METHOD: POST === POST DATA === -{"csp-report":{"document-uri":"http://127.0.0.1:8000/security/contentSecurityPolicy/report-uri.html","referrer":"","violated-directive":"script-src 'self'","effective-directive":"script-src","original-policy":"script-src 'self'; report-uri resources/save-report.php?test=report-uri.html","blocked-uri":"","status-code":200}} +{"csp-report":{"document-uri":"http://127.0.0.1:8000/security/contentSecurityPolicy/report-uri.html","referrer":"","violated-directive":"script-src 'self'","effective-directive":"script-src","original-policy":"script-src 'self'; report-uri resources/save-report.php?test=report-uri.html","blocked-uri":"inline","status-code":200}}
diff --git a/third_party/WebKit/LayoutTests/http/tests/security/contentSecurityPolicy/report-uri-from-child-frame-expected.txt b/third_party/WebKit/LayoutTests/http/tests/security/contentSecurityPolicy/report-uri-from-child-frame-expected.txt index 446ae218..d2ff7ba 100644 --- a/third_party/WebKit/LayoutTests/http/tests/security/contentSecurityPolicy/report-uri-from-child-frame-expected.txt +++ b/third_party/WebKit/LayoutTests/http/tests/security/contentSecurityPolicy/report-uri-from-child-frame-expected.txt
@@ -11,4 +11,4 @@ HTTP_REFERER: http://127.0.0.1:8000/security/contentSecurityPolicy/resources/generate-csp-report.html REQUEST_METHOD: POST === POST DATA === -{"csp-report":{"document-uri":"http://127.0.0.1:8000/security/contentSecurityPolicy/resources/generate-csp-report.html","referrer":"http://127.0.0.1:8000/security/contentSecurityPolicy/report-uri-from-child-frame.html","violated-directive":"script-src 'self'","effective-directive":"script-src","original-policy":"script-src 'self'; report-uri save-report.php?test=generate-csp-report.html","blocked-uri":"","status-code":200}} +{"csp-report":{"document-uri":"http://127.0.0.1:8000/security/contentSecurityPolicy/resources/generate-csp-report.html","referrer":"http://127.0.0.1:8000/security/contentSecurityPolicy/report-uri-from-child-frame.html","violated-directive":"script-src 'self'","effective-directive":"script-src","original-policy":"script-src 'self'; report-uri save-report.php?test=generate-csp-report.html","blocked-uri":"inline","status-code":200}}
diff --git a/third_party/WebKit/LayoutTests/http/tests/security/contentSecurityPolicy/report-uri-scheme-relative-expected.txt b/third_party/WebKit/LayoutTests/http/tests/security/contentSecurityPolicy/report-uri-scheme-relative-expected.txt index 0bcb21e..1f93ac03 100644 --- a/third_party/WebKit/LayoutTests/http/tests/security/contentSecurityPolicy/report-uri-scheme-relative-expected.txt +++ b/third_party/WebKit/LayoutTests/http/tests/security/contentSecurityPolicy/report-uri-scheme-relative-expected.txt
@@ -6,4 +6,4 @@ HTTP_REFERER: http://127.0.0.1:8000/security/contentSecurityPolicy/report-uri-scheme-relative.html REQUEST_METHOD: POST === POST DATA === -{"csp-report":{"document-uri":"http://127.0.0.1:8000/security/contentSecurityPolicy/report-uri-scheme-relative.html","referrer":"","violated-directive":"script-src 'self'","effective-directive":"script-src","original-policy":"script-src 'self'; report-uri //127.0.0.1:8080/security/contentSecurityPolicy/resources/save-report.php?test=report-uri-scheme-relative.html","blocked-uri":"","status-code":200}} +{"csp-report":{"document-uri":"http://127.0.0.1:8000/security/contentSecurityPolicy/report-uri-scheme-relative.html","referrer":"","violated-directive":"script-src 'self'","effective-directive":"script-src","original-policy":"script-src 'self'; report-uri //127.0.0.1:8080/security/contentSecurityPolicy/resources/save-report.php?test=report-uri-scheme-relative.html","blocked-uri":"inline","status-code":200}}
diff --git a/third_party/WebKit/LayoutTests/http/tests/security/cross-frame-access-enumeration-expected.txt b/third_party/WebKit/LayoutTests/http/tests/security/cross-frame-access-enumeration-expected.txt index a8e72b0..b0699c32 100644 --- a/third_party/WebKit/LayoutTests/http/tests/security/cross-frame-access-enumeration-expected.txt +++ b/third_party/WebKit/LayoutTests/http/tests/security/cross-frame-access-enumeration-expected.txt
@@ -5,6 +5,6 @@ PASS: Cross frame access by getting the keys of the window object was denied. PASS: Cross frame access by getting the property names of the window object was denied. PASS: Cross frame access by enumerating the Location object revealed no properties. -PASS: Cross frame access by getting the keys of the Location object revealed no keys. +PASS: Cross frame access by getting the keys of the Location object revealed only whitelisted keys. PASS: Cross frame access by getting the property names of the Location object revealed no custom properties.
diff --git a/third_party/WebKit/LayoutTests/http/tests/security/cross-frame-access-enumeration.html b/third_party/WebKit/LayoutTests/http/tests/security/cross-frame-access-enumeration.html index 331798c..b387fdc 100644 --- a/third_party/WebKit/LayoutTests/http/tests/security/cross-frame-access-enumeration.html +++ b/third_party/WebKit/LayoutTests/http/tests/security/cross-frame-access-enumeration.html
@@ -61,16 +61,23 @@ log("PASS: Cross frame access by enumerating the Location object revealed no properties."); var b_winLocationKeys = Object.keys(b_win_location); - if (b_winLocationKeys.length != 0) { - log("FAIL: Cross frame access by getting the keys of the Location object was allowed."); - return; + var keys_failure = false; + for (var i = 0; i < b_winLocationKeys.length; i++) { + var k = b_winLocationKeys[i]; + // See also cross-frame-access-location-get.html for the list of accessible keys. + if (k !== "assign" && k !== "replace") { + log("FAIL: Cross frame access by getting the keys of the Location object returned non-whitelisted key: " + k); + keys_failure = true; + } } - log("PASS: Cross frame access by getting the keys of the Location object revealed no keys."); + if (!keys_failure) { + log("PASS: Cross frame access by getting the keys of the Location object revealed only whitelisted keys."); + } var b_winLocationPropertyNames = Object.getOwnPropertyNames(b_win_location); if (b_winLocationPropertyNames.indexOf("customLocationProperty") != -1) { log("FAIL: Cross frame access by getting the property names of the Location object was allowed."); - return; + return; } log("PASS: Cross frame access by getting the property names of the Location object revealed no custom properties."); }
diff --git a/third_party/WebKit/LayoutTests/http/tests/security/frameNavigation/resources/frame-with-plugin-to-navigate.html b/third_party/WebKit/LayoutTests/http/tests/security/frameNavigation/resources/frame-with-plugin-to-navigate.html deleted file mode 100644 index 16120a6..0000000 --- a/third_party/WebKit/LayoutTests/http/tests/security/frameNavigation/resources/frame-with-plugin-to-navigate.html +++ /dev/null
@@ -1,44 +0,0 @@ -<html> -<head> - <script src="../../resources/cross-frame-access.js"></script> - <script> - window.onload = function() - { - document.getElementsByTagName('h4')[0].innerHTML = document.domain; - window.addEventListener('message', runTest); - } - - runTest = function() - { - if (!window.testRunner) - return; - - plg.getURL("navigation-happened.html", "toNavigate"); - - start = new Date(); - myInterval = setInterval(checkIfDone, 500); - } - - checkIfDone = function() - { - var numOpenWindows = testRunner.windowCount(); - var now = new Date(); - if (numOpenWindows == 2) { - log("Test PASSED"); - clearInterval(myInterval); - testRunner.notifyDone(); - } else if (now - start > 10000) { - log('TEST FAILED: Window count ' + numOpenWindows); - clearInterval(myInterval); - testRunner.notifyDone(); - } - } - </script> -</head> -<body> - <embed name="plg" type="application/x-webkit-test-netscape"></embed> - <h3>Frame-with-plugin-to-navigate</h3> - <h4>DOMAIN</h4> - <pre id='console'></pre> -</body> -</html>
diff --git a/third_party/WebKit/LayoutTests/http/tests/security/frameNavigation/xss-DENIED-plugin-navigation-expected.txt b/third_party/WebKit/LayoutTests/http/tests/security/frameNavigation/xss-DENIED-plugin-navigation-expected.txt deleted file mode 100644 index caf9d6b..0000000 --- a/third_party/WebKit/LayoutTests/http/tests/security/frameNavigation/xss-DENIED-plugin-navigation-expected.txt +++ /dev/null
@@ -1,19 +0,0 @@ -CONSOLE ERROR: Unsafe JavaScript attempt to initiate navigation for frame with URL 'http://127.0.0.1:8000/security/resources/cross-frame-iframe.html' from frame with URL 'http://localhost:8000/security/frameNavigation/resources/frame-with-plugin-to-navigate.html'. The frame attempting navigation is neither same-origin with the target, nor is it the target's parent or opener. - - - --------- -Frame: '<!--framePath //<!--frame0-->-->' --------- - -Frame-with-plugin-to-navigate - -localhost - -Test PASSED - - --------- -Frame: 'toNavigate' --------- -Inner iframe.
diff --git a/third_party/WebKit/LayoutTests/http/tests/security/frameNavigation/xss-DENIED-plugin-navigation.html b/third_party/WebKit/LayoutTests/http/tests/security/frameNavigation/xss-DENIED-plugin-navigation.html deleted file mode 100644 index b53c669..0000000 --- a/third_party/WebKit/LayoutTests/http/tests/security/frameNavigation/xss-DENIED-plugin-navigation.html +++ /dev/null
@@ -1,23 +0,0 @@ -<html> -<head> - <script src="../resources/cross-frame-access.js"></script> - <script> - window.onload = function() - { - if (window.testRunner) { - testRunner.dumpAsText(); - testRunner.dumpChildFramesAsText(); - testRunner.waitUntilDone(); - testRunner.setCanOpenWindows(); - testRunner.setCloseRemainingWindowsWhenComplete(true); - } - window.frames[0].postMessage('run test', '*'); - } - </script> -</head> -<body> -<pre id='console'></pre> -<iframe src="http://localhost:8000/security/frameNavigation/resources/frame-with-plugin-to-navigate.html"></iframe> -<iframe name="toNavigate" src="http://127.0.0.1:8000/security/resources/cross-frame-iframe.html"></iframe> -</body> -</html>
diff --git a/third_party/WebKit/LayoutTests/http/tests/security/w3c/cross-origin-objects-expected.txt b/third_party/WebKit/LayoutTests/http/tests/security/w3c/cross-origin-objects-expected.txt index 13ec3b87..a4d9bda 100644 --- a/third_party/WebKit/LayoutTests/http/tests/security/w3c/cross-origin-objects-expected.txt +++ b/third_party/WebKit/LayoutTests/http/tests/security/w3c/cross-origin-objects-expected.txt
@@ -8,7 +8,7 @@ FAIL [[GetOwnProperty]] - Properties on cross-origin objects should be reported |own| Blocked a frame with origin "http://web-platform.test:8000" from accessing a cross-origin frame. FAIL [[GetOwnProperty]] - Property descriptors for cross-origin properties should be set up correctly assert_equals: property descriptor for location should be non-enumerable expected false but got true PASS [[Delete]] Should throw on cross-origin objects -FAIL [[DefineOwnProperty]] Should throw for cross-origin objects assert_throws: Can't define cross-origin value property length function "function () { Object.defineProperty(obj, prop, valueDesc); }" did not throw +PASS [[DefineOwnProperty]] Should throw for cross-origin objects PASS [[Enumerate]] should return an empty iterator FAIL [[OwnPropertyKeys]] should return all properties from cross-origin objects assert_array_equals: Object.getOwnPropertyNames() gives the right answer for cross-origin Location property 0, expected "href" but got "assign" PASS A and B jointly observe the same identity for cross-origin Window and Location
diff --git a/third_party/WebKit/LayoutTests/http/tests/webfont/css-change-in-swap-period-expected.html b/third_party/WebKit/LayoutTests/http/tests/webfont/css-change-in-swap-period-expected.html new file mode 100644 index 0000000..4160dc4 --- /dev/null +++ b/third_party/WebKit/LayoutTests/http/tests/webfont/css-change-in-swap-period-expected.html
@@ -0,0 +1,11 @@ +<!DOCTYPE html> +<body> +<style id="target"> +#ref { + font-family: Arial; + font-size: 50px; +} +</style> +<p>CSS change should not make loading-fallback text blank.</p> +<div id="ref">abcdefg</div> +</body>
diff --git a/third_party/WebKit/LayoutTests/http/tests/webfont/css-change-in-swap-period.html b/third_party/WebKit/LayoutTests/http/tests/webfont/css-change-in-swap-period.html new file mode 100644 index 0000000..ea00bc2 --- /dev/null +++ b/third_party/WebKit/LayoutTests/http/tests/webfont/css-change-in-swap-period.html
@@ -0,0 +1,34 @@ +<!DOCTYPE html> +<body> +<style id="target"> +@font-face { + font-family: slow; + src: url(slow-ahem-loading.cgi?delay=8000); + font-display: fallback; +} +.test { + font-family: slow, Arial; + font-size: 50px; +} +</style> +<p>CSS change should not make loading-fallback text blank.</p> +<div id="test">abcdefg</div> +<script> + +if (window.testRunner) + testRunner.waitUntilDone(); + +window.onload = function() { + document.getElementById('test').classList.add('test'); + setTimeout(function() { + var newStyle = document.createElement('style'); + newStyle.innerHTML = "@font-face { font-family: dummy; src: local('Courier New'); }"; + document.body.insertBefore(newStyle, document.getElementById('target')); + setTimeout(function() { + if (window.testRunner) + testRunner.notifyDone(); + }, 0); + }, 500); +}; +</script> +</body>
diff --git a/third_party/WebKit/LayoutTests/imported/web-platform-tests/FileAPI/url/url_xmlhttprequest-expected.txt b/third_party/WebKit/LayoutTests/imported/web-platform-tests/FileAPI/url/url_xmlhttprequest-expected.txt index 0e33745a..decd914b 100644 --- a/third_party/WebKit/LayoutTests/imported/web-platform-tests/FileAPI/url/url_xmlhttprequest-expected.txt +++ b/third_party/WebKit/LayoutTests/imported/web-platform-tests/FileAPI/url/url_xmlhttprequest-expected.txt
@@ -1,4 +1,4 @@ This is a testharness.js-based test. -FAIL FileAPI Test: Creating Blob URL via XMLHttpRequest assert_true: XMLHttpRequest returns instanceof Blob expected true got false +FAIL FileAPI Test: Creating Blob URL via XMLHttpRequest Failed to execute 'createObjectURL' on 'URL': No function was found that matched the signature provided. Harness: the test ran to completion.
diff --git a/third_party/WebKit/LayoutTests/imported/web-platform-tests/html/semantics/forms/the-option-element/option-selected-expected.txt b/third_party/WebKit/LayoutTests/imported/web-platform-tests/html/semantics/forms/the-option-element/option-selected-expected.txt deleted file mode 100644 index d49cf74..0000000 --- a/third_party/WebKit/LayoutTests/imported/web-platform-tests/html/semantics/forms/the-option-element/option-selected-expected.txt +++ /dev/null
@@ -1,6 +0,0 @@ -This is a testharness.js-based test. -FAIL not dirty assert_equals: expected false but got true -FAIL dirty, selected assert_equals: expected false but got true -FAIL dirty, not selected assert_equals: expected false but got true -Harness: the test ran to completion. -
diff --git a/third_party/WebKit/LayoutTests/inspector/elements/styles-1/filter-matched-styles-expected.txt b/third_party/WebKit/LayoutTests/inspector/elements/styles-1/filter-matched-styles-expected.txt index 8f5b3b8..0b01cb2c 100644 --- a/third_party/WebKit/LayoutTests/inspector/elements/styles-1/filter-matched-styles-expected.txt +++ b/third_party/WebKit/LayoutTests/inspector/elements/styles-1/filter-matched-styles-expected.txt
@@ -37,6 +37,11 @@ border-left-color: black border-left-style: solid border-left-width: 1px + border-image-source: initial + border-image-slice: initial + border-image-width: initial + border-image-outset: initial + border-image-repeat: initial padding:v10px 10px 10px 10px F padding-top: 10px padding-right: 10px
diff --git a/third_party/WebKit/LayoutTests/inspector/elements/styles-2/force-pseudo-state-expected.txt b/third_party/WebKit/LayoutTests/inspector/elements/styles-2/force-pseudo-state-expected.txt index 2eb7706..0721e85 100644 --- a/third_party/WebKit/LayoutTests/inspector/elements/styles-2/force-pseudo-state-expected.txt +++ b/third_party/WebKit/LayoutTests/inspector/elements/styles-2/force-pseudo-state-expected.txt
@@ -54,6 +54,11 @@ border-left-color: green; border-left-style: solid; border-left-width: 1px; + border-image-source: initial; + border-image-slice: initial; + border-image-width: initial; + border-image-outset: initial; + border-image-repeat: initial; [expanded] :focus { (user agent stylesheet)
diff --git a/third_party/WebKit/LayoutTests/inspector/elements/styles-4/styles-properties-overload-expected.txt b/third_party/WebKit/LayoutTests/inspector/elements/styles-4/styles-properties-overload-expected.txt index c6ba76b..f3e01aa6 100644 --- a/third_party/WebKit/LayoutTests/inspector/elements/styles-4/styles-properties-overload-expected.txt +++ b/third_party/WebKit/LayoutTests/inspector/elements/styles-4/styles-properties-overload-expected.txt
@@ -39,6 +39,11 @@ border-left-color: black; border-left-style: solid; border-left-width: 1px; + border-image-source: initial; + border-image-slice: initial; + border-image-width: initial; + border-image-outset: initial; + border-image-repeat: initial; [expanded] div { (user agent stylesheet)
diff --git a/third_party/WebKit/LayoutTests/inspector/elements/styles-4/styles-update-from-js-expected.txt b/third_party/WebKit/LayoutTests/inspector/elements/styles-4/styles-update-from-js-expected.txt index 63e9447..9d2d5ca 100644 --- a/third_party/WebKit/LayoutTests/inspector/elements/styles-4/styles-update-from-js-expected.txt +++ b/third_party/WebKit/LayoutTests/inspector/elements/styles-4/styles-update-from-js-expected.txt
@@ -21,6 +21,11 @@ border-left-color: black; border-left-style: solid; border-left-width: 1px; + border-image-source: initial; + border-image-slice: initial; + border-image-width: initial; + border-image-outset: initial; + border-image-repeat: initial; [expanded] div { (user agent stylesheet) @@ -56,6 +61,11 @@ border-left-color: green; border-left-style: dashed; border-left-width: 3px; + border-image-source: initial; + border-image-slice: initial; + border-image-width: initial; + border-image-outset: initial; + border-image-repeat: initial; [expanded] div { (user agent stylesheet)
diff --git a/third_party/WebKit/LayoutTests/inspector/file-system-project-expected.txt b/third_party/WebKit/LayoutTests/inspector/file-system-project-expected.txt index 702987e4..d8664c0 100644 --- a/third_party/WebKit/LayoutTests/inspector/file-system-project-expected.txt +++ b/third_party/WebKit/LayoutTests/inspector/file-system-project-expected.txt
@@ -11,19 +11,16 @@ UISourceCode is content script: false Highlighter type: text/javascript UISourceCode content: <foo content> -modificationTime=1000000, size=13 UISourceCode: file:///var/www/bar.js UISourceCode is content script: false Highlighter type: text/javascript UISourceCode content: <bark content> -modificationTime=1000000, size=14 UISourceCode: file:///foo/bar/baz.js UISourceCode is content script: false Highlighter type: text/javascript UISourceCode content: <bazzz content> -modificationTime=1000000, size=15 Dumping uiSourceCode location link texts: - foo.js:6 @@ -40,11 +37,6 @@ UISourceCode is content script: false Highlighter type: text/javascript UISourceCode content: <Modified UISourceCode content> -New modificationTime=1001000, size=31 -Removing second file system. - number of uiSourceCodes in workspace after removing second file system: 1 -Removing first file system. - number of uiSourceCodes in workspace after removing first file system: 0 Running: testDefaultExcludes
diff --git a/third_party/WebKit/LayoutTests/inspector/file-system-project.html b/third_party/WebKit/LayoutTests/inspector/file-system-project.html index 6d9f63a3..34d3a73 100644 --- a/third_party/WebKit/LayoutTests/inspector/file-system-project.html +++ b/third_party/WebKit/LayoutTests/inspector/file-system-project.html
@@ -19,17 +19,7 @@ return; } - InspectorTest.dumpUISourceCode(uiSourceCodes[startIndex], dumpCallback.bind(this, uiSourceCodes, startIndex, next)); - function dumpCallback(uiSourceCodes, startIndex, next) - { - uiSourceCodes[startIndex].requestMetadata(dumpMetadata.bind(this, uiSourceCodes, startIndex, next)); - } - - function dumpMetadata(uiSourceCodes, startIndex, next, modificationTime, size) - { - InspectorTest.addResult("modificationTime=" + modificationTime.getTime() + ", size=" + size); - innerDumpUISourceCodes.call(this, uiSourceCodes, startIndex + 1, next); - } + InspectorTest.dumpUISourceCode(uiSourceCodes[startIndex], innerDumpUISourceCodes.bind(this, uiSourceCodes, startIndex + 1, next)); } } @@ -121,25 +111,14 @@ function contentCommitted() { InspectorTest.addResult("After revision added:"); - InspectorTest.dumpUISourceCode(uiSourceCodes[0], dumped); + InspectorTest.dumpUISourceCode(uiSourceCodes[0], finalize); + } - function dumped() - { - uiSourceCodes[0].requestMetadata(dumpModifiedMetadata); - } - - function dumpModifiedMetadata(modificationTime, size) - { - InspectorTest.addResult("New modificationTime=" + modificationTime.getTime() + ", size=" + size); - var uiSourceCodesCount = InspectorTest.fileSystemUISourceCodes().length; - InspectorTest.addResult("Removing second file system."); - fs1.reportRemoved(); - InspectorTest.addResult(" number of uiSourceCodes in workspace after removing second file system: " + InspectorTest.fileSystemUISourceCodes().length); - InspectorTest.addResult("Removing first file system."); - fs2.reportRemoved(); - InspectorTest.addResult(" number of uiSourceCodes in workspace after removing first file system: " + InspectorTest.fileSystemUISourceCodes().length); - next(); - } + function finalize() + { + fs1.reportRemoved(); + fs2.reportRemoved(); + next(); } },
diff --git a/third_party/WebKit/LayoutTests/inspector/network/network-toggle-type-filter-expected.txt b/third_party/WebKit/LayoutTests/inspector/network/network-toggle-type-filter-expected.txt index ba17ae9..fb7a4cd 100644 --- a/third_party/WebKit/LayoutTests/inspector/network/network-toggle-type-filter-expected.txt +++ b/third_party/WebKit/LayoutTests/inspector/network/network-toggle-type-filter-expected.txt
@@ -2,44 +2,44 @@ Clicked 'all' button. -Filter: xhr: true, fetch: true, eventsource: true, script: true, stylesheet: true, image: true, media: true, font: true, document: true, texttrack: true, websocket: true, other: true +Filter: xhr: true, fetch: true, eventsource: true, script: true, stylesheet: true, image: true, media: true, font: true, document: true, texttrack: true, websocket: true, other: true, sm-script: true, sm-stylesheet: true Clicked 'Documents' button. -Filter: xhr: false, fetch: false, eventsource: false, script: false, stylesheet: false, image: false, media: false, font: false, document: true, texttrack: false, websocket: false, other: false +Filter: xhr: false, fetch: false, eventsource: false, script: false, stylesheet: false, image: false, media: false, font: false, document: true, texttrack: false, websocket: false, other: false, sm-script: false, sm-stylesheet: false Clicked 'Documents' button. -Filter: xhr: false, fetch: false, eventsource: false, script: false, stylesheet: false, image: false, media: false, font: false, document: true, texttrack: false, websocket: false, other: false +Filter: xhr: false, fetch: false, eventsource: false, script: false, stylesheet: false, image: false, media: false, font: false, document: true, texttrack: false, websocket: false, other: false, sm-script: false, sm-stylesheet: false Clicked 'Scripts' button. -Filter: xhr: false, fetch: false, eventsource: false, script: true, stylesheet: false, image: false, media: false, font: false, document: false, texttrack: false, websocket: false, other: false +Filter: xhr: false, fetch: false, eventsource: false, script: true, stylesheet: false, image: false, media: false, font: false, document: false, texttrack: false, websocket: false, other: false, sm-script: true, sm-stylesheet: false Toggled 'all' button. -Filter: xhr: true, fetch: true, eventsource: true, script: true, stylesheet: true, image: true, media: true, font: true, document: true, texttrack: true, websocket: true, other: true +Filter: xhr: true, fetch: true, eventsource: true, script: true, stylesheet: true, image: true, media: true, font: true, document: true, texttrack: true, websocket: true, other: true, sm-script: true, sm-stylesheet: true Toggled 'all' button. -Filter: xhr: true, fetch: true, eventsource: true, script: true, stylesheet: true, image: true, media: true, font: true, document: true, texttrack: true, websocket: true, other: true +Filter: xhr: true, fetch: true, eventsource: true, script: true, stylesheet: true, image: true, media: true, font: true, document: true, texttrack: true, websocket: true, other: true, sm-script: true, sm-stylesheet: true Toggled 'Stylesheets' button. -Filter: xhr: false, fetch: false, eventsource: false, script: false, stylesheet: true, image: false, media: false, font: false, document: false, texttrack: false, websocket: false, other: false +Filter: xhr: false, fetch: false, eventsource: false, script: false, stylesheet: true, image: false, media: false, font: false, document: false, texttrack: false, websocket: false, other: false, sm-script: false, sm-stylesheet: true Toggled 'Images' button. -Filter: xhr: false, fetch: false, eventsource: false, script: false, stylesheet: true, image: true, media: false, font: false, document: false, texttrack: false, websocket: false, other: false +Filter: xhr: false, fetch: false, eventsource: false, script: false, stylesheet: true, image: true, media: false, font: false, document: false, texttrack: false, websocket: false, other: false, sm-script: false, sm-stylesheet: true Toggled 'Stylesheets' button. -Filter: xhr: false, fetch: false, eventsource: false, script: false, stylesheet: false, image: true, media: false, font: false, document: false, texttrack: false, websocket: false, other: false +Filter: xhr: false, fetch: false, eventsource: false, script: false, stylesheet: false, image: true, media: false, font: false, document: false, texttrack: false, websocket: false, other: false, sm-script: false, sm-stylesheet: false Clicked 'XHR and Fetch' button. -Filter: xhr: true, fetch: true, eventsource: true, script: false, stylesheet: false, image: false, media: false, font: false, document: false, texttrack: false, websocket: false, other: false +Filter: xhr: true, fetch: true, eventsource: true, script: false, stylesheet: false, image: false, media: false, font: false, document: false, texttrack: false, websocket: false, other: false, sm-script: false, sm-stylesheet: false Toggled 'Fonts' button. -Filter: xhr: true, fetch: true, eventsource: true, script: false, stylesheet: false, image: false, media: false, font: true, document: false, texttrack: false, websocket: false, other: false +Filter: xhr: true, fetch: true, eventsource: true, script: false, stylesheet: false, image: false, media: false, font: true, document: false, texttrack: false, websocket: false, other: false, sm-script: false, sm-stylesheet: false Toggled 'WebSockets' button. -Filter: xhr: true, fetch: true, eventsource: true, script: false, stylesheet: false, image: false, media: false, font: true, document: false, texttrack: false, websocket: true, other: false +Filter: xhr: true, fetch: true, eventsource: true, script: false, stylesheet: false, image: false, media: false, font: true, document: false, texttrack: false, websocket: true, other: false, sm-script: false, sm-stylesheet: false Toggled 'Media' button. -Filter: xhr: true, fetch: true, eventsource: true, script: false, stylesheet: false, image: false, media: true, font: true, document: false, texttrack: false, websocket: true, other: false +Filter: xhr: true, fetch: true, eventsource: true, script: false, stylesheet: false, image: false, media: true, font: true, document: false, texttrack: false, websocket: true, other: false, sm-script: false, sm-stylesheet: false Clicked 'all' button. -Filter: xhr: true, fetch: true, eventsource: true, script: true, stylesheet: true, image: true, media: true, font: true, document: true, texttrack: true, websocket: true, other: true +Filter: xhr: true, fetch: true, eventsource: true, script: true, stylesheet: true, image: true, media: true, font: true, document: true, texttrack: true, websocket: true, other: true, sm-script: true, sm-stylesheet: true
diff --git a/third_party/WebKit/LayoutTests/inspector/sources/debugger-ui/script-snippet-checkContent.html b/third_party/WebKit/LayoutTests/inspector/sources/debugger-ui/script-snippet-checkContent.html index 6c0dee8..ad9b6985 100644 --- a/third_party/WebKit/LayoutTests/inspector/sources/debugger-ui/script-snippet-checkContent.html +++ b/third_party/WebKit/LayoutTests/inspector/sources/debugger-ui/script-snippet-checkContent.html
@@ -17,9 +17,9 @@ window.confirm = confirmOverride; WebInspector.scriptSnippetModel.project().createFile("", null, "", onCreated.bind(this)); - function onCreated(path) + function onCreated(usc) { - uiSourceCode = WebInspector.scriptSnippetModel.project().uiSourceCode(path); + uiSourceCode = usc; uiSourceCode.requestContent(onContentAvailable); }
diff --git a/third_party/WebKit/LayoutTests/inspector/sources/debugger-ui/script-snippet-model.html b/third_party/WebKit/LayoutTests/inspector/sources/debugger-ui/script-snippet-model.html index 59983292..1ead584d 100644 --- a/third_party/WebKit/LayoutTests/inspector/sources/debugger-ui/script-snippet-model.html +++ b/third_party/WebKit/LayoutTests/inspector/sources/debugger-ui/script-snippet-model.html
@@ -92,9 +92,9 @@ WebInspector.scriptSnippetModel.project().createFile("", null, "", step2.bind(this)); - function step2(path) + function step2(uiSourceCode) { - uiSourceCode1 = WebInspector.scriptSnippetModel.project().uiSourceCode(path); + uiSourceCode1 = uiSourceCode; uiSourceCode1.requestContent(contentCallback); uiSourceCode1.addRevision("<snippet content>"); @@ -107,9 +107,9 @@ WebInspector.scriptSnippetModel.project().createFile("", null, "", step3.bind(this)); } - function step3(path) + function step3(uiSourceCode) { - var uiSourceCode2 = WebInspector.scriptSnippetModel.project().uiSourceCode(path); + var uiSourceCode2 = uiSourceCode; InspectorTest.addResult("Snippet2 created."); renameSnippetAndCheckWorkspace(uiSourceCode1, "foo"); renameSnippetAndCheckWorkspace(uiSourceCode1, " "); @@ -127,9 +127,9 @@ WebInspector.scriptSnippetModel.project().createFile("", null, "", step4.bind(this)); } - function step4(path) + function step4(uiSourceCode) { - var uiSourceCode3 = WebInspector.scriptSnippetModel.project().uiSourceCode(path); + var uiSourceCode3 = uiSourceCode; InspectorTest.addResult("Snippet3 created."); WebInspector.scriptSnippetModel.project().deleteFile(uiSourceCode3.path()); InspectorTest.addResult("Snippet3 deleted."); @@ -156,9 +156,9 @@ WebInspector.scriptSnippetModel.project().createFile("", null, "", step2.bind(this)); - function step2(path) + function step2(uiSourceCode) { - uiSourceCode1 = WebInspector.scriptSnippetModel.project().uiSourceCode(path); + uiSourceCode1 = uiSourceCode; uiSourceCode1.rename("Snippet1", function() { }); var content = ""; content += "// This snippet does nothing.\n"; @@ -167,9 +167,9 @@ WebInspector.scriptSnippetModel.project().createFile("", null, "", step3.bind(this)); } - function step3(path) + function step3(uiSourceCode) { - uiSourceCode2 = WebInspector.scriptSnippetModel.project().uiSourceCode(path); + uiSourceCode2 = uiSourceCode; uiSourceCode2.rename("Snippet2", function() { }); content = ""; content += "// This snippet creates a function that does nothing and returns it.\n"; @@ -213,9 +213,9 @@ WebInspector.scriptSnippetModel.project().createFile("", null, "", step3.bind(this)); - function step3(path) + function step3(uiSourceCode) { - var uiSourceCode1 = WebInspector.scriptSnippetModel.project().uiSourceCode(path); + var uiSourceCode1 = uiSourceCode; uiSourceCode1.rename("Snippet1", function() { }); var content = ""; content += "// This snippet does nothing.\n"; @@ -242,9 +242,8 @@ WebInspector.scriptSnippetModel.project().createFile("", null, "", step2.bind(this)); } - function step2(path) + function step2(uiSourceCode) { - var uiSourceCode = WebInspector.scriptSnippetModel.project().uiSourceCode(path); uiSourceCode.rename("Snippet1", function() { }); var content = "2+2;\n"; uiSourceCode.setWorkingCopy(content);
diff --git a/third_party/WebKit/LayoutTests/inspector/sources/debugger-ui/scripts-panel.html b/third_party/WebKit/LayoutTests/inspector/sources/debugger-ui/scripts-panel.html index 0e495a1..82601fd 100644 --- a/third_party/WebKit/LayoutTests/inspector/sources/debugger-ui/scripts-panel.html +++ b/third_party/WebKit/LayoutTests/inspector/sources/debugger-ui/scripts-panel.html
@@ -33,7 +33,7 @@ function createMockWorkspace() { InspectorTest.createWorkspaceWithTarget(true); - InspectorTest.testDebuggerProjectDelegate = new WebInspector.DebuggerProjectDelegate(InspectorTest.testWorkspace, "debugger:", WebInspector.projectTypes.Debugger); + InspectorTest.testDebuggerProject = new WebInspector.ContentProviderBasedProject(InspectorTest.testWorkspace, "", WebInspector.projectTypes.Debugger, "debugger:", ""); return InspectorTest.testWorkspace; } @@ -44,7 +44,7 @@ function addDebuggerFile(workspace, url) { - var path = InspectorTest.testDebuggerProjectDelegate.addContentProvider("", url, url, createContentProvider(url)); + var path = InspectorTest.testDebuggerProject.addContentProvider("", url, url, createContentProvider(url)); return InspectorTest.testWorkspace.uiSourceCode("debugger:", path) }
diff --git a/third_party/WebKit/LayoutTests/inspector/sources/sources-panel-extension-names-expected.txt b/third_party/WebKit/LayoutTests/inspector/sources/sources-panel-extension-names-expected.txt index 5175fb1..4a30b4df 100644 --- a/third_party/WebKit/LayoutTests/inspector/sources/sources-panel-extension-names-expected.txt +++ b/third_party/WebKit/LayoutTests/inspector/sources/sources-panel-extension-names-expected.txt
@@ -1,12 +1,6 @@ The test verifies that extension names are resolved properly in navigator view. -Running: testAddFileBeforeExecutionContext - Dumping ScriptsNavigator contentScripts tab: - 113581321345589144 - Dumping ScriptsNavigator contentScripts tab: - FibExtension - Running: testAddExecutionContextBeforeFile Dumping ScriptsNavigator contentScripts tab: FibExtension
diff --git a/third_party/WebKit/LayoutTests/inspector/sources/sources-panel-extension-names.html b/third_party/WebKit/LayoutTests/inspector/sources/sources-panel-extension-names.html index 3a9f192..c3c9bb2 100644 --- a/third_party/WebKit/LayoutTests/inspector/sources/sources-panel-extension-names.html +++ b/third_party/WebKit/LayoutTests/inspector/sources/sources-panel-extension-names.html
@@ -19,19 +19,6 @@ var mockContentScriptURL = mockExecutionContext.origin + "/script.js"; InspectorTest.runTestSuite([ - function testAddFileBeforeExecutionContext(next) - { - var contentProvider = new WebInspector.StaticContentProvider(WebInspector.resourceTypes.Script, ""); - WebInspector.NetworkProject.forTarget(InspectorTest.mainTarget).addFileForURL(mockContentScriptURL, contentProvider, true); - InspectorTest.dumpNavigatorView(contentScriptsNavigatorView, "contentScripts", " "); - InspectorTest.runtimeModel._executionContextCreated(mockExecutionContext); - InspectorTest.dumpNavigatorView(contentScriptsNavigatorView, "contentScripts", " "); - // cleanup after test - WebInspector.NetworkProject.forTarget(InspectorTest.mainTarget)._reset(); - InspectorTest.runtimeModel._executionContextsCleared(); - next(); - }, - function testAddExecutionContextBeforeFile(next) { InspectorTest.runtimeModel._executionContextCreated(mockExecutionContext);
diff --git a/third_party/WebKit/LayoutTests/inspector/uisourcecode-revisions.html b/third_party/WebKit/LayoutTests/inspector/uisourcecode-revisions.html index 3764549..67414bc 100644 --- a/third_party/WebKit/LayoutTests/inspector/uisourcecode-revisions.html +++ b/third_party/WebKit/LayoutTests/inspector/uisourcecode-revisions.html
@@ -8,8 +8,8 @@ function createMockProject() { var workspace = new WebInspector.Workspace(); - var projectDelegate = new WebInspector.NetworkProjectDelegate(InspectorTest.mainTarget, workspace, ""); - var project = workspace.addProject("projectId", projectDelegate); + var project = new WebInspector.NetworkProjectDelegate(InspectorTest.mainTarget, workspace, ""); + workspace.addProject(project); project.requestFileContent = function(uri, callback) { callback("<script content>"); @@ -17,11 +17,6 @@ project.setFileContent = function(uri, newContent, callback) { } - project.fileMimeType = function(uri) - { - return "text/javascript"; - } - return project; }
diff --git a/third_party/WebKit/LayoutTests/inspector/workspace-mapping-expected.txt b/third_party/WebKit/LayoutTests/inspector/workspace-mapping-expected.txt index 26ac947..81c41f5b 100644 --- a/third_party/WebKit/LayoutTests/inspector/workspace-mapping-expected.txt +++ b/third_party/WebKit/LayoutTests/inspector/workspace-mapping-expected.txt
@@ -5,10 +5,10 @@ url http://localhost/foo/index.html is mapped. url https://localhost/index.html is not mapped. - url http://www.example.com/index.html is mapped to http://www.example.com/index.html + url http://www.example.com/index.html is mapped to null url http://localhost/index.html is mapped to filesystem:/var/www/localhost/index.html url http://localhost/foo/index.html is mapped to null - url https://localhost/index.html is mapped to https://localhost/index.html + url https://localhost/index.html is mapped to null path /home/example.com / foo/index.html is mapped to null path /home/example.com / index.html is mapped to null
diff --git a/third_party/WebKit/LayoutTests/inspector/workspace-mapping.html b/third_party/WebKit/LayoutTests/inspector/workspace-mapping.html index fccbc7a..9c625cb 100644 --- a/third_party/WebKit/LayoutTests/inspector/workspace-mapping.html +++ b/third_party/WebKit/LayoutTests/inspector/workspace-mapping.html
@@ -6,33 +6,22 @@ function test() { var uiSourceCodes = {}; - var projectDelegates = {}; - var projectDelegates = {}; + var projects = {}; + var workspace = new WebInspector.Workspace(); + function createUISourceCode(projectId, path) { - var projectDelegate = projectDelegates[projectId]; - if (!projectDelegates[projectId]) { - projectDelegate = new MockProjectDelegate(projectId); - workspace.addProject(projectId, projectDelegate); - projectDelegates[projectId] = projectDelegate; + var project = projects[projectId]; + if (!projects[projectId]) { + if (projectId.startsWith("1:")) + projectId = projectId.substring(2); + project = new WebInspector.ProjectStore(workspace, projectId, WebInspector.projectTypes.Network, projectId, ""); + workspace.addProject(project); + projects[projectId] = project; } - var parentPath = path.substring(0, path.lastIndexOf("/")); var name = path.substring(path.lastIndexOf("/") + 1); - var fileDescriptor = new WebInspector.FileDescriptor(parentPath, name, path, path, WebInspector.resourceTypes.Script); - projectDelegate.dispatchEventToListeners(WebInspector.ProjectDelegate.Events.FileAdded, fileDescriptor); - } - - function MockProjectDelegate(projectId) - { - WebInspector.Object.call(this); - this._projectId = projectId.startsWith("1:") ? projectId.substring(2) : projectId; - } - MockProjectDelegate.prototype = { - url: function() { return this._projectId; }, - displayName: function() {}, - type: function() { return WebInspector.projectTypes.Network; }, - __proto__: WebInspector.Object.prototype + project.addUISourceCode(parentPath, name, path, WebInspector.resourceTypes.Script); } var fileSystemMapping = new WebInspector.FileSystemMapping(); @@ -40,7 +29,6 @@ var projectId = WebInspector.FileSystemWorkspaceBinding.projectId(fileSystemPath); fileSystemMapping.addFileSystem("/var/www"); fileSystemMapping.addFileMapping("/var/www", "http://localhost/", "/localhost/"); - var workspace = new WebInspector.Workspace(); var fileSystemWorkspaceBinding = new WebInspector.FileSystemWorkspaceBinding(WebInspector.isolatedFileSystemManager, workspace); var networkMapping = new WebInspector.NetworkMapping(WebInspector.targetManager, workspace, fileSystemWorkspaceBinding, fileSystemMapping);
diff --git a/third_party/WebKit/LayoutTests/media/gc-pending-event-inactive-document.html b/third_party/WebKit/LayoutTests/media/gc-pending-event.html similarity index 67% rename from third_party/WebKit/LayoutTests/media/gc-pending-event-inactive-document.html rename to third_party/WebKit/LayoutTests/media/gc-pending-event.html index 454cee14..6effe6a 100644 --- a/third_party/WebKit/LayoutTests/media/gc-pending-event-inactive-document.html +++ b/third_party/WebKit/LayoutTests/media/gc-pending-event.html
@@ -1,5 +1,5 @@ <!DOCTYPE html> -<title>GC with a pending event in an inactive document</title> +<title>Verify that a pending event prevents GC</title> <script src="../resources/testharness.js"></script> <script src="../resources/testharnessreport.js"></script> <script src="media-file.js"></script> @@ -9,11 +9,8 @@ var a = document.createElement("audio"); a.volume = 0; // queues a task to fire volumechange - var doc = document.implementation.createHTMLDocument(); - doc.body.appendChild(a); - a.onvolumechange = t.step_func_done(); - a = doc = null; + a = null; gc(); }); </script>
diff --git a/third_party/WebKit/LayoutTests/media/video-move-to-new-document.html b/third_party/WebKit/LayoutTests/media/video-move-to-new-document.html new file mode 100644 index 0000000..139f701 --- /dev/null +++ b/third_party/WebKit/LayoutTests/media/video-move-to-new-document.html
@@ -0,0 +1,34 @@ +<!DOCTYPE html> +<title>Verify that moving a video element to a new document, still loads it normally</title> +<script src="../resources/testharness.js"></script> +<script src="../resources/testharnessreport.js"></script> +<script src="media-file.js"></script> +<video></video> +<iframe></iframe> +<script> + async_test(function(t) { + var video = document.querySelector('video'); + video.src = findMediaFile("video", "content/test"); + video.onloadeddata = this.step_func(function() { + video.onloadeddata = null; + assert_true(video.networkState == video.NETWORK_IDLE || video.networkState == video.NETWORK_LOADING); + assert_greater_than(video.readyState, video.HAVE_METADATA); + // Move the video element to iframe document from + // main document and verify that it loads properly + document.querySelector('iframe').contentDocument.body.appendChild(video); + assert_equals(video.networkState, video.NETWORK_NO_SOURCE); + assert_equals(video.readyState, video.HAVE_NOTHING); + var actual_events = []; + var expected_events = ['emptied', 'loadstart', 'loadeddata']; + expected_events.forEach(function(type) { + video.addEventListener(type, t.step_func(function() { + actual_events.push(type); + if (type == 'loadeddata') { + assert_array_equals(actual_events, expected_events); + t.done(); + } + })); + }); + }); + }); +</script>
diff --git a/third_party/WebKit/LayoutTests/platform/linux/fast/repaint/change-text-content-and-background-color-expected.txt b/third_party/WebKit/LayoutTests/platform/linux/fast/repaint/change-text-content-and-background-color-expected.txt index fd98e29..99e65e6e 100644 --- a/third_party/WebKit/LayoutTests/platform/linux/fast/repaint/change-text-content-and-background-color-expected.txt +++ b/third_party/WebKit/LayoutTests/platform/linux/fast/repaint/change-text-content-and-background-color-expected.txt
@@ -6,14 +6,14 @@ "contentsOpaque": true, "drawsContent": true, "repaintRects": [ - [30, 30, 200, 23], + [30, 30, 200, 24], [30, 30, 45, 23], [30, 30, 41, 23], [8, 8, 244, 68] ], "paintInvalidationClients": [ - "InlineTextBox ''", "RootInlineBox", + "InlineTextBox ''", "LayoutTextControl (positioned) INPUT id='input'", "LayoutBlockFlow DIV id='inner-editor'", "LayoutText #text",
diff --git a/third_party/WebKit/LayoutTests/platform/linux/fast/repaint/multi-layout-one-frame-expected.txt b/third_party/WebKit/LayoutTests/platform/linux/fast/repaint/multi-layout-one-frame-expected.txt index 346aab1..53a8e030 100644 --- a/third_party/WebKit/LayoutTests/platform/linux/fast/repaint/multi-layout-one-frame-expected.txt +++ b/third_party/WebKit/LayoutTests/platform/linux/fast/repaint/multi-layout-one-frame-expected.txt
@@ -14,10 +14,10 @@ [10, 11, 45, 16] ], "paintInvalidationClients": [ - "InlineTextBox ''", "RootInlineBox", "InlineTextBox ''", "RootInlineBox", + "InlineTextBox ''", "LayoutBlockFlow DIV id='inner-editor'", "LayoutText #text", "InlineTextBox 'PASSED'",
diff --git a/third_party/WebKit/LayoutTests/platform/linux/fast/repaint/subtree-root-skipped-expected.txt b/third_party/WebKit/LayoutTests/platform/linux/fast/repaint/subtree-root-skipped-expected.txt index d3ffcb7..cf76b15 100644 --- a/third_party/WebKit/LayoutTests/platform/linux/fast/repaint/subtree-root-skipped-expected.txt +++ b/third_party/WebKit/LayoutTests/platform/linux/fast/repaint/subtree-root-skipped-expected.txt
@@ -13,8 +13,8 @@ [8, 288, 10, 20] ], "paintInvalidationClients": [ - "InlineTextBox ''", "RootInlineBox", + "InlineTextBox ''", "LayoutBlockFlow DIV id='inner-editor'", "LayoutText #text", "InlineTextBox 'PASS'",
diff --git a/third_party/WebKit/LayoutTests/platform/linux/virtual/syncpaint/fast/repaint/change-text-content-and-background-color-expected.txt b/third_party/WebKit/LayoutTests/platform/linux/virtual/syncpaint/fast/repaint/change-text-content-and-background-color-expected.txt new file mode 100644 index 0000000..99e65e6e --- /dev/null +++ b/third_party/WebKit/LayoutTests/platform/linux/virtual/syncpaint/fast/repaint/change-text-content-and-background-color-expected.txt
@@ -0,0 +1,25 @@ +{ + "bounds": [800, 600], + "children": [ + { + "bounds": [800, 600], + "contentsOpaque": true, + "drawsContent": true, + "repaintRects": [ + [30, 30, 200, 24], + [30, 30, 45, 23], + [30, 30, 41, 23], + [8, 8, 244, 68] + ], + "paintInvalidationClients": [ + "RootInlineBox", + "InlineTextBox ''", + "LayoutTextControl (positioned) INPUT id='input'", + "LayoutBlockFlow DIV id='inner-editor'", + "LayoutText #text", + "InlineTextBox 'NEW'" + ] + } + ] +} +
diff --git a/third_party/WebKit/LayoutTests/platform/linux/virtual/syncpaint/fast/repaint/multi-layout-one-frame-expected.txt b/third_party/WebKit/LayoutTests/platform/linux/virtual/syncpaint/fast/repaint/multi-layout-one-frame-expected.txt new file mode 100644 index 0000000..53a8e030 --- /dev/null +++ b/third_party/WebKit/LayoutTests/platform/linux/virtual/syncpaint/fast/repaint/multi-layout-one-frame-expected.txt
@@ -0,0 +1,31 @@ +{ + "bounds": [800, 600], + "children": [ + { + "bounds": [800, 600], + "contentsOpaque": true, + "drawsContent": true, + "repaintRects": [ + [168, 11, 150, 16], + [168, 11, 53, 16], + [168, 11, 45, 16], + [10, 11, 150, 16], + [10, 11, 53, 16], + [10, 11, 45, 16] + ], + "paintInvalidationClients": [ + "RootInlineBox", + "InlineTextBox ''", + "RootInlineBox", + "InlineTextBox ''", + "LayoutBlockFlow DIV id='inner-editor'", + "LayoutText #text", + "InlineTextBox 'PASSED'", + "LayoutBlockFlow DIV id='inner-editor'", + "LayoutText #text", + "InlineTextBox 'PASSED'" + ] + } + ] +} +
diff --git a/third_party/WebKit/LayoutTests/platform/linux/virtual/syncpaint/fast/repaint/subtree-root-skipped-expected.txt b/third_party/WebKit/LayoutTests/platform/linux/virtual/syncpaint/fast/repaint/subtree-root-skipped-expected.txt new file mode 100644 index 0000000..cf76b15 --- /dev/null +++ b/third_party/WebKit/LayoutTests/platform/linux/virtual/syncpaint/fast/repaint/subtree-root-skipped-expected.txt
@@ -0,0 +1,26 @@ +{ + "bounds": [800, 600], + "children": [ + { + "bounds": [800, 600], + "contentsOpaque": true, + "drawsContent": true, + "repaintRects": [ + [10, 11, 150, 16], + [10, 11, 35, 16], + [10, 11, 27, 16], + [8, 298, 10, 10], + [8, 288, 10, 20] + ], + "paintInvalidationClients": [ + "RootInlineBox", + "InlineTextBox ''", + "LayoutBlockFlow DIV id='inner-editor'", + "LayoutText #text", + "InlineTextBox 'PASS'", + "LayoutBlockFlow (positioned) DIV id='div'" + ] + } + ] +} +
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mavericks/fast/repaint/change-text-content-and-background-color-expected.txt b/third_party/WebKit/LayoutTests/platform/mac-mavericks/fast/repaint/change-text-content-and-background-color-expected.txt index d4c3d7c..fd1212d 100644 --- a/third_party/WebKit/LayoutTests/platform/mac-mavericks/fast/repaint/change-text-content-and-background-color-expected.txt +++ b/third_party/WebKit/LayoutTests/platform/mac-mavericks/fast/repaint/change-text-content-and-background-color-expected.txt
@@ -12,8 +12,8 @@ [8, 8, 244, 67] ], "paintInvalidationClients": [ - "InlineTextBox ''", "RootInlineBox", + "InlineTextBox ''", "LayoutTextControl (positioned) INPUT id='input'", "LayoutBlockFlow DIV id='inner-editor'", "LayoutText #text",
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mavericks/fast/repaint/multi-layout-one-frame-expected.txt b/third_party/WebKit/LayoutTests/platform/mac-mavericks/fast/repaint/multi-layout-one-frame-expected.txt index 430fc53..a44c99a2 100644 --- a/third_party/WebKit/LayoutTests/platform/mac-mavericks/fast/repaint/multi-layout-one-frame-expected.txt +++ b/third_party/WebKit/LayoutTests/platform/mac-mavericks/fast/repaint/multi-layout-one-frame-expected.txt
@@ -14,10 +14,10 @@ [11, 11, 37, 13] ], "paintInvalidationClients": [ - "InlineTextBox ''", "RootInlineBox", "InlineTextBox ''", "RootInlineBox", + "InlineTextBox ''", "LayoutBlockFlow DIV id='inner-editor'", "LayoutText #text", "InlineTextBox 'PASSED'",
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mavericks/fast/repaint/subtree-root-skipped-expected.txt b/third_party/WebKit/LayoutTests/platform/mac-mavericks/fast/repaint/subtree-root-skipped-expected.txt index 247f8f7..a357e7f 100644 --- a/third_party/WebKit/LayoutTests/platform/mac-mavericks/fast/repaint/subtree-root-skipped-expected.txt +++ b/third_party/WebKit/LayoutTests/platform/mac-mavericks/fast/repaint/subtree-root-skipped-expected.txt
@@ -13,8 +13,8 @@ [8, 288, 10, 20] ], "paintInvalidationClients": [ - "InlineTextBox ''", "RootInlineBox", + "InlineTextBox ''", "LayoutBlockFlow DIV id='inner-editor'", "LayoutText #text", "InlineTextBox 'PASS'",
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mavericks/virtual/syncpaint/fast/repaint/change-text-content-and-background-color-expected.txt b/third_party/WebKit/LayoutTests/platform/mac-mavericks/virtual/syncpaint/fast/repaint/change-text-content-and-background-color-expected.txt new file mode 100644 index 0000000..fd1212d --- /dev/null +++ b/third_party/WebKit/LayoutTests/platform/mac-mavericks/virtual/syncpaint/fast/repaint/change-text-content-and-background-color-expected.txt
@@ -0,0 +1,25 @@ +{ + "bounds": [800, 600], + "children": [ + { + "bounds": [800, 600], + "contentsOpaque": true, + "drawsContent": true, + "repaintRects": [ + [30, 30, 200, 23], + [30, 30, 43, 23], + [30, 30, 42, 23], + [8, 8, 244, 67] + ], + "paintInvalidationClients": [ + "RootInlineBox", + "InlineTextBox ''", + "LayoutTextControl (positioned) INPUT id='input'", + "LayoutBlockFlow DIV id='inner-editor'", + "LayoutText #text", + "InlineTextBox 'NEW'" + ] + } + ] +} +
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mavericks/virtual/syncpaint/fast/repaint/multi-layout-one-frame-expected.txt b/third_party/WebKit/LayoutTests/platform/mac-mavericks/virtual/syncpaint/fast/repaint/multi-layout-one-frame-expected.txt new file mode 100644 index 0000000..a44c99a2 --- /dev/null +++ b/third_party/WebKit/LayoutTests/platform/mac-mavericks/virtual/syncpaint/fast/repaint/multi-layout-one-frame-expected.txt
@@ -0,0 +1,31 @@ +{ + "bounds": [800, 600], + "children": [ + { + "bounds": [800, 600], + "contentsOpaque": true, + "drawsContent": true, + "repaintRects": [ + [138, 11, 117, 13], + [138, 11, 40, 13], + [138, 11, 37, 13], + [11, 11, 117, 13], + [11, 11, 40, 13], + [11, 11, 37, 13] + ], + "paintInvalidationClients": [ + "RootInlineBox", + "InlineTextBox ''", + "RootInlineBox", + "InlineTextBox ''", + "LayoutBlockFlow DIV id='inner-editor'", + "LayoutText #text", + "InlineTextBox 'PASSED'", + "LayoutBlockFlow DIV id='inner-editor'", + "LayoutText #text", + "InlineTextBox 'PASSED'" + ] + } + ] +} +
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mavericks/virtual/syncpaint/fast/repaint/subtree-root-skipped-expected.txt b/third_party/WebKit/LayoutTests/platform/mac-mavericks/virtual/syncpaint/fast/repaint/subtree-root-skipped-expected.txt new file mode 100644 index 0000000..a357e7f --- /dev/null +++ b/third_party/WebKit/LayoutTests/platform/mac-mavericks/virtual/syncpaint/fast/repaint/subtree-root-skipped-expected.txt
@@ -0,0 +1,26 @@ +{ + "bounds": [800, 600], + "children": [ + { + "bounds": [800, 600], + "contentsOpaque": true, + "drawsContent": true, + "repaintRects": [ + [11, 11, 117, 13], + [11, 11, 26, 13], + [11, 11, 23, 13], + [8, 298, 10, 10], + [8, 288, 10, 20] + ], + "paintInvalidationClients": [ + "RootInlineBox", + "InlineTextBox ''", + "LayoutBlockFlow DIV id='inner-editor'", + "LayoutText #text", + "InlineTextBox 'PASS'", + "LayoutBlockFlow (positioned) DIV id='div'" + ] + } + ] +} +
diff --git a/third_party/WebKit/LayoutTests/platform/mac/fast/repaint/change-text-content-and-background-color-expected.txt b/third_party/WebKit/LayoutTests/platform/mac/fast/repaint/change-text-content-and-background-color-expected.txt index bb90eaaf1..172b7d20 100644 --- a/third_party/WebKit/LayoutTests/platform/mac/fast/repaint/change-text-content-and-background-color-expected.txt +++ b/third_party/WebKit/LayoutTests/platform/mac/fast/repaint/change-text-content-and-background-color-expected.txt
@@ -12,8 +12,8 @@ [8, 8, 244, 67] ], "paintInvalidationClients": [ - "InlineTextBox ''", "RootInlineBox", + "InlineTextBox ''", "LayoutTextControl (positioned) INPUT id='input'", "LayoutBlockFlow DIV id='inner-editor'", "LayoutText #text",
diff --git a/third_party/WebKit/LayoutTests/platform/mac/fast/repaint/multi-layout-one-frame-expected.txt b/third_party/WebKit/LayoutTests/platform/mac/fast/repaint/multi-layout-one-frame-expected.txt index 604b122..5d90b9ad 100644 --- a/third_party/WebKit/LayoutTests/platform/mac/fast/repaint/multi-layout-one-frame-expected.txt +++ b/third_party/WebKit/LayoutTests/platform/mac/fast/repaint/multi-layout-one-frame-expected.txt
@@ -14,10 +14,10 @@ [11, 11, 37, 13] ], "paintInvalidationClients": [ - "InlineTextBox ''", "RootInlineBox", "InlineTextBox ''", "RootInlineBox", + "InlineTextBox ''", "LayoutBlockFlow DIV id='inner-editor'", "LayoutText #text", "InlineTextBox 'PASSED'",
diff --git a/third_party/WebKit/LayoutTests/platform/mac/fast/repaint/subtree-root-skipped-expected.txt b/third_party/WebKit/LayoutTests/platform/mac/fast/repaint/subtree-root-skipped-expected.txt index 3f32cc3..5f8471b 100644 --- a/third_party/WebKit/LayoutTests/platform/mac/fast/repaint/subtree-root-skipped-expected.txt +++ b/third_party/WebKit/LayoutTests/platform/mac/fast/repaint/subtree-root-skipped-expected.txt
@@ -13,8 +13,8 @@ [8, 288, 10, 20] ], "paintInvalidationClients": [ - "InlineTextBox ''", "RootInlineBox", + "InlineTextBox ''", "LayoutBlockFlow DIV id='inner-editor'", "LayoutText #text", "InlineTextBox 'PASS'",
diff --git a/third_party/WebKit/LayoutTests/platform/mac/virtual/syncpaint/fast/repaint/change-text-content-and-background-color-expected.txt b/third_party/WebKit/LayoutTests/platform/mac/virtual/syncpaint/fast/repaint/change-text-content-and-background-color-expected.txt new file mode 100644 index 0000000..172b7d20 --- /dev/null +++ b/third_party/WebKit/LayoutTests/platform/mac/virtual/syncpaint/fast/repaint/change-text-content-and-background-color-expected.txt
@@ -0,0 +1,25 @@ +{ + "bounds": [800, 600], + "children": [ + { + "bounds": [800, 600], + "contentsOpaque": true, + "drawsContent": true, + "repaintRects": [ + [30, 30, 200, 23], + [30, 30, 46, 23], + [30, 30, 42, 23], + [8, 8, 244, 67] + ], + "paintInvalidationClients": [ + "RootInlineBox", + "InlineTextBox ''", + "LayoutTextControl (positioned) INPUT id='input'", + "LayoutBlockFlow DIV id='inner-editor'", + "LayoutText #text", + "InlineTextBox 'NEW'" + ] + } + ] +} +
diff --git a/third_party/WebKit/LayoutTests/platform/mac/virtual/syncpaint/fast/repaint/multi-layout-one-frame-expected.txt b/third_party/WebKit/LayoutTests/platform/mac/virtual/syncpaint/fast/repaint/multi-layout-one-frame-expected.txt new file mode 100644 index 0000000..5d90b9ad --- /dev/null +++ b/third_party/WebKit/LayoutTests/platform/mac/virtual/syncpaint/fast/repaint/multi-layout-one-frame-expected.txt
@@ -0,0 +1,31 @@ +{ + "bounds": [800, 600], + "children": [ + { + "bounds": [800, 600], + "contentsOpaque": true, + "drawsContent": true, + "repaintRects": [ + [146, 11, 125, 13], + [146, 11, 43, 13], + [146, 11, 37, 13], + [11, 11, 125, 13], + [11, 11, 43, 13], + [11, 11, 37, 13] + ], + "paintInvalidationClients": [ + "RootInlineBox", + "InlineTextBox ''", + "RootInlineBox", + "InlineTextBox ''", + "LayoutBlockFlow DIV id='inner-editor'", + "LayoutText #text", + "InlineTextBox 'PASSED'", + "LayoutBlockFlow DIV id='inner-editor'", + "LayoutText #text", + "InlineTextBox 'PASSED'" + ] + } + ] +} +
diff --git a/third_party/WebKit/LayoutTests/platform/mac/virtual/syncpaint/fast/repaint/subtree-root-skipped-expected.txt b/third_party/WebKit/LayoutTests/platform/mac/virtual/syncpaint/fast/repaint/subtree-root-skipped-expected.txt new file mode 100644 index 0000000..5f8471b --- /dev/null +++ b/third_party/WebKit/LayoutTests/platform/mac/virtual/syncpaint/fast/repaint/subtree-root-skipped-expected.txt
@@ -0,0 +1,26 @@ +{ + "bounds": [800, 600], + "children": [ + { + "bounds": [800, 600], + "contentsOpaque": true, + "drawsContent": true, + "repaintRects": [ + [11, 11, 125, 13], + [11, 11, 29, 13], + [11, 11, 23, 13], + [8, 298, 10, 10], + [8, 288, 10, 20] + ], + "paintInvalidationClients": [ + "RootInlineBox", + "InlineTextBox ''", + "LayoutBlockFlow DIV id='inner-editor'", + "LayoutText #text", + "InlineTextBox 'PASS'", + "LayoutBlockFlow (positioned) DIV id='div'" + ] + } + ] +} +
diff --git a/third_party/WebKit/LayoutTests/platform/win-xp/fast/repaint/change-text-content-and-background-color-expected.txt b/third_party/WebKit/LayoutTests/platform/win-xp/fast/repaint/change-text-content-and-background-color-expected.txt index fd98e29..99e65e6e 100644 --- a/third_party/WebKit/LayoutTests/platform/win-xp/fast/repaint/change-text-content-and-background-color-expected.txt +++ b/third_party/WebKit/LayoutTests/platform/win-xp/fast/repaint/change-text-content-and-background-color-expected.txt
@@ -6,14 +6,14 @@ "contentsOpaque": true, "drawsContent": true, "repaintRects": [ - [30, 30, 200, 23], + [30, 30, 200, 24], [30, 30, 45, 23], [30, 30, 41, 23], [8, 8, 244, 68] ], "paintInvalidationClients": [ - "InlineTextBox ''", "RootInlineBox", + "InlineTextBox ''", "LayoutTextControl (positioned) INPUT id='input'", "LayoutBlockFlow DIV id='inner-editor'", "LayoutText #text",
diff --git a/third_party/WebKit/LayoutTests/platform/win-xp/fast/repaint/multi-layout-one-frame-expected.txt b/third_party/WebKit/LayoutTests/platform/win-xp/fast/repaint/multi-layout-one-frame-expected.txt index f581c766..ddd172ef 100644 --- a/third_party/WebKit/LayoutTests/platform/win-xp/fast/repaint/multi-layout-one-frame-expected.txt +++ b/third_party/WebKit/LayoutTests/platform/win-xp/fast/repaint/multi-layout-one-frame-expected.txt
@@ -14,10 +14,10 @@ [10, 11, 45, 16] ], "paintInvalidationClients": [ - "InlineTextBox ''", "RootInlineBox", "InlineTextBox ''", "RootInlineBox", + "InlineTextBox ''", "LayoutBlockFlow DIV id='inner-editor'", "LayoutText #text", "InlineTextBox 'PASSED'",
diff --git a/third_party/WebKit/LayoutTests/platform/win-xp/fast/repaint/subtree-root-skipped-expected.txt b/third_party/WebKit/LayoutTests/platform/win-xp/fast/repaint/subtree-root-skipped-expected.txt index 98ab6082..cae1954 100644 --- a/third_party/WebKit/LayoutTests/platform/win-xp/fast/repaint/subtree-root-skipped-expected.txt +++ b/third_party/WebKit/LayoutTests/platform/win-xp/fast/repaint/subtree-root-skipped-expected.txt
@@ -13,8 +13,8 @@ [8, 288, 10, 20] ], "paintInvalidationClients": [ - "InlineTextBox ''", "RootInlineBox", + "InlineTextBox ''", "LayoutBlockFlow DIV id='inner-editor'", "LayoutText #text", "InlineTextBox 'PASS'",
diff --git a/third_party/WebKit/LayoutTests/platform/win-xp/virtual/syncpaint/fast/repaint/change-text-content-and-background-color-expected.txt b/third_party/WebKit/LayoutTests/platform/win-xp/virtual/syncpaint/fast/repaint/change-text-content-and-background-color-expected.txt new file mode 100644 index 0000000..99e65e6e --- /dev/null +++ b/third_party/WebKit/LayoutTests/platform/win-xp/virtual/syncpaint/fast/repaint/change-text-content-and-background-color-expected.txt
@@ -0,0 +1,25 @@ +{ + "bounds": [800, 600], + "children": [ + { + "bounds": [800, 600], + "contentsOpaque": true, + "drawsContent": true, + "repaintRects": [ + [30, 30, 200, 24], + [30, 30, 45, 23], + [30, 30, 41, 23], + [8, 8, 244, 68] + ], + "paintInvalidationClients": [ + "RootInlineBox", + "InlineTextBox ''", + "LayoutTextControl (positioned) INPUT id='input'", + "LayoutBlockFlow DIV id='inner-editor'", + "LayoutText #text", + "InlineTextBox 'NEW'" + ] + } + ] +} +
diff --git a/third_party/WebKit/LayoutTests/platform/win-xp/virtual/syncpaint/fast/repaint/multi-layout-one-frame-expected.txt b/third_party/WebKit/LayoutTests/platform/win-xp/virtual/syncpaint/fast/repaint/multi-layout-one-frame-expected.txt new file mode 100644 index 0000000..ddd172ef --- /dev/null +++ b/third_party/WebKit/LayoutTests/platform/win-xp/virtual/syncpaint/fast/repaint/multi-layout-one-frame-expected.txt
@@ -0,0 +1,31 @@ +{ + "bounds": [800, 600], + "children": [ + { + "bounds": [800, 600], + "contentsOpaque": true, + "drawsContent": true, + "repaintRects": [ + [167, 11, 149, 16], + [167, 11, 54, 16], + [167, 11, 45, 16], + [10, 11, 149, 16], + [10, 11, 54, 16], + [10, 11, 45, 16] + ], + "paintInvalidationClients": [ + "RootInlineBox", + "InlineTextBox ''", + "RootInlineBox", + "InlineTextBox ''", + "LayoutBlockFlow DIV id='inner-editor'", + "LayoutText #text", + "InlineTextBox 'PASSED'", + "LayoutBlockFlow DIV id='inner-editor'", + "LayoutText #text", + "InlineTextBox 'PASSED'" + ] + } + ] +} +
diff --git a/third_party/WebKit/LayoutTests/platform/win-xp/virtual/syncpaint/fast/repaint/subtree-root-skipped-expected.txt b/third_party/WebKit/LayoutTests/platform/win-xp/virtual/syncpaint/fast/repaint/subtree-root-skipped-expected.txt new file mode 100644 index 0000000..cae1954 --- /dev/null +++ b/third_party/WebKit/LayoutTests/platform/win-xp/virtual/syncpaint/fast/repaint/subtree-root-skipped-expected.txt
@@ -0,0 +1,26 @@ +{ + "bounds": [800, 600], + "children": [ + { + "bounds": [800, 600], + "contentsOpaque": true, + "drawsContent": true, + "repaintRects": [ + [10, 11, 149, 16], + [10, 11, 36, 16], + [10, 11, 27, 16], + [8, 298, 10, 10], + [8, 288, 10, 20] + ], + "paintInvalidationClients": [ + "RootInlineBox", + "InlineTextBox ''", + "LayoutBlockFlow DIV id='inner-editor'", + "LayoutText #text", + "InlineTextBox 'PASS'", + "LayoutBlockFlow (positioned) DIV id='div'" + ] + } + ] +} +
diff --git a/third_party/WebKit/LayoutTests/platform/win/fast/repaint/change-text-content-and-background-color-expected.txt b/third_party/WebKit/LayoutTests/platform/win/fast/repaint/change-text-content-and-background-color-expected.txt index d1c5dea..3f07ce1 100644 --- a/third_party/WebKit/LayoutTests/platform/win/fast/repaint/change-text-content-and-background-color-expected.txt +++ b/third_party/WebKit/LayoutTests/platform/win/fast/repaint/change-text-content-and-background-color-expected.txt
@@ -6,14 +6,14 @@ "contentsOpaque": true, "drawsContent": true, "repaintRects": [ - [30, 30, 200, 22], + [30, 30, 200, 23], [30, 30, 47, 22], [30, 30, 42, 22], [8, 8, 244, 67] ], "paintInvalidationClients": [ - "InlineTextBox ''", "RootInlineBox", + "InlineTextBox ''", "LayoutTextControl (positioned) INPUT id='input'", "LayoutBlockFlow DIV id='inner-editor'", "LayoutText #text",
diff --git a/third_party/WebKit/LayoutTests/platform/win/fast/repaint/multi-layout-one-frame-expected.txt b/third_party/WebKit/LayoutTests/platform/win/fast/repaint/multi-layout-one-frame-expected.txt index e11c0b7..50cd6d2c 100644 --- a/third_party/WebKit/LayoutTests/platform/win/fast/repaint/multi-layout-one-frame-expected.txt +++ b/third_party/WebKit/LayoutTests/platform/win/fast/repaint/multi-layout-one-frame-expected.txt
@@ -14,10 +14,10 @@ [10, 11, 45, 16] ], "paintInvalidationClients": [ - "InlineTextBox ''", "RootInlineBox", "InlineTextBox ''", "RootInlineBox", + "InlineTextBox ''", "LayoutBlockFlow DIV id='inner-editor'", "LayoutText #text", "InlineTextBox 'PASSED'",
diff --git a/third_party/WebKit/LayoutTests/platform/win/fast/repaint/subtree-root-skipped-expected.txt b/third_party/WebKit/LayoutTests/platform/win/fast/repaint/subtree-root-skipped-expected.txt index 88c9f63..73eee651 100644 --- a/third_party/WebKit/LayoutTests/platform/win/fast/repaint/subtree-root-skipped-expected.txt +++ b/third_party/WebKit/LayoutTests/platform/win/fast/repaint/subtree-root-skipped-expected.txt
@@ -13,8 +13,8 @@ [8, 288, 10, 20] ], "paintInvalidationClients": [ - "InlineTextBox ''", "RootInlineBox", + "InlineTextBox ''", "LayoutBlockFlow DIV id='inner-editor'", "LayoutText #text", "InlineTextBox 'PASS'",
diff --git a/third_party/WebKit/LayoutTests/platform/win/virtual/syncpaint/fast/repaint/change-text-content-and-background-color-expected.txt b/third_party/WebKit/LayoutTests/platform/win/virtual/syncpaint/fast/repaint/change-text-content-and-background-color-expected.txt new file mode 100644 index 0000000..3f07ce1 --- /dev/null +++ b/third_party/WebKit/LayoutTests/platform/win/virtual/syncpaint/fast/repaint/change-text-content-and-background-color-expected.txt
@@ -0,0 +1,25 @@ +{ + "bounds": [800, 600], + "children": [ + { + "bounds": [800, 600], + "contentsOpaque": true, + "drawsContent": true, + "repaintRects": [ + [30, 30, 200, 23], + [30, 30, 47, 22], + [30, 30, 42, 22], + [8, 8, 244, 67] + ], + "paintInvalidationClients": [ + "RootInlineBox", + "InlineTextBox ''", + "LayoutTextControl (positioned) INPUT id='input'", + "LayoutBlockFlow DIV id='inner-editor'", + "LayoutText #text", + "InlineTextBox 'NEW'" + ] + } + ] +} +
diff --git a/third_party/WebKit/LayoutTests/platform/win/virtual/syncpaint/fast/repaint/multi-layout-one-frame-expected.txt b/third_party/WebKit/LayoutTests/platform/win/virtual/syncpaint/fast/repaint/multi-layout-one-frame-expected.txt new file mode 100644 index 0000000..50cd6d2c --- /dev/null +++ b/third_party/WebKit/LayoutTests/platform/win/virtual/syncpaint/fast/repaint/multi-layout-one-frame-expected.txt
@@ -0,0 +1,31 @@ +{ + "bounds": [800, 600], + "children": [ + { + "bounds": [800, 600], + "contentsOpaque": true, + "drawsContent": true, + "repaintRects": [ + [187, 11, 169, 16], + [187, 11, 53, 16], + [187, 11, 45, 16], + [10, 11, 169, 16], + [10, 11, 53, 16], + [10, 11, 45, 16] + ], + "paintInvalidationClients": [ + "RootInlineBox", + "InlineTextBox ''", + "RootInlineBox", + "InlineTextBox ''", + "LayoutBlockFlow DIV id='inner-editor'", + "LayoutText #text", + "InlineTextBox 'PASSED'", + "LayoutBlockFlow DIV id='inner-editor'", + "LayoutText #text", + "InlineTextBox 'PASSED'" + ] + } + ] +} +
diff --git a/third_party/WebKit/LayoutTests/platform/win/virtual/syncpaint/fast/repaint/subtree-root-skipped-expected.txt b/third_party/WebKit/LayoutTests/platform/win/virtual/syncpaint/fast/repaint/subtree-root-skipped-expected.txt new file mode 100644 index 0000000..73eee651 --- /dev/null +++ b/third_party/WebKit/LayoutTests/platform/win/virtual/syncpaint/fast/repaint/subtree-root-skipped-expected.txt
@@ -0,0 +1,26 @@ +{ + "bounds": [800, 600], + "children": [ + { + "bounds": [800, 600], + "contentsOpaque": true, + "drawsContent": true, + "repaintRects": [ + [10, 11, 169, 16], + [10, 11, 35, 16], + [10, 11, 27, 16], + [8, 298, 10, 10], + [8, 288, 10, 20] + ], + "paintInvalidationClients": [ + "RootInlineBox", + "InlineTextBox ''", + "LayoutBlockFlow DIV id='inner-editor'", + "LayoutText #text", + "InlineTextBox 'PASS'", + "LayoutBlockFlow (positioned) DIV id='div'" + ] + } + ] +} +
diff --git a/third_party/WebKit/LayoutTests/plugins/document-open-expected.txt b/third_party/WebKit/LayoutTests/plugins/document-open-expected.txt deleted file mode 100644 index 8b13789..0000000 --- a/third_party/WebKit/LayoutTests/plugins/document-open-expected.txt +++ /dev/null
@@ -1 +0,0 @@ -
diff --git a/third_party/WebKit/LayoutTests/plugins/document-open.html b/third_party/WebKit/LayoutTests/plugins/document-open.html deleted file mode 100644 index 1d0d39d..0000000 --- a/third_party/WebKit/LayoutTests/plugins/document-open.html +++ /dev/null
@@ -1,20 +0,0 @@ -<html> -<head> -<body> -<embed id="testPlugin" - type="application/x-webkit-test-netscape" - src="data:text/plain," - test="document-open-in-destroy-stream"> -</embed> - -<div> - This tests that document.open invoked by a plugin via NPN_Invoke without a javascript context succeeds. -</div> -<script> - if (window.testRunner) { - testRunner.dumpAsText(); - testRunner.waitUntilDone(); - } -</script> -</body> -</html>
diff --git a/third_party/WebKit/LayoutTests/plugins/embed-inside-object-expected.txt b/third_party/WebKit/LayoutTests/plugins/embed-inside-object-expected.txt deleted file mode 100644 index 93e31b3f..0000000 --- a/third_party/WebKit/LayoutTests/plugins/embed-inside-object-expected.txt +++ /dev/null
@@ -1,5 +0,0 @@ - -This tests that it's possible to control an embed that is nested inside an object with a span tag in between. -plugin object is: [object HTMLEmbedElement] -SUCCESS -
diff --git a/third_party/WebKit/LayoutTests/plugins/embed-inside-object.html b/third_party/WebKit/LayoutTests/plugins/embed-inside-object.html deleted file mode 100644 index dfc0da3d..0000000 --- a/third_party/WebKit/LayoutTests/plugins/embed-inside-object.html +++ /dev/null
@@ -1,37 +0,0 @@ -<html> -<script> - function debug(str) { - document.getElementById('console').innerHTML += str + "<br>"; - } - - function pluginCallback() { - debug('SUCCESS'); - if (window.testRunner) - testRunner.notifyDone(); - } - - function runTest() { - if (window.testRunner) { - testRunner.dumpAsText(); - testRunner.waitUntilDone(); - } - - var plugin = document.plugin; - - debug('plugin object is: ' + plugin); - plugin.getURL('javascript:pluginCallback()', '_self') - } -</script> -<body onload="runTest()"> -<object name="plugin" type="application/x-webkit-test-netscape"> - <span> - <embed name="plugin" type="application/x-webkit-test-netscape"></embed> - </span> -</object> -<div> - This tests that it's possible to control an embed that is nested inside an object with a span tag in between. -</div> -<div id="console"> -</div> -</body> -</html>
diff --git a/third_party/WebKit/LayoutTests/transforms/perspective-origin-parsing.html b/third_party/WebKit/LayoutTests/transforms/perspective-origin-parsing.html index 8eb82d1..5eb8c2e 100644 --- a/third_party/WebKit/LayoutTests/transforms/perspective-origin-parsing.html +++ b/third_party/WebKit/LayoutTests/transforms/perspective-origin-parsing.html
@@ -9,14 +9,14 @@ expect('initial').parsesAs('initial').isComputedTo('100px 50px'); expect('inherit').parsesAs('inherit'); -expect('left').parsesAs('left 50%').isComputedTo('0px 50px'); -expect('center').parsesAs('center 50%').isComputedTo('100px 50px'); -expect('right').parsesAs('right 50%').isComputedTo('200px 50px'); -expect('top').parsesAs('50% top'); -expect('bottom').parsesAs('50% bottom'); -expect('0').parsesAs('0px 50%'); -expect('10%').parsesAs('10% 50%').isComputedTo('20px 50px'); -expect('10px').parsesAs('10px 50%').isComputedTo('10px 50px'); +expect('left').parsesAs('left center').isComputedTo('0px 50px'); +expect('center').parsesAs('center center').isComputedTo('100px 50px'); +expect('right').parsesAs('right center').isComputedTo('200px 50px'); +expect('top').parsesAs('center top'); +expect('bottom').parsesAs('center bottom'); +expect('0').parsesAs('0px center'); +expect('10%').parsesAs('10% center').isComputedTo('20px 50px'); +expect('10px').parsesAs('10px center').isComputedTo('10px 50px'); expect('left top').parsesAs('left top'); expect('right bottom').parsesAs('right bottom'); @@ -36,6 +36,14 @@ expect('0px bottom').parsesAs('0px bottom').isComputedTo('0px 100px'); expect('0px center').parsesAs('0px center').isComputedTo('0px 50px'); +expect('center right 20%').parsesAs('right 20% center'); +expect('left bottom 30px').parsesAs('left bottom 30px'); +expect('top right 30px').parsesAs('right 30px top'); + +expect('left 30px bottom 20px').parsesAs('left 30px bottom 20px'); +expect('top 10px left 20px').parsesAs('left 20px top 10px'); +expect('top 40px right 15%').parsesAs('right 15% top 40px'); + expect('left right').isInvalid(); expect('top bottom').isInvalid(); expect('none').isInvalid();
diff --git a/third_party/WebKit/LayoutTests/transforms/transform-origin-parsing.html b/third_party/WebKit/LayoutTests/transforms/transform-origin-parsing.html index 39018d2e..ce31753 100644 --- a/third_party/WebKit/LayoutTests/transforms/transform-origin-parsing.html +++ b/third_party/WebKit/LayoutTests/transforms/transform-origin-parsing.html
@@ -9,14 +9,14 @@ expect('initial').parsesAs('initial').isComputedTo('100px 50px'); expect('inherit').parsesAs('inherit'); -expect('left').parsesAs('left 50% 0px').isComputedTo('0px 50px'); -expect('center').parsesAs('center 50% 0px').isComputedTo('100px 50px'); -expect('right').parsesAs('right 50% 0px').isComputedTo('200px 50px'); -expect('top').parsesAs('50% top 0px'); -expect('bottom').parsesAs('50% bottom 0px'); -expect('0').parsesAs('0px 50% 0px'); -expect('10%').parsesAs('10% 50% 0px').isComputedTo('20px 50px'); -expect('10px').parsesAs('10px 50% 0px').isComputedTo('10px 50px'); +expect('left').parsesAs('left center 0px').isComputedTo('0px 50px'); +expect('center').parsesAs('center center 0px').isComputedTo('100px 50px'); +expect('right').parsesAs('right center 0px').isComputedTo('200px 50px'); +expect('top').parsesAs('center top 0px'); +expect('bottom').parsesAs('center bottom 0px'); +expect('0').parsesAs('0px center 0px'); +expect('10%').parsesAs('10% center 0px').isComputedTo('20px 50px'); +expect('10px').parsesAs('10px center 0px').isComputedTo('10px 50px'); expect('left top').parsesAs('left top 0px'); expect('right bottom').parsesAs('right bottom 0px');
diff --git a/third_party/WebKit/LayoutTests/typedcssom/numbervalue.html b/third_party/WebKit/LayoutTests/typedcssom/numbervalue.html new file mode 100644 index 0000000..7d6f7e9 --- /dev/null +++ b/third_party/WebKit/LayoutTests/typedcssom/numbervalue.html
@@ -0,0 +1,23 @@ +<!DOCTYPE html> +<script src="../resources/testharness.js"></script> +<script src="../resources/testharnessreport.js"></script> + +<script> +var values = [ + {input: new NumberValue(0), cssString: '0'}, + {input: new NumberValue(1), cssString: '1'}, + {input: new NumberValue(-2), cssString: '-2'}, + {input: new NumberValue(3.4), cssString: '3.4'} +]; + +test(function() { + for (var i = 0; i < values.length; ++i) { + assert_equals(values[i].input.cssString, values[i].cssString); + } +}, "Test that the css string for NumberValue is correct."); + +</script> + +<body> +</body> +
diff --git a/third_party/WebKit/LayoutTests/webaudio/audiobuffersource-late-start-expected.txt b/third_party/WebKit/LayoutTests/webaudio/audiobuffersource-late-start-expected.txt index 808a7026..f0a8206 100644 --- a/third_party/WebKit/LayoutTests/webaudio/audiobuffersource-late-start-expected.txt +++ b/third_party/WebKit/LayoutTests/webaudio/audiobuffersource-late-start-expected.txt
@@ -3,6 +3,8 @@ On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE". +PASS The output contains all the expected values in the correct order: [0,1]. +PASS The index of value change is equal to 5504. PASS The rendered buffer contains non-zero values after the first sample. PASS successfullyParsed is true
diff --git a/third_party/WebKit/LayoutTests/webaudio/audiobuffersource-late-start.html b/third_party/WebKit/LayoutTests/webaudio/audiobuffersource-late-start.html index 0f61eca..9b2820a 100644 --- a/third_party/WebKit/LayoutTests/webaudio/audiobuffersource-late-start.html +++ b/third_party/WebKit/LayoutTests/webaudio/audiobuffersource-late-start.html
@@ -5,7 +5,6 @@ <script src="../resources/js-test.js"></script> <script src="resources/compatibility.js"></script> <script src="resources/audio-testing.js"></script> - <script src="resources/late-start-testing.js"></script> </head> <body> @@ -13,22 +12,77 @@ description('Test the late call of start(0) of BufferSource.'); window.jsTestIsAsync = true; - var audit = Audit.createTaskRunner(); + var renderQuantum = 128; var sampleRate = 44100; + var renderDuration = 0.25; + var startTime = 0.5 * renderDuration; - // The long render length (30 seconds) is to make sure the |onstatechange| - // event gets fired to start the source, which can take quite a bit of time. - var renderLength = 30; + var audit = Audit.createTaskRunner(); - var context = new OfflineAudioContext(1, sampleRate * renderLength, sampleRate); - var dcOffsetbuffer = createConstantBuffer(context, 1000, 1.0); - var source = context.createBufferSource(); - source.buffer = dcOffsetbuffer; + // Calculate the index for actual start time. + function getStartIndex(time) { + var startIndex = time * sampleRate; + return startIndex -= (startIndex) % renderQuantum; + } - // Test the buffer node is rendered correctly when the start time of start() - // call is in the past in terms of the context time. - runLateStartTest(audit, context, source); + // Get the index of value change. + function getValueChangeIndex(array, targetValue) { + return array.findIndex(function (element, index) { + if (element === targetValue) + return true; + }); + } + + audit.defineTask('test-late-start', function (done) { + var context = new OfflineAudioContext(1, renderDuration * sampleRate, sampleRate); + var dcOffsetbuffer = createConstantBuffer(context, 1, 1.0); + var source = context.createBufferSource(); + source.buffer = dcOffsetbuffer; + source.loop = true; + source.connect(context.destination); + + // Schedule source.start(0) at 0.01 second. The specified timing of + // start() call is already passed in terms of the context time. So the + // argument |0| will be clamped to the current context time. + // + // With the sample rate of 44100, 0.01 second is 441 samples. Rounding + // it down to the render quantum gives 384 samples. This is clearly larger + // than a single render quantum. + // + // See issue: crbug.com/462167 + context.suspend(startTime).then(function () { + source.start(0); + context.resume(); + }); + + // Start rendering and verify result: this verifies if 1) the rendered + // buffer contains at least one non-zero value and 2) the non-zero value is + // found later than the first output sample. + context.startRendering().then(function (buffer) { + + var channelData = buffer.getChannelData(0); + var startIndex = getStartIndex(startTime); + var nonZeroValueIndex = getValueChangeIndex(channelData, 1.0); + + Should('The output', channelData).containValues([0, 1]); + Should('The index of value change', nonZeroValueIndex) + .beEqualTo(startIndex); + + if (nonZeroValueIndex === 0) + testFailed('The first sample was non-zero value. It should be zero.'); + else + testPassed('The rendered buffer contains non-zero values after the first sample.'); + + }).then(done); + }); + + audit.defineTask('finish-test', function (done) { + done(); + finishJSTest(); + }); + + audit.runTasks(); successfullyParsed = true; </script>
diff --git a/third_party/WebKit/LayoutTests/webaudio/audiochannelmerger-disconnect-expected.txt b/third_party/WebKit/LayoutTests/webaudio/audiochannelmerger-disconnect-expected.txt index ec11c7a2..99229e5 100644 --- a/third_party/WebKit/LayoutTests/webaudio/audiochannelmerger-disconnect-expected.txt +++ b/third_party/WebKit/LayoutTests/webaudio/audiochannelmerger-disconnect-expected.txt
@@ -5,6 +5,7 @@ PASS Channel #0 contains only the constant 1. PASS Channel #1 contains all the expected values in the correct order: [1,0]. +PASS The index of first zero in the channel #1 is equal to 11008. PASS successfullyParsed is true TEST COMPLETE
diff --git a/third_party/WebKit/LayoutTests/webaudio/audiochannelmerger-disconnect.html b/third_party/WebKit/LayoutTests/webaudio/audiochannelmerger-disconnect.html index c100b8f..958cb12 100644 --- a/third_party/WebKit/LayoutTests/webaudio/audiochannelmerger-disconnect.html +++ b/third_party/WebKit/LayoutTests/webaudio/audiochannelmerger-disconnect.html
@@ -12,29 +12,27 @@ description('Test ChannelMergerNode behavior on dynamic input change.'); window.jsTestIsAsync = true; - var sampleRate = 44100; - var numberOfChannels = 2; + var renderQuantum = 128; - // The test needs the long render length (20 seconds) to capture the - // disconnection which happens after starting the rendering. - var renderLength = sampleRate * 20; + var numberOfChannels = 2; + var sampleRate = 44100; + var renderDuration = 0.5; + var disconnectTime = 0.5 * renderDuration; var audit = Audit.createTaskRunner(); // Task: Check if the merger outputs a silent channel when an input is // disconnected. audit.defineTask('silent-disconnect', function (done) { - var context = new OfflineAudioContext( - numberOfChannels, renderLength, sampleRate - ); + var context = new OfflineAudioContext(numberOfChannels, renderDuration * sampleRate, sampleRate); var merger = context.createChannelMerger(); var source1 = context.createBufferSource(); var source2 = context.createBufferSource(); - // Create and assign a mono testing buffer. - var bufferDCOffset = createTestingAudioBuffer(context, 1, renderLength); - source1.buffer = bufferDCOffset; - source2.buffer = bufferDCOffset; + // Create and assign a constant buffer. + var bufferDCOffset = createConstantBuffer(context, 1, 1); + source1.buffer = source2.buffer = bufferDCOffset; + source1.loop = source2.loop = true; // Connect the output of source into the 4th input of merger. The merger // should produce 6 channel output. @@ -44,22 +42,31 @@ source1.start(); source2.start(); - // When the rendering begins, disconnect |source2| as soon as possible. - context.onstatechange = function () { - if (context.state === 'running') - source2.disconnect(); - }; + // Schedule the disconnection of |source2| at the half of render duration. + context.suspend(disconnectTime).then(function () { + source2.disconnect(); + context.resume(); + }); context.startRendering().then(function (buffer) { - // The entire first channel of the output should be 1. Should('Channel #0', buffer.getChannelData(0)).beConstantValueOf(1); - // The second channel should contain 1, and 0 after the disconnection. - Should('Channel #1', buffer.getChannelData(1)).containValues([1, 0]); + // Calculate the first zero index in the second channel. + var channel1 = buffer.getChannelData(1); + var disconnectIndex = disconnectTime * sampleRate; + disconnectIndex -= (disconnectIndex) % renderQuantum; + var firstZeroIndex = channel1.findIndex(function (element, index) { + if (element === 0) + return index; + }); - done(); - }); + // The second channel should contain 1, and 0 after the disconnection. + Should('Channel #1', channel1).containValues([1, 0]); + Should('The index of first zero in the channel #1', firstZeroIndex) + .beEqualTo(disconnectIndex); + + }).then(done); }); audit.defineTask('finish', function (done) { @@ -67,10 +74,7 @@ done(); }); - audit.runTasks( - 'silent-disconnect', - 'finish' - ); + audit.runTasks(); successfullyParsed = true; </script>
diff --git a/third_party/WebKit/LayoutTests/webaudio/audionode-disconnect-audioparam-expected.txt b/third_party/WebKit/LayoutTests/webaudio/audionode-disconnect-audioparam-expected.txt index 9722864..d892b79e 100644 --- a/third_party/WebKit/LayoutTests/webaudio/audionode-disconnect-audioparam-expected.txt +++ b/third_party/WebKit/LayoutTests/webaudio/audionode-disconnect-audioparam-expected.txt
@@ -4,8 +4,11 @@ PASS Channel #0 contains all the expected values in the correct order: [2.25,1.5]. +PASS The index of value change is equal to 11008. PASS Channel #0 contains all the expected values in the correct order: [3,1.5]. +PASS The index of value change in channel #0 is equal to 11008. PASS Channel #1 contains all the expected values in the correct order: [6,3]. +PASS The index of value change in channel #1 is equal to 11008. PASS gain1.disconnect(gain3.gain) threw InvalidAccessError: Failed to execute 'disconnect' on 'AudioNode': the given AudioParam is not connected.. PASS splitter.disconnect(gain1.gain, 1) threw InvalidAccessError: Failed to execute 'disconnect' on 'AudioNode': specified destination AudioParam and node output (1) are not connected.. PASS splitter.disconnect(gain1.gain, 2) threw IndexSizeError: Failed to execute 'disconnect' on 'AudioNode': The output index provided (2) is outside the range [0, 1]..
diff --git a/third_party/WebKit/LayoutTests/webaudio/audionode-disconnect-audioparam.html b/third_party/WebKit/LayoutTests/webaudio/audionode-disconnect-audioparam.html index 3c9f1fb..04746db 100644 --- a/third_party/WebKit/LayoutTests/webaudio/audionode-disconnect-audioparam.html +++ b/third_party/WebKit/LayoutTests/webaudio/audionode-disconnect-audioparam.html
@@ -12,27 +12,44 @@ description('Test disconnect() method on AudioParam destination.'); window.jsTestIsAsync = true; + var renderQuantum = 128; + + var sampleRate = 44100; + var renderDuration = 0.5; + var disconnectTime = 0.5 * renderDuration; + var audit = Audit.createTaskRunner(); - // The long render length (20 seconds) test 1 and 2 is to make sure the - // |onstatechange| event gets fired to start the source, which can take - // quite a bit of time. - var testDuration = 20; + // Calculate the index for disconnection. + function getDisconnectIndex(disconnectTime) { + var disconnectIndex = disconnectTime * sampleRate; + return disconnectIndex -= (disconnectIndex) % renderQuantum; + } + + // Get the index of value change. + function getValueChangeIndex(array, targetValue) { + return array.findIndex(function (element, index) { + if (element === targetValue) + return true; + }); + } // Task 1: test disconnect(AudioParam) method. audit.defineTask('disconnect(AudioParam)', function (done) { // Creates a buffer source with value [1] and then connect it to two gain - // nodes in series. The output of the buffer source is lowered by half + // nodes in series. The output of the buffer source is lowered by half // (* 0.5) and then connected to two |.gain| AudioParams in each gain node. + // // (1) bufferSource => gain1 => gain2 // (2) bufferSource => half => gain1.gain // (3) half => gain2.gain + // // This graph should produce the output of 2.25 (= 1 * 1.5 * 1.5). After // disconnecting (3), it should produce 1.5. - var context = new OfflineAudioContext(1, 44100 * testDuration, 44100); + var context = new OfflineAudioContext(1, renderDuration * sampleRate, sampleRate); var source = context.createBufferSource(); - var buffer1ch = createTestingAudioBuffer(context, 1, 128); + var buffer1ch = createConstantBuffer(context, 1, 1); var half = context.createGain(); var gain1 = context.createGain(); var gain2 = context.createGain(); @@ -46,56 +63,51 @@ gain2.connect(context.destination); source.connect(half); - // Connecting |half| to both |gain1.gain| and |gain2.gain| amplifies the + // Connecting |half| to both |gain1.gain| and |gain2.gain| amplifies the // signal by 2.25 (= 1.5 * 1.5) because each gain node amplifies the signal // by 1.5 (= 1.0 + 0.5). - half.connect(gain1.gain); + half.connect(gain1.gain); half.connect(gain2.gain); - + source.start(); - // Disconnects after the rendering starts. - // - // FIXME: Although this guarantees that the disconnection happens after - // the rendering starts, still the actual disconnection might happen after - // oncomplete event fired. - // - // The 10ms delay is 1/1000 of the total render length (10,000ms). Because - // OfflineAudioContext runs faster than real time, the disconnection might - // happen after the rendering finishes. Then lower the delay and increase - // the render length to avoid the test failure. - context.onstatechange = function () { - if (context.state === 'running') - half.disconnect(gain2.gain); - }; + // Schedule the disconnection at the half of render duration. + context.suspend(disconnectTime).then(function () { + half.disconnect(gain2.gain); + context.resume(); + }); context.startRendering().then(function (buffer) { - - // Note that this test depends on the disconnection below to happen - // sometime during rendering. + var channelData = buffer.getChannelData(0); + var disconnectIndex = getDisconnectIndex(disconnectTime); + var valueChangeIndex = getValueChangeIndex(channelData, 1.5); // Expected values are: 1 * 1.5 * 1.5 -> 1 * 1.5 = [2.25, 1.5] - Should('Channel #0', buffer.getChannelData(0)).containValues([2.25, 1.5]); - + Should('Channel #0', channelData).containValues([2.25, 1.5]); + Should('The index of value change', valueChangeIndex) + .beEqualTo(disconnectIndex); + }).then(done); }); // Task 2: test disconnect(AudioParam, output) method. audit.defineTask('disconnect(AudioParam, output)', function (done) { - // Create a 2-channel buffer source with [1, 2] in each channel and + // Create a 2-channel buffer source with [1, 2] in each channel and // make a serial connection through gain1 and gain 2. The make the buffer // source half with a gain node and connect it to a 2-output splitter. // Connect each output to 2 gain AudioParams respectively. + // // (1) bufferSource => gain1 => gain2 // (2) bufferSource => half => splitter(2) // (3) splitter#0 => gain1.gain // (4) splitter#1 => gain2.gain - // This graph should produce 3 (= 1 * 1.5 * 2) and 6 (= 2 * 1.5 * 2) for + // + // This graph should produce 3 (= 1 * 1.5 * 2) and 6 (= 2 * 1.5 * 2) for // each channel. After disconnecting (4), it should output 1.5 and 3. - var context = new OfflineAudioContext(2, 44100 * testDuration, 44100); + var context = new OfflineAudioContext(2, renderDuration * sampleRate, sampleRate); var source = context.createBufferSource(); - var buffer2ch = createTestingAudioBuffer(context, 2, 128); + var buffer2ch = createConstantBuffer(context, 1, [1, 2]); var splitter = context.createChannelSplitter(2); var half = context.createGain(); var gain1 = context.createGain(); @@ -109,8 +121,8 @@ gain1.connect(gain2); gain2.connect(context.destination); - // |source| originally is [1, 2] but it becomes [0.5, 1] after 0.5 gain. - // Each splitter's output will be applied to |gain1.gain| and |gain2.gain| + // |source| originally is [1, 2] but it becomes [0.5, 1] after 0.5 gain. + // Each splitter's output will be applied to |gain1.gain| and |gain2.gain| // respectively in an additive fashion. source.connect(half); half.connect(splitter); @@ -123,20 +135,29 @@ source.start(); - // Disconnect after the rendering starts. See the comment in the previous - // test task. - context.onstatechange = function () { - if (context.state === 'running') - splitter.disconnect(gain2.gain, 1); - }; + // Schedule the disconnection at the half of render duration. + context.suspend(disconnectTime).then(function () { + splitter.disconnect(gain2.gain, 1); + context.resume(); + }); context.startRendering().then(function (buffer) { + var channelData0 = buffer.getChannelData(0); + var channelData1 = buffer.getChannelData(1); + var disconnectIndex = getDisconnectIndex(disconnectTime); + var valueChangeIndexCh0 = getValueChangeIndex(channelData0, 1.5); + var valueChangeIndexCh1 = getValueChangeIndex(channelData1, 3); + // Expected values are: 1 * 1.5 * 2 -> 1 * 1.5 = [3, 1.5] - Should('Channel #0', buffer.getChannelData(0)).containValues([3, 1.5]); + Should('Channel #0', channelData0).containValues([3, 1.5]); + Should('The index of value change in channel #0', valueChangeIndexCh0) + .beEqualTo(disconnectIndex); // Expected values are: 2 * 1.5 * 2 -> 2 * 1.5 = [6, 3] - Should('Channel #1', buffer.getChannelData(1)).containValues([6, 3]); + Should('Channel #1', channelData1).containValues([6, 3]); + Should('The index of value change in channel #1', valueChangeIndexCh1) + .beEqualTo(disconnectIndex); }).then(done); }); @@ -149,8 +170,8 @@ var gain2 = context.createGain(); var gain3 = context.createGain(); - // Connect a splitter to gain nodes and merger so we can test the possible - // ways of disconnecting the nodes to verify that appropriate exceptions + // Connect a splitter to gain nodes and merger so we can test the possible + // ways of disconnecting the nodes to verify that appropriate exceptions // are thrown. gain1.connect(splitter); splitter.connect(gain2.gain, 0);
diff --git a/third_party/WebKit/LayoutTests/webaudio/convolver-setBuffer-null-expected.txt b/third_party/WebKit/LayoutTests/webaudio/convolver-setBuffer-null-expected.txt index 62c8d7b..7b00bc7 100644 --- a/third_party/WebKit/LayoutTests/webaudio/convolver-setBuffer-null-expected.txt +++ b/third_party/WebKit/LayoutTests/webaudio/convolver-setBuffer-null-expected.txt
@@ -1,8 +1,8 @@ -Tests that ConvolverNode impulse response buffer can be set to 0. +Tests that ConvolverNode impulse response buffer can be set to null. On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE". -PASS ConvolverNode impulse response buffer was set to 0. +PASS ConvolverNode impulse response buffer was set to null. PASS successfullyParsed is true TEST COMPLETE
diff --git a/third_party/WebKit/LayoutTests/webaudio/convolver-setBuffer-null.html b/third_party/WebKit/LayoutTests/webaudio/convolver-setBuffer-null.html index a3803f7a..72a46e9 100644 --- a/third_party/WebKit/LayoutTests/webaudio/convolver-setBuffer-null.html +++ b/third_party/WebKit/LayoutTests/webaudio/convolver-setBuffer-null.html
@@ -11,7 +11,7 @@ <div id="console"></div> <script> -description("Tests that ConvolverNode impulse response buffer can be set to 0."); +description("Tests that ConvolverNode impulse response buffer can be set to null."); function runTest() { @@ -25,8 +25,8 @@ var context = new AudioContext(); var conv = context.createConvolver(); - conv.buffer = 0; - testPassed("ConvolverNode impulse response buffer was set to 0."); + conv.buffer = null; + testPassed("ConvolverNode impulse response buffer was set to null."); finishJSTest(); }
diff --git a/third_party/WebKit/LayoutTests/webaudio/dom-exceptions-expected.txt b/third_party/WebKit/LayoutTests/webaudio/dom-exceptions-expected.txt index f7892ccb..3aefb727 100644 --- a/third_party/WebKit/LayoutTests/webaudio/dom-exceptions-expected.txt +++ b/third_party/WebKit/LayoutTests/webaudio/dom-exceptions-expected.txt
@@ -52,6 +52,10 @@ PASS node.smoothingTimeConstant is not -0.1 PASS node.smoothingTimeConstant = 1.5 threw exception IndexSizeError: Failed to set the 'smoothingTimeConstant' property on 'AnalyserNode': The smoothing value provided (1.5) is outside the range [0, 1].. PASS node.smoothingTimeConstant is not 1.5 +PASS node.getFloatFrequencyData(null) threw exception TypeError: Failed to execute 'getFloatFrequencyData' on 'AnalyserNode': parameter 1 is not of type 'Float32Array'.. +PASS node.getByteFrequencyData(null) threw exception TypeError: Failed to execute 'getByteFrequencyData' on 'AnalyserNode': parameter 1 is not of type 'Uint8Array'.. +PASS node.getFloatTimeDomainData(null) threw exception TypeError: Failed to execute 'getFloatTimeDomainData' on 'AnalyserNode': parameter 1 is not of type 'Float32Array'.. +PASS node.getByteTimeDomainData(null) threw exception TypeError: Failed to execute 'getByteTimeDomainData' on 'AnalyserNode': parameter 1 is not of type 'Uint8Array'.. PASS node.getChannelData(2) threw exception IndexSizeError: Failed to execute 'getChannelData' on 'AudioBuffer': channel index (2) exceeds number of channels (1). PASS node.connect(null, 0, 0) threw exception TypeError: Failed to execute 'connect' on 'AudioNode': parameter 1 is not of type 'AudioNode'.. PASS node.connect(context.destination, 100, 0) threw exception IndexSizeError: Failed to execute 'connect' on 'AudioNode': output index (100) exceeds number of outputs (1).. @@ -66,6 +70,11 @@ PASS node.channelInterpretation = mode did not throw exception. PASS Invalid channelInterpration value did not change mode PASS context.destination.channelCount = 99 threw IndexSizeError exception on invalid channel count. +PASS param.setValueCurveAtTime(null, 0, 0) threw exception TypeError: Failed to execute 'setValueCurveAtTime' on 'AudioParam': parameter 1 is not of type 'Float32Array'.. +PASS node.getFrequencyResponse(new Float32Array(1), new Float32Array(1), new Float32Array(1)) did not throw exception. +PASS node.getFrequencyResponse(null, new Float32Array(1), new Float32Array(1)) threw exception TypeError: Failed to execute 'getFrequencyResponse' on 'BiquadFilterNode': parameter 1 is not of type 'Float32Array'.. +PASS node.getFrequencyResponse(new Float32Array(1), null, new Float32Array(1)) threw exception TypeError: Failed to execute 'getFrequencyResponse' on 'BiquadFilterNode': parameter 2 is not of type 'Float32Array'.. +PASS node.getFrequencyResponse(new Float32Array(1), new Float32Array(1), null) threw exception TypeError: Failed to execute 'getFrequencyResponse' on 'BiquadFilterNode': parameter 3 is not of type 'Float32Array'.. PASS new OfflineAudioContext(32, 100, context.sampleRate) did not throw exception. PASS new OfflineAudioContext(99, 100, context.sampleRate) threw exception IndexSizeError: Failed to construct 'OfflineAudioContext': The number of channels provided (99) is outside the range [0, 32].. PASS new OfflineAudioContext(1, 100, 1) threw exception IndexSizeError: Failed to construct 'OfflineAudioContext': The sampleRate provided (1) is outside the range [3000, 192000].. @@ -73,6 +82,7 @@ PASS new OfflineAudioContext(1, -88200000000000, 44100) threw exception NotSupportedError: Failed to construct 'OfflineAudioContext': OfflineAudioContext(1, 1448390656, 44100). PASS node.oversample = '9x' did not throw exception. PASS Invalid oversample value did not change node.oversample +PASS node.curve = {} threw exception TypeError: Failed to set the 'curve' property on 'WaveShaperNode': The provided value is not of type 'Float32Array'.. PASS node.curve = new Float32Array(1) threw exception InvalidAccessError: Failed to set the 'curve' property on 'WaveShaperNode': The curve length provided (1) is less than the minimum bound (2).. PASS node.curve is null PASS node.curve = new Float32Array(2) did not throw exception. @@ -135,12 +145,14 @@ PASS osc1 = context.createOscillator() did not throw exception. PASS osc1.start() did not throw exception. PASS osc1.stop() did not throw exception. +PASS osc.setPeriodicWave(null) threw exception TypeError: Failed to execute 'setPeriodicWave' on 'OscillatorNode': parameter 1 is not of type 'PeriodicWave'.. PASS node.gain.exponentialRampToValueAtTime(-1, 0.1) threw exception InvalidAccessError: Failed to execute 'exponentialRampToValueAtTime' on 'AudioParam': The float target value provided (-1) is outside the range [1.40130e-45, Infinity).. PASS node.gain.exponentialRampToValueAtTime(0, 0.1) threw exception InvalidAccessError: Failed to execute 'exponentialRampToValueAtTime' on 'AudioParam': The float target value provided (0) is outside the range [1.40130e-45, Infinity).. PASS node.gain.exponentialRampToValueAtTime(Math.pow(2, -149), 0.1) did not throw exception. PASS node.gain.exponentialRampToValueAtTime(Math.pow(2, -150), 0.1) threw exception InvalidAccessError: Failed to execute 'exponentialRampToValueAtTime' on 'AudioParam': The float target value provided (0) is outside the range [1.40130e-45, Infinity).. PASS oc = new OfflineAudioContext(1, 44100, 44100) did not throw exception. PASS conv = oc.createConvolver() did not throw exception. +PASS conv.buffer = {} threw exception TypeError: Failed to set the 'buffer' property on 'ConvolverNode': The provided value is not of type 'AudioBuffer'.. PASS conv.buffer = oc.createBuffer(1, 100, 22050) threw exception NotSupportedError: Failed to set the 'buffer' property on 'ConvolverNode': The buffer sample rate of 22050 does not match the context rate of 44100 Hz.. PASS conv.buffer is null PASS panner.channelCount = 1 did not throw exception.
diff --git a/third_party/WebKit/LayoutTests/webaudio/dom-exceptions.html b/third_party/WebKit/LayoutTests/webaudio/dom-exceptions.html index 4407134..1103943 100644 --- a/third_party/WebKit/LayoutTests/webaudio/dom-exceptions.html +++ b/third_party/WebKit/LayoutTests/webaudio/dom-exceptions.html
@@ -95,6 +95,11 @@ shouldThrowAndBeUnchanged("node.smoothingTimeConstant", "-0.1"); shouldThrowAndBeUnchanged("node.smoothingTimeConstant", "1.5"); + shouldThrow("node.getFloatFrequencyData(null)"); + shouldThrow("node.getByteFrequencyData(null)"); + shouldThrow("node.getFloatTimeDomainData(null)"); + shouldThrow("node.getByteTimeDomainData(null)"); + // AudioBuffers node = context.createBuffer(1,1, context.sampleRate); // Invalid channel index: IndexSizeError @@ -142,6 +147,17 @@ testFailed("context.destination.channelCount = 99 should throw IndexSizeError exception on invalid channel count."); } + // AudioParams + param = context.createGain().gain; + shouldThrow("param.setValueCurveAtTime(null, 0, 0)"); + + // BiquadFilterNode + node = context.createBiquadFilter(); + shouldNotThrow("node.getFrequencyResponse(new Float32Array(1), new Float32Array(1), new Float32Array(1))"); + shouldThrow("node.getFrequencyResponse(null, new Float32Array(1), new Float32Array(1))"); + shouldThrow("node.getFrequencyResponse(new Float32Array(1), null, new Float32Array(1))"); + shouldThrow("node.getFrequencyResponse(new Float32Array(1), new Float32Array(1), null)"); + // Delay nodes are tested elsewhere, so don't duplicate that work here. // OfflineAudioContext @@ -163,6 +179,7 @@ testPassed("Invalid oversample value did not change node.oversample"); else testFailed("node.oversample incorrectly changed to invalid value " + node.oversample); + shouldThrow("node.curve = {}"); shouldThrow("node.curve = new Float32Array(1)"); shouldBeNull("node.curve"); shouldNotThrow("node.curve = new Float32Array(2)"); @@ -246,6 +263,8 @@ shouldNotThrow("osc1.start()"); shouldNotThrow("osc1.stop()"); + shouldThrow("osc.setPeriodicWave(null)"); + // exponentialRampToValue should throw on non-positive target values. node = context.createGain(); node.connect(context.destination); @@ -266,10 +285,11 @@ // HW sample rates. shouldNotThrow("oc = new OfflineAudioContext(1, 44100, 44100)"); shouldNotThrow("conv = oc.createConvolver()"); + shouldThrow("conv.buffer = {}"); shouldThrow("conv.buffer = oc.createBuffer(1, 100, 22050)"); // conv.buffer should be unchanged (null) because the above failed. shouldBeNull("conv.buffer"); - + // PannerNode channel count and mode panner = context.createPanner(); // Channel count can only be set to 1 or 2.
diff --git a/third_party/WebKit/LayoutTests/webaudio/stereopannernode-no-glitch-expected.txt b/third_party/WebKit/LayoutTests/webaudio/stereopannernode-no-glitch-expected.txt index 25ae40bf..a6c7e47 100644 --- a/third_party/WebKit/LayoutTests/webaudio/stereopannernode-no-glitch-expected.txt +++ b/third_party/WebKit/LayoutTests/webaudio/stereopannernode-no-glitch-expected.txt
@@ -3,12 +3,12 @@ On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE". -PASS Transition found. (length = 15679) +PASS Transition found between sample #2175 and #17854. PASS Channel #0 has no glitch above the threshold of 0.0005. PASS Channel #1 has no glitch above the threshold of 0.0005. PASS Channel #0 equals [1.156434465040231,1.1562937736154577,...] with an element-wise tolerance of 1e-7. PASS Channel #1 equals [0.9876883405951378,0.987710613656166,...] with an element-wise tolerance of 1e-7. -PASS Transition found. (length = 15679) +PASS Transition found between sample #2175 and #17854. PASS Channel #0 has no glitch above the threshold of 0.0005. PASS Channel #1 has no glitch above the threshold of 0.0005. PASS Channel #0 equals [0.9876883405951378,0.987710613656166,...] with an element-wise tolerance of 1e-7.
diff --git a/third_party/WebKit/LayoutTests/webaudio/stereopannernode-no-glitch.html b/third_party/WebKit/LayoutTests/webaudio/stereopannernode-no-glitch.html index eccf740..fcb246d 100644 --- a/third_party/WebKit/LayoutTests/webaudio/stereopannernode-no-glitch.html +++ b/third_party/WebKit/LayoutTests/webaudio/stereopannernode-no-glitch.html
@@ -12,14 +12,8 @@ description('Test if StereoPannerNode producing glitches by crossing zero.'); window.jsTestIsAsync = true; - var audit = Audit.createTaskRunner(); - var sampleRate = 44100; - - // Note that this layout test requires rather large render duration because - // we need enough time to do something useful in the |onstatechange| event - // before rendering finishes. - var renderDuration = 20; + var renderDuration = 0.5; // The threshold for glitch detection. This was experimentally determined. var GLITCH_THRESHOLD = 0.0005; @@ -34,6 +28,7 @@ numberOfArrayLog: 2 }; + var audit = Audit.createTaskRunner(); // Extract a transitional region from the AudioBuffer. If no transition // found, fail this test. @@ -63,7 +58,7 @@ } end = index; - testPassed('Transition found. (length = ' + (end - start) + ')'); + testPassed('Transition found between sample #' + start + ' and #' + end + '.'); return { left: chanL.subarray(start, end), @@ -121,15 +116,15 @@ }; } - + // Build audio graph and render. Change the pan parameter in the middle of + // rendering. function panAndVerify(options, done) { - var context = new OfflineAudioContext(2, 44100 * renderDuration, 44100); + var context = new OfflineAudioContext(2, renderDuration * sampleRate, sampleRate); var source = context.createBufferSource(); var panner = context.createStereoPanner(); - var stereoBuffer = createConstantBuffer(context, 128, [1.0, 1.0]); + var stereoBuffer = createConstantBuffer(context, renderDuration * sampleRate, [1.0, 1.0]); source.buffer = stereoBuffer; - source.loop = true; panner.pan.value = options.startPanValue; @@ -137,10 +132,12 @@ panner.connect(context.destination); source.start(); - context.onstatechange = function () { - if (context.state === 'running') - panner.pan.value = options.endPanValue; - }; + // Schedule the parameter transition by the setter at 1/10 of the render + // duration. + context.suspend(0.1 * renderDuration).then(function () { + panner.pan.value = options.endPanValue; + context.resume(); + }); context.startRendering().then(function (buffer) { var actual = extractPanningTransition(buffer);
diff --git a/third_party/WebKit/LayoutTests/webexposed/css-properties-as-js-properties-expected.txt b/third_party/WebKit/LayoutTests/webexposed/css-properties-as-js-properties-expected.txt index 7232672..335c6f3 100644 --- a/third_party/WebKit/LayoutTests/webexposed/css-properties-as-js-properties-expected.txt +++ b/third_party/WebKit/LayoutTests/webexposed/css-properties-as-js-properties-expected.txt
@@ -78,6 +78,7 @@ colorInterpolationFilters colorRendering columnFill +contain content counterIncrement counterReset
diff --git a/third_party/WebKit/LayoutTests/webexposed/global-interface-listing-expected.txt b/third_party/WebKit/LayoutTests/webexposed/global-interface-listing-expected.txt index 117a8ad..83a5dd3 100644 --- a/third_party/WebKit/LayoutTests/webexposed/global-interface-listing-expected.txt +++ b/third_party/WebKit/LayoutTests/webexposed/global-interface-listing-expected.txt
@@ -3606,6 +3606,10 @@ setter onclose setter onerror setter onshow +interface NumberValue : StyleValue + getter value + method constructor + setter value interface OfflineAudioCompletionEvent : Event getter renderedBuffer method constructor
diff --git a/third_party/WebKit/ManualTests/NPN_Invoke/main.c b/third_party/WebKit/ManualTests/NPN_Invoke/main.c deleted file mode 100644 index b726b72..0000000 --- a/third_party/WebKit/ManualTests/NPN_Invoke/main.c +++ /dev/null
@@ -1,265 +0,0 @@ -/* - IMPORTANT: This Apple software is supplied to you by Apple Computer, Inc. ("Apple") in - consideration of your agreement to the following terms, and your use, installation, - modification or redistribution of this Apple software constitutes acceptance of these - terms. If you do not agree with these terms, please do not use, install, modify or - redistribute this Apple software. - - In consideration of your agreement to abide by the following terms, and subject to these - terms, Apple grants you a personal, non-exclusive license, under Apple's copyrights in - this original Apple software (the "Apple Software"), to use, reproduce, modify and - redistribute the Apple Software, with or without modifications, in source and/or binary - forms; provided that if you redistribute the Apple Software in its entirety and without - modifications, you must retain this notice and the following text and disclaimers in all - such redistributions of the Apple Software. Neither the name, trademarks, service marks - or logos of Apple Computer, Inc. may be used to endorse or promote products derived from - the Apple Software without specific prior written permission from Apple. Except as expressly - stated in this notice, no other rights or licenses, express or implied, are granted by Apple - herein, including but not limited to any patent rights that may be infringed by your - derivative works or by other works in which the Apple Software may be incorporated. - - The Apple Software is provided by Apple on an "AS IS" basis. APPLE MAKES NO WARRANTIES, - EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, - MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS - USE AND OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS. - - IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL OR CONSEQUENTIAL - DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS - OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, - REPRODUCTION, MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED AND - WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE), STRICT LIABILITY OR - OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#import <WebKit/npapi.h> -#import <WebKit/npfunctions.h> -#import <WebKit/npruntime.h> - -NPNetscapeFuncs *browser; - -NPError NPP_New(NPMIMEType pluginType, NPP instance, uint16_t mode, int16_t argc, char* argn[], char* argv[], NPSavedData* saved); -NPError NPP_Destroy(NPP instance, NPSavedData** save); -NPError NPP_SetWindow(NPP instance, NPWindow* window); -NPError NPP_NewStream(NPP instance, NPMIMEType type, NPStream* stream, NPBool seekable, uint16_t* stype); -NPError NPP_DestroyStream(NPP instance, NPStream* stream, NPReason reason); -int32_t NPP_WriteReady(NPP instance, NPStream* stream); -int32_t NPP_Write(NPP instance, NPStream* stream, int32_t offset, int32_t len, void* buffer); -void NPP_StreamAsFile(NPP instance, NPStream* stream, const char* fname); -void NPP_Print(NPP instance, NPPrint* platformPrint); -int16_t NPP_HandleEvent(NPP instance, void* event); -void NPP_URLNotify(NPP instance, const char* URL, NPReason reason, void* notifyData); -NPError NPP_GetValue(NPP instance, NPPVariable variable, void *value); -NPError NPP_SetValue(NPP instance, NPNVariable variable, void *value); - -#pragma export on -// Mach-o entry points -NPError NP_Initialize(NPNetscapeFuncs *browserFuncs); -NPError NP_GetEntryPoints(NPPluginFuncs *pluginFuncs); -void NP_Shutdown(void); -// For compatibility with CFM browsers. -int main(NPNetscapeFuncs *browserFuncs, NPPluginFuncs *pluginFuncs, NPP_ShutdownProcPtr *shutdown); -#pragma export off - - -typedef void (* FunctionPointer) (void); -typedef void (* TransitionVector) (void); -static FunctionPointer functionPointerForTVector(TransitionVector); -static TransitionVector tVectorForFunctionPointer(FunctionPointer); - -// Mach-o entry points -NPError NP_Initialize(NPNetscapeFuncs* browserFuncs) -{ - browser = browserFuncs; - return NPERR_NO_ERROR; -} - -NPError NP_GetEntryPoints(NPPluginFuncs* pluginFuncs) -{ - pluginFuncs->version = 11; - pluginFuncs->size = sizeof(pluginFuncs); - pluginFuncs->newp = NPP_New; - pluginFuncs->destroy = NPP_Destroy; - pluginFuncs->setwindow = NPP_SetWindow; - pluginFuncs->newstream = NPP_NewStream; - pluginFuncs->destroystream = NPP_DestroyStream; - pluginFuncs->asfile = NPP_StreamAsFile; - pluginFuncs->writeready = NPP_WriteReady; - pluginFuncs->write = (NPP_WriteProcPtr)NPP_Write; - pluginFuncs->print = NPP_Print; - pluginFuncs->event = NPP_HandleEvent; - pluginFuncs->urlnotify = NPP_URLNotify; - pluginFuncs->getvalue = NPP_GetValue; - pluginFuncs->setvalue = NPP_SetValue; - - return NPERR_NO_ERROR; -} - -void NP_Shutdown(void) -{ - -} - -// For compatibility with CFM browsers. -int main(NPNetscapeFuncs *browserFuncs, NPPluginFuncs *pluginFuncs, NPP_ShutdownProcPtr *shutdown) -{ - browser = malloc(sizeof(NPNetscapeFuncs)); - bzero(browser, sizeof(NPNetscapeFuncs)); - - browser->size = browserFuncs->size; - browser->version = browserFuncs->version; - - // Since this is a mach-o plugin and the browser is CFM because it is calling main, translate - // our function points into TVectors so the browser can call them. - browser->geturl = (NPN_GetURLProcPtr)functionPointerForTVector((TransitionVector)browserFuncs->geturl); - browser->posturl = (NPN_PostURLProcPtr)functionPointerForTVector((TransitionVector)browserFuncs->posturl); - browser->requestread = (NPN_RequestReadProcPtr)functionPointerForTVector((TransitionVector)browserFuncs->requestread); - browser->newstream = (NPN_NewStreamProcPtr)functionPointerForTVector((TransitionVector)browserFuncs->newstream); - browser->write = (NPN_WriteProcPtr)functionPointerForTVector((TransitionVector)browserFuncs->write); - browser->destroystream = (NPN_DestroyStreamProcPtr)functionPointerForTVector((TransitionVector)browserFuncs->destroystream); - browser->status = (NPN_StatusProcPtr)functionPointerForTVector((TransitionVector)browserFuncs->status); - browser->uagent = (NPN_UserAgentProcPtr)functionPointerForTVector((TransitionVector)browserFuncs->uagent); - browser->memalloc = (NPN_MemAllocProcPtr)functionPointerForTVector((TransitionVector)browserFuncs->memalloc); - browser->memfree = (NPN_MemFreeProcPtr)functionPointerForTVector((TransitionVector)browserFuncs->memfree); - browser->memflush = (NPN_MemFlushProcPtr)functionPointerForTVector((TransitionVector)browserFuncs->memflush); - browser->reloadplugins = (NPN_ReloadPluginsProcPtr)functionPointerForTVector((TransitionVector)browserFuncs->reloadplugins); - browser->geturlnotify = (NPN_GetURLNotifyProcPtr)functionPointerForTVector((TransitionVector)browserFuncs->geturlnotify); - browser->posturlnotify = (NPN_PostURLNotifyProcPtr)functionPointerForTVector((TransitionVector)browserFuncs->posturlnotify); - browser->getvalue = (NPN_GetValueProcPtr)functionPointerForTVector((TransitionVector)browserFuncs->getvalue); - browser->setvalue = (NPN_SetValueProcPtr)functionPointerForTVector((TransitionVector)browserFuncs->setvalue); - browser->invalidaterect = (NPN_InvalidateRectProcPtr)functionPointerForTVector((TransitionVector)browserFuncs->invalidaterect); - browser->invalidateregion = (NPN_InvalidateRegionProcPtr)functionPointerForTVector((TransitionVector)browserFuncs->invalidateregion); - browser->forceredraw = (NPN_ForceRedrawProcPtr)functionPointerForTVector((TransitionVector)browserFuncs->forceredraw); - browser->getJavaEnv = (NPN_GetJavaEnvProcPtr)functionPointerForTVector((TransitionVector)browserFuncs->getJavaEnv); - browser->getJavaPeer = (NPN_GetJavaPeerProcPtr)functionPointerForTVector((TransitionVector)browserFuncs->getJavaPeer); - - pluginFuncs->version = 11; - pluginFuncs->size = sizeof(pluginFuncs); - pluginFuncs->newp = (NPP_NewProcPtr)tVectorForFunctionPointer((FunctionPointer)NPP_New); - pluginFuncs->destroy = (NPP_DestroyProcPtr)tVectorForFunctionPointer((FunctionPointer)NPP_Destroy); - pluginFuncs->setwindow = (NPP_SetWindowProcPtr)tVectorForFunctionPointer((FunctionPointer)NPP_SetWindow); - pluginFuncs->newstream = (NPP_NewStreamProcPtr)tVectorForFunctionPointer((FunctionPointer)NPP_NewStream); - pluginFuncs->destroystream = (NPP_DestroyStreamProcPtr)tVectorForFunctionPointer((FunctionPointer)NPP_DestroyStream); - pluginFuncs->asfile = (NPP_StreamAsFileProcPtr)tVectorForFunctionPointer((FunctionPointer)NPP_StreamAsFile); - pluginFuncs->writeready = (NPP_WriteReadyProcPtr)tVectorForFunctionPointer((FunctionPointer)NPP_WriteReady); - pluginFuncs->write = (NPP_WriteProcPtr)tVectorForFunctionPointer((FunctionPointer)NPP_Write); - pluginFuncs->print = (NPP_PrintProcPtr)tVectorForFunctionPointer((FunctionPointer)NPP_Print); - pluginFuncs->event = (NPP_HandleEventProcPtr)tVectorForFunctionPointer((FunctionPointer)NPP_HandleEvent); - pluginFuncs->urlnotify = (NPP_URLNotifyProcPtr)tVectorForFunctionPointer((FunctionPointer)NPP_URLNotify); - pluginFuncs->getvalue = (NPP_GetValueProcPtr)tVectorForFunctionPointer((FunctionPointer)NPP_GetValue); - pluginFuncs->setvalue = (NPP_SetValueProcPtr)tVectorForFunctionPointer((FunctionPointer)NPP_SetValue); - - *shutdown = (NPP_ShutdownProcPtr)tVectorForFunctionPointer((FunctionPointer)NP_Shutdown); - - return NPERR_NO_ERROR; -} - -NPError NPP_New(NPMIMEType pluginType, NPP instance, uint16_t mode, int16_t argc, char* argn[], char* argv[], NPSavedData* saved) -{ - // Call window.alert("Success!") - NPError error; - NPObject *windowObject = NULL; - error = browser->getvalue(instance, NPNVWindowNPObject, &windowObject); - if (error == NPERR_NO_ERROR) { - NPVariant alertMessage; - STRINGZ_TO_NPVARIANT("Success!", alertMessage); - NPVariant result; - browser->invoke(instance, windowObject, browser->getstringidentifier("alert"), &alertMessage, 1, &result); - browser->releaseobject(windowObject); - } - - return NPERR_NO_ERROR; -} - -NPError NPP_Destroy(NPP instance, NPSavedData** save) -{ - return NPERR_NO_ERROR; -} - -NPError NPP_SetWindow(NPP instance, NPWindow* window) -{ - return NPERR_NO_ERROR; -} - -NPError NPP_NewStream(NPP instance, NPMIMEType type, NPStream* stream, NPBool seekable, uint16_t* stype) -{ - *stype = NP_ASFILEONLY; - return NPERR_NO_ERROR; -} - -NPError NPP_DestroyStream(NPP instance, NPStream* stream, NPReason reason) -{ - return NPERR_NO_ERROR; -} - -int32_t NPP_WriteReady(NPP instance, NPStream* stream) -{ - return 0; -} - -int32_t NPP_Write(NPP instance, NPStream* stream, int32_t offset, int32_t len, void* buffer) -{ - return 0; -} - -void NPP_StreamAsFile(NPP instance, NPStream* stream, const char* fname) -{ -} - -void NPP_Print(NPP instance, NPPrint* platformPrint) -{ - -} - -int16_t NPP_HandleEvent(NPP instance, void* event) -{ - return 1; -} - -void NPP_URLNotify(NPP instance, const char* url, NPReason reason, void* notifyData) -{ - -} - -NPError NPP_GetValue(NPP instance, NPPVariable variable, void *value) -{ - return NPERR_GENERIC_ERROR; -} - -NPError NPP_SetValue(NPP instance, NPNVariable variable, void *value) -{ - return NPERR_GENERIC_ERROR; -} - -// function pointer converters - -FunctionPointer functionPointerForTVector(TransitionVector tvp) -{ - const uint32_t temp[6] = {0x3D800000, 0x618C0000, 0x800C0000, 0x804C0004, 0x7C0903A6, 0x4E800420}; - uint32_t *newGlue = NULL; - - if (tvp != NULL) { - newGlue = (uint32_t *)malloc(sizeof(temp)); - if (newGlue != NULL) { - unsigned i; - for (i = 0; i < 6; i++) newGlue[i] = temp[i]; - newGlue[0] |= ((UInt32)tvp >> 16); - newGlue[1] |= ((UInt32)tvp & 0xFFFF); - MakeDataExecutable(newGlue, sizeof(temp)); - } - } - - return (FunctionPointer)newGlue; -} - -TransitionVector tVectorForFunctionPointer(FunctionPointer fp) -{ - FunctionPointer *newGlue = NULL; - if (fp != NULL) { - newGlue = (FunctionPointer *)malloc(2 * sizeof(FunctionPointer)); - if (newGlue != NULL) { - newGlue[0] = fp; - newGlue[1] = NULL; - } - } - return (TransitionVector)newGlue; -}
diff --git a/third_party/WebKit/ManualTests/NPN_Invoke/test.html b/third_party/WebKit/ManualTests/NPN_Invoke/test.html deleted file mode 100644 index 516470154..0000000 --- a/third_party/WebKit/ManualTests/NPN_Invoke/test.html +++ /dev/null
@@ -1,29 +0,0 @@ -<html> -<head> -<title>NPN_Invoke() test</title> -</head> -<body> - -<object width="0" height="0" type="test/npn-invoke"> - <!-- Fallback content to describe how to run the test -- /> - <p>You do not have the "NPN_Invoke" plugin installed. Before you run this test:</p> - <ol> - <li>Build the included Xcode project, "NPN_Invoke.xcodeproj".</li> - <li>Copy the built plugin (NPN_Invoke.plugin) to /Library/Internet Plug-Ins.</li> - <li>Restart Safari.</li> - </ol> -</object> - -<p>This tests NPN_Invoke(), part of the Netscape Plugin API scripting interface.</p> -<p>To verify, you must run this test with JavaScript enabled and then repeat the test with JavaScript disabled.</p> - -<h4>JavaScript enabled</h4> -<p style="color: green">Success: An alert dialog is shown with the message "Success!"</p> -<p style="color: red">Failure: No alert dialog is shown, or the message is not "Success!"</p> - -<h4>JavaScript disabled</h4> -<p style="color: green">Success: No alert dialog is shown, and Safari remains open (does not crash).</p> -<p style="color: red">Failure: An alert dialog is shown, or Safari crashes.</p> - -</body> -</html>
diff --git a/third_party/WebKit/Source/BUILD.gn b/third_party/WebKit/Source/BUILD.gn index da14ddd..14e4d9f 100644 --- a/third_party/WebKit/Source/BUILD.gn +++ b/third_party/WebKit/Source/BUILD.gn
@@ -30,6 +30,7 @@ include_dirs = [ ".", "..", + "$root_gen_dir/blink", ] cflags = []
diff --git a/third_party/WebKit/Source/bindings/core/v8/ScriptState.h b/third_party/WebKit/Source/bindings/core/v8/ScriptState.h index 85d7830..e093755d 100644 --- a/third_party/WebKit/Source/bindings/core/v8/ScriptState.h +++ b/third_party/WebKit/Source/bindings/core/v8/ScriptState.h
@@ -65,7 +65,7 @@ v8::Local<v8::Context> context = isolate->GetCurrentContext(); if (context.IsEmpty()) return false; - return context != v8::Debug::GetDebugContext(); + return context != v8::Debug::GetDebugContext(isolate); } static ScriptState* from(v8::Local<v8::Context> context)
diff --git a/third_party/WebKit/Source/core/core.gypi b/third_party/WebKit/Source/core/core.gypi index 0b32d3f..57d5cc942 100644 --- a/third_party/WebKit/Source/core/core.gypi +++ b/third_party/WebKit/Source/core/core.gypi
@@ -41,6 +41,7 @@ 'css/StyleSheetList.idl', 'css/WebKitCSSMatrix.idl', 'css/cssom/KeywordValue.idl', + 'css/cssom/NumberValue.idl', 'css/cssom/StyleValue.idl', 'dom/ArrayBuffer.idl', 'dom/ArrayBufferView.idl', @@ -1231,6 +1232,7 @@ 'css/StyleSheetList.h', 'css/cssom/KeywordValue.cpp', 'css/cssom/KeywordValue.h', + 'css/cssom/NumberValue.h', 'css/cssom/StyleValue.cpp', 'css/cssom/StyleValue.h', 'css/invalidation/InvalidationSet.cpp', @@ -3917,6 +3919,7 @@ 'loader/LinkHeaderTest.cpp', 'loader/LinkLoaderTest.cpp', 'loader/MixedContentCheckerTest.cpp', + 'page/ChromeClientTest.cpp', 'page/ContextMenuControllerTest.cpp', 'page/NetworkStateNotifierTest.cpp', 'page/PagePopupClientTest.cpp',
diff --git a/third_party/WebKit/Source/core/css/CSSPrimitiveValueMappings.h b/third_party/WebKit/Source/core/css/CSSPrimitiveValueMappings.h index a10c3c2..5f261fc 100644 --- a/third_party/WebKit/Source/core/css/CSSPrimitiveValueMappings.h +++ b/third_party/WebKit/Source/core/css/CSSPrimitiveValueMappings.h
@@ -4595,6 +4595,49 @@ return ScrollSnapTypeNone; } +template<> inline CSSPrimitiveValue::CSSPrimitiveValue(Containment snapType) + : CSSValue(PrimitiveClass) +{ + init(UnitType::ValueID); + switch (snapType) { + case ContainsNone: + m_value.valueID = CSSValueNone; + break; + case ContainsStrict: + m_value.valueID = CSSValueStrict; + break; + case ContainsPaint: + m_value.valueID = CSSValuePaint; + break; + case ContainsStyle: + m_value.valueID = CSSValueStyle; + break; + case ContainsLayout: + m_value.valueID = CSSValueLayout; + break; + } +} + +template<> inline Containment CSSPrimitiveValue::convertTo() const +{ + switch (getValueID()) { + case CSSValueNone: + return ContainsNone; + case CSSValueStrict: + return ContainsStrict; + case CSSValuePaint: + return ContainsPaint; + case CSSValueStyle: + return ContainsStyle; + case CSSValueLayout: + return ContainsLayout; + default: + break; + } + ASSERT_NOT_REACHED(); + return ContainsNone; +} + } // namespace blink #endif
diff --git a/third_party/WebKit/Source/core/css/CSSProperties.in b/third_party/WebKit/Source/core/css/CSSProperties.in index 6d4d2133..fd18ed9 100644 --- a/third_party/WebKit/Source/core/css/CSSProperties.in +++ b/third_party/WebKit/Source/core/css/CSSProperties.in
@@ -163,6 +163,7 @@ color-interpolation-filters inherited, svg, type_name=EColorInterpolation color-rendering inherited, svg column-fill runtime_flag=ColumnFill, type_name=ColumnFill +contain runtime_flag=CSSContainment, converter=convertFlags<Containment> content custom_all counter-increment custom_all counter-reset custom_all @@ -249,7 +250,7 @@ page-break-inside type_name=EPageBreak, initial=initialPageBreak paint-order inherited, svg, converter=convertPaintOrder perspective interpolable, converter=convertPerspective -perspective-origin interpolable, converter=convertPerspectiveOrigin +perspective-origin interpolable, converter=convertPosition pointer-events inherited position quotes inherited, converter=convertQuotes @@ -447,7 +448,7 @@ background longhands=background-image;background-position-x;background-position-y;background-size;background-repeat-x;background-repeat-y;background-attachment;background-origin;background-clip;background-color background-position longhands=background-position-x;background-position-y background-repeat longhands=background-repeat-x;background-repeat-y -border longhands=border-top-color;border-top-style;border-top-width;border-right-color;border-right-style;border-right-width;border-bottom-color;border-bottom-style;border-bottom-width;border-left-color;border-left-style;border-left-width +border longhands=border-top-color;border-top-style;border-top-width;border-right-color;border-right-style;border-right-width;border-bottom-color;border-bottom-style;border-bottom-width;border-left-color;border-left-style;border-left-width;border-image-source;border-image-slice;border-image-width;border-image-outset;border-image-repeat border-bottom longhands=border-bottom-width;border-bottom-style;border-bottom-color border-color longhands=border-top-color;border-right-color;border-bottom-color;border-left-color border-image longhands=border-image-source;border-image-slice;border-image-width;border-image-outset;border-image-repeat
diff --git a/third_party/WebKit/Source/core/css/CSSValueKeywords.in b/third_party/WebKit/Source/core/css/CSSValueKeywords.in index 79ceda3..ea1e0c43 100644 --- a/third_party/WebKit/Source/core/css/CSSValueKeywords.in +++ b/third_party/WebKit/Source/core/css/CSSValueKeywords.in
@@ -1054,5 +1054,10 @@ proximity from-image +// containment +paint +style +layout + var -internal-variable-value
diff --git a/third_party/WebKit/Source/core/css/ComputedStyleCSSValueMapping.cpp b/third_party/WebKit/Source/core/css/ComputedStyleCSSValueMapping.cpp index 2b4ff3a..27e94c1 100644 --- a/third_party/WebKit/Source/core/css/ComputedStyleCSSValueMapping.cpp +++ b/third_party/WebKit/Source/core/css/ComputedStyleCSSValueMapping.cpp
@@ -2679,6 +2679,22 @@ list->append(cssValuePool().createValue(style.scale()->z(), CSSPrimitiveValue::UnitType::Number)); return list.release(); } + case CSSPropertyContain: { + if (!style.contain()) + return cssValuePool().createIdentifierValue(CSSValueNone); + if (style.contain() == ContainsStrict) + return cssValuePool().createIdentifierValue(CSSValueStrict); + + RefPtrWillBeRawPtr<CSSValueList> list = CSSValueList::createSpaceSeparated(); + if (style.contain() & ContainsStyle) + list->append(cssValuePool().createIdentifierValue(CSSValueStyle)); + if (style.contain() & ContainsLayout) + list->append(cssValuePool().createIdentifierValue(CSSValueLayout)); + if (style.contain() & ContainsPaint) + list->append(cssValuePool().createIdentifierValue(CSSValuePaint)); + ASSERT(list->length()); + return list.release(); + } case CSSPropertyVariable: // TODO(leviw): We should have a way to retrive variables here. ASSERT_NOT_REACHED();
diff --git a/third_party/WebKit/Source/core/css/MediaQueryEvaluator.cpp b/third_party/WebKit/Source/core/css/MediaQueryEvaluator.cpp index b2c7a68..161fece 100644 --- a/third_party/WebKit/Source/core/css/MediaQueryEvaluator.cpp +++ b/third_party/WebKit/Source/core/css/MediaQueryEvaluator.cpp
@@ -393,7 +393,7 @@ static bool heightMediaFeatureEval(const MediaQueryExpValue& value, MediaFeaturePrefix op, const MediaValues& mediaValues) { - int height = mediaValues.viewportHeight(); + double height = mediaValues.viewportHeight(); if (value.isValid()) return computeLengthAndCompare(value, op, mediaValues, height); @@ -402,7 +402,7 @@ static bool widthMediaFeatureEval(const MediaQueryExpValue& value, MediaFeaturePrefix op, const MediaValues& mediaValues) { - int width = mediaValues.viewportWidth(); + double width = mediaValues.viewportWidth(); if (value.isValid()) return computeLengthAndCompare(value, op, mediaValues, width);
diff --git a/third_party/WebKit/Source/core/css/MediaQueryEvaluatorTest.cpp b/third_party/WebKit/Source/core/css/MediaQueryEvaluatorTest.cpp index 6770c7e4..25ee2ce 100644 --- a/third_party/WebKit/Source/core/css/MediaQueryEvaluatorTest.cpp +++ b/third_party/WebKit/Source/core/css/MediaQueryEvaluatorTest.cpp
@@ -92,6 +92,30 @@ {0, 0} // Do not remove the terminator line. }; +TestCase floatViewportTestCases[] = { + {"all and (min-width: 600.5px)", 1}, + {"(min-width: 600px)", 1}, + {"(min-width: 600.5px)", 1}, + {"(min-width: 601px)", 0}, + {"(max-width: 600px)", 0}, + {"(max-width: 600.5px)", 1}, + {"(max-width: 601px)", 1}, + {"(width: 600.5px)", 1}, + {"(width: 601px)", 0}, + {"(min-height: 700px)", 1}, + {"(min-height: 700.125px)", 1}, + {"(min-height: 701px)", 0}, + {"(min-height: 700.126px)", 0}, + {"(max-height: 701px)", 1}, + {"(max-height: 700.125px)", 1}, + {"(max-height: 700px)", 0}, + {"(height: 700.125px)", 1}, + {"(height: 700.126px)", 0}, + {"(height: 700.124px)", 0}, + {"(height: 701px)", 0}, + {0, 0} // Do not remove the terminator line. +}; + TestCase printTestCases[] = { {"print and (min-resolution: 1dppx)", 1}, {"print and (min-resolution: 118dpcm)", 1}, @@ -159,4 +183,15 @@ EXPECT_FALSE(mediaQueryEvaluator.eval(querySet.get())); } +TEST(MediaQueryEvaluatorTest, CachedFloatViewport) +{ + MediaValuesCached::MediaValuesCachedData data; + data.viewportWidth = 600.5; + data.viewportHeight = 700.125; + RefPtrWillBeRawPtr<MediaValues> mediaValues = MediaValuesCached::create(data); + + MediaQueryEvaluator mediaQueryEvaluator(*mediaValues); + testMQEvaluator(floatViewportTestCases, mediaQueryEvaluator); +} + } // namespace
diff --git a/third_party/WebKit/Source/core/css/MediaValues.cpp b/third_party/WebKit/Source/core/css/MediaValues.cpp index 294df98..a36c341 100644 --- a/third_party/WebKit/Source/core/css/MediaValues.cpp +++ b/third_party/WebKit/Source/core/css/MediaValues.cpp
@@ -32,18 +32,18 @@ return MediaValuesCached::create(); } -int MediaValues::calculateViewportWidth(LocalFrame* frame) const +double MediaValues::calculateViewportWidth(LocalFrame* frame) const { ASSERT(frame && frame->view() && frame->document()); int viewportWidth = frame->view()->layoutSize(IncludeScrollbars).width(); - return adjustForAbsoluteZoom(viewportWidth, frame->document()->layoutView()); + return adjustDoubleForAbsoluteZoom(viewportWidth, *frame->document()->layoutView()); } -int MediaValues::calculateViewportHeight(LocalFrame* frame) const +double MediaValues::calculateViewportHeight(LocalFrame* frame) const { ASSERT(frame && frame->view() && frame->document()); int viewportHeight = frame->view()->layoutSize(IncludeScrollbars).height(); - return adjustForAbsoluteZoom(viewportHeight, frame->document()->layoutView()); + return adjustDoubleForAbsoluteZoom(viewportHeight, *frame->document()->layoutView()); } int MediaValues::calculateDeviceWidth(LocalFrame* frame) const @@ -153,7 +153,7 @@ return frame->settings()->availableHoverTypes(); } -bool MediaValues::computeLengthImpl(double value, CSSPrimitiveValue::UnitType type, unsigned defaultFontSize, unsigned viewportWidth, unsigned viewportHeight, double& result) +bool MediaValues::computeLengthImpl(double value, CSSPrimitiveValue::UnitType type, unsigned defaultFontSize, double viewportWidth, double viewportHeight, double& result) { // The logic in this function is duplicated from CSSToLengthConversionData::zoomedComputedPixels() // because MediaValues::computeLength() needs nearly identical logic, but we haven't found a way to make
diff --git a/third_party/WebKit/Source/core/css/MediaValues.h b/third_party/WebKit/Source/core/css/MediaValues.h index d32c002..7ce4fdf 100644 --- a/third_party/WebKit/Source/core/css/MediaValues.h +++ b/third_party/WebKit/Source/core/css/MediaValues.h
@@ -28,9 +28,9 @@ virtual PassRefPtrWillBeRawPtr<MediaValues> copy() const = 0; virtual bool isSafeToSendToAnotherThread() const = 0; - static bool computeLengthImpl(double value, CSSPrimitiveValue::UnitType, unsigned defaultFontSize, unsigned viewportWidth, unsigned viewportHeight, double& result); + static bool computeLengthImpl(double value, CSSPrimitiveValue::UnitType, unsigned defaultFontSize, double viewportWidth, double viewportHeight, double& result); template<typename T> - static bool computeLength(double value, CSSPrimitiveValue::UnitType type, unsigned defaultFontSize, unsigned viewportWidth, unsigned viewportHeight, T& result) + static bool computeLength(double value, CSSPrimitiveValue::UnitType type, unsigned defaultFontSize, double viewportWidth, double viewportHeight, T& result) { double tempResult; if (!computeLengthImpl(value, type, defaultFontSize, viewportWidth, viewportHeight, tempResult)) @@ -41,8 +41,8 @@ virtual bool computeLength(double value, CSSPrimitiveValue::UnitType, int& result) const = 0; virtual bool computeLength(double value, CSSPrimitiveValue::UnitType, double& result) const = 0; - virtual int viewportWidth() const = 0; - virtual int viewportHeight() const = 0; + virtual double viewportWidth() const = 0; + virtual double viewportHeight() const = 0; virtual int deviceWidth() const = 0; virtual int deviceHeight() const = 0; virtual float devicePixelRatio() const = 0; @@ -62,8 +62,8 @@ virtual bool isCached() const { return false; } protected: - int calculateViewportWidth(LocalFrame*) const; - int calculateViewportHeight(LocalFrame*) const; + double calculateViewportWidth(LocalFrame*) const; + double calculateViewportHeight(LocalFrame*) const; int calculateDeviceWidth(LocalFrame*) const; int calculateDeviceHeight(LocalFrame*) const; bool calculateStrictMode(LocalFrame*) const;
diff --git a/third_party/WebKit/Source/core/css/MediaValuesCached.cpp b/third_party/WebKit/Source/core/css/MediaValuesCached.cpp index 3dedbd1..b4fd8efd 100644 --- a/third_party/WebKit/Source/core/css/MediaValuesCached.cpp +++ b/third_party/WebKit/Source/core/css/MediaValuesCached.cpp
@@ -100,12 +100,12 @@ #endif } -int MediaValuesCached::viewportWidth() const +double MediaValuesCached::viewportWidth() const { return m_data.viewportWidth; } -int MediaValuesCached::viewportHeight() const +double MediaValuesCached::viewportHeight() const { return m_data.viewportHeight; } @@ -185,12 +185,12 @@ return true; } -void MediaValuesCached::setViewportWidth(int width) +void MediaValuesCached::setViewportWidth(double width) { m_data.viewportWidth = width; } -void MediaValuesCached::setViewportHeight(int height) +void MediaValuesCached::setViewportHeight(double height) { m_data.viewportHeight = height; }
diff --git a/third_party/WebKit/Source/core/css/MediaValuesCached.h b/third_party/WebKit/Source/core/css/MediaValuesCached.h index 5f5331e..3bd3f62 100644 --- a/third_party/WebKit/Source/core/css/MediaValuesCached.h +++ b/third_party/WebKit/Source/core/css/MediaValuesCached.h
@@ -15,8 +15,8 @@ struct MediaValuesCachedData { DISALLOW_NEW(); // Members variables must be thread safe, since they're copied to the parser thread - int viewportWidth; - int viewportHeight; + double viewportWidth; + double viewportHeight; int deviceWidth; int deviceHeight; float devicePixelRatio; @@ -61,8 +61,8 @@ bool computeLength(double value, CSSPrimitiveValue::UnitType, int& result) const override; bool computeLength(double value, CSSPrimitiveValue::UnitType, double& result) const override; - int viewportWidth() const override; - int viewportHeight() const override; + double viewportWidth() const override; + double viewportHeight() const override; int deviceWidth() const override; int deviceHeight() const override; float devicePixelRatio() const override; @@ -79,8 +79,8 @@ const String mediaType() const override; WebDisplayMode displayMode() const override; - void setViewportWidth(int); - void setViewportHeight(int); + void setViewportWidth(double); + void setViewportHeight(double); bool isCached() const override { return true; } protected:
diff --git a/third_party/WebKit/Source/core/css/MediaValuesDynamic.cpp b/third_party/WebKit/Source/core/css/MediaValuesDynamic.cpp index a222f9d..eaf80b50 100644 --- a/third_party/WebKit/Source/core/css/MediaValuesDynamic.cpp +++ b/third_party/WebKit/Source/core/css/MediaValuesDynamic.cpp
@@ -62,12 +62,12 @@ return false; } -int MediaValuesDynamic::viewportWidth() const +double MediaValuesDynamic::viewportWidth() const { return calculateViewportWidth(m_frame); } -int MediaValuesDynamic::viewportHeight() const +double MediaValuesDynamic::viewportHeight() const { return calculateViewportHeight(m_frame); }
diff --git a/third_party/WebKit/Source/core/css/MediaValuesDynamic.h b/third_party/WebKit/Source/core/css/MediaValuesDynamic.h index 6a1731c9..e6698d27 100644 --- a/third_party/WebKit/Source/core/css/MediaValuesDynamic.h +++ b/third_party/WebKit/Source/core/css/MediaValuesDynamic.h
@@ -20,8 +20,8 @@ bool computeLength(double value, CSSPrimitiveValue::UnitType, int& result) const override; bool computeLength(double value, CSSPrimitiveValue::UnitType, double& result) const override; - int viewportWidth() const override; - int viewportHeight() const override; + double viewportWidth() const override; + double viewportHeight() const override; int deviceWidth() const override; int deviceHeight() const override; float devicePixelRatio() const override;
diff --git a/third_party/WebKit/Source/core/css/cssom/KeywordValue.cpp b/third_party/WebKit/Source/core/css/cssom/KeywordValue.cpp index 1022150..41f9c6e 100644 --- a/third_party/WebKit/Source/core/css/cssom/KeywordValue.cpp +++ b/third_party/WebKit/Source/core/css/cssom/KeywordValue.cpp
@@ -49,7 +49,7 @@ } } -const String& KeywordValue::cssString() const +String KeywordValue::cssString() const { return keywordValue(); }
diff --git a/third_party/WebKit/Source/core/css/cssom/KeywordValue.h b/third_party/WebKit/Source/core/css/cssom/KeywordValue.h index 6bdb0a77..5816fe37 100644 --- a/third_party/WebKit/Source/core/css/cssom/KeywordValue.h +++ b/third_party/WebKit/Source/core/css/cssom/KeywordValue.h
@@ -23,7 +23,7 @@ virtual const String& keywordValue() const; - const String& cssString() const override; + String cssString() const override; PassRefPtrWillBeRawPtr<CSSValue> toCSSValue() override; protected:
diff --git a/third_party/WebKit/Source/core/css/cssom/NumberValue.h b/third_party/WebKit/Source/core/css/cssom/NumberValue.h new file mode 100644 index 0000000..ed4bfc2 --- /dev/null +++ b/third_party/WebKit/Source/core/css/cssom/NumberValue.h
@@ -0,0 +1,43 @@ +#ifndef NumberValue_h +#define NumberValue_h + +#include "bindings/core/v8/ScriptWrappable.h" +#include "core/CoreExport.h" +#include "core/css/CSSPrimitiveValue.h" +#include "core/css/cssom/StyleValue.h" +#include "wtf/text/WTFString.h" + +namespace blink { + +class CORE_EXPORT NumberValue final : public StyleValue { + DEFINE_WRAPPERTYPEINFO(); +public: + static PassRefPtrWillBeRawPtr<NumberValue> create(double value) + { + return adoptRefWillBeNoop(new NumberValue(value)); + } + + double value() const { return m_value; } + void setValue(double value) + { + m_value = value; + } + + String cssString() const override { return String::number(m_value); } + + PassRefPtrWillBeRawPtr<CSSValue> toCSSValue() override + { + return cssValuePool().createValue(m_value, CSSPrimitiveValue::UnitType:: +Number); + } + + StyleValueType type() const override { return StyleValueType::NumberType; } +protected: + NumberValue(double value) : m_value(value) {} + + double m_value; +}; + +} // namespace blink + +#endif
diff --git a/third_party/WebKit/Source/core/css/cssom/NumberValue.idl b/third_party/WebKit/Source/core/css/cssom/NumberValue.idl new file mode 100644 index 0000000..7080174 --- /dev/null +++ b/third_party/WebKit/Source/core/css/cssom/NumberValue.idl
@@ -0,0 +1,6 @@ + [ + Constructor(double value), + RuntimeEnabled=CSSTypedOM + ] interface NumberValue : StyleValue { + attribute double value; + };
diff --git a/third_party/WebKit/Source/core/css/cssom/StyleValue.h b/third_party/WebKit/Source/core/css/cssom/StyleValue.h index 7dc1841..2b70c7c5 100644 --- a/third_party/WebKit/Source/core/css/cssom/StyleValue.h +++ b/third_party/WebKit/Source/core/css/cssom/StyleValue.h
@@ -24,7 +24,7 @@ static PassRefPtrWillBeRawPtr<StyleValue> create(const CSSValue&); static ScriptValue parse(ScriptState*, const String& property, const String& cssText); - virtual const String& cssString() const = 0; + virtual String cssString() const = 0; virtual PassRefPtrWillBeRawPtr<CSSValue> toCSSValue() = 0; DEFINE_INLINE_VIRTUAL_TRACE() { }
diff --git a/third_party/WebKit/Source/core/css/invalidation/InvalidationSet.cpp b/third_party/WebKit/Source/core/css/invalidation/InvalidationSet.cpp index 180c313..1eff1df 100644 --- a/third_party/WebKit/Source/core/css/invalidation/InvalidationSet.cpp +++ b/third_party/WebKit/Source/core/css/invalidation/InvalidationSet.cpp
@@ -51,8 +51,9 @@ s_tracingEnabled = TRACE_EVENT_API_GET_CATEGORY_GROUP_ENABLED(TRACE_DISABLED_BY_DEFAULT("devtools.timeline.invalidationTracking")); } -InvalidationSet::InvalidationSet() - : m_allDescendantsMightBeInvalid(false) +InvalidationSet::InvalidationSet(InvalidationType type) + : m_type(type) + , m_allDescendantsMightBeInvalid(false) , m_invalidatesSelf(false) , m_customPseudoInvalid(false) , m_treeBoundaryCrossing(false) @@ -99,6 +100,8 @@ void InvalidationSet::combine(const InvalidationSet& other) { + ASSERT(m_type == other.m_type); + // No longer bother combining data structures, since the whole subtree is deemed invalid. if (wholeSubtreeInvalid()) return; @@ -141,6 +144,14 @@ } } +void InvalidationSet::destroy() +{ + if (isDescendantInvalidationSet()) + delete toDescendantInvalidationSet(this); + else + delete toSiblingInvalidationSet(this); +} + HashSet<AtomicString>& InvalidationSet::ensureClassSet() { if (!m_classes) @@ -270,7 +281,8 @@ #endif // NDEBUG SiblingInvalidationSet::SiblingInvalidationSet() - : m_maxDirectAdjacentSelectors(1) + : InvalidationSet(InvalidateSiblings) + , m_maxDirectAdjacentSelectors(1) , m_descendantInvalidationSet(DescendantInvalidationSet::create()) { }
diff --git a/third_party/WebKit/Source/core/css/invalidation/InvalidationSet.h b/third_party/WebKit/Source/core/css/invalidation/InvalidationSet.h index 3a922578..f6010ee4 100644 --- a/third_party/WebKit/Source/core/css/invalidation/InvalidationSet.h +++ b/third_party/WebKit/Source/core/css/invalidation/InvalidationSet.h
@@ -58,10 +58,8 @@ WTF_MAKE_NONCOPYABLE(InvalidationSet); USING_FAST_MALLOC_WITH_TYPE_NAME(blink::InvalidationSet); public: - virtual ~InvalidationSet() {} - - virtual bool isDescendantInvalidationSet() const { return false; } - virtual bool isSiblingInvalidationSet() const { return false; } + bool isDescendantInvalidationSet() const { return m_type == InvalidateDescendants; } + bool isSiblingInvalidationSet() const { return m_type == InvalidateSiblings; } static void cacheTracingFlag(); @@ -100,12 +98,21 @@ const HashSet<AtomicString>& tagNameSetForTesting() const { ASSERT(m_tagNames); return *m_tagNames; } const HashSet<AtomicString>& attributeSetForTesting() const { ASSERT(m_attributes); return *m_attributes; } + void deref() + { + if (!derefBase()) + return; + destroy(); + } + protected: - InvalidationSet(); + InvalidationSet(InvalidationType); void combine(const InvalidationSet& other); private: + void destroy(); + HashSet<AtomicString>& ensureClassSet(); HashSet<AtomicString>& ensureIdSet(); HashSet<AtomicString>& ensureTagNameSet(); @@ -117,6 +124,8 @@ OwnPtr<HashSet<AtomicString>> m_tagNames; OwnPtr<HashSet<AtomicString>> m_attributes; + unsigned m_type : 1; + // If true, all descendants might be invalidated, so a full subtree recalc is required. unsigned m_allDescendantsMightBeInvalid : 1; @@ -140,15 +149,14 @@ return adoptRef(new DescendantInvalidationSet); } - bool isDescendantInvalidationSet() const final { return true; } - void combine(const DescendantInvalidationSet& other) { InvalidationSet::combine(other); } private: - DescendantInvalidationSet() {} + DescendantInvalidationSet() + : InvalidationSet(InvalidateDescendants) {} }; class CORE_EXPORT SiblingInvalidationSet final : public InvalidationSet { @@ -158,8 +166,6 @@ return adoptRef(new SiblingInvalidationSet); } - bool isSiblingInvalidationSet() const final { return true; } - void combine(const SiblingInvalidationSet& other); DescendantInvalidationSet& descendants() { return *m_descendantInvalidationSet; }
diff --git a/third_party/WebKit/Source/core/css/parser/CSSPropertyParser.cpp b/third_party/WebKit/Source/core/css/parser/CSSPropertyParser.cpp index f7d85192..671cabf 100644 --- a/third_party/WebKit/Source/core/css/parser/CSSPropertyParser.cpp +++ b/third_party/WebKit/Source/core/css/parser/CSSPropertyParser.cpp
@@ -602,21 +602,6 @@ return consumeLengthOrPercent(range, cssParserMode, ValueRangeAll, unitless); } -static PassRefPtrWillBeRawPtr<CSSPrimitiveValue> resolvePositionComponentKeywords(PassRefPtrWillBeRawPtr<CSSPrimitiveValue> value) -{ - if (!value->isValueID()) - return value; - CSSValueID id = value->getValueID(); - int percent = 0; - if (id == CSSValueCenter) - percent = 50; - else if (id == CSSValueBottom || id == CSSValueRight) - percent = 100; - else - ASSERT(id == CSSValueLeft || id == CSSValueTop); - return cssValuePool().createValue(percent, CSSPrimitiveValue::UnitType::Percentage); -} - static bool isHorizontalPositionKeywordOnly(const CSSPrimitiveValue& value) { return value.isValueID() && (value.getValueID() == CSSValueLeft || value.getValueID() == CSSValueRight); @@ -630,8 +615,8 @@ static void positionFromOneValue(PassRefPtrWillBeRawPtr<CSSPrimitiveValue> value, RefPtrWillBeRawPtr<CSSValue>& resultX, RefPtrWillBeRawPtr<CSSValue>& resultY) { bool valueAppliesToYAxisOnly = isVerticalPositionKeywordOnly(*value); - resultX = resolvePositionComponentKeywords(value); - resultY = cssValuePool().createValue(50, CSSPrimitiveValue::UnitType::Percentage); + resultX = value; + resultY = cssValuePool().createIdentifierValue(CSSValueCenter); if (valueAppliesToYAxisOnly) swap(resultX, resultY); } @@ -644,8 +629,8 @@ bool mustOrderAsYX = isVerticalPositionKeywordOnly(*value1) || isHorizontalPositionKeywordOnly(*value2); if (mustOrderAsXY && mustOrderAsYX) return false; - resultX = resolvePositionComponentKeywords(value1); - resultY = resolvePositionComponentKeywords(value2); + resultX = value1; + resultY = value2; if (mustOrderAsYX) swap(resultX, resultY); return true; @@ -653,7 +638,7 @@ static bool positionFromThreeOrFourValues(CSSPrimitiveValue** values, RefPtrWillBeRawPtr<CSSValue>& resultX, RefPtrWillBeRawPtr<CSSValue>& resultY) { - bool seenCenter = false; + CSSPrimitiveValue* center = nullptr; for (int i = 0; values[i]; i++) { CSSPrimitiveValue* currentValue = values[i]; if (!currentValue->isValueID()) @@ -661,42 +646,39 @@ CSSValueID id = currentValue->getValueID(); if (id == CSSValueCenter) { - if (seenCenter) + if (center) return false; - seenCenter = true; + center = currentValue; continue; } - RefPtrWillBeRawPtr<CSSPrimitiveValue> offset = nullptr; + RefPtrWillBeRawPtr<CSSValue> result = nullptr; if (values[i + 1] && !values[i + 1]->isValueID()) { - offset = values[++i]; + result = CSSValuePair::create(currentValue, values[++i], CSSValuePair::KeepIdenticalValues); } else { - offset = cssValuePool().createValue(0, CSSPrimitiveValue::UnitType::Percentage); + result = currentValue; } - RefPtrWillBeRawPtr<CSSValuePair> pair = CSSValuePair::create(currentValue, offset.release(), CSSValuePair::KeepIdenticalValues); - if (id == CSSValueLeft || id == CSSValueRight) { if (resultX) return false; - resultX = pair.release(); + resultX = result.release(); } else { ASSERT(id == CSSValueTop || id == CSSValueBottom); if (resultY) return false; - resultY = pair.release(); + resultY = result.release(); } } - if (seenCenter) { + if (center) { ASSERT(resultX || resultY); if (resultX && resultY) return false; - RefPtrWillBeRawPtr<CSSPrimitiveValue> offset = cssValuePool().createValue(50, CSSPrimitiveValue::UnitType::Percentage); if (!resultX) - resultX = CSSValuePair::create(cssValuePool().createIdentifierValue(CSSValueLeft), offset.release(), CSSValuePair::KeepIdenticalValues); + resultX = center; else - resultY = CSSValuePair::create(cssValuePool().createIdentifierValue(CSSValueTop), offset.release(), CSSValuePair::KeepIdenticalValues); + resultY = center; } ASSERT(resultX && resultY); @@ -739,6 +721,36 @@ return nullptr; } +static bool consumeTransformOrigin(CSSParserTokenRange& range, CSSParserMode cssParserMode, UnitlessQuirk unitless, RefPtrWillBeRawPtr<CSSValue>& resultX, RefPtrWillBeRawPtr<CSSValue>& resultY) +{ + RefPtrWillBeRawPtr<CSSPrimitiveValue> value1 = consumePositionComponent(range, cssParserMode, unitless); + if (!value1) + return false; + RefPtrWillBeRawPtr<CSSPrimitiveValue> value2 = consumePositionComponent(range, cssParserMode, unitless); + if (!value2) { + positionFromOneValue(value1.release(), resultX, resultY); + return true; + } + return positionFromTwoValues(value1.release(), value2.release(), resultX, resultY); +} + +static PassRefPtrWillBeRawPtr<CSSValueList> consumeTransformOrigin(CSSParserTokenRange& range, CSSParserMode cssParserMode, UnitlessQuirk unitless) +{ + RefPtrWillBeRawPtr<CSSValue> resultX = nullptr; + RefPtrWillBeRawPtr<CSSValue> resultY = nullptr; + if (consumeTransformOrigin(range, cssParserMode, unitless, resultX, resultY)) { + RefPtrWillBeRawPtr<CSSValueList> list = CSSValueList::createSpaceSeparated(); + list->append(resultX.release()); + list->append(resultY.release()); + RefPtrWillBeRawPtr<CSSValue> resultZ = consumeLength(range, cssParserMode, ValueRangeAll); + if (!resultZ) + resultZ = cssValuePool().createValue(0, CSSPrimitiveValue::UnitType::Pixels); + list->append(resultZ.release()); + return list.release(); + } + return nullptr; +} + static inline bool isCSSWideKeyword(const CSSValueID& id) { return id == CSSValueInitial || id == CSSValueInherit || id == CSSValueUnset || id == CSSValueDefault; @@ -1779,6 +1791,30 @@ return list.release(); } +// none | strict | [ layout || style || paint ] +static PassRefPtrWillBeRawPtr<CSSValue> consumeContain(CSSParserTokenRange& range) +{ + CSSValueID id = range.peek().id(); + if (id == CSSValueNone) + return consumeIdent(range); + + RefPtrWillBeRawPtr<CSSValueList> list = CSSValueList::createSpaceSeparated(); + if (id == CSSValueStrict) { + list->append(consumeIdent(range)); + return list.release(); + } + RefPtrWillBeRawPtr<CSSPrimitiveValue> ident = nullptr; + while ((ident = consumeIdent<CSSValuePaint, CSSValueLayout, CSSValueStyle>(range))) { + if (list->hasValue(ident.get())) + return nullptr; + list->append(ident.release()); + } + + if (!list->length()) + return nullptr; + return list.release(); +} + static PassRefPtrWillBeRawPtr<CSSValue> consumeMotionPath(CSSParserTokenRange& range) { CSSValueID id = range.peek().id(); @@ -2317,6 +2353,7 @@ case CSSPropertyTouchAction: return consumeTouchAction(m_range); case CSSPropertyObjectPosition: + case CSSPropertyPerspectiveOrigin: return consumePosition(m_range, m_context.mode(), UnitlessQuirk::Forbid); case CSSPropertyWebkitLineClamp: return consumeLineClamp(m_range); @@ -2445,6 +2482,10 @@ return consumeLengthOrPercent(m_range, SVGAttributeMode, ValueRangeAll, UnitlessQuirk::Forbid); case CSSPropertyCursor: return consumeCursor(m_range); + case CSSPropertyContain: + return consumeContain(m_range); + case CSSPropertyTransformOrigin: + return consumeTransformOrigin(m_range, m_context.mode(), UnitlessQuirk::Forbid); default: return nullptr; }
diff --git a/third_party/WebKit/Source/core/css/parser/CSSPropertyParser.h b/third_party/WebKit/Source/core/css/parser/CSSPropertyParser.h index b1130fa..d815869 100644 --- a/third_party/WebKit/Source/core/css/parser/CSSPropertyParser.h +++ b/third_party/WebKit/Source/core/css/parser/CSSPropertyParser.h
@@ -235,8 +235,6 @@ PassRefPtrWillBeRawPtr<CSSValueList> parseFilter(); PassRefPtrWillBeRawPtr<CSSFunctionValue> parseBuiltinFilterArguments(CSSParserValueList*, CSSValueID); - PassRefPtrWillBeRawPtr<CSSValueList> parseTransformOrigin(); - bool parseCalculation(CSSParserValue*, ValueRange); bool parseGeneratedImage(CSSParserValueList*, RefPtrWillBeRawPtr<CSSValue>&);
diff --git a/third_party/WebKit/Source/core/css/parser/LegacyCSSPropertyParser.cpp b/third_party/WebKit/Source/core/css/parser/LegacyCSSPropertyParser.cpp index 4cb356e7..033b23d 100644 --- a/third_party/WebKit/Source/core/css/parser/LegacyCSSPropertyParser.cpp +++ b/third_party/WebKit/Source/core/css/parser/LegacyCSSPropertyParser.cpp
@@ -572,18 +572,6 @@ case CSSPropertyOrder: validPrimitive = validUnit(value, FInteger); break; - case CSSPropertyTransformOrigin: { - RefPtrWillBeRawPtr<CSSValueList> list = parseTransformOrigin(); - if (!list) - return false; - // These values are added to match gecko serialization. - if (list->length() == 1) - list->append(cssValuePool().createValue(50, CSSPrimitiveValue::UnitType::Percentage)); - if (list->length() == 2) - list->append(cssValuePool().createValue(0, CSSPrimitiveValue::UnitType::Pixels)); - addProperty(propId, list.release(), important); - return true; - } case CSSPropertyWebkitPerspectiveOriginX: case CSSPropertyWebkitTransformOriginX: @@ -612,16 +600,6 @@ return false; } break; - case CSSPropertyPerspectiveOrigin: { - RefPtrWillBeRawPtr<CSSValueList> list = parseTransformOrigin(); - if (!list || list->length() == 3) - return false; - // This values are added to match gecko serialization. - if (list->length() == 1) - list->append(cssValuePool().createValue(50, CSSPrimitiveValue::UnitType::Percentage)); - addProperty(propId, list.release(), important); - return true; - } case CSSPropertyJustifyContent: ASSERT(RuntimeEnabledFeatures::cssGridLayoutEnabled()); @@ -830,6 +808,7 @@ case CSSPropertyWebkitLogicalWidth: case CSSPropertyWebkitLogicalHeight: case CSSPropertyObjectPosition: + case CSSPropertyPerspectiveOrigin: case CSSPropertyClip: case CSSPropertyTouchAction: case CSSPropertyWebkitLineClamp: @@ -955,6 +934,7 @@ case CSSPropertyScale: case CSSPropertyTranslate: case CSSPropertyCursor: + case CSSPropertyTransformOrigin: validPrimitive = false; break; @@ -5003,73 +4983,6 @@ return imageSet.release(); } -PassRefPtrWillBeRawPtr<CSSValueList> CSSPropertyParser::parseTransformOrigin() -{ - CSSParserValue* value = m_valueList->current(); - CSSValueID id = value->id; - RefPtrWillBeRawPtr<CSSValue> xValue = nullptr; - RefPtrWillBeRawPtr<CSSValue> yValue = nullptr; - RefPtrWillBeRawPtr<CSSValue> zValue = nullptr; - if (id == CSSValueLeft || id == CSSValueRight) { - xValue = cssValuePool().createIdentifierValue(id); - } else if (id == CSSValueTop || id == CSSValueBottom) { - yValue = cssValuePool().createIdentifierValue(id); - } else if (id == CSSValueCenter) { - // Unresolved as to whether this is X or Y. - } else if (validUnit(value, FPercent | FLength)) { - xValue = createPrimitiveNumericValue(value); - } else { - return nullptr; - } - - value = m_valueList->next(); - if (value) { - id = value->id; - if (!xValue && (id == CSSValueLeft || id == CSSValueRight)) { - xValue = cssValuePool().createIdentifierValue(id); - } else if (!yValue && (id == CSSValueTop || id == CSSValueBottom)) { - yValue = cssValuePool().createIdentifierValue(id); - } else if (id == CSSValueCenter) { - // Resolved below. - } else if (!yValue && validUnit(value, FPercent | FLength)) { - yValue = createPrimitiveNumericValue(value); - } else { - return nullptr; - } - - // If X or Y have not been resolved, they must be center. - if (!xValue) - xValue = cssValuePool().createIdentifierValue(CSSValueCenter); - if (!yValue) - yValue = cssValuePool().createIdentifierValue(CSSValueCenter); - - value = m_valueList->next(); - if (value) { - if (!validUnit(value, FLength)) - return nullptr; - zValue = createPrimitiveNumericValue(value); - - value = m_valueList->next(); - if (value) - return nullptr; - } - } else if (!xValue) { - if (yValue) { - xValue = cssValuePool().createValue(50, CSSPrimitiveValue::UnitType::Percentage); - } else { - xValue = cssValuePool().createIdentifierValue(CSSValueCenter); - } - } - - RefPtrWillBeRawPtr<CSSValueList> list = CSSValueList::createSpaceSeparated(); - list->append(xValue.release()); - if (yValue) - list->append(yValue.release()); - if (zValue) - list->append(zValue.release()); - return list.release(); -} - bool CSSPropertyParser::parseCalculation(CSSParserValue* value, ValueRange range) { ASSERT(isCalculation(value));
diff --git a/third_party/WebKit/Source/core/css/resolver/MatchedPropertiesCache.cpp b/third_party/WebKit/Source/core/css/resolver/MatchedPropertiesCache.cpp index 624b4818..fb94762 100644 --- a/third_party/WebKit/Source/core/css/resolver/MatchedPropertiesCache.cpp +++ b/third_party/WebKit/Source/core/css/resolver/MatchedPropertiesCache.cpp
@@ -160,6 +160,8 @@ // The cache assumes static knowledge about which properties are inherited. if (parentStyle.hasExplicitlyInheritedProperties()) return false; + if (style.hasVariableReferenceFromNonInheritedProperty()) + return false; return true; }
diff --git a/third_party/WebKit/Source/core/css/resolver/StyleBuilderConverter.cpp b/third_party/WebKit/Source/core/css/resolver/StyleBuilderConverter.cpp index 42ecf49..91cb9ea 100644 --- a/third_party/WebKit/Source/core/css/resolver/StyleBuilderConverter.cpp +++ b/third_party/WebKit/Source/core/css/resolver/StyleBuilderConverter.cpp
@@ -639,7 +639,21 @@ return length.subtractFromOneHundredPercent(); } - return StyleBuilderConverter::convertLength(state, value); + const CSSPrimitiveValue& primitiveValue = toCSSPrimitiveValue(value); + if (primitiveValue.isValueID()) { + switch (primitiveValue.getValueID()) { + case cssValueFor0: + return Length(0, Percent); + case cssValueFor100: + return Length(100, Percent); + case CSSValueCenter: + return Length(50, Percent); + default: + ASSERT_NOT_REACHED(); + } + } + + return StyleBuilderConverter::convertLength(state, primitiveValue); } LengthPoint StyleBuilderConverter::convertPosition(StyleResolverState& state, const CSSValue& value) @@ -684,20 +698,6 @@ return StyleBuilderConverter::convertLength(state, primitiveValue); } -LengthPoint StyleBuilderConverter::convertPerspectiveOrigin(StyleResolverState& state, const CSSValue& value) -{ - const CSSValueList& list = toCSSValueList(value); - ASSERT(list.length() == 2); - - const CSSPrimitiveValue& primitiveValueX = toCSSPrimitiveValue(*list.item(0)); - const CSSPrimitiveValue& primitiveValueY = toCSSPrimitiveValue(*list.item(1)); - - return LengthPoint( - convertOriginLength<CSSValueLeft, CSSValueRight>(state, primitiveValueX), - convertOriginLength<CSSValueTop, CSSValueBottom>(state, primitiveValueY) - ); -} - EPaintOrder StyleBuilderConverter::convertPaintOrder(StyleResolverState&, const CSSValue& cssPaintOrder) { if (cssPaintOrder.isValueList()) {
diff --git a/third_party/WebKit/Source/core/css/resolver/StyleBuilderConverter.h b/third_party/WebKit/Source/core/css/resolver/StyleBuilderConverter.h index de660bdc..dcc5c6a7 100644 --- a/third_party/WebKit/Source/core/css/resolver/StyleBuilderConverter.h +++ b/third_party/WebKit/Source/core/css/resolver/StyleBuilderConverter.h
@@ -80,7 +80,6 @@ static float convertNumberOrPercentage(StyleResolverState&, const CSSValue&); static LengthPoint convertPosition(StyleResolverState&, const CSSValue&); static float convertPerspective(StyleResolverState&, const CSSValue&); - static LengthPoint convertPerspectiveOrigin(StyleResolverState&, const CSSValue&); static Length convertQuirkyLength(StyleResolverState&, const CSSValue&); static PassRefPtr<QuotesData> convertQuotes(StyleResolverState&, const CSSValue&); static LengthSize convertRadius(StyleResolverState&, const CSSValue&);
diff --git a/third_party/WebKit/Source/core/css/resolver/StyleBuilderCustom.cpp b/third_party/WebKit/Source/core/css/resolver/StyleBuilderCustom.cpp index a7ab238..a9e843e 100644 --- a/third_party/WebKit/Source/core/css/resolver/StyleBuilderCustom.cpp +++ b/third_party/WebKit/Source/core/css/resolver/StyleBuilderCustom.cpp
@@ -113,6 +113,8 @@ { if (RuntimeEnabledFeatures::cssVariablesEnabled() && id != CSSPropertyVariable && value->isVariableReferenceValue()) { CSSVariableResolver::resolveAndApplyVariableReferences(state, id, *toCSSVariableReferenceValue(value)); + if (!state.style()->hasVariableReferenceFromNonInheritedProperty() && !CSSPropertyMetadata::isInheritedProperty(id)) + state.style()->setHasVariableReferenceFromNonInheritedProperty(); return; }
diff --git a/third_party/WebKit/Source/core/dom/ContainerNode.cpp b/third_party/WebKit/Source/core/dom/ContainerNode.cpp index 82cb94c..380860b 100644 --- a/third_party/WebKit/Source/core/dom/ContainerNode.cpp +++ b/third_party/WebKit/Source/core/dom/ContainerNode.cpp
@@ -638,6 +638,7 @@ ChildListMutationScope(*this).willRemoveChild(oldChild); oldChild.notifyMutationObserversNodeWillDetach(); + HTMLFrameOwnerElement::UpdateSuspendScope suspendWidgetHierarchyUpdates; Node* prev = oldChild.previousSibling(); Node* next = oldChild.nextSibling(); removeBetween(prev, next, oldChild); @@ -1082,7 +1083,7 @@ if (computedStyle()->affectedByFocus() && computedStyle()->hasPseudoStyle(FIRST_LETTER)) setNeedsStyleRecalc(SubtreeStyleChange, StyleChangeReasonForTracing::createWithExtraData(StyleChangeReason::PseudoClass, StyleChangeExtraData::Focus)); else if (isElementNode() && toElement(this)->childrenOrSiblingsAffectedByFocus()) - document().styleEngine().pseudoStateChangedForElement(CSSSelector::PseudoFocus, *toElement(this)); + toElement(this)->pseudoStateChanged(CSSSelector::PseudoFocus); else if (computedStyle()->affectedByFocus()) setNeedsStyleRecalc(LocalStyleChange, StyleChangeReasonForTracing::createWithExtraData(StyleChangeReason::PseudoClass, StyleChangeExtraData::Focus)); } @@ -1118,8 +1119,8 @@ return; // If :focus sets display: none, we lose focus but still need to recalc our style. - if (isElementNode() && toElement(this)->childrenOrSiblingsAffectedByFocus() && styleChangeType() < SubtreeStyleChange) - document().styleEngine().pseudoStateChangedForElement(CSSSelector::PseudoFocus, *toElement(this)); + if (isElementNode() && toElement(this)->childrenOrSiblingsAffectedByFocus()) + toElement(this)->pseudoStateChanged(CSSSelector::PseudoFocus); else setNeedsStyleRecalc(LocalStyleChange, StyleChangeReasonForTracing::createWithExtraData(StyleChangeReason::PseudoClass, StyleChangeExtraData::Focus)); } @@ -1137,7 +1138,7 @@ if (computedStyle()->affectedByActive() && computedStyle()->hasPseudoStyle(FIRST_LETTER)) setNeedsStyleRecalc(SubtreeStyleChange, StyleChangeReasonForTracing::createWithExtraData(StyleChangeReason::PseudoClass, StyleChangeExtraData::Active)); else if (isElementNode() && toElement(this)->childrenOrSiblingsAffectedByActive()) - document().styleEngine().pseudoStateChangedForElement(CSSSelector::PseudoActive, *toElement(this)); + toElement(this)->pseudoStateChanged(CSSSelector::PseudoActive); else if (computedStyle()->affectedByActive()) setNeedsStyleRecalc(LocalStyleChange, StyleChangeReasonForTracing::createWithExtraData(StyleChangeReason::PseudoClass, StyleChangeExtraData::Active)); } @@ -1157,8 +1158,8 @@ if (!layoutObject()) { if (over) return; - if (isElementNode() && toElement(this)->childrenOrSiblingsAffectedByHover() && styleChangeType() < SubtreeStyleChange) - document().styleEngine().pseudoStateChangedForElement(CSSSelector::PseudoHover, *toElement(this)); + if (isElementNode() && toElement(this)->childrenOrSiblingsAffectedByHover()) + toElement(this)->pseudoStateChanged(CSSSelector::PseudoHover); else setNeedsStyleRecalc(LocalStyleChange, StyleChangeReasonForTracing::createWithExtraData(StyleChangeReason::PseudoClass, StyleChangeExtraData::Hover)); return; @@ -1168,7 +1169,7 @@ if (computedStyle()->affectedByHover() && computedStyle()->hasPseudoStyle(FIRST_LETTER)) setNeedsStyleRecalc(SubtreeStyleChange, StyleChangeReasonForTracing::createWithExtraData(StyleChangeReason::PseudoClass, StyleChangeExtraData::Hover)); else if (isElementNode() && toElement(this)->childrenOrSiblingsAffectedByHover()) - document().styleEngine().pseudoStateChangedForElement(CSSSelector::PseudoHover, *toElement(this)); + toElement(this)->pseudoStateChanged(CSSSelector::PseudoHover); else if (computedStyle()->affectedByHover()) setNeedsStyleRecalc(LocalStyleChange, StyleChangeReasonForTracing::createWithExtraData(StyleChangeReason::PseudoClass, StyleChangeExtraData::Hover)); }
diff --git a/third_party/WebKit/Source/core/dom/DOMURL.cpp b/third_party/WebKit/Source/core/dom/DOMURL.cpp index 61c56bf..89fc742 100644 --- a/third_party/WebKit/Source/core/dom/DOMURL.cpp +++ b/third_party/WebKit/Source/core/dom/DOMURL.cpp
@@ -64,7 +64,8 @@ String DOMURL::createObjectURL(ExecutionContext* executionContext, Blob* blob, ExceptionState& exceptionState) { - if (!executionContext || !blob) + ASSERT(blob); + if (!executionContext) return String(); if (blob->hasBeenClosed()) { exceptionState.throwDOMException(InvalidStateError, String(blob->isFile() ? "File" : "Blob") + " has been closed.");
diff --git a/third_party/WebKit/Source/core/dom/DocumentStyleSheetCollection.cpp b/third_party/WebKit/Source/core/dom/DocumentStyleSheetCollection.cpp index 79e5cff..a3d35ad 100644 --- a/third_party/WebKit/Source/core/dom/DocumentStyleSheetCollection.cpp +++ b/third_party/WebKit/Source/core/dom/DocumentStyleSheetCollection.cpp
@@ -82,7 +82,7 @@ void DocumentStyleSheetCollection::collectStyleSheets(StyleEngine& engine, DocumentStyleSheetCollector& collector) { ASSERT(&document().styleEngine() == &engine); - collector.appendActiveStyleSheets(engine.documentAuthorStyleSheets()); + collector.appendActiveStyleSheets(engine.injectedAuthorStyleSheets()); collectStyleSheetsFromCandidates(engine, collector); }
diff --git a/third_party/WebKit/Source/core/dom/Element.cpp b/third_party/WebKit/Source/core/dom/Element.cpp index b0ec8b3..d542409 100644 --- a/third_party/WebKit/Source/core/dom/Element.cpp +++ b/third_party/WebKit/Source/core/dom/Element.cpp
@@ -2067,7 +2067,7 @@ return; if (!style || (styleAffectedByEmpty() && (!style->emptyState() || hasChildren()))) - document().styleEngine().pseudoStateChangedForElement(CSSSelector::PseudoEmpty, *this); + pseudoStateChanged(CSSSelector::PseudoEmpty); } void Element::childrenChanged(const ChildrenChange& change)
diff --git a/third_party/WebKit/Source/core/dom/StyleEngine.cpp b/third_party/WebKit/Source/core/dom/StyleEngine.cpp index a5f449f..d5d9941d1c 100644 --- a/third_party/WebKit/Source/core/dom/StyleEngine.cpp +++ b/third_party/WebKit/Source/core/dom/StyleEngine.cpp
@@ -90,8 +90,8 @@ // Cleanup is performed eagerly when the StyleEngine is removed from the // document. The StyleEngine is unreachable after this, since only the // document has a reference to it. - for (unsigned i = 0; i < m_authorStyleSheets.size(); ++i) - m_authorStyleSheets[i]->clearOwnerNode(); + for (unsigned i = 0; i < m_injectedAuthorStyleSheets.size(); ++i) + m_injectedAuthorStyleSheets[i]->clearOwnerNode(); if (m_fontSelector) { m_fontSelector->clearDocument(); @@ -163,10 +163,10 @@ m_maxDirectAdjacentSelectors = features.maxDirectAdjacentSelectors(); } -void StyleEngine::addAuthorSheet(PassRefPtrWillBeRawPtr<StyleSheetContents> authorSheet) +void StyleEngine::injectAuthorSheet(PassRefPtrWillBeRawPtr<StyleSheetContents> authorSheet) { - m_authorStyleSheets.append(CSSStyleSheet::create(authorSheet, m_document)); - document().addedStyleSheet(m_authorStyleSheets.last().get()); + m_injectedAuthorStyleSheets.append(CSSStyleSheet::create(authorSheet, m_document)); + document().addedStyleSheet(m_injectedAuthorStyleSheets.last().get()); markDocumentDirty(); } @@ -711,7 +711,7 @@ { #if ENABLE(OILPAN) visitor->trace(m_document); - visitor->trace(m_authorStyleSheets); + visitor->trace(m_injectedAuthorStyleSheets); visitor->trace(m_documentStyleSheetCollection); visitor->trace(m_styleSheetCollectionMap); visitor->trace(m_resolver);
diff --git a/third_party/WebKit/Source/core/dom/StyleEngine.h b/third_party/WebKit/Source/core/dom/StyleEngine.h index 46ebb6f..931a72ca 100644 --- a/third_party/WebKit/Source/core/dom/StyleEngine.h +++ b/third_party/WebKit/Source/core/dom/StyleEngine.h
@@ -80,7 +80,7 @@ const WillBeHeapVector<RefPtrWillBeMember<StyleSheet>>& styleSheetsForStyleSheetList(TreeScope&); - const WillBeHeapVector<RefPtrWillBeMember<CSSStyleSheet>>& documentAuthorStyleSheets() const { return m_authorStyleSheets; } + const WillBeHeapVector<RefPtrWillBeMember<CSSStyleSheet>>& injectedAuthorStyleSheets() const { return m_injectedAuthorStyleSheets; } const WillBeHeapVector<RefPtrWillBeMember<CSSStyleSheet>> activeStyleSheetsForInspector() const; @@ -90,7 +90,7 @@ void removeStyleSheetCandidateNode(Node*, TreeScope&); void modifiedStyleSheetCandidateNode(Node*); - void addAuthorSheet(PassRefPtrWillBeRawPtr<StyleSheetContents> authorSheet); + void injectAuthorSheet(PassRefPtrWillBeRawPtr<StyleSheetContents> authorSheet); void clearMediaQueryRuleSetStyleSheets(); void updateStyleSheetsInImport(DocumentStyleSheetCollector& parentCollector); @@ -227,7 +227,7 @@ // elements and when it is safe to execute scripts. int m_pendingStylesheets; - WillBeHeapVector<RefPtrWillBeMember<CSSStyleSheet>> m_authorStyleSheets; + WillBeHeapVector<RefPtrWillBeMember<CSSStyleSheet>> m_injectedAuthorStyleSheets; OwnPtrWillBeMember<DocumentStyleSheetCollection> m_documentStyleSheetCollection;
diff --git a/third_party/WebKit/Source/core/dom/URL.idl b/third_party/WebKit/Source/core/dom/URL.idl index a4e75fc..f5df0bb7b 100644 --- a/third_party/WebKit/Source/core/dom/URL.idl +++ b/third_party/WebKit/Source/core/dom/URL.idl
@@ -41,8 +41,8 @@ // TODO(philipj): This should be in a partial interface definition: // File API // https://w3c.github.io/FileAPI/#creating-revoking - // TODO(philipj): Neither the return value nor the argument should be nullable. - [RaisesException, CallWith=ExecutionContext, LegacyInterfaceTypeChecking] static DOMString? createObjectURL(Blob? blob); + // TODO(philipj): The return type should not be nullable. + [RaisesException, CallWith=ExecutionContext] static DOMString? createObjectURL(Blob blob); [CallWith=ExecutionContext] static void revokeObjectURL(DOMString url); };
diff --git a/third_party/WebKit/Source/core/editing/serializers/MarkupFormatter.cpp b/third_party/WebKit/Source/core/editing/serializers/MarkupFormatter.cpp index 7afbb55..317e8c6f 100644 --- a/third_party/WebKit/Source/core/editing/serializers/MarkupFormatter.cpp +++ b/third_party/WebKit/Source/core/editing/serializers/MarkupFormatter.cpp
@@ -78,6 +78,9 @@ DEFINE_STATIC_LOCAL(const CString, gtReference, (">")); DEFINE_STATIC_LOCAL(const CString, quotReference, (""")); DEFINE_STATIC_LOCAL(const CString, nbspReference, (" ")); + DEFINE_STATIC_LOCAL(const CString, tabReference, ("	")); + DEFINE_STATIC_LOCAL(const CString, lineFeedReference, (" ")); + DEFINE_STATIC_LOCAL(const CString, carriageReturnReference, (" ")); static const EntityDescription entityMaps[] = { { '&', ampReference, EntityAmp }, @@ -85,6 +88,9 @@ { '>', gtReference, EntityGt }, { '"', quotReference, EntityQuot }, { noBreakSpaceCharacter, nbspReference, EntityNbsp }, + { '\t', tabReference, EntityTab }, + { '\n', lineFeedReference, EntityLineFeed }, + { '\r', carriageReturnReference, EntityCarriageReturn }, }; if (!(offset + length))
diff --git a/third_party/WebKit/Source/core/editing/serializers/MarkupFormatter.h b/third_party/WebKit/Source/core/editing/serializers/MarkupFormatter.h index 91732f2c..dcfd32b 100644 --- a/third_party/WebKit/Source/core/editing/serializers/MarkupFormatter.h +++ b/third_party/WebKit/Source/core/editing/serializers/MarkupFormatter.h
@@ -47,13 +47,16 @@ EntityGt = 0x0004, EntityQuot = 0x0008, EntityNbsp = 0x0010, + EntityTab = 0x0020, + EntityLineFeed = 0x0040, + EntityCarriageReturn = 0x0080, // Non-breaking space needs to be escaped in innerHTML for compatibility reason. See http://trac.webkit.org/changeset/32879 // However, we cannot do this in a XML document because it does not have the entity reference defined (See the bug 19215). EntityMaskInCDATA = 0, EntityMaskInPCDATA = EntityAmp | EntityLt | EntityGt, EntityMaskInHTMLPCDATA = EntityMaskInPCDATA | EntityNbsp, - EntityMaskInAttributeValue = EntityAmp | EntityQuot | EntityLt | EntityGt, + EntityMaskInAttributeValue = EntityAmp | EntityQuot | EntityLt | EntityGt | EntityTab | EntityLineFeed | EntityCarriageReturn, EntityMaskInHTMLAttributeValue = EntityAmp | EntityQuot | EntityNbsp, };
diff --git a/third_party/WebKit/Source/core/editing/spellcheck/SpellChecker.cpp b/third_party/WebKit/Source/core/editing/spellcheck/SpellChecker.cpp index e7f4955..8dbfcaae 100644 --- a/third_party/WebKit/Source/core/editing/spellcheck/SpellChecker.cpp +++ b/third_party/WebKit/Source/core/editing/spellcheck/SpellChecker.cpp
@@ -124,11 +124,6 @@ } } -bool SpellChecker::isGrammarCheckingEnabled() -{ - return spellCheckerClient().isGrammarCheckingEnabled(); -} - void SpellChecker::didBeginEditing(Element* element) { if (isContinuousSpellCheckingEnabled() && unifiedTextCheckerEnabled()) { @@ -242,7 +237,7 @@ if (unifiedTextCheckerEnabled()) { grammarSearchStart = spellingSearchStart; grammarSearchEnd = spellingSearchEnd; - foundItem = TextCheckingHelper(spellCheckerClient(), spellingSearchStart, spellingSearchEnd).findFirstMisspellingOrBadGrammar(isGrammarCheckingEnabled(), isSpelling, foundOffset, grammarDetail); + foundItem = TextCheckingHelper(spellCheckerClient(), spellingSearchStart, spellingSearchEnd).findFirstMisspellingOrBadGrammar(isSpelling, foundOffset, grammarDetail); if (isSpelling) { misspelledWord = foundItem; misspellingOffset = foundOffset; @@ -261,8 +256,7 @@ grammarSearchEnd = chars.startPosition(); } - if (isGrammarCheckingEnabled()) - badGrammarPhrase = TextCheckingHelper(spellCheckerClient(), grammarSearchStart, grammarSearchEnd).findFirstBadGrammar(grammarDetail, grammarPhraseOffset, false); + badGrammarPhrase = TextCheckingHelper(spellCheckerClient(), grammarSearchStart, grammarSearchEnd).findFirstBadGrammar(grammarDetail, grammarPhraseOffset, false); } // If we found neither bad grammar nor a misspelled word, wrap and try again (but don't bother if we started at the beginning of the @@ -275,7 +269,7 @@ if (unifiedTextCheckerEnabled()) { grammarSearchStart = spellingSearchStart; grammarSearchEnd = spellingSearchEnd; - foundItem = TextCheckingHelper(spellCheckerClient(), spellingSearchStart, spellingSearchEnd).findFirstMisspellingOrBadGrammar(isGrammarCheckingEnabled(), isSpelling, foundOffset, grammarDetail); + foundItem = TextCheckingHelper(spellCheckerClient(), spellingSearchStart, spellingSearchEnd).findFirstMisspellingOrBadGrammar(isSpelling, foundOffset, grammarDetail); if (isSpelling) { misspelledWord = foundItem; misspellingOffset = foundOffset; @@ -294,8 +288,7 @@ grammarSearchEnd = chars.startPosition(); } - if (isGrammarCheckingEnabled()) - badGrammarPhrase = TextCheckingHelper(spellCheckerClient(), grammarSearchStart, grammarSearchEnd).findFirstBadGrammar(grammarDetail, grammarPhraseOffset, false); + badGrammarPhrase = TextCheckingHelper(spellCheckerClient(), grammarSearchStart, grammarSearchEnd).findFirstBadGrammar(grammarDetail, grammarPhraseOffset, false); } } @@ -344,7 +337,7 @@ void SpellChecker::markMisspellingsAndBadGrammar(const VisibleSelection &movingSelection) { - markMisspellingsAndBadGrammar(movingSelection, isContinuousSpellCheckingEnabled() && isGrammarCheckingEnabled(), movingSelection); + markMisspellingsAndBadGrammar(movingSelection, isContinuousSpellCheckingEnabled(), movingSelection); } void SpellChecker::markMisspellingsAfterLineBreak(const VisibleSelection& wordSelection) @@ -356,14 +349,11 @@ return; } - TextCheckingTypeMask textCheckingOptions = 0; + TextCheckingTypeMask textCheckingOptions = TextCheckingTypeGrammar; if (isContinuousSpellCheckingEnabled()) textCheckingOptions |= TextCheckingTypeSpelling; - if (isGrammarCheckingEnabled()) - textCheckingOptions |= TextCheckingTypeGrammar; - VisibleSelection wholeParagraph( startOfParagraph(wordSelection.visibleStart()), endOfParagraph(wordSelection.visibleEnd())); @@ -386,8 +376,7 @@ if (!(textCheckingOptions & TextCheckingTypeSpelling)) return; - if (isGrammarCheckingEnabled()) - textCheckingOptions |= TextCheckingTypeGrammar; + textCheckingOptions |= TextCheckingTypeGrammar; VisibleSelection adjacentWords = VisibleSelection(startOfWord(wordStart, LeftWordIfOnBoundary), endOfWord(wordStart, RightWordIfOnBoundary)); if (textCheckingOptions & TextCheckingTypeGrammar) { @@ -405,7 +394,7 @@ // Check spelling of one word bool result = markMisspellings(VisibleSelection(startOfWord(wordStart, LeftWordIfOnBoundary), endOfWord(wordStart, RightWordIfOnBoundary))); - if (!result || !isGrammarCheckingEnabled()) + if (!result) return; // Check grammar of entire sentence @@ -440,8 +429,7 @@ if (checkSpelling) return checker.markAllMisspellings(); - if (isGrammarCheckingEnabled()) - checker.markAllBadGrammar(); + checker.markAllBadGrammar(); return false; } @@ -635,7 +623,7 @@ // markMisspellingsAndBadGrammar() is triggered by selection change, in which case we check spelling and grammar, but don't autocorrect misspellings. TextCheckingTypeMask textCheckingOptions = TextCheckingTypeSpelling; - if (markGrammar && isGrammarCheckingEnabled()) + if (markGrammar) textCheckingOptions |= TextCheckingTypeGrammar; markAllMisspellingsAndBadGrammarInRanges(textCheckingOptions, spellingSelection.toNormalizedEphemeralRange(), grammarSelection.toNormalizedEphemeralRange()); return; @@ -648,9 +636,6 @@ void SpellChecker::updateMarkersForWordsAffectedByEditing(bool doNotRemoveIfSelectionAtWordBoundary) { - if (textChecker().shouldEraseMarkersAfterChangeSelection(TextCheckingTypeSpelling)) - return; - TRACE_EVENT0("blink", "SpellChecker::updateMarkersForWordsAffectedByEditing"); // We want to remove the markers from a word if an editing command will change the word. This can happen in one of @@ -729,7 +714,7 @@ HTMLTextFormControlElement* textFormControlElement = toHTMLTextFormControlElement(e); HTMLElement* innerEditor = textFormControlElement->innerEditorElement(); DocumentMarker::MarkerTypes markerTypes(DocumentMarker::Spelling); - if (isGrammarCheckingEnabled() || unifiedTextCheckerEnabled()) + if (unifiedTextCheckerEnabled()) markerTypes.add(DocumentMarker::Grammar); for (Node& node : NodeTraversal::inclusiveDescendantsOf(*innerEditor)) frame().document()->markers().removeMarkers(&node, markerTypes); @@ -756,7 +741,7 @@ bool closeTyping = options & FrameSelection::CloseTyping; bool isContinuousSpellCheckingEnabled = this->isContinuousSpellCheckingEnabled(); - bool isContinuousGrammarCheckingEnabled = isContinuousSpellCheckingEnabled && isGrammarCheckingEnabled(); + bool isContinuousGrammarCheckingEnabled = isContinuousSpellCheckingEnabled; if (isContinuousSpellCheckingEnabled) { VisibleSelection newAdjacentWords; VisibleSelection newSelectedSentence; @@ -789,14 +774,6 @@ && oldSelection.start().inDocument()) { spellCheckOldSelection(oldSelection, newAdjacentWords); } - - // FIXME(http://crbug.com/382809): - // shouldEraseMarkersAfterChangeSelection is true, we cause synchronous - // layout. - if (textChecker().shouldEraseMarkersAfterChangeSelection(TextCheckingTypeSpelling)) - removeMarkers(newAdjacentWords, DocumentMarker::Spelling); - if (textChecker().shouldEraseMarkersAfterChangeSelection(TextCheckingTypeGrammar)) - removeMarkers(newSelectedSentence, DocumentMarker::Grammar); } // When continuous spell checking is off, existing markers disappear after the selection changes. @@ -841,7 +818,7 @@ VisiblePosition oldStart(oldSelection.visibleStart()); VisibleSelection oldAdjacentWords = VisibleSelection(startOfWord(oldStart, LeftWordIfOnBoundary), endOfWord(oldStart, RightWordIfOnBoundary)); if (!equalSelectionsInDOMTree(oldAdjacentWords, newAdjacentWords)) { - if (isContinuousSpellCheckingEnabled() && isGrammarCheckingEnabled()) { + if (isContinuousSpellCheckingEnabled()) { VisibleSelection selectedSentence = VisibleSelection(startOfSentence(oldStart), endOfSentence(oldStart)); markMisspellingsAndBadGrammar(oldAdjacentWords, true, selectedSentence); } else {
diff --git a/third_party/WebKit/Source/core/editing/spellcheck/SpellChecker.h b/third_party/WebKit/Source/core/editing/spellcheck/SpellChecker.h index fde20fd..f3138ab3 100644 --- a/third_party/WebKit/Source/core/editing/spellcheck/SpellChecker.h +++ b/third_party/WebKit/Source/core/editing/spellcheck/SpellChecker.h
@@ -57,7 +57,6 @@ bool isContinuousSpellCheckingEnabled() const; void toggleContinuousSpellChecking(); - bool isGrammarCheckingEnabled(); void ignoreSpelling(); bool isSpellCheckingEnabledInFocusedNode() const; bool isSpellCheckingEnabledFor(Node*) const;
diff --git a/third_party/WebKit/Source/core/editing/spellcheck/TextCheckingHelper.cpp b/third_party/WebKit/Source/core/editing/spellcheck/TextCheckingHelper.cpp index 0714e89..c2186724 100644 --- a/third_party/WebKit/Source/core/editing/spellcheck/TextCheckingHelper.cpp +++ b/third_party/WebKit/Source/core/editing/spellcheck/TextCheckingHelper.cpp
@@ -309,7 +309,7 @@ return firstMisspelling; } -String TextCheckingHelper::findFirstMisspellingOrBadGrammar(bool checkGrammar, bool& outIsSpelling, int& outFirstFoundOffset, GrammarDetail& outGrammarDetail) +String TextCheckingHelper::findFirstMisspellingOrBadGrammar(bool& outIsSpelling, int& outFirstFoundOffset, GrammarDetail& outGrammarDetail) { if (!unifiedTextCheckerEnabled()) return ""; @@ -360,7 +360,7 @@ unsigned grammarDetailIndex = 0; Vector<TextCheckingResult> results; - TextCheckingTypeMask checkingTypes = checkGrammar ? (TextCheckingTypeSpelling | TextCheckingTypeGrammar) : TextCheckingTypeSpelling; + TextCheckingTypeMask checkingTypes = TextCheckingTypeSpelling | TextCheckingTypeGrammar; checkTextOfParagraph(m_client->textChecker(), paragraphString, checkingTypes, results); for (unsigned i = 0; i < results.size(); i++) { @@ -372,7 +372,7 @@ ASSERT(misspelledWord.length()); break; } - if (checkGrammar && result->decoration == TextDecorationTypeGrammar && result->location < currentEndOffset && result->location + result->length > currentStartOffset) { + if (result->decoration == TextDecorationTypeGrammar && result->location < currentEndOffset && result->location + result->length > currentStartOffset) { ASSERT(result->length > 0 && result->location >= 0); // We can't stop after the first grammar result, since there might still be a spelling result after // it begins but before the first detail in it, but we can stop if we find a second grammar result. @@ -396,7 +396,7 @@ } } - if (!misspelledWord.isEmpty() && (!checkGrammar || badGrammarPhrase.isEmpty() || spellingLocation <= grammarDetailLocation)) { + if (!misspelledWord.isEmpty() && (badGrammarPhrase.isEmpty() || spellingLocation <= grammarDetailLocation)) { int spellingOffset = spellingLocation - currentStartOffset; if (!firstIteration) spellingOffset += TextIterator::rangeLength(m_start, paragraphStart); @@ -405,7 +405,7 @@ firstFoundItem = misspelledWord; break; } - if (checkGrammar && !badGrammarPhrase.isEmpty()) { + if (!badGrammarPhrase.isEmpty()) { int grammarPhraseOffset = grammarPhraseLocation - currentStartOffset; if (!firstIteration) grammarPhraseOffset += TextIterator::rangeLength(m_start, paragraphStart);
diff --git a/third_party/WebKit/Source/core/editing/spellcheck/TextCheckingHelper.h b/third_party/WebKit/Source/core/editing/spellcheck/TextCheckingHelper.h index 176a8c4..7eae542 100644 --- a/third_party/WebKit/Source/core/editing/spellcheck/TextCheckingHelper.h +++ b/third_party/WebKit/Source/core/editing/spellcheck/TextCheckingHelper.h
@@ -89,7 +89,7 @@ ~TextCheckingHelper(); String findFirstMisspelling(int& firstMisspellingOffset, bool markAll); - String findFirstMisspellingOrBadGrammar(bool checkGrammar, bool& outIsSpelling, int& outFirstFoundOffset, GrammarDetail& outGrammarDetail); + String findFirstMisspellingOrBadGrammar(bool& outIsSpelling, int& outFirstFoundOffset, GrammarDetail& outGrammarDetail); String findFirstBadGrammar(GrammarDetail& outGrammarDetail, int& outGrammarPhraseOffset, bool markAll); bool markAllMisspellings(); void markAllBadGrammar();
diff --git a/third_party/WebKit/Source/core/fetch/FontResource.cpp b/third_party/WebKit/Source/core/fetch/FontResource.cpp index 68f88e0..1c3e83b 100644 --- a/third_party/WebKit/Source/core/fetch/FontResource.cpp +++ b/third_party/WebKit/Source/core/fetch/FontResource.cpp
@@ -117,11 +117,15 @@ Resource::didAddClient(c); if (!isLoading()) static_cast<FontResourceClient*>(c)->fontLoaded(this); + if (m_state == ShortLimitExceeded || m_state == LongLimitExceeded) + static_cast<FontResourceClient*>(c)->fontLoadShortLimitExceeded(this); + if (m_state == LongLimitExceeded) + static_cast<FontResourceClient*>(c)->fontLoadLongLimitExceeded(this); } void FontResource::beginLoadIfNeeded(ResourceFetcher* dl) { - if (m_state != LoadInitiated) { + if (stillNeedsLoad()) { m_state = LoadInitiated; Resource::load(dl, m_options); m_fontLoadShortLimitTimer.startOneShot(fontLoadWaitShortLimitSec, BLINK_FROM_HERE); @@ -164,6 +168,8 @@ { if (!isLoading()) return; + ASSERT(m_state == LoadInitiated); + m_state = ShortLimitExceeded; ResourceClientWalker<FontResourceClient> walker(m_clients); while (FontResourceClient* client = walker.next()) client->fontLoadShortLimitExceeded(this); @@ -173,6 +179,8 @@ { if (!isLoading()) return; + ASSERT(m_state == ShortLimitExceeded); + m_state = LongLimitExceeded; ResourceClientWalker<FontResourceClient> walker(m_clients); while (FontResourceClient* client = walker.next()) client->fontLoadLongLimitExceeded(this);
diff --git a/third_party/WebKit/Source/core/fetch/FontResource.h b/third_party/WebKit/Source/core/fetch/FontResource.h index 6e6db47b..9a582c8 100644 --- a/third_party/WebKit/Source/core/fetch/FontResource.h +++ b/third_party/WebKit/Source/core/fetch/FontResource.h
@@ -52,7 +52,7 @@ void allClientsRemoved() override; void beginLoadIfNeeded(ResourceFetcher* dl); - bool stillNeedsLoad() const override { return m_state != LoadInitiated; } + bool stillNeedsLoad() const override { return m_state < LoadInitiated; } bool loadScheduled() const { return m_state != Unloaded; } void didScheduleLoad(); @@ -85,7 +85,7 @@ void fontLoadShortLimitCallback(Timer<FontResource>*); void fontLoadLongLimitCallback(Timer<FontResource>*); - enum State { Unloaded, LoadScheduled, LoadInitiated }; + enum State { Unloaded, LoadScheduled, LoadInitiated, ShortLimitExceeded, LongLimitExceeded }; OwnPtr<FontCustomPlatformData> m_fontData; String m_otsParsingMessage;
diff --git a/third_party/WebKit/Source/core/fetch/LinkFetchResource.cpp b/third_party/WebKit/Source/core/fetch/LinkFetchResource.cpp index b47985a..7af3b54 100644 --- a/third_party/WebKit/Source/core/fetch/LinkFetchResource.cpp +++ b/third_party/WebKit/Source/core/fetch/LinkFetchResource.cpp
@@ -13,8 +13,7 @@ ResourcePtr<Resource> LinkFetchResource::fetch(Resource::Type type, FetchRequest& request, ResourceFetcher* fetcher) { - // TODO(yoav): Enforce a LinkPreload context here, once we know we're adding one - https://github.com/whatwg/fetch/issues/36 - ASSERT(type == LinkPrefetch || type == LinkSubresource || type == LinkPreload); + ASSERT(type == LinkPrefetch || type == LinkSubresource); ASSERT(request.resourceRequest().frameType() == WebURLRequest::FrameTypeNone); fetcher->determineRequestContext(request.mutableResourceRequest(), type); return fetcher->requestResource(request, LinkResourceFactory(type));
diff --git a/third_party/WebKit/Source/core/fetch/MemoryCache.cpp b/third_party/WebKit/Source/core/fetch/MemoryCache.cpp index c609a0e..3e50498 100644 --- a/third_party/WebKit/Source/core/fetch/MemoryCache.cpp +++ b/third_party/WebKit/Source/core/fetch/MemoryCache.cpp
@@ -176,17 +176,6 @@ WTF_LOG(ResourceLoading, "MemoryCache::add Added '%s', resource %p\n", resource->url().string().latin1().data(), resource); } -void MemoryCache::replace(Resource* newResource, Resource* oldResource) -{ - ASSERT(newResource->cacheIdentifier() == oldResource->cacheIdentifier()); - ResourceMap* resources = ensureResourceMap(oldResource->cacheIdentifier()); - if (MemoryCacheEntry* oldEntry = resources->get(oldResource->url())) - evict(oldEntry); - add(newResource); - if (newResource->decodedSize() && newResource->hasClients()) - insertInLiveDecodedResourcesList(resources->get(newResource->url())); -} - void MemoryCache::remove(Resource* resource) { // The resource may have already been removed by someone other than our caller, @@ -342,7 +331,12 @@ while (current) { // Protect 'previous' so it can't get deleted during destroyDecodedData(). MemoryCacheEntry* previous = current->m_previousInAllResourcesList; - ASSERT(!previous || contains(previous->m_resource.get())); + if (previous) { + // These release assertions are for investigating crashes and + // should be removed shortly. + RELEASE_ASSERT(previous->m_resource); + RELEASE_ASSERT(contains(previous->m_resource.get())); + } if (!current->m_resource->hasClients() && !current->m_resource->isPreloaded() && current->m_resource->isLoaded()) { // Destroy our decoded data. This will remove us from // m_liveDecodedResources, and possibly move us to a different @@ -363,7 +357,12 @@ current = m_allResources[i].m_tail; while (current) { MemoryCacheEntry* previous = current->m_previousInAllResourcesList; - ASSERT(!previous || contains(previous->m_resource.get())); + if (previous) { + // These release assertions are for investigating crashes and + // should be removed shortly. + RELEASE_ASSERT(previous->m_resource); + RELEASE_ASSERT(contains(previous->m_resource.get())); + } if (!current->m_resource->hasClients() && !current->m_resource->isPreloaded() && !current->m_resource->isCacheValidator() && current->m_resource->canDelete() && current->m_resource->type() != Resource::MainResource) {
diff --git a/third_party/WebKit/Source/core/fetch/MemoryCache.h b/third_party/WebKit/Source/core/fetch/MemoryCache.h index b0085ca..ad1cb6a65 100644 --- a/third_party/WebKit/Source/core/fetch/MemoryCache.h +++ b/third_party/WebKit/Source/core/fetch/MemoryCache.h
@@ -179,7 +179,6 @@ WillBeHeapVector<RawPtrWillBeMember<Resource>> resourcesForURL(const KURL&); void add(Resource*); - void replace(Resource* newResource, Resource* oldResource); void remove(Resource*); bool contains(const Resource*) const;
diff --git a/third_party/WebKit/Source/core/fetch/MemoryCacheTest.cpp b/third_party/WebKit/Source/core/fetch/MemoryCacheTest.cpp index 2cd0334..e4fbc14e 100644 --- a/third_party/WebKit/Source/core/fetch/MemoryCacheTest.cpp +++ b/third_party/WebKit/Source/core/fetch/MemoryCacheTest.cpp
@@ -487,22 +487,6 @@ } } -TEST_F(MemoryCacheTest, MultipleReplace) -{ - ResourcePtr<FakeResource> resource1 = new FakeResource(ResourceRequest("http://test/resource"), Resource::Raw); - memoryCache()->add(resource1.get()); - - ResourcePtr<FakeResource> resource2 = new FakeResource(ResourceRequest("http://test/resource"), Resource::Raw); - memoryCache()->replace(resource2.get(), resource1.get()); - EXPECT_TRUE(memoryCache()->contains(resource2.get())); - EXPECT_FALSE(memoryCache()->contains(resource1.get())); - - ResourcePtr<FakeResource> resource3 = new FakeResource(ResourceRequest("http://test/resource"), Resource::Raw); - memoryCache()->replace(resource3.get(), resource2.get()); - EXPECT_TRUE(memoryCache()->contains(resource3.get())); - EXPECT_FALSE(memoryCache()->contains(resource2.get())); -} - TEST_F(MemoryCacheTest, RemoveDuringRevalidation) { ResourcePtr<FakeResource> resource1 = new FakeResource(ResourceRequest("http://test/resource"), Resource::Raw); @@ -519,11 +503,6 @@ memoryCache()->add(resource3.get()); EXPECT_TRUE(memoryCache()->contains(resource3.get())); EXPECT_FALSE(memoryCache()->contains(resource2.get())); - - memoryCache()->replace(resource1.get(), resource2.get()); - EXPECT_TRUE(memoryCache()->contains(resource1.get())); - EXPECT_FALSE(memoryCache()->contains(resource2.get())); - EXPECT_FALSE(memoryCache()->contains(resource3.get())); } TEST_F(MemoryCacheTest, ResourceMapIsolation) @@ -551,13 +530,6 @@ EXPECT_FALSE(memoryCache()->contains(resource2.get())); EXPECT_TRUE(memoryCache()->contains(resource3.get())); - ResourcePtr<FakeResource> resource4 = new FakeResource(ResourceRequest("http://test/resource"), Resource::Raw); - resource4->setCacheIdentifier("foo"); - memoryCache()->replace(resource4.get(), resource3.get()); - EXPECT_TRUE(memoryCache()->contains(resource1.get())); - EXPECT_FALSE(memoryCache()->contains(resource3.get())); - EXPECT_TRUE(memoryCache()->contains(resource4.get())); - WillBeHeapVector<RawPtrWillBeMember<Resource>> resources = memoryCache()->resourcesForURL(url); EXPECT_EQ(2u, resources.size());
diff --git a/third_party/WebKit/Source/core/fetch/Resource.cpp b/third_party/WebKit/Source/core/fetch/Resource.cpp index ffca995..36811503 100644 --- a/third_party/WebKit/Source/core/fetch/Resource.cpp +++ b/third_party/WebKit/Source/core/fetch/Resource.cpp
@@ -1098,8 +1098,6 @@ return "Link prefetch resource"; case Resource::LinkSubresource: return "Link subresource"; - case Resource::LinkPreload: - return "Link preload"; case Resource::TextTrack: return "Text track"; case Resource::ImportResource: @@ -1149,8 +1147,6 @@ return "LinkPrefetch"; case Resource::LinkSubresource: return "LinkSubresource"; - case Resource::LinkPreload: - return "LinkPreload"; case Resource::TextTrack: return "TextTrack"; case Resource::ImportResource:
diff --git a/third_party/WebKit/Source/core/fetch/Resource.h b/third_party/WebKit/Source/core/fetch/Resource.h index 12fcfa6..39bca1c 100644 --- a/third_party/WebKit/Source/core/fetch/Resource.h +++ b/third_party/WebKit/Source/core/fetch/Resource.h
@@ -77,7 +77,6 @@ XSLStyleSheet, LinkPrefetch, LinkSubresource, - LinkPreload, TextTrack, ImportResource, Media // Audio or video file requested by a HTML5 media element
diff --git a/third_party/WebKit/Source/core/fetch/ResourceFetcher.cpp b/third_party/WebKit/Source/core/fetch/ResourceFetcher.cpp index 93c0806b..96d11361 100644 --- a/third_party/WebKit/Source/core/fetch/ResourceFetcher.cpp +++ b/third_party/WebKit/Source/core/fetch/ResourceFetcher.cpp
@@ -95,7 +95,6 @@ return ResourceLoadPriorityLow; case Resource::Image: case Resource::LinkPrefetch: - case Resource::LinkPreload: return ResourceLoadPriorityVeryLow; } @@ -154,10 +153,6 @@ return WebURLRequest::RequestContextPrefetch; case Resource::LinkSubresource: return WebURLRequest::RequestContextSubresource; - case Resource::LinkPreload: - // TODO(yoav): We should give preload its own context: - // https://github.com/whatwg/fetch/commit/26e5cca8ab5bb4b68a8f238f41dd7364d8c276b3 - return WebURLRequest::RequestContextSubresource; case Resource::TextTrack: return WebURLRequest::RequestContextTrack; case Resource::SVGDocument: @@ -470,10 +465,15 @@ context().addResourceTiming(*timingInfo); } +void ResourceFetcher::determineRequestContext(ResourceRequest& request, Resource::Type type, bool isMainFrame) +{ + WebURLRequest::RequestContext requestContext = requestContextFromType(isMainFrame, type); + request.setRequestContext(requestContext); +} + void ResourceFetcher::determineRequestContext(ResourceRequest& request, Resource::Type type) { - WebURLRequest::RequestContext requestContext = requestContextFromType(context().isMainFrame(), type); - request.setRequestContext(requestContext); + determineRequestContext(request, type, context().isMainFrame()); } void ResourceFetcher::initializeResourceRequest(ResourceRequest& request, Resource::Type type)
diff --git a/third_party/WebKit/Source/core/fetch/ResourceFetcher.h b/third_party/WebKit/Source/core/fetch/ResourceFetcher.h index f74b5eb..992bc49 100644 --- a/third_party/WebKit/Source/core/fetch/ResourceFetcher.h +++ b/third_party/WebKit/Source/core/fetch/ResourceFetcher.h
@@ -144,6 +144,7 @@ void scheduleDocumentResourcesGC(); bool clientDefersImage(const KURL&) const; + static void determineRequestContext(ResourceRequest&, Resource::Type, bool isMainFrame); void determineRequestContext(ResourceRequest&, Resource::Type); WebTaskRunner* loadingTaskRunner();
diff --git a/third_party/WebKit/Source/core/frame/Frame.cpp b/third_party/WebKit/Source/core/frame/Frame.cpp index b5cbebb..4ac536f 100644 --- a/third_party/WebKit/Source/core/frame/Frame.cpp +++ b/third_party/WebKit/Source/core/frame/Frame.cpp
@@ -288,13 +288,6 @@ return nullptr; } -void Frame::scheduleVisualUpdateUnlessThrottled() -{ - if (isLocalFrame() && toLocalFrame(this)->shouldThrottleRendering()) - return; - page()->animator().scheduleVisualUpdate(); -} - Frame::Frame(FrameClient* client, FrameHost* host, FrameOwner* owner) : m_treeNode(this) , m_host(host)
diff --git a/third_party/WebKit/Source/core/frame/Frame.h b/third_party/WebKit/Source/core/frame/Frame.h index 24909d3d..c15b094 100644 --- a/third_party/WebKit/Source/core/frame/Frame.h +++ b/third_party/WebKit/Source/core/frame/Frame.h
@@ -60,6 +60,9 @@ // Status of user gesture. enum class UserGestureStatus { Active, None }; +// Frame is the base class of LocalFrame and RemoteFrame and should only contain +// functionality shared between both. In particular, any method related to +// input, layout, or painting probably belongs on LocalFrame. class CORE_EXPORT Frame : public RefCountedWillBeGarbageCollectedFinalized<Frame> { public: virtual ~Frame(); @@ -130,8 +133,6 @@ virtual WindowProxyManager* windowProxyManager() const = 0; - void scheduleVisualUpdateUnlessThrottled(); - protected: Frame(FrameClient*, FrameHost*, FrameOwner*);
diff --git a/third_party/WebKit/Source/core/frame/LocalFrame.cpp b/third_party/WebKit/Source/core/frame/LocalFrame.cpp index 7f8da12..549efa6 100644 --- a/third_party/WebKit/Source/core/frame/LocalFrame.cpp +++ b/third_party/WebKit/Source/core/frame/LocalFrame.cpp
@@ -904,6 +904,13 @@ return m_frameScheduler.get(); } +void LocalFrame::scheduleVisualUpdateUnlessThrottled() +{ + if (shouldThrottleRendering()) + return; + page()->animator().scheduleVisualUpdate(); +} + void LocalFrame::updateSecurityOrigin(SecurityOrigin* origin) { script().updateSecurityOrigin(origin);
diff --git a/third_party/WebKit/Source/core/frame/LocalFrame.h b/third_party/WebKit/Source/core/frame/LocalFrame.h index 32000d8..1ec0848e 100644 --- a/third_party/WebKit/Source/core/frame/LocalFrame.h +++ b/third_party/WebKit/Source/core/frame/LocalFrame.h
@@ -186,6 +186,7 @@ // Returns the frame scheduler, creating one if needed. WebFrameScheduler* frameScheduler(); + void scheduleVisualUpdateUnlessThrottled(); void updateSecurityOrigin(SecurityOrigin*);
diff --git a/third_party/WebKit/Source/core/frame/RemoteDOMWindow.cpp b/third_party/WebKit/Source/core/frame/RemoteDOMWindow.cpp index 56bacf32..e6935ed6 100644 --- a/third_party/WebKit/Source/core/frame/RemoteDOMWindow.cpp +++ b/third_party/WebKit/Source/core/frame/RemoteDOMWindow.cpp
@@ -344,4 +344,9 @@ { } +void RemoteDOMWindow::frameDetached() +{ + m_frame = nullptr; +} + } // namespace blink
diff --git a/third_party/WebKit/Source/core/frame/RemoteDOMWindow.h b/third_party/WebKit/Source/core/frame/RemoteDOMWindow.h index 35b796b6..27cc423 100644 --- a/third_party/WebKit/Source/core/frame/RemoteDOMWindow.h +++ b/third_party/WebKit/Source/core/frame/RemoteDOMWindow.h
@@ -80,6 +80,8 @@ int requestIdleCallback(IdleRequestCallback*, const IdleRequestOptions&) override; void cancelIdleCallback(int id) override; + void frameDetached(); + private: explicit RemoteDOMWindow(RemoteFrame&);
diff --git a/third_party/WebKit/Source/core/frame/RemoteFrame.cpp b/third_party/WebKit/Source/core/frame/RemoteFrame.cpp index 88ba745..5d7965a 100644 --- a/third_party/WebKit/Source/core/frame/RemoteFrame.cpp +++ b/third_party/WebKit/Source/core/frame/RemoteFrame.cpp
@@ -8,6 +8,7 @@ #include "bindings/core/v8/WindowProxy.h" #include "bindings/core/v8/WindowProxyManager.h" #include "core/dom/RemoteSecurityContext.h" +#include "core/frame/LocalFrame.h" #include "core/frame/RemoteDOMWindow.h" #include "core/frame/RemoteFrameClient.h" #include "core/frame/RemoteFrameView.h" @@ -145,6 +146,14 @@ // Oilpan: as RemoteFrameView performs no finalization actions, // no explicit dispose() of it needed here. (cf. FrameView::dispose().) m_view = view; + + // ... the RemoteDOMWindow will need to be informed of detachment, + // as otherwise it will keep a strong reference back to this RemoteFrame. + // That combined with wrappers (owned and kept alive by RemoteFrame) keeping + // persistent strong references to RemoteDOMWindow will prevent the GCing + // of all these objects. Break the cycle by notifying of detachment. + if (!m_view) + m_domWindow->frameDetached(); } void RemoteFrame::createView() @@ -179,4 +188,9 @@ toHTMLFrameOwnerElement(owner())->setNeedsCompositingUpdate(); } +void RemoteFrame::advanceFocus(WebFocusType type, LocalFrame* source) +{ + remoteFrameClient()->advanceFocus(type, source); +} + } // namespace blink
diff --git a/third_party/WebKit/Source/core/frame/RemoteFrame.h b/third_party/WebKit/Source/core/frame/RemoteFrame.h index c12ec4b..21e0c4e 100644 --- a/third_party/WebKit/Source/core/frame/RemoteFrame.h +++ b/third_party/WebKit/Source/core/frame/RemoteFrame.h
@@ -8,11 +8,13 @@ #include "core/CoreExport.h" #include "core/dom/RemoteSecurityContext.h" #include "core/frame/Frame.h" +#include "public/platform/WebFocusType.h" namespace blink { class Event; class IntRect; +class LocalFrame; class RemoteDOMWindow; class RemoteFrameClient; class RemoteFrameView; @@ -50,6 +52,8 @@ void setRemotePlatformLayer(WebLayer*); WebLayer* remotePlatformLayer() const { return m_remotePlatformLayer; } + void advanceFocus(WebFocusType, LocalFrame* source); + void setView(PassRefPtrWillBeRawPtr<RemoteFrameView>); void createView();
diff --git a/third_party/WebKit/Source/core/frame/RemoteFrameClient.h b/third_party/WebKit/Source/core/frame/RemoteFrameClient.h index 50d88f8..7beb80a 100644 --- a/third_party/WebKit/Source/core/frame/RemoteFrameClient.h +++ b/third_party/WebKit/Source/core/frame/RemoteFrameClient.h
@@ -8,6 +8,7 @@ #include "core/frame/FrameClient.h" #include "core/frame/FrameTypes.h" #include "core/loader/FrameLoaderTypes.h" +#include "public/platform/WebFocusType.h" namespace blink { @@ -28,6 +29,8 @@ virtual void forwardInputEvent(Event*) = 0; virtual void frameRectsChanged(const IntRect& frameRect) = 0; + + virtual void advanceFocus(WebFocusType, LocalFrame* source) = 0; }; } // namespace blink
diff --git a/third_party/WebKit/Source/core/frame/Settings.in b/third_party/WebKit/Source/core/frame/Settings.in index c54a085..13b686e 100644 --- a/third_party/WebKit/Source/core/frame/Settings.in +++ b/third_party/WebKit/Source/core/frame/Settings.in
@@ -96,8 +96,6 @@ # WebAudio support. webAudioEnabled initial=false -asynchronousSpellCheckingEnabled initial=false - hyperlinkAuditingEnabled initial=false allowDisplayOfInsecureContent initial=true allowRunningOfInsecureContent initial=true
diff --git a/third_party/WebKit/Source/core/frame/UseCounter.cpp b/third_party/WebKit/Source/core/frame/UseCounter.cpp index 80baf8d3..63f6db30 100644 --- a/third_party/WebKit/Source/core/frame/UseCounter.cpp +++ b/third_party/WebKit/Source/core/frame/UseCounter.cpp
@@ -549,6 +549,7 @@ case CSSPropertyFontFeatureSettings: return 514; case CSSPropertyVariable: return 515; case CSSPropertyFontDisplay: return 516; + case CSSPropertyContain: return 517; // 1. Add new features above this line (don't change the assigned numbers of the existing // items). @@ -565,7 +566,7 @@ return 0; } -static int maximumCSSSampleId() { return 516; } +static int maximumCSSSampleId() { return 517; } void UseCounter::muteForInspector() {
diff --git a/third_party/WebKit/Source/core/frame/UseCounter.h b/third_party/WebKit/Source/core/frame/UseCounter.h index c68a5459..445fa206 100644 --- a/third_party/WebKit/Source/core/frame/UseCounter.h +++ b/third_party/WebKit/Source/core/frame/UseCounter.h
@@ -896,6 +896,24 @@ PresentationConnectionClose = 1038, SVG1DOMShape = 1039, SVG1DOMText = 1040, + RTCPeerConnectionConstructorConstraints = 1041, + RTCPeerConnectionConstructorCompliant = 1042, + RTCPeerConnectionCreateOfferLegacyNoFailureCallback = 1043, + RTCPeerConnectionCreateOfferLegacyFailureCallback = 1044, + RTCPeerConnectionCreateOfferLegacyConstraints = 1045, + RTCPeerConnectionCreateOfferLegacyOfferOptions = 1046, + RTCPeerConnectionCreateOfferLegacyCompliant = 1047, + RTCPeerConnectionCreateAnswerLegacyNoFailureCallback = 1048, + RTCPeerConnectionCreateAnswerLegacyFailureCallback = 1049, + RTCPeerConnectionCreateAnswerLegacyConstraints = 1050, + RTCPeerConnectionCreateAnswerLegacyCompliant = 1051, + RTCPeerConnectionSetLocalDescriptionLegacyNoSuccessCallback = 1052, + RTCPeerConnectionSetLocalDescriptionLegacyNoFailureCallback = 1053, + RTCPeerConnectionSetLocalDescriptionLegacyCompliant = 1054, + RTCPeerConnectionSetRemoteDescriptionLegacyNoSuccessCallback = 1055, + RTCPeerConnectionSetRemoteDescriptionLegacyNoFailureCallback = 1056, + RTCPeerConnectionSetRemoteDescriptionLegacyCompliant = 1057, + RTCPeerConnectionGetStatsLegacyNonCompliant = 1058, // Add new features immediately above this line. Don't change assigned // numbers of any item, and don't reuse removed slots.
diff --git a/third_party/WebKit/Source/core/frame/csp/CSPDirectiveList.cpp b/third_party/WebKit/Source/core/frame/csp/CSPDirectiveList.cpp index d6f38fc..898d4fa 100644 --- a/third_party/WebKit/Source/core/frame/csp/CSPDirectiveList.cpp +++ b/third_party/WebKit/Source/core/frame/csp/CSPDirectiveList.cpp
@@ -73,21 +73,21 @@ { String message = m_reportOnly ? "[Report Only] " + consoleMessage : consoleMessage; m_policy->logToConsole(ConsoleMessage::create(SecurityMessageSource, ErrorMessageLevel, message)); - m_policy->reportViolation(directiveText, effectiveDirective, message, blockedURL, m_reportEndpoints, m_header); + m_policy->reportViolation(directiveText, effectiveDirective, message, blockedURL, m_reportEndpoints, m_header, ContentSecurityPolicy::URLViolation); } void CSPDirectiveList::reportViolationWithFrame(const String& directiveText, const String& effectiveDirective, const String& consoleMessage, const KURL& blockedURL, LocalFrame* frame) const { String message = m_reportOnly ? "[Report Only] " + consoleMessage : consoleMessage; m_policy->logToConsole(ConsoleMessage::create(SecurityMessageSource, ErrorMessageLevel, message), frame); - m_policy->reportViolation(directiveText, effectiveDirective, message, blockedURL, m_reportEndpoints, m_header, frame); + m_policy->reportViolation(directiveText, effectiveDirective, message, blockedURL, m_reportEndpoints, m_header, ContentSecurityPolicy::URLViolation, frame); } void CSPDirectiveList::reportViolationWithLocation(const String& directiveText, const String& effectiveDirective, const String& consoleMessage, const KURL& blockedURL, const String& contextURL, const WTF::OrdinalNumber& contextLine) const { String message = m_reportOnly ? "[Report Only] " + consoleMessage : consoleMessage; m_policy->logToConsole(ConsoleMessage::create(SecurityMessageSource, ErrorMessageLevel, message, contextURL, contextLine.oneBasedInt())); - m_policy->reportViolation(directiveText, effectiveDirective, message, blockedURL, m_reportEndpoints, m_header); + m_policy->reportViolation(directiveText, effectiveDirective, message, blockedURL, m_reportEndpoints, m_header, ContentSecurityPolicy::InlineViolation); } void CSPDirectiveList::reportViolationWithState(const String& directiveText, const String& effectiveDirective, const String& message, const KURL& blockedURL, ScriptState* scriptState, const ContentSecurityPolicy::ExceptionStatus exceptionStatus) const @@ -102,7 +102,7 @@ consoleMessage->setScriptState(scriptState); m_policy->logToConsole(consoleMessage.release()); } - m_policy->reportViolation(directiveText, effectiveDirective, message, blockedURL, m_reportEndpoints, m_header); + m_policy->reportViolation(directiveText, effectiveDirective, message, blockedURL, m_reportEndpoints, m_header, ContentSecurityPolicy::EvalViolation); } bool CSPDirectiveList::checkEval(SourceListDirective* directive) const
diff --git a/third_party/WebKit/Source/core/frame/csp/ContentSecurityPolicy.cpp b/third_party/WebKit/Source/core/frame/csp/ContentSecurityPolicy.cpp index cb2a42ea2..630aba8 100644 --- a/third_party/WebKit/Source/core/frame/csp/ContentSecurityPolicy.cpp +++ b/third_party/WebKit/Source/core/frame/csp/ContentSecurityPolicy.cpp
@@ -724,8 +724,9 @@ } } -void ContentSecurityPolicy::reportViolation(const String& directiveText, const String& effectiveDirective, const String& consoleMessage, const KURL& blockedURL, const Vector<String>& reportEndpoints, const String& header, LocalFrame* contextFrame) +void ContentSecurityPolicy::reportViolation(const String& directiveText, const String& effectiveDirective, const String& consoleMessage, const KURL& blockedURL, const Vector<String>& reportEndpoints, const String& header, ViolationType violationType, LocalFrame* contextFrame) { + ASSERT(violationType == URLViolation || blockedURL.isEmpty()); ASSERT((m_executionContext && !contextFrame) || (equalIgnoringCase(effectiveDirective, ContentSecurityPolicy::FrameAncestors) && contextFrame)); // FIXME: Support sending reports from worker. @@ -768,7 +769,17 @@ cspReport->setString("violated-directive", violationData.violatedDirective()); cspReport->setString("effective-directive", violationData.effectiveDirective()); cspReport->setString("original-policy", violationData.originalPolicy()); - cspReport->setString("blocked-uri", violationData.blockedURI()); + switch (violationType) { + case InlineViolation: + cspReport->setString("blocked-uri", "inline"); + break; + case EvalViolation: + cspReport->setString("blocked-uri", "eval"); + break; + case URLViolation: + cspReport->setString("blocked-uri", violationData.blockedURI()); + break; + } if (!violationData.sourceFile().isEmpty() && violationData.lineNumber()) { cspReport->setString("source-file", violationData.sourceFile()); cspReport->setNumber("line-number", violationData.lineNumber());
diff --git a/third_party/WebKit/Source/core/frame/csp/ContentSecurityPolicy.h b/third_party/WebKit/Source/core/frame/csp/ContentSecurityPolicy.h index df15db7..7a37106 100644 --- a/third_party/WebKit/Source/core/frame/csp/ContentSecurityPolicy.h +++ b/third_party/WebKit/Source/core/frame/csp/ContentSecurityPolicy.h
@@ -123,6 +123,16 @@ WillNotThrowException }; + // This covers the possible values of a violation's 'resource', as defined in + // https://w3c.github.io/webappsec-csp/#violation-resource. By the time we + // generate a report, we're guaranteed that the value isn't 'null', so we don't + // need that state in this enum. + enum ViolationType { + InlineViolation, + EvalViolation, + URLViolation + }; + static PassRefPtrWillBeRawPtr<ContentSecurityPolicy> create() { return adoptRefWillBeNoop(new ContentSecurityPolicy()); @@ -226,7 +236,7 @@ // If a frame is passed in, the report will be sent using it as a context. If no frame is // passed in, the report will be sent via this object's |m_executionContext| (or dropped // on the floor if no such context is available). - void reportViolation(const String& directiveText, const String& effectiveDirective, const String& consoleMessage, const KURL& blockedURL, const Vector<String>& reportEndpoints, const String& header, LocalFrame* = nullptr); + void reportViolation(const String& directiveText, const String& effectiveDirective, const String& consoleMessage, const KURL& blockedURL, const Vector<String>& reportEndpoints, const String& header, ViolationType, LocalFrame* = nullptr); void reportBlockedScriptExecutionToInspector(const String& directiveText) const;
diff --git a/third_party/WebKit/Source/core/html/HTMLMediaElement.cpp b/third_party/WebKit/Source/core/html/HTMLMediaElement.cpp index badbe171..b723253 100644 --- a/third_party/WebKit/Source/core/html/HTMLMediaElement.cpp +++ b/third_party/WebKit/Source/core/html/HTMLMediaElement.cpp
@@ -384,13 +384,6 @@ removeElementFromDocumentMap(this, &document()); // Destroying the player may cause a resource load to be canceled, - // which could result in userCancelledLoad() being called back. - // Setting m_isFinalizing ensures that such a call will not cause - // us to dispatch an abort event, which would result in a crash. - // See http://crbug.com/233654 for more details. - m_isFinalizing = true; - - // Destroying the player may cause a resource load to be canceled, // which could result in Document::dispatchWindowLoadEvent() being // called via ResourceFetch::didLoadResource() then // FrameLoader::checkCompleted(). To prevent load event dispatching during @@ -474,10 +467,12 @@ // FIXME: This is a temporary fix to prevent this object from causing the // MediaPlayer to dereference LocalFrame and FrameLoader pointers from the - // previous document. A proper fix would provide a mechanism to allow this - // object to refresh the MediaPlayer's LocalFrame and FrameLoader references on + // previous document. This restarts the load, as if the src attribute had been set. + // A proper fix would provide a mechanism to allow this object to refresh + // the MediaPlayer's LocalFrame and FrameLoader references on // document changes so that playback can be resumed properly. - userCancelledLoad(); + clearMediaPlayer(LoadMediaResource); + scheduleDelayedAction(LoadMediaResource); // Decrement the load event delay count on oldDocument now that m_webMediaPlayer has been destroyed // and there is no risk of dispatching a load event from within the destructor. @@ -2978,50 +2973,6 @@ m_playbackProgressTimer.stop(); } -void HTMLMediaElement::userCancelledLoad() -{ - WTF_LOG(Media, "HTMLMediaElement::userCancelledLoad(%p)", this); - - // If the media data fetching process is aborted by the user: - - // 1 - The user agent should cancel the fetching process. - clearMediaPlayer(-1); - // Reset m_readyState and m_readyStateMaximum since m_webMediaPlayer is gone. - ReadyState readyState = m_readyState; - m_readyState = HAVE_NOTHING; - m_readyStateMaximum = HAVE_NOTHING; - - // TODO(srirama.m): Investigate if this condition can be dropped entirely without any issues. - if (m_networkState == NETWORK_EMPTY || m_completelyLoaded || m_isFinalizing) - return; - - // 2 - Set the error attribute to a new MediaError object whose code attribute is set to MEDIA_ERR_ABORTED. - m_error = MediaError::create(MediaError::MEDIA_ERR_ABORTED); - - // 3 - Queue a task to fire a simple event named error at the media element. - scheduleEvent(EventTypeNames::abort); - - // 4 - If the media element's readyState attribute has a value equal to HAVE_NOTHING, set the - // element's networkState attribute to the NETWORK_EMPTY value and queue a task to fire a - // simple event named emptied at the element. Otherwise, set the element's networkState - // attribute to the NETWORK_IDLE value. - if (readyState == HAVE_NOTHING) { - setNetworkState(NETWORK_EMPTY); - scheduleEvent(EventTypeNames::emptied); - } else { - setNetworkState(NETWORK_IDLE); - } - - // 5 - Set the element's delaying-the-load-event flag to false. This stops delaying the load event. - setShouldDelayLoadEvent(false); - - // 6 - Abort the overall resource selection algorithm. - m_currentSourceNode = nullptr; - - invalidateCachedTime(); - cueTimeline().updateActiveCues(0); -} - void HTMLMediaElement::clearMediaPlayerAndAudioSourceProviderClientWithoutLocking() { #if ENABLE(WEB_AUDIO) @@ -3070,13 +3021,19 @@ recordMetricsIfPausing(); - // Close the async event queue so that no events are enqueued by userCancelledLoad. + // Close the async event queue so that no events are enqueued. cancelPendingEventsAndCallbacks(); m_asyncEventQueue->close(); - userCancelledLoad(); - // Stop the playback without generating events + clearMediaPlayer(-1); + m_readyState = HAVE_NOTHING; + m_readyStateMaximum = HAVE_NOTHING; + setNetworkState(NETWORK_EMPTY); + setShouldDelayLoadEvent(false); + m_currentSourceNode = nullptr; + invalidateCachedTime(); + cueTimeline().updateActiveCues(0); m_playing = false; m_paused = true; m_seeking = false;
diff --git a/third_party/WebKit/Source/core/html/HTMLMediaElement.h b/third_party/WebKit/Source/core/html/HTMLMediaElement.h index e1c6785..45d33451 100644 --- a/third_party/WebKit/Source/core/html/HTMLMediaElement.h +++ b/third_party/WebKit/Source/core/html/HTMLMediaElement.h
@@ -356,7 +356,6 @@ WebMediaPlayer::LoadType loadType() const; void scheduleNextSourceChild(); void loadNextSourceChild(); - void userCancelledLoad(); void clearMediaPlayer(int flags); void clearMediaPlayerAndAudioSourceProviderClientWithoutLocking(); bool havePotentialSourceChild();
diff --git a/third_party/WebKit/Source/core/html/HTMLOptionElement.cpp b/third_party/WebKit/Source/core/html/HTMLOptionElement.cpp index c94e8f47..8594640e7 100644 --- a/third_party/WebKit/Source/core/html/HTMLOptionElement.cpp +++ b/third_party/WebKit/Source/core/html/HTMLOptionElement.cpp
@@ -213,8 +213,8 @@ LayoutTheme::theme().controlStateChanged(*layoutObject(), EnabledControlState); } } else if (name == selectedAttr) { - if (bool willBeSelected = !value.isNull()) - setSelected(willBeSelected); + if (oldValue.isNull() != value.isNull() && !m_isDirty) + setSelected(!value.isNull()); } else if (name == labelAttr) { updateLabel(); } else { @@ -263,6 +263,17 @@ select->optionSelectionStateChanged(this, selected); } +bool HTMLOptionElement::selectedForBinding() const +{ + return selected(); +} + +void HTMLOptionElement::setSelectedForBinding(bool selected) +{ + setSelected(selected); + m_isDirty = true; +} + void HTMLOptionElement::setSelectedState(bool selected) { if (m_isSelected == selected) @@ -286,6 +297,11 @@ } } +void HTMLOptionElement::setDirty(bool value) +{ + m_isDirty = true; +} + void HTMLOptionElement::childrenChanged(const ChildrenChange& change) { if (HTMLDataListElement* dataList = ownerDataListElement())
diff --git a/third_party/WebKit/Source/core/html/HTMLOptionElement.h b/third_party/WebKit/Source/core/html/HTMLOptionElement.h index 88ca48a..cb509cf 100644 --- a/third_party/WebKit/Source/core/html/HTMLOptionElement.h +++ b/third_party/WebKit/Source/core/html/HTMLOptionElement.h
@@ -58,6 +58,8 @@ bool selected() const; void setSelected(bool); + bool selectedForBinding() const; + void setSelectedForBinding(bool); HTMLDataListElement* ownerDataListElement() const; HTMLSelectElement* ownerSelectElement() const; @@ -71,7 +73,10 @@ String textIndentedToRespectGroupLabel() const; + // Update 'selectedness'. void setSelectedState(bool); + // Update 'dirtiness'. + void setDirty(bool); HTMLFormElement* form() const; bool spatialNavigationFocused() const; @@ -104,7 +109,12 @@ void updateLabel(); bool m_disabled; + // Represents 'selectedness'. + // https://html.spec.whatwg.org/multipage/forms.html#concept-option-selectedness bool m_isSelected; + // Represents 'dirtiness'. + // https://html.spec.whatwg.org/multipage/forms.html#concept-option-dirtiness + bool m_isDirty = false; RefPtr<ComputedStyle> m_style; };
diff --git a/third_party/WebKit/Source/core/html/HTMLOptionElement.idl b/third_party/WebKit/Source/core/html/HTMLOptionElement.idl index bcbeed3..92a23236 100644 --- a/third_party/WebKit/Source/core/html/HTMLOptionElement.idl +++ b/third_party/WebKit/Source/core/html/HTMLOptionElement.idl
@@ -32,7 +32,7 @@ readonly attribute HTMLFormElement? form; attribute DOMString label; [Reflect=selected] attribute boolean defaultSelected; - attribute boolean selected; + [ImplementedAs=selectedForBinding] attribute boolean selected; attribute DOMString value; // TODO(philipj): The text setter should never throw.
diff --git a/third_party/WebKit/Source/core/html/HTMLSelectElement.cpp b/third_party/WebKit/Source/core/html/HTMLSelectElement.cpp index dc1c7de..8dd4727 100644 --- a/third_party/WebKit/Source/core/html/HTMLSelectElement.cpp +++ b/third_party/WebKit/Source/core/html/HTMLSelectElement.cpp
@@ -143,7 +143,7 @@ if (optionIndex == selectedIndex()) return; - selectOption(optionIndex, DeselectOtherOptions | (fireOnChangeNow ? DispatchInputAndChangeEvent : 0)); + selectOption(optionIndex, DeselectOtherOptions | MakeOptionDirty | (fireOnChangeNow ? DispatchInputAndChangeEvent : 0)); } bool HTMLSelectElement::hasPlaceholderLabelOption() const @@ -282,7 +282,7 @@ setSuggestedIndex(-1); if (m_isAutofilledByPreview) setAutofilled(false); - SelectOptionFlags flags = DeselectOtherOptions; + SelectOptionFlags flags = DeselectOtherOptions | MakeOptionDirty; if (sendEvents) flags |= DispatchInputAndChangeEvent; selectOption(optionIndex, flags); @@ -447,7 +447,7 @@ // Restore selectedIndex after changing the multiple flag to preserve // selection as single-line and multi-line has different defaults. if (oldMultiple != this->multiple()) - setSelectedIndex(oldSelectedIndex); + selectOption(oldSelectedIndex, DeselectOtherOptions); } void HTMLSelectElement::setSize(unsigned size) @@ -679,16 +679,20 @@ const WillBeHeapVector<RawPtrWillBeMember<HTMLElement>>& items = listItems(); for (int i = 0; i < static_cast<int>(items.size()); ++i) { - HTMLElement* element = items[i]; - if (!isHTMLOptionElement(*element) || toHTMLOptionElement(element)->isDisabledFormControl() || !toHTMLOptionElement(element)->layoutObject()) + if (!isHTMLOptionElement(*items[i])) continue; - - if (i >= start && i <= end) - toHTMLOptionElement(element)->setSelectedState(m_activeSelectionState); - else if (deselectOtherOptions || i >= static_cast<int>(m_cachedStateForActiveSelection.size())) - toHTMLOptionElement(element)->setSelectedState(false); - else - toHTMLOptionElement(element)->setSelectedState(m_cachedStateForActiveSelection[i]); + HTMLOptionElement& option = toHTMLOptionElement(*items[i]); + if (option.isDisabledFormControl() || !option.layoutObject()) + continue; + if (i >= start && i <= end) { + option.setSelectedState(m_activeSelectionState); + option.setDirty(true); + } else if (deselectOtherOptions || i >= static_cast<int>(m_cachedStateForActiveSelection.size())) { + option.setSelectedState(false); + option.setDirty(true); + } else { + option.setSelectedState(m_cachedStateForActiveSelection[i]); + } } setNeedsValidityCheck(); @@ -899,7 +903,7 @@ void HTMLSelectElement::setSelectedIndex(int index) { - selectOption(index, DeselectOtherOptions); + selectOption(index, DeselectOtherOptions | MakeOptionDirty); } int HTMLSelectElement::suggestedIndex() const @@ -1009,6 +1013,8 @@ // because optionToListIndex() returned it. element = toHTMLOptionElement(items[listIndex]); element->setSelectedState(true); + if (flags & MakeOptionDirty) + element->setDirty(true); } // deselectItemsWithoutValidation() is O(N). @@ -1171,10 +1177,13 @@ size_t index = state[1].toUInt(); if (index < itemsSize && isHTMLOptionElement(items[index]) && toHTMLOptionElement(items[index])->value() == state[0]) { toHTMLOptionElement(items[index])->setSelectedState(true); + toHTMLOptionElement(items[index])->setDirty(true); } else { size_t foundIndex = searchOptionsForValue(state[0], 0, itemsSize); - if (foundIndex != kNotFound) + if (foundIndex != kNotFound) { toHTMLOptionElement(items[foundIndex])->setSelectedState(true); + toHTMLOptionElement(items[foundIndex])->setDirty(true); + } } } else { size_t startIndex = 0; @@ -1183,6 +1192,7 @@ const size_t index = state[i + 1].toUInt(); if (index < itemsSize && isHTMLOptionElement(items[index]) && toHTMLOptionElement(items[index])->value() == value) { toHTMLOptionElement(items[index])->setSelectedState(true); + toHTMLOptionElement(items[index])->setDirty(true); startIndex = index + 1; } else { size_t foundIndex = searchOptionsForValue(value, startIndex, itemsSize); @@ -1191,6 +1201,7 @@ if (foundIndex == kNotFound) continue; toHTMLOptionElement(items[foundIndex])->setSelectedState(true); + toHTMLOptionElement(items[foundIndex])->setDirty(true); startIndex = foundIndex + 1; } } @@ -1229,21 +1240,21 @@ const WillBeHeapVector<RawPtrWillBeMember<HTMLElement>>& items = listItems(); for (unsigned i = 0; i < items.size(); ++i) { - HTMLElement* element = items[i]; - if (!isHTMLOptionElement(*element)) + if (!isHTMLOptionElement(*items[i])) continue; - - if (items[i]->fastHasAttribute(selectedAttr)) { + HTMLOptionElement* option = toHTMLOptionElement(items[i]); + if (option->fastHasAttribute(selectedAttr)) { if (selectedOption && !m_multiple) selectedOption->setSelectedState(false); - toHTMLOptionElement(element)->setSelectedState(true); - selectedOption = toHTMLOptionElement(element); + option->setSelectedState(true); + selectedOption = option; } else { - toHTMLOptionElement(element)->setSelectedState(false); + option->setSelectedState(false); } + option->setDirty(false); if (!firstOption) - firstOption = toHTMLOptionElement(element); + firstOption = option; } if (!selectedOption && firstOption && !m_multiple && m_size <= 1) @@ -1338,7 +1349,7 @@ handled = false; if (handled && static_cast<size_t>(listIndex) < listItems.size()) - selectOption(listToOptionIndex(listIndex), DeselectOtherOptions | DispatchInputAndChangeEvent); + selectOption(listToOptionIndex(listIndex), DeselectOtherOptions | MakeOptionDirty | DispatchInputAndChangeEvent); if (handled) event->setDefaultHandled(); @@ -1415,12 +1426,14 @@ bool multiSelect = m_multiple && multi && !shift; if (isHTMLOptionElement(*clickedElement)) { + HTMLOptionElement& option = toHTMLOptionElement(*clickedElement); // Keep track of whether an active selection (like during drag // selection), should select or deselect. - if (toHTMLOptionElement(*clickedElement).selected() && multiSelect) + if (option.selected() && multiSelect) { m_activeSelectionState = false; - if (!m_activeSelectionState) - toHTMLOptionElement(*clickedElement).setSelectedState(false); + option.setSelectedState(false); + option.setDirty(true); + } } // If we're not in any special multiple selection mode, then deselect all @@ -1435,8 +1448,10 @@ setActiveSelectionAnchorIndex(selectedIndex()); // Set the selection state of the clicked option. - if (isHTMLOptionElement(*clickedElement) && !toHTMLOptionElement(*clickedElement).isDisabledFormControl()) + if (isHTMLOptionElement(*clickedElement) && !toHTMLOptionElement(*clickedElement).isDisabledFormControl()) { toHTMLOptionElement(*clickedElement).setSelectedState(true); + toHTMLOptionElement(*clickedElement).setDirty(true); + } // If there was no selectedIndex() for the previous initialization, or If // we're doing a single selection, or a multiple selection (using cmd or @@ -1725,7 +1740,7 @@ int index = m_typeAhead.handleEvent(event, TypeAhead::MatchPrefix | TypeAhead::CycleFirstChar); if (index < 0) return; - selectOption(listToOptionIndex(index), DeselectOtherOptions | DispatchInputAndChangeEvent); + selectOption(listToOptionIndex(index), DeselectOtherOptions | MakeOptionDirty | DispatchInputAndChangeEvent); if (!usesMenuList()) listBoxOnChange(); } @@ -1754,6 +1769,7 @@ } else { selectOption(index, DispatchInputAndChangeEvent); } + toHTMLOptionElement(element).setDirty(true); if (usesMenuList()) return; listBoxOnChange();
diff --git a/third_party/WebKit/Source/core/html/HTMLSelectElement.h b/third_party/WebKit/Source/core/html/HTMLSelectElement.h index 06287eff..afb46724 100644 --- a/third_party/WebKit/Source/core/html/HTMLSelectElement.h +++ b/third_party/WebKit/Source/core/html/HTMLSelectElement.h
@@ -208,6 +208,7 @@ enum SelectOptionFlag { DeselectOtherOptions = 1 << 0, DispatchInputAndChangeEvent = 1 << 1, + MakeOptionDirty = 1 << 2, }; typedef unsigned SelectOptionFlags; void selectOption(int optionIndex, SelectOptionFlags = 0);
diff --git a/third_party/WebKit/Source/core/html/HTMLTextFormControlElementTest.cpp b/third_party/WebKit/Source/core/html/HTMLTextFormControlElementTest.cpp index 2ff8c82..590560d9 100644 --- a/third_party/WebKit/Source/core/html/HTMLTextFormControlElementTest.cpp +++ b/third_party/WebKit/Source/core/html/HTMLTextFormControlElementTest.cpp
@@ -47,24 +47,16 @@ RefPtrWillBePersistent<HTMLInputElement> m_input; }; -class DummyTextCheckerClient : public EmptyTextCheckerClient { -public: - ~DummyTextCheckerClient() { } - - bool shouldEraseMarkersAfterChangeSelection(TextCheckingType) const override { return false; } -}; - class DummySpellCheckerClient : public EmptySpellCheckerClient { public: virtual ~DummySpellCheckerClient() { } bool isContinuousSpellCheckingEnabled() override { return true; } - bool isGrammarCheckingEnabled() override { return true; } - TextCheckerClient& textChecker() override { return m_dummyTextCheckerClient; } + TextCheckerClient& textChecker() override { return m_emptyTextCheckerClient; } private: - DummyTextCheckerClient m_dummyTextCheckerClient; + EmptyTextCheckerClient m_emptyTextCheckerClient; }; void HTMLTextFormControlElementTest::SetUp()
diff --git a/third_party/WebKit/Source/core/html/HTMLTrackElement.h b/third_party/WebKit/Source/core/html/HTMLTrackElement.h index 19beb53c..8d1d1990 100644 --- a/third_party/WebKit/Source/core/html/HTMLTrackElement.h +++ b/third_party/WebKit/Source/core/html/HTMLTrackElement.h
@@ -72,7 +72,6 @@ void newCuesAvailable(TextTrackLoader*) override; void cueLoadingCompleted(TextTrackLoader*, bool loadingFailed) override; void newRegionsAvailable(TextTrackLoader*) override; - String debugName() const override { return "HTMLTrackElement"; } void setReadyState(ReadyState);
diff --git a/third_party/WebKit/Source/core/html/PluginDocument.cpp b/third_party/WebKit/Source/core/html/PluginDocument.cpp index dc40f1c5..b10bfbf 100644 --- a/third_party/WebKit/Source/core/html/PluginDocument.cpp +++ b/third_party/WebKit/Source/core/html/PluginDocument.cpp
@@ -135,14 +135,7 @@ void PluginDocumentParser::finish() { - if (PluginView* view = pluginView()) { - const ResourceError& error = document()->loader()->mainDocumentError(); - if (error.isNull()) - view->didFinishLoading(); - else - view->didFailLoading(error); - m_embedElement = nullptr; - } + m_embedElement = nullptr; RawDataDocumentParser::finish(); }
diff --git a/third_party/WebKit/Source/core/html/shadow/MediaControlElementTypes.cpp b/third_party/WebKit/Source/core/html/shadow/MediaControlElementTypes.cpp index 9edb2ad..2ea2f3d 100644 --- a/third_party/WebKit/Source/core/html/shadow/MediaControlElementTypes.cpp +++ b/third_party/WebKit/Source/core/html/shadow/MediaControlElementTypes.cpp
@@ -97,6 +97,8 @@ void MediaControlElement::setIsWanted(bool wanted) { + if (m_isWanted == wanted) + return; m_isWanted = wanted; updateShownState(); }
diff --git a/third_party/WebKit/Source/core/imagebitmap/ImageBitmapFactories.idl b/third_party/WebKit/Source/core/imagebitmap/ImageBitmapFactories.idl index a94b9922..fa642d1 100644 --- a/third_party/WebKit/Source/core/imagebitmap/ImageBitmapFactories.idl +++ b/third_party/WebKit/Source/core/imagebitmap/ImageBitmapFactories.idl
@@ -28,6 +28,8 @@ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ +// https://html.spec.whatwg.org/#imagebitmapfactories + typedef (HTMLImageElement or HTMLVideoElement or HTMLCanvasElement or
diff --git a/third_party/WebKit/Source/core/input/EventHandler.cpp b/third_party/WebKit/Source/core/input/EventHandler.cpp index 444132c7..1363f3f 100644 --- a/third_party/WebKit/Source/core/input/EventHandler.cpp +++ b/third_party/WebKit/Source/core/input/EventHandler.cpp
@@ -3200,7 +3200,7 @@ WebInputEventResult EventHandler::keyEvent(const PlatformKeyboardEvent& initialKeyEvent) { RefPtrWillBeRawPtr<FrameView> protector(m_frame->view()); - m_frame->chromeClient().setToolTip(String(), LTR); + m_frame->chromeClient().clearToolTip(); if (initialKeyEvent.windowsVirtualKeyCode() == VK_CAPITAL) capsLockStateMayHaveChanged();
diff --git a/third_party/WebKit/Source/core/input/TouchActionUtil.cpp b/third_party/WebKit/Source/core/input/TouchActionUtil.cpp index 8ef15dfd8..cf93a4a 100644 --- a/third_party/WebKit/Source/core/input/TouchActionUtil.cpp +++ b/third_party/WebKit/Source/core/input/TouchActionUtil.cpp
@@ -6,6 +6,7 @@ #include "core/input/TouchActionUtil.h" #include "core/dom/Node.h" +#include "core/html/HTMLFrameOwnerElement.h" #include "core/layout/LayoutBox.h" #include "core/layout/LayoutObject.h" @@ -18,7 +19,7 @@ // According to the CSS Box Model Spec (http://dev.w3.org/csswg/css-box/#the-width-and-height-properties) // width applies to all elements but non-replaced inline elements, table rows, and row groups and // height applies to all elements but non-replaced inline elements, table columns, and column groups. -static bool supportsTouchAction(const LayoutObject& object) +bool supportsTouchAction(const LayoutObject& object) { if (object.isInline() && !object.isReplaced()) return false; @@ -28,26 +29,45 @@ return true; } +const Node* parentNodeAcrossFrames(const Node* curNode) +{ + Node* parentNode = ComposedTreeTraversal::parent(*curNode); + if (parentNode) + return parentNode; + + if (curNode->isDocumentNode()) { + const Document* doc = toDocument(curNode); + return doc->ownerElement(); + } + + return nullptr; +} + } // namespace TouchAction computeEffectiveTouchAction(const Node& node) { // Start by permitting all actions, then walk the elements supporting - // touch-action from the target node up to the nearest scrollable ancestor - // and exclude any prohibited actions. + // touch-action from the target node up to root document, exclude any + // prohibited actions at or below the element that supports them. + // I.e. pan-related actions are considered up to the nearest scroller, + // and zoom related actions are considered up to the root. TouchAction effectiveTouchAction = TouchActionAuto; - for (const Node* curNode = &node; curNode; curNode = ComposedTreeTraversal::parent(*curNode)) { + TouchAction handledTouchActions = TouchActionNone; + for (const Node* curNode = &node; curNode; curNode = parentNodeAcrossFrames(curNode)) { if (LayoutObject* layoutObject = curNode->layoutObject()) { if (supportsTouchAction(*layoutObject)) { TouchAction action = layoutObject->style()->touchAction(); + action |= handledTouchActions; effectiveTouchAction &= action; if (effectiveTouchAction == TouchActionNone) break; } - // If we've reached an ancestor that supports a touch action, search no further. - if (layoutObject->isBox() && toLayoutBox(layoutObject)->scrollsOverflow()) - break; + // If we've reached an ancestor that supports panning, stop allowing panning to be disabled. + if ((layoutObject->isBox() && toLayoutBox(layoutObject)->scrollsOverflow()) + || layoutObject->isLayoutView()) + handledTouchActions |= TouchActionPan; } } return effectiveTouchAction;
diff --git a/third_party/WebKit/Source/core/inspector/v8/InspectorWrapper.cpp b/third_party/WebKit/Source/core/inspector/v8/InspectorWrapper.cpp index 1cab1b3..a9588d6 100644 --- a/third_party/WebKit/Source/core/inspector/v8/InspectorWrapper.cpp +++ b/third_party/WebKit/Source/core/inspector/v8/InspectorWrapper.cpp
@@ -52,8 +52,8 @@ void* InspectorWrapperBase::unwrap(v8::Local<v8::Context> context, v8::Local<v8::Object> object, const char* name) { - ASSERT(context != v8::Debug::GetDebugContext()); v8::Isolate* isolate = context->GetIsolate(); + ASSERT(context != v8::Debug::GetDebugContext(isolate)); v8::Local<v8::Value> value = V8HiddenValue::getHiddenValue(ScriptState::from(context), object, v8InternalizedString(isolate, name)); if (value.IsEmpty()) return nullptr;
diff --git a/third_party/WebKit/Source/core/inspector/v8/V8DebuggerImpl.cpp b/third_party/WebKit/Source/core/inspector/v8/V8DebuggerImpl.cpp index fdb4be8..60ff3fe6 100644 --- a/third_party/WebKit/Source/core/inspector/v8/V8DebuggerImpl.cpp +++ b/third_party/WebKit/Source/core/inspector/v8/V8DebuggerImpl.cpp
@@ -80,8 +80,8 @@ { ASSERT(!enabled()); v8::HandleScope scope(m_isolate); - v8::Debug::SetDebugEventListener(&V8DebuggerImpl::v8DebugEventCallback, v8::External::New(m_isolate, this)); - m_debuggerContext.Reset(m_isolate, v8::Debug::GetDebugContext()); + v8::Debug::SetDebugEventListener(m_isolate, &V8DebuggerImpl::v8DebugEventCallback, v8::External::New(m_isolate, this)); + m_debuggerContext.Reset(m_isolate, v8::Debug::GetDebugContext(m_isolate)); m_callFrameWrapperTemplate.Reset(m_isolate, V8JavaScriptCallFrame::createWrapperTemplate(m_isolate)); compileDebuggerScript(); } @@ -93,7 +93,7 @@ m_debuggerScript.Reset(); m_debuggerContext.Reset(); m_callFrameWrapperTemplate.Reset(); - v8::Debug::SetDebugEventListener(nullptr); + v8::Debug::SetDebugEventListener(m_isolate, nullptr); } bool V8DebuggerImpl::enabled() const @@ -192,8 +192,8 @@ info->Set(v8InternalizedString("condition"), v8String(m_isolate, scriptBreakpoint.condition)); v8::Local<v8::Function> setBreakpointFunction = v8::Local<v8::Function>::Cast(m_debuggerScript.Get(m_isolate)->Get(v8InternalizedString("setBreakpoint"))); - v8::Local<v8::Value> breakpointId = v8::Debug::Call(setBreakpointFunction, info); - if (breakpointId.IsEmpty() || !breakpointId->IsString()) + v8::Local<v8::Value> breakpointId = v8CallOrCrash(v8::Debug::Call(debuggerContext(), setBreakpointFunction, info)); + if (!breakpointId->IsString()) return ""; *actualLineNumber = info->Get(v8InternalizedString("lineNumber"))->Int32Value(); *actualColumnNumber = info->Get(v8InternalizedString("columnNumber"))->Int32Value(); @@ -209,7 +209,7 @@ info->Set(v8InternalizedString("breakpointId"), v8String(m_isolate, breakpointId)); v8::Local<v8::Function> removeBreakpointFunction = v8::Local<v8::Function>::Cast(m_debuggerScript.Get(m_isolate)->Get(v8InternalizedString("removeBreakpoint"))); - v8::Debug::Call(removeBreakpointFunction, info); + v8CallOrCrash(v8::Debug::Call(debuggerContext(), removeBreakpointFunction, info)); } void V8DebuggerImpl::clearBreakpoints() @@ -218,7 +218,7 @@ v8::Context::Scope contextScope(debuggerContext()); v8::Local<v8::Function> clearBreakpoints = v8::Local<v8::Function>::Cast(m_debuggerScript.Get(m_isolate)->Get(v8InternalizedString("clearBreakpoints"))); - v8::Debug::Call(clearBreakpoints); + v8CallOrCrash(v8::Debug::Call(debuggerContext(), clearBreakpoints)); } void V8DebuggerImpl::setBreakpointsActivated(bool activated) @@ -233,7 +233,7 @@ v8::Local<v8::Object> info = v8::Object::New(m_isolate); info->Set(v8InternalizedString("enabled"), v8::Boolean::New(m_isolate, activated)); v8::Local<v8::Function> setBreakpointsActivated = v8::Local<v8::Function>::Cast(m_debuggerScript.Get(m_isolate)->Get(v8InternalizedString("setBreakpointsActivated"))); - v8::Debug::Call(setBreakpointsActivated, info); + v8CallOrCrash(v8::Debug::Call(debuggerContext(), setBreakpointsActivated, info)); m_breakpointsActivated = activated; } @@ -301,7 +301,7 @@ } v8::Local<v8::Function> breakProgramFunction = v8::Local<v8::FunctionTemplate>::New(m_isolate, m_breakProgramCallbackTemplate)->GetFunction(); - v8::Debug::Call(breakProgramFunction); + v8CallOrCrash(v8::Debug::Call(debuggerContext(), breakProgramFunction)); } void V8DebuggerImpl::continueProgram() @@ -447,7 +447,7 @@ v8::Local<v8::Value> currentCallFrameV8; if (m_executionState.IsEmpty()) { v8::Local<v8::Function> currentCallFrameFunction = v8::Local<v8::Function>::Cast(m_debuggerScript.Get(m_isolate)->Get(v8InternalizedString("currentCallFrame"))); - currentCallFrameV8 = v8::Debug::Call(currentCallFrameFunction, v8::Integer::New(m_isolate, data)); + currentCallFrameV8 = v8CallOrCrash(v8::Debug::Call(debuggerContext(), currentCallFrameFunction, v8::Integer::New(m_isolate, data))); } else { v8::Local<v8::Value> argv[] = { m_executionState, v8::Integer::New(m_isolate, data) }; currentCallFrameV8 = callDebuggerMethod("currentCallFrame", WTF_ARRAY_LENGTH(argv), argv).ToLocalChecked(); @@ -498,7 +498,7 @@ v8::Local<v8::Value> currentCallFrameV8; if (m_executionState.IsEmpty()) { v8::Local<v8::Function> currentCallFrameFunction = v8::Local<v8::Function>::Cast(m_debuggerScript.Get(m_isolate)->Get(v8InternalizedString("currentCallFrameByIndex"))); - currentCallFrameV8 = v8::Debug::Call(currentCallFrameFunction, v8::Integer::New(m_isolate, index)); + currentCallFrameV8 = v8CallOrCrash(v8::Debug::Call(debuggerContext(), currentCallFrameFunction, v8::Integer::New(m_isolate, index))); } else { v8::Local<v8::Value> argv[] = { m_executionState, v8::Integer::New(m_isolate, index) }; currentCallFrameV8 = callDebuggerMethod("currentCallFrameByIndex", WTF_ARRAY_LENGTH(argv), argv).ToLocalChecked();
diff --git a/third_party/WebKit/Source/core/layout/LayoutBlock.cpp b/third_party/WebKit/Source/core/layout/LayoutBlock.cpp index 0a7572f..c4299e3 100644 --- a/third_party/WebKit/Source/core/layout/LayoutBlock.cpp +++ b/third_party/WebKit/Source/core/layout/LayoutBlock.cpp
@@ -618,12 +618,9 @@ return; Vector<LayoutBlock*, 3> blocksToRemove; - Vector<LayoutBox*, 16> floatsToRemoveFromFloatLists; for (LayoutObject* child = firstChild(); child; child = child->nextSibling()) { - if (child->isFloating()) { - floatsToRemoveFromFloatLists.append(toLayoutBox(child)); + if (child->isFloating()) continue; - } if (child->isOutOfFlowPositioned()) continue; @@ -648,10 +645,9 @@ } // If we make an object's children inline we are going to frustrate any future attempts to remove - // floats from its children's float-lists before the next layout happens so remove them proactively here. - // TODO(rhogan): We need to understand if intruding floats in this object's float list need to be removed also. - for (size_t i = 0; i < floatsToRemoveFromFloatLists.size(); i++) - toLayoutBlockFlow(this)->markAllDescendantsWithFloatsForLayout(floatsToRemoveFromFloatLists[i]); + // floats from its children's float-lists before the next layout happens so clear down all the floatlists + // now - they will be rebuilt at layout. + toLayoutBlockFlow(this)->removeFloatingObjectsFromDescendants(); for (size_t i = 0; i < blocksToRemove.size(); i++) collapseAnonymousBlockChild(this, blocksToRemove[i]);
diff --git a/third_party/WebKit/Source/core/layout/LayoutBlockFlow.cpp b/third_party/WebKit/Source/core/layout/LayoutBlockFlow.cpp index 5438572..b83ced6 100644 --- a/third_party/WebKit/Source/core/layout/LayoutBlockFlow.cpp +++ b/third_party/WebKit/Source/core/layout/LayoutBlockFlow.cpp
@@ -1745,6 +1745,24 @@ m_lineBoxes.deleteLineBoxTree(); } +void LayoutBlockFlow::removeFloatingObjectsFromDescendants() +{ + if (!containsFloats()) + return; + removeFloatingObjects(); + + // If our children are inline, then the only boxes which could contain floats are atomic inlines (e.g. inline-block, float etc.) + // and these create formatting contexts, so can't pick up intruding floats from ancestors/siblings - making them safe to skip. + if (childrenInline()) + return; + for (LayoutObject* child = firstChild(); child; child = child->nextSibling()) { + // We don't skip blocks that create formatting contexts as they may have only recently + // changed style and their float lists may still contain floats from siblings and ancestors. + if (child->isLayoutBlockFlow()) + toLayoutBlockFlow(child)->removeFloatingObjectsFromDescendants(); + } +} + void LayoutBlockFlow::markAllDescendantsWithFloatsForLayout(LayoutBox* floatToRemove, bool inLayout) { if (!everHadLayout() && !containsFloats()) @@ -1763,7 +1781,6 @@ // Iterate over our children and mark them as needed. If our children are inline, then the // only boxes which could contain floats are atomic inlines (e.g. inline-block, float etc.) and these create formatting // contexts, so can't pick up intruding floats from ancestors/siblings - making them safe to skip. - // TODO(rhogan): Should this be !createsNewFormattingContext() instead of !childrenInline()? if (!childrenInline()) { for (LayoutObject* child = firstChild(); child; child = child->nextSibling()) { if ((!floatToRemove && child->isFloatingOrOutOfFlowPositioned()) || !child->isLayoutBlock())
diff --git a/third_party/WebKit/Source/core/layout/LayoutBlockFlow.h b/third_party/WebKit/Source/core/layout/LayoutBlockFlow.h index 36120f88..61057fe8 100644 --- a/third_party/WebKit/Source/core/layout/LayoutBlockFlow.h +++ b/third_party/WebKit/Source/core/layout/LayoutBlockFlow.h
@@ -133,6 +133,7 @@ RootInlineBox* createAndAppendRootInlineBox(); + void removeFloatingObjectsFromDescendants(); void markAllDescendantsWithFloatsForLayout(LayoutBox* floatToRemove = nullptr, bool inLayout = true); void markSiblingsWithFloatsForLayout(LayoutBox* floatToRemove = nullptr);
diff --git a/third_party/WebKit/Source/core/layout/LayoutBox.cpp b/third_party/WebKit/Source/core/layout/LayoutBox.cpp index 029dc87c..4a51e69 100644 --- a/third_party/WebKit/Source/core/layout/LayoutBox.cpp +++ b/third_party/WebKit/Source/core/layout/LayoutBox.cpp
@@ -2362,7 +2362,7 @@ // grab our cached flexible height. // FIXME: Account for writing-mode in flexible boxes. // https://bugs.webkit.org/show_bug.cgi?id=46418 - if (hasOverrideLogicalContentHeight() && (parent()->isFlexibleBoxIncludingDeprecated() || parent()->isLayoutGrid())) { + if (hasOverrideLogicalContentHeight()) { LayoutUnit contentHeight = overrideLogicalContentHeight(); if (parent()->isLayoutGrid() && style()->logicalMinHeight().isAuto() && style()->overflowY() == OVISIBLE) { ASSERT(style()->logicalHeight().isAuto());
diff --git a/third_party/WebKit/Source/core/layout/LayoutMultiColumnSpannerPlaceholder.cpp b/third_party/WebKit/Source/core/layout/LayoutMultiColumnSpannerPlaceholder.cpp index 327edd8..1da77af 100644 --- a/third_party/WebKit/Source/core/layout/LayoutMultiColumnSpannerPlaceholder.cpp +++ b/third_party/WebKit/Source/core/layout/LayoutMultiColumnSpannerPlaceholder.cpp
@@ -91,6 +91,11 @@ { ASSERT(needsLayout()); + // The placeholder, like any other block level object, has its logical top calculated and set + // before layout. Copy this to the actual column-span:all object before laying it out, so that + // it gets paginated correctly, in case we have an enclosing fragmentation context. + m_layoutObjectInFlowThread->setLogicalTop(logicalTop()); + // Lay out the actual column-span:all element. m_layoutObjectInFlowThread->layoutIfNeeded();
diff --git a/third_party/WebKit/Source/core/layout/LayoutObject.cpp b/third_party/WebKit/Source/core/layout/LayoutObject.cpp index 21e6e9c..a92baefe 100644 --- a/third_party/WebKit/Source/core/layout/LayoutObject.cpp +++ b/third_party/WebKit/Source/core/layout/LayoutObject.cpp
@@ -2696,7 +2696,7 @@ setIsDragging(dragOn); if (valueChanged && node()) { if (node()->isElementNode() && toElement(node())->childrenOrSiblingsAffectedByDrag()) - document().styleEngine().pseudoStateChangedForElement(CSSSelector::PseudoDrag, *toElement(node())); + toElement(node())->pseudoStateChanged(CSSSelector::PseudoDrag); else if (style()->affectedByDrag()) node()->setNeedsStyleRecalc(LocalStyleChange, StyleChangeReasonForTracing::create(StyleChangeReason::Drag)); }
diff --git a/third_party/WebKit/Source/core/layout/LayoutState.cpp b/third_party/WebKit/Source/core/layout/LayoutState.cpp index bedcbad2..64a5004 100644 --- a/third_party/WebKit/Source/core/layout/LayoutState.cpp +++ b/third_party/WebKit/Source/core/layout/LayoutState.cpp
@@ -52,7 +52,7 @@ { if (layoutObject.isLayoutFlowThread()) m_flowThread = toLayoutFlowThread(&layoutObject); - else if (!layoutObject.isOutOfFlowPositioned() && !layoutObject.isColumnSpanAll()) + else if (!layoutObject.isOutOfFlowPositioned()) m_flowThread = m_next->flowThread(); else m_flowThread = nullptr;
diff --git a/third_party/WebKit/Source/core/layout/LayoutTestHelper.cpp b/third_party/WebKit/Source/core/layout/LayoutTestHelper.cpp index 83dace3..97db2f3d 100644 --- a/third_party/WebKit/Source/core/layout/LayoutTestHelper.cpp +++ b/third_party/WebKit/Source/core/layout/LayoutTestHelper.cpp
@@ -6,30 +6,24 @@ #include "core/layout/LayoutTestHelper.h" #include "core/frame/FrameHost.h" -#include "platform/graphics/GraphicsLayer.h" -#include "platform/graphics/GraphicsLayerFactory.h" +#include "platform/graphics/test/FakeGraphicsLayerFactory.h" namespace blink { -class FakeGraphicsLayerFactory : public GraphicsLayerFactory { -public: - PassOwnPtr<GraphicsLayer> createGraphicsLayer(GraphicsLayerClient* client) override - { - return adoptPtr(new GraphicsLayer(client)); - } -}; +namespace { class FakeChromeClient : public EmptyChromeClient { public: static PassOwnPtrWillBeRawPtr<FakeChromeClient> create() { return adoptPtrWillBeNoop(new FakeChromeClient); } - virtual GraphicsLayerFactory* graphicsLayerFactory() const + GraphicsLayerFactory* graphicsLayerFactory() const override { - static FakeGraphicsLayerFactory* factory = adoptPtr(new FakeGraphicsLayerFactory).leakPtr(); - return factory; + return FakeGraphicsLayerFactory::instance(); } }; +} // namespace + RenderingTest::RenderingTest(PassOwnPtrWillBeRawPtr<FrameLoaderClient> frameLoaderClient) { Page::PageClients pageClients;
diff --git a/third_party/WebKit/Source/core/layout/LayoutTextControlSingleLine.cpp b/third_party/WebKit/Source/core/layout/LayoutTextControlSingleLine.cpp index 73bc95d9..d23c798 100644 --- a/third_party/WebKit/Source/core/layout/LayoutTextControlSingleLine.cpp +++ b/third_party/WebKit/Source/core/layout/LayoutTextControlSingleLine.cpp
@@ -121,19 +121,26 @@ LayoutBox* viewPortLayoutObject = editingViewPortElement() ? editingViewPortElement()->layoutBox() : 0; // To ensure consistency between layouts, we need to reset any conditionally overriden height. - if (innerEditorLayoutObject && !innerEditorLayoutObject->styleRef().logicalHeight().isAuto()) { - innerEditorLayoutObject->mutableStyleRef().setLogicalHeight(Length(Auto)); + if (innerEditorLayoutObject) { + innerEditorLayoutObject->clearOverrideLogicalContentHeight(); + // TODO(jchaffraix): We could probably skip some of these due to + // forcing children relayout below but keeping them for safety for now. layoutScope.setNeedsLayout(innerEditorLayoutObject, LayoutInvalidationReason::TextControlChanged); HTMLElement* placeholderElement = inputElement()->placeholderElement(); if (LayoutBox* placeholderBox = placeholderElement ? placeholderElement->layoutBox() : 0) layoutScope.setNeedsLayout(placeholderBox, LayoutInvalidationReason::TextControlChanged); } + // TODO(jchaffraix): This logic is not correct and will yield to bugs such + // as crbug.com/529252. The fix is similar to what is done with + // innerEditorLayoutObject above. if (viewPortLayoutObject && !viewPortLayoutObject->styleRef().logicalHeight().isAuto()) { viewPortLayoutObject->mutableStyleRef().setLogicalHeight(Length(Auto)); layoutScope.setNeedsLayout(viewPortLayoutObject, LayoutInvalidationReason::TextControlChanged); } - LayoutBlockFlow::layoutBlock(false); + // This is the measuring phase. Thus we force children to be relayout so + // that the checks below are executed consistently. + LayoutBlockFlow::layoutBlock(true); Element* container = containerElement(); LayoutBox* containerLayoutObject = container ? container->layoutBox() : 0; @@ -147,7 +154,7 @@ m_desiredInnerEditorLogicalHeight = desiredLogicalHeight; - innerEditorLayoutObject->mutableStyleRef().setLogicalHeight(Length(desiredLogicalHeight, Fixed)); + innerEditorLayoutObject->setOverrideLogicalContentHeight(desiredLogicalHeight); layoutScope.setNeedsLayout(innerEditorLayoutObject, LayoutInvalidationReason::TextControlChanged); if (viewPortLayoutObject) { viewPortLayoutObject->mutableStyleRef().setLogicalHeight(Length(desiredLogicalHeight, Fixed)); @@ -252,9 +259,6 @@ containerLayoutObject->mutableStyleRef().setHeight(Length()); containerLayoutObject->mutableStyleRef().setWidth(Length()); } - LayoutObject* innerEditorLayoutObject = innerEditorElement()->layoutObject(); - if (innerEditorLayoutObject && diff.needsFullLayout()) - innerEditorLayoutObject->setNeedsLayoutAndFullPaintInvalidation(LayoutInvalidationReason::StyleChange); if (HTMLElement* placeholder = inputElement()->placeholderElement()) placeholder->setInlineStyleProperty(CSSPropertyTextOverflow, textShouldBeTruncated() ? CSSValueEllipsis : CSSValueClip); setHasOverflowClip(false);
diff --git a/third_party/WebKit/Source/core/loader/DocumentLoader.cpp b/third_party/WebKit/Source/core/loader/DocumentLoader.cpp index 245b086..a5df91f 100644 --- a/third_party/WebKit/Source/core/loader/DocumentLoader.cpp +++ b/third_party/WebKit/Source/core/loader/DocumentLoader.cpp
@@ -37,6 +37,7 @@ #include "core/fetch/CSSStyleSheetResource.h" #include "core/fetch/FetchInitiatorTypeNames.h" #include "core/fetch/FetchRequest.h" +#include "core/fetch/FontResource.h" #include "core/fetch/ImageResource.h" #include "core/fetch/MemoryCache.h" #include "core/fetch/ResourceFetcher.h" @@ -161,7 +162,6 @@ void DocumentLoader::startPreload(Resource::Type type, FetchRequest& request) { - ASSERT(type == Resource::Script || type == Resource::CSSStyleSheet || type == Resource::Image || type == Resource::ImportResource); ResourcePtr<Resource> resource; switch (type) { case Resource::Image: @@ -173,9 +173,23 @@ case Resource::CSSStyleSheet: resource = CSSStyleSheetResource::fetch(request, fetcher()); break; - default: // Resource::ImportResource + case Resource::Font: + resource = FontResource::fetch(request, fetcher()); + break; + case Resource::Media: + resource = RawResource::fetchMedia(request, fetcher()); + break; + case Resource::TextTrack: + resource = RawResource::fetchTextTrack(request, fetcher()); + break; + case Resource::ImportResource: resource = RawResource::fetchImport(request, fetcher()); break; + case Resource::LinkSubresource: + resource = RawResource::fetch(request, fetcher()); + break; + default: + ASSERT_NOT_REACHED(); } if (resource) @@ -217,7 +231,6 @@ m_applicationCacheHost->failedLoadingMainResource(); if (!frameLoader()) return; - m_mainDocumentError = error; if (m_state < MainResourceDone) m_state = MainResourceDone; frameLoader()->receivedMainResourceError(this, error); @@ -723,7 +736,6 @@ void DocumentLoader::startLoadingMainResource() { RefPtrWillBeRawPtr<DocumentLoader> protect(this); - m_mainDocumentError = ResourceError(); timing().markNavigationStart(); ASSERT(!m_mainResource); ASSERT(m_state == NotStarted);
diff --git a/third_party/WebKit/Source/core/loader/DocumentLoader.h b/third_party/WebKit/Source/core/loader/DocumentLoader.h index ff2d375..6b2e39c 100644 --- a/third_party/WebKit/Source/core/loader/DocumentLoader.h +++ b/third_party/WebKit/Source/core/loader/DocumentLoader.h
@@ -98,7 +98,6 @@ void stopLoading(); bool isLoading() const; const ResourceResponse& response() const { return m_response; } - const ResourceError& mainDocumentError() const { return m_mainDocumentError; } bool isClientRedirect() const { return m_isClientRedirect; } void setIsClientRedirect(bool isClientRedirect) { m_isClientRedirect = isClientRedirect; } bool replacesCurrentHistoryItem() const { return m_replacesCurrentHistoryItem; } @@ -213,8 +212,6 @@ ResourceResponse m_response; - ResourceError m_mainDocumentError; - bool m_isClientRedirect; bool m_replacesCurrentHistoryItem;
diff --git a/third_party/WebKit/Source/core/loader/DocumentThreadableLoader.cpp b/third_party/WebKit/Source/core/loader/DocumentThreadableLoader.cpp index 07d88a8a..d323bb2b 100644 --- a/third_party/WebKit/Source/core/loader/DocumentThreadableLoader.cpp +++ b/third_party/WebKit/Source/core/loader/DocumentThreadableLoader.cpp
@@ -288,7 +288,13 @@ void DocumentThreadableLoader::overrideTimeout(unsigned long timeoutMilliseconds) { ASSERT(m_async); - ASSERT(m_requestStartedSeconds > 0.0); + + // |m_requestStartedSeconds| == 0.0 indicates loading is already finished + // and |m_timeoutTimer| is already stopped, and thus we do nothing for such + // cases. See https://crbug.com/551663 for details. + if (m_requestStartedSeconds <= 0.0) + return; + m_timeoutTimer.stop(); // At the time of this method's implementation, it is only ever called by // XMLHttpRequest, when the timeout attribute is set after sending the
diff --git a/third_party/WebKit/Source/core/loader/EmptyClients.h b/third_party/WebKit/Source/core/loader/EmptyClients.h index 6564317..a0ae2774 100644 --- a/third_party/WebKit/Source/core/loader/EmptyClients.h +++ b/third_party/WebKit/Source/core/loader/EmptyClients.h
@@ -273,7 +273,6 @@ public: ~EmptyTextCheckerClient() { } - bool shouldEraseMarkersAfterChangeSelection(TextCheckingType) const override { return true; } void checkSpellingOfString(const String&, int*, int*) override {} void checkGrammarOfString(const String&, Vector<GrammarDetail>&, int*, int*) override {} void requestCheckingOfString(PassRefPtrWillBeRawPtr<TextCheckingRequest>) override; @@ -287,7 +286,6 @@ bool isContinuousSpellCheckingEnabled() override { return false; } void toggleContinuousSpellChecking() override {} - bool isGrammarCheckingEnabled() override { return false; } TextCheckerClient& textChecker() override { return m_textCheckerClient; }
diff --git a/third_party/WebKit/Source/core/loader/FrameFetchContext.cpp b/third_party/WebKit/Source/core/loader/FrameFetchContext.cpp index 273dfed..41bed10 100644 --- a/third_party/WebKit/Source/core/loader/FrameFetchContext.cpp +++ b/third_party/WebKit/Source/core/loader/FrameFetchContext.cpp
@@ -409,7 +409,6 @@ case Resource::Raw: case Resource::LinkPrefetch: case Resource::LinkSubresource: - case Resource::LinkPreload: case Resource::TextTrack: case Resource::ImportResource: case Resource::Media: @@ -484,7 +483,6 @@ case Resource::Raw: case Resource::LinkPrefetch: case Resource::LinkSubresource: - case Resource::LinkPreload: break; case Resource::Media: case Resource::TextTrack:
diff --git a/third_party/WebKit/Source/core/loader/FrameLoader.cpp b/third_party/WebKit/Source/core/loader/FrameLoader.cpp index 0d4559b..ba674ec 100644 --- a/third_party/WebKit/Source/core/loader/FrameLoader.cpp +++ b/third_party/WebKit/Source/core/loader/FrameLoader.cpp
@@ -996,11 +996,6 @@ m_frame->navigationScheduler().cancel(); m_inStopAllLoaders = false; - - // LocalFrame::detach() can be called multiple times which - // means we may no longer have a FrameLoaderClient to talk to. - if (client()) - client()->didStopAllLoaders(); } void FrameLoader::didAccessInitialDocument() @@ -1118,8 +1113,14 @@ void FrameLoader::restoreScrollPositionAndViewState() { FrameView* view = m_frame->view(); - if (!m_frame->page() || !view || !view->layoutViewportScrollableArea() || !m_currentItem || !m_stateMachine.committedFirstRealDocumentLoad()) + if (!m_frame->page() + || !view + || !view->layoutViewportScrollableArea() + || !m_currentItem + || !m_stateMachine.committedFirstRealDocumentLoad() + || !documentLoader()) { return; + } if (!needsHistoryItemRestore(m_loadType)) return;
diff --git a/third_party/WebKit/Source/core/loader/FrameLoader.h b/third_party/WebKit/Source/core/loader/FrameLoader.h index b12caa89..b67c737 100644 --- a/third_party/WebKit/Source/core/loader/FrameLoader.h +++ b/third_party/WebKit/Source/core/loader/FrameLoader.h
@@ -239,7 +239,7 @@ RefPtrWillBeMember<HistoryItem> m_provisionalItem; class DeferredHistoryLoad : public NoBaseWillBeGarbageCollectedFinalized<DeferredHistoryLoad> { - DISALLOW_COPY(DeferredHistoryLoad); + WTF_MAKE_NONCOPYABLE(DeferredHistoryLoad); public: static PassOwnPtrWillBeRawPtr<DeferredHistoryLoad> create(ResourceRequest request, HistoryItem* item, FrameLoadType loadType, HistoryLoadType historyLoadType) {
diff --git a/third_party/WebKit/Source/core/loader/FrameLoaderClient.h b/third_party/WebKit/Source/core/loader/FrameLoaderClient.h index 7fe131b2..42e507db 100644 --- a/third_party/WebKit/Source/core/loader/FrameLoaderClient.h +++ b/third_party/WebKit/Source/core/loader/FrameLoaderClient.h
@@ -231,8 +231,6 @@ virtual PassOwnPtr<WebApplicationCacheHost> createApplicationCacheHost(WebApplicationCacheHostClient*) = 0; - virtual void didStopAllLoaders() { } - virtual void dispatchDidChangeManifest() { } virtual unsigned backForwardLength() { return 0; }
diff --git a/third_party/WebKit/Source/core/loader/LinkLoader.cpp b/third_party/WebKit/Source/core/loader/LinkLoader.cpp index 6de4b8e..41d1dca 100644 --- a/third_party/WebKit/Source/core/loader/LinkLoader.cpp +++ b/third_party/WebKit/Source/core/loader/LinkLoader.cpp
@@ -165,21 +165,23 @@ } } -static bool getTypeFromAsAttribute(const String& as, Resource::Type& type) +static Resource::Type getTypeFromAsAttribute(const String& as, Document& document) { - if (as.isEmpty()) - return false; - if (equalIgnoringCase(as, "image")) - type = Resource::Image; - else if (equalIgnoringCase(as, "script")) - type = Resource::Script; - else if (equalIgnoringCase(as, "stylesheet")) - type = Resource::CSSStyleSheet; - else - return false; - - return true; + return Resource::Image; + if (equalIgnoringCase(as, "script")) + return Resource::Script; + if (equalIgnoringCase(as, "style")) + return Resource::CSSStyleSheet; + if (equalIgnoringCase(as, "audio") || equalIgnoringCase(as, "video")) + return Resource::Media; + if (equalIgnoringCase(as, "font")) + return Resource::Font; + if (equalIgnoringCase(as, "track")) + return Resource::TextTrack; + if (!as.isEmpty()) + document.addConsoleMessage(ConsoleMessage::create(OtherMessageSource, WarningMessageLevel, String("<link rel=preload> must have a valid `as` value"))); + return Resource::LinkSubresource; } static void preloadIfNeeded(const LinkRelAttribute& relAttribute, const KURL& href, Document& document, const String& as) @@ -194,13 +196,11 @@ document.addConsoleMessage(ConsoleMessage::create(OtherMessageSource, WarningMessageLevel, String("<link rel=preload> has an invalid `href` value"))); return; } - // TODO(yoav): Figure out a way that 'as' would be used to set request headers. - Resource::Type type; - if (!getTypeFromAsAttribute(as, type)) { - document.addConsoleMessage(ConsoleMessage::create(OtherMessageSource, WarningMessageLevel, String("<link rel=preload> must have a valid `as` value"))); - return; - } - FetchRequest linkRequest(ResourceRequest(document.completeURL(href)), FetchInitiatorTypeNames::link); + Resource::Type type = getTypeFromAsAttribute(as, document); + ResourceRequest resourceRequest(document.completeURL(href)); + ResourceFetcher::determineRequestContext(resourceRequest, type, false); + FetchRequest linkRequest(resourceRequest, FetchInitiatorTypeNames::link); + linkRequest.setPriority(document.fetcher()->loadPriority(type, linkRequest)); Settings* settings = document.settings(); if (settings && settings->logPreload())
diff --git a/third_party/WebKit/Source/core/loader/LinkLoaderTest.cpp b/third_party/WebKit/Source/core/loader/LinkLoaderTest.cpp index f1e04492..c4b7570dc 100644 --- a/third_party/WebKit/Source/core/loader/LinkLoaderTest.cpp +++ b/third_party/WebKit/Source/core/loader/LinkLoaderTest.cpp
@@ -80,12 +80,22 @@ const char* href; const char* as; const ResourceLoadPriority priority; + const WebURLRequest::RequestContext context; const bool shouldLoad; + const char* accept; } cases[] = { - {"data://example.test/cat.jpg", "image", ResourceLoadPriorityVeryLow, true}, - {"data://example.test/cat.js", "script", ResourceLoadPriorityMedium, true}, - {"data://example.test/cat.css", "stylesheet", ResourceLoadPriorityHigh, true}, - {"data://example.test/cat.blob", "blabla", ResourceLoadPriorityUnresolved, false}, + {"data://example.test/cat.jpg", "image", ResourceLoadPriorityVeryLow, WebURLRequest::RequestContextImage, true, "image/webp,image/*,*/*;q=0.8"}, + {"data://example.test/cat.js", "script", ResourceLoadPriorityMedium, WebURLRequest::RequestContextScript, true, "*/*"}, + {"data://example.test/cat.css", "style", ResourceLoadPriorityHigh, WebURLRequest::RequestContextStyle, true, "text/css,*/*;q=0.1"}, + // TODO(yoav): It doesn't seem like the audio context is ever used. That should probably be fixed (or we can consolidate audio and video). + {"data://example.test/cat.wav", "audio", ResourceLoadPriorityLow, WebURLRequest::RequestContextVideo, true, ""}, + {"data://example.test/cat.mp4", "video", ResourceLoadPriorityLow, WebURLRequest::RequestContextVideo, true, ""}, + {"data://example.test/cat.vtt", "track", ResourceLoadPriorityLow, WebURLRequest::RequestContextTrack, true, ""}, + {"data://example.test/cat.woff", "font", ResourceLoadPriorityMedium, WebURLRequest::RequestContextFont, true, ""}, + // TODO(yoav): subresource should be *very* low priority (rather than low). + {"data://example.test/cat.empty", "", ResourceLoadPriorityLow, WebURLRequest::RequestContextSubresource, true, ""}, + {"data://example.test/cat.blob", "blabla", ResourceLoadPriorityLow, WebURLRequest::RequestContextSubresource, true, ""}, + {"bla://example.test/cat.gif", "image", ResourceLoadPriorityUnresolved, WebURLRequest::RequestContextImage, false, ""}, }; // Test the cases with a single header @@ -111,8 +121,12 @@ ASSERT_EQ((unsigned)0, preloads->size()); } else { ASSERT_EQ((unsigned)1, preloads->size()); - if (preloads->size() > 0) - ASSERT_EQ(testCase.priority, preloads->begin().get()->get()->resourceRequest().priority()); + if (preloads->size() > 0) { + Resource* resource = preloads->begin().get()->get(); + ASSERT_EQ(testCase.priority, resource->resourceRequest().priority()); + ASSERT_EQ(testCase.context, resource->resourceRequest().requestContext()); + ASSERT_STREQ(testCase.accept, resource->accept().string().ascii().data()); + } } } }
diff --git a/third_party/WebKit/Source/core/loader/TextTrackLoader.h b/third_party/WebKit/Source/core/loader/TextTrackLoader.h index b301b35..1677f88 100644 --- a/third_party/WebKit/Source/core/loader/TextTrackLoader.h +++ b/third_party/WebKit/Source/core/loader/TextTrackLoader.h
@@ -38,9 +38,9 @@ class Document; class TextTrackLoader; -class TextTrackLoaderClient : public ResourceOwner<RawResource> { +class TextTrackLoaderClient { public: - ~TextTrackLoaderClient() override {} + virtual ~TextTrackLoaderClient() {} virtual void newCuesAvailable(TextTrackLoader*) = 0; virtual void cueLoadingCompleted(TextTrackLoader*, bool loadingFailed) = 0;
diff --git a/third_party/WebKit/Source/core/page/ChromeClient.cpp b/third_party/WebKit/Source/core/page/ChromeClient.cpp index ac605312..89c71fea 100644 --- a/third_party/WebKit/Source/core/page/ChromeClient.cpp +++ b/third_party/WebKit/Source/core/page/ChromeClient.cpp
@@ -167,9 +167,20 @@ } } + if (m_lastToolTipPoint == result.hitTestLocation().point() && m_lastToolTipText == toolTip) + return; + m_lastToolTipPoint = result.hitTestLocation().point(); + m_lastToolTipText = toolTip; setToolTip(toolTip, toolTipDirection); } +void ChromeClient::clearToolTip() +{ + // Do not check m_lastToolTip* and do not update them intentionally. + // We don't want to show tooltips with same content after clearToolTip(). + setToolTip(String(), LTR); +} + void ChromeClient::print(LocalFrame* frame) { // Defer loads in case the client method runs a new event loop that would
diff --git a/third_party/WebKit/Source/core/page/ChromeClient.h b/third_party/WebKit/Source/core/page/ChromeClient.h index 431a1f0b..771528b7 100644 --- a/third_party/WebKit/Source/core/page/ChromeClient.h +++ b/third_party/WebKit/Source/core/page/ChromeClient.h
@@ -22,6 +22,7 @@ #ifndef ChromeClient_h #define ChromeClient_h +#include "base/gtest_prod_util.h" #include "core/CoreExport.h" #include "core/dom/AXObjectCache.h" #include "core/frame/ConsoleTypes.h" @@ -155,6 +156,7 @@ void mouseDidMoveOverElement(const HitTestResult&); virtual void setToolTip(const String&, TextDirection) = 0; + void clearToolTip(); void print(LocalFrame*); @@ -270,6 +272,11 @@ private: bool canOpenModalIfDuringPageDismissal(Frame* mainFrame, DialogType, const String& message); void setToolTip(const HitTestResult&); + + LayoutPoint m_lastToolTipPoint; + String m_lastToolTipText; + + FRIEND_TEST_ALL_PREFIXES(ChromeClientTest, SetToolTipFlood); }; } // namespace blink
diff --git a/third_party/WebKit/Source/core/page/ChromeClientTest.cpp b/third_party/WebKit/Source/core/page/ChromeClientTest.cpp new file mode 100644 index 0000000..42099adf --- /dev/null +++ b/third_party/WebKit/Source/core/page/ChromeClientTest.cpp
@@ -0,0 +1,70 @@ +// 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. + +#include "config.h" +#include "core/page/ChromeClient.h" + +#include "core/dom/Document.h" +#include "core/layout/HitTestResult.h" +#include "core/loader/EmptyClients.h" +#include "testing/gtest/include/gtest/gtest.h" + +namespace blink { + +namespace { + +class ChromeClientToolTipLogger : public EmptyChromeClient { +public: + void setToolTip(const String& text, TextDirection) override + { + m_toolTipForLastSetToolTip = text; + } + + String toolTipForLastSetToolTip() const { return m_toolTipForLastSetToolTip; } + void clearToolTipForLastSetToolTip() { m_toolTipForLastSetToolTip = String(); } + +private: + String m_toolTipForLastSetToolTip; +}; + +} // anonymous namespace + +class ChromeClientTest : public testing::Test { +}; + +TEST_F(ChromeClientTest, SetToolTipFlood) +{ + ChromeClientToolTipLogger logger; + ChromeClient* client = &logger; + HitTestResult result(HitTestRequest(HitTestRequest::Move), LayoutPoint(10, 20)); + RefPtrWillBeRawPtr<Document> doc = Document::create(); + RefPtrWillBeRawPtr<Element> element = HTMLElement::create(HTMLNames::divTag, *doc); + element->setAttribute(HTMLNames::titleAttr, "tooltip"); + result.setInnerNode(element.get()); + + client->setToolTip(result); + EXPECT_EQ("tooltip", logger.toolTipForLastSetToolTip()); + + // seToolTip(HitTestResult) again in the same condition. + logger.clearToolTipForLastSetToolTip(); + client->setToolTip(result); + // setToolTip(String,TextDirection) should not be called. + EXPECT_EQ(String(), logger.toolTipForLastSetToolTip()); + + // Cancel the tooltip, and setToolTip(HitTestResult) again. + client->clearToolTip(); + logger.clearToolTipForLastSetToolTip(); + client->setToolTip(result); + // setToolTip(String,TextDirection) should not be called. + EXPECT_EQ(String(), logger.toolTipForLastSetToolTip()); + + logger.clearToolTipForLastSetToolTip(); + element->setAttribute(HTMLNames::titleAttr, "updated"); + client->setToolTip(result); + // setToolTip(String,TextDirection) should be called because tooltip string + // is different from the last one. + EXPECT_EQ("updated", logger.toolTipForLastSetToolTip()); +} + +} // namespace blink
diff --git a/third_party/WebKit/Source/core/page/FocusController.cpp b/third_party/WebKit/Source/core/page/FocusController.cpp index 4bde2a9..dc9b4ac 100644 --- a/third_party/WebKit/Source/core/page/FocusController.cpp +++ b/third_party/WebKit/Source/core/page/FocusController.cpp
@@ -43,6 +43,7 @@ #include "core/frame/FrameView.h" #include "core/frame/LocalDOMWindow.h" #include "core/frame/LocalFrame.h" +#include "core/frame/RemoteFrame.h" #include "core/frame/Settings.h" #include "core/html/HTMLAreaElement.h" #include "core/html/HTMLImageElement.h" @@ -690,8 +691,13 @@ { switch (type) { case WebFocusTypeForward: - case WebFocusTypeBackward: - return advanceFocusInDocumentOrder(type, initialFocus, sourceCapabilities); + case WebFocusTypeBackward: { + // We should never hit this when a RemoteFrame is focused, since the key + // event that initiated focus advancement should've been routed to that + // frame's process from the beginning. + LocalFrame* startingFrame = toLocalFrame(focusedOrMainFrame()); + return advanceFocusInDocumentOrder(startingFrame, nullptr, type, initialFocus, sourceCapabilities); + } case WebFocusTypeLeft: case WebFocusTypeRight: case WebFocusTypeUp: @@ -704,17 +710,30 @@ return false; } -bool FocusController::advanceFocusInDocumentOrder(WebFocusType type, bool initialFocus, InputDeviceCapabilities* sourceCapabilities) +bool FocusController::advanceFocusAcrossFrames(WebFocusType type, RemoteFrame* from, LocalFrame* to, InputDeviceCapabilities* sourceCapabilities) { - // FIXME: Focus advancement won't work with externally rendered frames until after - // inter-frame focus control is moved out of Blink. - if (!focusedOrMainFrame()->isLocalFrame()) - return false; - LocalFrame* frame = toLocalFrame(focusedOrMainFrame()); + // If we are shifting focus from a child frame to its parent, the + // child frame has no more focusable elements, and we should continue + // looking for focusable elements in the parent, starting from the <iframe> + // element of the child frame. + Node* startingNode = nullptr; + if (from->tree().parent() == to) { + ASSERT(from->owner()->isLocal()); + startingNode = toHTMLFrameOwnerElement(from->owner()); + } + + return advanceFocusInDocumentOrder(to, startingNode, type, false, sourceCapabilities); +} + +bool FocusController::advanceFocusInDocumentOrder(LocalFrame* frame, Node* startingNode, WebFocusType type, bool initialFocus, InputDeviceCapabilities* sourceCapabilities) +{ ASSERT(frame); Document* document = frame->document(); - Node* currentNode = document->focusedElement(); + Node* currentNode = startingNode; + if (!currentNode) + currentNode = document->focusedElement(); + // FIXME: Not quite correct when it comes to focus transitions leaving/entering the WebView itself bool caretBrowsing = frame->settings() && frame->settings()->caretBrowsingEnabled(); @@ -726,6 +745,14 @@ RefPtrWillBeRawPtr<Element> element = findFocusableElementAcrossFocusScopes(type, FocusNavigationScope::focusNavigationScopeOf(currentNode ? *currentNode : *document), currentNode); if (!element) { + // If there's a RemoteFrame on the ancestor chain, we need to continue + // searching for focusable elements there. + if (frame->localFrameRoot() != frame->tree().top()) { + document->clearFocusedElement(); + toRemoteFrame(frame->localFrameRoot()->tree().parent())->advanceFocus(type, frame->localFrameRoot()); + return true; + } + // We didn't find an element to focus, so we should try to pass focus to Chrome. if (!initialFocus && m_page->chromeClient().canTakeFocus(type)) { document->clearFocusedElement(); @@ -735,9 +762,7 @@ } // Chrome doesn't want focus, so we should wrap focus. - if (!m_page->mainFrame()->isLocalFrame()) - return false; - element = findFocusableElementRecursively(type, FocusNavigationScope::focusNavigationScopeOf(*m_page->deprecatedLocalMainFrame()->document()), nullptr); + element = findFocusableElementRecursively(type, FocusNavigationScope::focusNavigationScopeOf(*toLocalFrame(m_page->mainFrame())->document()), nullptr); element = findFocusableElementDescendingDownIntoFrameDocument(type, element.get()); if (!element) @@ -760,6 +785,14 @@ document->clearFocusedElement(); setFocusedFrame(owner->contentFrame()); + + // If contentFrame is remote, continue the search for focusable + // elements in that frame's process. + // clearFocusedElement() fires events that might detach the + // contentFrame, hence the need to null-check it again. + if (owner->contentFrame() && owner->contentFrame()->isRemoteFrame()) + toRemoteFrame(owner->contentFrame())->advanceFocus(type, frame); + return true; }
diff --git a/third_party/WebKit/Source/core/page/FocusController.h b/third_party/WebKit/Source/core/page/FocusController.h index 40cf228..1bc31f4 100644 --- a/third_party/WebKit/Source/core/page/FocusController.h +++ b/third_party/WebKit/Source/core/page/FocusController.h
@@ -46,6 +46,7 @@ class LocalFrame; class Node; class Page; +class RemoteFrame; class CORE_EXPORT FocusController final : public NoBaseWillBeGarbageCollectedFinalized<FocusController> { WTF_MAKE_NONCOPYABLE(FocusController); USING_FAST_MALLOC_WILL_BE_REMOVED(FocusController); @@ -68,6 +69,7 @@ bool setInitialFocus(WebFocusType); bool advanceFocus(WebFocusType type, InputDeviceCapabilities* sourceCapabilities = nullptr) { return advanceFocus(type, false, sourceCapabilities); } + bool advanceFocusAcrossFrames(WebFocusType, RemoteFrame* from, LocalFrame* to, InputDeviceCapabilities* sourceCapabilities = nullptr); Element* findFocusableElement(WebFocusType, Node&); bool setFocusedElement(Element*, PassRefPtrWillBeRawPtr<Frame>, const FocusParams&); @@ -88,7 +90,7 @@ bool advanceFocus(WebFocusType, bool initialFocus, InputDeviceCapabilities* sourceCapabilities = nullptr); bool advanceFocusDirectionally(WebFocusType); - bool advanceFocusInDocumentOrder(WebFocusType, bool initialFocus, InputDeviceCapabilities* sourceCapabilities); + bool advanceFocusInDocumentOrder(LocalFrame*, Node* startingNode, WebFocusType, bool initialFocus, InputDeviceCapabilities* sourceCapabilities); bool advanceFocusDirectionallyInContainer(Node* container, const LayoutRect& startingRect, WebFocusType); void findFocusCandidateInContainer(Node& container, const LayoutRect& startingRect, WebFocusType, FocusCandidate& closest);
diff --git a/third_party/WebKit/Source/core/page/NetworkStateNotifier.cpp b/third_party/WebKit/Source/core/page/NetworkStateNotifier.cpp index 6a5f39d..6f94f09 100644 --- a/third_party/WebKit/Source/core/page/NetworkStateNotifier.cpp +++ b/third_party/WebKit/Source/core/page/NetworkStateNotifier.cpp
@@ -128,6 +128,8 @@ ASSERT(isMainThread()); MutexLocker locker(m_mutex); + m_initialized = true; + if (m_type == type && m_maxBandwidthMbps == maxBandwidthMbps) return; m_type = type;
diff --git a/third_party/WebKit/Source/core/page/NetworkStateNotifier.h b/third_party/WebKit/Source/core/page/NetworkStateNotifier.h index 5c372760..1514ba5d 100644 --- a/third_party/WebKit/Source/core/page/NetworkStateNotifier.h +++ b/third_party/WebKit/Source/core/page/NetworkStateNotifier.h
@@ -47,9 +47,10 @@ }; NetworkStateNotifier() - : m_isOnLine(true) + : m_initialized(false) + , m_isOnLine(true) , m_type(WebConnectionTypeOther) - , m_maxBandwidthMbps(std::numeric_limits<double>::infinity()) + , m_maxBandwidthMbps(kInvalidMaxBandwidth) , m_testUpdatesOnly(false) { } @@ -58,6 +59,7 @@ bool onLine() const { MutexLocker locker(m_mutex); + ASSERT(m_initialized); return m_isOnLine; } @@ -67,6 +69,7 @@ WebConnectionType connectionType() const { MutexLocker locker(m_mutex); + ASSERT(m_initialized); return m_type; } @@ -74,6 +77,7 @@ double maxBandwidth() const { MutexLocker locker(m_mutex); + ASSERT(m_initialized); return m_maxBandwidthMbps; } @@ -109,6 +113,8 @@ Vector<size_t> zeroedObservers; // Indices in observers that are 0. }; + const int kInvalidMaxBandwidth = -1; + void setWebConnectionImpl(WebConnectionType, double maxBandwidthMbps); void setMaxBandwidthImpl(double maxBandwidthMbps); @@ -127,6 +133,7 @@ void collectZeroedObservers(ObserverList*, ExecutionContext*); mutable Mutex m_mutex; + bool m_initialized; bool m_isOnLine; WebConnectionType m_type; double m_maxBandwidthMbps;
diff --git a/third_party/WebKit/Source/core/page/Page.cpp b/third_party/WebKit/Source/core/page/Page.cpp index 3ec85f1..d06a8e1 100644 --- a/third_party/WebKit/Source/core/page/Page.cpp +++ b/third_party/WebKit/Source/core/page/Page.cpp
@@ -89,6 +89,12 @@ } } +void Page::onMemoryPressure() +{ + for (auto& page : ordinaryPages()) + page->memoryPurgeController().purgeMemory(); +} + float deviceScaleFactor(LocalFrame* frame) { if (!frame) @@ -361,13 +367,6 @@ return; m_visibilityState = visibilityState; - if (visibilityState == PageVisibilityStateVisible) { - memoryPurgeController().pageBecameActive(); - } else { - if (!isInitialState) - memoryPurgeController().pageBecameInactive(); - } - if (!isInitialState) notifyPageVisibilityChanged(); @@ -510,16 +509,14 @@ frames[i]->localDOMWindow()->acceptLanguagesChanged(); } -void Page::purgeMemory(MemoryPurgeMode mode, DeviceKind deviceKind) +void Page::purgeMemory(DeviceKind deviceKind) { Frame* frame = mainFrame(); if (deviceKind != DeviceKind::LowEnd || !frame || !frame->isLocalFrame()) return; - if (mode == MemoryPurgeMode::InactiveTab) { - if (Document* document = toLocalFrame(frame)->document()) - document->fetcher()->garbageCollectDocumentResources(); - memoryCache()->pruneAll(); - } + if (Document* document = toLocalFrame(frame)->document()) + document->fetcher()->garbageCollectDocumentResources(); + memoryCache()->pruneAll(); } DEFINE_TRACE(Page) @@ -546,10 +543,16 @@ MemoryPurgeClient::trace(visitor); } -void Page::willCloseLayerTreeView() +void Page::layerTreeViewInitialized(WebLayerTreeView& layerTreeView) +{ + if (scrollingCoordinator()) + scrollingCoordinator()->layerTreeViewInitialized(layerTreeView); +} + +void Page::willCloseLayerTreeView(WebLayerTreeView& layerTreeView) { if (m_scrollingCoordinator) - m_scrollingCoordinator->willCloseLayerTreeView(); + m_scrollingCoordinator->willCloseLayerTreeView(layerTreeView); } void Page::willBeDestroyed()
diff --git a/third_party/WebKit/Source/core/page/Page.h b/third_party/WebKit/Source/core/page/Page.h index 1ce3024..9389eb8 100644 --- a/third_party/WebKit/Source/core/page/Page.h +++ b/third_party/WebKit/Source/core/page/Page.h
@@ -64,6 +64,7 @@ class SpellCheckerClient; class UndoStack; class ValidationMessageClient; +class WebLayerTreeView; typedef uint64_t LinkHash; @@ -76,6 +77,7 @@ friend class Settings; public: static void platformColorsChanged(); + static void onMemoryPressure(); // It is up to the platform to ensure that non-null clients are provided where required. struct CORE_EXPORT PageClients final { @@ -201,11 +203,13 @@ MemoryPurgeController& memoryPurgeController(); - void purgeMemory(MemoryPurgeMode, DeviceKind) override; + void purgeMemory(DeviceKind) override; DECLARE_TRACE(); - void willCloseLayerTreeView(); + void layerTreeViewInitialized(WebLayerTreeView&); + void willCloseLayerTreeView(WebLayerTreeView&); + void willBeDestroyed(); private:
diff --git a/third_party/WebKit/Source/core/page/SpellCheckerClient.h b/third_party/WebKit/Source/core/page/SpellCheckerClient.h index a3eff445..024e7bc0 100644 --- a/third_party/WebKit/Source/core/page/SpellCheckerClient.h +++ b/third_party/WebKit/Source/core/page/SpellCheckerClient.h
@@ -39,7 +39,6 @@ virtual bool isContinuousSpellCheckingEnabled() = 0; virtual void toggleContinuousSpellChecking() = 0; - virtual bool isGrammarCheckingEnabled() = 0; virtual TextCheckerClient& textChecker() = 0;
diff --git a/third_party/WebKit/Source/core/page/scrolling/ScrollingCoordinator.cpp b/third_party/WebKit/Source/core/page/scrolling/ScrollingCoordinator.cpp index 21d9172..e7e5e58 100644 --- a/third_party/WebKit/Source/core/page/scrolling/ScrollingCoordinator.cpp +++ b/third_party/WebKit/Source/core/page/scrolling/ScrollingCoordinator.cpp
@@ -59,6 +59,7 @@ #include "public/platform/WebCompositorAnimationTimeline.h" #include "public/platform/WebCompositorSupport.h" #include "public/platform/WebLayerPositionConstraint.h" +#include "public/platform/WebLayerTreeView.h" #include "public/platform/WebScrollbarLayer.h" #include "public/platform/WebScrollbarThemeGeometry.h" #include "public/platform/WebScrollbarThemePainter.h" @@ -94,7 +95,6 @@ , m_wasFrameScrollable(false) , m_lastMainThreadScrollingReasons(0) { - createProgrammaticScrollAnimatorTimeline(); } ScrollingCoordinator::~ScrollingCoordinator() @@ -720,17 +720,27 @@ } } -void ScrollingCoordinator::willCloseLayerTreeView() +void ScrollingCoordinator::layerTreeViewInitialized(WebLayerTreeView& layerTreeView) { - destroyProgrammaticScrollAnimatorTimeline(); + if (RuntimeEnabledFeatures::compositorAnimationTimelinesEnabled() && Platform::current()->isThreadedAnimationEnabled()) { + ASSERT(Platform::current()->compositorSupport()); + m_programmaticScrollAnimatorTimeline = adoptPtr(Platform::current()->compositorSupport()->createAnimationTimeline()); + layerTreeView.attachCompositorAnimationTimeline(m_programmaticScrollAnimatorTimeline.get()); + } +} + +void ScrollingCoordinator::willCloseLayerTreeView(WebLayerTreeView& layerTreeView) +{ + if (m_programmaticScrollAnimatorTimeline) { + layerTreeView.detachCompositorAnimationTimeline(m_programmaticScrollAnimatorTimeline.get()); + m_programmaticScrollAnimatorTimeline.clear(); + } } void ScrollingCoordinator::willBeDestroyed() { ASSERT(m_page); - destroyProgrammaticScrollAnimatorTimeline(); - m_page = nullptr; for (const auto& scrollbar : m_horizontalScrollbars) GraphicsLayer::unregisterContentsLayer(scrollbar.value->layer()); @@ -1075,26 +1085,4 @@ return false; } -void ScrollingCoordinator::createProgrammaticScrollAnimatorTimeline() -{ - if (RuntimeEnabledFeatures::compositorAnimationTimelinesEnabled() && Platform::current()->isThreadedAnimationEnabled()) { - ASSERT(m_page); - if (m_page->mainFrame()->isLocalFrame()) { - ASSERT(Platform::current()->compositorSupport()); - m_programmaticScrollAnimatorTimeline = adoptPtr(Platform::current()->compositorSupport()->createAnimationTimeline()); - m_page->chromeClient().attachCompositorAnimationTimeline(m_programmaticScrollAnimatorTimeline.get(), toLocalFrame(m_page->mainFrame())); - } - } -} - -void ScrollingCoordinator::destroyProgrammaticScrollAnimatorTimeline() -{ - if (m_programmaticScrollAnimatorTimeline) { - ASSERT(m_page); - ASSERT(m_page->mainFrame()->isLocalFrame()); - m_page->chromeClient().detachCompositorAnimationTimeline(m_programmaticScrollAnimatorTimeline.get(), toLocalFrame(m_page->mainFrame())); - m_programmaticScrollAnimatorTimeline.clear(); - } -} - } // namespace blink
diff --git a/third_party/WebKit/Source/core/page/scrolling/ScrollingCoordinator.h b/third_party/WebKit/Source/core/page/scrolling/ScrollingCoordinator.h index 6e3921c4..d18201e 100644 --- a/third_party/WebKit/Source/core/page/scrolling/ScrollingCoordinator.h +++ b/third_party/WebKit/Source/core/page/scrolling/ScrollingCoordinator.h
@@ -49,6 +49,7 @@ class Region; class ScrollableArea; class WebCompositorAnimationTimeline; +class WebLayerTreeView; class CORE_EXPORT ScrollingCoordinator final : public NoBaseWillBeGarbageCollectedFinalized<ScrollingCoordinator> { WTF_MAKE_NONCOPYABLE(ScrollingCoordinator); @@ -59,7 +60,9 @@ ~ScrollingCoordinator(); DECLARE_TRACE(); - void willCloseLayerTreeView(); + void layerTreeViewInitialized(WebLayerTreeView&); + void willCloseLayerTreeView(WebLayerTreeView&); + void willBeDestroyed(); // Return whether this scrolling coordinator handles scrolling for the given frame view. @@ -156,9 +159,6 @@ bool frameViewIsDirty() const; - void createProgrammaticScrollAnimatorTimeline(); - void destroyProgrammaticScrollAnimatorTimeline(); - OwnPtr<WebCompositorAnimationTimeline> m_programmaticScrollAnimatorTimeline; using ScrollbarMap = WillBeHeapHashMap<RawPtrWillBeMember<ScrollableArea>, OwnPtr<WebScrollbarLayer>>;
diff --git a/third_party/WebKit/Source/core/paint/PaintLayer.cpp b/third_party/WebKit/Source/core/paint/PaintLayer.cpp index 71c6999..df78365 100644 --- a/third_party/WebKit/Source/core/paint/PaintLayer.cpp +++ b/third_party/WebKit/Source/core/paint/PaintLayer.cpp
@@ -1546,7 +1546,7 @@ return insideLayer; } -Node* PaintLayer::enclosingElement() const +Node* PaintLayer::enclosingNode() const { for (LayoutObject* r = layoutObject(); r; r = r->parent()) { if (Node* e = r->node()) @@ -1912,7 +1912,7 @@ return false; } - Node* e = enclosingElement(); + Node* e = enclosingNode(); // FIXME: should be a call to result.setNodeAndPosition. What we would really want to do here is to // return and look for the nearest non-anonymous ancestor, and ignore aunts and uncles on // our way. It's bad to look for it manually like we do here, and give up on setting a local @@ -2555,7 +2555,7 @@ namespace { -FilterOperations computeFilterOperationsHandleReferenceFilters(const FilterOperations& filters, float effectiveZoom, Node* enclosingElement) +FilterOperations computeFilterOperationsHandleReferenceFilters(const FilterOperations& filters, float effectiveZoom, Node* enclosingNode) { if (filters.hasReferenceFilter()) { for (size_t i = 0; i < filters.size(); ++i) { @@ -2564,7 +2564,7 @@ continue; ReferenceFilterOperation& referenceOperation = toReferenceFilterOperation(*filterOperation); // FIXME: Cache the Filter if it didn't change. - RefPtrWillBeRawPtr<Filter> referenceFilter = ReferenceFilterBuilder::build(effectiveZoom, toElement(enclosingElement), nullptr, referenceOperation); + RefPtrWillBeRawPtr<Filter> referenceFilter = ReferenceFilterBuilder::build(effectiveZoom, toElement(enclosingNode), nullptr, referenceOperation); referenceOperation.setFilter(referenceFilter.release()); } } @@ -2576,12 +2576,12 @@ FilterOperations PaintLayer::computeFilterOperations(const ComputedStyle& style) const { - return computeFilterOperationsHandleReferenceFilters(style.filter(), style.effectiveZoom(), enclosingElement()); + return computeFilterOperationsHandleReferenceFilters(style.filter(), style.effectiveZoom(), enclosingNode()); } FilterOperations PaintLayer::computeBackdropFilterOperations(const ComputedStyle& style) const { - return computeFilterOperationsHandleReferenceFilters(style.backdropFilter(), style.effectiveZoom(), enclosingElement()); + return computeFilterOperationsHandleReferenceFilters(style.backdropFilter(), style.effectiveZoom(), enclosingNode()); } void PaintLayer::updateOrRemoveFilterClients() @@ -2615,7 +2615,7 @@ filterInfo->setBuilder(FilterEffectBuilder::create()); float zoom = layoutObject()->style() ? layoutObject()->style()->effectiveZoom() : 1.0f; - if (!filterInfo->builder()->build(toElement(enclosingElement()), computeFilterOperations(layoutObject()->styleRef()), zoom)) + if (!filterInfo->builder()->build(toElement(enclosingNode()), computeFilterOperations(layoutObject()->styleRef()), zoom)) filterInfo->setBuilder(nullptr); return filterInfo->builder();
diff --git a/third_party/WebKit/Source/core/paint/PaintLayer.h b/third_party/WebKit/Source/core/paint/PaintLayer.h index ccb4577..b49b421e 100644 --- a/third_party/WebKit/Source/core/paint/PaintLayer.h +++ b/third_party/WebKit/Source/core/paint/PaintLayer.h
@@ -440,7 +440,7 @@ void updateFilters(const ComputedStyle* oldStyle, const ComputedStyle& newStyle); - Node* enclosingElement() const; + Node* enclosingNode() const; bool isInTopLayer() const;
diff --git a/third_party/WebKit/Source/core/plugins/PluginView.h b/third_party/WebKit/Source/core/plugins/PluginView.h index 372d999..638ae68 100644 --- a/third_party/WebKit/Source/core/plugins/PluginView.h +++ b/third_party/WebKit/Source/core/plugins/PluginView.h
@@ -53,8 +53,6 @@ virtual void didReceiveResponse(const ResourceResponse&) { } virtual void didReceiveData(const char*, int) { } - virtual void didFinishLoading() { } - virtual void didFailLoading(const ResourceError&) { } virtual void layoutIfNeeded() { } virtual void invalidatePaintIfNeeded() { }
diff --git a/third_party/WebKit/Source/core/style/ComputedStyle.cpp b/third_party/WebKit/Source/core/style/ComputedStyle.cpp index f82d8cb..aca10ca0 100644 --- a/third_party/WebKit/Source/core/style/ComputedStyle.cpp +++ b/third_party/WebKit/Source/core/style/ComputedStyle.cpp
@@ -266,6 +266,10 @@ // unique() styles are not cacheable. ASSERT(!other.noninherited_flags.unique); + // styles with non inherited properties that reference variables are not + // cacheable. + ASSERT(!other.noninherited_flags.variableReference); + // The following flags are set during matching before we decide that we get a // match in the MatchedPropertiesCache which in turn calls this method. The // reason why we don't copy these flags is that they're already correctly set
diff --git a/third_party/WebKit/Source/core/style/ComputedStyle.h b/third_party/WebKit/Source/core/style/ComputedStyle.h index 43ca7e6..da23091 100644 --- a/third_party/WebKit/Source/core/style/ComputedStyle.h +++ b/third_party/WebKit/Source/core/style/ComputedStyle.h
@@ -271,6 +271,7 @@ unsigned styleType : 6; // PseudoId unsigned pseudoBits : 8; unsigned explicitInheritance : 1; // Explicitly inherits a non-inherited property + unsigned variableReference : 1; // A non-inherited property references a variable. unsigned unique : 1; // Style can not be shared. unsigned emptyState : 1; @@ -284,7 +285,7 @@ mutable unsigned hasRemUnits : 1; // If you add more style bits here, you will also need to update ComputedStyle::copyNonInheritedFromCached() - // 63 bits + // 62 bits } noninherited_flags; // !END SYNC! @@ -326,6 +327,7 @@ noninherited_flags.styleType = NOPSEUDO; noninherited_flags.pseudoBits = 0; noninherited_flags.explicitInheritance = false; + noninherited_flags.variableReference = false; noninherited_flags.unique = false; noninherited_flags.emptyState = false; noninherited_flags.hasViewportUnits = false; @@ -821,6 +823,8 @@ // through their self-painting layers. So the layout code doesn't account for them. bool hasVisualOverflowingEffect() const { return boxShadow() || hasBorderImageOutsets() || hasOutline(); } + Containment contain() const { return static_cast<Containment>(rareNonInheritedData->m_contain); } + EBoxSizing boxSizing() const { return m_box->boxSizing(); } EUserModify userModify() const { return static_cast<EUserModify>(rareInheritedData->userModify); } EUserDrag userDrag() const { return static_cast<EUserDrag>(rareNonInheritedData->userDrag); } @@ -1304,6 +1308,7 @@ void setBoxShadow(PassRefPtr<ShadowList>); void setBoxReflect(PassRefPtr<StyleReflection> reflect) { if (rareNonInheritedData->m_boxReflect != reflect) rareNonInheritedData.access()->m_boxReflect = reflect; } void setBoxSizing(EBoxSizing s) { SET_VAR(m_box, m_boxSizing, s); } + void setContain(Containment contain) { SET_VAR(rareNonInheritedData, m_contain, contain); } void setFlexGrow(float f) { SET_VAR(rareNonInheritedData.access()->m_flexibleBox, m_flexGrow, f); } void setFlexShrink(float f) { SET_VAR(rareNonInheritedData.access()->m_flexibleBox, m_flexShrink, f); } void setFlexBasis(const Length& length) { SET_VAR(rareNonInheritedData.access()->m_flexibleBox, m_flexBasis, length); } @@ -1601,6 +1606,9 @@ void setHasExplicitlyInheritedProperties() { noninherited_flags.explicitInheritance = true; } bool hasExplicitlyInheritedProperties() const { return noninherited_flags.explicitInheritance; } + void setHasVariableReferenceFromNonInheritedProperty() { noninherited_flags.variableReference = true; } + bool hasVariableReferenceFromNonInheritedProperty() const { return noninherited_flags.variableReference; } + bool hasChildDependentFlags() const { return emptyState() || hasExplicitlyInheritedProperties(); } void copyChildDependentFlagsFrom(const ComputedStyle&); @@ -1623,6 +1631,7 @@ static ECaptionSide initialCaptionSide() { return CAPTOP; } static EClear initialClear() { return CNONE; } static LengthBox initialClip() { return LengthBox(); } + static Containment initialContain() { return ContainsNone; } static TextDirection initialDirection() { return LTR; } static WritingMode initialWritingMode() { return TopToBottomWritingMode; } static TextCombine initialTextCombine() { return TextCombineNone; }
diff --git a/third_party/WebKit/Source/core/style/ComputedStyleConstants.h b/third_party/WebKit/Source/core/style/ComputedStyleConstants.h index 14d6831..e15b5cb2 100644 --- a/third_party/WebKit/Source/core/style/ComputedStyleConstants.h +++ b/third_party/WebKit/Source/core/style/ComputedStyleConstants.h
@@ -485,6 +485,17 @@ enum EIsolation { IsolationAuto, IsolationIsolate }; +static const size_t ContainmentBits = 3; +enum Containment { + ContainsNone = 0x0, + ContainsLayout = 0x1, + ContainsStyle = 0x2, + ContainsPaint = 0x4, + ContainsStrict = ContainsLayout | ContainsStyle | ContainsPaint, +}; +inline Containment operator| (Containment a, Containment b) { return Containment(int(a) | int(b)); } +inline Containment& operator|= (Containment& a, Containment b) { return a = a | b; } + enum ItemPosition { ItemPositionAuto, ItemPositionStretch,
diff --git a/third_party/WebKit/Source/core/style/StyleRareNonInheritedData.cpp b/third_party/WebKit/Source/core/style/StyleRareNonInheritedData.cpp index 66e520e3..b432ac9 100644 --- a/third_party/WebKit/Source/core/style/StyleRareNonInheritedData.cpp +++ b/third_party/WebKit/Source/core/style/StyleRareNonInheritedData.cpp
@@ -118,6 +118,7 @@ , m_touchAction(ComputedStyle::initialTouchAction()) , m_objectFit(ComputedStyle::initialObjectFit()) , m_isolation(ComputedStyle::initialIsolation()) + , m_contain(ComputedStyle::initialContain()) , m_scrollBehavior(ComputedStyle::initialScrollBehavior()) , m_scrollSnapType(ComputedStyle::initialScrollSnapType()) , m_requiresAcceleratedCompositingForExternalReasons(false) @@ -199,6 +200,7 @@ , m_touchAction(o.m_touchAction) , m_objectFit(o.m_objectFit) , m_isolation(o.m_isolation) + , m_contain(o.m_contain) , m_scrollBehavior(o.m_scrollBehavior) , m_scrollSnapType(o.m_scrollSnapType) , m_requiresAcceleratedCompositingForExternalReasons(o.m_requiresAcceleratedCompositingForExternalReasons) @@ -289,6 +291,7 @@ && m_touchAction == o.m_touchAction && m_objectFit == o.m_objectFit && m_isolation == o.m_isolation + && m_contain == o.m_contain && m_scrollBehavior == o.m_scrollBehavior && m_scrollSnapType == o.m_scrollSnapType && m_requiresAcceleratedCompositingForExternalReasons == o.m_requiresAcceleratedCompositingForExternalReasons
diff --git a/third_party/WebKit/Source/core/style/StyleRareNonInheritedData.h b/third_party/WebKit/Source/core/style/StyleRareNonInheritedData.h index afd5c17c..64b6d65 100644 --- a/third_party/WebKit/Source/core/style/StyleRareNonInheritedData.h +++ b/third_party/WebKit/Source/core/style/StyleRareNonInheritedData.h
@@ -189,6 +189,8 @@ unsigned m_isolation : 1; // Isolation + unsigned m_contain : 3; // Containment + // ScrollBehavior. 'scroll-behavior' has 2 accepted values, but ScrollBehavior has a third // value (that can only be specified using CSSOM scroll APIs) so 2 bits are needed. unsigned m_scrollBehavior: 2;
diff --git a/third_party/WebKit/Source/devtools/devtools.gypi b/third_party/WebKit/Source/devtools/devtools.gypi index a6e8a4de..0f513c1 100644 --- a/third_party/WebKit/Source/devtools/devtools.gypi +++ b/third_party/WebKit/Source/devtools/devtools.gypi
@@ -176,11 +176,10 @@ 'front_end/bindings/BlackboxSupport.js', 'front_end/bindings/BreakpointManager.js', 'front_end/bindings/CompilerScriptMapping.js', - 'front_end/bindings/ContentProviderBasedProjectDelegate.js', + 'front_end/bindings/ContentProviderBasedProject.js', 'front_end/bindings/CSSWorkspaceBinding.js', 'front_end/bindings/DebuggerWorkspaceBinding.js', 'front_end/bindings/DefaultScriptMapping.js', - 'front_end/bindings/ContentScriptProjectDecorator.js', 'front_end/bindings/FileSystemWorkspaceBinding.js', 'front_end/bindings/FileUtils.js', 'front_end/bindings/LiveLocation.js', @@ -670,7 +669,9 @@ ], 'devtools_timeline_js_files': [ 'front_end/timeline/invalidationsTree.css', + 'front_end/timeline/timelineFlamechartPopover.css', 'front_end/timeline/timelinePanel.css', + 'front_end/timeline/timelineStatusDialog.css', 'front_end/timeline/CountersGraph.js', 'front_end/timeline/LayerDetailsView.js', 'front_end/timeline/LayerTreeModel.js',
diff --git a/third_party/WebKit/Source/devtools/front_end/bindings/BreakpointManager.js b/third_party/WebKit/Source/devtools/front_end/bindings/BreakpointManager.js index 34547b3..7477b7433 100644 --- a/third_party/WebKit/Source/devtools/front_end/bindings/BreakpointManager.js +++ b/third_party/WebKit/Source/devtools/front_end/bindings/BreakpointManager.js
@@ -163,7 +163,7 @@ { var uiSourceCode = /** @type {!WebInspector.UISourceCode} */ (event.data); this._restoreBreakpoints(uiSourceCode); - if (uiSourceCode.contentType() === WebInspector.resourceTypes.Script || uiSourceCode.contentType() === WebInspector.resourceTypes.Document) + if (uiSourceCode.contentType().hasScripts()) uiSourceCode.addEventListener(WebInspector.UISourceCode.Events.SourceMappingChanged, this._uiSourceCodeMappingChanged, this); },
diff --git a/third_party/WebKit/Source/devtools/front_end/bindings/CompilerScriptMapping.js b/third_party/WebKit/Source/devtools/front_end/bindings/CompilerScriptMapping.js index 311fdce..cdf9faa 100644 --- a/third_party/WebKit/Source/devtools/front_end/bindings/CompilerScriptMapping.js +++ b/third_party/WebKit/Source/devtools/front_end/bindings/CompilerScriptMapping.js
@@ -61,7 +61,7 @@ this._stubUISourceCodes = new Map(); this._stubProjectID = "compiler-script-project"; - this._stubProjectDelegate = new WebInspector.ContentProviderBasedProjectDelegate(this._workspace, this._stubProjectID, WebInspector.projectTypes.Service); + this._stubProject = new WebInspector.ContentProviderBasedProject(this._workspace, this._stubProjectID, WebInspector.projectTypes.Service, "", ""); debuggerModel.addEventListener(WebInspector.DebuggerModel.Events.GlobalObjectCleared, this._debuggerReset, this); } @@ -166,12 +166,11 @@ var splitURL = WebInspector.ParsedURL.splitURLIntoPathComponents(url); var parentPath = splitURL.slice(1, -1).join("/"); var name = splitURL.peekLast() || ""; - var uiSourceCodePath = this._stubProjectDelegate.addContentProvider(parentPath, name, url, new WebInspector.StaticContentProvider(WebInspector.resourceTypes.Script, "\n\n\n\n\n// Please wait a bit.\n// Compiled script is not shown while source map is being loaded!", url)); - var stubUISourceCode = /** @type {!WebInspector.UISourceCode} */ (this._workspace.uiSourceCode(this._stubProjectID, uiSourceCodePath)); + var stubUISourceCode = this._stubProject.addContentProvider(parentPath, name, url, new WebInspector.StaticContentProvider(WebInspector.resourceTypes.Script, "\n\n\n\n\n// Please wait a bit.\n// Compiled script is not shown while source map is being loaded!", url)); this._stubUISourceCodes.set(script.scriptId, stubUISourceCode); this._debuggerWorkspaceBinding.pushSourceMapping(script, this); - this._loadSourceMapForScript(script, this._sourceMapLoaded.bind(this, script, uiSourceCodePath)); + this._loadSourceMapForScript(script, this._sourceMapLoaded.bind(this, script, stubUISourceCode.path())); }, /** @@ -182,7 +181,7 @@ _sourceMapLoaded: function(script, uiSourceCodePath, sourceMap) { this._stubUISourceCodes.delete(script.scriptId); - this._stubProjectDelegate.removeFile(uiSourceCodePath); + this._stubProject.removeFile(uiSourceCodePath); if (!sourceMap) { this._debuggerWorkspaceBinding.updateLocations(script); @@ -206,7 +205,7 @@ continue; this._sourceMapForURL.set(sourceURL, sourceMap); if (!this._networkMapping.hasMappingForURL(sourceURL) && !this._networkMapping.uiSourceCodeForURL(sourceURL, script.target())) { - var contentProvider = sourceMap.sourceContentProvider(sourceURL, WebInspector.resourceTypes.Script); + var contentProvider = sourceMap.sourceContentProvider(sourceURL, WebInspector.resourceTypes.SourceMapScript); this._networkProject.addFileForURL(sourceURL, contentProvider, script.isContentScript()); } var uiSourceCode = this._networkMapping.uiSourceCodeForURL(sourceURL, this._target);
diff --git a/third_party/WebKit/Source/devtools/front_end/bindings/ContentProviderBasedProjectDelegate.js b/third_party/WebKit/Source/devtools/front_end/bindings/ContentProviderBasedProject.js similarity index 69% rename from third_party/WebKit/Source/devtools/front_end/bindings/ContentProviderBasedProjectDelegate.js rename to third_party/WebKit/Source/devtools/front_end/bindings/ContentProviderBasedProject.js index 781783c1..3b144b8 100644 --- a/third_party/WebKit/Source/devtools/front_end/bindings/ContentProviderBasedProjectDelegate.js +++ b/third_party/WebKit/Source/devtools/front_end/bindings/ContentProviderBasedProject.js
@@ -30,79 +30,31 @@ /** * @constructor - * @extends {WebInspector.Object} - * @implements {WebInspector.ProjectDelegate} + * @extends {WebInspector.ProjectStore} + * @implements {WebInspector.Project} * @param {!WebInspector.Workspace} workspace * @param {string} id * @param {!WebInspector.projectTypes} type + * @param {string} url + * @param {string} displayName */ -WebInspector.ContentProviderBasedProjectDelegate = function(workspace, id, type) +WebInspector.ContentProviderBasedProject = function(workspace, id, type, url, displayName) { - WebInspector.Object.call(this); - this._type = type; + WebInspector.ProjectStore.call(this, workspace, id, type, url, displayName); /** @type {!Object.<string, !WebInspector.ContentProvider>} */ this._contentProviders = {}; - this._workspace = workspace; - this._id = id; - this._project = workspace.addProject(id, this); + workspace.addProject(this); } -WebInspector.ContentProviderBasedProjectDelegate.prototype = { - /** - * @return {!WebInspector.Project} - */ - project: function() - { - return this._project; - }, - +WebInspector.ContentProviderBasedProject.prototype = { /** * @override - * @return {string} - */ - type: function() - { - return this._type; - }, - - /** - * @override - * @return {string} - */ - displayName: function() - { - // Overridden by subclasses - return ""; - }, - - /** - * @override - * @return {string} - */ - url: function() - { - // Overridden by subclasses - return ""; - }, - - /** - * @override - * @param {string} path - * @param {function(?Date, ?number)} callback - */ - requestMetadata: function(path, callback) - { - callback(null, null); - }, - - /** - * @override - * @param {string} path + * @param {!WebInspector.UISourceCode} uiSourceCode * @param {function(?string)} callback */ - requestFileContent: function(path, callback) + requestFileContent: function(uiSourceCode, callback) { - var contentProvider = this._contentProviders[path]; + var contentProvider = this._contentProviders[uiSourceCode.path()]; contentProvider.requestContent(callback); /** @@ -127,11 +79,11 @@ /** * @override - * @param {string} path + * @param {!WebInspector.UISourceCode} uiSourceCode * @param {string} newContent * @param {function(?string)} callback */ - setFileContent: function(path, newContent, callback) + setFileContent: function(uiSourceCode, newContent, callback) { callback(null); }, @@ -147,23 +99,30 @@ /** * @override - * @param {string} path + * @param {!WebInspector.UISourceCode} uiSourceCode * @param {string} newName * @param {function(boolean, string=, string=, !WebInspector.ResourceType=)} callback */ - rename: function(path, newName, callback) + rename: function(uiSourceCode, newName, callback) { + var path = uiSourceCode.path(); this.performRename(path, newName, innerCallback.bind(this)); /** * @param {boolean} success * @param {string=} newName - * @this {WebInspector.ContentProviderBasedProjectDelegate} + * @this {WebInspector.ContentProviderBasedProject} */ function innerCallback(success, newName) { - if (success) - this._updateName(path, /** @type {string} */ (newName)); + if (success && newName) { + var copyOfPath = path.split("/"); + copyOfPath[copyOfPath.length - 1] = newName; + var newPath = copyOfPath.join("/"); + this._contentProviders[newPath] = this._contentProviders[path]; + delete this._contentProviders[path]; + this.renameUISourceCode(uiSourceCode, newName); + } callback(success, newName); } }, @@ -192,7 +151,7 @@ * @param {string} path * @param {?string} name * @param {string} content - * @param {function(?string)} callback + * @param {function(?WebInspector.UISourceCode)} callback */ createFile: function(path, name, content, callback) { @@ -224,30 +183,16 @@ }, /** - * @param {string} path - * @param {string} newName - */ - _updateName: function(path, newName) - { - var oldPath = path; - var copyOfPath = path.split("/"); - copyOfPath[copyOfPath.length - 1] = newName; - var newPath = copyOfPath.join("/"); - this._contentProviders[newPath] = this._contentProviders[oldPath]; - delete this._contentProviders[oldPath]; - }, - - /** * @override - * @param {string} path + * @param {!WebInspector.UISourceCode} uiSourceCode * @param {string} query * @param {boolean} caseSensitive * @param {boolean} isRegex * @param {function(!Array.<!WebInspector.ContentProvider.SearchMatch>)} callback */ - searchInFileContent: function(path, query, caseSensitive, isRegex, callback) + searchInFileContent: function(uiSourceCode, query, caseSensitive, isRegex, callback) { - var contentProvider = this._contentProviders[path]; + var contentProvider = this._contentProviders[uiSourceCode.path()]; contentProvider.searchInContent(query, caseSensitive, isRegex, callback); }, @@ -278,7 +223,7 @@ /** * @param {string} path * @param {function(boolean)} callback - * @this {WebInspector.ContentProviderBasedProjectDelegate} + * @this {WebInspector.ContentProviderBasedProject} */ function searchInContent(path, callback) { @@ -286,7 +231,7 @@ searchNextQuery.call(this); /** - * @this {WebInspector.ContentProviderBasedProjectDelegate} + * @this {WebInspector.ContentProviderBasedProject} */ function searchNextQuery() { @@ -300,7 +245,7 @@ /** * @param {!Array.<!WebInspector.ContentProvider.SearchMatch>} searchMatches - * @this {WebInspector.ContentProviderBasedProjectDelegate} + * @this {WebInspector.ContentProviderBasedProject} */ function contentCallback(searchMatches) { @@ -336,7 +281,7 @@ */ indexContent: function(progress) { - setTimeout(progress.done.bind(progress), 0); + setImmediate(progress.done.bind(progress)); }, /** @@ -344,17 +289,15 @@ * @param {string} name * @param {string} originURL * @param {!WebInspector.ContentProvider} contentProvider - * @return {string} + * @return {!WebInspector.UISourceCode} */ addContentProvider: function(parentPath, name, originURL, contentProvider) { var path = parentPath ? parentPath + "/" + name : name; if (this._contentProviders[path]) - this.dispatchEventToListeners(WebInspector.ProjectDelegate.Events.FileRemoved, path); - var fileDescriptor = new WebInspector.FileDescriptor(parentPath, name, originURL, contentProvider.contentType()); + this.removeUISourceCode(path); this._contentProviders[path] = contentProvider; - this.dispatchEventToListeners(WebInspector.ProjectDelegate.Events.FileAdded, fileDescriptor); - return path; + return this.addUISourceCode(parentPath, name, originURL, contentProvider.contentType()); }, /** @@ -363,23 +306,21 @@ removeFile: function(path) { delete this._contentProviders[path]; - this.dispatchEventToListeners(WebInspector.ProjectDelegate.Events.FileRemoved, path); - }, - - /** - * @return {!Object.<string, !WebInspector.ContentProvider>} - */ - contentProviders: function() - { - return this._contentProviders; + this.removeUISourceCode(path); }, reset: function() { this._contentProviders = {}; - this._workspace.removeProject(this._id); - this._workspace.addProject(this._id, this); + this.removeProject(); + this.workspace().addProject(this); }, - __proto__: WebInspector.Object.prototype + dispose: function() + { + this._contentProviders = {}; + this.removeProject(); + }, + + __proto__: WebInspector.ProjectStore.prototype }
diff --git a/third_party/WebKit/Source/devtools/front_end/bindings/ContentScriptProjectDecorator.js b/third_party/WebKit/Source/devtools/front_end/bindings/ContentScriptProjectDecorator.js deleted file mode 100644 index 41c37d2..0000000 --- a/third_party/WebKit/Source/devtools/front_end/bindings/ContentScriptProjectDecorator.js +++ /dev/null
@@ -1,77 +0,0 @@ -// Copyright 2014 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -/** - * @constructor - */ -WebInspector.ContentScriptProjectDecorator = function() -{ - WebInspector.targetManager.addModelListener(WebInspector.RuntimeModel, WebInspector.RuntimeModel.Events.ExecutionContextCreated, this._onContextCreated, this); - WebInspector.workspace.addEventListener(WebInspector.Workspace.Events.ProjectAdded, this._onProjectAdded, this); -} - -/** - * @param {!WebInspector.Project} project - * @param {!WebInspector.ExecutionContext} context - */ -WebInspector.ContentScriptProjectDecorator._updateProjectWithExtensionName = function(project, context) -{ - if (project.url().startsWith(context.origin)) - project.setDisplayName(context.name); -} - -WebInspector.ContentScriptProjectDecorator.prototype = { - /** - * @param {!WebInspector.Event} event - */ - _onContextCreated: function(event) - { - var context = /** @type {!WebInspector.ExecutionContext} */(event.data); - if (!context.origin || !context.name) - return; - - var projects = WebInspector.workspace.projects(); - projects = projects.filter(contentProjectWithName); - - for (var i = 0; i < projects.length; ++i) - WebInspector.ContentScriptProjectDecorator._updateProjectWithExtensionName(projects[i], context); - - /** - * @param {!WebInspector.Project} project - * @return {boolean} - */ - function contentProjectWithName(project) - { - return !!project.url() && project.type() === WebInspector.projectTypes.ContentScripts; - } - }, - - /** - * @param {!WebInspector.Event} event - */ - _onProjectAdded: function(event) - { - var project = /** @type {!WebInspector.Project} */(event.data); - if (project.type() !== WebInspector.projectTypes.ContentScripts) - return; - - var targets = WebInspector.targetManager.targets(); - var contexts = []; - for (var i = 0; i < targets.length; ++i) - contexts = contexts.concat(targets[i].runtimeModel.executionContexts()); - contexts = contexts.filter(contextWithOriginAndName); - - for (var i = 0; i < contexts.length; ++i) - WebInspector.ContentScriptProjectDecorator._updateProjectWithExtensionName(project, contexts[i]); - - /** - * @param {!WebInspector.ExecutionContext} context - * @return {boolean} - */ - function contextWithOriginAndName(context) - { - return !!context.origin && !!context.name; - } - } -} \ No newline at end of file
diff --git a/third_party/WebKit/Source/devtools/front_end/bindings/DefaultScriptMapping.js b/third_party/WebKit/Source/devtools/front_end/bindings/DefaultScriptMapping.js index 46d0872c..21030162 100644 --- a/third_party/WebKit/Source/devtools/front_end/bindings/DefaultScriptMapping.js +++ b/third_party/WebKit/Source/devtools/front_end/bindings/DefaultScriptMapping.js
@@ -41,7 +41,7 @@ this._debuggerWorkspaceBinding = debuggerWorkspaceBinding; this._workspace = workspace; this._projectId = WebInspector.DefaultScriptMapping.projectIdForTarget(debuggerModel.target()); - this._projectDelegate = new WebInspector.DebuggerProjectDelegate(this._workspace, this._projectId, WebInspector.projectTypes.Debugger); + this._project = new WebInspector.ContentProviderBasedProject(this._workspace, this._projectId, WebInspector.projectTypes.Debugger, "debugger:", ""); debuggerModel.addEventListener(WebInspector.DebuggerModel.Events.GlobalObjectCleared, this._debuggerReset, this); this._debuggerReset(); } @@ -85,8 +85,12 @@ */ addScript: function(script) { - var path = this._projectDelegate.addScript(script); - var uiSourceCode = this._workspace.uiSourceCode(this._projectId, path); + + var splitURL = WebInspector.ParsedURL.splitURLIntoPathComponents(script.sourceURL); + var name = splitURL[splitURL.length - 1]; + name = "VM" + script.scriptId + (name ? " " + name : ""); + + var uiSourceCode = this._project.addContentProvider("", name, script.sourceURL, script); console.assert(uiSourceCode); uiSourceCode = /** @type {!WebInspector.UISourceCode} */ (uiSourceCode); @@ -121,12 +125,12 @@ /** @type {!Map.<string, !WebInspector.UISourceCode>} */ this._uiSourceCodeForScriptId = new Map(); this._scriptIdForUISourceCode = new Map(); - this._projectDelegate.reset(); + this._project.reset(); }, dispose: function() { - this._workspace.removeProject(this._projectId); + this._project.dispose(); } } @@ -138,49 +142,3 @@ { return "debugger:" + target.id(); } - -/** - * @constructor - * @param {!WebInspector.Workspace} workspace - * @param {string} id - * @param {!WebInspector.projectTypes} type - * @extends {WebInspector.ContentProviderBasedProjectDelegate} - */ -WebInspector.DebuggerProjectDelegate = function(workspace, id, type) -{ - WebInspector.ContentProviderBasedProjectDelegate.call(this, workspace, id, type); -} - -WebInspector.DebuggerProjectDelegate.prototype = { - /** - * @override - * @return {string} - */ - displayName: function() - { - return ""; - }, - - /** - * @override - * @return {string} - */ - url: function() - { - return "debugger:"; - }, - - /** - * @param {!WebInspector.Script} script - * @return {string} - */ - addScript: function(script) - { - var splitURL = WebInspector.ParsedURL.splitURLIntoPathComponents(script.sourceURL); - var name = splitURL[splitURL.length - 1]; - name = "VM" + script.scriptId + (name ? " " + name : ""); - return this.addContentProvider("", name, script.sourceURL, script); - }, - - __proto__: WebInspector.ContentProviderBasedProjectDelegate.prototype -}
diff --git a/third_party/WebKit/Source/devtools/front_end/bindings/FileSystemWorkspaceBinding.js b/third_party/WebKit/Source/devtools/front_end/bindings/FileSystemWorkspaceBinding.js index d8e69f0e..5d40a65b 100644 --- a/third_party/WebKit/Source/devtools/front_end/bindings/FileSystemWorkspaceBinding.js +++ b/third_party/WebKit/Source/devtools/front_end/bindings/FileSystemWorkspaceBinding.js
@@ -233,38 +233,33 @@ /** * @constructor - * @extends {WebInspector.Object} - * @implements {WebInspector.ProjectDelegate} + * @extends {WebInspector.ProjectStore} + * @implements {WebInspector.Project} * @param {!WebInspector.FileSystemWorkspaceBinding} fileSystemWorkspaceBinding * @param {!WebInspector.IsolatedFileSystem} isolatedFileSystem * @param {!WebInspector.Workspace} workspace */ WebInspector.FileSystemWorkspaceBinding.FileSystem = function(fileSystemWorkspaceBinding, isolatedFileSystem, workspace) { - WebInspector.Object.call(this); this._fileSystemWorkspaceBinding = fileSystemWorkspaceBinding; this._fileSystem = isolatedFileSystem; this._fileSystemBaseURL = "file://" + this._fileSystem.normalizedPath() + "/"; - this._fileSystemProjectURL = "filesystem:" + this._fileSystem.normalizedPath(); - this._workspace = workspace; - this._projectId = WebInspector.FileSystemWorkspaceBinding.projectId(this._fileSystem.path()); - console.assert(!this._workspace.project(this._projectId)); - this._project = this._workspace.addProject(this._projectId, this); + var id = WebInspector.FileSystemWorkspaceBinding.projectId(this._fileSystem.path()); + console.assert(!workspace.project(id)); + + var url = "filesystem:" + this._fileSystem.normalizedPath(); + var normalizedPath = isolatedFileSystem.normalizedPath(); + var displayName = normalizedPath.substr(normalizedPath.lastIndexOf("/") + 1); + + WebInspector.ProjectStore.call(this, workspace, id, WebInspector.projectTypes.FileSystem, url, displayName); + + workspace.addProject(this); this.populate(); } WebInspector.FileSystemWorkspaceBinding.FileSystem.prototype = { /** - * @override - * @return {string} - */ - type: function() - { - return WebInspector.projectTypes.FileSystem; - }, - - /** * @return {string} */ fileSystemPath: function() @@ -273,57 +268,27 @@ }, /** - * @override + * @param {!WebInspector.UISourceCode} uiSourceCode * @return {string} */ - displayName: function() + _filePathForUISourceCode: function(uiSourceCode) { - var normalizedPath = this._fileSystem.normalizedPath(); - return normalizedPath.substr(normalizedPath.lastIndexOf("/") + 1); + return "/" + uiSourceCode.path(); }, /** * @override - * @return {string} - */ - url: function() - { - return this._fileSystemProjectURL; - }, - - /** - * @param {string} path - * @return {string} - */ - _filePathForPath: function(path) - { - return "/" + path; - }, - - /** - * @override - * @param {string} path + * @param {!WebInspector.UISourceCode} uiSourceCode * @param {function(?string)} callback */ - requestFileContent: function(path, callback) + requestFileContent: function(uiSourceCode, callback) { - var filePath = this._filePathForPath(path); + var filePath = this._filePathForUISourceCode(uiSourceCode); this._fileSystem.requestFileContent(filePath, callback); }, /** * @override - * @param {string} path - * @param {function(?Date, ?number)} callback - */ - requestMetadata: function(path, callback) - { - var filePath = this._filePathForPath(path); - this._fileSystem.requestMetadata(filePath, callback); - }, - - /** - * @override * @return {boolean} */ canSetFileContent: function() @@ -333,13 +298,13 @@ /** * @override - * @param {string} path + * @param {!WebInspector.UISourceCode} uiSourceCode * @param {string} newContent * @param {function(?string)} callback */ - setFileContent: function(path, newContent, callback) + setFileContent: function(uiSourceCode, newContent, callback) { - var filePath = this._filePathForPath(path); + var filePath = this._filePathForUISourceCode(uiSourceCode); this._fileSystem.setFileContent(filePath, newContent, callback.bind(this, "")); }, @@ -354,13 +319,18 @@ /** * @override - * @param {string} path + * @param {!WebInspector.UISourceCode} uiSourceCode * @param {string} newName * @param {function(boolean, string=, string=, !WebInspector.ResourceType=)} callback */ - rename: function(path, newName, callback) + rename: function(uiSourceCode, newName, callback) { - var filePath = this._filePathForPath(path); + if (newName === uiSourceCode.name()) { + callback(true, uiSourceCode.name(), uiSourceCode.originURL(), uiSourceCode.contentType()); + return; + } + + var filePath = this._filePathForUISourceCode(uiSourceCode); this._fileSystem.renameFile(filePath, newName, innerCallback.bind(this)); /** @@ -370,34 +340,34 @@ */ function innerCallback(success, newName) { - if (!success) { + if (!success || !newName) { callback(false, newName); return; } - var validNewName = /** @type {string} */ (newName); - console.assert(validNewName); + console.assert(newName); var slash = filePath.lastIndexOf("/"); var parentPath = filePath.substring(0, slash); - filePath = parentPath + "/" + validNewName; + filePath = parentPath + "/" + newName; filePath = filePath.substr(1); - var extension = this._extensionForPath(validNewName); + var extension = this._extensionForPath(newName); var newOriginURL = this._fileSystemBaseURL + filePath; var newContentType = this._contentTypeForExtension(extension); - callback(true, validNewName, newOriginURL, newContentType); + this.renameUISourceCode(uiSourceCode, newName); + callback(true, newName, newOriginURL, newContentType); } }, /** * @override - * @param {string} path + * @param {!WebInspector.UISourceCode} uiSourceCode * @param {string} query * @param {boolean} caseSensitive * @param {boolean} isRegex * @param {function(!Array.<!WebInspector.ContentProvider.SearchMatch>)} callback */ - searchInFileContent: function(path, query, caseSensitive, isRegex, callback) + searchInFileContent: function(uiSourceCode, query, caseSensitive, isRegex, callback) { - var filePath = this._filePathForPath(path); + var filePath = this._filePathForUISourceCode(uiSourceCode); this._fileSystem.requestFileContent(filePath, contentCallback); /** @@ -547,6 +517,12 @@ excludeFolder: function(path) { this._fileSystem.addExcludedFolder(path); + var uiSourceCodes = this.uiSourceCodes().slice(); + for (var i = 0; i < uiSourceCodes.length; ++i) { + var uiSourceCode = uiSourceCodes[i]; + if (uiSourceCode.path().startsWith(path.substr(1))) + this.removeUISourceCode(uiSourceCode.path()); + } }, /** @@ -554,7 +530,7 @@ * @param {string} path * @param {?string} name * @param {string} content - * @param {function(?string)} callback + * @param {function(?WebInspector.UISourceCode)} callback */ createFile: function(path, name, content, callback) { @@ -584,8 +560,7 @@ */ function contentSet() { - this._addFile(createFilePath); - callback(createFilePath); + callback(this._addFile(createFilePath)); } }, @@ -596,7 +571,7 @@ deleteFile: function(path) { this._fileSystem.deleteFile(path); - this._removeFile(path); + this.removeUISourceCode(path); }, /** @@ -609,6 +584,7 @@ /** * @param {string} filePath + * @return {!WebInspector.UISourceCode} */ _addFile: function(filePath) { @@ -622,16 +598,7 @@ var extension = this._extensionForPath(name); var contentType = this._contentTypeForExtension(extension); - var fileDescriptor = new WebInspector.FileDescriptor(parentPath, name, this._fileSystemBaseURL + filePath, contentType); - this.dispatchEventToListeners(WebInspector.ProjectDelegate.Events.FileAdded, fileDescriptor); - }, - - /** - * @param {string} path - */ - _removeFile: function(path) - { - this.dispatchEventToListeners(WebInspector.ProjectDelegate.Events.FileRemoved, path); + return this.addUISourceCode(parentPath, name, this._fileSystemBaseURL + filePath, contentType); }, /** @@ -639,18 +606,18 @@ */ _fileChanged: function(path) { - var uiSourceCode = this._project.uiSourceCode(path); + var uiSourceCode = this.uiSourceCode(path); if (!uiSourceCode) { this._addFile(path); return; } - this.dispatchEventToListeners(WebInspector.ProjectDelegate.Events.FileChanged, path); + uiSourceCode.checkContentUpdated(); }, dispose: function() { - this._workspace.removeProject(this._projectId); + this.removeProject(); }, - __proto__: WebInspector.Object.prototype + __proto__: WebInspector.ProjectStore.prototype }
diff --git a/third_party/WebKit/Source/devtools/front_end/bindings/NetworkProject.js b/third_party/WebKit/Source/devtools/front_end/bindings/NetworkProject.js index c4b43b3..b1ac3f00 100644 --- a/third_party/WebKit/Source/devtools/front_end/bindings/NetworkProject.js +++ b/third_party/WebKit/Source/devtools/front_end/bindings/NetworkProject.js
@@ -30,7 +30,7 @@ /** * @constructor - * @extends {WebInspector.ContentProviderBasedProjectDelegate} + * @extends {WebInspector.ContentProviderBasedProject} * @param {!WebInspector.Target} target * @param {!WebInspector.Workspace} workspace * @param {string} projectId @@ -39,11 +39,8 @@ */ WebInspector.NetworkProjectDelegate = function(target, workspace, projectId, projectURL, projectType) { - this._url = projectURL; this._target = target; - this._id = projectId; - WebInspector.ContentProviderBasedProjectDelegate.call(this, workspace, projectId, projectType); - this.project()[WebInspector.NetworkProject._targetSymbol] = target; + WebInspector.ContentProviderBasedProject.call(this, workspace, projectId, projectType, projectURL, this._computeDisplayName(projectURL)); } WebInspector.NetworkProjectDelegate.prototype = { @@ -56,40 +53,22 @@ }, /** + * @param {string} url * @return {string} */ - id: function() + _computeDisplayName: function(url) { - return this._id; - }, - - /** - * @override - * @return {string} - */ - displayName: function() - { - if (typeof this._displayName !== "undefined") - return this._displayName; + for (var context of this._target.runtimeModel.executionContexts()) { + if (context.origin && url.startsWith(context.origin)) + return context.name; + } var targetSuffix = this._target.isPage() ? "" : " \u2014 " + this._target.name(); - if (!this._url) { - this._displayName = WebInspector.UIString("(no domain)") + targetSuffix; - return this._displayName; - } - var parsedURL = new WebInspector.ParsedURL(this._url); + if (!url) + return WebInspector.UIString("(no domain)") + targetSuffix; + var parsedURL = new WebInspector.ParsedURL(url); var prettyURL = parsedURL.isValid ? parsedURL.host + (parsedURL.port ? (":" + parsedURL.port) : "") : ""; - this._displayName = (prettyURL || this._url) + targetSuffix; - return this._displayName; - }, - - /** - * @override - * @return {string} - */ - url: function() - { - return this._url; + return (prettyURL || url) + targetSuffix; }, /** @@ -97,14 +76,14 @@ * @param {string} name * @param {string} url * @param {!WebInspector.ContentProvider} contentProvider - * @return {string} + * @return {!WebInspector.UISourceCode} */ addFile: function(parentPath, name, url, contentProvider) { return this.addContentProvider(parentPath, name, url, contentProvider); }, - __proto__: WebInspector.ContentProviderBasedProjectDelegate.prototype + __proto__: WebInspector.ContentProviderBasedProject.prototype } /** @@ -173,7 +152,6 @@ } WebInspector.NetworkProject._networkProjectSymbol = Symbol("networkProject"); -WebInspector.NetworkProject._targetSymbol = Symbol("target"); WebInspector.NetworkProject._contentTypeSymbol = Symbol("networkContentType"); /** @@ -188,15 +166,6 @@ } /** - * @param {!WebInspector.Project} project - * @return {?WebInspector.Target} - */ -WebInspector.NetworkProject._targetForProject = function(project) -{ - return project[WebInspector.NetworkProject._targetSymbol]; -} - -/** * @param {!WebInspector.Target} target * @return {!WebInspector.NetworkProject} */ @@ -214,7 +183,7 @@ if (uiSourceCode.project().type() !== WebInspector.projectTypes.ContentScripts && uiSourceCode.project().type() !== WebInspector.projectTypes.Network) return null; - return WebInspector.NetworkProject._targetForProject(uiSourceCode.project()); + return /** @type {!WebInspector.NetworkProjectDelegate} */(uiSourceCode.project())._target; } /** @@ -257,9 +226,7 @@ var parentPath = splitURL.slice(1, -1).join("/"); var name = splitURL.peekLast() || ""; var projectDelegate = this._projectDelegate(projectURL, isContentScript || false); - var path = projectDelegate.addFile(parentPath, name, url, contentProvider); - var uiSourceCode = /** @type {!WebInspector.UISourceCode} */ (this._workspace.uiSourceCode(projectDelegate.id(), path)); - console.assert(uiSourceCode); + var uiSourceCode = projectDelegate.addFile(parentPath, name, url, contentProvider); return uiSourceCode; }, @@ -391,7 +358,7 @@ return; var type = contentProvider.contentType(); - if (type !== WebInspector.resourceTypes.Stylesheet && type !== WebInspector.resourceTypes.Document && type !== WebInspector.resourceTypes.Script) + if (!type.isDocumentOrScriptOrStyleSheet()) return; var uiSourceCode = this.addFileForURL(url, contentProvider, isContentScript); uiSourceCode[WebInspector.NetworkProject._contentTypeSymbol] = type;
diff --git a/third_party/WebKit/Source/devtools/front_end/bindings/ResourceScriptMapping.js b/third_party/WebKit/Source/devtools/front_end/bindings/ResourceScriptMapping.js index ab30fa6..5418b484 100644 --- a/third_party/WebKit/Source/devtools/front_end/bindings/ResourceScriptMapping.js +++ b/third_party/WebKit/Source/devtools/front_end/bindings/ResourceScriptMapping.js
@@ -159,7 +159,7 @@ var uiSourceCode = /** @type {!WebInspector.UISourceCode} */ (event.data); if (!this._networkMapping.networkURL(uiSourceCode)) return; - if (uiSourceCode.project().isServiceProject()) + if (uiSourceCode.isFromServiceProject()) return; var scripts = this._scriptsForUISourceCode(uiSourceCode); @@ -177,7 +177,7 @@ var uiSourceCode = /** @type {!WebInspector.UISourceCode} */ (event.data); if (!this._networkMapping.networkURL(uiSourceCode)) return; - if (uiSourceCode.project().isServiceProject()) + if (uiSourceCode.isFromServiceProject()) return; this._unbindUISourceCode(uiSourceCode); @@ -303,7 +303,7 @@ this._uiSourceCode = uiSourceCode; this._uiSourceCode.forceLoadOnCheckContent(); - if (this._uiSourceCode.contentType() === WebInspector.resourceTypes.Script) + if (this._uiSourceCode.contentType().isScript()) this._script = scripts[0]; this._uiSourceCode.addEventListener(WebInspector.UISourceCode.Events.WorkingCopyChanged, this._workingCopyChanged, this);
diff --git a/third_party/WebKit/Source/devtools/front_end/bindings/SASSSourceMapping.js b/third_party/WebKit/Source/devtools/front_end/bindings/SASSSourceMapping.js index f2f1d1f..b95e046c 100644 --- a/third_party/WebKit/Source/devtools/front_end/bindings/SASSSourceMapping.js +++ b/third_party/WebKit/Source/devtools/front_end/bindings/SASSSourceMapping.js
@@ -156,7 +156,7 @@ for (var i = 0; i < sources.length; ++i) { var sassURL = sources[i]; if (!this._networkMapping.hasMappingForURL(sassURL)) { - var contentProvider = sourceMap.sourceContentProvider(sassURL, WebInspector.resourceTypes.Stylesheet); + var contentProvider = sourceMap.sourceContentProvider(sassURL, WebInspector.resourceTypes.SourceMapStyleSheet); this._networkProject.addFileForURL(sassURL, contentProvider); } }
diff --git a/third_party/WebKit/Source/devtools/front_end/bindings/module.json b/third_party/WebKit/Source/devtools/front_end/bindings/module.json index 4f2b5be..78f5f67ef 100644 --- a/third_party/WebKit/Source/devtools/front_end/bindings/module.json +++ b/third_party/WebKit/Source/devtools/front_end/bindings/module.json
@@ -9,7 +9,7 @@ "CSSWorkspaceBinding.js", "DebuggerWorkspaceBinding.js", "BreakpointManager.js", - "ContentProviderBasedProjectDelegate.js", + "ContentProviderBasedProject.js", "DefaultScriptMapping.js", "FileSystemWorkspaceBinding.js", "FileUtils.js", @@ -18,7 +18,6 @@ "NetworkProject.js", "PresentationConsoleMessageHelper.js", "ResourceUtils.js", - "TempFile.js", - "ContentScriptProjectDecorator.js" + "TempFile.js" ] }
diff --git a/third_party/WebKit/Source/devtools/front_end/common/ResourceType.js b/third_party/WebKit/Source/devtools/front_end/common/ResourceType.js index ce79fbb..dabb735 100644 --- a/third_party/WebKit/Source/devtools/front_end/common/ResourceType.js +++ b/third_party/WebKit/Source/devtools/front_end/common/ResourceType.js
@@ -76,6 +76,54 @@ }, /** + * @return {boolean} + */ + isScript: function() + { + return this._name === "script" || this._name === "sm-script"; + }, + + /** + * @return {boolean} + */ + hasScripts: function() + { + return this.isScript() || this.isDocument(); + }, + + /** + * @return {boolean} + */ + isStyleSheet: function() + { + return this._name === "stylesheet" || this._name === "sm-stylesheet"; + }, + + /** + * @return {boolean} + */ + isDocument: function() + { + return this._name === "document"; + }, + + /** + * @return {boolean} + */ + isDocumentOrScriptOrStyleSheet: function() + { + return this.isDocument() || this.isScript() || this.isStyleSheet(); + }, + + /** + * @return {boolean} + */ + isFromSourceMap: function() + { + return this._name.startsWith("sm-"); + }, + + /** * @override * @return {string} */ @@ -89,11 +137,11 @@ */ canonicalMimeType: function() { - if (this === WebInspector.resourceTypes.Document) + if (this.isDocument()) return "text/html"; - if (this === WebInspector.resourceTypes.Script) + if (this.isScript()) return "text/javascript"; - if (this === WebInspector.resourceTypes.Stylesheet) + if (this.isStyleSheet()) return "text/css"; return ""; } @@ -138,7 +186,9 @@ Document: new WebInspector.ResourceType("document", "Document", WebInspector.resourceCategories.Document, true), TextTrack: new WebInspector.ResourceType("texttrack", "TextTrack", WebInspector.resourceCategories.Other, true), WebSocket: new WebInspector.ResourceType("websocket", "WebSocket", WebInspector.resourceCategories.WebSocket, false), - Other: new WebInspector.ResourceType("other", "Other", WebInspector.resourceCategories.Other, false) + Other: new WebInspector.ResourceType("other", "Other", WebInspector.resourceCategories.Other, false), + SourceMapScript: new WebInspector.ResourceType("sm-script", "Script", WebInspector.resourceCategories.Script, false), + SourceMapStyleSheet: new WebInspector.ResourceType("sm-stylesheet", "Stylesheet", WebInspector.resourceCategories.Stylesheet, false), } /**
diff --git a/third_party/WebKit/Source/devtools/front_end/components/HandlerRegistry.js b/third_party/WebKit/Source/devtools/front_end/components/HandlerRegistry.js index 8468ad0..2137414 100644 --- a/third_party/WebKit/Source/devtools/front_end/components/HandlerRegistry.js +++ b/third_party/WebKit/Source/devtools/front_end/components/HandlerRegistry.js
@@ -122,10 +122,7 @@ if (!contentProvider.contentURL()) return; - var contentType = contentProvider.contentType(); - if (contentType !== WebInspector.resourceTypes.Document && - contentType !== WebInspector.resourceTypes.Stylesheet && - contentType !== WebInspector.resourceTypes.Script) + if (!contentProvider.contentType().isDocumentOrScriptOrStyleSheet()) return; /**
diff --git a/third_party/WebKit/Source/devtools/front_end/elements/elementsTreeOutline.css b/third_party/WebKit/Source/devtools/front_end/elements/elementsTreeOutline.css index beb5cfd..f7f1d7d3 100644 --- a/third_party/WebKit/Source/devtools/front_end/elements/elementsTreeOutline.css +++ b/third_party/WebKit/Source/devtools/front_end/elements/elementsTreeOutline.css
@@ -257,11 +257,29 @@ } } +@-webkit-keyframes dom-update-highlight-animation-dark { + from { + background-color: rgb(158, 54, 153); + color: white; + } + 80% { + background-color: #333; + color: inherit; + } + to { + background-color: inherit; + } +} + .dom-update-highlight { -webkit-animation: dom-update-highlight-animation 1.4s 1 cubic-bezier(0, 0, 0.2, 1); border-radius: 2px; } +:host-context(.-theme-with-dark-background) .dom-update-highlight { + -webkit-animation: dom-update-highlight-animation-dark 1.4s 1 cubic-bezier(0, 0, 0.2, 1); +} + .elements-disclosure.single-node li { padding-left: 2px; }
diff --git a/third_party/WebKit/Source/devtools/front_end/main/Main.js b/third_party/WebKit/Source/devtools/front_end/main/Main.js index 218c2c7..74b420c 100644 --- a/third_party/WebKit/Source/devtools/front_end/main/Main.js +++ b/third_party/WebKit/Source/devtools/front_end/main/Main.js
@@ -207,7 +207,6 @@ WebInspector.extensionServer = new WebInspector.ExtensionServer(); new WebInspector.OverlayController(); - new WebInspector.ContentScriptProjectDecorator(); new WebInspector.ExecutionContextSelector(WebInspector.targetManager, WebInspector.context); var autoselectPanel = WebInspector.UIString("auto");
diff --git a/third_party/WebKit/Source/devtools/front_end/main/Tests.js b/third_party/WebKit/Source/devtools/front_end/main/Tests.js index 69c0d8b..75b9568 100644 --- a/third_party/WebKit/Source/devtools/front_end/main/Tests.js +++ b/third_party/WebKit/Source/devtools/front_end/main/Tests.js
@@ -701,7 +701,7 @@ function filterOutService(uiSourceCode) { - return !uiSourceCode.project().isServiceProject(); + return !uiSourceCode.isFromServiceProject(); } var uiSourceCodes = WebInspector.workspace.uiSourceCodes();
diff --git a/third_party/WebKit/Source/devtools/front_end/popover.css b/third_party/WebKit/Source/devtools/front_end/popover.css index 8ff24965..ef0064c 100644 --- a/third_party/WebKit/Source/devtools/front_end/popover.css +++ b/third_party/WebKit/Source/devtools/front_end/popover.css
@@ -37,6 +37,10 @@ left: 0; } +.-theme-with-dark-background .popover .arrow { + -webkit-filter: invert(80%); +} + .popover.top-left-arrow .arrow { /* The default is top-left, no styles needed. */ }
diff --git a/third_party/WebKit/Source/devtools/front_end/sdk/SourceMap.js b/third_party/WebKit/Source/devtools/front_end/sdk/SourceMap.js index 56aee44..03f6c5d4 100644 --- a/third_party/WebKit/Source/devtools/front_end/sdk/SourceMap.js +++ b/third_party/WebKit/Source/devtools/front_end/sdk/SourceMap.js
@@ -63,10 +63,11 @@ * Implements Source Map V3 model. See http://code.google.com/p/closure-compiler/wiki/SourceMaps * for format description. * @constructor + * @param {string} compiledURL * @param {string} sourceMappingURL * @param {!SourceMapV3} payload */ -WebInspector.SourceMap = function(sourceMappingURL, payload) +WebInspector.SourceMap = function(compiledURL, sourceMappingURL, payload) { if (!WebInspector.SourceMap.prototype._base64Map) { const base64Digits = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; @@ -75,6 +76,7 @@ WebInspector.SourceMap.prototype._base64Map[base64Digits.charAt(i)] = i; } + this._compiledURL = compiledURL; this._sourceMappingURL = sourceMappingURL; this._reverseMappingsBySourceURL = new Map(); this._mappings = []; @@ -119,7 +121,7 @@ try { var payload = /** @type {!SourceMapV3} */ (JSON.parse(content)); var baseURL = sourceMapURL.startsWith("data:") ? compiledURL : sourceMapURL; - callback(new WebInspector.SourceMap(baseURL, payload)); + callback(new WebInspector.SourceMap(compiledURL, baseURL, payload)); } catch(e) { console.error(e.message); WebInspector.console.error("Failed to parse SourceMap: " + sourceMapURL); @@ -285,19 +287,19 @@ var nameIndex = 0; var sources = []; - var originalToCanonicalURLMap = {}; + var sourceRoot = map.sourceRoot || ""; + if (sourceRoot && !sourceRoot.endsWith("/")) + sourceRoot += "/"; for (var i = 0; i < map.sources.length; ++i) { - var originalSourceURL = map.sources[i]; - var sourceRoot = map.sourceRoot || ""; - if (sourceRoot && !sourceRoot.endsWith("/")) - sourceRoot += "/"; - var href = sourceRoot + originalSourceURL; + var href = sourceRoot + map.sources[i]; var url = WebInspector.ParsedURL.completeURL(this._sourceMappingURL, href) || href; - originalToCanonicalURLMap[originalSourceURL] = url; + var hasSource = map.sourcesContent && map.sourcesContent[i]; + if (url === this._compiledURL && hasSource) + url += WebInspector.UIString(" [sm]"); sources.push(url); this._sources[url] = true; - if (map.sourcesContent && map.sourcesContent[i]) + if (hasSource) this._sourceContentByURL[url] = map.sourcesContent[i]; }
diff --git a/third_party/WebKit/Source/devtools/front_end/snippets/ScriptSnippetModel.js b/third_party/WebKit/Source/devtools/front_end/snippets/ScriptSnippetModel.js index 777730a..f2373200 100644 --- a/third_party/WebKit/Source/devtools/front_end/snippets/ScriptSnippetModel.js +++ b/third_party/WebKit/Source/devtools/front_end/snippets/ScriptSnippetModel.js
@@ -46,9 +46,7 @@ this._mappingForTarget = new Map(); this._snippetStorage = new WebInspector.SnippetStorage("script", "Script snippet #"); this._lastSnippetEvaluationIndexSetting = WebInspector.settings.createSetting("lastSnippetEvaluationIndex", 0); - this._projectId = WebInspector.projectTypes.Snippets + ":"; - this._projectDelegate = new WebInspector.SnippetsProjectDelegate(workspace, this, this._projectId); - this._project = this._workspace.project(this._projectId); + this._project = new WebInspector.SnippetsProject(workspace, this); this._loadSnippets(); WebInspector.targetManager.observeTargets(this); } @@ -105,7 +103,7 @@ /** * @param {string} content - * @return {string} + * @return {!WebInspector.UISourceCode} */ createScriptSnippet: function(content) { @@ -116,22 +114,17 @@ /** * @param {!WebInspector.Snippet} snippet - * @return {string} + * @return {!WebInspector.UISourceCode} */ _addScriptSnippet: function(snippet) { - var path = this._projectDelegate.addSnippet(snippet.name, new WebInspector.SnippetContentProvider(snippet)); - var uiSourceCode = this._workspace.uiSourceCode(this._projectId, path); - if (!uiSourceCode) { - console.assert(uiSourceCode); - return ""; - } + var uiSourceCode = this._project.addSnippet(snippet.name, new WebInspector.SnippetContentProvider(snippet)); uiSourceCode.addEventListener(WebInspector.UISourceCode.Events.WorkingCopyChanged, this._workingCopyChanged, this); this._snippetIdForUISourceCode.set(uiSourceCode, snippet.id); var breakpointLocations = this._removeBreakpoints(uiSourceCode); this._restoreBreakpoints(uiSourceCode, breakpointLocations); this._uiSourceCodeForSnippetId[snippet.id] = uiSourceCode; - return path; + return uiSourceCode; }, /** @@ -148,7 +141,7 @@ */ deleteScriptSnippet: function(path) { - var uiSourceCode = this._workspace.uiSourceCode(this._projectId, path); + var uiSourceCode = this._project.uiSourceCode(path); if (!uiSourceCode) return; var snippetId = this._snippetIdForUISourceCode.get(uiSourceCode) || ""; @@ -158,7 +151,7 @@ this._releaseSnippetScript(uiSourceCode); delete this._uiSourceCodeForSnippetId[snippet.id]; this._snippetIdForUISourceCode.remove(uiSourceCode); - this._projectDelegate.removeFile(snippet.name); + this._project.removeFile(snippet.name); }, /** @@ -591,22 +584,21 @@ /** * @constructor - * @extends {WebInspector.ContentProviderBasedProjectDelegate} + * @extends {WebInspector.ContentProviderBasedProject} * @param {!WebInspector.Workspace} workspace * @param {!WebInspector.ScriptSnippetModel} model - * @param {string} id */ -WebInspector.SnippetsProjectDelegate = function(workspace, model, id) +WebInspector.SnippetsProject = function(workspace, model) { - WebInspector.ContentProviderBasedProjectDelegate.call(this, workspace, id, WebInspector.projectTypes.Snippets); + WebInspector.ContentProviderBasedProject.call(this, workspace, "snippets:", WebInspector.projectTypes.Snippets, "", ""); this._model = model; } -WebInspector.SnippetsProjectDelegate.prototype = { +WebInspector.SnippetsProject.prototype = { /** * @param {string} name * @param {!WebInspector.ContentProvider} contentProvider - * @return {string} + * @return {!WebInspector.UISourceCode} */ addSnippet: function(name, contentProvider) { @@ -624,13 +616,13 @@ /** * @override - * @param {string} path + * @param {!WebInspector.UISourceCode} uiSourceCode * @param {string} newContent * @param {function(?string)} callback */ - setFileContent: function(path, newContent, callback) + setFileContent: function(uiSourceCode, newContent, callback) { - this._model._setScriptSnippetContent(path, newContent); + this._model._setScriptSnippetContent(uiSourceCode.path(), newContent); callback(""); }, @@ -659,12 +651,11 @@ * @param {string} path * @param {?string} name * @param {string} content - * @param {function(?string)} callback + * @param {function(?WebInspector.UISourceCode)} callback */ createFile: function(path, name, content, callback) { - var filePath = this._model.createScriptSnippet(content); - callback(filePath); + callback(this._model.createScriptSnippet(content)); }, /** @@ -676,7 +667,7 @@ this._model.deleteScriptSnippet(path); }, - __proto__: WebInspector.ContentProviderBasedProjectDelegate.prototype + __proto__: WebInspector.ContentProviderBasedProject.prototype } /**
diff --git a/third_party/WebKit/Source/devtools/front_end/source_frame/cmdevtools.css b/third_party/WebKit/Source/devtools/front_end/source_frame/cmdevtools.css index 1ca0dd42..9e9e504 100644 --- a/third_party/WebKit/Source/devtools/front_end/source_frame/cmdevtools.css +++ b/third_party/WebKit/Source/devtools/front_end/source_frame/cmdevtools.css
@@ -234,6 +234,14 @@ z-index: -1; } +.-theme-with-dark-background .cm-line-with-selection .cm-column-with-selection.cm-search-highlight:before { + background-color: hsl(133, 100%, 30%); +} + +.-theme-with-dark-background.cm-line-with-selection .cm-search-highlight { + color: #333; +} + .CodeMirror .text-editor-line-decoration { position: absolute; }
diff --git a/third_party/WebKit/Source/devtools/front_end/sources/FilteredItemSelectionDialog.js b/third_party/WebKit/Source/devtools/front_end/sources/FilteredItemSelectionDialog.js index 46ab0833..b72a865 100644 --- a/third_party/WebKit/Source/devtools/front_end/sources/FilteredItemSelectionDialog.js +++ b/third_party/WebKit/Source/devtools/front_end/sources/FilteredItemSelectionDialog.js
@@ -846,7 +846,7 @@ */ filterProject: function(project) { - return !project.isServiceProject(); + return !WebInspector.Project.isServiceProject(project); }, __proto__: WebInspector.SelectUISourceCodeDialog.prototype
diff --git a/third_party/WebKit/Source/devtools/front_end/sources/InplaceFormatterEditorAction.js b/third_party/WebKit/Source/devtools/front_end/sources/InplaceFormatterEditorAction.js index 86d28e5..baa0318 100644 --- a/third_party/WebKit/Source/devtools/front_end/sources/InplaceFormatterEditorAction.js +++ b/third_party/WebKit/Source/devtools/front_end/sources/InplaceFormatterEditorAction.js
@@ -71,7 +71,7 @@ return false; if (uiSourceCode.project().type() === WebInspector.projectTypes.FileSystem) return true; - return uiSourceCode.contentType() === WebInspector.resourceTypes.Stylesheet + return uiSourceCode.contentType().isStyleSheet() || uiSourceCode.project().type() === WebInspector.projectTypes.Snippets; },
diff --git a/third_party/WebKit/Source/devtools/front_end/sources/JavaScriptSourceFrame.js b/third_party/WebKit/Source/devtools/front_end/sources/JavaScriptSourceFrame.js index 8ed6c485..c53cd03 100644 --- a/third_party/WebKit/Source/devtools/front_end/sources/JavaScriptSourceFrame.js +++ b/third_party/WebKit/Source/devtools/front_end/sources/JavaScriptSourceFrame.js
@@ -88,7 +88,7 @@ _showDivergedInfobar: function() { - if (this._uiSourceCode.contentType() !== WebInspector.resourceTypes.Script) + if (!this._uiSourceCode.contentType().isScript()) return; if (this._divergedInfobar) @@ -127,8 +127,7 @@ _showBlackboxInfobarIfNeeded: function() { - var contentType = this._uiSourceCode.contentType(); - if (contentType !== WebInspector.resourceTypes.Script && contentType !== WebInspector.resourceTypes.Document) + if (!this._uiSourceCode.contentType().hasScripts()) return; var projectType = this._uiSourceCode.project().type(); if (projectType === WebInspector.projectTypes.Snippets)
diff --git a/third_party/WebKit/Source/devtools/front_end/sources/NavigatorView.js b/third_party/WebKit/Source/devtools/front_end/sources/NavigatorView.js index 6b13bcf5..da8f97c24 100644 --- a/third_party/WebKit/Source/devtools/front_end/sources/NavigatorView.js +++ b/third_party/WebKit/Source/devtools/front_end/sources/NavigatorView.js
@@ -65,7 +65,8 @@ Domain: "Domain", Folder: "Folder", UISourceCode: "UISourceCode", - FileSystem: "FileSystem" + FileSystem: "FileSystem", + SourceMapFolder: "SourceMapFolder" } /** @@ -78,6 +79,8 @@ return "navigator-domain-tree-item"; if (type === WebInspector.NavigatorView.Types.FileSystem) return "navigator-folder-tree-item"; + if (type === WebInspector.NavigatorView.Types.SourceMapFolder) + return "navigator-sm-folder-tree-item"; return "navigator-folder-tree-item"; } @@ -118,7 +121,7 @@ */ accept: function(uiSourceCode) { - return !uiSourceCode.project().isServiceProject(); + return !uiSourceCode.isFromServiceProject(); }, /** @@ -128,8 +131,9 @@ { if (!this.accept(uiSourceCode)) return; - var projectNode = this._projectNode(uiSourceCode.project()); - var folderNode = this._folderNode(projectNode, uiSourceCode.parentPath()); + var isFromSourceMap = uiSourceCode.contentType().isFromSourceMap(); + var projectNode = this._projectNode(uiSourceCode.project(), isFromSourceMap); + var folderNode = this._folderNode(projectNode, uiSourceCode.parentPath(), isFromSourceMap); var uiSourceCodeNode = new WebInspector.NavigatorUISourceCodeTreeNode(this, uiSourceCode); this._uiSourceCodeNodes.set(uiSourceCode, uiSourceCodeNode); folderNode.appendChild(uiSourceCodeNode); @@ -159,7 +163,6 @@ _projectRemoved: function(event) { var project = /** @type {!WebInspector.Project} */ (event.data); - project.removeEventListener(WebInspector.Project.Events.DisplayNameUpdated, this._updateProjectNodeTitle, this); var uiSourceCodes = project.uiSourceCodes(); for (var i = 0; i < uiSourceCodes.length; ++i) this._removeUISourceCode(uiSourceCodes[i]); @@ -167,16 +170,17 @@ /** * @param {!WebInspector.Project} project + * @param {boolean} isFromSourceMap * @return {!WebInspector.NavigatorTreeNode} */ - _projectNode: function(project) + _projectNode: function(project, isFromSourceMap) { if (!project.displayName()) return this._rootNode; var projectNode = this._rootNode.child(project.id()); if (!projectNode) { - projectNode = this._createProjectNode(project); + projectNode = this._createProjectNode(project, isFromSourceMap); this._rootNode.appendChild(projectNode); } return projectNode; @@ -184,34 +188,27 @@ /** * @param {!WebInspector.Project} project + * @param {boolean} isFromSourceMap * @return {!WebInspector.NavigatorTreeNode} */ - _createProjectNode: function(project) + _createProjectNode: function(project, isFromSourceMap) { - var type = project.type() === WebInspector.projectTypes.FileSystem ? WebInspector.NavigatorView.Types.FileSystem : WebInspector.NavigatorView.Types.Domain; + var type; + if (isFromSourceMap) + type = WebInspector.NavigatorView.Types.SourceMapFolder; + else + type = project.type() === WebInspector.projectTypes.FileSystem ? WebInspector.NavigatorView.Types.FileSystem : WebInspector.NavigatorView.Types.Domain; var projectNode = new WebInspector.NavigatorFolderTreeNode(this, project, project.id(), type, "", project.displayName()); - project.addEventListener(WebInspector.Project.Events.DisplayNameUpdated, this._updateProjectNodeTitle, this); return projectNode; }, /** - * @param {!WebInspector.Event} event - */ - _updateProjectNodeTitle: function(event) - { - var project = /** @type {!WebInspector.Project} */(event.target); - var projectNode = this._rootNode.child(project.id()); - if (!projectNode) - return; - projectNode.treeNode().titleText = project.displayName(); - }, - - /** - * @param {!WebInspector.NavigatorTreeNode} projectNode + * @param {!WebInspector.NavigatorTreeNode} projectNode * @param {string} folderPath + * @param {boolean} fromSourceMap * @return {!WebInspector.NavigatorTreeNode} */ - _folderNode: function(projectNode, folderPath) + _folderNode: function(projectNode, folderPath, fromSourceMap) { if (!folderPath) return projectNode; @@ -229,10 +226,10 @@ var parentNode = projectNode; var index = folderPath.lastIndexOf("/"); if (index !== -1) - parentNode = this._folderNode(projectNode, folderPath.substring(0, index)); + parentNode = this._folderNode(projectNode, folderPath.substring(0, index), fromSourceMap); var name = folderPath.substring(index + 1); - folderNode = new WebInspector.NavigatorFolderTreeNode(this, null, name, WebInspector.NavigatorView.Types.Folder, folderPath, name); + folderNode = new WebInspector.NavigatorFolderTreeNode(this, null, name, fromSourceMap ? WebInspector.NavigatorView.Types.SourceMapFolder : WebInspector.NavigatorView.Types.Folder, folderPath, name); subfolderNodes.set(folderPath, folderNode); parentNode.appendChild(folderNode); return folderNode; @@ -280,7 +277,7 @@ if (!node) return; - var projectNode = this._projectNode(uiSourceCode.project()); + var projectNode = this._projectNode(uiSourceCode.project(), false); var subfolderNodes = this._subfolderNodes.get(projectNode); var parentNode = node.parent; this._uiSourceCodeNodes.remove(uiSourceCode); @@ -504,18 +501,12 @@ /** * @this {WebInspector.NavigatorView} - * @param {?string} path + * @param {?WebInspector.UISourceCode} uiSourceCode */ - function fileCreated(path) + function fileCreated(uiSourceCode) { - if (!path) + if (!uiSourceCode) return; - filePath = path; - uiSourceCode = project.uiSourceCode(filePath); - if (!uiSourceCode) { - console.assert(uiSourceCode); - return; - } this._sourceSelected(uiSourceCode, false); this.revealUISourceCode(uiSourceCode, true); this.rename(uiSourceCode, true); @@ -615,13 +606,13 @@ { var type = treeElement.type(); if (type === WebInspector.NavigatorView.Types.Domain) { - if (treeElement.titleText === WebInspector.targetManager.inspectedPageDomain()) + if (treeElement.nodeTitle() === WebInspector.targetManager.inspectedPageDomain()) return 1; return 2; } if (type === WebInspector.NavigatorView.Types.FileSystem) return 3; - if (type === WebInspector.NavigatorView.Types.Folder) + if (type === WebInspector.NavigatorView.Types.Folder || type === WebInspector.NavigatorView.Types.SourceMapFolder) return 4; return 5; } @@ -635,8 +626,8 @@ else if (typeWeight1 < typeWeight2) result = -1; else { - var title1 = treeElement1.titleText; - var title2 = treeElement2.titleText; + var title1 = treeElement1.nodeTitle(); + var title2 = treeElement2.nodeTitle(); result = title1.compareTo(title2); } return result; @@ -676,6 +667,7 @@ this.titleElement = this.listItemElement.createChild("div", "base-navigator-tree-element-title"); this.titleElement.textContent = this._titleText; + this.tooltip = this._tooltip || this._titleText; }, /** @@ -693,19 +685,24 @@ /** * @return {string} */ - get titleText() + nodeTitle: function() { return this._titleText; }, - set titleText(titleText) + /** + * @param {string} titleText + * @param {string=} tooltip + */ + setNodeTitle: function(titleText, tooltip) { - if (this._titleText === titleText) + if (this._titleText === titleText && this._tooltip === tooltip) return; this._titleText = titleText || ""; + this._tooltip = tooltip; if (this.titleElement) { this.titleElement.textContent = this._titleText; - this.titleElement.title = this._titleText; + this.tooltip = this._tooltip || this._titleText; } }, @@ -1155,7 +1152,10 @@ var titleText = this._uiSourceCode.displayName(); if (!ignoreIsDirty && (this._uiSourceCode.isDirty() || this._uiSourceCode.hasUnsavedCommittedChanges())) titleText = "*" + titleText; - this._treeElement.titleText = titleText; + var tooltip = titleText; + if (this._uiSourceCode.contentType().isFromSourceMap()) + tooltip = WebInspector.UIString("%s (from source map)", this._uiSourceCode.displayName()); + this._treeElement.setNodeTitle(titleText, tooltip); }, /** @@ -1224,7 +1224,7 @@ function commitHandler(element, newTitle, oldTitle) { if (newTitle !== oldTitle) { - this._treeElement.titleText = newTitle; + this._treeElement.setNodeTitle(newTitle); this._uiSourceCode.rename(newTitle, renameCallback.bind(this)); return; } @@ -1356,7 +1356,7 @@ if (children.length === 1 && this._shouldMerge(node)) { node._isMerged = true; - this._treeElement.titleText = this._treeElement.titleText + "/" + node._title; + this._treeElement.setNodeTitle(this._treeElement.nodeTitle() + "/" + node._title); node._treeElement = this._treeElement; this._treeElement.setNode(node); return; @@ -1386,7 +1386,7 @@ } while (treeNode && treeNode._isMerged); if (!this.isPopulated()) { - this._treeElement.titleText = titleText; + this._treeElement.setNodeTitle(titleText); this._treeElement.setNode(this); for (var i = 0; i < nodes.length; ++i) { delete nodes[i]._treeElement; @@ -1401,7 +1401,7 @@ oldTreeElement.parent.appendChild(treeElement); oldTreeElement.setNode(nodes[nodes.length - 1]); - oldTreeElement.titleText = nodes.map(titleForNode).join("/"); + oldTreeElement.setNodeTitle(nodes.map(titleForNode).join("/")); oldTreeElement.parent.removeChild(oldTreeElement); this._treeElement.appendChild(oldTreeElement); if (oldTreeElement.expanded)
diff --git a/third_party/WebKit/Source/devtools/front_end/sources/ScriptFormatter.js b/third_party/WebKit/Source/devtools/front_end/sources/ScriptFormatter.js index 8e72d27c..b9314fc0 100644 --- a/third_party/WebKit/Source/devtools/front_end/sources/ScriptFormatter.js +++ b/third_party/WebKit/Source/devtools/front_end/sources/ScriptFormatter.js
@@ -43,7 +43,7 @@ */ WebInspector.Formatter.format = function(contentType, mimeType, content, callback) { - if (contentType === WebInspector.resourceTypes.Script || contentType === WebInspector.resourceTypes.Document || contentType === WebInspector.resourceTypes.Stylesheet) + if (contentType.isDocumentOrScriptOrStyleSheet()) new WebInspector.ScriptFormatter(mimeType, content, callback); else new WebInspector.IdentityFormatter(mimeType, content, callback);
diff --git a/third_party/WebKit/Source/devtools/front_end/sources/ScriptFormatterEditorAction.js b/third_party/WebKit/Source/devtools/front_end/sources/ScriptFormatterEditorAction.js index 5d4a951..62d8a16 100644 --- a/third_party/WebKit/Source/devtools/front_end/sources/ScriptFormatterEditorAction.js +++ b/third_party/WebKit/Source/devtools/front_end/sources/ScriptFormatterEditorAction.js
@@ -97,58 +97,13 @@ /** * @constructor - * @param {!WebInspector.Workspace} workspace - * @param {string} id - * @extends {WebInspector.ContentProviderBasedProjectDelegate} - */ -WebInspector.FormatterProjectDelegate = function(workspace, id) -{ - WebInspector.ContentProviderBasedProjectDelegate.call(this, workspace, id, WebInspector.projectTypes.Formatter); -} - -WebInspector.FormatterProjectDelegate.prototype = { - /** - * @override - * @return {string} - */ - displayName: function() - { - return "formatter"; - }, - - /** - * @param {string} name - * @param {string} sourceURL - * @param {!WebInspector.ResourceType} contentType - * @param {string} content - * @return {string} - */ - _addFormatted: function(name, sourceURL, contentType, content) - { - var contentProvider = new WebInspector.StaticContentProvider(contentType, content); - return this.addContentProvider(sourceURL, name + ":formatted", sourceURL, contentProvider); - }, - - /** - * @param {string} path - */ - _removeFormatted: function(path) - { - this.removeFile(path); - }, - - __proto__: WebInspector.ContentProviderBasedProjectDelegate.prototype -} - -/** - * @constructor * @implements {WebInspector.SourcesView.EditorAction} * @implements {WebInspector.TargetManager.Observer} */ WebInspector.ScriptFormatterEditorAction = function() { this._projectId = "formatter:"; - this._projectDelegate = new WebInspector.FormatterProjectDelegate(WebInspector.workspace, this._projectId); + this._project = new WebInspector.ContentProviderBasedProject(WebInspector.workspace, this._projectId, WebInspector.projectTypes.Formatter, "", "formatter"); /** @type {!Map.<!WebInspector.Script, !WebInspector.UISourceCode>} */ this._uiSourceCodes = new Map(); @@ -262,8 +217,7 @@ var supportedProjectTypes = [WebInspector.projectTypes.Network, WebInspector.projectTypes.Debugger, WebInspector.projectTypes.ContentScripts]; if (supportedProjectTypes.indexOf(uiSourceCode.project().type()) === -1) return false; - var contentType = uiSourceCode.contentType(); - return contentType === WebInspector.resourceTypes.Script || contentType === WebInspector.resourceTypes.Document; + return uiSourceCode.contentType().hasScripts(); }, _toggleFormatScriptSource: function() @@ -311,7 +265,7 @@ this._uiSourceCodes.remove(formatData.scripts[i]); WebInspector.debuggerWorkspaceBinding.popSourceMapping(formatData.scripts[i]); } - this._projectDelegate._removeFormatted(formattedUISourceCode.path()); + this._project.removeFile(formattedUISourceCode.path()); }, /** @@ -336,7 +290,7 @@ else { this._formattedPaths.remove(formatData.projectId + ":" + formatData.path); this._formatData.remove(uiSourceCodes[i]); - this._projectDelegate._removeFormatted(uiSourceCodes[i].path()); + this._project.removeFile(uiSourceCodes[i].path()); } } }, @@ -374,7 +328,7 @@ } return scripts.filter(isInlineScript); } - if (uiSourceCode.contentType() === WebInspector.resourceTypes.Script) { + if (uiSourceCode.contentType().isScript()) { var rawLocations = WebInspector.debuggerWorkspaceBinding.uiLocationToRawLocations(uiSourceCode, 0, 0); return rawLocations.map(function(rawLocation) { return rawLocation.script(); }); } @@ -423,8 +377,10 @@ name = uiSourceCode.name() || (scripts.length ? scripts[0].scriptId : ""); var networkURL = WebInspector.networkMapping.networkURL(uiSourceCode); - formattedPath = this._projectDelegate._addFormatted(name, networkURL, uiSourceCode.contentType(), formattedContent); - var formattedUISourceCode = /** @type {!WebInspector.UISourceCode} */ (this._workspace.uiSourceCode(this._projectId, formattedPath)); + + var contentProvider = new WebInspector.StaticContentProvider(uiSourceCode.contentType(), formattedContent); + var formattedUISourceCode = this._project.addContentProvider(networkURL, name + ":formatted", networkURL, contentProvider); + var formattedPath = formattedUISourceCode.path(); var formatData = new WebInspector.FormatterScriptMapping.FormatData(uiSourceCode.project().id(), uiSourceCode.path(), formatterMapping, scripts); this._formatData.set(formattedUISourceCode, formatData); var path = uiSourceCode.project().id() + ":" + uiSourceCode.path();
diff --git a/third_party/WebKit/Source/devtools/front_end/sources/SourcesPanel.js b/third_party/WebKit/Source/devtools/front_end/sources/SourcesPanel.js index 8bff5d3..e9b17c9 100644 --- a/third_party/WebKit/Source/devtools/front_end/sources/SourcesPanel.js +++ b/third_party/WebKit/Source/devtools/front_end/sources/SourcesPanel.js
@@ -926,14 +926,14 @@ var projectType = uiSourceCode.project().type(); var contentType = uiSourceCode.contentType(); - if (contentType === WebInspector.resourceTypes.Script || contentType === WebInspector.resourceTypes.Document) { + if (contentType.hasScripts()) { var target = WebInspector.context.flavor(WebInspector.Target); var debuggerModel = WebInspector.DebuggerModel.fromTarget(target); if (debuggerModel && debuggerModel.isPaused()) contextMenu.appendItem(WebInspector.UIString.capitalize("Continue to ^here"), this._continueToLocation.bind(this, uiLocation)); } - if ((contentType === WebInspector.resourceTypes.Script || contentType === WebInspector.resourceTypes.Document) && projectType !== WebInspector.projectTypes.Snippets) { + if (contentType.hasScripts() && projectType !== WebInspector.projectTypes.Snippets) { var networkURL = this._networkMapping.networkURL(uiSourceCode); var url = projectType === WebInspector.projectTypes.Formatter ? uiSourceCode.originURL() : networkURL; this.sidebarPanes.callstack.appendBlackboxURLContextMenuItems(contextMenu, url, projectType === WebInspector.projectTypes.ContentScripts);
diff --git a/third_party/WebKit/Source/devtools/front_end/sources/SourcesSearchScope.js b/third_party/WebKit/Source/devtools/front_end/sources/SourcesSearchScope.js index 2520b99..e5798f0 100644 --- a/third_party/WebKit/Source/devtools/front_end/sources/SourcesSearchScope.js +++ b/third_party/WebKit/Source/devtools/front_end/sources/SourcesSearchScope.js
@@ -86,7 +86,7 @@ */ function filterOutServiceProjects(project) { - return !project.isServiceProject() || project.type() === WebInspector.projectTypes.Formatter; + return !WebInspector.Project.isServiceProject(project) || project.type() === WebInspector.projectTypes.Formatter; } /**
diff --git a/third_party/WebKit/Source/devtools/front_end/sources/SourcesView.js b/third_party/WebKit/Source/devtools/front_end/sources/SourcesView.js index a406574b..04028e7 100644 --- a/third_party/WebKit/Source/devtools/front_end/sources/SourcesView.js +++ b/third_party/WebKit/Source/devtools/front_end/sources/SourcesView.js
@@ -253,7 +253,7 @@ */ _addUISourceCode: function(uiSourceCode) { - if (uiSourceCode.project().isServiceProject()) + if (uiSourceCode.isFromServiceProject()) return; this._editorContainer.addUISourceCode(uiSourceCode); // Replace debugger script-based uiSourceCode with a network-based one. @@ -262,7 +262,7 @@ return; var networkURL = WebInspector.networkMapping.networkURL(uiSourceCode); var currentNetworkURL = WebInspector.networkMapping.networkURL(currentUISourceCode); - if (currentUISourceCode.project().isServiceProject() && currentUISourceCode !== uiSourceCode && currentNetworkURL === networkURL && networkURL) { + if (currentUISourceCode.isFromServiceProject() && currentUISourceCode !== uiSourceCode && currentNetworkURL === networkURL && networkURL) { this._showFile(uiSourceCode); this._editorContainer.removeUISourceCode(currentUISourceCode); } @@ -345,20 +345,13 @@ _createSourceFrame: function(uiSourceCode) { var sourceFrame; - switch (uiSourceCode.contentType()) { - case WebInspector.resourceTypes.Script: + var contentType = uiSourceCode.contentType(); + if (contentType.hasScripts()) sourceFrame = new WebInspector.JavaScriptSourceFrame(this._sourcesPanel, uiSourceCode); - break; - case WebInspector.resourceTypes.Document: - sourceFrame = new WebInspector.JavaScriptSourceFrame(this._sourcesPanel, uiSourceCode); - break; - case WebInspector.resourceTypes.Stylesheet: + else if (contentType.isStyleSheet()) sourceFrame = new WebInspector.CSSSourceFrame(uiSourceCode); - break; - default: + else sourceFrame = new WebInspector.UISourceCodeFrame(uiSourceCode); - break; - } sourceFrame.setHighlighterType(WebInspector.SourcesView.uiSourceCodeHighlighterType(uiSourceCode)); this._sourceFramesByUISourceCode.set(uiSourceCode, sourceFrame); this._historyManager.trackSourceFrameCursorJumps(sourceFrame); @@ -381,15 +374,11 @@ */ _sourceFrameMatchesUISourceCode: function(sourceFrame, uiSourceCode) { - switch (uiSourceCode.contentType()) { - case WebInspector.resourceTypes.Script: - case WebInspector.resourceTypes.Document: + if (uiSourceCode.contentType().hasScripts()) return sourceFrame instanceof WebInspector.JavaScriptSourceFrame; - case WebInspector.resourceTypes.Stylesheet: + if (uiSourceCode.contentType().isStyleSheet()) return sourceFrame instanceof WebInspector.CSSSourceFrame; - default: - return !(sourceFrame instanceof WebInspector.JavaScriptSourceFrame); - } + return !(sourceFrame instanceof WebInspector.JavaScriptSourceFrame); }, /** @@ -646,18 +635,18 @@ if (!uiSourceCode) return false; - switch (uiSourceCode.contentType()) { - case WebInspector.resourceTypes.Document: - case WebInspector.resourceTypes.Script: + if (uiSourceCode.contentType().hasScripts()) { WebInspector.JavaScriptOutlineDialog.show(uiSourceCode, this.showSourceLocation.bind(this, uiSourceCode)); return true; - case WebInspector.resourceTypes.Stylesheet: + } + + if (uiSourceCode.contentType().isStyleSheet()) { WebInspector.StyleSheetOutlineDialog.show(uiSourceCode, this.showSourceLocation.bind(this, uiSourceCode)); return true; - default: - // We don't want default browser shortcut to be executed, so pretend to handle this event. - return true; } + + // We don't want default browser shortcut to be executed, so pretend to handle this event. + return true; }, /**
diff --git a/third_party/WebKit/Source/devtools/front_end/sources/navigatorView.css b/third_party/WebKit/Source/devtools/front_end/sources/navigatorView.css index 9dbb3c91..dc69a9ab7 100644 --- a/third_party/WebKit/Source/devtools/front_end/sources/navigatorView.css +++ b/third_party/WebKit/Source/devtools/front_end/sources/navigatorView.css
@@ -31,19 +31,34 @@ content: url(Images/domain.png); } -.navigator-folder-tree-item .icon { +.navigator-folder-tree-item .icon, +.navigator-sm-folder-tree-item .icon { opacity: 0.7; content: url(Images/frame.png); } -.navigator-script-tree-item .icon { +.navigator-script-tree-item .icon, +.navigator-sm-script-tree-item .icon { content: url(Images/resourceJSIcon.png); } -.navigator-stylesheet-tree-item .icon { +.navigator-stylesheet-tree-item .icon, +.navigator-sm-stylesheet-tree-item .icon { content: url(Images/resourceCSSIcon.png); } +.navigator-sm-folder-tree-item .icon, +.navigator-sm-script-tree-item .icon, +.navigator-sm-stylesheet-tree-item .icon { + -webkit-filter: saturate(0); +} + +.navigator-sm-folder-tree-item .base-navigator-tree-element-title, +.navigator-sm-script-tree-item .base-navigator-tree-element-title, +.navigator-sm-stylesheet-tree-item .base-navigator-tree-element-title { + font-style: italic; +} + .navigator-document-tree-item .icon { content: url(Images/resourceDocumentIcon.png); }
diff --git a/third_party/WebKit/Source/devtools/front_end/timeline/TimelineFlameChart.js b/third_party/WebKit/Source/devtools/front_end/timeline/TimelineFlameChart.js index 7e0a4a5..46718f0 100644 --- a/third_party/WebKit/Source/devtools/front_end/timeline/TimelineFlameChart.js +++ b/third_party/WebKit/Source/devtools/front_end/timeline/TimelineFlameChart.js
@@ -522,6 +522,49 @@ /** * @override * @param {number} entryIndex + * @return {?Array.<!{title: string, value: (string|!Element)}>} + */ + prepareHighlightedEntryInfo: function(entryIndex) + { + var event = this._entryEvents[entryIndex]; + var time; + var title; + var warning; + if (event) { + var totalTime = event.duration; + var selfTime = event.selfTime; + var /** @const */ eps = 1e-6; + time = typeof totalTime === "number" && Math.abs(totalTime - selfTime) > eps && selfTime > eps ? + WebInspector.UIString("%s (self %s)", Number.millisToString(totalTime, true), Number.millisToString(selfTime, true)) : + Number.millisToString(totalTime, true); + title = this.entryTitle(entryIndex); + warning = WebInspector.TimelineUIUtils.eventWarning(event); + } else { + var frame = this._entryIndexToFrame[entryIndex]; + if (!frame) + return null; + time = WebInspector.UIString("%s ~ %.0f\u2009fps", Number.preciseMillisToString(frame.duration, 1), (1000 / frame.duration)); + title = frame.idle ? WebInspector.UIString("Idle Frame") : WebInspector.UIString("Frame"); + if (frame.hasWarnings()) { + warning = createElement("span"); + warning.textContent = WebInspector.UIString("Long frame"); + } + } + var value = createElement("div"); + var root = WebInspector.createShadowRootWithCoreStyles(value, "timeline/timelineFlamechartPopover.css"); + var contents = root.createChild("div", "timeline-flamechart-popover"); + contents.createChild("span", "timeline-info-time").textContent = time; + contents.createChild("span", "timeline-info-title").textContent = title; + if (warning) { + warning.classList.add("timeline-info-warning"); + contents.appendChild(warning); + } + return [{ title: "", value: value }]; + }, + + /** + * @override + * @param {number} entryIndex * @return {string} */ entryColor: function(entryIndex) @@ -959,15 +1002,17 @@ if (!request.url) return null; var value = createElement("div"); + var root = WebInspector.createShadowRootWithCoreStyles(value, "timeline/timelineFlamechartPopover.css"); + var contents = root.createChild("div", "timeline-flamechart-popover"); var duration = request.endTime - request.startTime; if (request.startTime && isFinite(duration)) - value.createChild("span", "timeline-network-info-duration").textContent = Number.millisToString(duration); + contents.createChild("span", "timeline-info-network-time").textContent = Number.millisToString(duration); if (typeof request.priority === "string") { - var div = value.createChild("span", "timeline-network-info-priority"); + var div = contents.createChild("span"); div.textContent = WebInspector.uiLabelForPriority(/** @type {!NetworkAgent.ResourcePriority} */ (request.priority)); div.style.color = this._colorForPriority(request.priority) || "black"; } - value.createChild("span", "timeline-network-info-url").textContent = request.url.trimMiddle(maxURLChars); + contents.createChild("span").textContent = request.url.trimMiddle(maxURLChars); return [{ title: "", value: value }]; },
diff --git a/third_party/WebKit/Source/devtools/front_end/timeline/TimelineUIUtils.js b/third_party/WebKit/Source/devtools/front_end/timeline/TimelineUIUtils.js index bb190fd..fd8ece2 100644 --- a/third_party/WebKit/Source/devtools/front_end/timeline/TimelineUIUtils.js +++ b/third_party/WebKit/Source/devtools/front_end/timeline/TimelineUIUtils.js
@@ -591,7 +591,7 @@ var contentHelper = new WebInspector.TimelineDetailsContentHelper(model.target(), linkifier, relatedNodesMap, true); if (event.warning) - contentHelper.appendWarningRow(event.warning, event); + contentHelper.appendWarningRow(event); if (detailed) { contentHelper.appendTextRow(WebInspector.UIString("Type"), WebInspector.TimelineUIUtils.eventTitle(event)); @@ -617,7 +617,7 @@ contentHelper.appendElementRow(WebInspector.UIString("Function"), detailsNode); var deoptReason = eventData["deoptReason"]; if (deoptReason && deoptReason != "no reason") - contentHelper.appendWarningRow(WebInspector.TimelineModel.WarningType.V8Deopt, event); + contentHelper.appendWarningRow(event, WebInspector.TimelineModel.WarningType.V8Deopt); break; case recordTypes.TimerFire: case recordTypes.TimerInstall: @@ -2049,36 +2049,49 @@ }, /** - * @param {?string} warningType * @param {!WebInspector.TracingModel.Event} event + * @param {string=} warningType */ - appendWarningRow: function(warningType, event) + appendWarningRow: function(event, warningType) { - - var warnings = WebInspector.TimelineModel.WarningType; - var span = createElement("span"); - var eventData = event.args["data"]; - - switch (warningType) { - case warnings.ForcedStyle: - case warnings.ForcedLayout: - span.appendChild(WebInspector.linkifyDocumentationURLAsNode("../../fundamentals/performance/rendering/avoid-large-complex-layouts-and-layout-thrashing#avoid-forced-synchronous-layouts", - WebInspector.UIString("Forced reflow"))); - span.createTextChild(WebInspector.UIString(" is a likely performance bottleneck.")); - break; - case warnings.IdleDeadlineExceeded: - span.textContent = WebInspector.UIString("Idle callback execution extended beyond deadline by " + - Number.millisToString(event.duration - eventData["allottedMilliseconds"], true)); - break; - case warnings.V8Deopt: - span.appendChild(WebInspector.linkifyURLAsNode("https://github.com/GoogleChrome/devtools-docs/issues/53", - WebInspector.UIString("Not optimized"), undefined, true)); - span.createTextChild(WebInspector.UIString(": %s", eventData["deoptReason"])); - break; - default: - console.assert(false, "Unhandled TimelineModel.WarningType"); - } - - this.appendElementRow(WebInspector.UIString("Warning"), span, true); + var warning = WebInspector.TimelineUIUtils.eventWarning(event, warningType); + if (warning) + this.appendElementRow(WebInspector.UIString("Warning"), warning, true); } } + +/** + * @param {!WebInspector.TracingModel.Event} event + * @param {string=} warningType + * @return {?Element} + */ +WebInspector.TimelineUIUtils.eventWarning = function(event, warningType) +{ + var warning = warningType || event.warning; + if (!warning) + return null; + var warnings = WebInspector.TimelineModel.WarningType; + var span = createElement("span"); + var eventData = event.args["data"]; + + switch (warning) { + case warnings.ForcedStyle: + case warnings.ForcedLayout: + span.appendChild(WebInspector.linkifyDocumentationURLAsNode("../../fundamentals/performance/rendering/avoid-large-complex-layouts-and-layout-thrashing#avoid-forced-synchronous-layouts", + WebInspector.UIString("Forced reflow"))); + span.createTextChild(WebInspector.UIString(" is a likely performance bottleneck.")); + break; + case warnings.IdleDeadlineExceeded: + span.textContent = WebInspector.UIString("Idle callback execution extended beyond deadline by " + + Number.millisToString(event.duration - eventData["allottedMilliseconds"], true)); + break; + case warnings.V8Deopt: + span.appendChild(WebInspector.linkifyURLAsNode("https://github.com/GoogleChrome/devtools-docs/issues/53", + WebInspector.UIString("Not optimized"), undefined, true)); + span.createTextChild(WebInspector.UIString(": %s", eventData["deoptReason"])); + break; + default: + console.assert(false, "Unhandled TimelineModel.WarningType"); + } + return span; +}
diff --git a/third_party/WebKit/Source/devtools/front_end/timeline/module.json b/third_party/WebKit/Source/devtools/front_end/timeline/module.json index 8cd9613..7977911 100644 --- a/third_party/WebKit/Source/devtools/front_end/timeline/module.json +++ b/third_party/WebKit/Source/devtools/front_end/timeline/module.json
@@ -123,6 +123,7 @@ ], "resources": [ "invalidationsTree.css", + "timelineFlamechartPopover.css", "timelinePanel.css", "timelineStatusDialog.css" ]
diff --git a/third_party/WebKit/Source/devtools/front_end/timeline/timelineFlamechartPopover.css b/third_party/WebKit/Source/devtools/front_end/timeline/timelineFlamechartPopover.css new file mode 100644 index 0000000..4d5ca1ef --- /dev/null +++ b/third_party/WebKit/Source/devtools/front_end/timeline/timelineFlamechartPopover.css
@@ -0,0 +1,25 @@ +/* + * Copyright (c) 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. + */ + +.timeline-flamechart-popover span { + margin-right: 5px; +} + +.timeline-flamechart-popover span.timeline-info-network-time { + color: #009; +} + +.timeline-flamechart-popover span.timeline-info-time { + color: #282; +} + +.timeline-flamechart-popover span.timeline-info-warning { + color: #e44; +} + +.timeline-flamechart-popover span.timeline-info-warning * { + color: inherit; +}
diff --git a/third_party/WebKit/Source/devtools/front_end/ui/UIUtils.js b/third_party/WebKit/Source/devtools/front_end/ui/UIUtils.js index 2d84d8cd..68aff2e 100644 --- a/third_party/WebKit/Source/devtools/front_end/ui/UIUtils.js +++ b/third_party/WebKit/Source/devtools/front_end/ui/UIUtils.js
@@ -1640,7 +1640,6 @@ * Theming API is primarily targeted at making dark theme look good. * - If rule has ".-theme-preserve" in selector, it won't be affected. * - If rule has ".selection" or "selected" or "-theme-selection-color" in selector, its hue is rotated 180deg in dark themes. - * - If rule has "highlight" its lightness is dimmmed 50%. * - One can create specializations for dark themes via body.-theme-with-dark-background selector in host context. */ _patchProperty: function(selectorText, style, name, output)
diff --git a/third_party/WebKit/Source/devtools/front_end/ui/inspectorCommon.css b/third_party/WebKit/Source/devtools/front_end/ui/inspectorCommon.css index 4d28d42..fa2794d6 100644 --- a/third_party/WebKit/Source/devtools/front_end/ui/inspectorCommon.css +++ b/third_party/WebKit/Source/devtools/front_end/ui/inspectorCommon.css
@@ -157,6 +157,10 @@ background-color: white; } +:host-context(.-theme-with-dark-background) input[type="checkbox"] { + -webkit-filter: invert(80%); +} + input[type="search"]:focus, input[type="text"]:focus { outline: auto 5px -webkit-focus-ring-color;
diff --git a/third_party/WebKit/Source/devtools/front_end/ui/inspectorSyntaxHighlightDark.css b/third_party/WebKit/Source/devtools/front_end/ui/inspectorSyntaxHighlightDark.css index e4ccf58..e661aa2 100644 --- a/third_party/WebKit/Source/devtools/front_end/ui/inspectorSyntaxHighlightDark.css +++ b/third_party/WebKit/Source/devtools/front_end/ui/inspectorSyntaxHighlightDark.css
@@ -67,6 +67,6 @@ .webkit-css-important{color:rgb(255, 26, 26);} .webkit-css-keyword{color:rgb(255, 163, 79);} .webkit-css-number{color:rgb(217, 217, 217);} -.webkit-css-property{color:rgb(132, 240, 255);} +.webkit-css-property{color: rgb(53, 212, 199);} .webkit-css-string{color:rgb(231, 194, 111);} .webkit-css-url{color:rgb(231, 194, 111);}
diff --git a/third_party/WebKit/Source/devtools/front_end/ui/searchableView.css b/third_party/WebKit/Source/devtools/front_end/ui/searchableView.css index e346e55..1ca26aa32 100644 --- a/third_party/WebKit/Source/devtools/front_end/ui/searchableView.css +++ b/third_party/WebKit/Source/devtools/front_end/ui/searchableView.css
@@ -103,6 +103,10 @@ border-left: 1px solid rgb(163, 163, 163); } +:host-context(.-theme-with-dark-background) .toolbar-search-navigation { + -webkit-filter: invert(90%); +} + .toolbar-search-navigation.toolbar-search-navigation-prev.enabled:active { background-image: url(Images/searchPrev.png), linear-gradient(rgb(168, 168, 168), rgb(116, 116, 116)); }
diff --git a/third_party/WebKit/Source/devtools/front_end/ui_lazy/FlameChart.js b/third_party/WebKit/Source/devtools/front_end/ui_lazy/FlameChart.js index bf76eb6..378e631 100644 --- a/third_party/WebKit/Source/devtools/front_end/ui_lazy/FlameChart.js +++ b/third_party/WebKit/Source/devtools/front_end/ui_lazy/FlameChart.js
@@ -447,12 +447,22 @@ WebInspector.FlameChart.prototype = { /** + * @override + */ + willHide: function() + { + this.hideHighlight(); + }, + + /** * @param {number} entryIndex */ highlightEntry: function(entryIndex) { - this._entryInfo.removeChildren(); - this._innerHighlightEntry(entryIndex); + if (this._highlightedEntryIndex === entryIndex) + return; + this._highlightedEntryIndex = entryIndex; + this._updateElementPosition(this._highlightElement, this._highlightedEntryIndex); }, hideHighlight: function() @@ -539,6 +549,7 @@ } this._cancelAnimation(); + this._updateHighlight(); this._cancelWindowTimesAnimation = WebInspector.animateFunction(this.element.window(), this._animateWindowTimes.bind(this), [{from: this._timeWindowLeft, to: startTime}, {from: this._timeWindowRight, to: endTime}], 5, this._animationCompleted.bind(this)); @@ -554,12 +565,14 @@ { this._timeWindowLeft = startTime; this._timeWindowRight = endTime; + this._updateHighlight(); this.update(); }, _animationCompleted: function() { delete this._cancelWindowTimesAnimation; + this._updateHighlight(); }, /** @@ -609,6 +622,7 @@ this._dragStartWindowLeft = this._timeWindowLeft; this._dragStartWindowRight = this._timeWindowRight; this._canvas.style.cursor = ""; + this.hideHighlight(); return true; }, @@ -631,6 +645,7 @@ _endCanvasDragging: function() { this._isDragging = false; + this._updateHighlight(); }, /** @@ -651,6 +666,7 @@ style.width = "1px"; this._selectedTimeSpanLabel.textContent = ""; this._selectionOverlay.classList.remove("hidden"); + this.hideHighlight(); return true; }, @@ -658,6 +674,7 @@ { this._isDragging = false; this._flameChartDelegate.endRangeSelection(); + this._updateHighlight(); }, _hideRangeSelection: function() @@ -699,15 +716,17 @@ { this._lastMouseOffsetX = event.offsetX; this._lastMouseOffsetY = event.offsetY; - if (!this._enabled()) return; - if (this._isDragging) return; + this._updateHighlight(); + }, - var inDividersBar = event.offsetY < WebInspector.FlameChart.DividersBarHeight; - this._highlightedMarkerIndex = inDividersBar ? this._markerIndexAtPosition(event.offsetX) : -1; + _updateHighlight: function() + { + var inDividersBar = this._lastMouseOffsetY < WebInspector.FlameChart.DividersBarHeight; + this._highlightedMarkerIndex = inDividersBar ? this._markerIndexAtPosition(this._lastMouseOffsetX) : -1; this._updateMarkerHighlight(); var entryIndex = this._coordinatesToEntryIndex(this._lastMouseOffsetX, this._lastMouseOffsetY); @@ -715,21 +734,22 @@ this.hideHighlight(); return; } - this._updateEntryInfo(entryIndex); - + this._updatePopover(entryIndex); this._canvas.style.cursor = this._dataProvider.canJumpToEntry(entryIndex) ? "pointer" : "default"; - this._innerHighlightEntry(entryIndex); + this.highlightEntry(entryIndex); }, _onMouseOut: function() { + this._lastMouseOffsetX = -1; + this._lastMouseOffsetY = -1; this.hideHighlight(); }, /** * @param {number} entryIndex */ - _updateEntryInfo: function(entryIndex) + _updatePopover: function(entryIndex) { if (entryIndex !== this._highlightedEntryIndex) { this._entryInfo.removeChildren(); @@ -759,17 +779,6 @@ this._entryInfo.style.top = y + "px"; }, - /** - * @param {number} entryIndex - */ - _innerHighlightEntry: function(entryIndex) - { - if (this._highlightedEntryIndex === entryIndex) - return; - this._highlightedEntryIndex = entryIndex; - this._updateElementPosition(this._highlightElement, this._highlightedEntryIndex); - }, - _onClick: function() { this.focus(); @@ -975,6 +984,8 @@ */ _coordinatesToEntryIndex: function(x, y) { + if (x < 0 || y < 0) + return -1; y += this._scrollTop; var timelineData = this._timelineData(); if (!timelineData) @@ -1583,6 +1594,8 @@ this._updateBoundaries(); this._calculator._updateBoundaries(this); this._draw(this._offsetWidth, this._offsetHeight); + if (!this._isDragging) + this._updateHighlight(); }, reset: function()
diff --git a/third_party/WebKit/Source/devtools/front_end/ui_lazy/dataGrid.css b/third_party/WebKit/Source/devtools/front_end/ui_lazy/dataGrid.css index 8036f8d..c8f9f851 100644 --- a/third_party/WebKit/Source/devtools/front_end/ui_lazy/dataGrid.css +++ b/third_party/WebKit/Source/devtools/front_end/ui_lazy/dataGrid.css
@@ -138,7 +138,13 @@ position: relative; } -.data-grid th.sortable:active { +.data-grid th.sortable:active::after { + content: ""; + position: absolute; + left: 0; + right: 0; + top: 0; + bottom: 0; background-color: rgba(0, 0, 0, 0.15); }
diff --git a/third_party/WebKit/Source/devtools/front_end/ui_lazy/flameChart.css b/third_party/WebKit/Source/devtools/front_end/ui_lazy/flameChart.css index e417ff2..fd7176c9 100644 --- a/third_party/WebKit/Source/devtools/front_end/ui_lazy/flameChart.css +++ b/third_party/WebKit/Source/devtools/front_end/ui_lazy/flameChart.css
@@ -84,7 +84,3 @@ .flame-chart-entry-info table tr td span { margin-right: 5px; } - -.flame-chart-entry-info table tr td span.timeline-network-info-duration { - color: darkblue; -}
diff --git a/third_party/WebKit/Source/devtools/front_end/workspace/IsolatedFileSystem.js b/third_party/WebKit/Source/devtools/front_end/workspace/IsolatedFileSystem.js index 5208e4a..1d5d957 100644 --- a/third_party/WebKit/Source/devtools/front_end/workspace/IsolatedFileSystem.js +++ b/third_party/WebKit/Source/devtools/front_end/workspace/IsolatedFileSystem.js
@@ -283,39 +283,6 @@ /** * @param {string} path - * @param {function(?Date, ?number)} callback - */ - requestMetadata: function(path, callback) - { - this._domFileSystem.root.getFile(path, null, fileEntryLoaded, errorHandler); - - /** - * @param {!FileEntry} entry - */ - function fileEntryLoaded(entry) - { - entry.getMetadata(successHandler, errorHandler); - } - - /** - * @param {!Metadata} metadata - */ - function successHandler(metadata) - { - callback(metadata.modificationTime, metadata.size); - } - - /** - * @param {!FileError} error - */ - function errorHandler(error) - { - callback(null, null); - } - }, - - /** - * @param {string} path * @param {function(?string)} callback */ requestFileContent: function(path, callback)
diff --git a/third_party/WebKit/Source/devtools/front_end/workspace/UISourceCode.js b/third_party/WebKit/Source/devtools/front_end/workspace/UISourceCode.js index 80e9b53..8b037012 100644 --- a/third_party/WebKit/Source/devtools/front_end/workspace/UISourceCode.js +++ b/third_party/WebKit/Source/devtools/front_end/workspace/UISourceCode.js
@@ -136,6 +136,14 @@ /** * @return {boolean} */ + isFromServiceProject: function() + { + return WebInspector.Project.isServiceProject(this._project); + }, + + /** + * @return {boolean} + */ canRename: function() { return this._project.canRename(); @@ -212,14 +220,6 @@ }, /** - * @param {function(?Date, ?number)} callback - */ - requestMetadata: function(callback) - { - this._project.requestMetadata(this, callback); - }, - - /** * @override * @param {function(?string)} callback */
diff --git a/third_party/WebKit/Source/devtools/front_end/workspace/Workspace.js b/third_party/WebKit/Source/devtools/front_end/workspace/Workspace.js index a81a122..b3423cb3 100644 --- a/third_party/WebKit/Source/devtools/front_end/workspace/Workspace.js +++ b/third_party/WebKit/Source/devtools/front_end/workspace/Workspace.js
@@ -62,33 +62,30 @@ } /** - * @constructor - * @param {string} parentPath - * @param {string} name - * @param {string} originURL - * @param {!WebInspector.ResourceType} contentType + * @interface */ -WebInspector.FileDescriptor = function(parentPath, name, originURL, contentType) -{ - this.parentPath = parentPath; - this.name = name; - this.originURL = originURL; - this.contentType = contentType; -} +WebInspector.Project = function() { } /** - * @interface - * @extends {WebInspector.EventTarget} + * @param {!WebInspector.Project} project + * @return {boolean} */ -WebInspector.ProjectDelegate = function() { } - -WebInspector.ProjectDelegate.Events = { - FileAdded: "FileAdded", - FileRemoved: "FileRemoved", - FileChanged: "FileChanged" +WebInspector.Project.isServiceProject = function(project) +{ + return project.type() === WebInspector.projectTypes.Debugger || project.type() === WebInspector.projectTypes.Formatter || project.type() === WebInspector.projectTypes.Service; } -WebInspector.ProjectDelegate.prototype = { +WebInspector.Project.prototype = { + /** + * @return {!WebInspector.Workspace} + */ + workspace: function() { }, + + /** + * @return {string} + */ + id: function() { }, + /** * @return {string} */ @@ -105,16 +102,10 @@ url: function() { }, /** - * @param {string} path - * @param {function(?Date, ?number)} callback - */ - requestMetadata: function(path, callback) { }, - - /** - * @param {string} path + * @param {!WebInspector.UISourceCode} uiSourceCode * @param {function(?string)} callback */ - requestFileContent: function(path, callback) { }, + requestFileContent: function(uiSourceCode, callback) { }, /** * @return {boolean} @@ -122,11 +113,11 @@ canSetFileContent: function() { }, /** - * @param {string} path + * @param {!WebInspector.UISourceCode} uiSourceCode * @param {string} newContent * @param {function(?string)} callback */ - setFileContent: function(path, newContent, callback) { }, + setFileContent: function(uiSourceCode, newContent, callback) { }, /** * @return {boolean} @@ -134,11 +125,11 @@ canRename: function() { }, /** - * @param {string} path + * @param {!WebInspector.UISourceCode} uiSourceCode * @param {string} newName * @param {function(boolean, string=, string=, !WebInspector.ResourceType=)} callback */ - rename: function(path, newName, callback) { }, + rename: function(uiSourceCode, newName, callback) { }, /** * @param {string} path @@ -155,7 +146,7 @@ * @param {string} path * @param {?string} name * @param {string} content - * @param {function(?string)} callback + * @param {function(?WebInspector.UISourceCode)} callback */ createFile: function(path, name, content, callback) { }, @@ -167,13 +158,13 @@ remove: function() { }, /** - * @param {string} path + * @param {!WebInspector.UISourceCode} uiSourceCode * @param {string} query * @param {boolean} caseSensitive * @param {boolean} isRegex * @param {function(!Array.<!WebInspector.ContentProvider.SearchMatch>)} callback */ - searchInFileContent: function(path, query, caseSensitive, isRegex, callback) { }, + searchInFileContent: function(uiSourceCode, query, caseSensitive, isRegex, callback) { }, /** * @param {!WebInspector.ProjectSearchConfig} searchConfig @@ -186,46 +177,70 @@ /** * @param {!WebInspector.Progress} progress */ - indexContent: function(progress) { } -} + indexContent: function(progress) { }, -/** - * @constructor - * @extends {WebInspector.Object} - * @param {!WebInspector.Workspace} workspace - * @param {string} projectId - * @param {!WebInspector.ProjectDelegate} projectDelegate - */ -WebInspector.Project = function(workspace, projectId, projectDelegate) -{ - /** @type {!Map.<string, !{uiSourceCode: !WebInspector.UISourceCode, index: number}>} */ - this._uiSourceCodesMap = new Map(); - /** @type {!Array.<!WebInspector.UISourceCode>} */ - this._uiSourceCodesList = []; - this._workspace = workspace; - this._projectId = projectId; - this._projectDelegate = projectDelegate; - this._url = this._projectDelegate.url(); - this._displayName = this._projectDelegate.displayName(); - projectDelegate.addEventListener(WebInspector.ProjectDelegate.Events.FileAdded, this._fileAdded, this); - projectDelegate.addEventListener(WebInspector.ProjectDelegate.Events.FileRemoved, this._fileRemoved, this); - projectDelegate.addEventListener(WebInspector.ProjectDelegate.Events.FileChanged, this._fileChanged, this); + /** + * @param {string} path + * @return {?WebInspector.UISourceCode} + */ + uiSourceCode: function(path) { }, + + /** + * @param {string} originURL + * @return {?WebInspector.UISourceCode} + */ + uiSourceCodeForOriginURL: function(originURL) { }, + + /** + * @return {!Array.<!WebInspector.UISourceCode>} + */ + uiSourceCodes: function() { } } /** * @enum {string} */ -WebInspector.Project.Events = { - DisplayNameUpdated: "DisplayNameUpdated" -}; +WebInspector.projectTypes = { + Debugger: "debugger", + Formatter: "formatter", + Network: "network", + Snippets: "snippets", + FileSystem: "filesystem", + ContentScripts: "contentscripts", + Service: "service" +} -WebInspector.Project.prototype = { +/** + * @constructor + * @param {!WebInspector.Workspace} workspace + * @param {string} id + * @param {!WebInspector.projectTypes} type + * @param {string} url + * @param {string} displayName + */ +WebInspector.ProjectStore = function(workspace, id, type, url, displayName) +{ + this._workspace = workspace; + this._id = id; + this._type = type; + this._url = url; + this._displayName = displayName; + + /** @type {!Map.<string, !{uiSourceCode: !WebInspector.UISourceCode, index: number}>} */ + this._uiSourceCodesMap = new Map(); + /** @type {!Array.<!WebInspector.UISourceCode>} */ + this._uiSourceCodesList = []; + + this._project = /** @type {!WebInspector.Project} */(this); +} + +WebInspector.ProjectStore.prototype = { /** * @return {string} */ id: function() { - return this._projectId; + return this._id; }, /** @@ -233,26 +248,7 @@ */ type: function() { - return this._projectDelegate.type(); - }, - - /** - * @return {string} - */ - displayName: function() - { - return this._displayName; - }, - - /** - * @param {string} displayName - */ - setDisplayName: function(displayName) - { - if (this._displayName === displayName) - return; - this._displayName = displayName; - this.dispatchEventToListeners(WebInspector.Project.Events.DisplayNameUpdated); + return this._type; }, /** @@ -264,56 +260,45 @@ }, /** - * @return {boolean} + * @return {string} */ - isServiceProject: function() + displayName: function() { - return this._projectDelegate.type() === WebInspector.projectTypes.Debugger || this._projectDelegate.type() === WebInspector.projectTypes.Formatter || this._projectDelegate.type() === WebInspector.projectTypes.Service; + return this._displayName; }, + /** + * @return {!WebInspector.Workspace} + */ + workspace: function() + { + return this._workspace; + }, /** - * @param {!WebInspector.Event} event + * @param {string} parentPath + * @param {string} name + * @param {string} originURL + * @param {!WebInspector.ResourceType} contentType + * @return {!WebInspector.UISourceCode} */ - _fileAdded: function(event) + addUISourceCode: function(parentPath, name, originURL, contentType) { - var fileDescriptor = /** @type {!WebInspector.FileDescriptor} */ (event.data); - var path = fileDescriptor.parentPath ? fileDescriptor.parentPath + "/" + fileDescriptor.name : fileDescriptor.name; + var path = parentPath ? parentPath + "/" + name : name; var uiSourceCode = this.uiSourceCode(path); if (uiSourceCode) - return; - - uiSourceCode = new WebInspector.UISourceCode(this, fileDescriptor.parentPath, fileDescriptor.name, fileDescriptor.originURL, fileDescriptor.contentType); - + return uiSourceCode; + uiSourceCode = new WebInspector.UISourceCode(this._project, parentPath, name, originURL, contentType); this._uiSourceCodesMap.set(path, {uiSourceCode: uiSourceCode, index: this._uiSourceCodesList.length}); this._uiSourceCodesList.push(uiSourceCode); this._workspace.dispatchEventToListeners(WebInspector.Workspace.Events.UISourceCodeAdded, uiSourceCode); - }, - - /** - * @param {!WebInspector.Event} event - */ - _fileRemoved: function(event) - { - var path = /** @type {string} */ (event.data); - this._removeFile(path); - }, - - /** - * @param {!WebInspector.Event} event - */ - _fileChanged: function(event) - { - var path = /** @type {string} */ (event.data); - var uiSourceCode = this.uiSourceCode(path); - if (uiSourceCode) - uiSourceCode.checkContentUpdated(); + return uiSourceCode; }, /** * @param {string} path */ - _removeFile: function(path) + removeUISourceCode: function(path) { var uiSourceCode = this.uiSourceCode(path); if (!uiSourceCode) @@ -329,24 +314,14 @@ this._workspace.dispatchEventToListeners(WebInspector.Workspace.Events.UISourceCodeRemoved, entry.uiSourceCode); }, - _remove: function() + removeProject: function() { - this._projectDelegate.removeEventListener(WebInspector.ProjectDelegate.Events.FileAdded, this._fileAdded, this); - this._projectDelegate.removeEventListener(WebInspector.ProjectDelegate.Events.FileRemoved, this._fileRemoved, this); - this._workspace.dispatchEventToListeners(WebInspector.Workspace.Events.ProjectRemoved, this); + this._workspace._removeProject(this._project); this._uiSourceCodesMap = new Map(); this._uiSourceCodesList = []; }, /** - * @return {!WebInspector.Workspace} - */ - workspace: function() - { - return this._workspace; - }, - - /** * @param {string} path * @return {?WebInspector.UISourceCode} */ @@ -380,181 +355,16 @@ /** * @param {!WebInspector.UISourceCode} uiSourceCode - * @param {function(?Date, ?number)} callback - */ - requestMetadata: function(uiSourceCode, callback) - { - this._projectDelegate.requestMetadata(uiSourceCode.path(), callback); - }, - - /** - * @param {!WebInspector.UISourceCode} uiSourceCode - * @param {function(?string)} callback - */ - requestFileContent: function(uiSourceCode, callback) - { - this._projectDelegate.requestFileContent(uiSourceCode.path(), callback); - }, - - /** - * @return {boolean} - */ - canSetFileContent: function() - { - return this._projectDelegate.canSetFileContent(); - }, - - /** - * @param {!WebInspector.UISourceCode} uiSourceCode - * @param {string} newContent - * @param {function(?string)} callback - */ - setFileContent: function(uiSourceCode, newContent, callback) - { - this._projectDelegate.setFileContent(uiSourceCode.path(), newContent, callback); - }, - - /** - * @return {boolean} - */ - canRename: function() - { - return this._projectDelegate.canRename(); - }, - - /** - * @param {!WebInspector.UISourceCode} uiSourceCode * @param {string} newName - * @param {function(boolean, string=, string=, !WebInspector.ResourceType=)} callback */ - rename: function(uiSourceCode, newName, callback) + renameUISourceCode: function(uiSourceCode, newName) { - if (newName === uiSourceCode.name()) { - callback(true, uiSourceCode.name(), uiSourceCode.originURL(), uiSourceCode.contentType()); - return; - } - - this._projectDelegate.rename(uiSourceCode.path(), newName, innerCallback.bind(this)); - - /** - * @param {boolean} success - * @param {string=} newName - * @param {string=} newOriginURL - * @param {!WebInspector.ResourceType=} newContentType - * @this {WebInspector.Project} - */ - function innerCallback(success, newName, newOriginURL, newContentType) - { - if (!success || !newName) { - callback(false); - return; - } - var oldPath = uiSourceCode.path(); - var newPath = uiSourceCode.parentPath() ? uiSourceCode.parentPath() + "/" + newName : newName; - var value = /** @type {!{uiSourceCode: !WebInspector.UISourceCode, index: number}} */ (this._uiSourceCodesMap.get(oldPath)); - this._uiSourceCodesMap.set(newPath, value); - this._uiSourceCodesMap.delete(oldPath); - callback(true, newName, newOriginURL, newContentType); - } - }, - - /** - * @param {string} path - * @param {function()=} callback - */ - refresh: function(path, callback) - { - this._projectDelegate.refresh(path, callback); - }, - - /** - * @param {string} path - */ - excludeFolder: function(path) - { - this._projectDelegate.excludeFolder(path); - var uiSourceCodes = this._uiSourceCodesList.slice(); - for (var i = 0; i < uiSourceCodes.length; ++i) { - var uiSourceCode = uiSourceCodes[i]; - if (uiSourceCode.path().startsWith(path.substr(1))) - this._removeFile(uiSourceCode.path()); - } - }, - - /** - * @param {string} path - * @param {?string} name - * @param {string} content - * @param {function(?string)} callback - */ - createFile: function(path, name, content, callback) - { - this._projectDelegate.createFile(path, name, content, innerCallback); - - function innerCallback(filePath) - { - callback(filePath); - } - }, - - /** - * @param {string} path - */ - deleteFile: function(path) - { - this._projectDelegate.deleteFile(path); - }, - - remove: function() - { - this._projectDelegate.remove(); - }, - - /** - * @param {!WebInspector.UISourceCode} uiSourceCode - * @param {string} query - * @param {boolean} caseSensitive - * @param {boolean} isRegex - * @param {function(!Array.<!WebInspector.ContentProvider.SearchMatch>)} callback - */ - searchInFileContent: function(uiSourceCode, query, caseSensitive, isRegex, callback) - { - this._projectDelegate.searchInFileContent(uiSourceCode.path(), query, caseSensitive, isRegex, callback); - }, - - /** - * @param {!WebInspector.ProjectSearchConfig} searchConfig - * @param {!Array.<string>} filesMathingFileQuery - * @param {!WebInspector.Progress} progress - * @param {function(!Array.<string>)} callback - */ - findFilesMatchingSearchRequest: function(searchConfig, filesMathingFileQuery, progress, callback) - { - this._projectDelegate.findFilesMatchingSearchRequest(searchConfig, filesMathingFileQuery, progress, callback); - }, - - /** - * @param {!WebInspector.Progress} progress - */ - indexContent: function(progress) - { - this._projectDelegate.indexContent(progress); - }, - - __proto__: WebInspector.Object.prototype -} - -/** - * @enum {string} - */ -WebInspector.projectTypes = { - Debugger: "debugger", - Formatter: "formatter", - Network: "network", - Snippets: "snippets", - FileSystem: "filesystem", - ContentScripts: "contentscripts", - Service: "service" + var oldPath = uiSourceCode.path(); + var newPath = uiSourceCode.parentPath() ? uiSourceCode.parentPath() + "/" + newName : newName; + var value = /** @type {!{uiSourceCode: !WebInspector.UISourceCode, index: number}} */ (this._uiSourceCodesMap.get(oldPath)); + this._uiSourceCodesMap.set(newPath, value); + this._uiSourceCodesMap.delete(oldPath); + } } /** @@ -563,8 +373,8 @@ */ WebInspector.Workspace = function() { - /** @type {!Object.<string, !WebInspector.Project>} */ - this._projects = {}; + /** @type {!Map<string, !WebInspector.Project>} */ + this._projects = new Map(); this._hasResourceContentTrackingExtensions = false; } @@ -608,7 +418,7 @@ */ uiSourceCode: function(projectId, path) { - var project = this._projects[projectId]; + var project = this._projects.get(projectId); return project ? project.uiSourceCode(path) : null; }, @@ -620,8 +430,7 @@ { var projects = this.projectsForType(WebInspector.projectTypes.Network); projects = projects.concat(this.projectsForType(WebInspector.projectTypes.ContentScripts)); - for (var i = 0; i < projects.length; ++i) { - var project = projects[i]; + for (var project of projects) { var uiSourceCode = project.uiSourceCodeForOriginURL(originURL); if (uiSourceCode) return uiSourceCode; @@ -635,9 +444,7 @@ */ filesystemUISourceCode: function(originURL) { - var projects = this.projectsForType(WebInspector.projectTypes.FileSystem); - for (var i = 0; i < projects.length; ++i) { - var project = projects[i]; + for (var project of this.projectsForType(WebInspector.projectTypes.FileSystem)) { var uiSourceCode = project.uiSourceCodeForOriginURL(originURL); if (uiSourceCode) return uiSourceCode; @@ -652,8 +459,7 @@ uiSourceCodesForProjectType: function(type) { var result = []; - for (var projectName in this._projects) { - var project = this._projects[projectName]; + for (var project of this._projects.values()) { if (project.type() === type) result = result.concat(project.uiSourceCodes()); } @@ -661,37 +467,30 @@ }, /** - * @param {string} projectId - * @param {!WebInspector.ProjectDelegate} projectDelegate - * @return {!WebInspector.Project} + * @param {!WebInspector.Project} project */ - addProject: function(projectId, projectDelegate) + addProject: function(project) { - var project = new WebInspector.Project(this, projectId, projectDelegate); - this._projects[projectId] = project; + this._projects.set(project.id(), project); this.dispatchEventToListeners(WebInspector.Workspace.Events.ProjectAdded, project); - return project; }, /** - * @param {string} projectId + * @param {!WebInspector.Project} project */ - removeProject: function(projectId) + _removeProject: function(project) { - var project = this._projects[projectId]; - if (!project) - return; - delete this._projects[projectId]; - project._remove(); + this._projects.delete(project.id()); + this.dispatchEventToListeners(WebInspector.Workspace.Events.ProjectRemoved, project); }, /** * @param {string} projectId - * @return {!WebInspector.Project} + * @return {?WebInspector.Project} */ project: function(projectId) { - return this._projects[projectId]; + return this._projects.get(projectId) || null; }, /** @@ -699,7 +498,7 @@ */ projects: function() { - return Object.values(this._projects); + return Array.from(this._projects.values()); }, /** @@ -721,10 +520,8 @@ uiSourceCodes: function() { var result = []; - for (var projectId in this._projects) { - var project = this._projects[projectId]; + for (var project of this._projects.values()) result = result.concat(project.uiSourceCodes()); - } return result; },
diff --git a/third_party/WebKit/Source/modules/accessibility/AXNodeObject.cpp b/third_party/WebKit/Source/modules/accessibility/AXNodeObject.cpp index e343919..d0fc039c 100644 --- a/third_party/WebKit/Source/modules/accessibility/AXNodeObject.cpp +++ b/third_party/WebKit/Source/modules/accessibility/AXNodeObject.cpp
@@ -1625,11 +1625,8 @@ return false; // Step 2A from: http://www.w3.org/TR/accname-aam-1.1 - if (layoutObject() - && layoutObject()->style()->visibility() != VISIBLE - && !equalIgnoringCase(getAttribute(aria_hiddenAttr), "false")) { + if (isHiddenForTextAlternativeCalculation()) return false; - } // Step 2B from: http://www.w3.org/TR/accname-aam-1.1 WillBeHeapVector<RawPtrWillBeMember<Element>> elements; @@ -2464,7 +2461,8 @@ for (size_t i = 0; i < relatedObjects.size(); i++) descriptionObjects->append(relatedObjects[i]->object); } - return result; + + return collapseWhitespace(result); } // Based on http://rawgit.com/w3c/aria/master/html-aam/html-aam.html#accessible-name-and-description-calculation
diff --git a/third_party/WebKit/Source/modules/accessibility/AXObject.cpp b/third_party/WebKit/Source/modules/accessibility/AXObject.cpp index e04b267a..feb0186 100644 --- a/third_party/WebKit/Source/modules/accessibility/AXObject.cpp +++ b/third_party/WebKit/Source/modules/accessibility/AXObject.cpp
@@ -676,6 +676,19 @@ return m_cachedIsPresentationalChild; } +// Simplify whitespace, but preserve a single leading and trailing whitespace character if it's present. +// static +String AXObject::collapseWhitespace(const String& str) +{ + StringBuilder result; + if (!str.isEmpty() && isHTMLSpace<UChar>(str[0])) + result.append(' '); + result.append(str.simplifyWhiteSpace(isHTMLSpace<UChar>)); + if (!str.isEmpty() && isHTMLSpace<UChar>(str[str.length() - 1])) + result.append(' '); + return result.toString(); +} + String AXObject::computedName() const { AXNameFrom nameFrom; @@ -689,8 +702,9 @@ AXRelatedObjectVector relatedObjects; String text = textAlternative(false, false, visited, nameFrom, &relatedObjects, nullptr); - if (!node() || !isHTMLBRElement(node())) - text = text.simplifyWhiteSpace(isHTMLSpace<UChar>, WTF::DoNotStripWhiteSpace); + AccessibilityRole role = roleValue(); + if (!node() || (!isHTMLBRElement(node()) && role != StaticTextRole && role != InlineTextBoxRole)) + text = collapseWhitespace(text); if (nameObjects) { nameObjects->clear(); @@ -716,6 +730,28 @@ return axObj.textAlternative(true, inAriaLabelledByTraversal, visited, tmpNameFrom, nullptr, nullptr); } +bool AXObject::isHiddenForTextAlternativeCalculation() const +{ + if (equalIgnoringCase(getAttribute(aria_hiddenAttr), "false")) + return false; + + if (layoutObject()) + return layoutObject()->style()->visibility() != VISIBLE; + + // This is an obscure corner case: if a node has no LayoutObject, that means it's not rendered, + // but we still may be exploring it as part of a text alternative calculation, for example if it + // was explicitly referenced by aria-labelledby. So we need to explicitly call the style resolver + // to check whether it's invisible or display:none, rather than relying on the style cached in the + // LayoutObject. + Document* doc = document(); + if (doc && doc->frame() && node() && node()->isElementNode()) { + RefPtr<ComputedStyle> style = doc->ensureStyleResolver().styleForElement(toElement(node())); + return style->display() == NONE || style->visibility() != VISIBLE; + } + + return false; +} + String AXObject::ariaTextAlternative(bool recursive, bool inAriaLabelledByTraversal, AXObjectSet& visited, AXNameFrom& nameFrom, AXRelatedObjectVector* relatedObjects, NameSources* nameSources, bool* foundTextAlternative) const { String textAlternative; @@ -724,9 +760,8 @@ // Step 2A from: http://www.w3.org/TR/accname-aam-1.1 // If you change this logic, update AXNodeObject::nameFromLabelElement, too. - if (!recursive && layoutObject() - && layoutObject()->style()->visibility() != VISIBLE - && !equalIgnoringCase(getAttribute(aria_hiddenAttr), "false")) { + if (!inAriaLabelledByTraversal && isHiddenForTextAlternativeCalculation()) { + *foundTextAlternative = true; return String(); }
diff --git a/third_party/WebKit/Source/modules/accessibility/AXObject.h b/third_party/WebKit/Source/modules/accessibility/AXObject.h index 4ebcb13..94ad5bf 100644 --- a/third_party/WebKit/Source/modules/accessibility/AXObject.h +++ b/third_party/WebKit/Source/modules/accessibility/AXObject.h
@@ -929,7 +929,9 @@ LayoutRect m_explicitElementRect; // Used only inside textAlternative(): + static String collapseWhitespace(const String&); static String recursiveTextAlternative(const AXObject&, bool inAriaLabelledByTraversal, AXObjectSet& visited); + bool isHiddenForTextAlternativeCalculation() const; String ariaTextAlternative(bool recursive, bool inAriaLabelledByTraversal, AXObjectSet& visited, AXNameFrom&, AXRelatedObjectVector*, NameSources*, bool* foundTextAlternative) const; String textFromElements(bool inAriaLabelledByTraversal, AXObjectSet& visited, WillBeHeapVector<RawPtrWillBeMember<Element>>& elements, AXRelatedObjectVector* relatedObjects) const; void tokenVectorFromAttribute(Vector<String>&, const QualifiedName&) const;
diff --git a/third_party/WebKit/Source/modules/mediastream/RTCPeerConnection.cpp b/third_party/WebKit/Source/modules/mediastream/RTCPeerConnection.cpp index d762b2f..38891a8d 100644 --- a/third_party/WebKit/Source/modules/mediastream/RTCPeerConnection.cpp +++ b/third_party/WebKit/Source/modules/mediastream/RTCPeerConnection.cpp
@@ -41,6 +41,7 @@ #include "core/dom/ExceptionCode.h" #include "core/dom/ExecutionContext.h" #include "core/frame/LocalFrame.h" +#include "core/frame/UseCounter.h" #include "core/html/VoidCallback.h" #include "core/loader/FrameLoader.h" #include "core/loader/FrameLoaderClient.h" @@ -300,6 +301,11 @@ RTCPeerConnection* RTCPeerConnection::create(ExecutionContext* context, const Dictionary& rtcConfiguration, const Dictionary& mediaConstraints, ExceptionState& exceptionState) { + if (mediaConstraints.isObject()) + UseCounter::count(context, UseCounter::RTCPeerConnectionConstructorConstraints); + else + UseCounter::count(context, UseCounter::RTCPeerConnectionConstructorCompliant); + RTCConfiguration* configuration = parseConfiguration(rtcConfiguration, exceptionState); if (exceptionState.hadException()) return 0; @@ -361,8 +367,13 @@ ASSERT(m_closed || m_stopped); } -void RTCPeerConnection::createOffer(RTCSessionDescriptionCallback* successCallback, RTCErrorCallback* errorCallback, const Dictionary& rtcOfferOptions, ExceptionState& exceptionState) +void RTCPeerConnection::createOffer(ExecutionContext* context, RTCSessionDescriptionCallback* successCallback, RTCErrorCallback* errorCallback, const Dictionary& rtcOfferOptions, ExceptionState& exceptionState) { + if (errorCallback) + UseCounter::count(context, UseCounter::RTCPeerConnectionCreateOfferLegacyFailureCallback); + else + UseCounter::count(context, UseCounter::RTCPeerConnectionCreateOfferLegacyNoFailureCallback); + if (throwExceptionIfSignalingStateClosed(m_signalingState, exceptionState)) return; @@ -375,18 +386,38 @@ RTCSessionDescriptionRequest* request = RTCSessionDescriptionRequestImpl::create(executionContext(), this, successCallback, errorCallback); if (offerOptions) { + if (offerOptions->offerToReceiveAudio() != -1 || offerOptions->offerToReceiveVideo() != -1) + UseCounter::count(context, UseCounter::RTCPeerConnectionCreateOfferLegacyOfferOptions); + else if (errorCallback) + UseCounter::count(context, UseCounter::RTCPeerConnectionCreateOfferLegacyCompliant); + m_peerHandler->createOffer(request, offerOptions); } else { WebMediaConstraints constraints = MediaConstraintsImpl::create(rtcOfferOptions, exceptionState); if (exceptionState.hadException()) return; + if (!constraints.isEmpty()) + UseCounter::count(context, UseCounter::RTCPeerConnectionCreateOfferLegacyConstraints); + else if (errorCallback) + UseCounter::count(context, UseCounter::RTCPeerConnectionCreateOfferLegacyCompliant); + m_peerHandler->createOffer(request, constraints); } } -void RTCPeerConnection::createAnswer(RTCSessionDescriptionCallback* successCallback, RTCErrorCallback* errorCallback, const Dictionary& mediaConstraints, ExceptionState& exceptionState) +void RTCPeerConnection::createAnswer(ExecutionContext* context, RTCSessionDescriptionCallback* successCallback, RTCErrorCallback* errorCallback, const Dictionary& mediaConstraints, ExceptionState& exceptionState) { + if (errorCallback) + UseCounter::count(context, UseCounter::RTCPeerConnectionCreateAnswerLegacyFailureCallback); + else + UseCounter::count(context, UseCounter::RTCPeerConnectionCreateAnswerLegacyNoFailureCallback); + + if (mediaConstraints.isObject()) + UseCounter::count(context, UseCounter::RTCPeerConnectionCreateAnswerLegacyConstraints); + else if (errorCallback) + UseCounter::count(context, UseCounter::RTCPeerConnectionCreateAnswerLegacyCompliant); + if (throwExceptionIfSignalingStateClosed(m_signalingState, exceptionState)) return; @@ -400,8 +431,17 @@ m_peerHandler->createAnswer(request, constraints); } -void RTCPeerConnection::setLocalDescription(RTCSessionDescription* sessionDescription, VoidCallback* successCallback, RTCErrorCallback* errorCallback, ExceptionState& exceptionState) +void RTCPeerConnection::setLocalDescription(ExecutionContext* context, RTCSessionDescription* sessionDescription, VoidCallback* successCallback, RTCErrorCallback* errorCallback, ExceptionState& exceptionState) { + if (successCallback && errorCallback) { + UseCounter::count(context, UseCounter::RTCPeerConnectionSetLocalDescriptionLegacyCompliant); + } else { + if (!successCallback) + UseCounter::count(context, UseCounter::RTCPeerConnectionSetLocalDescriptionLegacyNoSuccessCallback); + if (!errorCallback) + UseCounter::count(context, UseCounter::RTCPeerConnectionSetLocalDescriptionLegacyNoFailureCallback); + } + if (throwExceptionIfSignalingStateClosed(m_signalingState, exceptionState)) return; @@ -420,8 +460,17 @@ return RTCSessionDescription::create(webSessionDescription); } -void RTCPeerConnection::setRemoteDescription(RTCSessionDescription* sessionDescription, VoidCallback* successCallback, RTCErrorCallback* errorCallback, ExceptionState& exceptionState) +void RTCPeerConnection::setRemoteDescription(ExecutionContext* context, RTCSessionDescription* sessionDescription, VoidCallback* successCallback, RTCErrorCallback* errorCallback, ExceptionState& exceptionState) { + if (successCallback && errorCallback) { + UseCounter::count(context, UseCounter::RTCPeerConnectionSetRemoteDescriptionLegacyCompliant); + } else { + if (!successCallback) + UseCounter::count(context, UseCounter::RTCPeerConnectionSetRemoteDescriptionLegacyNoSuccessCallback); + if (!errorCallback) + UseCounter::count(context, UseCounter::RTCPeerConnectionSetRemoteDescriptionLegacyNoFailureCallback); + } + if (throwExceptionIfSignalingStateClosed(m_signalingState, exceptionState)) return; @@ -683,8 +732,9 @@ return 0; } -void RTCPeerConnection::getStats(RTCStatsCallback* successCallback, MediaStreamTrack* selector) +void RTCPeerConnection::getStats(ExecutionContext* context, RTCStatsCallback* successCallback, MediaStreamTrack* selector) { + UseCounter::count(context, UseCounter::RTCPeerConnectionGetStatsLegacyNonCompliant); RTCStatsRequest* statsRequest = RTCStatsRequestImpl::create(executionContext(), this, successCallback, selector); // FIXME: Add passing selector as part of the statsRequest. m_peerHandler->getStats(statsRequest);
diff --git a/third_party/WebKit/Source/modules/mediastream/RTCPeerConnection.h b/third_party/WebKit/Source/modules/mediastream/RTCPeerConnection.h index f6eefc7..ddbd951d 100644 --- a/third_party/WebKit/Source/modules/mediastream/RTCPeerConnection.h +++ b/third_party/WebKit/Source/modules/mediastream/RTCPeerConnection.h
@@ -68,14 +68,14 @@ static RTCPeerConnection* create(ExecutionContext*, const Dictionary&, const Dictionary&, ExceptionState&); ~RTCPeerConnection() override; - void createOffer(RTCSessionDescriptionCallback*, RTCErrorCallback*, const Dictionary&, ExceptionState&); + void createOffer(ExecutionContext*, RTCSessionDescriptionCallback*, RTCErrorCallback*, const Dictionary&, ExceptionState&); - void createAnswer(RTCSessionDescriptionCallback*, RTCErrorCallback*, const Dictionary&, ExceptionState&); + void createAnswer(ExecutionContext*, RTCSessionDescriptionCallback*, RTCErrorCallback*, const Dictionary&, ExceptionState&); - void setLocalDescription(RTCSessionDescription*, VoidCallback*, RTCErrorCallback*, ExceptionState&); + void setLocalDescription(ExecutionContext*, RTCSessionDescription*, VoidCallback*, RTCErrorCallback*, ExceptionState&); RTCSessionDescription* localDescription(); - void setRemoteDescription(RTCSessionDescription*, VoidCallback*, RTCErrorCallback*, ExceptionState&); + void setRemoteDescription(ExecutionContext*, RTCSessionDescription*, VoidCallback*, RTCErrorCallback*, ExceptionState&); RTCSessionDescription* remoteDescription(); String signalingState() const; @@ -105,7 +105,7 @@ void removeStream(MediaStream*, ExceptionState&); - void getStats(RTCStatsCallback* successCallback, MediaStreamTrack* selector); + void getStats(ExecutionContext*, RTCStatsCallback* successCallback, MediaStreamTrack* selector); RTCDataChannel* createDataChannel(String label, const Dictionary& dataChannelDict, ExceptionState&);
diff --git a/third_party/WebKit/Source/modules/mediastream/RTCPeerConnection.idl b/third_party/WebKit/Source/modules/mediastream/RTCPeerConnection.idl index f42c7b3..ce512b5 100644 --- a/third_party/WebKit/Source/modules/mediastream/RTCPeerConnection.idl +++ b/third_party/WebKit/Source/modules/mediastream/RTCPeerConnection.idl
@@ -99,20 +99,20 @@ // https://w3c.github.io/webrtc-pc/#legacy-interface-extensions // TODO(guidou): The failureCallback argument should be non-optional. - [RaisesException] void createOffer(RTCSessionDescriptionCallback successCallback, [Default=Undefined] optional RTCErrorCallback failureCallback, optional Dictionary rtcOfferOptions); + [CallWith=ExecutionContext, RaisesException] void createOffer(RTCSessionDescriptionCallback successCallback, [Default=Undefined] optional RTCErrorCallback failureCallback, optional Dictionary rtcOfferOptions); // TODO(guidou): None of the arguments should be optional. - [RaisesException] void setLocalDescription(RTCSessionDescription description, [Default=Undefined] optional VoidCallback successCallback, [Default=Undefined] optional RTCErrorCallback failureCallback); + [CallWith=ExecutionContext, RaisesException] void setLocalDescription(RTCSessionDescription description, [Default=Undefined] optional VoidCallback successCallback, [Default=Undefined] optional RTCErrorCallback failureCallback); // TODO(guidou): The failureCallback argument should be non-optional, and // there should be no mediaConstraints argument. - [RaisesException] void createAnswer(RTCSessionDescriptionCallback successCallback, [Default=Undefined] optional RTCErrorCallback failureCallback, optional Dictionary mediaConstraints); + [CallWith=ExecutionContext, RaisesException] void createAnswer(RTCSessionDescriptionCallback successCallback, [Default=Undefined] optional RTCErrorCallback failureCallback, optional Dictionary mediaConstraints); // TODO(guidou): The successCallback and failureCallback arguments should be // non-optional. - [RaisesException] void setRemoteDescription(RTCSessionDescription description, [Default=Undefined] optional VoidCallback successCallback, [Default=Undefined] optional RTCErrorCallback failureCallback); + [CallWith=ExecutionContext, RaisesException] void setRemoteDescription(RTCSessionDescription description, [Default=Undefined] optional VoidCallback successCallback, [Default=Undefined] optional RTCErrorCallback failureCallback); [RaisesException] void addIceCandidate(RTCIceCandidate candidate, VoidCallback successCallback, RTCErrorCallback failureCallback); // TODO(guidou): The selector argument should the first (nullable, // non-optional) argument, and there should be a third failureCallback // argument. - [LegacyInterfaceTypeChecking] void getStats(RTCStatsCallback successCallback, [Default=Undefined] optional MediaStreamTrack selector); + [CallWith=ExecutionContext, LegacyInterfaceTypeChecking] void getStats(RTCStatsCallback successCallback, [Default=Undefined] optional MediaStreamTrack selector); // https://w3c.github.io/webrtc-pc/#peer-to-peer-data-api // TODO(guidou): The label argument should have [TreatNullAs=EmptyString]
diff --git a/third_party/WebKit/Source/modules/webaudio/AnalyserNode.idl b/third_party/WebKit/Source/modules/webaudio/AnalyserNode.idl index a17621d..f066b8c 100644 --- a/third_party/WebKit/Source/modules/webaudio/AnalyserNode.idl +++ b/third_party/WebKit/Source/modules/webaudio/AnalyserNode.idl
@@ -37,10 +37,10 @@ // Copies the current frequency data into the passed array. // If the array has fewer elements than the frequencyBinCount, the excess elements will be dropped. - [LegacyInterfaceTypeChecking] void getFloatFrequencyData(Float32Array array); - [LegacyInterfaceTypeChecking] void getByteFrequencyData(Uint8Array array); + void getFloatFrequencyData(Float32Array array); + void getByteFrequencyData(Uint8Array array); // Real-time waveform data - [LegacyInterfaceTypeChecking] void getFloatTimeDomainData(Float32Array array); - [LegacyInterfaceTypeChecking] void getByteTimeDomainData(Uint8Array array); + void getFloatTimeDomainData(Float32Array array); + void getByteTimeDomainData(Uint8Array array); };
diff --git a/third_party/WebKit/Source/modules/webaudio/AudioParam.idl b/third_party/WebKit/Source/modules/webaudio/AudioParam.idl index 6169def..cc3746f 100644 --- a/third_party/WebKit/Source/modules/webaudio/AudioParam.idl +++ b/third_party/WebKit/Source/modules/webaudio/AudioParam.idl
@@ -43,7 +43,7 @@ // Sets an array of arbitrary parameter values starting at time for the given duration. // The number of values will be scaled to fit into the desired duration. - [RaisesException, MeasureAs=AudioParamSetValueCurveAtTime, LegacyInterfaceTypeChecking] AudioParam setValueCurveAtTime(Float32Array values, double time, double duration); + [RaisesException, MeasureAs=AudioParamSetValueCurveAtTime] AudioParam setValueCurveAtTime(Float32Array values, double time, double duration); // Cancels all scheduled parameter changes with times greater than or equal to startTime. [RaisesException, MeasureAs=AudioParamCancelScheduledValues] AudioParam cancelScheduledValues(double startTime);
diff --git a/third_party/WebKit/Source/modules/webaudio/AudioParamTimeline.cpp b/third_party/WebKit/Source/modules/webaudio/AudioParamTimeline.cpp index e16331e..f4967991 100644 --- a/third_party/WebKit/Source/modules/webaudio/AudioParamTimeline.cpp +++ b/third_party/WebKit/Source/modules/webaudio/AudioParamTimeline.cpp
@@ -201,6 +201,7 @@ void AudioParamTimeline::setValueCurveAtTime(DOMFloat32Array* curve, double time, double duration, ExceptionState& exceptionState) { ASSERT(isMainThread()); + ASSERT(curve); if (!isNonNegativeAudioParamTime(time, exceptionState) || !isPositiveAudioParamTime(duration, exceptionState, "Duration"))
diff --git a/third_party/WebKit/Source/modules/webaudio/BiquadFilterNode.cpp b/third_party/WebKit/Source/modules/webaudio/BiquadFilterNode.cpp index cd7ca03..412a92ab 100644 --- a/third_party/WebKit/Source/modules/webaudio/BiquadFilterNode.cpp +++ b/third_party/WebKit/Source/modules/webaudio/BiquadFilterNode.cpp
@@ -110,8 +110,7 @@ void BiquadFilterNode::getFrequencyResponse(const DOMFloat32Array* frequencyHz, DOMFloat32Array* magResponse, DOMFloat32Array* phaseResponse) { - if (!frequencyHz || !magResponse || !phaseResponse) - return; + ASSERT(frequencyHz && magResponse && phaseResponse); int n = std::min(frequencyHz->length(), std::min(magResponse->length(), phaseResponse->length())); if (n)
diff --git a/third_party/WebKit/Source/modules/webaudio/BiquadFilterNode.idl b/third_party/WebKit/Source/modules/webaudio/BiquadFilterNode.idl index 9abd2b6..9783ab2a 100644 --- a/third_party/WebKit/Source/modules/webaudio/BiquadFilterNode.idl +++ b/third_party/WebKit/Source/modules/webaudio/BiquadFilterNode.idl
@@ -43,7 +43,7 @@ readonly attribute AudioParam Q; // Quality factor readonly attribute AudioParam gain; // in Decibels - [LegacyInterfaceTypeChecking] void getFrequencyResponse(Float32Array frequencyHz, - Float32Array magResponse, - Float32Array phaseResponse); + void getFrequencyResponse(Float32Array frequencyHz, + Float32Array magResponse, + Float32Array phaseResponse); };
diff --git a/third_party/WebKit/Source/modules/webaudio/ConvolverNode.idl b/third_party/WebKit/Source/modules/webaudio/ConvolverNode.idl index 9f1a3fb0..6831fc32 100644 --- a/third_party/WebKit/Source/modules/webaudio/ConvolverNode.idl +++ b/third_party/WebKit/Source/modules/webaudio/ConvolverNode.idl
@@ -26,6 +26,6 @@ [ Conditional=WEB_AUDIO ] interface ConvolverNode : AudioNode { - [RaisesException=Setter, LegacyInterfaceTypeChecking] attribute AudioBuffer buffer; + [RaisesException=Setter] attribute AudioBuffer? buffer; attribute boolean normalize; };
diff --git a/third_party/WebKit/Source/modules/webaudio/OscillatorNode.cpp b/third_party/WebKit/Source/modules/webaudio/OscillatorNode.cpp index b62f824..ed38aa2 100644 --- a/third_party/WebKit/Source/modules/webaudio/OscillatorNode.cpp +++ b/third_party/WebKit/Source/modules/webaudio/OscillatorNode.cpp
@@ -327,6 +327,7 @@ void OscillatorHandler::setPeriodicWave(PeriodicWave* periodicWave) { ASSERT(isMainThread()); + ASSERT(periodicWave); // This synchronizes with process(). MutexLocker processLocker(m_processLock);
diff --git a/third_party/WebKit/Source/modules/webaudio/OscillatorNode.idl b/third_party/WebKit/Source/modules/webaudio/OscillatorNode.idl index 8564d81..203abfe7 100644 --- a/third_party/WebKit/Source/modules/webaudio/OscillatorNode.idl +++ b/third_party/WebKit/Source/modules/webaudio/OscillatorNode.idl
@@ -43,7 +43,7 @@ [RaisesException] void start(optional double when); [RaisesException] void stop(optional double when); - [LegacyInterfaceTypeChecking] void setPeriodicWave(PeriodicWave periodicWave); + void setPeriodicWave(PeriodicWave periodicWave); attribute EventHandler onended; };
diff --git a/third_party/WebKit/Source/modules/webaudio/RealtimeAnalyser.cpp b/third_party/WebKit/Source/modules/webaudio/RealtimeAnalyser.cpp index 26b2f68..6f8b620 100644 --- a/third_party/WebKit/Source/modules/webaudio/RealtimeAnalyser.cpp +++ b/third_party/WebKit/Source/modules/webaudio/RealtimeAnalyser.cpp
@@ -190,9 +190,7 @@ void RealtimeAnalyser::getFloatFrequencyData(DOMFloat32Array* destinationArray) { ASSERT(isMainThread()); - - if (!destinationArray) - return; + ASSERT(destinationArray); doFFTAnalysis(); @@ -215,9 +213,7 @@ void RealtimeAnalyser::getByteFrequencyData(DOMUint8Array* destinationArray) { ASSERT(isMainThread()); - - if (!destinationArray) - return; + ASSERT(destinationArray); doFFTAnalysis(); @@ -252,9 +248,7 @@ void RealtimeAnalyser::getFloatTimeDomainData(DOMFloat32Array* destinationArray) { ASSERT(isMainThread()); - - if (!destinationArray) - return; + ASSERT(destinationArray); unsigned fftSize = this->fftSize(); size_t len = std::min(fftSize, destinationArray->length()); @@ -281,9 +275,7 @@ void RealtimeAnalyser::getByteTimeDomainData(DOMUint8Array* destinationArray) { ASSERT(isMainThread()); - - if (!destinationArray) - return; + ASSERT(destinationArray); unsigned fftSize = this->fftSize(); size_t len = std::min(fftSize, destinationArray->length());
diff --git a/third_party/WebKit/Source/modules/webaudio/ScriptProcessorNode.cpp b/third_party/WebKit/Source/modules/webaudio/ScriptProcessorNode.cpp index 3108db80..ce9c88a 100644 --- a/third_party/WebKit/Source/modules/webaudio/ScriptProcessorNode.cpp +++ b/third_party/WebKit/Source/modules/webaudio/ScriptProcessorNode.cpp
@@ -42,7 +42,6 @@ ScriptProcessorHandler::ScriptProcessorHandler(AudioNode& node, float sampleRate, size_t bufferSize, unsigned numberOfInputChannels, unsigned numberOfOutputChannels) : AudioHandler(NodeTypeJavaScript, node, sampleRate) , m_doubleBufferIndex(0) - , m_doubleBufferIndexForEvent(0) , m_bufferSize(bufferSize) , m_bufferReadWriteIndex(0) , m_numberOfInputChannels(numberOfInputChannels) @@ -166,26 +165,26 @@ // The best we can do is clear out the buffer ourself here. outputBuffer->zero(); } else if (context()->executionContext()) { - // Fire the event on the main thread, not this one (which is the realtime audio thread). - m_doubleBufferIndexForEvent = m_doubleBufferIndex; - context()->executionContext()->postTask(BLINK_FROM_HERE, createCrossThreadTask(&ScriptProcessorHandler::fireProcessEvent, PassRefPtr<ScriptProcessorHandler>(this))); + // Fire the event on the main thread with the appropriate buffer + // index. + context()->executionContext()->postTask(BLINK_FROM_HERE, + createCrossThreadTask(&ScriptProcessorHandler::fireProcessEvent, this, m_doubleBufferIndex)); } swapBuffers(); } } -void ScriptProcessorHandler::fireProcessEvent() +void ScriptProcessorHandler::fireProcessEvent(unsigned doubleBufferIndex) { ASSERT(isMainThread()); - bool isIndexGood = m_doubleBufferIndexForEvent < 2; - ASSERT(isIndexGood); - if (!isIndexGood) + ASSERT(doubleBufferIndex < 2); + if (doubleBufferIndex > 1) return; - AudioBuffer* inputBuffer = m_inputBuffers[m_doubleBufferIndexForEvent].get(); - AudioBuffer* outputBuffer = m_outputBuffers[m_doubleBufferIndexForEvent].get(); + AudioBuffer* inputBuffer = m_inputBuffers[doubleBufferIndex].get(); + AudioBuffer* outputBuffer = m_outputBuffers[doubleBufferIndex].get(); ASSERT(outputBuffer); if (!outputBuffer) return;
diff --git a/third_party/WebKit/Source/modules/webaudio/ScriptProcessorNode.h b/third_party/WebKit/Source/modules/webaudio/ScriptProcessorNode.h index 1b9bf9ae..dbb58cf 100644 --- a/third_party/WebKit/Source/modules/webaudio/ScriptProcessorNode.h +++ b/third_party/WebKit/Source/modules/webaudio/ScriptProcessorNode.h
@@ -65,13 +65,13 @@ double tailTime() const override; double latencyTime() const override; - void fireProcessEvent(); + void fireProcessEvent(unsigned); // Double buffering unsigned doubleBufferIndex() const { return m_doubleBufferIndex; } void swapBuffers() { m_doubleBufferIndex = 1 - m_doubleBufferIndex; } unsigned m_doubleBufferIndex; - unsigned m_doubleBufferIndexForEvent; + // These Persistent don't make reference cycles including the owner // ScriptProcessorNode. PersistentHeapVector<Member<AudioBuffer>> m_inputBuffers;
diff --git a/third_party/WebKit/Source/modules/webaudio/WaveShaperNode.idl b/third_party/WebKit/Source/modules/webaudio/WaveShaperNode.idl index 586125a9..49ff1cc 100644 --- a/third_party/WebKit/Source/modules/webaudio/WaveShaperNode.idl +++ b/third_party/WebKit/Source/modules/webaudio/WaveShaperNode.idl
@@ -31,6 +31,6 @@ [ Conditional=WEB_AUDIO ] interface WaveShaperNode : AudioNode { - [RaisesException=Setter, LegacyInterfaceTypeChecking] attribute Float32Array curve; + [RaisesException=Setter] attribute Float32Array? curve; attribute OverSampleType oversample; };
diff --git a/third_party/WebKit/Source/modules/webgl/WebGL2RenderingContextBase.cpp b/third_party/WebKit/Source/modules/webgl/WebGL2RenderingContextBase.cpp index 2e298a3a..be4958b 100644 --- a/third_party/WebKit/Source/modules/webgl/WebGL2RenderingContextBase.cpp +++ b/third_party/WebKit/Source/modules/webgl/WebGL2RenderingContextBase.cpp
@@ -2366,8 +2366,10 @@ return String(); } OwnPtr<GLchar[]> name = adoptArrayPtr(new GLchar[maxNameLength]); - GLsizei length; + + GLsizei length = 0; webContext()->getActiveUniformBlockName(objectOrZero(program), uniformBlockIndex, maxNameLength, &length, name.get()); + return String(name.get(), length); } @@ -3298,4 +3300,16 @@ return GL_RGB; } +const WebGLSamplerState* WebGL2RenderingContextBase::getTextureUnitSamplerState(GLenum target, GLuint unit) const +{ + ASSERT(unit < m_samplerUnits.size()); + + WebGLSampler* sampler = m_samplerUnits[unit]; + + if (sampler) + return sampler->getSamplerState(); + + return WebGLRenderingContextBase::getTextureUnitSamplerState(target, unit); +} + } // namespace blink
diff --git a/third_party/WebKit/Source/modules/webgl/WebGL2RenderingContextBase.h b/third_party/WebKit/Source/modules/webgl/WebGL2RenderingContextBase.h index 47d94d2..ba0b485 100644 --- a/third_party/WebKit/Source/modules/webgl/WebGL2RenderingContextBase.h +++ b/third_party/WebKit/Source/modules/webgl/WebGL2RenderingContextBase.h
@@ -229,6 +229,7 @@ GLint getMaxTextureLevelForTarget(GLenum target) override; void renderbufferStorageImpl(GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height, const char* functionName) override; GLenum boundFramebufferColorFormat() override; + const WebGLSamplerState* getTextureUnitSamplerState(GLenum target, GLuint unit) const override; // Helper function to validate the target for compressedTex{Sub}Image3D. bool validateTexFunc3DTarget(const char* functionName, GLenum target);
diff --git a/third_party/WebKit/Source/modules/webgl/WebGLRenderingContextBase.cpp b/third_party/WebKit/Source/modules/webgl/WebGLRenderingContextBase.cpp index b0657c4..1dcf1f6e 100644 --- a/third_party/WebKit/Source/modules/webgl/WebGLRenderingContextBase.cpp +++ b/third_party/WebKit/Source/modules/webgl/WebGLRenderingContextBase.cpp
@@ -34,6 +34,7 @@ #include "core/dom/ExceptionCode.h" #include "core/dom/FlexibleArrayBufferView.h" #include "core/fetch/ImageResource.h" +#include "core/frame/ImageBitmap.h" #include "core/frame/LocalFrame.h" #include "core/frame/Settings.h" #include "core/html/HTMLCanvasElement.h" @@ -2046,6 +2047,33 @@ return renderbuffer->emulatedStencilBuffer(); } +const WebGLSamplerState* WebGLRenderingContextBase::getTextureUnitSamplerState(GLenum target, GLuint unit) const +{ + ASSERT(unit < m_textureUnits.size()); + + WebGLTexture* texture = nullptr; + + switch (target) { + case GL_TEXTURE_2D: + texture = m_textureUnits[unit].m_texture2DBinding; + break; + case GL_TEXTURE_CUBE_MAP: + texture = m_textureUnits[unit].m_textureCubeMapBinding; + break; + case GL_TEXTURE_2D_ARRAY: + texture = m_textureUnits[unit].m_texture2DArrayBinding; + break; + case GL_TEXTURE_3D: + texture = m_textureUnits[unit].m_texture3DBinding; + break; + } + + if (texture) + return texture->getSamplerState(); + + return nullptr; +} + void WebGLRenderingContextBase::setBoundVertexArrayObject(ScriptState* scriptState, WebGLVertexArrayObjectBase* arrayObject) { if (arrayObject) @@ -4312,6 +4340,10 @@ synthesizeGLError(GL_INVALID_VALUE, "texImage2D", "no image data"); return; } + if (pixels->data()->bufferBase()->isNeutered()) { + synthesizeGLError(GL_INVALID_VALUE, "texImage2D", "The source data has been neutered."); + return; + } if (isContextLost() || !validateTexFunc("texImage2D", NotTexSubImage2D, SourceImageData, target, level, internalformat, pixels->width(), pixels->height(), 0, format, type, 0, 0)) return; if (type == GL_UNSIGNED_INT_10F_11F_11F_REV) { @@ -4505,6 +4537,20 @@ texImage2DImpl(target, level, internalformat, format, type, image.get(), WebGLImageConversion::HtmlDomVideo, m_unpackFlipY, m_unpackPremultiplyAlpha); } +void WebGLRenderingContextBase::texImage2D(GLenum target, GLint level, GLenum internalformat, + GLenum format, GLenum type, PassRefPtrWillBeRawPtr<ImageBitmap> bitmap) +{ + ASSERT(bitmap->bitmapImage()); + if (bitmap->isNeutered()) { + synthesizeGLError(GL_INVALID_VALUE, "texImage2D", "The source data has been neutered."); + return; + } + if (isContextLost() || !validateTexFunc("texImage2D", NotTexSubImage2D, SourceImageBitmap, target, level, 0, bitmap->width(), bitmap->height(), 0, format, type, 0, 0)) + return; + StaticBitmapImage* imageForRender = bitmap->bitmapImage(); + texImage2DImpl(target, level, internalformat, format, type, imageForRender, WebGLImageConversion::HtmlDomImage, m_unpackFlipY, m_unpackPremultiplyAlpha); +} + void WebGLRenderingContextBase::texParameter(GLenum target, GLenum pname, GLfloat paramf, GLint parami, bool isFloat) { if (isContextLost()) @@ -4633,6 +4679,10 @@ synthesizeGLError(GL_INVALID_VALUE, "texSubImage2D", "no image data"); return; } + if (pixels->data()->bufferBase()->isNeutered()) { + synthesizeGLError(GL_INVALID_VALUE, "texSubImage2D", "The source data has been neutered."); + return; + } if (isContextLost() || !validateTexFunc("texSubImage2D", TexSubImage2D, SourceImageData, target, level, 0, pixels->width(), pixels->height(), 0, format, type, xoffset, yoffset)) return; if (type == GL_UNSIGNED_INT_10F_11F_11F_REV) { @@ -4713,6 +4763,20 @@ texSubImage2DImpl(target, level, xoffset, yoffset, format, type, image.get(), WebGLImageConversion::HtmlDomVideo, m_unpackFlipY, m_unpackPremultiplyAlpha); } +void WebGLRenderingContextBase::texSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset, + GLenum format, GLenum type, PassRefPtrWillBeRawPtr<ImageBitmap> bitmap) +{ + ASSERT(bitmap->bitmapImage()); + if (bitmap->isNeutered()) { + synthesizeGLError(GL_INVALID_VALUE, "texSubImage2D", "The source data has been neutered."); + return; + } + if (isContextLost() || !validateTexFunc("texSubImage2D", TexSubImage2D, SourceImageBitmap, target, level, 0, bitmap->width(), bitmap->height(), 0, format, type, 0, 0)) + return; + StaticBitmapImage* imageForRender = bitmap->bitmapImage(); + texSubImage2DImpl(target, level, xoffset, yoffset, format, type, imageForRender, WebGLImageConversion::HtmlDomImage, m_unpackFlipY, m_unpackPremultiplyAlpha); +} + void WebGLRenderingContextBase::uniform1f(const WebGLUniformLocation* location, GLfloat x) { if (isContextLost() || !location) @@ -5392,8 +5456,10 @@ WebGLTexture::TextureExtensionFlag flag = static_cast<WebGLTexture::TextureExtensionFlag>((extensionEnabled(OESTextureFloatLinearName) ? WebGLTexture::TextureFloatLinearExtensionEnabled : 0) | ((extensionEnabled(OESTextureHalfFloatLinearName) || isWebGL2OrHigher()) ? WebGLTexture::TextureHalfFloatLinearExtensionEnabled : 0)); for (unsigned ii = 0; ii < m_onePlusMaxNonDefaultTextureUnit; ++ii) { - if ((m_textureUnits[ii].m_texture2DBinding.get() && m_textureUnits[ii].m_texture2DBinding->needToUseBlackTexture(flag)) - || (m_textureUnits[ii].m_textureCubeMapBinding.get() && m_textureUnits[ii].m_textureCubeMapBinding->needToUseBlackTexture(flag))) { + const WebGLSamplerState* samplerState2D = getTextureUnitSamplerState(GL_TEXTURE_2D, ii); + const WebGLSamplerState* samplerStateCubeMap = getTextureUnitSamplerState(GL_TEXTURE_CUBE_MAP, ii); + if ((m_textureUnits[ii].m_texture2DBinding.get() && m_textureUnits[ii].m_texture2DBinding->needToUseBlackTexture(flag, samplerState2D)) + || (m_textureUnits[ii].m_textureCubeMapBinding.get() && m_textureUnits[ii].m_textureCubeMapBinding->needToUseBlackTexture(flag, samplerStateCubeMap))) { if (ii != m_activeTextureUnit) { webContext()->activeTexture(GL_TEXTURE0 + ii); resetActiveUnit = true; @@ -5414,9 +5480,9 @@ tex2D = m_textureUnits[ii].m_texture2DBinding.get(); texCubeMap = m_textureUnits[ii].m_textureCubeMapBinding.get(); } - if (m_textureUnits[ii].m_texture2DBinding && m_textureUnits[ii].m_texture2DBinding->needToUseBlackTexture(flag)) + if (m_textureUnits[ii].m_texture2DBinding && m_textureUnits[ii].m_texture2DBinding->needToUseBlackTexture(flag, samplerState2D)) webContext()->bindTexture(GL_TEXTURE_2D, objectOrZero(tex2D)); - if (m_textureUnits[ii].m_textureCubeMapBinding && m_textureUnits[ii].m_textureCubeMapBinding->needToUseBlackTexture(flag)) + if (m_textureUnits[ii].m_textureCubeMapBinding && m_textureUnits[ii].m_textureCubeMapBinding->needToUseBlackTexture(flag, samplerStateCubeMap)) webContext()->bindTexture(GL_TEXTURE_CUBE_MAP, objectOrZero(texCubeMap)); } }
diff --git a/third_party/WebKit/Source/modules/webgl/WebGLRenderingContextBase.h b/third_party/WebKit/Source/modules/webgl/WebGLRenderingContextBase.h index c2862a9..9527dd8 100644 --- a/third_party/WebKit/Source/modules/webgl/WebGLRenderingContextBase.h +++ b/third_party/WebKit/Source/modules/webgl/WebGLRenderingContextBase.h
@@ -70,6 +70,7 @@ class ExceptionState; class HTMLImageElement; class HTMLVideoElement; +class ImageBitmap; class ImageBuffer; class ImageData; class IntSize; @@ -301,6 +302,8 @@ GLenum format, GLenum type, HTMLCanvasElement*, ExceptionState&); void texImage2D(GLenum target, GLint level, GLenum internalformat, GLenum format, GLenum type, HTMLVideoElement*, ExceptionState&); + void texImage2D(GLenum target, GLint level, GLenum internalformat, + GLenum format, GLenum type, PassRefPtrWillBeRawPtr<ImageBitmap>); void texParameterf(GLenum target, GLenum pname, GLfloat param); void texParameteri(GLenum target, GLenum pname, GLint param); @@ -316,6 +319,8 @@ GLenum format, GLenum type, HTMLCanvasElement*, ExceptionState&); void texSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLenum format, GLenum type, HTMLVideoElement*, ExceptionState&); + void texSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset, + GLenum format, GLenum type, PassRefPtrWillBeRawPtr<ImageBitmap>); void uniform1f(const WebGLUniformLocation*, GLfloat x); void uniform1fv(const WebGLUniformLocation*, const FlexibleFloat32ArrayView&); @@ -498,6 +503,8 @@ WebGLRenderbuffer* ensureEmulatedStencilBuffer(GLenum target, WebGLRenderbuffer*); + virtual const WebGLSamplerState* getTextureUnitSamplerState(GLenum target, GLuint unit) const; + // Structure for rendering to a DrawingBuffer, instead of directly // to the back-buffer of m_context. RefPtr<DrawingBuffer> m_drawingBuffer; @@ -916,6 +923,7 @@ SourceHTMLImageElement, SourceHTMLCanvasElement, SourceHTMLVideoElement, + SourceImageBitmap, }; // Helper function for tex{Sub}Image2D to check if the input format/type/level/target/width/height/border/xoffset/yoffset are valid.
diff --git a/third_party/WebKit/Source/modules/webgl/WebGLRenderingContextBase.idl b/third_party/WebKit/Source/modules/webgl/WebGLRenderingContextBase.idl index 77b4600..03df3622 100644 --- a/third_party/WebKit/Source/modules/webgl/WebGLRenderingContextBase.idl +++ b/third_party/WebKit/Source/modules/webgl/WebGLRenderingContextBase.idl
@@ -631,6 +631,9 @@ [RaisesException] void texImage2D( GLenum target, GLint level, GLenum internalformat, GLenum format, GLenum type, HTMLVideoElement video); + [RuntimeEnabled=ExperimentalCanvasFeatures] void texImage2D( + GLenum target, GLint level, GLenum internalformat, + GLenum format, GLenum type, ImageBitmap bitmap); void texSubImage2D( GLenum target, GLint level, GLint xoffset, GLint yoffset, @@ -648,6 +651,9 @@ [RaisesException] void texSubImage2D( GLenum target, GLint level, GLint xoffset, GLint yoffset, GLenum format, GLenum type, HTMLVideoElement video); + [RuntimeEnabled=ExperimentalCanvasFeatures] void texSubImage2D( + GLenum target, GLint level, GLint xoffset, GLint yoffset, + GLenum format, GLenum type, ImageBitmap bitmap); void uniform1f(WebGLUniformLocation? location, GLfloat x); void uniform1fv(WebGLUniformLocation? location, [FlexibleArrayBufferView] Float32Array v);
diff --git a/third_party/WebKit/Source/modules/webgl/WebGLSampler.cpp b/third_party/WebKit/Source/modules/webgl/WebGLSampler.cpp index cc8958f..95688a0 100644 --- a/third_party/WebKit/Source/modules/webgl/WebGLSampler.cpp +++ b/third_party/WebKit/Source/modules/webgl/WebGLSampler.cpp
@@ -10,6 +10,19 @@ namespace blink { +WebGLSamplerState::WebGLSamplerState() + : compreFunc(GL_LEQUAL) + , compreMode(GL_NONE) + , magFilter(GL_LINEAR) + , minFilter(GL_NEAREST_MIPMAP_LINEAR) + , wrapR(GL_REPEAT) + , wrapS(GL_REPEAT) + , wrapT(GL_REPEAT) + , maxLod(1000.0f) + , minLod(-1000.0f) +{ +} + WebGLSampler* WebGLSampler::create(WebGL2RenderingContextBase* ctx) { return new WebGLSampler(ctx); @@ -23,15 +36,6 @@ WebGLSampler::WebGLSampler(WebGL2RenderingContextBase* ctx) : WebGLSharedPlatform3DObject(ctx) - , m_compreFunc(GL_LEQUAL) - , m_compreMode(GL_NONE) - , m_magFilter(GL_LINEAR) - , m_minFilter(GL_NEAREST_MIPMAP_LINEAR) - , m_wrapR(GL_REPEAT) - , m_wrapS(GL_REPEAT) - , m_wrapT(GL_REPEAT) - , m_maxLod(1000.0f) - , m_minLod(-1000.0f) { setObject(ctx->webContext()->createSampler()); } @@ -55,25 +59,25 @@ return; } case GL_TEXTURE_COMPARE_FUNC: - m_compreFunc = param; + m_state.compreFunc = param; break; case GL_TEXTURE_COMPARE_MODE: - m_compreMode = param; + m_state.compreMode = param; break; case GL_TEXTURE_MAG_FILTER: - m_magFilter = param; + m_state.magFilter = param; break; case GL_TEXTURE_MIN_FILTER: - m_minFilter = param; + m_state.minFilter = param; break; case GL_TEXTURE_WRAP_R: - m_wrapR = param; + m_state.wrapR = param; break; case GL_TEXTURE_WRAP_S: - m_wrapS = param; + m_state.wrapS = param; break; case GL_TEXTURE_WRAP_T: - m_wrapT = param; + m_state.wrapT = param; break; default: ASSERT_NOT_REACHED(); @@ -99,10 +103,10 @@ return; } case GL_TEXTURE_MAX_LOD: - m_maxLod = param; + m_state.maxLod = param; break; case GL_TEXTURE_MIN_LOD: - m_minLod = param; + m_state.minLod = param; break; default: ASSERT_NOT_REACHED();
diff --git a/third_party/WebKit/Source/modules/webgl/WebGLSampler.h b/third_party/WebKit/Source/modules/webgl/WebGLSampler.h index 7a5f1792..167549b 100644 --- a/third_party/WebKit/Source/modules/webgl/WebGLSampler.h +++ b/third_party/WebKit/Source/modules/webgl/WebGLSampler.h
@@ -6,6 +6,7 @@ #define WebGLSampler_h #include "modules/webgl/WebGLSharedPlatform3DObject.h" +#include "modules/webgl/WebGLTexture.h" namespace blink { @@ -20,15 +21,17 @@ void setParameteri(GLenum pname, GLint param); void setParameterf(GLenum pname, GLfloat param); - GLenum getCompareFunc() const { return m_compreFunc; } - GLenum getCompareMode() const { return m_compreMode; } - GLenum getMagFilter() const { return m_magFilter; } - GLenum getMinFilter() const { return m_minFilter; } - GLenum getWrapR() const { return m_wrapR; } - GLenum getWrapS() const { return m_wrapS; } - GLenum getWrapT() const { return m_wrapT; } - GLfloat getMaxLod() const { return m_maxLod; } - GLfloat getMinLod() const { return m_minLod; } + GLenum getCompareFunc() const { return m_state.compreFunc; } + GLenum getCompareMode() const { return m_state.compreMode; } + GLenum getMagFilter() const { return m_state.magFilter; } + GLenum getMinFilter() const { return m_state.minFilter; } + GLenum getWrapR() const { return m_state.wrapR; } + GLenum getWrapS() const { return m_state.wrapS; } + GLenum getWrapT() const { return m_state.wrapT; } + GLfloat getMaxLod() const { return m_state.maxLod; } + GLfloat getMinLod() const { return m_state.minLod; } + + const WebGLSamplerState* getSamplerState() const { return &m_state; } protected: explicit WebGLSampler(WebGL2RenderingContextBase*); @@ -38,15 +41,7 @@ private: bool isSampler() const override { return true; } - GLenum m_compreFunc; - GLenum m_compreMode; - GLenum m_magFilter; - GLenum m_minFilter; - GLenum m_wrapR; - GLenum m_wrapS; - GLenum m_wrapT; - GLfloat m_maxLod; - GLfloat m_minLod; + WebGLSamplerState m_state; }; } // namespace blink
diff --git a/third_party/WebKit/Source/modules/webgl/WebGLTexture.cpp b/third_party/WebKit/Source/modules/webgl/WebGLTexture.cpp index 80d5bd1..3b497766 100644 --- a/third_party/WebKit/Source/modules/webgl/WebGLTexture.cpp +++ b/third_party/WebKit/Source/modules/webgl/WebGLTexture.cpp
@@ -39,11 +39,6 @@ WebGLTexture::WebGLTexture(WebGLRenderingContextBase* ctx) : WebGLSharedPlatform3DObject(ctx) , m_target(0) - , m_minFilter(GL_NEAREST_MIPMAP_LINEAR) - , m_magFilter(GL_LINEAR) - , m_wrapR(GL_REPEAT) - , m_wrapS(GL_REPEAT) - , m_wrapT(GL_REPEAT) , m_isNPOT(false) , m_isCubeComplete(false) , m_isComplete(false) @@ -101,7 +96,7 @@ case GL_LINEAR_MIPMAP_NEAREST: case GL_NEAREST_MIPMAP_LINEAR: case GL_LINEAR_MIPMAP_LINEAR: - m_minFilter = param; + m_samplerState.minFilter = param; break; } break; @@ -109,7 +104,7 @@ switch (param) { case GL_NEAREST: case GL_LINEAR: - m_magFilter = param; + m_samplerState.magFilter = param; break; } break; @@ -118,7 +113,7 @@ case GL_CLAMP_TO_EDGE: case GL_MIRRORED_REPEAT: case GL_REPEAT: - m_wrapR = param; + m_samplerState.wrapR = param; break; } break; @@ -127,7 +122,7 @@ case GL_CLAMP_TO_EDGE: case GL_MIRRORED_REPEAT: case GL_REPEAT: - m_wrapS = param; + m_samplerState.wrapS = param; break; } break; @@ -136,7 +131,7 @@ case GL_CLAMP_TO_EDGE: case GL_MIRRORED_REPEAT: case GL_REPEAT: - m_wrapT = param; + m_samplerState.wrapT = param; break; } break; @@ -303,14 +298,15 @@ return m_isNPOT; } -bool WebGLTexture::needToUseBlackTexture(TextureExtensionFlag flag) const +bool WebGLTexture::needToUseBlackTexture(TextureExtensionFlag flag, const WebGLSamplerState* samplerState) const { + ASSERT(samplerState); if (!object()) return false; if (m_needToUseBlackTexture) return true; if ((m_isFloatType && !(flag & TextureFloatLinearExtensionEnabled)) || (m_isHalfFloatType && !(flag && TextureHalfFloatLinearExtensionEnabled))) { - if (m_magFilter != GL_NEAREST || (m_minFilter != GL_NEAREST && m_minFilter != GL_NEAREST_MIPMAP_NEAREST)) + if (samplerState->magFilter != GL_NEAREST || (samplerState->minFilter != GL_NEAREST && samplerState->minFilter != GL_NEAREST_MIPMAP_NEAREST)) return true; } return false; @@ -445,16 +441,19 @@ m_isHalfFloatType = m_info[0][0].type == GL_HALF_FLOAT_OES; m_needToUseBlackTexture = false; - // NPOT - if (!m_isWebGL2OrHigher && m_isNPOT && ((m_minFilter != GL_NEAREST && m_minFilter != GL_LINEAR) - || m_wrapS != GL_CLAMP_TO_EDGE || m_wrapT != GL_CLAMP_TO_EDGE || (m_target == GL_TEXTURE_3D && m_wrapR != GL_CLAMP_TO_EDGE))) - m_needToUseBlackTexture = true; // If it is a Cube texture, check Cube Completeness first if (m_info.size() > 1 && !m_isCubeComplete) m_needToUseBlackTexture = true; - // Completeness - if (!m_isComplete && m_minFilter != GL_NEAREST && m_minFilter != GL_LINEAR) - m_needToUseBlackTexture = true; + if (!m_isWebGL2OrHigher) { + // We can do these checks up front in WebGL 1 because there's no separate samplers. + // NPOT + if (m_isNPOT && ((m_samplerState.minFilter != GL_NEAREST && m_samplerState.minFilter != GL_LINEAR) + || m_samplerState.wrapS != GL_CLAMP_TO_EDGE || m_samplerState.wrapT != GL_CLAMP_TO_EDGE)) + m_needToUseBlackTexture = true; + // Completeness + if (!m_isComplete && m_samplerState.minFilter != GL_NEAREST && m_samplerState.minFilter != GL_LINEAR) + m_needToUseBlackTexture = true; + } } const WebGLTexture::LevelInfo* WebGLTexture::getLevelInfo(GLenum target, GLint level) const
diff --git a/third_party/WebKit/Source/modules/webgl/WebGLTexture.h b/third_party/WebKit/Source/modules/webgl/WebGLTexture.h index 8c0b749f..b1fbaf26 100644 --- a/third_party/WebKit/Source/modules/webgl/WebGLTexture.h +++ b/third_party/WebKit/Source/modules/webgl/WebGLTexture.h
@@ -31,6 +31,20 @@ namespace blink { +struct WebGLSamplerState { + WebGLSamplerState(); + + GLenum compreFunc; + GLenum compreMode; + GLenum magFilter; + GLenum minFilter; + GLenum wrapR; + GLenum wrapS; + GLenum wrapT; + GLfloat maxLod; + GLfloat minLod; +}; + class WebGLTexture final : public WebGLSharedPlatform3DObject { DEFINE_WRAPPERTYPEINFO(); public: @@ -49,7 +63,7 @@ GLenum getTarget() const { return m_target; } - int getMinFilter() const { return m_minFilter; } + int getMinFilter() const { return m_samplerState.minFilter; } void setLevelInfo(GLenum target, GLint level, GLenum internalFormat, GLsizei width, GLsizei height, GLsizei depth, GLenum type); void setTexStorageInfo(GLenum target, GLint levels, GLenum internalFormat, GLsizei width, GLsizei height, GLsizei depth); @@ -75,13 +89,15 @@ bool isNPOT() const; // Determine if texture sampling should always return [0, 0, 0, 1] (OpenGL ES 2.0 Sec 3.8.2). - bool needToUseBlackTexture(TextureExtensionFlag) const; + bool needToUseBlackTexture(TextureExtensionFlag, const WebGLSamplerState*) const; bool hasEverBeenBound() const { return object() && m_target; } static GLint computeLevelCount(GLsizei width, GLsizei height, GLsizei depth); static GLenum getValidTypeForInternalFormat(GLenum); + const WebGLSamplerState* getSamplerState() const { return &m_samplerState; } + private: explicit WebGLTexture(WebGLRenderingContextBase*); @@ -127,11 +143,7 @@ GLenum m_target; - GLenum m_minFilter; - GLenum m_magFilter; - GLenum m_wrapR; - GLenum m_wrapS; - GLenum m_wrapT; + WebGLSamplerState m_samplerState; Vector<Vector<LevelInfo>> m_info;
diff --git a/third_party/WebKit/Source/platform/BUILD.gn b/third_party/WebKit/Source/platform/BUILD.gn index c59f6534..1242951 100644 --- a/third_party/WebKit/Source/platform/BUILD.gn +++ b/third_party/WebKit/Source/platform/BUILD.gn
@@ -201,6 +201,7 @@ "//gpu/command_buffer/client:gles2_c_lib", "//skia", "//third_party:jpeg", + "//third_party/WebKit/Source/wtf", "//third_party/iccjpeg", "//third_party/libpng", "//third_party/libwebp", @@ -212,7 +213,6 @@ deps = [ ":make_platform_generated", "//third_party/WebKit/Source/platform/heap", - "//third_party/WebKit/Source/wtf", "//third_party/harfbuzz-ng", "//third_party/icu", "//ui/gfx/geometry",
diff --git a/third_party/WebKit/Source/platform/MemoryPurgeController.cpp b/third_party/WebKit/Source/platform/MemoryPurgeController.cpp index d00d9cc..3860e7e7 100644 --- a/third_party/WebKit/Source/platform/MemoryPurgeController.cpp +++ b/third_party/WebKit/Source/platform/MemoryPurgeController.cpp
@@ -9,13 +9,6 @@ #include "public/platform/Platform.h" #include "wtf/Partitions.h" -namespace { - -// TODO(bashi): Determine appropriate value for this interval. -const size_t kInactiveTimerIntervalInSecond = 10; - -} // namespace - namespace blink { DEFINE_TRACE(MemoryPurgeClient) @@ -24,7 +17,6 @@ MemoryPurgeController::MemoryPurgeController() : m_deviceKind(Platform::current()->isLowEndDeviceMode() ? DeviceKind::LowEnd : DeviceKind::NotSpecified) - , m_inactiveTimer(this, &MemoryPurgeController::pageInactiveTask) { } @@ -32,37 +24,12 @@ { } -void MemoryPurgeController::pageBecameActive() +void MemoryPurgeController::purgeMemory() { - m_inactiveTimer.stop(); -} - -void MemoryPurgeController::pageBecameInactive() -{ - if (!m_inactiveTimer.isActive()) - m_inactiveTimer.startOneShot(kInactiveTimerIntervalInSecond, BLINK_FROM_HERE); -} - -void MemoryPurgeController::pageInactiveTask(Timer<MemoryPurgeController>*) -{ - static const size_t maxSizeInKB = 10 * 1024; - - size_t totalSizeBefore = WTF::Partitions::totalSizeOfCommittedPages(); - purgeMemory(MemoryPurgeMode::InactiveTab); - size_t totalSizeAfter = WTF::Partitions::totalSizeOfCommittedPages(); - if (totalSizeAfter >= totalSizeBefore) - return; - size_t reclaimedInKB = (totalSizeBefore - totalSizeAfter) / 1024 + 1; - if (reclaimedInKB >= maxSizeInKB) - reclaimedInKB = maxSizeInKB - 1; - Platform::current()->histogramCustomCounts("MemoryPurgeController.ReclaimedPartitionAllocInactiveTab", reclaimedInKB, 1, maxSizeInKB, 50); -} - -void MemoryPurgeController::purgeMemory(MemoryPurgeMode purgeMode) -{ + // TODO(bashi): Add UMA TRACE_EVENT0("blink", "MemoryPurgeController::purgeMemory"); for (auto& client : m_clients) - client->purgeMemory(purgeMode, m_deviceKind); + client->purgeMemory(m_deviceKind); WTF::Partitions::decommitFreeableMemory(); }
diff --git a/third_party/WebKit/Source/platform/MemoryPurgeController.h b/third_party/WebKit/Source/platform/MemoryPurgeController.h index 9d10d8f2..59114b19 100644 --- a/third_party/WebKit/Source/platform/MemoryPurgeController.h +++ b/third_party/WebKit/Source/platform/MemoryPurgeController.h
@@ -12,12 +12,6 @@ namespace blink { -enum class MemoryPurgeMode { - // The tab contains the webview went to background - InactiveTab, - // TODO(bashi): Add more modes as needed. -}; - enum class DeviceKind { NotSpecified, LowEnd, @@ -33,7 +27,7 @@ // MemoryPurgeController invokes this callback when a memory purge event // has occurred. - virtual void purgeMemory(MemoryPurgeMode, DeviceKind) = 0; + virtual void purgeMemory(DeviceKind) = 0; DECLARE_VIRTUAL_TRACE(); }; @@ -44,6 +38,8 @@ // Page. class PLATFORM_EXPORT MemoryPurgeController final : public NoBaseWillBeGarbageCollectedFinalized<MemoryPurgeController> { public: + static void onMemoryPressure(); + static PassOwnPtrWillBeRawPtr<MemoryPurgeController> create() { return adoptPtrWillBeNoop(new MemoryPurgeController); @@ -66,20 +62,15 @@ m_clients.remove(client); } - void pageBecameActive(); - void pageBecameInactive(); - void pageInactiveTask(Timer<MemoryPurgeController>*); + void purgeMemory(); DECLARE_TRACE(); private: MemoryPurgeController(); - void purgeMemory(MemoryPurgeMode); - WillBeHeapHashSet<RawPtrWillBeWeakMember<MemoryPurgeClient>> m_clients; DeviceKind m_deviceKind; - Timer<MemoryPurgeController> m_inactiveTimer; }; } // namespace blink
diff --git a/third_party/WebKit/Source/platform/RuntimeEnabledFeatures.in b/third_party/WebKit/Source/platform/RuntimeEnabledFeatures.in index 491578c9..3cf385c 100644 --- a/third_party/WebKit/Source/platform/RuntimeEnabledFeatures.in +++ b/third_party/WebKit/Source/platform/RuntimeEnabledFeatures.in
@@ -44,6 +44,7 @@ CSSAttributeCaseSensitivity status=experimental CSSBackdropFilter status=experimental CSSCompositing status=stable +CSSContainment status=experimental CSSFontDisplay status=experimental CSSFontSizeAdjust status=experimental CSSGridLayout status=experimental @@ -137,8 +138,7 @@ PresentationReceiver status=test PromiseRejectionEvent status=stable PushMessaging status=stable -// Push messaging payloads are blocked on the Push API supporting encryption. -PushMessagingData status=test +PushMessagingData status=experimental QuotaPromise status=experimental ReducedReferrerGranularity RenderingPipelineThrottling status=experimental
diff --git a/third_party/WebKit/Source/platform/blink_platform.gypi b/third_party/WebKit/Source/platform/blink_platform.gypi index f0dbfe7..5d374e0 100644 --- a/third_party/WebKit/Source/platform/blink_platform.gypi +++ b/third_party/WebKit/Source/platform/blink_platform.gypi
@@ -1072,6 +1072,8 @@ 'testing/UnitTestHelpers.h', ], 'platform_test_support_files': [ + 'graphics/test/FakeGraphicsLayerFactory.cpp', + 'graphics/test/FakeGraphicsLayerFactory.h', 'testing/GeometryPrinters.cpp', 'testing/GeometryPrinters.h', 'testing/PaintPrinters.cpp',
diff --git a/third_party/WebKit/Source/platform/blink_platform_tests.gyp b/third_party/WebKit/Source/platform/blink_platform_tests.gyp index 0eef2e6..5305eeb 100644 --- a/third_party/WebKit/Source/platform/blink_platform_tests.gyp +++ b/third_party/WebKit/Source/platform/blink_platform_tests.gyp
@@ -120,11 +120,15 @@ 'type': 'static_library', 'dependencies': [ '../config.gyp:config', + '../wtf/wtf.gyp:wtf', 'blink_platform.gyp:blink_platform', ], 'defines': [ 'INSIDE_BLINK', ], + 'include_dirs': [ + '<(SHARED_INTERMEDIATE_DIR)/blink', + ], 'sources': [ '<@(platform_test_support_files)', ],
diff --git a/third_party/WebKit/Source/platform/exported/WebMediaConstraints.cpp b/third_party/WebKit/Source/platform/exported/WebMediaConstraints.cpp index 6e617b5c..96f5e381 100644 --- a/third_party/WebKit/Source/platform/exported/WebMediaConstraints.cpp +++ b/third_party/WebKit/Source/platform/exported/WebMediaConstraints.cpp
@@ -42,6 +42,7 @@ static PassRefPtr<WebMediaConstraintsPrivate> create(); static PassRefPtr<WebMediaConstraintsPrivate> create(const WebVector<WebMediaConstraint>& optional, const WebVector<WebMediaConstraint>& mandatory); + bool isEmpty() const; void getOptionalConstraints(WebVector<WebMediaConstraint>&); void getMandatoryConstraints(WebVector<WebMediaConstraint>&); bool getMandatoryConstraintValue(const WebString& name, WebString& value); @@ -72,6 +73,11 @@ { } +bool WebMediaConstraintsPrivate::isEmpty() const +{ + return m_optional.isEmpty() && m_mandatory.isEmpty(); +} + void WebMediaConstraintsPrivate::getOptionalConstraints(WebVector<WebMediaConstraint>& constraints) { constraints = m_optional; @@ -116,6 +122,11 @@ m_private.reset(); } +bool WebMediaConstraints::isEmpty() const +{ + return m_private.isNull() || m_private->isEmpty(); +} + void WebMediaConstraints::getMandatoryConstraints(WebVector<WebMediaConstraint>& constraints) const { ASSERT(!isNull());
diff --git a/third_party/WebKit/Source/platform/graphics/test/FakeGraphicsLayerFactory.cpp b/third_party/WebKit/Source/platform/graphics/test/FakeGraphicsLayerFactory.cpp new file mode 100644 index 0000000..5039db3 --- /dev/null +++ b/third_party/WebKit/Source/platform/graphics/test/FakeGraphicsLayerFactory.cpp
@@ -0,0 +1,30 @@ +// 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. + +#include "config.h" +#include "platform/graphics/test/FakeGraphicsLayerFactory.h" + +#include "platform/graphics/GraphicsLayer.h" +#include "wtf/PassOwnPtr.h" +#include "wtf/StdLibExtras.h" + +namespace blink { + +FakeGraphicsLayerFactory::FakeGraphicsLayerFactory() +{ +} + +// static +FakeGraphicsLayerFactory* FakeGraphicsLayerFactory::instance() +{ + DEFINE_STATIC_LOCAL(FakeGraphicsLayerFactory, factory, ()); + return &factory; +} + +PassOwnPtr<GraphicsLayer> FakeGraphicsLayerFactory::createGraphicsLayer(GraphicsLayerClient* client) +{ + return adoptPtr(new GraphicsLayer(client)); +} + +} // namespace blink
diff --git a/third_party/WebKit/Source/platform/graphics/test/FakeGraphicsLayerFactory.h b/third_party/WebKit/Source/platform/graphics/test/FakeGraphicsLayerFactory.h new file mode 100644 index 0000000..4cf0463 --- /dev/null +++ b/third_party/WebKit/Source/platform/graphics/test/FakeGraphicsLayerFactory.h
@@ -0,0 +1,25 @@ +// 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. + +#ifndef FakeGraphicsLayerFactory_h +#define FakeGraphicsLayerFactory_h + +#include "platform/graphics/GraphicsLayerFactory.h" + +namespace blink { + +class FakeGraphicsLayerFactory : public GraphicsLayerFactory { +public: + static FakeGraphicsLayerFactory* instance(); + + // GraphicsLayerFactory + PassOwnPtr<GraphicsLayer> createGraphicsLayer(GraphicsLayerClient*) override; + +private: + FakeGraphicsLayerFactory(); +}; + +} // namespace blink + +#endif // FakeGraphicsLayerFactory_h
diff --git a/third_party/WebKit/Source/platform/mac/ScrollAnimatorMac.h b/third_party/WebKit/Source/platform/mac/ScrollAnimatorMac.h index e324f1b..b8665e48 100644 --- a/third_party/WebKit/Source/platform/mac/ScrollAnimatorMac.h +++ b/third_party/WebKit/Source/platform/mac/ScrollAnimatorMac.h
@@ -30,6 +30,7 @@ #include "platform/geometry/FloatPoint.h" #include "platform/geometry/FloatSize.h" #include "platform/geometry/IntRect.h" +#include "platform/heap/Handle.h" #include "platform/scroll/ScrollAnimatorBase.h" #include "wtf/RetainPtr.h" @@ -44,11 +45,13 @@ class Scrollbar; class PLATFORM_EXPORT ScrollAnimatorMac : public ScrollAnimatorBase { - + WILL_BE_USING_PRE_FINALIZER(ScrollAnimatorMac, dispose); public: ScrollAnimatorMac(ScrollableArea*); ~ScrollAnimatorMac() override; + void dispose() override; + void immediateScrollToPointForScrollAnimation(const FloatPoint& newPosition); bool haveScrolledSincePageLoad() const { return m_haveScrolledSincePageLoad; } @@ -64,6 +67,11 @@ static bool canUseCoordinatedScrollbar(); + DEFINE_INLINE_VIRTUAL_TRACE() + { + ScrollAnimatorBase::trace(visitor); + } + private: RetainPtr<id> m_scrollAnimationHelper; RetainPtr<WebScrollAnimationHelperDelegate> m_scrollAnimationHelperDelegate;
diff --git a/third_party/WebKit/Source/platform/mac/ScrollAnimatorMac.mm b/third_party/WebKit/Source/platform/mac/ScrollAnimatorMac.mm index af0ba67..fb411cf 100644 --- a/third_party/WebKit/Source/platform/mac/ScrollAnimatorMac.mm +++ b/third_party/WebKit/Source/platform/mac/ScrollAnimatorMac.mm
@@ -679,9 +679,9 @@ namespace blink { -PassOwnPtr<ScrollAnimatorBase> ScrollAnimatorBase::create(ScrollableArea* scrollableArea) +PassOwnPtrWillBeRawPtr<ScrollAnimatorBase> ScrollAnimatorBase::create(ScrollableArea* scrollableArea) { - return adoptPtr(new ScrollAnimatorMac(scrollableArea)); + return adoptPtrWillBeNoop(new ScrollAnimatorMac(scrollableArea)); } ScrollAnimatorMac::ScrollAnimatorMac(ScrollableArea* scrollableArea) @@ -691,6 +691,10 @@ , m_haveScrolledSincePageLoad(false) , m_needsScrollerStyleUpdate(false) { +#if ENABLE(OILPAN) + ThreadState::current()->registerPreFinalizer(this); +#endif + m_scrollAnimationHelperDelegate.adoptNS([[WebScrollAnimationHelperDelegate alloc] initWithScrollAnimator:this]); m_scrollAnimationHelper.adoptNS([[NSClassFromString(@"NSScrollAnimationHelper") alloc] initWithDelegate:m_scrollAnimationHelperDelegate.get()]); @@ -704,6 +708,13 @@ ScrollAnimatorMac::~ScrollAnimatorMac() { +#if !ENABLE(OILPAN) + dispose(); +#endif +} + +void ScrollAnimatorMac::dispose() +{ if (ScrollbarThemeMacCommon::isOverlayAPIAvailable()) { BEGIN_BLOCK_OBJC_EXCEPTIONS; [m_scrollbarPainterControllerDelegate.get() invalidate]; @@ -713,6 +724,8 @@ [m_scrollAnimationHelperDelegate.get() invalidate]; END_BLOCK_OBJC_EXCEPTIONS; } + m_initialScrollbarPaintTimer.stop(); + m_sendContentAreaScrolledTimer.stop(); } ScrollResultOneDimensional ScrollAnimatorMac::userScroll(ScrollbarOrientation orientation, ScrollGranularity granularity, float step, float delta)
diff --git a/third_party/WebKit/Source/platform/scroll/ProgrammaticScrollAnimator.cpp b/third_party/WebKit/Source/platform/scroll/ProgrammaticScrollAnimator.cpp index 4e4099a..2b807d0 100644 --- a/third_party/WebKit/Source/platform/scroll/ProgrammaticScrollAnimator.cpp +++ b/third_party/WebKit/Source/platform/scroll/ProgrammaticScrollAnimator.cpp
@@ -18,9 +18,9 @@ namespace blink { -PassOwnPtr<ProgrammaticScrollAnimator> ProgrammaticScrollAnimator::create(ScrollableArea* scrollableArea) +PassOwnPtrWillBeRawPtr<ProgrammaticScrollAnimator> ProgrammaticScrollAnimator::create(ScrollableArea* scrollableArea) { - return adoptPtr(new ProgrammaticScrollAnimator(scrollableArea)); + return adoptPtrWillBeNoop(new ProgrammaticScrollAnimator(scrollableArea)); } ProgrammaticScrollAnimator::ProgrammaticScrollAnimator(ScrollableArea* scrollableArea) @@ -289,4 +289,9 @@ return m_compositorPlayer.get(); } +DEFINE_TRACE(ProgrammaticScrollAnimator) +{ + visitor->trace(m_scrollableArea); +} + } // namespace blink
diff --git a/third_party/WebKit/Source/platform/scroll/ProgrammaticScrollAnimator.h b/third_party/WebKit/Source/platform/scroll/ProgrammaticScrollAnimator.h index ef6286a..d45cd66 100644 --- a/third_party/WebKit/Source/platform/scroll/ProgrammaticScrollAnimator.h +++ b/third_party/WebKit/Source/platform/scroll/ProgrammaticScrollAnimator.h
@@ -23,13 +23,13 @@ // Animator for fixed-destination scrolls, such as those triggered by // CSSOM View scroll APIs. -class ProgrammaticScrollAnimator : private WebCompositorAnimationPlayerClient, WebCompositorAnimationDelegate { +class ProgrammaticScrollAnimator : public NoBaseWillBeGarbageCollectedFinalized<ProgrammaticScrollAnimator>, private WebCompositorAnimationPlayerClient, WebCompositorAnimationDelegate { WTF_MAKE_NONCOPYABLE(ProgrammaticScrollAnimator); - USING_FAST_MALLOC(ProgrammaticScrollAnimator); + USING_FAST_MALLOC_WILL_BE_REMOVED(ProgrammaticScrollAnimator); public: - static PassOwnPtr<ProgrammaticScrollAnimator> create(ScrollableArea*); + static PassOwnPtrWillBeRawPtr<ProgrammaticScrollAnimator> create(ScrollableArea*); - ~ProgrammaticScrollAnimator(); + virtual ~ProgrammaticScrollAnimator(); void scrollToOffsetWithoutAnimation(const FloatPoint&); void animateToOffset(FloatPoint); @@ -46,6 +46,8 @@ // WebCompositorAnimationPlayerClient implementation. WebCompositorAnimationPlayer* compositorPlayer() const override; + DECLARE_TRACE(); + private: explicit ProgrammaticScrollAnimator(ScrollableArea*); @@ -76,8 +78,7 @@ OwnPtr<WebCompositorAnimationPlayer> m_compositorPlayer; int m_compositorAnimationAttachedToLayerId; - GC_PLUGIN_IGNORE("509911") - ScrollableArea* m_scrollableArea; + RawPtrWillBeMember<ScrollableArea> m_scrollableArea; OwnPtr<WebScrollOffsetAnimationCurve> m_animationCurve; FloatPoint m_targetOffset; double m_startTime;
diff --git a/third_party/WebKit/Source/platform/scroll/ScrollAnimator.cpp b/third_party/WebKit/Source/platform/scroll/ScrollAnimator.cpp index a01daa2..a6dc9bff 100644 --- a/third_party/WebKit/Source/platform/scroll/ScrollAnimator.cpp +++ b/third_party/WebKit/Source/platform/scroll/ScrollAnimator.cpp
@@ -41,11 +41,11 @@ namespace blink { -PassOwnPtr<ScrollAnimatorBase> ScrollAnimatorBase::create(ScrollableArea* scrollableArea) +PassOwnPtrWillBeRawPtr<ScrollAnimatorBase> ScrollAnimatorBase::create(ScrollableArea* scrollableArea) { if (scrollableArea && scrollableArea->scrollAnimatorEnabled()) - return adoptPtr(new ScrollAnimator(scrollableArea)); - return adoptPtr(new ScrollAnimatorBase(scrollableArea)); + return adoptPtrWillBeNoop(new ScrollAnimator(scrollableArea)); + return adoptPtrWillBeNoop(new ScrollAnimatorBase(scrollableArea)); } ScrollAnimator::ScrollAnimator(ScrollableArea* scrollableArea, WTF::TimeFunction timeFunction) @@ -150,4 +150,9 @@ notifyPositionChanged(); } +DEFINE_TRACE(ScrollAnimator) +{ + ScrollAnimatorBase::trace(visitor); +} + } // namespace blink
diff --git a/third_party/WebKit/Source/platform/scroll/ScrollAnimator.h b/third_party/WebKit/Source/platform/scroll/ScrollAnimator.h index ae84f9c..257f734 100644 --- a/third_party/WebKit/Source/platform/scroll/ScrollAnimator.h +++ b/third_party/WebKit/Source/platform/scroll/ScrollAnimator.h
@@ -40,7 +40,7 @@ class ScrollAnimatorTest; -class PLATFORM_EXPORT ScrollAnimator : public ScrollAnimatorBase { +class PLATFORM_EXPORT ScrollAnimator final : public ScrollAnimatorBase { public: explicit ScrollAnimator(ScrollableArea*, WTF::TimeFunction = WTF::monotonicallyIncreasingTime); ~ScrollAnimator() override; @@ -52,6 +52,8 @@ void serviceScrollAnimations() override; bool hasRunningAnimation() const override; + DECLARE_VIRTUAL_TRACE(); + protected: void animationTimerFired();
diff --git a/third_party/WebKit/Source/platform/scroll/ScrollAnimatorBase.cpp b/third_party/WebKit/Source/platform/scroll/ScrollAnimatorBase.cpp index 8971694d..78d359c 100644 --- a/third_party/WebKit/Source/platform/scroll/ScrollAnimatorBase.cpp +++ b/third_party/WebKit/Source/platform/scroll/ScrollAnimatorBase.cpp
@@ -95,4 +95,9 @@ return std::max(std::min(pos, maxScrollPos), minScrollPos); } +DEFINE_TRACE(ScrollAnimatorBase) +{ + visitor->trace(m_scrollableArea); +} + } // namespace blink
diff --git a/third_party/WebKit/Source/platform/scroll/ScrollAnimatorBase.h b/third_party/WebKit/Source/platform/scroll/ScrollAnimatorBase.h index 0917eea..0a561831 100644 --- a/third_party/WebKit/Source/platform/scroll/ScrollAnimatorBase.h +++ b/third_party/WebKit/Source/platform/scroll/ScrollAnimatorBase.h
@@ -44,12 +44,14 @@ class ScrollableArea; class Scrollbar; -class PLATFORM_EXPORT ScrollAnimatorBase { +class PLATFORM_EXPORT ScrollAnimatorBase : public NoBaseWillBeGarbageCollectedFinalized<ScrollAnimatorBase> { public: - static PassOwnPtr<ScrollAnimatorBase> create(ScrollableArea*); + static PassOwnPtrWillBeRawPtr<ScrollAnimatorBase> create(ScrollableArea*); virtual ~ScrollAnimatorBase(); + virtual void dispose() { } + // Computes a scroll destination for the given parameters. The returned // ScrollResultOneDimensional will have didScroll set to false if already at // the destination. Otherwise, starts scrolling towards the destination and @@ -99,13 +101,15 @@ virtual void notifyContentAreaScrolled(const FloatSize&) { } virtual bool setScrollbarsVisibleForTesting(bool) { return false; } + + DECLARE_VIRTUAL_TRACE(); + protected: explicit ScrollAnimatorBase(ScrollableArea*); virtual void notifyPositionChanged(); - GC_PLUGIN_IGNORE("509911") - ScrollableArea* m_scrollableArea; + RawPtrWillBeMember<ScrollableArea> m_scrollableArea; float m_currentPosX; // We avoid using a FloatPoint in order to reduce float m_currentPosY; // subclass code complexity.
diff --git a/third_party/WebKit/Source/platform/scroll/ScrollAnimatorTest.cpp b/third_party/WebKit/Source/platform/scroll/ScrollAnimatorTest.cpp index 310b11dd..70d1e47 100644 --- a/third_party/WebKit/Source/platform/scroll/ScrollAnimatorTest.cpp +++ b/third_party/WebKit/Source/platform/scroll/ScrollAnimatorTest.cpp
@@ -104,7 +104,7 @@ TEST(ScrollAnimatorTest, Enabled) { OwnPtrWillBeRawPtr<MockScrollableArea> scrollableArea = MockScrollableArea::create(true); - OwnPtr<ScrollAnimator> scrollAnimator = adoptPtr(new ScrollAnimator(scrollableArea.get(), getMockedTime)); + OwnPtrWillBeRawPtr<ScrollAnimator> scrollAnimator = adoptPtrWillBeNoop(new ScrollAnimator(scrollableArea.get(), getMockedTime)); EXPECT_CALL(*scrollableArea, minimumScrollPosition()).Times(AtLeast(1)).WillRepeatedly(Return(IntPoint())); EXPECT_CALL(*scrollableArea, maximumScrollPosition()).Times(AtLeast(1)).WillRepeatedly(Return(IntPoint(1000, 1000))); @@ -172,7 +172,7 @@ TEST(ScrollAnimatorTest, Disabled) { OwnPtrWillBeRawPtr<MockScrollableArea> scrollableArea = MockScrollableArea::create(false); - OwnPtr<ScrollAnimator> scrollAnimator = adoptPtr(new ScrollAnimator(scrollableArea.get(), getMockedTime)); + OwnPtrWillBeRawPtr<ScrollAnimator> scrollAnimator = adoptPtrWillBeNoop(new ScrollAnimator(scrollableArea.get(), getMockedTime)); EXPECT_CALL(*scrollableArea, minimumScrollPosition()).Times(AtLeast(1)).WillRepeatedly(Return(IntPoint())); EXPECT_CALL(*scrollableArea, maximumScrollPosition()).Times(AtLeast(1)).WillRepeatedly(Return(IntPoint(1000, 1000)));
diff --git a/third_party/WebKit/Source/platform/scroll/ScrollableArea.cpp b/third_party/WebKit/Source/platform/scroll/ScrollableArea.cpp index 85016be..14086dc 100644 --- a/third_party/WebKit/Source/platform/scroll/ScrollableArea.cpp +++ b/third_party/WebKit/Source/platform/scroll/ScrollableArea.cpp
@@ -54,7 +54,7 @@ #if ENABLE(ASSERT) && ENABLE(OILPAN) VerifyEagerFinalization verifyEager; #endif - void* pointer; + OwnPtrWillBeMember<void*> pointer[2]; unsigned bitfields : 16; IntPoint origin; }; @@ -93,29 +93,28 @@ void ScrollableArea::clearScrollAnimators() { - m_animators.clear(); +#if OS(MACOSX) && ENABLE(OILPAN) + if (m_scrollAnimator) + m_scrollAnimator->dispose(); +#endif + m_scrollAnimator.clear(); + m_programmaticScrollAnimator.clear(); } ScrollAnimatorBase* ScrollableArea::scrollAnimator() const { - if (!m_animators) - m_animators = adoptPtr(new ScrollableAreaAnimators); + if (!m_scrollAnimator) + m_scrollAnimator = ScrollAnimatorBase::create(const_cast<ScrollableArea*>(this)); - if (!m_animators->scrollAnimator) - m_animators->scrollAnimator = ScrollAnimatorBase::create(const_cast<ScrollableArea*>(this)); - - return m_animators->scrollAnimator.get(); + return m_scrollAnimator.get(); } ProgrammaticScrollAnimator* ScrollableArea::programmaticScrollAnimator() const { - if (!m_animators) - m_animators = adoptPtr(new ScrollableAreaAnimators); + if (!m_programmaticScrollAnimator) + m_programmaticScrollAnimator = ProgrammaticScrollAnimator::create(const_cast<ScrollableArea*>(this)); - if (!m_animators->programmaticScrollAnimator) - m_animators->programmaticScrollAnimator = ProgrammaticScrollAnimator::create(const_cast<ScrollableArea*>(this)); - - return m_animators->programmaticScrollAnimator.get(); + return m_programmaticScrollAnimator.get(); } void ScrollableArea::setScrollOrigin(const IntPoint& origin) @@ -584,4 +583,10 @@ } +DEFINE_TRACE(ScrollableArea) +{ + visitor->trace(m_scrollAnimator); + visitor->trace(m_programmaticScrollAnimator); +} + } // namespace blink
diff --git a/third_party/WebKit/Source/platform/scroll/ScrollableArea.h b/third_party/WebKit/Source/platform/scroll/ScrollableArea.h index 390fea4..d643a1a 100644 --- a/third_party/WebKit/Source/platform/scroll/ScrollableArea.h +++ b/third_party/WebKit/Source/platform/scroll/ScrollableArea.h
@@ -126,13 +126,10 @@ ScrollAnimatorBase* scrollAnimator() const; // This getter will return null if the ScrollAnimatorBase hasn't been created yet. - ScrollAnimatorBase* existingScrollAnimator() const { return m_animators ? m_animators->scrollAnimator.get() : 0; } + ScrollAnimatorBase* existingScrollAnimator() const { return m_scrollAnimator.get(); } ProgrammaticScrollAnimator* programmaticScrollAnimator() const; - ProgrammaticScrollAnimator* existingProgrammaticScrollAnimator() const - { - return m_animators ? m_animators->programmaticScrollAnimator.get() : 0; - } + ProgrammaticScrollAnimator* existingProgrammaticScrollAnimator() const { return m_programmaticScrollAnimator.get(); } const IntPoint& scrollOrigin() const { return m_scrollOrigin; } bool scrollOriginChanged() const { return m_scrollOriginChanged; } @@ -278,7 +275,7 @@ // Need to promptly let go of owned animator objects. EAGERLY_FINALIZE(); - DEFINE_INLINE_VIRTUAL_TRACE() { } + DECLARE_VIRTUAL_TRACE(); protected: ScrollableArea(); @@ -325,12 +322,8 @@ virtual int documentStep(ScrollbarOrientation) const; virtual float pixelStep(ScrollbarOrientation) const; - struct ScrollableAreaAnimators { - OwnPtr<ScrollAnimatorBase> scrollAnimator; - OwnPtr<ProgrammaticScrollAnimator> programmaticScrollAnimator; - }; - - mutable OwnPtr<ScrollableAreaAnimators> m_animators; + mutable OwnPtrWillBeMember<ScrollAnimatorBase> m_scrollAnimator; + mutable OwnPtrWillBeMember<ProgrammaticScrollAnimator> m_programmaticScrollAnimator; unsigned m_inLiveResize : 1;
diff --git a/third_party/WebKit/Source/platform/text/TextCheckerClient.h b/third_party/WebKit/Source/platform/text/TextCheckerClient.h index dbdcee0..90743c3 100644 --- a/third_party/WebKit/Source/platform/text/TextCheckerClient.h +++ b/third_party/WebKit/Source/platform/text/TextCheckerClient.h
@@ -41,7 +41,6 @@ public: virtual ~TextCheckerClient() { } - virtual bool shouldEraseMarkersAfterChangeSelection(TextCheckingType) const = 0; virtual void checkSpellingOfString(const String&, int* misspellingLocation, int* misspellingLength) = 0; virtual void checkGrammarOfString(const String&, Vector<GrammarDetail>&, int* badGrammarLocation, int* badGrammarLength) = 0; virtual void requestCheckingOfString(PassRefPtrWillBeRawPtr<TextCheckingRequest>) = 0;
diff --git a/third_party/WebKit/Source/web/FrameLoaderClientImpl.cpp b/third_party/WebKit/Source/web/FrameLoaderClientImpl.cpp index 69945ad..19de8ca 100644 --- a/third_party/WebKit/Source/web/FrameLoaderClientImpl.cpp +++ b/third_party/WebKit/Source/web/FrameLoaderClientImpl.cpp
@@ -99,7 +99,6 @@ #include "web/WebDevToolsFrontendImpl.h" #include "web/WebLocalFrameImpl.h" #include "web/WebPluginContainerImpl.h" -#include "web/WebPluginLoadObserver.h" #include "web/WebViewImpl.h" #include "wtf/StringExtras.h" #include "wtf/text/CString.h" @@ -494,37 +493,17 @@ void FrameLoaderClientImpl::dispatchDidFailProvisionalLoad( const ResourceError& error, HistoryCommitType commitType) { - OwnPtrWillBeRawPtr<WebPluginLoadObserver> observer = pluginLoadObserver(m_webFrame->frame()->loader().provisionalDocumentLoader()); m_webFrame->didFail(error, true, commitType); - if (observer) - observer->didFailLoading(error); } void FrameLoaderClientImpl::dispatchDidFailLoad(const ResourceError& error, HistoryCommitType commitType) { - OwnPtrWillBeRawPtr<WebPluginLoadObserver> observer = pluginLoadObserver(m_webFrame->frame()->loader().documentLoader()); m_webFrame->didFail(error, false, commitType); - if (observer) - observer->didFailLoading(error); - - // Don't clear the redirect chain, this will happen in the middle of client - // redirects, and we need the context. The chain will be cleared when the - // provisional load succeeds or fails, not the "real" one. } void FrameLoaderClientImpl::dispatchDidFinishLoad() { - OwnPtrWillBeRawPtr<WebPluginLoadObserver> observer = pluginLoadObserver(m_webFrame->frame()->loader().documentLoader()); - - if (m_webFrame->client()) - m_webFrame->client()->didFinishLoad(m_webFrame); - - if (observer) - observer->didFinishLoading(); - - // Don't clear the redirect chain, this will happen in the middle of client - // redirects, and we need the context. The chain will be cleared when the - // provisional load succeeds or fails, not the "real" one. + m_webFrame->didFinish(); } void FrameLoaderClientImpl::dispatchDidChangeThemeColor() @@ -883,11 +862,6 @@ return ObjectContentNone; } -PassOwnPtrWillBeRawPtr<WebPluginLoadObserver> FrameLoaderClientImpl::pluginLoadObserver(DocumentLoader* loader) -{ - return WebDataSourceImpl::fromDocumentLoader(loader)->releasePluginLoadObserver(); -} - WebCookieJar* FrameLoaderClientImpl::cookieJar() const { if (!m_webFrame->client()) @@ -1001,12 +975,6 @@ return adoptPtr(m_webFrame->client()->createApplicationCacheHost(m_webFrame, client)); } -void FrameLoaderClientImpl::didStopAllLoaders() -{ - if (m_webFrame->client()) - m_webFrame->client()->didAbortLoading(m_webFrame); -} - void FrameLoaderClientImpl::dispatchDidChangeManifest() { if (m_webFrame->client())
diff --git a/third_party/WebKit/Source/web/FrameLoaderClientImpl.h b/third_party/WebKit/Source/web/FrameLoaderClientImpl.h index 3cdeabc4..360f5b00 100644 --- a/third_party/WebKit/Source/web/FrameLoaderClientImpl.h +++ b/third_party/WebKit/Source/web/FrameLoaderClientImpl.h
@@ -41,7 +41,6 @@ namespace blink { class WebLocalFrameImpl; -class WebPluginLoadObserver; class FrameLoaderClientImpl final : public FrameLoaderClient { public: @@ -171,8 +170,6 @@ PassOwnPtr<WebApplicationCacheHost> createApplicationCacheHost(WebApplicationCacheHostClient*) override; - void didStopAllLoaders() override; - void dispatchDidChangeManifest() override; unsigned backForwardLength() override; @@ -184,8 +181,6 @@ bool isFrameLoaderClientImpl() const override { return true; } - PassOwnPtrWillBeRawPtr<WebPluginLoadObserver> pluginLoadObserver(DocumentLoader*); - // The WebFrame that owns this object and manages its lifetime. Therefore, // the web frame object is guaranteed to exist. RawPtrWillBeMember<WebLocalFrameImpl> m_webFrame;
diff --git a/third_party/WebKit/Source/web/RemoteFrameClientImpl.cpp b/third_party/WebKit/Source/web/RemoteFrameClientImpl.cpp index 9250810..fde5147 100644 --- a/third_party/WebKit/Source/web/RemoteFrameClientImpl.cpp +++ b/third_party/WebKit/Source/web/RemoteFrameClientImpl.cpp
@@ -188,4 +188,9 @@ m_webFrame->client()->frameRectsChanged(frameRect); } +void RemoteFrameClientImpl::advanceFocus(WebFocusType type, LocalFrame* source) +{ + m_webFrame->client()->advanceFocus(type, WebLocalFrameImpl::fromFrame(source)); +} + } // namespace blink
diff --git a/third_party/WebKit/Source/web/RemoteFrameClientImpl.h b/third_party/WebKit/Source/web/RemoteFrameClientImpl.h index eb2342d8..388c808f 100644 --- a/third_party/WebKit/Source/web/RemoteFrameClientImpl.h +++ b/third_party/WebKit/Source/web/RemoteFrameClientImpl.h
@@ -36,6 +36,7 @@ unsigned backForwardLength() override; void forwardInputEvent(Event*) override; void frameRectsChanged(const IntRect& frameRect) override; + void advanceFocus(WebFocusType, LocalFrame*) override; WebRemoteFrameImpl* webFrame() const { return m_webFrame; }
diff --git a/third_party/WebKit/Source/web/SpellCheckerClientImpl.cpp b/third_party/WebKit/Source/web/SpellCheckerClientImpl.cpp index 342ae99..5d132f1a 100644 --- a/third_party/WebKit/Source/web/SpellCheckerClientImpl.cpp +++ b/third_party/WebKit/Source/web/SpellCheckerClientImpl.cpp
@@ -115,21 +115,6 @@ } } -// TODO(yosin): We should get rid of -// |SepllCheckerClient::isGrammarCheckingEnabled()| as it always true. -bool SpellCheckerClientImpl::isGrammarCheckingEnabled() -{ - return true; -} - -// TODO(yosin): We should get rid of -// |TextCheckerClient::shouldEraseMarkersAfterChangeSelection()| as it always -// false. -bool SpellCheckerClientImpl::shouldEraseMarkersAfterChangeSelection(TextCheckingType type) const -{ - return false; -} - void SpellCheckerClientImpl::checkSpellingOfString(const String& text, int* misspellingLocation, int* misspellingLength) { // SpellCheckWord will write (0, 0) into the output vars, which is what our
diff --git a/third_party/WebKit/Source/web/SpellCheckerClientImpl.h b/third_party/WebKit/Source/web/SpellCheckerClientImpl.h index cf96ecf..4755b19 100644 --- a/third_party/WebKit/Source/web/SpellCheckerClientImpl.h +++ b/third_party/WebKit/Source/web/SpellCheckerClientImpl.h
@@ -47,8 +47,6 @@ bool isContinuousSpellCheckingEnabled() override; void toggleContinuousSpellChecking() override; - bool isGrammarCheckingEnabled() override; - bool shouldEraseMarkersAfterChangeSelection(TextCheckingType) const override; void checkSpellingOfString(const String&, int* misspellingLocation, int* misspellingLength) override; void checkGrammarOfString(const String&, Vector<GrammarDetail>&, int* badGrammarLocation, int* badGrammarLength) override;
diff --git a/third_party/WebKit/Source/web/WebCache.cpp b/third_party/WebKit/Source/web/WebCache.cpp index fc115da9..eb0dee08 100644 --- a/third_party/WebKit/Source/web/WebCache.cpp +++ b/third_party/WebKit/Source/web/WebCache.cpp
@@ -93,11 +93,4 @@ memset(result, 0, sizeof(WebCache::ResourceTypeStats)); } -void WebCache::pruneAll() -{ - MemoryCache* cache = memoryCache(); - if (cache) - cache->pruneAll(); -} - } // namespace blink
diff --git a/third_party/WebKit/Source/web/WebDataSourceImpl.cpp b/third_party/WebKit/Source/web/WebDataSourceImpl.cpp index 45a6748..455be26b 100644 --- a/third_party/WebKit/Source/web/WebDataSourceImpl.cpp +++ b/third_party/WebKit/Source/web/WebDataSourceImpl.cpp
@@ -38,12 +38,6 @@ namespace blink { -static OwnPtrWillBePersistent<WebPluginLoadObserver>& nextPluginLoadObserver() -{ - DEFINE_STATIC_LOCAL(OwnPtrWillBePersistent<WebPluginLoadObserver>, nextPluginLoadObserver, ()); - return nextPluginLoadObserver; -} - PassRefPtrWillBeRawPtr<WebDataSourceImpl> WebDataSourceImpl::create(LocalFrame* frame, const ResourceRequest& request, const SubstituteData& data) { return adoptRefWillBeNoop(new WebDataSourceImpl(frame, request, data)); @@ -137,25 +131,9 @@ } } -void WebDataSourceImpl::setNextPluginLoadObserver(PassOwnPtrWillBeRawPtr<WebPluginLoadObserver> observer) -{ - nextPluginLoadObserver() = observer; -} - WebDataSourceImpl::WebDataSourceImpl(LocalFrame* frame, const ResourceRequest& request, const SubstituteData& data) : DocumentLoader(frame, request, data) { - if (!nextPluginLoadObserver()) - return; - // When a new frame is created, it initially gets a data source for an - // empty document. Then it is navigated to the source URL of the - // frame, which results in a second data source being created. We want - // to wait to attach the WebPluginLoadObserver to that data source. - if (request.url().isEmpty()) - return; - - ASSERT(nextPluginLoadObserver()->url() == WebURL(request.url())); - m_pluginLoadObserver = nextPluginLoadObserver().release(); } WebDataSourceImpl::~WebDataSourceImpl() @@ -170,12 +148,10 @@ DocumentLoader::detachFromFrame(); m_extraData.clear(); - m_pluginLoadObserver.clear(); } DEFINE_TRACE(WebDataSourceImpl) { - visitor->trace(m_pluginLoadObserver); DocumentLoader::trace(visitor); }
diff --git a/third_party/WebKit/Source/web/WebDataSourceImpl.h b/third_party/WebKit/Source/web/WebDataSourceImpl.h index 77e8580..b948d879 100644 --- a/third_party/WebKit/Source/web/WebDataSourceImpl.h +++ b/third_party/WebKit/Source/web/WebDataSourceImpl.h
@@ -37,7 +37,6 @@ #include "platform/heap/Handle.h" #include "platform/weborigin/KURL.h" #include "public/web/WebDataSource.h" -#include "web/WebPluginLoadObserver.h" #include "wtf/OwnPtr.h" #include "wtf/PassOwnPtr.h" #include "wtf/Vector.h" @@ -70,9 +69,6 @@ static WebNavigationType toWebNavigationType(NavigationType); - PassOwnPtrWillBeRawPtr<WebPluginLoadObserver> releasePluginLoadObserver() { return m_pluginLoadObserver.release(); } - static void setNextPluginLoadObserver(PassOwnPtrWillBeRawPtr<WebPluginLoadObserver>); - DECLARE_VIRTUAL_TRACE(); private: @@ -88,7 +84,6 @@ mutable WrappedResourceResponse m_responseWrapper; OwnPtr<ExtraData> m_extraData; - OwnPtrWillBeMember<WebPluginLoadObserver> m_pluginLoadObserver; }; } // namespace blink
diff --git a/third_party/WebKit/Source/web/WebDocument.cpp b/third_party/WebKit/Source/web/WebDocument.cpp index 450ccaa..f3b4146c7 100644 --- a/third_party/WebKit/Source/web/WebDocument.cpp +++ b/third_party/WebKit/Source/web/WebDocument.cpp
@@ -216,7 +216,7 @@ ASSERT(document); RefPtrWillBeRawPtr<StyleSheetContents> parsedSheet = StyleSheetContents::create(CSSParserContext(*document, 0)); parsedSheet->parseString(sourceCode); - document->styleEngine().addAuthorSheet(parsedSheet); + document->styleEngine().injectAuthorSheet(parsedSheet); } void WebDocument::watchCSSSelectors(const WebVector<WebString>& webSelectors)
diff --git a/third_party/WebKit/Source/web/WebFormControlElement.cpp b/third_party/WebKit/Source/web/WebFormControlElement.cpp index c78a047..0c65d270e 100644 --- a/third_party/WebKit/Source/web/WebFormControlElement.cpp +++ b/third_party/WebKit/Source/web/WebFormControlElement.cpp
@@ -83,6 +83,8 @@ return constUnwrap<HTMLInputElement>()->shouldAutocomplete(); if (isHTMLTextAreaElement(*m_private)) return constUnwrap<HTMLTextAreaElement>()->shouldAutocomplete(); + if (isHTMLSelectElement(*m_private)) + return constUnwrap<HTMLSelectElement>()->shouldAutocomplete(); return false; }
diff --git a/third_party/WebKit/Source/web/WebFrameWidgetImpl.cpp b/third_party/WebKit/Source/web/WebFrameWidgetImpl.cpp index 46f9bc1..736a58a 100644 --- a/third_party/WebKit/Source/web/WebFrameWidgetImpl.cpp +++ b/third_party/WebKit/Source/web/WebFrameWidgetImpl.cpp
@@ -604,6 +604,9 @@ void WebFrameWidgetImpl::willCloseLayerTreeView() { + if (m_layerTreeView) + page()->willCloseLayerTreeView(*m_layerTreeView); + setIsAcceleratedCompositingActive(false); m_layerTreeView = nullptr; m_layerTreeViewClosed = true; @@ -985,6 +988,8 @@ devTools->layerTreeViewChanged(m_layerTreeView); page()->settings().setAcceleratedCompositingEnabled(m_layerTreeView); + if (m_layerTreeView) + page()->layerTreeViewInitialized(*m_layerTreeView); // FIXME: only unittests, click to play, Android priting, and printing (for headers and footers) // make this assert necessary. We should make them not hit this code and then delete allowsBrokenNullLayerTreeView.
diff --git a/third_party/WebKit/Source/web/WebLocalFrameImpl.cpp b/third_party/WebKit/Source/web/WebLocalFrameImpl.cpp index eb7bedf..89295a1 100644 --- a/third_party/WebKit/Source/web/WebLocalFrameImpl.cpp +++ b/third_party/WebKit/Source/web/WebLocalFrameImpl.cpp
@@ -1971,12 +1971,27 @@ return; WebURLError webError = error; WebHistoryCommitType webCommitType = static_cast<WebHistoryCommitType>(commitType); + + if (WebPluginContainerImpl* plugin = pluginContainerFromFrame(frame())) + plugin->didFailLoading(error); + if (wasProvisional) client()->didFailProvisionalLoad(this, webError, webCommitType); else client()->didFailLoad(this, webError, webCommitType); } +void WebLocalFrameImpl::didFinish() +{ + if (!client()) + return; + + if (WebPluginContainerImpl* plugin = pluginContainerFromFrame(frame())) + plugin->didFinishLoading(); + + client()->didFinishLoad(this); +} + void WebLocalFrameImpl::setCanHaveScrollbars(bool canHaveScrollbars) { frame()->view()->setCanHaveScrollbars(canHaveScrollbars);
diff --git a/third_party/WebKit/Source/web/WebLocalFrameImpl.h b/third_party/WebKit/Source/web/WebLocalFrameImpl.h index c2618b72..147c417 100644 --- a/third_party/WebKit/Source/web/WebLocalFrameImpl.h +++ b/third_party/WebKit/Source/web/WebLocalFrameImpl.h
@@ -317,6 +317,7 @@ void setFindEndstateFocusAndSelection(); void didFail(const ResourceError&, bool wasProvisional, HistoryCommitType); + void didFinish(); // Sets whether the WebLocalFrameImpl allows its document to be scrolled. // If the parameter is true, allow the document to be scrolled.
diff --git a/third_party/WebKit/Source/web/WebMemoryPressureListener.cpp b/third_party/WebKit/Source/web/WebMemoryPressureListener.cpp new file mode 100644 index 0000000..42760fe --- /dev/null +++ b/third_party/WebKit/Source/web/WebMemoryPressureListener.cpp
@@ -0,0 +1,18 @@ +// Copyright (c) 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. + +#include "config.h" +#include "public/web/WebMemoryPressureListener.h" + +#include "core/page/Page.h" +#include "platform/MemoryPurgeController.h" + +namespace blink { + +void WebMemoryPressureListener::onMemoryPressure() +{ + Page::onMemoryPressure(); +} + +} // namespace blink
diff --git a/third_party/WebKit/Source/web/WebPagePopupImpl.cpp b/third_party/WebKit/Source/web/WebPagePopupImpl.cpp index d41da16..296c0ace 100644 --- a/third_party/WebKit/Source/web/WebPagePopupImpl.cpp +++ b/third_party/WebKit/Source/web/WebPagePopupImpl.cpp
@@ -344,6 +344,7 @@ m_layerTreeView->setVisible(true); m_isAcceleratedCompositingActive = true; m_layerTreeView->setDeviceScaleFactor(m_webView->deviceScaleFactor()); + m_page->layerTreeViewInitialized(*m_layerTreeView); } else { m_isAcceleratedCompositingActive = false; } @@ -361,6 +362,9 @@ void WebPagePopupImpl::willCloseLayerTreeView() { + if (m_page && m_layerTreeView) + m_page->willCloseLayerTreeView(*m_layerTreeView); + setIsAcceleratedCompositingActive(false); m_layerTreeView = 0; }
diff --git a/third_party/WebKit/Source/web/WebPluginContainerImpl.cpp b/third_party/WebKit/Source/web/WebPluginContainerImpl.cpp index 10a10cf..8de3047c 100644 --- a/third_party/WebKit/Source/web/WebPluginContainerImpl.cpp +++ b/third_party/WebKit/Source/web/WebPluginContainerImpl.cpp
@@ -493,23 +493,12 @@ return toCoreString(v8::Local<v8::String>::Cast(result)); } -void WebPluginContainerImpl::loadFrameRequest(const WebURLRequest& request, const WebString& target, bool notifyNeeded, void* notifyData) +void WebPluginContainerImpl::loadFrameRequest(const WebURLRequest& request, const WebString& target) { LocalFrame* frame = m_element->document().frame(); if (!frame || !frame->loader().documentLoader()) return; // FIXME: send a notification in this case? - if (notifyNeeded) { - // FIXME: This is a bit of hack to allow us to observe completion of - // our frame request. It would be better to evolve FrameLoader to - // support a completion callback instead. - OwnPtrWillBeRawPtr<WebPluginLoadObserver> observer = WebPluginLoadObserver::create(this, request.url(), notifyData); -#if !ENABLE(OILPAN) - m_pluginLoadObservers.append(observer.get()); -#endif - WebDataSourceImpl::setNextPluginLoadObserver(observer.release()); - } - FrameLoadRequest frameRequest(frame->document(), request.toResourceRequest(), target); frame->loader().load(frameRequest); } @@ -686,16 +675,6 @@ return m_wantsWheelEvents; } -#if !ENABLE(OILPAN) -void WebPluginContainerImpl::willDestroyPluginLoadObserver(WebPluginLoadObserver* observer) -{ - size_t pos = m_pluginLoadObservers.find(observer); - if (pos == kNotFound) - return; - m_pluginLoadObservers.remove(pos); -} -#endif - // Private methods ------------------------------------------------------------- WebPluginContainerImpl::WebPluginContainerImpl(HTMLPlugInElement* element, WebPlugin* webPlugin) @@ -731,11 +710,6 @@ if (m_element && m_touchEventRequestType != TouchEventRequestTypeNone && m_element->document().frameHost()) m_element->document().frameHost()->eventHandlerRegistry().didRemoveEventHandler(*m_element, EventHandlerRegistry::TouchEvent); -#if !ENABLE(OILPAN) - for (const auto& observer : m_pluginLoadObservers) - observer->clearPluginContainer(); -#endif - if (m_webPlugin) { RELEASE_ASSERT(!m_webPlugin->container() || m_webPlugin->container() == this); m_webPlugin->destroy(); @@ -747,9 +721,6 @@ m_webLayer = nullptr; } -#if !ENABLE(OILPAN) - m_pluginLoadObservers.clear(); -#endif m_element = nullptr; }
diff --git a/third_party/WebKit/Source/web/WebPluginContainerImpl.h b/third_party/WebKit/Source/web/WebPluginContainerImpl.h index d0be624..a79503b 100644 --- a/third_party/WebKit/Source/web/WebPluginContainerImpl.h +++ b/third_party/WebKit/Source/web/WebPluginContainerImpl.h
@@ -55,7 +55,6 @@ class ResourceResponse; class TouchEvent; class WebPlugin; -class WebPluginLoadObserver; class WheelEvent; class Widget; struct WebPrintParams; @@ -108,7 +107,7 @@ NPObject* scriptableObjectForElement() override; v8::Local<v8::Object> v8ObjectForElement() override; WebString executeScriptURL(const WebURL&, bool popupsAllowed) override; - void loadFrameRequest(const WebURLRequest&, const WebString& target, bool notifyNeeded, void* notifyData) override; + void loadFrameRequest(const WebURLRequest&, const WebString& target) override; bool isRectTopmost(const WebRect&) override; void requestTouchEventType(TouchEventRequestType) override; void setWantsWheelEvents(bool) override; @@ -153,12 +152,8 @@ // Resource load events for the plugin's source data: void didReceiveResponse(const ResourceResponse&) override; void didReceiveData(const char *data, int dataLength) override; - void didFinishLoading() override; - void didFailLoading(const ResourceError&) override; - -#if !ENABLE(OILPAN) - void willDestroyPluginLoadObserver(WebPluginLoadObserver*); -#endif + void didFinishLoading(); + void didFailLoading(const ResourceError&); DECLARE_VIRTUAL_TRACE(); void dispose() override; @@ -202,9 +197,6 @@ RawPtrWillBeMember<HTMLPlugInElement> m_element; WebPlugin* m_webPlugin; -#if !ENABLE(OILPAN) - Vector<WebPluginLoadObserver*> m_pluginLoadObservers; -#endif WebLayer* m_webLayer;
diff --git a/third_party/WebKit/Source/web/WebPluginLoadObserver.cpp b/third_party/WebKit/Source/web/WebPluginLoadObserver.cpp deleted file mode 100644 index 911a7519..0000000 --- a/third_party/WebKit/Source/web/WebPluginLoadObserver.cpp +++ /dev/null
@@ -1,68 +0,0 @@ -/* - * Copyright (C) 2009 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. - */ - -#include "config.h" -#include "web/WebPluginLoadObserver.h" - -#include "public/web/WebPlugin.h" -#include "web/WebPluginContainerImpl.h" - -namespace blink { - -WebPluginLoadObserver::~WebPluginLoadObserver() -{ -#if !ENABLE(OILPAN) - if (m_pluginContainer) - m_pluginContainer->willDestroyPluginLoadObserver(this); -#endif -} - -DEFINE_TRACE(WebPluginLoadObserver) -{ - visitor->trace(m_pluginContainer); -} - -void WebPluginLoadObserver::didFinishLoading() -{ - if (!m_pluginContainer) - return; - if (WebPlugin* plugin = m_pluginContainer->plugin()) - plugin->didFinishLoadingFrameRequest(m_notifyURL, m_notifyData); -} - -void WebPluginLoadObserver::didFailLoading(const WebURLError& error) -{ - if (!m_pluginContainer) - return; - if (WebPlugin* plugin = m_pluginContainer->plugin()) - plugin->didFailLoadingFrameRequest(m_notifyURL, m_notifyData, error); -} - -} // namespace blink
diff --git a/third_party/WebKit/Source/web/WebPluginLoadObserver.h b/third_party/WebKit/Source/web/WebPluginLoadObserver.h deleted file mode 100644 index 25ecd7a1..0000000 --- a/third_party/WebKit/Source/web/WebPluginLoadObserver.h +++ /dev/null
@@ -1,75 +0,0 @@ -/* - * Copyright (C) 2009 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 WebPluginLoadObserver_h -#define WebPluginLoadObserver_h - -#include "platform/heap/Handle.h" -#include "public/platform/WebURL.h" - -namespace blink { - -class WebPluginContainerImpl; -struct WebURLError; - -class WebPluginLoadObserver final : public NoBaseWillBeGarbageCollectedFinalized<WebPluginLoadObserver> { -public: - static PassOwnPtrWillBeRawPtr<WebPluginLoadObserver> create(WebPluginContainerImpl* pluginContainer, const WebURL& notifyURL, void* notifyData) - { - return adoptPtrWillBeNoop(new WebPluginLoadObserver(pluginContainer, notifyURL, notifyData)); - } - ~WebPluginLoadObserver(); - - const WebURL& url() const { return m_notifyURL; } - -#if !ENABLE(OILPAN) - void clearPluginContainer() { m_pluginContainer = nullptr; } -#endif - void didFinishLoading(); - void didFailLoading(const WebURLError&); - - DECLARE_TRACE(); - -private: - WebPluginLoadObserver(WebPluginContainerImpl* pluginContainer, const WebURL& notifyURL, void* notifyData) - : m_pluginContainer(pluginContainer) - , m_notifyURL(notifyURL) - , m_notifyData(notifyData) - { - } - - RawPtrWillBeWeakMember<WebPluginContainerImpl> m_pluginContainer; - WebURL m_notifyURL; - void* m_notifyData; -}; - -} // namespace blink - -#endif
diff --git a/third_party/WebKit/Source/web/WebSettingsImpl.cpp b/third_party/WebKit/Source/web/WebSettingsImpl.cpp index c6ec5af..6df9dad 100644 --- a/third_party/WebKit/Source/web/WebSettingsImpl.cpp +++ b/third_party/WebKit/Source/web/WebSettingsImpl.cpp
@@ -569,11 +569,6 @@ m_settings->setHyperlinkAuditingEnabled(enabled); } -void WebSettingsImpl::setAsynchronousSpellCheckingEnabled(bool enabled) -{ - m_settings->setAsynchronousSpellCheckingEnabled(enabled); -} - void WebSettingsImpl::setAutoplayExperimentMode(const WebString& mode) { m_settings->setAutoplayExperimentMode(mode);
diff --git a/third_party/WebKit/Source/web/WebSettingsImpl.h b/third_party/WebKit/Source/web/WebSettingsImpl.h index 6835ec36..3ee436a 100644 --- a/third_party/WebKit/Source/web/WebSettingsImpl.h +++ b/third_party/WebKit/Source/web/WebSettingsImpl.h
@@ -63,7 +63,6 @@ void setAllowUniversalAccessFromFileURLs(bool) override; void setAntialiased2dCanvasEnabled(bool) override; void setAntialiasedClips2dCanvasEnabled(bool) override; - void setAsynchronousSpellCheckingEnabled(bool) override; void setAutoplayExperimentMode(const WebString&) override; void setAutoZoomFocusedNodeToLegibleScale(bool) override; void setCaretBrowsingEnabled(bool) override;
diff --git a/third_party/WebKit/Source/web/WebViewImpl.cpp b/third_party/WebKit/Source/web/WebViewImpl.cpp index 86cf714..e6417fad 100644 --- a/third_party/WebKit/Source/web/WebViewImpl.cpp +++ b/third_party/WebKit/Source/web/WebViewImpl.cpp
@@ -2690,8 +2690,8 @@ m_linkHighlightsTimeline.clear(); } - if (page()) - page()->willCloseLayerTreeView(); + if (m_layerTreeView) + page()->willCloseLayerTreeView(*m_layerTreeView); setRootGraphicsLayer(nullptr); m_layerTreeView = nullptr; @@ -2968,6 +2968,13 @@ page()->focusController().advanceFocus(reverse ? WebFocusTypeBackward : WebFocusTypeForward); } +void WebViewImpl::advanceFocusAcrossFrames(WebFocusType type, WebRemoteFrame* from, WebLocalFrame* to) +{ + // TODO(alexmos): Pass in proper with sourceCapabilities. + page()->focusController().advanceFocusAcrossFrames( + type, toWebRemoteFrameImpl(from)->frame(), toWebLocalFrameImpl(to)->frame()); +} + double WebViewImpl::zoomLevel() { return m_zoomLevel; @@ -3771,6 +3778,13 @@ } } +void WebViewImpl::didCloseContextMenu() +{ + LocalFrame* frame = m_page->focusController().focusedFrame(); + if (frame) + frame->selection().setCaretBlinkingSuspended(false); +} + void WebViewImpl::extractSmartClipData(WebRect rectInViewport, WebString& clipText, WebString& clipHtml, WebRect& clipRectInViewport) { LocalFrame* localFrame = toLocalFrame(focusedCoreFrame()); @@ -4242,6 +4256,8 @@ devTools->layerTreeViewChanged(m_layerTreeView); m_page->settings().setAcceleratedCompositingEnabled(m_layerTreeView); + if (m_layerTreeView) + m_page->layerTreeViewInitialized(*m_layerTreeView); // FIXME: only unittests, click to play, Android printing, and printing (for headers and footers) // make this assert necessary. We should make them not hit this code and then delete allowsBrokenNullLayerTreeView.
diff --git a/third_party/WebKit/Source/web/WebViewImpl.h b/third_party/WebKit/Source/web/WebViewImpl.h index 65458543..c4453c1 100644 --- a/third_party/WebKit/Source/web/WebViewImpl.h +++ b/third_party/WebKit/Source/web/WebViewImpl.h
@@ -82,10 +82,12 @@ class WebDevToolsAgentImpl; class WebElement; class WebLayerTreeView; +class WebLocalFrame; class WebLocalFrameImpl; class WebImage; class WebPagePopupImpl; class WebPlugin; +class WebRemoteFrame; class WebSelection; class WebSettingsImpl; class WebViewScheduler; @@ -189,6 +191,7 @@ void smoothScroll(int targetX, int targetY, long durationMs) override; void zoomToFindInPageRect(const WebRect&); void advanceFocus(bool reverse) override; + void advanceFocusAcrossFrames(WebFocusType, WebRemoteFrame* from, WebLocalFrame* to) override; double zoomLevel() override; double setZoomLevel(double) override; void zoomLimitsChanged(double minimumZoomLevel, double maximumZoomLevel) override; @@ -262,6 +265,7 @@ unsigned inactiveForegroundColor) override; void performCustomContextMenuAction(unsigned action) override; void showContextMenu() override; + void didCloseContextMenu() override; void extractSmartClipData(WebRect, WebString&, WebString&, WebRect&) override; void hidePopups() override; void setPageOverlayColor(WebColor) override;
diff --git a/third_party/WebKit/Source/web/tests/FakeWebPlugin.h b/third_party/WebKit/Source/web/tests/FakeWebPlugin.h index 6fd138e..5b3f1c3 100644 --- a/third_party/WebKit/Source/web/tests/FakeWebPlugin.h +++ b/third_party/WebKit/Source/web/tests/FakeWebPlugin.h
@@ -64,8 +64,6 @@ void didReceiveData(const char* data, int dataLength) override { } void didFinishLoading() override { } void didFailLoading(const WebURLError&) override { } - void didFinishLoadingFrameRequest(const WebURL&, void* notifyData) override { } - void didFailLoadingFrameRequest(const WebURL&, void* notifyData, const WebURLError&) override { } bool isPlaceholder() override { return false; } protected:
diff --git a/third_party/WebKit/Source/web/tests/SpinLockTest.cpp b/third_party/WebKit/Source/web/tests/SpinLockTest.cpp index 18abef9..7806b5b 100644 --- a/third_party/WebKit/Source/web/tests/SpinLockTest.cpp +++ b/third_party/WebKit/Source/web/tests/SpinLockTest.cpp
@@ -44,7 +44,7 @@ static const size_t bufferSize = 16; -static int lock = 0; +static SpinLock lock; static void fillBuffer(volatile char* buffer, char fillPattern) { @@ -69,9 +69,8 @@ static void threadMain(volatile char* buffer) { for (int i = 0; i < 500000; ++i) { - spinLockLock(&lock); + SpinLock::Guard guard(lock); changeAndCheckBuffer(buffer); - spinLockUnlock(&lock); } }
diff --git a/third_party/WebKit/Source/web/tests/TouchActionTest.cpp b/third_party/WebKit/Source/web/tests/TouchActionTest.cpp index 0719ecf..82992c1 100644 --- a/third_party/WebKit/Source/web/tests/TouchActionTest.cpp +++ b/third_party/WebKit/Source/web/tests/TouchActionTest.cpp
@@ -38,6 +38,7 @@ #include "core/dom/shadow/ShadowRoot.h" #include "core/frame/FrameView.h" #include "core/frame/LocalFrame.h" +#include "core/html/HTMLIFrameElement.h" #include "core/input/EventHandler.h" #include "core/layout/HitTestResult.h" #include "core/layout/LayoutTreeAsText.h" @@ -54,6 +55,7 @@ #include "public/web/WebViewClient.h" #include "public/web/WebWidgetClient.h" #include "testing/gtest/include/gtest/gtest.h" +#include "web/WebFrameImplBase.h" #include "web/WebViewImpl.h" #include "web/tests/FrameTestHelpers.h" @@ -118,6 +120,7 @@ protected: void runTouchActionTest(std::string file); void runShadowDOMTest(std::string file); + void runIFrameTest(std::string file); void sendTouchEvent(WebView*, WebInputEvent::Type, IntPoint clientPoint); WebView* setupTest(std::string file, TouchActionTrackingWebViewClient&); void runTestOnTree(ContainerNode* root, WebView*, TouchActionTrackingWebViewClient&); @@ -173,6 +176,23 @@ m_webViewHelper.reset(); // Explicitly reset to break dependency on locally scoped client. } +void TouchActionTest::runIFrameTest(std::string file) +{ + TouchActionTrackingWebViewClient client; + + WebView* webView = setupTest(file, client); + WebFrame* curFrame = webView->mainFrame()->firstChild(); + ASSERT_TRUE(curFrame); + + for (; curFrame; curFrame = curFrame->nextSibling()) { + // Oilpan: see runTouchActionTest() comment why these are persistent references. + RefPtrWillBePersistent<Document> contentDoc = static_cast<PassRefPtrWillBeRawPtr<Document>>(curFrame->document()); + runTestOnTree(contentDoc.get(), webView, client); + } + + m_webViewHelper.reset(); // Explicitly reset to break dependency on locally scoped client. +} + WebView* TouchActionTest::setupTest(std::string file, TouchActionTrackingWebViewClient& client) { URLTestHelpers::registerMockedURLFromBaseURL(WebString::fromUTF8(m_baseURL), WebString::fromUTF8(file)); @@ -224,33 +244,35 @@ FloatRect clientFloatRect = FloatRect(r->left(), r->top(), r->width(), r->height()); IntRect clientRect = enclosedIntRect(clientFloatRect); for (int locIdx = 0; locIdx < 3; locIdx++) { - IntPoint clientPoint; + IntPoint framePoint; std::stringstream contextStream; contextStream << failureContext << " ("; switch (locIdx) { case 0: - clientPoint = clientRect.center(); + framePoint = clientRect.center(); contextStream << "center"; break; case 1: - clientPoint = clientRect.location(); + framePoint = clientRect.location(); contextStream << "top-left"; break; case 2: - clientPoint = clientRect.maxXMaxYCorner(); - clientPoint.move(-1, -1); + framePoint = clientRect.maxXMaxYCorner(); + framePoint.move(-1, -1); contextStream << "bottom-right"; break; default: FAIL() << "Invalid location index."; } - contextStream << "=" << clientPoint.x() << "," << clientPoint.y() << ")."; + + IntPoint windowPoint = root->document().frame()->view()->convertToRootFrame(framePoint); + contextStream << "=" << windowPoint.x() << "," << windowPoint.y() << ")."; std::string failureContextPos = contextStream.str(); - LocalFrame* frame = root->document().frame(); - FrameView* frameView = frame->view(); - IntRect visibleRect = frameView->windowClipRect(); - ASSERT_TRUE(visibleRect.contains(clientPoint)) << failureContextPos + LocalFrame* mainFrame = static_cast<LocalFrame*>(webView->mainFrame()->toImplBase()->frame()); + FrameView* mainFrameView = mainFrame->view(); + IntRect visibleRect = mainFrameView->windowClipRect(); + ASSERT_TRUE(visibleRect.contains(windowPoint)) << failureContextPos << " Test point not contained in visible area: " << visibleRect.x() << "," << visibleRect.y() << "-" << visibleRect.maxX() << "," << visibleRect.maxY(); @@ -258,14 +280,14 @@ // we intended. This is the easiest way for a test to be broken, but has nothing really // to do with touch action. // Note that we can't use WebView's hit test API because it doesn't look into shadow DOM. - IntPoint docPoint(frameView->rootFrameToContents(clientPoint)); - HitTestResult result = frame->eventHandler().hitTestResultAtPoint(docPoint, HitTestRequest::ReadOnly | HitTestRequest::Active); + IntPoint docPoint(mainFrameView->frameToContents(windowPoint)); + HitTestResult result = mainFrame->eventHandler().hitTestResultAtPoint(docPoint, HitTestRequest::ReadOnly | HitTestRequest::Active); ASSERT_EQ(element, result.innerElement()) << "Unexpected hit test result " << failureContextPos << " Got element: \"" << result.innerElement()->outerHTML().stripWhiteSpace().left(80).ascii().data() << "\"" << std::endl << "Document render tree:" << std::endl << externalRepresentation(root->document().frame()).utf8().data(); // Now send the touch event and check any touch action result. - sendTouchEvent(webView, WebInputEvent::TouchStart, clientPoint); + sendTouchEvent(webView, WebInputEvent::TouchStart, windowPoint); AtomicString expectedAction = element->getAttribute("expected-action"); if (expectedAction == "auto") { @@ -283,9 +305,9 @@ } else if (expectedAction == "pan-y") { EXPECT_EQ(WebTouchActionPanY, client.lastTouchAction()) << failureContextPos; } else if (expectedAction == "pan-x-y") { - EXPECT_EQ((WebTouchActionPanX | WebTouchActionPanY), client.lastTouchAction()) << failureContextPos; + EXPECT_EQ((WebTouchActionPan), client.lastTouchAction()) << failureContextPos; } else if (expectedAction == "manipulation") { - EXPECT_EQ((WebTouchActionPanX | WebTouchActionPanY | WebTouchActionPinchZoom), client.lastTouchAction()) << failureContextPos; + EXPECT_EQ((WebTouchActionManipulation), client.lastTouchAction()) << failureContextPos; } else { FAIL() << "Unrecognized expected-action \"" << expectedAction.ascii().data() << "\" " << failureContextPos; @@ -295,7 +317,7 @@ // Reset webview touch state. client.reset(); - sendTouchEvent(webView, WebInputEvent::TouchCancel, clientPoint); + sendTouchEvent(webView, WebInputEvent::TouchCancel, windowPoint); EXPECT_EQ(0, client.touchActionSetCount()); } } @@ -335,6 +357,11 @@ runTouchActionTest("touch-action-overflow.html"); } +TEST_F(TouchActionTest, IFrame) +{ + runIFrameTest("touch-action-iframe.html"); +} + TEST_F(TouchActionTest, ShadowDOM) { runShadowDOMTest("touch-action-shadow-dom.html");
diff --git a/third_party/WebKit/Source/web/tests/WebFrameTest.cpp b/third_party/WebKit/Source/web/tests/WebFrameTest.cpp index a2e5930a..0e164e8 100644 --- a/third_party/WebKit/Source/web/tests/WebFrameTest.cpp +++ b/third_party/WebKit/Source/web/tests/WebFrameTest.cpp
@@ -5180,7 +5180,6 @@ Document* document = frame->frame()->document(); Element* element = document->getElementById("data"); - webViewHelper.webView()->settings()->setAsynchronousSpellCheckingEnabled(true); webViewHelper.webView()->settings()->setUnifiedTextCheckerEnabled(true); webViewHelper.webView()->settings()->setEditingBehavior(WebSettings::EditingBehaviorWin); @@ -5213,7 +5212,6 @@ Document* document = frame->frame()->document(); Element* element = document->getElementById("data"); - webViewHelper.webView()->settings()->setAsynchronousSpellCheckingEnabled(true); webViewHelper.webView()->settings()->setUnifiedTextCheckerEnabled(true); webViewHelper.webView()->settings()->setEditingBehavior(WebSettings::EditingBehaviorWin); @@ -5244,7 +5242,6 @@ Document* document = frame->document(); Element* element = document->getElementById("data"); - webViewHelper.webView()->settings()->setAsynchronousSpellCheckingEnabled(true); webViewHelper.webView()->settings()->setUnifiedTextCheckerEnabled(true); webViewHelper.webView()->settings()->setEditingBehavior(WebSettings::EditingBehaviorWin); @@ -5280,7 +5277,6 @@ Document* document = frame->frame()->document(); Element* element = document->getElementById("data"); - webViewHelper.webView()->settings()->setAsynchronousSpellCheckingEnabled(true); webViewHelper.webView()->settings()->setUnifiedTextCheckerEnabled(true); webViewHelper.webView()->settings()->setEditingBehavior(WebSettings::EditingBehaviorWin); @@ -5357,7 +5353,6 @@ Document* document = frame->frame()->document(); Element* element = document->getElementById("data"); - webViewHelper.webView()->settings()->setAsynchronousSpellCheckingEnabled(true); webViewHelper.webView()->settings()->setUnifiedTextCheckerEnabled(true); webViewHelper.webView()->settings()->setEditingBehavior(WebSettings::EditingBehaviorWin); @@ -5388,7 +5383,6 @@ Document* document = frame->frame()->document(); Element* element = document->getElementById("data"); - webViewHelper.webView()->settings()->setAsynchronousSpellCheckingEnabled(true); webViewHelper.webView()->settings()->setUnifiedTextCheckerEnabled(true); webViewHelper.webView()->settings()->setEditingBehavior(WebSettings::EditingBehaviorWin); @@ -5410,7 +5404,6 @@ Document* document = frame->frame()->document(); Element* element = document->getElementById("data"); - webViewHelper.webView()->settings()->setAsynchronousSpellCheckingEnabled(true); webViewHelper.webView()->settings()->setUnifiedTextCheckerEnabled(true); webViewHelper.webView()->settings()->setEditingBehavior(WebSettings::EditingBehaviorWin); @@ -5441,7 +5434,6 @@ Document* document = frame->frame()->document(); Element* element = document->getElementById("data"); - webViewHelper.webView()->settings()->setAsynchronousSpellCheckingEnabled(true); webViewHelper.webView()->settings()->setUnifiedTextCheckerEnabled(true); webViewHelper.webView()->settings()->setEditingBehavior(WebSettings::EditingBehaviorWin);
diff --git a/third_party/WebKit/Source/web/tests/WebViewTest.cpp b/third_party/WebKit/Source/web/tests/WebViewTest.cpp index ee1289e9..1c0e36e 100644 --- a/third_party/WebKit/Source/web/tests/WebViewTest.cpp +++ b/third_party/WebKit/Source/web/tests/WebViewTest.cpp
@@ -1638,6 +1638,39 @@ } #endif +TEST_F(WebViewTest, BlinkCaretOnClosingContextMenu) +{ + URLTestHelpers::registerMockedURLFromBaseURL(WebString::fromUTF8(m_baseURL.c_str()), WebString::fromUTF8("form.html")); + WebView* webView = m_webViewHelper.initializeAndLoad(m_baseURL + "form.html", true); + + webView->setInitialFocus(false); + runPendingTasks(); + + // We suspend caret blinking when pressing with mouse right button. + // Note that we do not send MouseUp event here since it will be consumed + // by the context menu once it shows up. + WebMouseEvent mouseEvent; + mouseEvent.button = WebMouseEvent::ButtonRight; + mouseEvent.x = 1; + mouseEvent.y = 1; + mouseEvent.clickCount = 1; + mouseEvent.type = WebInputEvent::MouseDown; + webView->handleInputEvent(mouseEvent); + runPendingTasks(); + + WebLocalFrameImpl* mainFrame = toWebLocalFrameImpl(webView->mainFrame()); + EXPECT_TRUE(mainFrame->frame()->selection().isCaretBlinkingSuspended()); + + // Caret blinking is still suspended after showing context menu. + webView->showContextMenu(); + EXPECT_TRUE(mainFrame->frame()->selection().isCaretBlinkingSuspended()); + + // Caret blinking will be resumed only after context menu is closed. + webView->didCloseContextMenu(); + + EXPECT_FALSE(mainFrame->frame()->selection().isCaretBlinkingSuspended()); +} + TEST_F(WebViewTest, SelectionOnReadOnlyInput) { URLTestHelpers::registerMockedURLFromBaseURL(WebString::fromUTF8(m_baseURL.c_str()), WebString::fromUTF8("selection_readonly.html"));
diff --git a/third_party/WebKit/Source/web/tests/data/touch-action-iframe.html b/third_party/WebKit/Source/web/tests/data/touch-action-iframe.html new file mode 100644 index 0000000..336478a --- /dev/null +++ b/third_party/WebKit/Source/web/tests/data/touch-action-iframe.html
@@ -0,0 +1,24 @@ +<!DOCTYPE html> +<link rel='stylesheet' type='text/css' href='touch-action-tests.css'> +<script src='touch-action-tests.js'></script> + +<!-- + Test a bunch of cases involving iframes. +--> +<iframe srcdoc=" + <div style='touch-action: none;' expected-action='none'> + touch-action: none still applies inside an iframe + </div> +"></iframe> + +<iframe style='touch-action: none;' srcdoc=" + <div expected-action='pan-x-y'> + Zoom (but not scroll) related touch-action bits propagate into iframes + </div> +"></iframe> + +<iframe style='touch-action: manipulation;' srcdoc=" + <div expected-action='manipulation'> + touch-action: manipulation is maintained across iframes + </div> +"></iframe>
diff --git a/third_party/WebKit/Source/web/tests/data/touch-action-overflow.html b/third_party/WebKit/Source/web/tests/data/touch-action-overflow.html index 525aade..ec6f7393 100644 --- a/third_party/WebKit/Source/web/tests/data/touch-action-overflow.html +++ b/third_party/WebKit/Source/web/tests/data/touch-action-overflow.html
@@ -20,7 +20,13 @@ </div> <div class='ta-none'> - <div class='scroll' expected-action='auto'> - Touch-action: none is not propagated into overflow-scroll elements + <div class='scroll' expected-action='pan-x-y'> + Zoom (but not scroll) related touch-action bits propagate into overflow-scroll elements + </div> +</div> + +<div class='ta-manipulation'> + <div class='scroll' expected-action='manipulation'> + touch-action: manipulation is maintained across overflow-scroll elements </div> </div>
diff --git a/third_party/WebKit/Source/web/tests/data/touch-action-tests.css b/third_party/WebKit/Source/web/tests/data/touch-action-tests.css index b0c5724..92a3a4b5 100644 --- a/third_party/WebKit/Source/web/tests/data/touch-action-tests.css +++ b/third_party/WebKit/Source/web/tests/data/touch-action-tests.css
@@ -70,6 +70,11 @@ overflow: scroll; height: 50px; } +iframe { + height: 50px; + display: block; + margin: 5px; +} .spacer { height: 500px; }
diff --git a/third_party/WebKit/Source/web/web.gypi b/third_party/WebKit/Source/web/web.gypi index bcbc134..add9ebe6 100644 --- a/third_party/WebKit/Source/web/web.gypi +++ b/third_party/WebKit/Source/web/web.gypi
@@ -177,6 +177,7 @@ 'WebMediaDevicesRequest.cpp', 'WebMediaStreamRegistry.cpp', 'WebMetaElement.cpp', + 'WebMemoryPressureListener.cpp', 'WebNetworkStateNotifier.cpp', 'WebNode.cpp', 'WebOptionElement.cpp', @@ -190,8 +191,6 @@ 'WebPluginContainerImpl.cpp', 'WebPluginContainerImpl.h', 'WebPluginDocument.cpp', - 'WebPluginLoadObserver.cpp', - 'WebPluginLoadObserver.h', 'WebPluginScriptForbiddenScope.cpp', 'WebRange.cpp', 'WebRemoteFrameImpl.cpp',
diff --git a/third_party/WebKit/Source/wtf/AddressSpaceRandomization.cpp b/third_party/WebKit/Source/wtf/AddressSpaceRandomization.cpp index bad3158..cc00aaa 100644 --- a/third_party/WebKit/Source/wtf/AddressSpaceRandomization.cpp +++ b/third_party/WebKit/Source/wtf/AddressSpaceRandomization.cpp
@@ -22,7 +22,7 @@ // This is the same PRNG as used by tcmalloc for mapping address randomness; // see http://burtleburtle.net/bob/rand/smallprng.html struct ranctx { - int lock; + SpinLock lock; bool initialized; uint32_t a; uint32_t b; @@ -46,7 +46,7 @@ uint32_t ranval(ranctx* x) { - spinLockLock(&x->lock); + SpinLock::Guard guard(x->lock); if (UNLIKELY(!x->initialized)) { x->initialized = true; char c; @@ -73,7 +73,6 @@ } } uint32_t ret = ranvalInternal(x); - spinLockUnlock(&x->lock); return ret; }
diff --git a/third_party/WebKit/Source/wtf/ContainerAnnotations.h b/third_party/WebKit/Source/wtf/ContainerAnnotations.h index 9c5fb9e..105515438 100644 --- a/third_party/WebKit/Source/wtf/ContainerAnnotations.h +++ b/third_party/WebKit/Source/wtf/ContainerAnnotations.h
@@ -5,6 +5,7 @@ #ifndef WTF_ContainerAnnotations_h #define WTF_ContainerAnnotations_h +#include "wtf/AddressSanitizer.h" #include "wtf/CPU.h" // TODO(ochang): Remove the CPU(X86_64) condition to enable this for X86 once
diff --git a/third_party/WebKit/Source/wtf/PartitionAlloc.cpp b/third_party/WebKit/Source/wtf/PartitionAlloc.cpp index 8e6cdd9..a71dd00 100644 --- a/third_party/WebKit/Source/wtf/PartitionAlloc.cpp +++ b/third_party/WebKit/Source/wtf/PartitionAlloc.cpp
@@ -55,7 +55,7 @@ namespace WTF { -int PartitionRootBase::gInitializedLock = 0; +SpinLock PartitionRootBase::gInitializedLock; bool PartitionRootBase::gInitialized = false; PartitionPage PartitionRootBase::gSeedPage; PartitionBucket PartitionRootBase::gPagedBucket; @@ -104,15 +104,15 @@ static void partitionAllocBaseInit(PartitionRootBase* root) { ASSERT(!root->initialized); - - spinLockLock(&PartitionRootBase::gInitializedLock); - if (!PartitionRootBase::gInitialized) { - PartitionRootBase::gInitialized = true; - // We mark the seed page as free to make sure it is skipped by our - // logic to find a new active page. - PartitionRootBase::gPagedBucket.activePagesHead = &PartitionRootGeneric::gSeedPage; + { + SpinLock::Guard guard(PartitionRootBase::gInitializedLock); + if (!PartitionRootBase::gInitialized) { + PartitionRootBase::gInitialized = true; + // We mark the seed page as free to make sure it is skipped by our + // logic to find a new active page. + PartitionRootBase::gPagedBucket.activePagesHead = &PartitionRootGeneric::gSeedPage; + } } - spinLockUnlock(&PartitionRootBase::gInitializedLock); root->initialized = true; root->totalSizeOfCommittedPages = 0; @@ -166,7 +166,7 @@ void partitionAllocGenericInit(PartitionRootGeneric* root) { - spinLockLock(&root->lock); + SpinLock::Guard guard(root->lock); partitionAllocBaseInit(root); @@ -243,8 +243,6 @@ // And there's one last bucket lookup that will be hit for e.g. malloc(-1), // which tries to overflow to a non-existant order. *bucketPtr = &PartitionRootGeneric::gPagedBucket; - - spinLockUnlock(&root->lock); } static bool partitionAllocShutdownBucket(PartitionBucket* bucket) @@ -293,7 +291,7 @@ bool partitionAllocGenericShutdown(PartitionRootGeneric* root) { - spinLockLock(&root->lock); + SpinLock::Guard guard(root->lock); bool foundLeak = false; size_t i; for (i = 0; i < kGenericNumBuckets; ++i) { @@ -301,7 +299,6 @@ foundLeak |= partitionAllocShutdownBucket(bucket); } foundLeak |= partitionAllocBaseShutdown(root); - spinLockUnlock(&root->lock); return !foundLeak; } @@ -1241,7 +1238,7 @@ void partitionPurgeMemoryGeneric(PartitionRootGeneric* root, int flags) { - spinLockLock(&root->lock); + SpinLock::Guard guard(root->lock); if (flags & PartitionPurgeDecommitEmptyPages) partitionDecommitEmptyPages(root); if (flags & PartitionPurgeDiscardUnusedSystemPages) { @@ -1251,7 +1248,6 @@ partitionPurgeBucket(bucket); } } - spinLockUnlock(&root->lock); } static void partitionDumpPageStats(PartitionBucketMemoryStats* statsOut, const PartitionPage* page) @@ -1329,29 +1325,29 @@ uint32_t directMapLengths[kMaxReportableDirectMaps]; size_t numDirectMappedAllocations = 0; - spinLockLock(&partition->lock); + { + SpinLock::Guard guard(partition->lock); - for (size_t i = 0; i < kGenericNumBuckets; ++i) { - const PartitionBucket* bucket = &partition->buckets[i]; - // Don't report the pseudo buckets that the generic allocator sets up in - // order to preserve a fast size->bucket map (see - // partitionAllocGenericInit for details). - if (!bucket->activePagesHead) - bucketStats[i].isValid = false; - else - partitionDumpBucketStats(&bucketStats[i], bucket); + for (size_t i = 0; i < kGenericNumBuckets; ++i) { + const PartitionBucket* bucket = &partition->buckets[i]; + // Don't report the pseudo buckets that the generic allocator sets up in + // order to preserve a fast size->bucket map (see + // partitionAllocGenericInit for details). + if (!bucket->activePagesHead) + bucketStats[i].isValid = false; + else + partitionDumpBucketStats(&bucketStats[i], bucket); + } + + for (PartitionDirectMapExtent* extent = partition->directMapList; extent; extent = extent->nextExtent) { + ASSERT(!extent->nextExtent || extent->nextExtent->prevExtent == extent); + directMapLengths[numDirectMappedAllocations] = extent->bucket->slotSize; + ++numDirectMappedAllocations; + if (numDirectMappedAllocations == kMaxReportableDirectMaps) + break; + } } - for (PartitionDirectMapExtent* extent = partition->directMapList; extent; extent = extent->nextExtent) { - ASSERT(!extent->nextExtent || extent->nextExtent->prevExtent == extent); - directMapLengths[numDirectMappedAllocations] = extent->bucket->slotSize; - ++numDirectMappedAllocations; - if (numDirectMappedAllocations == kMaxReportableDirectMaps) - break; - } - - spinLockUnlock(&partition->lock); - // partitionsDumpBucketStats is called after collecting stats because it // can try to allocate using PartitionAllocGeneric and it can't obtain the // lock.
diff --git a/third_party/WebKit/Source/wtf/PartitionAlloc.h b/third_party/WebKit/Source/wtf/PartitionAlloc.h index 1dba60909..2f2d82158 100644 --- a/third_party/WebKit/Source/wtf/PartitionAlloc.h +++ b/third_party/WebKit/Source/wtf/PartitionAlloc.h
@@ -309,7 +309,7 @@ int16_t globalEmptyPageRingIndex; uintptr_t invertedSelf; - static int gInitializedLock; + static SpinLock gInitializedLock; static bool gInitialized; // gSeedPage is used as a sentinel to indicate that there is no page // in the active page list. We can use nullptr, but in that case we need @@ -330,7 +330,7 @@ // Never instantiate a PartitionRootGeneric directly, instead use PartitionAllocatorGeneric. struct PartitionRootGeneric : public PartitionRootBase { - int lock; + SpinLock lock; // Some pre-computed constants. size_t orderIndexShifts[kBitsPerSizet + 1]; size_t orderSubIndexMasks[kBitsPerSizet + 1]; @@ -752,16 +752,18 @@ size_t requestedSize = size; size = partitionCookieSizeAdjustAdd(size); PartitionBucket* bucket = partitionGenericSizeToBucket(root, size); - spinLockLock(&root->lock); - // TODO(bashi): Remove following RELEAE_ASSERT()s once we find the cause of - // http://crbug.com/514141 + void* ret = nullptr; + { + SpinLock::Guard guard(root->lock); + // TODO(bashi): Remove following RELEAE_ASSERT()s once we find the cause of + // http://crbug.com/514141 #if OS(ANDROID) - RELEASE_ASSERT(bucket >= &root->buckets[0] || bucket == &PartitionRootGeneric::gPagedBucket); - RELEASE_ASSERT(bucket <= &root->buckets[kGenericNumBuckets - 1] || bucket == &PartitionRootGeneric::gPagedBucket); - RELEASE_ASSERT(root->initialized); + RELEASE_ASSERT(bucket >= &root->buckets[0] || bucket == &PartitionRootGeneric::gPagedBucket); + RELEASE_ASSERT(bucket <= &root->buckets[kGenericNumBuckets - 1] || bucket == &PartitionRootGeneric::gPagedBucket); + RELEASE_ASSERT(root->initialized); #endif - void* ret = partitionBucketAlloc(root, flags, size, bucket); - spinLockUnlock(&root->lock); + ret = partitionBucketAlloc(root, flags, size, bucket); + } PartitionAllocHooks::allocationHookIfEnabled(ret, requestedSize, typeName); return ret; #endif @@ -786,9 +788,10 @@ ptr = partitionCookieFreePointerAdjust(ptr); ASSERT(partitionPointerIsValid(ptr)); PartitionPage* page = partitionPointerToPage(ptr); - spinLockLock(&root->lock); - partitionFreeWithPage(ptr, page); - spinLockUnlock(&root->lock); + { + SpinLock::Guard guard(root->lock); + partitionFreeWithPage(ptr, page); + } #endif }
diff --git a/third_party/WebKit/Source/wtf/Partitions.cpp b/third_party/WebKit/Source/wtf/Partitions.cpp index 39914b4..2e97e011 100644 --- a/third_party/WebKit/Source/wtf/Partitions.cpp +++ b/third_party/WebKit/Source/wtf/Partitions.cpp
@@ -39,7 +39,7 @@ const char* const Partitions::kAllocatedObjectPoolName = "partition_alloc/allocated_objects"; -int Partitions::s_initializationLock = 0; +SpinLock Partitions::s_initializationLock; bool Partitions::s_initialized = false; PartitionAllocatorGeneric Partitions::m_fastMallocAllocator; @@ -50,7 +50,7 @@ void Partitions::initialize(HistogramEnumerationFunction histogramEnumeration) { - spinLockLock(&s_initializationLock); + SpinLock::Guard guard(s_initializationLock); if (!s_initialized) { partitionAllocGlobalInit(&Partitions::handleOutOfMemory); @@ -61,13 +61,11 @@ m_histogramEnumeration = histogramEnumeration; s_initialized = true; } - - spinLockUnlock(&s_initializationLock); } void Partitions::shutdown() { - spinLockLock(&s_initializationLock); + SpinLock::Guard guard(s_initializationLock); // We could ASSERT here for a memory leak within the partition, but it leads // to very hard to diagnose ASSERTs, so it's best to leave leak checking for @@ -78,8 +76,6 @@ (void) m_bufferAllocator.shutdown(); (void) m_fastMallocAllocator.shutdown(); } - - spinLockUnlock(&s_initializationLock); } void Partitions::decommitFreeableMemory()
diff --git a/third_party/WebKit/Source/wtf/Partitions.h b/third_party/WebKit/Source/wtf/Partitions.h index 7b18ef8..5651c2b8 100644 --- a/third_party/WebKit/Source/wtf/Partitions.h +++ b/third_party/WebKit/Source/wtf/Partitions.h
@@ -125,7 +125,7 @@ static void handleOutOfMemory(); private: - static int s_initializationLock; + static SpinLock s_initializationLock; static bool s_initialized; // We have the following four partitions.
diff --git a/third_party/WebKit/Source/wtf/SpinLock.cpp b/third_party/WebKit/Source/wtf/SpinLock.cpp index 542f97be..c85203b 100644 --- a/third_party/WebKit/Source/wtf/SpinLock.cpp +++ b/third_party/WebKit/Source/wtf/SpinLock.cpp
@@ -53,7 +53,7 @@ namespace WTF { -void slowSpinLockLock(int volatile* lock) +void SpinLock::lockSlow() { // The value of kYieldProcessorTries is cargo culted from TCMalloc, Windows // critical section defaults, and various other recommendations. @@ -64,14 +64,14 @@ for (int count = 0; count < kYieldProcessorTries; ++count) { // Let the Processor know we're spinning. YIELD_PROCESSOR; - if (!*lock && LIKELY(!atomicTestAndSetToOne(lock))) + if (!m_lock.load(std::memory_order_relaxed) && LIKELY(!m_lock.exchange(true, std::memory_order_acq_rel))) return; } // Give the OS a chance to schedule something on this core. YIELD_THREAD; - } while (*lock); - } while (UNLIKELY(atomicTestAndSetToOne(lock))); + } while (m_lock.load(std::memory_order_relaxed)); + } while (UNLIKELY(m_lock.exchange(true, std::memory_order_acq_rel))); } } // namespace WTF
diff --git a/third_party/WebKit/Source/wtf/SpinLock.h b/third_party/WebKit/Source/wtf/SpinLock.h index 08724a3..b8d6b9c 100644 --- a/third_party/WebKit/Source/wtf/SpinLock.h +++ b/third_party/WebKit/Source/wtf/SpinLock.h
@@ -31,36 +31,48 @@ #ifndef WTF_SpinLock_h #define WTF_SpinLock_h -// DESCRIPTION -// spinLockLock() and spinLockUnlock() are simple spinlock primitives based on -// the standard CPU primitive of atomic increment and decrement of an int at -// a given memory address. These are intended only for very short duration locks -// and assume a system with multiple cores. For any potentially longer wait you -// should be using a real lock. +#include "wtf/Compiler.h" +#include "wtf/WTFExport.h" +#include <atomic> +#include <memory> +#include <mutex> -#include "wtf/Atomics.h" +// DESCRIPTION +// Spinlock is a simple spinlock class based on the standard CPU primitive of +// atomic increment and decrement of an int at a given memory address. These are +// intended only for very short duration locks and assume a system with multiple +// cores. For any potentially longer wait you should be using a real lock. namespace WTF { -// This is called if the initial attempt to acquire the lock fails. It's a bit -// slower, but has a much better scheduling and power consumption behavior. -WTF_EXPORT void slowSpinLockLock(int volatile* lock); +class SpinLock { +public: + using Guard = std::lock_guard<SpinLock>; -ALWAYS_INLINE void spinLockLock(int volatile* lock) -{ - if (LIKELY(!atomicTestAndSetToOne(lock))) - return; - slowSpinLockLock(lock); -} + ALWAYS_INLINE void lock() + { + static_assert(sizeof(m_lock) == sizeof(int), "int and m_lock are different sizes"); + if (LIKELY(!m_lock.exchange(true, std::memory_order_acq_rel))) + return; + lockSlow(); + } -ALWAYS_INLINE void spinLockUnlock(int volatile* lock) -{ - atomicSetOneToZero(lock); -} + ALWAYS_INLINE void unlock() + { + m_lock.store(false, std::memory_order_release); + } + +private: + // This is called if the initial attempt to acquire the lock fails. It's + // slower, but has a much better scheduling and power consumption behavior. + WTF_EXPORT void lockSlow(); + + std::atomic<int> m_lock; +}; + } // namespace WTF -using WTF::spinLockLock; -using WTF::spinLockUnlock; +using WTF::SpinLock; #endif // WTF_SpinLock_h
diff --git a/third_party/WebKit/Source/wtf/text/TextEncodingRegistry.cpp b/third_party/WebKit/Source/wtf/text/TextEncodingRegistry.cpp index 73c38d9f..d49195e 100644 --- a/third_party/WebKit/Source/wtf/text/TextEncodingRegistry.cpp +++ b/third_party/WebKit/Source/wtf/text/TextEncodingRegistry.cpp
@@ -28,6 +28,7 @@ #include "wtf/text/TextEncodingRegistry.h" #include "wtf/ASCIICType.h" +#include "wtf/Atomics.h" #include "wtf/CurrentTime.h" #include "wtf/HashMap.h" #include "wtf/HashSet.h"
diff --git a/third_party/WebKit/public/blink_headers.gypi b/third_party/WebKit/public/blink_headers.gypi index fb89da1..612a396 100644 --- a/third_party/WebKit/public/blink_headers.gypi +++ b/third_party/WebKit/public/blink_headers.gypi
@@ -418,6 +418,7 @@ "web/WebMediaDevicesRequest.h", "web/WebMediaPlayerAction.h", "web/WebMediaStreamRegistry.h", + "web/WebMemoryPressureListener.h", "web/WebMenuItemInfo.h", "web/WebMetaElement.h", "web/WebNavigationPolicy.h",
diff --git a/third_party/WebKit/public/platform/WebMediaConstraints.h b/third_party/WebKit/public/platform/WebMediaConstraints.h index 82ccbf41..da3380e8 100644 --- a/third_party/WebKit/public/platform/WebMediaConstraints.h +++ b/third_party/WebKit/public/platform/WebMediaConstraints.h
@@ -73,6 +73,7 @@ BLINK_PLATFORM_EXPORT void reset(); bool isNull() const { return m_private.isNull(); } + BLINK_PLATFORM_EXPORT bool isEmpty() const; BLINK_PLATFORM_EXPORT void getOptionalConstraints(WebVector<WebMediaConstraint>&) const; BLINK_PLATFORM_EXPORT void getMandatoryConstraints(WebVector<WebMediaConstraint>&) const;
diff --git a/third_party/WebKit/public/web/WebCache.h b/third_party/WebKit/public/web/WebCache.h index 8f4a619..7ea39c9 100644 --- a/third_party/WebKit/public/web/WebCache.h +++ b/third_party/WebKit/public/web/WebCache.h
@@ -84,10 +84,6 @@ // Get usage stats about the resource cache. BLINK_EXPORT static void getResourceTypeStats(ResourceTypeStats*); - // Prunes all resources (as much as possible; some resources may not be - // cleared if they are actively referenced). And releases cache memory. - BLINK_EXPORT static void pruneAll(); - private: WebCache(); // Not intended to be instanced. };
diff --git a/third_party/WebKit/public/web/WebFrame.h b/third_party/WebKit/public/web/WebFrame.h index c99c667..176df40c 100644 --- a/third_party/WebKit/public/web/WebFrame.h +++ b/third_party/WebKit/public/web/WebFrame.h
@@ -744,10 +744,6 @@ WebPrivateOwnPtr<OpenedFrameTracker> m_openedFrameTracker; }; -#if BLINK_IMPLEMENTATION -Frame* toCoreFrame(const WebFrame*); -#endif - } // namespace blink #endif
diff --git a/third_party/WebKit/public/web/WebFrameClient.h b/third_party/WebKit/public/web/WebFrameClient.h index d51e8210..89f2cef 100644 --- a/third_party/WebKit/public/web/WebFrameClient.h +++ b/third_party/WebKit/public/web/WebFrameClient.h
@@ -460,9 +460,6 @@ // A performance timing event (e.g. first paint) occurred virtual void didChangePerformanceTiming() { } - // The loaders in this frame have been stopped. - virtual void didAbortLoading(WebLocalFrame*) { } - // Script notifications ------------------------------------------------
diff --git a/third_party/WebKit/public/web/WebMemoryPressureListener.h b/third_party/WebKit/public/web/WebMemoryPressureListener.h new file mode 100644 index 0000000..c1cbdd3 --- /dev/null +++ b/third_party/WebKit/public/web/WebMemoryPressureListener.h
@@ -0,0 +1,20 @@ +// 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. + +#ifndef WebMemoryPressureListener_h +#define WebMemoryPressureListener_h + +#include "public/platform/WebCommon.h" + +namespace blink { + +class WebMemoryPressureListener { +public: + // Called when a memory pressure notification is received. + BLINK_EXPORT static void onMemoryPressure(); +}; + +} // namespace blink + +#endif
diff --git a/third_party/WebKit/public/web/WebPlugin.h b/third_party/WebKit/public/web/WebPlugin.h index 0d979f46..dfeefbf7 100644 --- a/third_party/WebKit/public/web/WebPlugin.h +++ b/third_party/WebKit/public/web/WebPlugin.h
@@ -118,12 +118,6 @@ virtual void didFinishLoading() = 0; virtual void didFailLoading(const WebURLError&) = 0; - // Called in response to WebPluginContainer::loadFrameRequest - virtual void didFinishLoadingFrameRequest( - const WebURL&, void* notifyData) = 0; - virtual void didFailLoadingFrameRequest( - const WebURL&, void* notifyData, const WebURLError&) = 0; - // Printing interface. // Whether the plugin supports its own paginated print. The other print // interface methods are called only if this method returns true.
diff --git a/third_party/WebKit/public/web/WebPluginContainer.h b/third_party/WebKit/public/web/WebPluginContainer.h index b757702..46edc00 100644 --- a/third_party/WebKit/public/web/WebPluginContainer.h +++ b/third_party/WebKit/public/web/WebPluginContainer.h
@@ -106,7 +106,7 @@ // called if the load failed. The given notifyData is passed along to // the callback. virtual void loadFrameRequest( - const WebURLRequest&, const WebString& target, bool notifyNeeded, void* notifyData) = 0; + const WebURLRequest&, const WebString& target) = 0; // Determines whether the given rectangle in this plugin is above all other // content. The rectangle is in the plugin's coordinate system.
diff --git a/third_party/WebKit/public/web/WebRemoteFrameClient.h b/third_party/WebKit/public/web/WebRemoteFrameClient.h index 703943b..5a6a8248 100644 --- a/third_party/WebKit/public/web/WebRemoteFrameClient.h +++ b/third_party/WebKit/public/web/WebRemoteFrameClient.h
@@ -5,6 +5,7 @@ #ifndef WebRemoteFrameClient_h #define WebRemoteFrameClient_h +#include "public/platform/WebFocusType.h" #include "public/platform/WebSecurityOrigin.h" #include "public/web/WebDOMMessageEvent.h" @@ -48,6 +49,11 @@ // This frame updated its opener to another frame. virtual void didChangeOpener(WebFrame* opener) { } + + // Continue sequential focus navigation in this frame. This is called when + // the |source| frame is searching for the next focusable element (e.g., in + // response to <tab>) and encounters a remote frame. + virtual void advanceFocus(WebFocusType type, WebLocalFrame* source) { } }; } // namespace blink
diff --git a/third_party/WebKit/public/web/WebSettings.h b/third_party/WebKit/public/web/WebSettings.h index 93af9d1d..270b0cbe 100644 --- a/third_party/WebKit/public/web/WebSettings.h +++ b/third_party/WebKit/public/web/WebSettings.h
@@ -119,7 +119,6 @@ virtual void setAllowUniversalAccessFromFileURLs(bool) = 0; virtual void setAntialiased2dCanvasEnabled(bool) = 0; virtual void setAntialiasedClips2dCanvasEnabled(bool) = 0; - virtual void setAsynchronousSpellCheckingEnabled(bool) = 0; virtual void setAutoplayExperimentMode(const WebString&) = 0; virtual void setAutoZoomFocusedNodeToLegibleScale(bool) = 0; virtual void setCaretBrowsingEnabled(bool) = 0;
diff --git a/third_party/WebKit/public/web/WebView.h b/third_party/WebKit/public/web/WebView.h index 7a8867ca..843f6339 100644 --- a/third_party/WebKit/public/web/WebView.h +++ b/third_party/WebKit/public/web/WebView.h
@@ -33,6 +33,7 @@ #include "../platform/WebColor.h" #include "../platform/WebDisplayMode.h" +#include "../platform/WebFocusType.h" #include "../platform/WebPageVisibilityState.h" #include "../platform/WebString.h" #include "../platform/WebVector.h" @@ -50,9 +51,11 @@ class WebDragData; class WebFrame; class WebHitTestResult; +class WebLocalFrame; class WebPageImportanceSignals; class WebPageOverlay; class WebPrerendererClient; +class WebRemoteFrame; class WebSettings; class WebSpellCheckClient; class WebString; @@ -191,6 +194,11 @@ // previous element in the tab sequence (if reverse is true). virtual void advanceFocus(bool reverse) { } + // Advance the focus from the frame |from| to the next in sequence + // (determined by WebFocusType) focusable element in frame |to|. Used when + // focus needs to advance to/from a cross-process frame. + virtual void advanceFocusAcrossFrames(WebFocusType, WebRemoteFrame* from, WebLocalFrame* to) { } + // Animate a scale into the specified rect where multiple targets were // found from previous tap gesture. // Returns false if it doesn't do any zooming. @@ -391,6 +399,9 @@ // Shows a context menu for the currently focused element. virtual void showContextMenu() = 0; + // Notify that context menu has been closed. + virtual void didCloseContextMenu() = 0; + // SmartClip support --------------------------------------------------- virtual void extractSmartClipData(WebRect initRect, WebString& text, WebString& html, WebRect& resultRect) = 0;
diff --git a/third_party/boringssl/linux-x86_64/crypto/bn/x86_64-mont5.S b/third_party/boringssl/linux-x86_64/crypto/bn/x86_64-mont5.S index 02edc69b..214064e6 100644 --- a/third_party/boringssl/linux-x86_64/crypto/bn/x86_64-mont5.S +++ b/third_party/boringssl/linux-x86_64/crypto/bn/x86_64-mont5.S
@@ -1561,6 +1561,15 @@ .align 32 .L8x_tail_done: addq (%rdx),%r8 + adcq $0,%r9 + adcq $0,%r10 + adcq $0,%r11 + adcq $0,%r12 + adcq $0,%r13 + adcq $0,%r14 + adcq $0,%r15 + + xorq %rax,%rax negq %rsi
diff --git a/third_party/boringssl/linux-x86_64/crypto/ec/p256-x86_64-asm.S b/third_party/boringssl/linux-x86_64/crypto/ec/p256-x86_64-asm.S index db00544c..2884c69b 100644 --- a/third_party/boringssl/linux-x86_64/crypto/ec/p256-x86_64-asm.S +++ b/third_party/boringssl/linux-x86_64/crypto/ec/p256-x86_64-asm.S
@@ -8,10 +8,6 @@ .Lpoly: .quad 0xffffffffffffffff, 0x00000000ffffffff, 0x0000000000000000, 0xffffffff00000001 - -.LRR: -.quad 0x0000000000000003, 0xfffffffbffffffff, 0xfffffffffffffffe, 0x00000004fffffffd - .LOne: .long 1,1,1,1,1,1,1,1 .LTwo: @@ -21,8 +17,6 @@ .LONE_mont: .quad 0x0000000000000001, 0xffffffff00000000, 0xffffffffffffffff, 0x00000000fffffffe -.globl ecp_nistz256_mul_by_2 -.hidden ecp_nistz256_mul_by_2 .type ecp_nistz256_mul_by_2,@function .align 64 ecp_nistz256_mul_by_2: @@ -66,228 +60,6 @@ -.globl ecp_nistz256_div_by_2 -.hidden ecp_nistz256_div_by_2 -.type ecp_nistz256_div_by_2,@function -.align 32 -ecp_nistz256_div_by_2: - pushq %r12 - pushq %r13 - - movq 0(%rsi),%r8 - movq 8(%rsi),%r9 - movq 16(%rsi),%r10 - movq %r8,%rax - movq 24(%rsi),%r11 - leaq .Lpoly(%rip),%rsi - - movq %r9,%rdx - xorq %r13,%r13 - addq 0(%rsi),%r8 - movq %r10,%rcx - adcq 8(%rsi),%r9 - adcq 16(%rsi),%r10 - movq %r11,%r12 - adcq 24(%rsi),%r11 - adcq $0,%r13 - xorq %rsi,%rsi - testq $1,%rax - - cmovzq %rax,%r8 - cmovzq %rdx,%r9 - cmovzq %rcx,%r10 - cmovzq %r12,%r11 - cmovzq %rsi,%r13 - - movq %r9,%rax - shrq $1,%r8 - shlq $63,%rax - movq %r10,%rdx - shrq $1,%r9 - orq %rax,%r8 - shlq $63,%rdx - movq %r11,%rcx - shrq $1,%r10 - orq %rdx,%r9 - shlq $63,%rcx - shrq $1,%r11 - shlq $63,%r13 - orq %rcx,%r10 - orq %r13,%r11 - - movq %r8,0(%rdi) - movq %r9,8(%rdi) - movq %r10,16(%rdi) - movq %r11,24(%rdi) - - popq %r13 - popq %r12 - .byte 0xf3,0xc3 -.size ecp_nistz256_div_by_2,.-ecp_nistz256_div_by_2 - - - -.globl ecp_nistz256_mul_by_3 -.hidden ecp_nistz256_mul_by_3 -.type ecp_nistz256_mul_by_3,@function -.align 32 -ecp_nistz256_mul_by_3: - pushq %r12 - pushq %r13 - - movq 0(%rsi),%r8 - xorq %r13,%r13 - movq 8(%rsi),%r9 - addq %r8,%r8 - movq 16(%rsi),%r10 - adcq %r9,%r9 - movq 24(%rsi),%r11 - movq %r8,%rax - adcq %r10,%r10 - adcq %r11,%r11 - movq %r9,%rdx - adcq $0,%r13 - - subq $-1,%r8 - movq %r10,%rcx - sbbq .Lpoly+8(%rip),%r9 - sbbq $0,%r10 - movq %r11,%r12 - sbbq .Lpoly+24(%rip),%r11 - testq %r13,%r13 - - cmovzq %rax,%r8 - cmovzq %rdx,%r9 - cmovzq %rcx,%r10 - cmovzq %r12,%r11 - - xorq %r13,%r13 - addq 0(%rsi),%r8 - adcq 8(%rsi),%r9 - movq %r8,%rax - adcq 16(%rsi),%r10 - adcq 24(%rsi),%r11 - movq %r9,%rdx - adcq $0,%r13 - - subq $-1,%r8 - movq %r10,%rcx - sbbq .Lpoly+8(%rip),%r9 - sbbq $0,%r10 - movq %r11,%r12 - sbbq .Lpoly+24(%rip),%r11 - testq %r13,%r13 - - cmovzq %rax,%r8 - cmovzq %rdx,%r9 - movq %r8,0(%rdi) - cmovzq %rcx,%r10 - movq %r9,8(%rdi) - cmovzq %r12,%r11 - movq %r10,16(%rdi) - movq %r11,24(%rdi) - - popq %r13 - popq %r12 - .byte 0xf3,0xc3 -.size ecp_nistz256_mul_by_3,.-ecp_nistz256_mul_by_3 - - - -.globl ecp_nistz256_add -.hidden ecp_nistz256_add -.type ecp_nistz256_add,@function -.align 32 -ecp_nistz256_add: - pushq %r12 - pushq %r13 - - movq 0(%rsi),%r8 - xorq %r13,%r13 - movq 8(%rsi),%r9 - movq 16(%rsi),%r10 - movq 24(%rsi),%r11 - leaq .Lpoly(%rip),%rsi - - addq 0(%rdx),%r8 - adcq 8(%rdx),%r9 - movq %r8,%rax - adcq 16(%rdx),%r10 - adcq 24(%rdx),%r11 - movq %r9,%rdx - adcq $0,%r13 - - subq 0(%rsi),%r8 - movq %r10,%rcx - sbbq 8(%rsi),%r9 - sbbq 16(%rsi),%r10 - movq %r11,%r12 - sbbq 24(%rsi),%r11 - testq %r13,%r13 - - cmovzq %rax,%r8 - cmovzq %rdx,%r9 - movq %r8,0(%rdi) - cmovzq %rcx,%r10 - movq %r9,8(%rdi) - cmovzq %r12,%r11 - movq %r10,16(%rdi) - movq %r11,24(%rdi) - - popq %r13 - popq %r12 - .byte 0xf3,0xc3 -.size ecp_nistz256_add,.-ecp_nistz256_add - - - -.globl ecp_nistz256_sub -.hidden ecp_nistz256_sub -.type ecp_nistz256_sub,@function -.align 32 -ecp_nistz256_sub: - pushq %r12 - pushq %r13 - - movq 0(%rsi),%r8 - xorq %r13,%r13 - movq 8(%rsi),%r9 - movq 16(%rsi),%r10 - movq 24(%rsi),%r11 - leaq .Lpoly(%rip),%rsi - - subq 0(%rdx),%r8 - sbbq 8(%rdx),%r9 - movq %r8,%rax - sbbq 16(%rdx),%r10 - sbbq 24(%rdx),%r11 - movq %r9,%rdx - sbbq $0,%r13 - - addq 0(%rsi),%r8 - movq %r10,%rcx - adcq 8(%rsi),%r9 - adcq 16(%rsi),%r10 - movq %r11,%r12 - adcq 24(%rsi),%r11 - testq %r13,%r13 - - cmovzq %rax,%r8 - cmovzq %rdx,%r9 - movq %r8,0(%rdi) - cmovzq %rcx,%r10 - movq %r9,8(%rdi) - cmovzq %r12,%r11 - movq %r10,16(%rdi) - movq %r11,24(%rdi) - - popq %r13 - popq %r12 - .byte 0xf3,0xc3 -.size ecp_nistz256_sub,.-ecp_nistz256_sub - - - .globl ecp_nistz256_neg .hidden ecp_nistz256_neg .type ecp_nistz256_neg,@function @@ -336,19 +108,6 @@ -.globl ecp_nistz256_to_mont -.hidden ecp_nistz256_to_mont -.type ecp_nistz256_to_mont,@function -.align 32 -ecp_nistz256_to_mont: - leaq .LRR(%rip),%rdx - jmp .Lmul_mont -.size ecp_nistz256_to_mont,.-ecp_nistz256_to_mont - - - - - .globl ecp_nistz256_mul_mont
diff --git a/third_party/boringssl/mac-x86_64/crypto/bn/x86_64-mont5.S b/third_party/boringssl/mac-x86_64/crypto/bn/x86_64-mont5.S index 2e8f469c..461bfb2 100644 --- a/third_party/boringssl/mac-x86_64/crypto/bn/x86_64-mont5.S +++ b/third_party/boringssl/mac-x86_64/crypto/bn/x86_64-mont5.S
@@ -1560,6 +1560,15 @@ .p2align 5 L$8x_tail_done: addq (%rdx),%r8 + adcq $0,%r9 + adcq $0,%r10 + adcq $0,%r11 + adcq $0,%r12 + adcq $0,%r13 + adcq $0,%r14 + adcq $0,%r15 + + xorq %rax,%rax negq %rsi
diff --git a/third_party/boringssl/mac-x86_64/crypto/ec/p256-x86_64-asm.S b/third_party/boringssl/mac-x86_64/crypto/ec/p256-x86_64-asm.S index 43f7dff..bed1130 100644 --- a/third_party/boringssl/mac-x86_64/crypto/ec/p256-x86_64-asm.S +++ b/third_party/boringssl/mac-x86_64/crypto/ec/p256-x86_64-asm.S
@@ -7,10 +7,6 @@ L$poly: .quad 0xffffffffffffffff, 0x00000000ffffffff, 0x0000000000000000, 0xffffffff00000001 - -L$RR: -.quad 0x0000000000000003, 0xfffffffbffffffff, 0xfffffffffffffffe, 0x00000004fffffffd - L$One: .long 1,1,1,1,1,1,1,1 L$Two: @@ -20,11 +16,9 @@ L$ONE_mont: .quad 0x0000000000000001, 0xffffffff00000000, 0xffffffffffffffff, 0x00000000fffffffe -.globl _ecp_nistz256_mul_by_2 -.private_extern _ecp_nistz256_mul_by_2 .p2align 6 -_ecp_nistz256_mul_by_2: +ecp_nistz256_mul_by_2: pushq %r12 pushq %r13 @@ -65,228 +59,6 @@ -.globl _ecp_nistz256_div_by_2 -.private_extern _ecp_nistz256_div_by_2 - -.p2align 5 -_ecp_nistz256_div_by_2: - pushq %r12 - pushq %r13 - - movq 0(%rsi),%r8 - movq 8(%rsi),%r9 - movq 16(%rsi),%r10 - movq %r8,%rax - movq 24(%rsi),%r11 - leaq L$poly(%rip),%rsi - - movq %r9,%rdx - xorq %r13,%r13 - addq 0(%rsi),%r8 - movq %r10,%rcx - adcq 8(%rsi),%r9 - adcq 16(%rsi),%r10 - movq %r11,%r12 - adcq 24(%rsi),%r11 - adcq $0,%r13 - xorq %rsi,%rsi - testq $1,%rax - - cmovzq %rax,%r8 - cmovzq %rdx,%r9 - cmovzq %rcx,%r10 - cmovzq %r12,%r11 - cmovzq %rsi,%r13 - - movq %r9,%rax - shrq $1,%r8 - shlq $63,%rax - movq %r10,%rdx - shrq $1,%r9 - orq %rax,%r8 - shlq $63,%rdx - movq %r11,%rcx - shrq $1,%r10 - orq %rdx,%r9 - shlq $63,%rcx - shrq $1,%r11 - shlq $63,%r13 - orq %rcx,%r10 - orq %r13,%r11 - - movq %r8,0(%rdi) - movq %r9,8(%rdi) - movq %r10,16(%rdi) - movq %r11,24(%rdi) - - popq %r13 - popq %r12 - .byte 0xf3,0xc3 - - - - -.globl _ecp_nistz256_mul_by_3 -.private_extern _ecp_nistz256_mul_by_3 - -.p2align 5 -_ecp_nistz256_mul_by_3: - pushq %r12 - pushq %r13 - - movq 0(%rsi),%r8 - xorq %r13,%r13 - movq 8(%rsi),%r9 - addq %r8,%r8 - movq 16(%rsi),%r10 - adcq %r9,%r9 - movq 24(%rsi),%r11 - movq %r8,%rax - adcq %r10,%r10 - adcq %r11,%r11 - movq %r9,%rdx - adcq $0,%r13 - - subq $-1,%r8 - movq %r10,%rcx - sbbq L$poly+8(%rip),%r9 - sbbq $0,%r10 - movq %r11,%r12 - sbbq L$poly+24(%rip),%r11 - testq %r13,%r13 - - cmovzq %rax,%r8 - cmovzq %rdx,%r9 - cmovzq %rcx,%r10 - cmovzq %r12,%r11 - - xorq %r13,%r13 - addq 0(%rsi),%r8 - adcq 8(%rsi),%r9 - movq %r8,%rax - adcq 16(%rsi),%r10 - adcq 24(%rsi),%r11 - movq %r9,%rdx - adcq $0,%r13 - - subq $-1,%r8 - movq %r10,%rcx - sbbq L$poly+8(%rip),%r9 - sbbq $0,%r10 - movq %r11,%r12 - sbbq L$poly+24(%rip),%r11 - testq %r13,%r13 - - cmovzq %rax,%r8 - cmovzq %rdx,%r9 - movq %r8,0(%rdi) - cmovzq %rcx,%r10 - movq %r9,8(%rdi) - cmovzq %r12,%r11 - movq %r10,16(%rdi) - movq %r11,24(%rdi) - - popq %r13 - popq %r12 - .byte 0xf3,0xc3 - - - - -.globl _ecp_nistz256_add -.private_extern _ecp_nistz256_add - -.p2align 5 -_ecp_nistz256_add: - pushq %r12 - pushq %r13 - - movq 0(%rsi),%r8 - xorq %r13,%r13 - movq 8(%rsi),%r9 - movq 16(%rsi),%r10 - movq 24(%rsi),%r11 - leaq L$poly(%rip),%rsi - - addq 0(%rdx),%r8 - adcq 8(%rdx),%r9 - movq %r8,%rax - adcq 16(%rdx),%r10 - adcq 24(%rdx),%r11 - movq %r9,%rdx - adcq $0,%r13 - - subq 0(%rsi),%r8 - movq %r10,%rcx - sbbq 8(%rsi),%r9 - sbbq 16(%rsi),%r10 - movq %r11,%r12 - sbbq 24(%rsi),%r11 - testq %r13,%r13 - - cmovzq %rax,%r8 - cmovzq %rdx,%r9 - movq %r8,0(%rdi) - cmovzq %rcx,%r10 - movq %r9,8(%rdi) - cmovzq %r12,%r11 - movq %r10,16(%rdi) - movq %r11,24(%rdi) - - popq %r13 - popq %r12 - .byte 0xf3,0xc3 - - - - -.globl _ecp_nistz256_sub -.private_extern _ecp_nistz256_sub - -.p2align 5 -_ecp_nistz256_sub: - pushq %r12 - pushq %r13 - - movq 0(%rsi),%r8 - xorq %r13,%r13 - movq 8(%rsi),%r9 - movq 16(%rsi),%r10 - movq 24(%rsi),%r11 - leaq L$poly(%rip),%rsi - - subq 0(%rdx),%r8 - sbbq 8(%rdx),%r9 - movq %r8,%rax - sbbq 16(%rdx),%r10 - sbbq 24(%rdx),%r11 - movq %r9,%rdx - sbbq $0,%r13 - - addq 0(%rsi),%r8 - movq %r10,%rcx - adcq 8(%rsi),%r9 - adcq 16(%rsi),%r10 - movq %r11,%r12 - adcq 24(%rsi),%r11 - testq %r13,%r13 - - cmovzq %rax,%r8 - cmovzq %rdx,%r9 - movq %r8,0(%rdi) - cmovzq %rcx,%r10 - movq %r9,8(%rdi) - cmovzq %r12,%r11 - movq %r10,16(%rdi) - movq %r11,24(%rdi) - - popq %r13 - popq %r12 - .byte 0xf3,0xc3 - - - - .globl _ecp_nistz256_neg .private_extern _ecp_nistz256_neg @@ -335,19 +107,6 @@ -.globl _ecp_nistz256_to_mont -.private_extern _ecp_nistz256_to_mont - -.p2align 5 -_ecp_nistz256_to_mont: - leaq L$RR(%rip),%rdx - jmp L$mul_mont - - - - - - .globl _ecp_nistz256_mul_mont
diff --git a/third_party/boringssl/win-x86_64/crypto/bn/x86_64-mont5.asm b/third_party/boringssl/win-x86_64/crypto/bn/x86_64-mont5.asm index 284318a..560b384 100644 --- a/third_party/boringssl/win-x86_64/crypto/bn/x86_64-mont5.asm +++ b/third_party/boringssl/win-x86_64/crypto/bn/x86_64-mont5.asm
@@ -1616,6 +1616,15 @@ ALIGN 32 $L$8x_tail_done: add r8,QWORD[rdx] + adc r9,0 + adc r10,0 + adc r11,0 + adc r12,0 + adc r13,0 + adc r14,0 + adc r15,0 + + xor rax,rax neg rsi
diff --git a/third_party/boringssl/win-x86_64/crypto/ec/p256-x86_64-asm.asm b/third_party/boringssl/win-x86_64/crypto/ec/p256-x86_64-asm.asm index c9789f5..45ba686c 100644 --- a/third_party/boringssl/win-x86_64/crypto/ec/p256-x86_64-asm.asm +++ b/third_party/boringssl/win-x86_64/crypto/ec/p256-x86_64-asm.asm
@@ -11,10 +11,6 @@ $L$poly: DQ 0xffffffffffffffff,0x00000000ffffffff,0x0000000000000000,0xffffffff00000001 - -$L$RR: - DQ 0x0000000000000003,0xfffffffbffffffff,0xfffffffffffffffe,0x00000004fffffffd - $L$One: DD 1,1,1,1,1,1,1,1 $L$Two: @@ -24,7 +20,6 @@ $L$ONE_mont: DQ 0x0000000000000001,0xffffffff00000000,0xffffffffffffffff,0x00000000fffffffe -global ecp_nistz256_mul_by_2 ALIGN 64 ecp_nistz256_mul_by_2: @@ -78,266 +73,6 @@ -global ecp_nistz256_div_by_2 - -ALIGN 32 -ecp_nistz256_div_by_2: - mov QWORD[8+rsp],rdi ;WIN64 prologue - mov QWORD[16+rsp],rsi - mov rax,rsp -$L$SEH_begin_ecp_nistz256_div_by_2: - mov rdi,rcx - mov rsi,rdx - - - push r12 - push r13 - - mov r8,QWORD[rsi] - mov r9,QWORD[8+rsi] - mov r10,QWORD[16+rsi] - mov rax,r8 - mov r11,QWORD[24+rsi] - lea rsi,[$L$poly] - - mov rdx,r9 - xor r13,r13 - add r8,QWORD[rsi] - mov rcx,r10 - adc r9,QWORD[8+rsi] - adc r10,QWORD[16+rsi] - mov r12,r11 - adc r11,QWORD[24+rsi] - adc r13,0 - xor rsi,rsi - test rax,1 - - cmovz r8,rax - cmovz r9,rdx - cmovz r10,rcx - cmovz r11,r12 - cmovz r13,rsi - - mov rax,r9 - shr r8,1 - shl rax,63 - mov rdx,r10 - shr r9,1 - or r8,rax - shl rdx,63 - mov rcx,r11 - shr r10,1 - or r9,rdx - shl rcx,63 - shr r11,1 - shl r13,63 - or r10,rcx - or r11,r13 - - mov QWORD[rdi],r8 - mov QWORD[8+rdi],r9 - mov QWORD[16+rdi],r10 - mov QWORD[24+rdi],r11 - - pop r13 - pop r12 - mov rdi,QWORD[8+rsp] ;WIN64 epilogue - mov rsi,QWORD[16+rsp] - DB 0F3h,0C3h ;repret -$L$SEH_end_ecp_nistz256_div_by_2: - - - -global ecp_nistz256_mul_by_3 - -ALIGN 32 -ecp_nistz256_mul_by_3: - mov QWORD[8+rsp],rdi ;WIN64 prologue - mov QWORD[16+rsp],rsi - mov rax,rsp -$L$SEH_begin_ecp_nistz256_mul_by_3: - mov rdi,rcx - mov rsi,rdx - - - push r12 - push r13 - - mov r8,QWORD[rsi] - xor r13,r13 - mov r9,QWORD[8+rsi] - add r8,r8 - mov r10,QWORD[16+rsi] - adc r9,r9 - mov r11,QWORD[24+rsi] - mov rax,r8 - adc r10,r10 - adc r11,r11 - mov rdx,r9 - adc r13,0 - - sub r8,-1 - mov rcx,r10 - sbb r9,QWORD[(($L$poly+8))] - sbb r10,0 - mov r12,r11 - sbb r11,QWORD[(($L$poly+24))] - test r13,r13 - - cmovz r8,rax - cmovz r9,rdx - cmovz r10,rcx - cmovz r11,r12 - - xor r13,r13 - add r8,QWORD[rsi] - adc r9,QWORD[8+rsi] - mov rax,r8 - adc r10,QWORD[16+rsi] - adc r11,QWORD[24+rsi] - mov rdx,r9 - adc r13,0 - - sub r8,-1 - mov rcx,r10 - sbb r9,QWORD[(($L$poly+8))] - sbb r10,0 - mov r12,r11 - sbb r11,QWORD[(($L$poly+24))] - test r13,r13 - - cmovz r8,rax - cmovz r9,rdx - mov QWORD[rdi],r8 - cmovz r10,rcx - mov QWORD[8+rdi],r9 - cmovz r11,r12 - mov QWORD[16+rdi],r10 - mov QWORD[24+rdi],r11 - - pop r13 - pop r12 - mov rdi,QWORD[8+rsp] ;WIN64 epilogue - mov rsi,QWORD[16+rsp] - DB 0F3h,0C3h ;repret -$L$SEH_end_ecp_nistz256_mul_by_3: - - - -global ecp_nistz256_add - -ALIGN 32 -ecp_nistz256_add: - mov QWORD[8+rsp],rdi ;WIN64 prologue - mov QWORD[16+rsp],rsi - mov rax,rsp -$L$SEH_begin_ecp_nistz256_add: - mov rdi,rcx - mov rsi,rdx - mov rdx,r8 - - - push r12 - push r13 - - mov r8,QWORD[rsi] - xor r13,r13 - mov r9,QWORD[8+rsi] - mov r10,QWORD[16+rsi] - mov r11,QWORD[24+rsi] - lea rsi,[$L$poly] - - add r8,QWORD[rdx] - adc r9,QWORD[8+rdx] - mov rax,r8 - adc r10,QWORD[16+rdx] - adc r11,QWORD[24+rdx] - mov rdx,r9 - adc r13,0 - - sub r8,QWORD[rsi] - mov rcx,r10 - sbb r9,QWORD[8+rsi] - sbb r10,QWORD[16+rsi] - mov r12,r11 - sbb r11,QWORD[24+rsi] - test r13,r13 - - cmovz r8,rax - cmovz r9,rdx - mov QWORD[rdi],r8 - cmovz r10,rcx - mov QWORD[8+rdi],r9 - cmovz r11,r12 - mov QWORD[16+rdi],r10 - mov QWORD[24+rdi],r11 - - pop r13 - pop r12 - mov rdi,QWORD[8+rsp] ;WIN64 epilogue - mov rsi,QWORD[16+rsp] - DB 0F3h,0C3h ;repret -$L$SEH_end_ecp_nistz256_add: - - - -global ecp_nistz256_sub - -ALIGN 32 -ecp_nistz256_sub: - mov QWORD[8+rsp],rdi ;WIN64 prologue - mov QWORD[16+rsp],rsi - mov rax,rsp -$L$SEH_begin_ecp_nistz256_sub: - mov rdi,rcx - mov rsi,rdx - mov rdx,r8 - - - push r12 - push r13 - - mov r8,QWORD[rsi] - xor r13,r13 - mov r9,QWORD[8+rsi] - mov r10,QWORD[16+rsi] - mov r11,QWORD[24+rsi] - lea rsi,[$L$poly] - - sub r8,QWORD[rdx] - sbb r9,QWORD[8+rdx] - mov rax,r8 - sbb r10,QWORD[16+rdx] - sbb r11,QWORD[24+rdx] - mov rdx,r9 - sbb r13,0 - - add r8,QWORD[rsi] - mov rcx,r10 - adc r9,QWORD[8+rsi] - adc r10,QWORD[16+rsi] - mov r12,r11 - adc r11,QWORD[24+rsi] - test r13,r13 - - cmovz r8,rax - cmovz r9,rdx - mov QWORD[rdi],r8 - cmovz r10,rcx - mov QWORD[8+rdi],r9 - cmovz r11,r12 - mov QWORD[16+rdi],r10 - mov QWORD[24+rdi],r11 - - pop r13 - pop r12 - mov rdi,QWORD[8+rsp] ;WIN64 epilogue - mov rsi,QWORD[16+rsp] - DB 0F3h,0C3h ;repret -$L$SEH_end_ecp_nistz256_sub: - - - global ecp_nistz256_neg ALIGN 32 @@ -395,26 +130,6 @@ -global ecp_nistz256_to_mont - -ALIGN 32 -ecp_nistz256_to_mont: - mov QWORD[8+rsp],rdi ;WIN64 prologue - mov QWORD[16+rsp],rsi - mov rax,rsp -$L$SEH_begin_ecp_nistz256_to_mont: - mov rdi,rcx - mov rsi,rdx - - - lea rdx,[$L$RR] - jmp NEAR $L$mul_mont -$L$SEH_end_ecp_nistz256_to_mont: - - - - - global ecp_nistz256_mul_mont
diff --git a/third_party/mojo/src/mojo/edk/embedder/embedder.cc b/third_party/mojo/src/mojo/edk/embedder/embedder.cc index 9daa0517..692547ac 100644 --- a/third_party/mojo/src/mojo/edk/embedder/embedder.cc +++ b/third_party/mojo/src/mojo/edk/embedder/embedder.cc
@@ -4,6 +4,8 @@ #include "third_party/mojo/src/mojo/edk/embedder/embedder.h" +#include <utility> + #include "base/atomicops.h" #include "base/bind.h" #include "base/bind_helpers.h" @@ -283,7 +285,7 @@ scoped_refptr<system::MessagePipeDispatcher> dispatcher = internal::g_ipc_support->ConnectToSlave( connection_id, slave_info, platform_handle.Pass(), - did_connect_to_slave_callback, did_connect_to_slave_runner.Pass(), + did_connect_to_slave_callback, std::move(did_connect_to_slave_runner), &channel_id); *channel_info = new ChannelInfo(channel_id); @@ -312,7 +314,7 @@ scoped_refptr<system::MessagePipeDispatcher> dispatcher = internal::g_ipc_support->ConnectToMaster( connection_id, did_connect_to_master_callback, - did_connect_to_master_runner.Pass(), &channel_id); + std::move(did_connect_to_master_runner), &channel_id); *channel_info = new ChannelInfo(channel_id); ScopedMessagePipeHandle rv(
diff --git a/third_party/mojo/src/mojo/edk/system/channel.cc b/third_party/mojo/src/mojo/edk/system/channel.cc index b0101b5c..0b3e9f85 100644 --- a/third_party/mojo/src/mojo/edk/system/channel.cc +++ b/third_party/mojo/src/mojo/edk/system/channel.cc
@@ -5,6 +5,7 @@ #include "third_party/mojo/src/mojo/edk/system/channel.h" #include <algorithm> +#include <utility> #include "base/bind.h" #include "base/logging.h" @@ -126,7 +127,7 @@ void Channel::SetBootstrapEndpoint(scoped_refptr<ChannelEndpoint> endpoint) { // Used for both local and remote IDs. ChannelEndpointId bootstrap_id = ChannelEndpointId::GetBootstrap(); - SetBootstrapEndpointWithIds(endpoint.Pass(), bootstrap_id, bootstrap_id); + SetBootstrapEndpointWithIds(std::move(endpoint), bootstrap_id, bootstrap_id); } void Channel::SetBootstrapEndpointWithIds(
diff --git a/third_party/mojo/src/mojo/edk/system/ipc_support.cc b/third_party/mojo/src/mojo/edk/system/ipc_support.cc index ba4f05f..1738578 100644 --- a/third_party/mojo/src/mojo/edk/system/ipc_support.cc +++ b/third_party/mojo/src/mojo/edk/system/ipc_support.cc
@@ -4,6 +4,8 @@ #include "third_party/mojo/src/mojo/edk/system/ipc_support.h" +#include <utility> + #include "base/logging.h" #include "third_party/mojo/src/mojo/edk/embedder/master_process_delegate.h" #include "third_party/mojo/src/mojo/edk/embedder/slave_process_delegate.h" @@ -15,15 +17,14 @@ namespace mojo { namespace system { -IPCSupport::IPCSupport( - embedder::PlatformSupport* platform_support, - embedder::ProcessType process_type, - embedder::ProcessDelegate* process_delegate, - scoped_refptr<base::TaskRunner> io_thread_task_runner, - embedder::ScopedPlatformHandle platform_handle) +IPCSupport::IPCSupport(embedder::PlatformSupport* platform_support, + embedder::ProcessType process_type, + embedder::ProcessDelegate* process_delegate, + scoped_refptr<base::TaskRunner> io_thread_task_runner, + embedder::ScopedPlatformHandle platform_handle) : process_type_(process_type), process_delegate_(process_delegate), - io_thread_task_runner_(io_thread_task_runner.Pass()) { + io_thread_task_runner_(std::move(io_thread_task_runner)) { DCHECK(io_thread_task_runner_); switch (process_type_) {
diff --git a/third_party/mojo/src/mojo/edk/system/ipc_support_unittest.cc b/third_party/mojo/src/mojo/edk/system/ipc_support_unittest.cc index 2df558e..4ebaafd 100644 --- a/third_party/mojo/src/mojo/edk/system/ipc_support_unittest.cc +++ b/third_party/mojo/src/mojo/edk/system/ipc_support_unittest.cc
@@ -319,11 +319,11 @@ } scoped_refptr<MessagePipeDispatcher> PassMasterMessagePipe() { - return master_mp_.Pass(); + return std::move(master_mp_); } scoped_refptr<MessagePipeDispatcher> PassSlaveMessagePipe() { - return slave_mp_.Pass(); + return std::move(slave_mp_); } void Shutdown() { @@ -652,7 +652,8 @@ embedder::ScopedPlatformHandle second_platform_handle = master_ipc_support().ConnectToSlaveInternal( connection_id, nullptr, - multiprocess_test_helper.server_platform_handle.Pass(), &slave_id); + std::move(multiprocess_test_helper.server_platform_handle), + &slave_id); ASSERT_TRUE(second_platform_handle.is_valid()); EXPECT_NE(slave_id, kInvalidProcessIdentifier); EXPECT_NE(slave_id, kMasterProcessIdentifier); @@ -682,7 +683,7 @@ MOJO_MULTIPROCESS_TEST_CHILD_TEST(MultiprocessMasterSlaveInternal) { embedder::ScopedPlatformHandle client_platform_handle = - mojo::test::MultiprocessTestHelper::client_platform_handle.Pass(); + std::move(mojo::test::MultiprocessTestHelper::client_platform_handle); ASSERT_TRUE(client_platform_handle.is_valid()); embedder::SimplePlatformSupport platform_support; @@ -692,7 +693,7 @@ // Note: Run process delegate methods on the I/O thread. IPCSupport ipc_support(&platform_support, embedder::ProcessType::SLAVE, &slave_process_delegate, test_io_thread.task_runner(), - client_platform_handle.Pass()); + std::move(client_platform_handle)); const base::CommandLine& command_line = *base::CommandLine::ForCurrentProcess();
diff --git a/third_party/mojo/src/mojo/edk/system/shared_buffer_dispatcher.cc b/third_party/mojo/src/mojo/edk/system/shared_buffer_dispatcher.cc index 75c85cfa..8c64e1a 100644 --- a/third_party/mojo/src/mojo/edk/system/shared_buffer_dispatcher.cc +++ b/third_party/mojo/src/mojo/edk/system/shared_buffer_dispatcher.cc
@@ -5,6 +5,7 @@ #include "third_party/mojo/src/mojo/edk/system/shared_buffer_dispatcher.h" #include <limits> +#include <utility> #include "base/logging.h" #include "base/memory/scoped_ptr.h" @@ -77,7 +78,7 @@ if (!shared_buffer) return MOJO_RESULT_RESOURCE_EXHAUSTED; - *result = CreateInternal(shared_buffer.Pass()); + *result = CreateInternal(std::move(shared_buffer)); return MOJO_RESULT_OK; } @@ -132,7 +133,7 @@ return nullptr; } - return CreateInternal(shared_buffer.Pass()); + return CreateInternal(std::move(shared_buffer)); } SharedBufferDispatcher::SharedBufferDispatcher( @@ -186,7 +187,7 @@ SharedBufferDispatcher::CreateEquivalentDispatcherAndCloseImplNoLock() { mutex().AssertHeld(); DCHECK(shared_buffer_); - return CreateInternal(shared_buffer_.Pass()); + return CreateInternal(std::move(shared_buffer_)); } MojoResult SharedBufferDispatcher::DuplicateBufferHandleImplNoLock(
diff --git a/third_party/mojo/src/mojo/edk/system/shared_buffer_dispatcher.h b/third_party/mojo/src/mojo/edk/system/shared_buffer_dispatcher.h index 3e6d4f25..49fda03 100644 --- a/third_party/mojo/src/mojo/edk/system/shared_buffer_dispatcher.h +++ b/third_party/mojo/src/mojo/edk/system/shared_buffer_dispatcher.h
@@ -5,6 +5,8 @@ #ifndef THIRD_PARTY_MOJO_SRC_MOJO_EDK_SYSTEM_SHARED_BUFFER_DISPATCHER_H_ #define THIRD_PARTY_MOJO_SRC_MOJO_EDK_SYSTEM_SHARED_BUFFER_DISPATCHER_H_ +#include <utility> + #include "mojo/public/cpp/system/macros.h" #include "third_party/mojo/src/mojo/edk/embedder/platform_shared_buffer.h" #include "third_party/mojo/src/mojo/edk/system/memory.h" @@ -63,7 +65,8 @@ private: static scoped_refptr<SharedBufferDispatcher> CreateInternal( scoped_refptr<embedder::PlatformSharedBuffer> shared_buffer) { - return make_scoped_refptr(new SharedBufferDispatcher(shared_buffer.Pass())); + return make_scoped_refptr( + new SharedBufferDispatcher(std::move(shared_buffer))); } explicit SharedBufferDispatcher(
diff --git a/third_party/mojo/src/mojo/edk/test/scoped_ipc_support.cc b/third_party/mojo/src/mojo/edk/test/scoped_ipc_support.cc index 4965b940..e5e338c1 100644 --- a/third_party/mojo/src/mojo/edk/test/scoped_ipc_support.cc +++ b/third_party/mojo/src/mojo/edk/test/scoped_ipc_support.cc
@@ -4,6 +4,8 @@ #include "third_party/mojo/src/mojo/edk/test/scoped_ipc_support.h" +#include <utility> + #include "base/message_loop/message_loop.h" #include "third_party/mojo/src/mojo/edk/embedder/embedder.h" @@ -33,7 +35,7 @@ io_thread_task_runner_ = io_thread_task_runner; // Note: Run delegate methods on the I/O thread. embedder::InitIPCSupport(process_type, process_delegate, - io_thread_task_runner_, platform_handle.Pass()); + io_thread_task_runner_, std::move(platform_handle)); } void ScopedIPCSupportHelper::OnShutdownCompleteImpl() { @@ -44,7 +46,8 @@ ScopedIPCSupport::ScopedIPCSupport( scoped_refptr<base::TaskRunner> io_thread_task_runner) { - helper_.Init(embedder::ProcessType::NONE, this, io_thread_task_runner.Pass(), + helper_.Init(embedder::ProcessType::NONE, this, + std::move(io_thread_task_runner), embedder::ScopedPlatformHandle()); } @@ -58,7 +61,8 @@ ScopedMasterIPCSupport::ScopedMasterIPCSupport( scoped_refptr<base::TaskRunner> io_thread_task_runner) { helper_.Init(embedder::ProcessType::MASTER, this, - io_thread_task_runner.Pass(), embedder::ScopedPlatformHandle()); + std::move(io_thread_task_runner), + embedder::ScopedPlatformHandle()); } ScopedMasterIPCSupport::ScopedMasterIPCSupport( @@ -66,7 +70,8 @@ base::Callback<void(embedder::SlaveInfo slave_info)> on_slave_disconnect) : on_slave_disconnect_(on_slave_disconnect) { helper_.Init(embedder::ProcessType::MASTER, this, - io_thread_task_runner.Pass(), embedder::ScopedPlatformHandle()); + std::move(io_thread_task_runner), + embedder::ScopedPlatformHandle()); } ScopedMasterIPCSupport::~ScopedMasterIPCSupport() { @@ -84,8 +89,8 @@ ScopedSlaveIPCSupport::ScopedSlaveIPCSupport( scoped_refptr<base::TaskRunner> io_thread_task_runner, embedder::ScopedPlatformHandle platform_handle) { - helper_.Init(embedder::ProcessType::SLAVE, this, io_thread_task_runner.Pass(), - platform_handle.Pass()); + helper_.Init(embedder::ProcessType::SLAVE, this, + std::move(io_thread_task_runner), std::move(platform_handle)); } ScopedSlaveIPCSupport::ScopedSlaveIPCSupport( @@ -93,8 +98,8 @@ embedder::ScopedPlatformHandle platform_handle, base::Closure on_master_disconnect) : on_master_disconnect_(on_master_disconnect) { - helper_.Init(embedder::ProcessType::SLAVE, this, io_thread_task_runner.Pass(), - platform_handle.Pass()); + helper_.Init(embedder::ProcessType::SLAVE, this, + std::move(io_thread_task_runner), std::move(platform_handle)); } ScopedSlaveIPCSupport::~ScopedSlaveIPCSupport() {
diff --git a/third_party/mojo/src/mojo/public/c/gles2/gles2_call_visitor_chromium_extension_autogen.h b/third_party/mojo/src/mojo/public/c/gles2/gles2_call_visitor_chromium_extension_autogen.h new file mode 100644 index 0000000..88ab603a --- /dev/null +++ b/third_party/mojo/src/mojo/public/c/gles2/gles2_call_visitor_chromium_extension_autogen.h
@@ -0,0 +1,568 @@ +// Copyright 2014 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// This file is auto-generated from +// gpu/command_buffer/build_gles2_cmd_buffer.py +// It's formatted by clang-format using chromium coding style: +// clang-format -i -style=chromium filename +// DO NOT EDIT! + +VISIT_GL_CALL(ShallowFinishCHROMIUM, void, (), ()) +VISIT_GL_CALL(ShallowFlushCHROMIUM, void, (), ()) +VISIT_GL_CALL(OrderingBarrierCHROMIUM, void, (), ()) +VISIT_GL_CALL( + BlitFramebufferCHROMIUM, + void, + (GLint srcX0, + GLint srcY0, + GLint srcX1, + GLint srcY1, + GLint dstX0, + GLint dstY0, + GLint dstX1, + GLint dstY1, + GLbitfield mask, + GLenum filter), + (srcX0, srcY0, srcX1, srcY1, dstX0, dstY0, dstX1, dstY1, mask, filter)) +VISIT_GL_CALL(RenderbufferStorageMultisampleCHROMIUM, + void, + (GLenum target, + GLsizei samples, + GLenum internalformat, + GLsizei width, + GLsizei height), + (target, samples, internalformat, width, height)) +VISIT_GL_CALL(RenderbufferStorageMultisampleEXT, + void, + (GLenum target, + GLsizei samples, + GLenum internalformat, + GLsizei width, + GLsizei height), + (target, samples, internalformat, width, height)) +VISIT_GL_CALL(FramebufferTexture2DMultisampleEXT, + void, + (GLenum target, + GLenum attachment, + GLenum textarget, + GLuint texture, + GLint level, + GLsizei samples), + (target, attachment, textarget, texture, level, samples)) +VISIT_GL_CALL(TexStorage2DEXT, + void, + (GLenum target, + GLsizei levels, + GLenum internalFormat, + GLsizei width, + GLsizei height), + (target, levels, internalFormat, width, height)) +VISIT_GL_CALL(GenQueriesEXT, void, (GLsizei n, GLuint* queries), (n, queries)) +VISIT_GL_CALL(DeleteQueriesEXT, + void, + (GLsizei n, const GLuint* queries), + (n, queries)) +VISIT_GL_CALL(QueryCounterEXT, void, (GLuint id, GLenum target), (id, target)) +VISIT_GL_CALL(IsQueryEXT, GLboolean, (GLuint id), (id)) +VISIT_GL_CALL(BeginQueryEXT, void, (GLenum target, GLuint id), (target, id)) +VISIT_GL_CALL(EndQueryEXT, void, (GLenum target), (target)) +VISIT_GL_CALL(GetQueryivEXT, + void, + (GLenum target, GLenum pname, GLint* params), + (target, pname, params)) +VISIT_GL_CALL(GetQueryObjectivEXT, + void, + (GLuint id, GLenum pname, GLint* params), + (id, pname, params)) +VISIT_GL_CALL(GetQueryObjectuivEXT, + void, + (GLuint id, GLenum pname, GLuint* params), + (id, pname, params)) +VISIT_GL_CALL(GetQueryObjecti64vEXT, + void, + (GLuint id, GLenum pname, GLint64* params), + (id, pname, params)) +VISIT_GL_CALL(GetQueryObjectui64vEXT, + void, + (GLuint id, GLenum pname, GLuint64* params), + (id, pname, params)) +VISIT_GL_CALL(SetDisjointValueSyncCHROMIUM, void, (), ()) +VISIT_GL_CALL(InsertEventMarkerEXT, + void, + (GLsizei length, const GLchar* marker), + (length, marker)) +VISIT_GL_CALL(PushGroupMarkerEXT, + void, + (GLsizei length, const GLchar* marker), + (length, marker)) +VISIT_GL_CALL(PopGroupMarkerEXT, void, (), ()) +VISIT_GL_CALL(GenVertexArraysOES, + void, + (GLsizei n, GLuint* arrays), + (n, arrays)) +VISIT_GL_CALL(DeleteVertexArraysOES, + void, + (GLsizei n, const GLuint* arrays), + (n, arrays)) +VISIT_GL_CALL(IsVertexArrayOES, GLboolean, (GLuint array), (array)) +VISIT_GL_CALL(BindVertexArrayOES, void, (GLuint array), (array)) +VISIT_GL_CALL(SwapBuffers, void, (), ()) +VISIT_GL_CALL(GetMaxValueInBufferCHROMIUM, + GLuint, + (GLuint buffer_id, GLsizei count, GLenum type, GLuint offset), + (buffer_id, count, type, offset)) +VISIT_GL_CALL(EnableFeatureCHROMIUM, + GLboolean, + (const char* feature), + (feature)) +VISIT_GL_CALL(MapBufferCHROMIUM, + void*, + (GLuint target, GLenum access), + (target, access)) +VISIT_GL_CALL(UnmapBufferCHROMIUM, GLboolean, (GLuint target), (target)) +VISIT_GL_CALL(MapBufferSubDataCHROMIUM, + void*, + (GLuint target, GLintptr offset, GLsizeiptr size, GLenum access), + (target, offset, size, access)) +VISIT_GL_CALL(UnmapBufferSubDataCHROMIUM, void, (const void* mem), (mem)) +VISIT_GL_CALL( + MapTexSubImage2DCHROMIUM, + void*, + (GLenum target, + GLint level, + GLint xoffset, + GLint yoffset, + GLsizei width, + GLsizei height, + GLenum format, + GLenum type, + GLenum access), + (target, level, xoffset, yoffset, width, height, format, type, access)) +VISIT_GL_CALL(UnmapTexSubImage2DCHROMIUM, void, (const void* mem), (mem)) +VISIT_GL_CALL(ResizeCHROMIUM, + void, + (GLuint width, GLuint height, GLfloat scale_factor), + (width, height, scale_factor)) +VISIT_GL_CALL(GetRequestableExtensionsCHROMIUM, const GLchar*, (), ()) +VISIT_GL_CALL(RequestExtensionCHROMIUM, + void, + (const char* extension), + (extension)) +VISIT_GL_CALL(GetProgramInfoCHROMIUM, + void, + (GLuint program, GLsizei bufsize, GLsizei* size, void* info), + (program, bufsize, size, info)) +VISIT_GL_CALL(CreateStreamTextureCHROMIUM, GLuint, (GLuint texture), (texture)) +VISIT_GL_CALL( + CreateImageCHROMIUM, + GLuint, + (ClientBuffer buffer, GLsizei width, GLsizei height, GLenum internalformat), + (buffer, width, height, internalformat)) +VISIT_GL_CALL(DestroyImageCHROMIUM, void, (GLuint image_id), (image_id)) +VISIT_GL_CALL( + CreateGpuMemoryBufferImageCHROMIUM, + GLuint, + (GLsizei width, GLsizei height, GLenum internalformat, GLenum usage), + (width, height, internalformat, usage)) +VISIT_GL_CALL(GetTranslatedShaderSourceANGLE, + void, + (GLuint shader, GLsizei bufsize, GLsizei* length, char* source), + (shader, bufsize, length, source)) +VISIT_GL_CALL(PostSubBufferCHROMIUM, + void, + (GLint x, GLint y, GLint width, GLint height), + (x, y, width, height)) +VISIT_GL_CALL(TexImageIOSurface2DCHROMIUM, + void, + (GLenum target, + GLsizei width, + GLsizei height, + GLuint ioSurfaceId, + GLuint plane), + (target, width, height, ioSurfaceId, plane)) +VISIT_GL_CALL(CopyTextureCHROMIUM, + void, + (GLenum target, + GLenum source_id, + GLenum dest_id, + GLint internalformat, + GLenum dest_type, + GLboolean unpack_flip_y, + GLboolean unpack_premultiply_alpha, + GLboolean unpack_unmultiply_alpha), + (target, + source_id, + dest_id, + internalformat, + dest_type, + unpack_flip_y, + unpack_premultiply_alpha, + unpack_unmultiply_alpha)) +VISIT_GL_CALL(CopySubTextureCHROMIUM, + void, + (GLenum target, + GLenum source_id, + GLenum dest_id, + GLint xoffset, + GLint yoffset, + GLint x, + GLint y, + GLsizei width, + GLsizei height, + GLboolean unpack_flip_y, + GLboolean unpack_premultiply_alpha, + GLboolean unpack_unmultiply_alpha), + (target, + source_id, + dest_id, + xoffset, + yoffset, + x, + y, + width, + height, + unpack_flip_y, + unpack_premultiply_alpha, + unpack_unmultiply_alpha)) +VISIT_GL_CALL(CompressedCopyTextureCHROMIUM, + void, + (GLenum target, GLenum source_id, GLenum dest_id), + (target, source_id, dest_id)) +VISIT_GL_CALL( + CompressedCopySubTextureCHROMIUM, + void, + (GLenum target, + GLenum source_id, + GLenum dest_id, + GLint xoffset, + GLint yoffset, + GLint x, + GLint y, + GLsizei width, + GLsizei height), + (target, source_id, dest_id, xoffset, yoffset, x, y, width, height)) +VISIT_GL_CALL(DrawArraysInstancedANGLE, + void, + (GLenum mode, GLint first, GLsizei count, GLsizei primcount), + (mode, first, count, primcount)) +VISIT_GL_CALL(DrawElementsInstancedANGLE, + void, + (GLenum mode, + GLsizei count, + GLenum type, + const void* indices, + GLsizei primcount), + (mode, count, type, indices, primcount)) +VISIT_GL_CALL(VertexAttribDivisorANGLE, + void, + (GLuint index, GLuint divisor), + (index, divisor)) +VISIT_GL_CALL(GenMailboxCHROMIUM, void, (GLbyte * mailbox), (mailbox)) +VISIT_GL_CALL(ProduceTextureCHROMIUM, + void, + (GLenum target, const GLbyte* mailbox), + (target, mailbox)) +VISIT_GL_CALL(ProduceTextureDirectCHROMIUM, + void, + (GLuint texture, GLenum target, const GLbyte* mailbox), + (texture, target, mailbox)) +VISIT_GL_CALL(ConsumeTextureCHROMIUM, + void, + (GLenum target, const GLbyte* mailbox), + (target, mailbox)) +VISIT_GL_CALL(CreateAndConsumeTextureCHROMIUM, + GLuint, + (GLenum target, const GLbyte* mailbox), + (target, mailbox)) +VISIT_GL_CALL(BindUniformLocationCHROMIUM, + void, + (GLuint program, GLint location, const char* name), + (program, location, name)) +VISIT_GL_CALL(GenValuebuffersCHROMIUM, + void, + (GLsizei n, GLuint* buffers), + (n, buffers)) +VISIT_GL_CALL(DeleteValuebuffersCHROMIUM, + void, + (GLsizei n, const GLuint* valuebuffers), + (n, valuebuffers)) +VISIT_GL_CALL(IsValuebufferCHROMIUM, + GLboolean, + (GLuint valuebuffer), + (valuebuffer)) +VISIT_GL_CALL(BindValuebufferCHROMIUM, + void, + (GLenum target, GLuint valuebuffer), + (target, valuebuffer)) +VISIT_GL_CALL(SubscribeValueCHROMIUM, + void, + (GLenum target, GLenum subscription), + (target, subscription)) +VISIT_GL_CALL(PopulateSubscribedValuesCHROMIUM, void, (GLenum target), (target)) +VISIT_GL_CALL(UniformValuebufferCHROMIUM, + void, + (GLint location, GLenum target, GLenum subscription), + (location, target, subscription)) +VISIT_GL_CALL(BindTexImage2DCHROMIUM, + void, + (GLenum target, GLint imageId), + (target, imageId)) +VISIT_GL_CALL(ReleaseTexImage2DCHROMIUM, + void, + (GLenum target, GLint imageId), + (target, imageId)) +VISIT_GL_CALL(TraceBeginCHROMIUM, + void, + (const char* category_name, const char* trace_name), + (category_name, trace_name)) +VISIT_GL_CALL(TraceEndCHROMIUM, void, (), ()) +VISIT_GL_CALL(DiscardFramebufferEXT, + void, + (GLenum target, GLsizei count, const GLenum* attachments), + (target, count, attachments)) +VISIT_GL_CALL(LoseContextCHROMIUM, + void, + (GLenum current, GLenum other), + (current, other)) +VISIT_GL_CALL(InsertSyncPointCHROMIUM, GLuint, (), ()) +VISIT_GL_CALL(WaitSyncPointCHROMIUM, void, (GLuint sync_point), (sync_point)) +VISIT_GL_CALL(InsertFenceSyncCHROMIUM, GLuint64, (), ()) +VISIT_GL_CALL(GenSyncTokenCHROMIUM, + void, + (GLuint64 fence_sync, GLbyte* sync_token), + (fence_sync, sync_token)) +VISIT_GL_CALL(GenUnverifiedSyncTokenCHROMIUM, + void, + (GLuint64 fence_sync, GLbyte* sync_token), + (fence_sync, sync_token)) +VISIT_GL_CALL(WaitSyncTokenCHROMIUM, + void, + (const GLbyte* sync_token), + (sync_token)) +VISIT_GL_CALL(DrawBuffersEXT, + void, + (GLsizei count, const GLenum* bufs), + (count, bufs)) +VISIT_GL_CALL(DiscardBackbufferCHROMIUM, void, (), ()) +VISIT_GL_CALL(ScheduleOverlayPlaneCHROMIUM, + void, + (GLint plane_z_order, + GLenum plane_transform, + GLuint overlay_texture_id, + GLint bounds_x, + GLint bounds_y, + GLint bounds_width, + GLint bounds_height, + GLfloat uv_x, + GLfloat uv_y, + GLfloat uv_width, + GLfloat uv_height), + (plane_z_order, + plane_transform, + overlay_texture_id, + bounds_x, + bounds_y, + bounds_width, + bounds_height, + uv_x, + uv_y, + uv_width, + uv_height)) +VISIT_GL_CALL(SwapInterval, void, (GLint interval), (interval)) +VISIT_GL_CALL(FlushDriverCachesCHROMIUM, void, (), ()) +VISIT_GL_CALL(MatrixLoadfCHROMIUM, + void, + (GLenum matrixMode, const GLfloat* m), + (matrixMode, m)) +VISIT_GL_CALL(MatrixLoadIdentityCHROMIUM, + void, + (GLenum matrixMode), + (matrixMode)) +VISIT_GL_CALL(GenPathsCHROMIUM, GLuint, (GLsizei range), (range)) +VISIT_GL_CALL(DeletePathsCHROMIUM, + void, + (GLuint path, GLsizei range), + (path, range)) +VISIT_GL_CALL(IsPathCHROMIUM, GLboolean, (GLuint path), (path)) +VISIT_GL_CALL(PathCommandsCHROMIUM, + void, + (GLuint path, + GLsizei numCommands, + const GLubyte* commands, + GLsizei numCoords, + GLenum coordType, + const GLvoid* coords), + (path, numCommands, commands, numCoords, coordType, coords)) +VISIT_GL_CALL(PathParameterfCHROMIUM, + void, + (GLuint path, GLenum pname, GLfloat value), + (path, pname, value)) +VISIT_GL_CALL(PathParameteriCHROMIUM, + void, + (GLuint path, GLenum pname, GLint value), + (path, pname, value)) +VISIT_GL_CALL(PathStencilFuncCHROMIUM, + void, + (GLenum func, GLint ref, GLuint mask), + (func, ref, mask)) +VISIT_GL_CALL(StencilFillPathCHROMIUM, + void, + (GLuint path, GLenum fillMode, GLuint mask), + (path, fillMode, mask)) +VISIT_GL_CALL(StencilStrokePathCHROMIUM, + void, + (GLuint path, GLint reference, GLuint mask), + (path, reference, mask)) +VISIT_GL_CALL(CoverFillPathCHROMIUM, + void, + (GLuint path, GLenum coverMode), + (path, coverMode)) +VISIT_GL_CALL(CoverStrokePathCHROMIUM, + void, + (GLuint path, GLenum coverMode), + (path, coverMode)) +VISIT_GL_CALL(StencilThenCoverFillPathCHROMIUM, + void, + (GLuint path, GLenum fillMode, GLuint mask, GLenum coverMode), + (path, fillMode, mask, coverMode)) +VISIT_GL_CALL(StencilThenCoverStrokePathCHROMIUM, + void, + (GLuint path, GLint reference, GLuint mask, GLenum coverMode), + (path, reference, mask, coverMode)) +VISIT_GL_CALL(StencilFillPathInstancedCHROMIUM, + void, + (GLsizei numPaths, + GLenum pathNameType, + const GLvoid* paths, + GLuint pathBase, + GLenum fillMode, + GLuint mask, + GLenum transformType, + const GLfloat* transformValues), + (numPaths, + pathNameType, + paths, + pathBase, + fillMode, + mask, + transformType, + transformValues)) +VISIT_GL_CALL(StencilStrokePathInstancedCHROMIUM, + void, + (GLsizei numPaths, + GLenum pathNameType, + const GLvoid* paths, + GLuint pathBase, + GLint reference, + GLuint mask, + GLenum transformType, + const GLfloat* transformValues), + (numPaths, + pathNameType, + paths, + pathBase, + reference, + mask, + transformType, + transformValues)) +VISIT_GL_CALL(CoverFillPathInstancedCHROMIUM, + void, + (GLsizei numPaths, + GLenum pathNameType, + const GLvoid* paths, + GLuint pathBase, + GLenum coverMode, + GLenum transformType, + const GLfloat* transformValues), + (numPaths, + pathNameType, + paths, + pathBase, + coverMode, + transformType, + transformValues)) +VISIT_GL_CALL(CoverStrokePathInstancedCHROMIUM, + void, + (GLsizei numPaths, + GLenum pathNameType, + const GLvoid* paths, + GLuint pathBase, + GLenum coverMode, + GLenum transformType, + const GLfloat* transformValues), + (numPaths, + pathNameType, + paths, + pathBase, + coverMode, + transformType, + transformValues)) +VISIT_GL_CALL(StencilThenCoverFillPathInstancedCHROMIUM, + void, + (GLsizei numPaths, + GLenum pathNameType, + const GLvoid* paths, + GLuint pathBase, + GLenum fillMode, + GLuint mask, + GLenum coverMode, + GLenum transformType, + const GLfloat* transformValues), + (numPaths, + pathNameType, + paths, + pathBase, + fillMode, + mask, + coverMode, + transformType, + transformValues)) +VISIT_GL_CALL(StencilThenCoverStrokePathInstancedCHROMIUM, + void, + (GLsizei numPaths, + GLenum pathNameType, + const GLvoid* paths, + GLuint pathBase, + GLint reference, + GLuint mask, + GLenum coverMode, + GLenum transformType, + const GLfloat* transformValues), + (numPaths, + pathNameType, + paths, + pathBase, + reference, + mask, + coverMode, + transformType, + transformValues)) +VISIT_GL_CALL(BindFragmentInputLocationCHROMIUM, + void, + (GLuint program, GLint location, const char* name), + (program, location, name)) +VISIT_GL_CALL(ProgramPathFragmentInputGenCHROMIUM, + void, + (GLuint program, + GLint location, + GLenum genMode, + GLint components, + const GLfloat* coeffs), + (program, location, genMode, components, coeffs)) +VISIT_GL_CALL(GetGraphicsResetStatusKHR, GLenum, (), ()) +VISIT_GL_CALL(BlendBarrierKHR, void, (), ()) +VISIT_GL_CALL(ApplyScreenSpaceAntialiasingCHROMIUM, void, (), ()) +VISIT_GL_CALL( + BindFragDataLocationIndexedEXT, + void, + (GLuint program, GLuint colorNumber, GLuint index, const char* name), + (program, colorNumber, index, name)) +VISIT_GL_CALL(BindFragDataLocationEXT, + void, + (GLuint program, GLuint colorNumber, const char* name), + (program, colorNumber, name)) +VISIT_GL_CALL(GetFragDataIndexEXT, + GLint, + (GLuint program, const char* name), + (program, name))
diff --git a/third_party/usrsctp/usrsctp.gyp b/third_party/usrsctp/usrsctp.gyp index b4a86b2..1ebb78a 100644 --- a/third_party/usrsctp/usrsctp.gyp +++ b/third_party/usrsctp/usrsctp.gyp
@@ -130,15 +130,15 @@ 'defines': [ '__Userspace_os_Windows', # Manually setting WINVER and _WIN32_WINNT is needed because Chrome - # sets WINVER to a newer version of windows. But compiling usrsctp - # this way would is incompatible with windows XP. + # sets WINVER to a newer version of Windows. But compiling usrsctp + # this way would be incompatible with Windows XP. 'WINVER=0x0502', '_WIN32_WINNT=0x0502', ], 'defines!': [ # Remove Chrome's WINVER defines to avoid redefinition warnings. - 'WINVER=0x0603', - '_WIN32_WINNT=0x0603', + 'WINVER=0x0A00', + '_WIN32_WINNT=0x0A00', ], 'cflags!': [ '/W3', '/WX' ], 'cflags': [ '/w' ],
diff --git a/tools/android/android_tools.gyp b/tools/android/android_tools.gyp index 9ae163c..92b2b71 100644 --- a/tools/android/android_tools.gyp +++ b/tools/android/android_tools.gyp
@@ -17,7 +17,6 @@ 'md5sum/md5sum.gyp:md5sum', 'memtrack_helper/memtrack_helper.gyp:memtrack_helper', 'purge_ashmem/purge_ashmem.gyp:purge_ashmem', - 'run_pie/run_pie.gyp:run_pie', '../../tools/telemetry/telemetry.gyp:*#host', ], },
diff --git a/tools/android/eclipse/.classpath b/tools/android/eclipse/.classpath index 51d9f40c..eef7d41 100644 --- a/tools/android/eclipse/.classpath +++ b/tools/android/eclipse/.classpath
@@ -29,7 +29,6 @@ <classpathentry kind="src" path="chrome/android/java/src"/> <classpathentry kind="src" path="chrome/android/javatests/src"/> <classpathentry kind="src" path="chrome/android/sync_shell/javatests/src"/> - <classpathentry kind="src" path="chrome/android/uiautomator_tests/src"/> <classpathentry kind="src" path="chrome/android/junit/src"/> <classpathentry kind="src" path="chrome/test/android/javatests/src"/> <classpathentry kind="src" path="chrome/test/chromedriver/test/webview_shell/java/src"/> @@ -95,23 +94,6 @@ <classpathentry kind="src" path="out/Debug/android_webview_test_apk/gen"/> <classpathentry kind="src" path="out/Debug/chrome_public_apk/gen"/> <classpathentry kind="src" path="out/Debug/content_shell_apk/gen"/> - <classpathentry kind="src" path="out/Debug/gen/base/base_android_java_enums_srcjar__generate_enum/enums"/> - <classpathentry kind="src" path="out/Debug/gen/base/base_multidex_gen__apply_gcc/java_cpp_template"/> - <classpathentry kind="src" path="out/Debug/gen/base/base_native_libraries_gen__apply_gcc/java_cpp_template"/> - <classpathentry kind="src" path="out/Debug/gen/chrome/android/chrome_android_java_enums_srcjar__generate_enum/enums"/> - <classpathentry kind="src" path="out/Debug/gen/chrome/android/chrome_public_apk__native_libraries_java__apply_gcc/java_cpp_template"/> - <classpathentry kind="src" path="out/Debug/gen/chrome/android/resource_id_javagen__apply_gcc/java_cpp_template"/> - <classpathentry kind="src" path="out/Debug/gen/chrome/content_setting_javagen__generate_enum/enums"/> - <classpathentry kind="src" path="out/Debug/gen/chrome/content_settings_type_javagen__generate_enum/enums"/> - <classpathentry kind="src" path="out/Debug/gen/chrome/page_info_connection_type_javagen__generate_enum/enums"/> - <classpathentry kind="src" path="out/Debug/gen/components/bookmarks/common/android/bookmark_type_javagen__generate_enum/enums"/> - <classpathentry kind="src" path="out/Debug/gen/components/dom_distiller/android/dom_distiller_core_font_family_javagen__apply_gcc/java_cpp_template"/> - <classpathentry kind="src" path="out/Debug/gen/components/dom_distiller/android/dom_distiller_core_theme_javagen__apply_gcc/java_cpp_template"/> - <classpathentry kind="src" path="out/Debug/gen/components/enhanced_bookmarks/enhanced_bookmarks_java_enums_srcjar__generate_enum/enums"/> - <classpathentry kind="src" path="out/Debug/gen/components/offline_pages/offline_pages_enums_java__generate_enum/enums"/> - <classpathentry kind="src" path="out/Debug/gen/components/omnibox/browser/autocomplete_match_type_javagen__generate_enum/enums"/> - <classpathentry kind="src" path="out/Debug/gen/content/browser/accessibility/content_browser_accessibility_java_enums_srcjar__generate_enum/enums"/> - <classpathentry kind="src" path="out/Debug/gen/content/public/android/content_public_android_java_enums_srcjar__generate_enum/enums"/> <classpathentry kind="src" path="out/Debug/gen/enums/accessibility_java"/> <classpathentry kind="src" path="out/Debug/gen/enums/activity_type_ids_java"/> <classpathentry kind="src" path="out/Debug/gen/enums/android_resource_type_java"/> @@ -165,10 +147,6 @@ <classpathentry kind="src" path="out/Debug/gen/enums/web_input_event_java"/> <classpathentry kind="src" path="out/Debug/gen/enums/web_text_input_type"/> <classpathentry kind="src" path="out/Debug/gen/enums/window_open_disposition_java"/> - <classpathentry kind="src" path="out/Debug/gen/media/base/android/media_java_enums_srcjar__generate_enum/enums"/> - <classpathentry kind="src" path="out/Debug/gen/net/android/net_android_java_enums_srcjar__generate_enum/enums"/> - <classpathentry kind="src" path="out/Debug/gen/net/android/net_errors_java__apply_gcc/java_cpp_template"/> - <classpathentry kind="src" path="out/Debug/gen/sync/android/java_enums__generate_enum/enums"/> <classpathentry kind="src" path="out/Debug/gen/templates/base_native_libraries_gen"/> <classpathentry kind="src" path="out/Debug/gen/templates/chrome_version_java"/> <classpathentry kind="src" path="out/Debug/gen/templates/dom_distiller_core_font_family_java"/> @@ -176,11 +154,6 @@ <classpathentry kind="src" path="out/Debug/gen/templates/load_states_list"/> <classpathentry kind="src" path="out/Debug/gen/templates/net_errors_java"/> <classpathentry kind="src" path="out/Debug/gen/templates/resource_id_java"/> - <classpathentry kind="src" path="out/Debug/gen/third_party/WebKit/public/blink_headers_java_enums_srcjar__generate_enum/enums"/> - <classpathentry kind="src" path="out/Debug/gen/ui/accessibility/ax_enumerations_srcjar__generate_enum/enums"/> - <classpathentry kind="src" path="out/Debug/gen/ui/android/java_enums_srcjar__generate_enum/enums"/> - <classpathentry kind="src" path="out/Debug/gen/ui/touch_selection/ui_touch_handle_orientation_srcjar__generate_enum/enums"/> - <classpathentry kind="src" path="out/Debug/gen/ui/touch_selection/ui_touch_selection_enums_srcjar__generate_enum/enums"/> <classpathentry kind="src" path="out/Debug/java_mojo/device_battery_mojo_bindings/src"/> <classpathentry kind="src" path="out/Debug/java_mojo/mojo_public_test_interfaces_mojom/src"/> <classpathentry kind="src" path="out/Debug/java_proto/cacheinvalidation_proto_java/src"/> @@ -202,12 +175,60 @@ <classpathentry kind="lib" path="third_party/findbugs/lib/findbugs.jar"/> <classpathentry kind="lib" path="third_party/junit/src/lib/hamcrest-core-1.1.jar"/> <classpathentry kind="lib" path="third_party/robolectric/lib/robolectric-2.4-jar-with-dependencies.jar"/> - <classpathentry kind="lib" path="out/Debug/gen/chrome/android/chrome_public_apk/chrome_public_apk.jar"/> <classpathentry kind="lib" path="out/Debug/lib.java/cacheinvalidation_proto_java.jar"/> <classpathentry kind="lib" path="out/Debug/lib.java/content_java.jar"/> <classpathentry kind="lib" path="out/Debug/lib.java/jsr_305_javalib.jar"/> <classpathentry kind="lib" path="out/Debug/lib.java/net_java.jar"/> - <classpathentry kind="output" path="out/bin"/> + + <!-- GN: R (resources) and NativeLibraries classes. --> + <classpathentry kind="lib" path="out/Debug/gen/chrome/android/chrome_public_apk/chrome_public_apk.jar"/> + + <!-- GN: library jars, includes generated Java files. --> + <classpathentry kind="lib" path="out/Debug/lib.java/android_webview/android_webview_java.jar"/> + <classpathentry kind="lib" path="out/Debug/lib.java/base/base_java.jar"/> + <classpathentry kind="lib" path="out/Debug/lib.java/chrome/android/chrome_java.jar"/> + <classpathentry kind="lib" path="out/Debug/lib.java/chrome/android/document_tab_model_info_proto_java.jar"/> + <classpathentry kind="lib" path="out/Debug/lib.java/components/bookmarks/common/android/bookmarks_java.jar"/> + <classpathentry kind="lib" path="out/Debug/lib.java/components/dom_distiller/android/dom_distiller_content_java.jar"/> + <classpathentry kind="lib" path="out/Debug/lib.java/components/dom_distiller/android/dom_distiller_core_java.jar"/> + <classpathentry kind="lib" path="out/Debug/lib.java/components/external_video_surface/java.jar"/> + <classpathentry kind="lib" path="out/Debug/lib.java/components/gcm_driver/android/gcm_driver_java.jar"/> + <classpathentry kind="lib" path="out/Debug/lib.java/components/invalidation/impl/java.jar"/> + <classpathentry kind="lib" path="out/Debug/lib.java/components/invalidation/impl/proto_java.jar"/> + <classpathentry kind="lib" path="out/Debug/lib.java/components/navigation_interception/android/navigation_interception_java.jar"/> + <classpathentry kind="lib" path="out/Debug/lib.java/components/policy/android/policy_java.jar"/> + <classpathentry kind="lib" path="out/Debug/lib.java/components/precache/android/precache_java.jar"/> + <classpathentry kind="lib" path="out/Debug/lib.java/components/safe_json/android/safe_json_java.jar"/> + <classpathentry kind="lib" path="out/Debug/lib.java/components/service_tab_launcher/service_tab_launcher_java.jar"/> + <classpathentry kind="lib" path="out/Debug/lib.java/components/signin/core/browser/android/java.jar"/> + <classpathentry kind="lib" path="out/Debug/lib.java/components/variations/android/variations_java.jar"/> + <classpathentry kind="lib" path="out/Debug/lib.java/components/web_contents_delegate_android/web_contents_delegate_android_java.jar"/> + <classpathentry kind="lib" path="out/Debug/lib.java/content/public/android/content_java.jar"/> + <classpathentry kind="lib" path="out/Debug/lib.java/device/battery/android/battery_monitor_android.jar"/> + <classpathentry kind="lib" path="out/Debug/lib.java/device/battery/mojo_bindings_java.jar"/> + <classpathentry kind="lib" path="out/Debug/lib.java/device/bluetooth/java.jar"/> + <classpathentry kind="lib" path="out/Debug/lib.java/device/vibration/android/vibration_manager_android.jar"/> + <classpathentry kind="lib" path="out/Debug/lib.java/device/vibration/mojo_bindings_java.jar"/> + <classpathentry kind="lib" path="out/Debug/lib.java/media/base/android/media_java.jar"/> + <classpathentry kind="lib" path="out/Debug/lib.java/media/midi/midi_java.jar"/> + <classpathentry kind="lib" path="out/Debug/lib.java/mojo/android/system_java.jar"/> + <classpathentry kind="lib" path="out/Debug/lib.java/mojo/public/java/bindings.jar"/> + <classpathentry kind="lib" path="out/Debug/lib.java/mojo/public/java/system.jar"/> + <classpathentry kind="lib" path="out/Debug/lib.java/net/android/net_java.jar"/> + <classpathentry kind="lib" path="out/Debug/lib.java/printing/printing_java.jar"/> + <classpathentry kind="lib" path="out/Debug/lib.java/sync/android/sync_java.jar"/> + <classpathentry kind="lib" path="out/Debug/lib.java/sync/test_support_sync_proto_java.jar"/> + <classpathentry kind="lib" path="out/Debug/lib.java/third_party/android_data_chart/android_data_chart_java.jar"/> + <classpathentry kind="lib" path="out/Debug/lib.java/third_party/android_media/android_media_java.jar"/> + <classpathentry kind="lib" path="out/Debug/lib.java/third_party/android_protobuf/protobuf_nano_javalib.jar"/> + <classpathentry kind="lib" path="out/Debug/lib.java/third_party/android_swipe_refresh/android_swipe_refresh_java.jar"/> + <classpathentry kind="lib" path="out/Debug/lib.java/third_party/cacheinvalidation/cacheinvalidation_javalib.jar"/> + <classpathentry kind="lib" path="out/Debug/lib.java/third_party/cacheinvalidation/cacheinvalidation_proto_java.jar"/> + <classpathentry kind="lib" path="out/Debug/lib.java/third_party/cardboard-java/cardboard-java.jar"/> + <classpathentry kind="lib" path="out/Debug/lib.java/third_party/gif_player/gif_player_java.jar"/> + <classpathentry kind="lib" path="out/Debug/lib.java/third_party/WebKit/public/blink_headers_java.jar"/> + <classpathentry kind="lib" path="out/Debug/lib.java/ui/accessibility/ui_accessibility_java.jar"/> + <classpathentry kind="lib" path="out/Debug/lib.java/ui/android/ui_java.jar"/> <!-- {% block additional_entries %} --> <!-- When this file is processed as a jinja2 template, additional
diff --git a/tools/android/heap_profiler/heap_dump.c b/tools/android/heap_profiler/heap_dump.c index 5d468da9..9df78c5 100644 --- a/tools/android/heap_profiler/heap_dump.c +++ b/tools/android/heap_profiler/heap_dump.c
@@ -40,6 +40,7 @@ #include <unistd.h> #include <sys/ptrace.h> #include <sys/stat.h> +#include <sys/wait.h> #include "tools/android/heap_profiler/heap_profiler.h" @@ -234,8 +235,6 @@ static ssize_t read_safe(int fd, void* buf, size_t count) { ssize_t res; size_t bytes_read = 0; - if (count < 0) - return -1; do { do { res = read(fd, buf + bytes_read, count - bytes_read);
diff --git a/tools/android/run_pie/run_pie.c b/tools/android/run_pie/run_pie.c deleted file mode 100644 index ee1a622..0000000 --- a/tools/android/run_pie/run_pie.c +++ /dev/null
@@ -1,68 +0,0 @@ -// Copyright 2014 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include <dlfcn.h> -#include <stdio.h> -#include <string.h> -#include <sys/prctl.h> -#include <unistd.h> - -// This is a wrapper to run position independent executables on Android ICS, -// where the linker doesn't support PIE. This requires the PIE binaries to be -// built with CFLAGS +=-fvisibility=default -fPIE, and LDFLAGS += -rdynamic -pie -// such that the main() symbol remains exported and can be dlsym-ed. - -#define ERR_PREFIX "[PIE Loader] " - -typedef int (*main_t)(int, char**); - - -int main(int argc, char** argv) { - if (argc < 2) { - printf("Usage: %s path_to_pie_executable [args]\n", argv[0]); - return -1; - } - - // Shift left the argv[]. argv is what /proc/PID/cmdline prints out. In turn - // cmdline is what Android "ps" prints out. In turn "ps" is what many scripts - // look for to decide which processes to kill / killall. - int i; - char* next_argv_start = argv[0]; - for (i = 1; i < argc; ++i) { - const size_t argv_len = strlen(argv[i]) + 1; - memcpy(argv[i - 1], argv[i], argv_len); - next_argv_start += argv_len; - argv[i] = next_argv_start; - } - argv[argc - 1] = NULL; // The last argv must be a NULL ptr. - - // Set also the proc name accordingly (/proc/PID/comm). - prctl(PR_SET_NAME, (long) argv[0]); - - // dlopen should not fail, unless: - // - The target binary does not exists: - // - The dependent .so libs cannot be loaded. - // In both cases, just bail out with an explicit error message. - void* handle = dlopen(argv[0], RTLD_NOW); - if (handle == NULL) { - printf(ERR_PREFIX "dlopen() failed: %s.\n", dlerror()); - return -1; - } - - main_t pie_main = (main_t) dlsym(handle, "main"); - if (pie_main) { - return pie_main(argc - 1, argv); - } - - // If we reached this point dlsym failed, very likely because the target - // binary has not been compiled with the proper CFLAGS / LDFLAGS. - // At this point the most sensible thing to do is running that normally - // via exec and hope that the target binary wasn't a PIE. - execv(argv[0], argv); - - // exevc is supposed to never return, unless it fails. - printf(ERR_PREFIX "Both dlsym() and the execv() fallback failed.\n"); - perror("execv"); - return -1; -}
diff --git a/tools/android/run_pie/run_pie.gyp b/tools/android/run_pie/run_pie.gyp deleted file mode 100644 index 75850f4..0000000 --- a/tools/android/run_pie/run_pie.gyp +++ /dev/null
@@ -1,49 +0,0 @@ -# Copyright 2014 The Chromium Authors. All rights reserved. -# Use of this source code is governed by a BSD-style license that can be -# found in the LICENSE file. - -{ - 'targets': [ - { - 'target_name': 'run_pie-unstripped', - 'type': 'executable', - 'sources': [ - 'run_pie.c', - ], - # See crbug.com/373219. This is the only Android executable which must be - # non PIE. - 'cflags!': [ - '-fPIE', - ], - 'ldflags!': [ - '-pie', - ], - # Don't inherit unneeded dependencies on libc++, so the binary remains - # self-contained also in component=shared_library builds. - 'libraries!': [ - '-l<(android_libcpp_library)', - ], - }, - { - 'target_name': 'run_pie', - 'type': 'none', - 'dependencies': [ - 'run_pie-unstripped', - ], - 'actions': [ - { - 'action_name': 'strip_run_pie', - 'inputs': ['<(PRODUCT_DIR)/run_pie-unstripped'], - 'outputs': ['<(PRODUCT_DIR)/run_pie'], - 'action': [ - '<(android_strip)', - '--strip-unneeded', - '<@(_inputs)', - '-o', - '<@(_outputs)', - ], - }, - ], - }, - ], -}
diff --git a/tools/clang/pass_to_move/CMakeLists.txt b/tools/clang/pass_to_move/CMakeLists.txt new file mode 100644 index 0000000..b3ceee1 --- /dev/null +++ b/tools/clang/pass_to_move/CMakeLists.txt
@@ -0,0 +1,27 @@ +set(LLVM_LINK_COMPONENTS + BitReader + MCParser + Option + X86AsmParser + ) + +add_llvm_executable(pass_to_move + PassToMove.cpp + ) + +target_link_libraries(pass_to_move + clangAST + clangASTMatchers + clangAnalysis + clangBasic + clangDriver + clangEdit + clangFrontend + clangLex + clangParse + clangSema + clangSerialization + clangTooling + ) + +cr_install(TARGETS pass_to_move RUNTIME DESTINATION bin)
diff --git a/tools/clang/pass_to_move/PassToMove.cpp b/tools/clang/pass_to_move/PassToMove.cpp new file mode 100644 index 0000000..90a94ce --- /dev/null +++ b/tools/clang/pass_to_move/PassToMove.cpp
@@ -0,0 +1,104 @@ +// 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. +// +// Clang tool to change calls to scoper::Pass() to just use std::move(). + +#include <memory> +#include <string> + +#include "clang/AST/ASTContext.h" +#include "clang/ASTMatchers/ASTMatchFinder.h" +#include "clang/ASTMatchers/ASTMatchers.h" +#include "clang/ASTMatchers/ASTMatchersMacros.h" +#include "clang/Basic/SourceManager.h" +#include "clang/Frontend/FrontendActions.h" +#include "clang/Lex/Lexer.h" +#include "clang/Tooling/CommonOptionsParser.h" +#include "clang/Tooling/Refactoring.h" +#include "clang/Tooling/Tooling.h" +#include "llvm/Support/CommandLine.h" +#include "llvm/Support/TargetSelect.h" + +using namespace clang::ast_matchers; +using clang::tooling::CommonOptionsParser; +using clang::tooling::Replacement; +using clang::tooling::Replacements; +using llvm::StringRef; + +namespace { + +class RewriterCallback : public MatchFinder::MatchCallback { + public: + explicit RewriterCallback(Replacements* replacements) + : replacements_(replacements) {} + virtual void run(const MatchFinder::MatchResult& result) override; + + private: + Replacements* const replacements_; +}; + +void RewriterCallback::run(const MatchFinder::MatchResult& result) { + const clang::Expr* arg = result.Nodes.getNodeAs<clang::Expr>("arg"); + clang::CharSourceRange arg_range = clang::CharSourceRange::getTokenRange( + result.SourceManager->getSpellingLoc(arg->getLocStart()), + result.SourceManager->getSpellingLoc(arg->getLocEnd())); + llvm::Twine new_source_text = + llvm::Twine("std::move(") + .concat(clang::Lexer::getSourceText(arg_range, *result.SourceManager, + result.Context->getLangOpts())) + .concat(")"); + // Replace the entire original expression with std::move(arg). + const clang::Expr* expr = result.Nodes.getNodeAs<clang::Expr>("expr"); + clang::CharSourceRange expr_range = clang::CharSourceRange::getTokenRange( + result.SourceManager->getSpellingLoc(expr->getLocStart()), + result.SourceManager->getSpellingLoc(expr->getLocEnd())); + replacements_->emplace(*result.SourceManager, expr_range, + new_source_text.str()); +} + +} // namespace + +static llvm::cl::extrahelp common_help(CommonOptionsParser::HelpMessage); + +int main(int argc, const char* argv[]) { + // TODO(dcheng): Clang tooling should do this itself. + // http://llvm.org/bugs/show_bug.cgi?id=21627 + llvm::InitializeNativeTarget(); + llvm::InitializeNativeTargetAsmParser(); + llvm::cl::OptionCategory category( + "C++11 modernization: change scoped::Pass() to std::move()"); + CommonOptionsParser options(argc, argv, category); + clang::tooling::ClangTool tool(options.getCompilations(), + options.getSourcePathList()); + + MatchFinder match_finder; + Replacements replacements; + + auto pass_matcher = id( + "expr", + cxxMemberCallExpr(argumentCountIs(0), + hasDeclaration(functionDecl( + hasName("Pass"), returns(rValueReferenceType()))), + on(id("arg", expr())))); + RewriterCallback callback(&replacements); + match_finder.addMatcher(pass_matcher, &callback); + + std::unique_ptr<clang::tooling::FrontendActionFactory> factory = + clang::tooling::newFrontendActionFactory(&match_finder); + int result = tool.run(factory.get()); + if (result != 0) + return result; + + // Serialization format is documented in tools/clang/scripts/run_tool.py + llvm::outs() << "==== BEGIN EDITS ====\n"; + for (const auto& r : replacements) { + std::string replacement_text = r.getReplacementText().str(); + std::replace(replacement_text.begin(), replacement_text.end(), '\n', '\0'); + llvm::outs() << "r:::" << r.getFilePath() << ":::" << r.getOffset() + << ":::" << r.getLength() << ":::" << replacement_text << "\n"; + } + llvm::outs() << "==== END EDITS ====\n"; + + return 0; +}
diff --git a/tools/clang/pass_to_move/tests/test-expected.cc b/tools/clang/pass_to_move/tests/test-expected.cc new file mode 100644 index 0000000..f7d6d3f --- /dev/null +++ b/tools/clang/pass_to_move/tests/test-expected.cc
@@ -0,0 +1,33 @@ +// 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. + +struct A { + A&& Pass(); +}; + +struct B { + B& Pass(); +}; + +struct C { + A a; +}; + +struct D { + D&& NotPass(); +}; + +void F() { + A a1; + A a2 = std::move(a1); + + B b1; + B b2 = b2.Pass(); + + C c; + A a3 = std::move(c.a); + + D d1; + D d2 = d1.NotPass(); +}
diff --git a/tools/clang/pass_to_move/tests/test-original.cc b/tools/clang/pass_to_move/tests/test-original.cc new file mode 100644 index 0000000..7024aa7 --- /dev/null +++ b/tools/clang/pass_to_move/tests/test-original.cc
@@ -0,0 +1,33 @@ +// 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. + +struct A { + A&& Pass(); +}; + +struct B { + B& Pass(); +}; + +struct C { + A a; +}; + +struct D { + D&& NotPass(); +}; + +void F() { + A a1; + A a2 = a1.Pass(); + + B b1; + B b2 = b2.Pass(); + + C c; + A a3 = c.a.Pass(); + + D d1; + D d2 = d1.NotPass(); +}
diff --git a/tools/clang/plugins/README.chromium b/tools/clang/plugins/README.chromium index a2ce0ff..1c6f0c01 100644 --- a/tools/clang/plugins/README.chromium +++ b/tools/clang/plugins/README.chromium
@@ -1,4 +1,4 @@ Documentation for this code is: -- http://code.google.com/p/chromium/wiki/Clang -- http://code.google.com/p/chromium/wiki/WritingClangPlugins +- https://chromium.googlesource.com/chromium/src/+/master/docs/clang.md +- https://chromium.googlesource.com/chromium/src/+/master/docs/writing_clang_plugins.md
diff --git a/tools/clang/scripts/update.py b/tools/clang/scripts/update.py index 03f484c6..db7df2ac 100755 --- a/tools/clang/scripts/update.py +++ b/tools/clang/scripts/update.py
@@ -63,7 +63,8 @@ LIBCXXABI_DIR = os.path.join(LLVM_DIR, 'projects', 'libcxxabi') LLVM_BUILD_TOOLS_DIR = os.path.abspath( os.path.join(LLVM_DIR, '..', 'llvm-build-tools')) -STAMP_FILE = os.path.join(LLVM_DIR, '..', 'llvm-build', 'cr_build_revision') +STAMP_FILE = os.path.normpath( + os.path.join(LLVM_DIR, '..', 'llvm-build', 'cr_build_revision')) BINUTILS_DIR = os.path.join(THIRD_PARTY_DIR, 'binutils') VERSION = '3.8.0' ANDROID_NDK_DIR = os.path.join(
diff --git a/tools/generate_library_loader/generate_library_loader.gni b/tools/generate_library_loader/generate_library_loader.gni index 24f753b..c714c12 100644 --- a/tools/generate_library_loader/generate_library_loader.gni +++ b/tools/generate_library_loader/generate_library_loader.gni
@@ -63,7 +63,7 @@ output_cc, output_h, ] - deps = [ + public_deps = [ ":${target_name}_loader", ] }
diff --git a/tools/gn/docs/reference.md b/tools/gn/docs/reference.md index a180d88..97f12f2 100644 --- a/tools/gn/docs/reference.md +++ b/tools/gn/docs/reference.md
@@ -1431,7 +1431,7 @@ "root_out_dir" The root of the output file tree for the target. This will - match the value of the "root_gen_dir" variable when inside that + match the value of the "root_out_dir" variable when inside that target's declaration. "label_no_toolchain" @@ -3306,20 +3306,13 @@ ``` -## **cflags***: Flags passed to the C compiler. +## **asmflags**: Flags passed to the assembler. ``` A list of strings. - "cflags" are passed to all invocations of the C, C++, Objective C, - and Objective C++ compilers. - - To target one of these variants individually, use "cflags_c", - "cflags_cc", "cflags_objc", and "cflags_objcc", - respectively. - - These variant-specific versions of cflags* will be appended to the - "cflags". + "asmflags" are passed to any invocation of a tool that takes an + .asm or .S file as input. ``` @@ -3352,10 +3345,10 @@ To target one of these variants individually, use "cflags_c", "cflags_cc", "cflags_objc", and "cflags_objcc", - respectively. + respectively. These variant-specific versions of cflags* will be + appended on the compiler command line after "cflags". - These variant-specific versions of cflags* will be appended to the - "cflags". + See also "asmflags" for flags for assembly-language files. ``` @@ -3388,10 +3381,10 @@ To target one of these variants individually, use "cflags_c", "cflags_cc", "cflags_objc", and "cflags_objcc", - respectively. + respectively. These variant-specific versions of cflags* will be + appended on the compiler command line after "cflags". - These variant-specific versions of cflags* will be appended to the - "cflags". + See also "asmflags" for flags for assembly-language files. ``` @@ -3424,10 +3417,10 @@ To target one of these variants individually, use "cflags_c", "cflags_cc", "cflags_objc", and "cflags_objcc", - respectively. + respectively. These variant-specific versions of cflags* will be + appended on the compiler command line after "cflags". - These variant-specific versions of cflags* will be appended to the - "cflags". + See also "asmflags" for flags for assembly-language files. ``` @@ -3460,10 +3453,46 @@ To target one of these variants individually, use "cflags_c", "cflags_cc", "cflags_objc", and "cflags_objcc", - respectively. + respectively. These variant-specific versions of cflags* will be + appended on the compiler command line after "cflags". - These variant-specific versions of cflags* will be appended to the - "cflags". + See also "asmflags" for flags for assembly-language files. + +``` + +### **Ordering of flags and values** + +``` + 1. Those set on the current target (not in a config). + 2. Those set on the "configs" on the target in order that the + configs appear in the list. + 3. Those set on the "all_dependent_configs" on the target in order + that the configs appear in the list. + 4. Those set on the "public_configs" on the target in order that + those configs appear in the list. + 5. all_dependent_configs pulled from dependencies, in the order of + the "deps" list. This is done recursively. If a config appears + more than once, only the first occurance will be used. + 6. public_configs pulled from dependencies, in the order of the + "deps" list. If a dependency is public, they will be applied + recursively. + + +``` +## **cflags***: Flags passed to the C compiler. + +``` + A list of strings. + + "cflags" are passed to all invocations of the C, C++, Objective C, + and Objective C++ compilers. + + To target one of these variants individually, use "cflags_c", + "cflags_cc", "cflags_objc", and "cflags_objcc", + respectively. These variant-specific versions of cflags* will be + appended on the compiler command line after "cflags". + + See also "asmflags" for flags for assembly-language files. ```
diff --git a/tools/gn/filesystem_utils.cc b/tools/gn/filesystem_utils.cc index a3455fd..5905cdb 100644 --- a/tools/gn/filesystem_utils.cc +++ b/tools/gn/filesystem_utils.cc
@@ -377,7 +377,7 @@ #endif } -void NormalizePath(std::string* path) { +void NormalizePath(std::string* path, const base::StringPiece& source_root) { char* pathbuf = path->empty() ? nullptr : &(*path)[0]; // top_index is the first character we can modify in the path. Anything @@ -433,9 +433,48 @@ // up more levels. Otherwise "../.." would collapse to // nothing. top_index = dest_i; + } else if (top_index == 2 && !source_root.empty()) { + // |path| was passed in as a source-absolute path. Prepend + // |source_root| to make |path| absolute. |source_root| must not + // end with a slash unless we are at root. + DCHECK(source_root.size() == 1u || + !IsSlash(source_root[source_root.size() - 1u])); + size_t source_root_len = source_root.size(); + +#if defined(OS_WIN) + // On Windows, if the source_root does not start with a slash, + // append one here for consistency. + if (!IsSlash(source_root[0])) { + path->insert(0, "/" + source_root.as_string()); + source_root_len++; + } else { + path->insert(0, source_root.data(), source_root_len); + } + + // Normalize slashes in source root portion. + for (size_t i = 0; i < source_root_len; ++i) { + if ((*path)[i] == '\\') + (*path)[i] = '/'; + } +#else + path->insert(0, source_root.data(), source_root_len); +#endif + + // |path| is now absolute, so |top_index| is 1. |dest_i| and + // |src_i| should be incremented to keep the same relative + // position. Comsume the leading "//" by decrementing |dest_i|. + top_index = 1; + pathbuf = &(*path)[0]; + dest_i += source_root_len - 2; + src_i += source_root_len; + + // Just find the previous slash or the beginning of input. + while (dest_i > 0 && !IsSlash(pathbuf[dest_i - 1])) + dest_i--; } - // Otherwise we're at the beginning of an absolute path. Don't - // allow ".." to go up another level and just eat it. + // Otherwise we're at the beginning of a system-absolute path, or + // a source-absolute path for which we don't know the absolute + // path. Don't allow ".." to go up another level, and just eat it. } else { // Just find the previous slash or the beginning of input. while (dest_i > 0 && !IsSlash(pathbuf[dest_i - 1]))
diff --git a/tools/gn/filesystem_utils.h b/tools/gn/filesystem_utils.h index 4d71ca7b..e6a17ab 100644 --- a/tools/gn/filesystem_utils.h +++ b/tools/gn/filesystem_utils.h
@@ -111,8 +111,15 @@ const base::StringPiece& path, std::string* dest); -// Collapses "." and sequential "/"s and evaluates "..". -void NormalizePath(std::string* path); +// Collapses "." and sequential "/"s and evaluates "..". |path| may be +// system-absolute, source-absolute, or relative. If |path| is source-absolute +// and |source_root| is non-empty, |path| may be system absolute after this +// function returns, if |path| references the filesystem outside of +// |source_root| (ex. path = "//.."). In this case on Windows, |path| will have +// a leading slash. Otherwise, |path| will retain its relativity. |source_root| +// must not end with a slash. +void NormalizePath(std::string* path, + const base::StringPiece& source_root = base::StringPiece()); // Converts slashes to backslashes for Windows. Keeps the string unchanged // for other systems.
diff --git a/tools/gn/filesystem_utils_unittest.cc b/tools/gn/filesystem_utils_unittest.cc index 9f89512..27ccab2 100644 --- a/tools/gn/filesystem_utils_unittest.cc +++ b/tools/gn/filesystem_utils_unittest.cc
@@ -204,7 +204,7 @@ NormalizePath(&input); EXPECT_EQ("../bar", input); - input = "/../foo"; // Don't go aboe the root dir. + input = "/../foo"; // Don't go above the root dir. NormalizePath(&input); EXPECT_EQ("/foo", input); @@ -241,6 +241,134 @@ input = "//foo/bar/"; NormalizePath(&input); EXPECT_EQ("//foo/bar/", input); + +#if defined(OS_WIN) + // Go above and outside of the source root. + input = "//../foo"; + NormalizePath(&input, "/C:/source/root"); + EXPECT_EQ("/C:/source/foo", input); + + input = "//../foo"; + NormalizePath(&input, "C:\\source\\root"); + EXPECT_EQ("/C:/source/foo", input); + + input = "//../"; + NormalizePath(&input, "/C:/source/root"); + EXPECT_EQ("/C:/source/", input); + + input = "//../foo.txt"; + NormalizePath(&input, "/C:/source/root"); + EXPECT_EQ("/C:/source/foo.txt", input); + + input = "//../foo/bar/"; + NormalizePath(&input, "/C:/source/root"); + EXPECT_EQ("/C:/source/foo/bar/", input); + + // Go above and back into the source root. This should return a system- + // absolute path. We could arguably return this as a source-absolute path, + // but that would require additional handling to account for a rare edge + // case. + input = "//../root/foo"; + NormalizePath(&input, "/C:/source/root"); + EXPECT_EQ("/C:/source/root/foo", input); + + input = "//../root/foo/bar/"; + NormalizePath(&input, "/C:/source/root"); + EXPECT_EQ("/C:/source/root/foo/bar/", input); + + // Stay inside the source root + input = "//foo/bar"; + NormalizePath(&input, "/C:/source/root"); + EXPECT_EQ("//foo/bar", input); + + input = "//foo/bar/"; + NormalizePath(&input, "/C:/source/root"); + EXPECT_EQ("//foo/bar/", input); + + // The path should not go above the system root. Note that on Windows, this + // will consume the drive (C:). + input = "//../../../../../foo/bar"; + NormalizePath(&input, "/C:/source/root"); + EXPECT_EQ("/foo/bar", input); + + // Test when the source root is the letter drive. + input = "//../foo"; + NormalizePath(&input, "/C:"); + EXPECT_EQ("/foo", input); + + input = "//../foo"; + NormalizePath(&input, "C:"); + EXPECT_EQ("/foo", input); + + input = "//../foo"; + NormalizePath(&input, "/"); + EXPECT_EQ("/foo", input); + + input = "//../"; + NormalizePath(&input, "\\C:"); + EXPECT_EQ("/", input); + + input = "//../foo.txt"; + NormalizePath(&input, "/C:"); + EXPECT_EQ("/foo.txt", input); +#else + // Go above and outside of the source root. + input = "//../foo"; + NormalizePath(&input, "/source/root"); + EXPECT_EQ("/source/foo", input); + + input = "//../"; + NormalizePath(&input, "/source/root"); + EXPECT_EQ("/source/", input); + + input = "//../foo.txt"; + NormalizePath(&input, "/source/root"); + EXPECT_EQ("/source/foo.txt", input); + + input = "//../foo/bar/"; + NormalizePath(&input, "/source/root"); + EXPECT_EQ("/source/foo/bar/", input); + + // Go above and back into the source root. This should return a system- + // absolute path. We could arguably return this as a source-absolute path, + // but that would require additional handling to account for a rare edge + // case. + input = "//../root/foo"; + NormalizePath(&input, "/source/root"); + EXPECT_EQ("/source/root/foo", input); + + input = "//../root/foo/bar/"; + NormalizePath(&input, "/source/root"); + EXPECT_EQ("/source/root/foo/bar/", input); + + // Stay inside the source root + input = "//foo/bar"; + NormalizePath(&input, "/source/root"); + EXPECT_EQ("//foo/bar", input); + + input = "//foo/bar/"; + NormalizePath(&input, "/source/root"); + EXPECT_EQ("//foo/bar/", input); + + // The path should not go above the system root. + input = "//../../../../../foo/bar"; + NormalizePath(&input, "/source/root"); + EXPECT_EQ("/foo/bar", input); + + // Test when the source root is the system root. + input = "//../foo/bar/"; + NormalizePath(&input, "/"); + EXPECT_EQ("/foo/bar/", input); + + input = "//../"; + NormalizePath(&input, "/"); + EXPECT_EQ("/", input); + + input = "//../foo.txt"; + NormalizePath(&input, "/"); + EXPECT_EQ("/foo.txt", input); + +#endif } TEST(FilesystemUtils, RebasePath) {
diff --git a/tools/gn/function_rebase_path_unittest.cc b/tools/gn/function_rebase_path_unittest.cc index bed5663..456d4fb8 100644 --- a/tools/gn/function_rebase_path_unittest.cc +++ b/tools/gn/function_rebase_path_unittest.cc
@@ -43,7 +43,7 @@ EXPECT_EQ("../..", RebaseOne(scope, "../..", "//out/Debug", ".")); EXPECT_EQ("../../", RebaseOne(scope, "../../", "//out/Debug", ".")); - // We don't allow going above the root source dir. + // Without a source root defined, we cannot move out of the source tree. EXPECT_EQ("../..", RebaseOne(scope, "../../..", "//out/Debug", ".")); // Source-absolute input paths. @@ -62,19 +62,36 @@ // Test system path output. #if defined(OS_WIN) - setup.build_settings()->SetRootPath(base::FilePath(L"C:/source")); - EXPECT_EQ("C:/source", RebaseOne(scope, ".", "", "//")); - EXPECT_EQ("C:/source/", RebaseOne(scope, "//", "", "//")); - EXPECT_EQ("C:/source/foo", RebaseOne(scope, "foo", "", "//")); - EXPECT_EQ("C:/source/foo/", RebaseOne(scope, "foo/", "", "//")); - EXPECT_EQ("C:/source/tools/gn/foo", RebaseOne(scope, "foo", "", ".")); + setup.build_settings()->SetRootPath(base::FilePath(L"C:/path/to/src")); + EXPECT_EQ("C:/path/to/src", RebaseOne(scope, ".", "", "//")); + EXPECT_EQ("C:/path/to/src/", RebaseOne(scope, "//", "", "//")); + EXPECT_EQ("C:/path/to/src/foo", RebaseOne(scope, "foo", "", "//")); + EXPECT_EQ("C:/path/to/src/foo/", RebaseOne(scope, "foo/", "", "//")); + EXPECT_EQ("C:/path/to/src/tools/gn/foo", RebaseOne(scope, "foo", "", ".")); + EXPECT_EQ("C:/path/to/other/tools", + RebaseOne(scope, "//../other/tools", "", "//")); + EXPECT_EQ("C:/path/to/src/foo/bar", + RebaseOne(scope, "//../src/foo/bar", "", "//")); + EXPECT_EQ("C:/path/to", RebaseOne(scope, "//..", "", "//")); + EXPECT_EQ("C:/path", RebaseOne(scope, "../../../..", "", ".")); + EXPECT_EQ("C:/path/to/external/dir/", + RebaseOne(scope, "//../external/dir/", "", "//")); + #else - setup.build_settings()->SetRootPath(base::FilePath("/source")); - EXPECT_EQ("/source", RebaseOne(scope, ".", "", "//")); - EXPECT_EQ("/source/", RebaseOne(scope, "//", "", "//")); - EXPECT_EQ("/source/foo", RebaseOne(scope, "foo", "", "//")); - EXPECT_EQ("/source/foo/", RebaseOne(scope, "foo/", "", "//")); - EXPECT_EQ("/source/tools/gn/foo", RebaseOne(scope, "foo", "", ".")); + setup.build_settings()->SetRootPath(base::FilePath("/path/to/src")); + EXPECT_EQ("/path/to/src", RebaseOne(scope, ".", "", "//")); + EXPECT_EQ("/path/to/src/", RebaseOne(scope, "//", "", "//")); + EXPECT_EQ("/path/to/src/foo", RebaseOne(scope, "foo", "", "//")); + EXPECT_EQ("/path/to/src/foo/", RebaseOne(scope, "foo/", "", "//")); + EXPECT_EQ("/path/to/src/tools/gn/foo", RebaseOne(scope, "foo", "", ".")); + EXPECT_EQ("/path/to/other/tools", + RebaseOne(scope, "//../other/tools", "", "//")); + EXPECT_EQ("/path/to/src/foo/bar", + RebaseOne(scope, "//../src/foo/bar", "", "//")); + EXPECT_EQ("/path/to", RebaseOne(scope, "//..", "", "//")); + EXPECT_EQ("/path", RebaseOne(scope, "../../../..", "", ".")); + EXPECT_EQ("/path/to/external/dir/", + RebaseOne(scope, "//../external/dir/", "", "//")); #endif }
diff --git a/tools/gn/source_dir.cc b/tools/gn/source_dir.cc index 0966cc6..d9fb4cc 100644 --- a/tools/gn/source_dir.cc +++ b/tools/gn/source_dir.cc
@@ -71,7 +71,7 @@ if (str.size() >= 2 && str[0] == '/' && str[1] == '/') { // Source-relative. ret.value_.assign(str.data(), str.size()); - NormalizePath(&ret.value_); + NormalizePath(&ret.value_, source_root); return ret; } else if (IsPathAbsolute(str)) { if (source_root.empty() || @@ -145,7 +145,7 @@ ret.value_.assign(str.data(), str.size()); if (!EndsWithSlash(ret.value_)) ret.value_.push_back('/'); - NormalizePath(&ret.value_); + NormalizePath(&ret.value_, source_root); return ret; } else if (IsPathAbsolute(str)) { if (source_root.empty() ||
diff --git a/tools/gn/source_dir_unittest.cc b/tools/gn/source_dir_unittest.cc index 04684e6..0c73865e 100644 --- a/tools/gn/source_dir_unittest.cc +++ b/tools/gn/source_dir_unittest.cc
@@ -61,11 +61,41 @@ Value(nullptr, "../../foo"), &err, source_root) == SourceFile("/C:/source/foo")); EXPECT_FALSE(err.has_error()); + + EXPECT_TRUE(base.ResolveRelativeFile( + Value(nullptr, "//../foo"), &err, source_root) == + SourceFile("/C:/source/foo")); + EXPECT_FALSE(err.has_error()); + + EXPECT_TRUE(base.ResolveRelativeFile( + Value(nullptr, "//../root/foo"), &err, source_root) == + SourceFile("/C:/source/root/foo")); + EXPECT_FALSE(err.has_error()); + + EXPECT_TRUE(base.ResolveRelativeFile( + Value(nullptr, "//../../../foo/bar"), &err, source_root) == + SourceFile("/foo/bar")); + EXPECT_FALSE(err.has_error()); #else EXPECT_TRUE(base.ResolveRelativeFile( Value(nullptr, "../../foo"), &err, source_root) == SourceFile("/source/foo")); EXPECT_FALSE(err.has_error()); + + EXPECT_TRUE(base.ResolveRelativeFile( + Value(nullptr, "//../foo"), &err, source_root) == + SourceFile("/source/foo")); + EXPECT_FALSE(err.has_error()); + + EXPECT_TRUE(base.ResolveRelativeFile( + Value(nullptr, "//../root/foo"), &err, source_root) == + SourceFile("/source/root/foo")); + EXPECT_FALSE(err.has_error()); + + EXPECT_TRUE(base.ResolveRelativeFile( + Value(nullptr, "//../../../foo/bar"), &err, source_root) == + SourceFile("/foo/bar")); + EXPECT_FALSE(err.has_error()); #endif #if defined(OS_WIN) @@ -120,11 +150,27 @@ Value(nullptr, "../../foo"), &err, source_root) == SourceDir("/C:/source/foo/")); EXPECT_FALSE(err.has_error()); + EXPECT_TRUE(base.ResolveRelativeDir( + Value(nullptr, "//../foo"), &err, source_root) == + SourceDir("/C:/source/foo/")); + EXPECT_FALSE(err.has_error()); + EXPECT_TRUE(base.ResolveRelativeDir( + Value(nullptr, "//.."), &err, source_root) == + SourceDir("/C:/source/")); + EXPECT_FALSE(err.has_error()); #else EXPECT_TRUE(base.ResolveRelativeDir( Value(nullptr, "../../foo"), &err, source_root) == SourceDir("/source/foo/")); EXPECT_FALSE(err.has_error()); + EXPECT_TRUE(base.ResolveRelativeDir( + Value(nullptr, "//../foo"), &err, source_root) == + SourceDir("/source/foo/")); + EXPECT_FALSE(err.has_error()); + EXPECT_TRUE(base.ResolveRelativeDir( + Value(nullptr, "//.."), &err, source_root) == + SourceDir("/source/")); + EXPECT_FALSE(err.has_error()); #endif #if defined(OS_WIN)
diff --git a/tools/gn/trace.cc b/tools/gn/trace.cc index 4746310..5844293 100644 --- a/tools/gn/trace.cc +++ b/tools/gn/trace.cc
@@ -9,6 +9,8 @@ #include <sstream> #include <vector> +#include "base/command_line.h" +#include "base/files/file_path.h" #include "base/files/file_util.h" #include "base/json/string_escape.h" #include "base/logging.h"
diff --git a/tools/gn/trace.h b/tools/gn/trace.h index e32f319e..de8ab09d 100644 --- a/tools/gn/trace.h +++ b/tools/gn/trace.h
@@ -7,14 +7,17 @@ #include <string> -#include "base/command_line.h" -#include "base/files/file_path.h" #include "base/macros.h" #include "base/threading/platform_thread.h" #include "base/time/time.h" class Label; +namespace base { +class CommandLine; +class FilePath; +} + class TraceItem { public: enum Type {
diff --git a/tools/metrics/actions/actions.xml b/tools/metrics/actions/actions.xml index 536e640..e074c27 100644 --- a/tools/metrics/actions/actions.xml +++ b/tools/metrics/actions/actions.xml
@@ -7936,21 +7936,25 @@ <action name="MobileFirstEditInOmnibox"> <owner>Please list the metric's owners. Add more owner tags as needed.</owner> <description>Please enter the description of this user action.</description> + <obsolete>Deprecated as of 12/2015</obsolete> </action> <action name="MobileFocusedFakeboxOnNtp"> <owner>Please list the metric's owners. Add more owner tags as needed.</owner> <description>Please enter the description of this user action.</description> + <obsolete>Deprecated as of 12/2015</obsolete> </action> <action name="MobileFocusedOmniboxNotOnNtp"> <owner>Please list the metric's owners. Add more owner tags as needed.</owner> <description>Please enter the description of this user action.</description> + <obsolete>Deprecated as of 12/2015</obsolete> </action> <action name="MobileFocusedOmniboxOnNtp"> <owner>Please list the metric's owners. Add more owner tags as needed.</owner> <description>Please enter the description of this user action.</description> + <obsolete>Deprecated as of 12/2015</obsolete> </action> <action name="MobileFre.SignInShown">
diff --git a/tools/metrics/histograms/histograms.xml b/tools/metrics/histograms/histograms.xml index 7ad19572..abd8810 100644 --- a/tools/metrics/histograms/histograms.xml +++ b/tools/metrics/histograms/histograms.xml
@@ -367,6 +367,16 @@ </summary> </histogram> +<histogram name="AppBanners.MinutesFromFirstVisitToBannerShown" units="minutes"> + <owner>dominickn@chromium.org</owner> + <summary> + App banners promote an application related to the current website, and are + requested specifically through the current page's HTML. This stat tracks + the number of minutes between the first recorded visit to an origin and the + time when the banner is actually shown. + </summary> +</histogram> + <histogram name="AppBanners.UserResponse" enum="AppBannersUserResponse"> <owner>dominickn@chromium.org</owner> <summary> @@ -10756,6 +10766,23 @@ </summary> </histogram> +<histogram name="Event.PassiveListeners" enum="EventResultType"> + <owner>dtapuska@chromium.org</owner> + <summary> + The result of handling of MouseWheel, TouchStart, TouchMove, TouchEnd events + in the renderer. + </summary> +</histogram> + +<histogram name="Event.PassiveListeners.Latency" units="microseconds"> + <owner>dtapuska@chromium.org</owner> + <summary> + Time between when a cancelable event was generated and the event processed + yet no action was executed for the event. This histogram tracks the + potential benefit of using passive events listeners. + </summary> +</histogram> + <histogram name="Event.SingleTapType" enum="TapDelayType"> <owner>rbyers@chromium.org</owner> <summary> @@ -20354,6 +20381,16 @@ </summary> </histogram> +<histogram name="MobileStartup.TimeSinceLastUse" units="minutes"> + <owner>knn@chromium.org</owner> + <summary> + Android: The time since last use until Chrome is launched from the home + screen. This is measured from the time the last tab is closed until a Main + intent is received. Has a minute level precision for first 10 minutes + increasing exponentially till 30 days. + </summary> +</histogram> + <histogram name="MobileStartup.ToolbarFirstDrawTime" units="milliseconds"> <owner>yusufo@chromium.org</owner> <summary> @@ -50551,6 +50588,33 @@ </summary> </histogram> +<histogram name="UpdateEngine.CertificateCheck.Download" + enum="UpdateEngineCertificateCheckStatus"> + <owner>deymo@chromium.org</owner> + <summary> + The status of the certificate check done when downloading a payload over + HTTPS. Note that most downloads are done over HTTP. + + This is reported on every HTTPS connection to the payload download server. + Connection drops on the same payload may report different values. + + This metric is specific to ChromeOS. + </summary> +</histogram> + +<histogram name="UpdateEngine.CertificateCheck.UpdateCheck" + enum="UpdateEngineCertificateCheckStatus"> + <owner>deymo@chromium.org</owner> + <summary> + The status of the certificate check done when querying Omaha for a new + version. + + This is reported on every update check. + + This metric is specific to ChromeOS. + </summary> +</histogram> + <histogram name="UpdateEngine.Check.DownloadErrorCode" enum="UpdateEngineDownloadErrorCode"> <owner>zeuthen@chromium.org</owner> @@ -51218,6 +51282,12 @@ <summary>Time spent doing a full GC during an IdleNotification.</summary> </histogram> +<histogram name="V8.GCFinalizeMC" units="milliseconds"> + <owner>ulan@chromium.org</owner> + <owner>hpayer@chromium.org</owner> + <summary>Time spent in finalize incremental mark-sweep phase of GC.</summary> +</histogram> + <histogram name="V8.GCFinalizeMCReduceMemory" units="milliseconds"> <owner>ulan@chromium.org</owner> <owner>hpayer@chromium.org</owner> @@ -51227,6 +51297,10 @@ </histogram> <histogram name="V8.GCFinalzeMC" units="milliseconds"> + <obsolete> + This histogram has been replaced by V8.GCFinalizeMC because of typo in the + name. + </obsolete> <owner>ulan@chromium.org</owner> <owner>hpayer@chromium.org</owner> <summary>Time spent in finalize incremental mark-sweep phase of GC.</summary> @@ -55989,6 +56063,8 @@ <int value="98" label="BDH_CHARACTERISTIC_ALREADY_SUBSCRIBED"/> <int value="99" label="RFH_OWNER_PROPERTY"/> <int value="100" label="BDH_EMPTY_OR_INVALID_FILTERS"/> + <int value="101" label="WC_CONTENT_WITH_CERT_ERRORS_BAD_SECURITY_INFO"/> + <int value="102" label="RFMF_RENDERER_FAKED_ITS_OWN_DEATH"/> </enum> <enum name="BadMessageReasonExtensions" type="int"> @@ -57854,6 +57930,7 @@ <int value="7010" label="SBOX_FATAL_CLOSEHANDLES"/> <int value="7011" label="SBOX_FATAL_MITIGATION"/> <int value="7012" label="SBOX_FATAL_MEMORY_EXCEEDED"/> + <int value="7013" label="SBOX_FATAL_WARMUP"/> <int value="529697949" label="CPP_EH_EXCEPTION"/> <int value="533692099" label="STATUS_GUARD_PAGE_VIOLATION"/> <int value="1073740791" label="STATUS_STACK_BUFFER_OVERRUN"/> @@ -60411,6 +60488,13 @@ <int value="128" label="Request type matched."/> </enum> +<enum name="EventResultType" type="int"> + <int value="0" label="Passive"/> + <int value="1" label="Uncancelable"/> + <int value="2" label="Cancelable and not canceled"/> + <int value="3" label="Cancelable and canceled"/> +</enum> + <enum name="EVWhitelistStatus" type="int"> <int value="0" label="Not present"/> <int value="1" label="Invalid"/> @@ -63672,6 +63756,32 @@ <int value="1038" label="PresentationConnectionClose"/> <int value="1039" label="SVG1DOMShape"/> <int value="1040" label="SVG1DOMText"/> + <int value="1041" label="RTCPeerConnectionConstructorConstraints"/> + <int value="1042" label="RTCPeerConnectionConstructorCompliant"/> + <int value="1043" + label="RTCPeerConnectionCreateOfferLegacyNoFailureCallback"/> + <int value="1044" label="RTCPeerConnectionCreateOfferLegacyFailureCallback"/> + <int value="1045" label="RTCPeerConnectionCreateOfferLegacyConstraints"/> + <int value="1046" label="RTCPeerConnectionCreateOfferLegacyOfferOptions"/> + <int value="1047" label="RTCPeerConnectionCreateOfferLegacyCompliant"/> + <int value="1048" + label="RTCPeerConnectionCreateAnswerLegacyNoFailureCallback"/> + <int value="1049" label="RTCPeerConnectionCreateAnswerLegacyFailureCallback"/> + <int value="1050" label="RTCPeerConnectionCreateAnswerLegacyConstraints"/> + <int value="1051" label="RTCPeerConnectionCreateAnswerLegacyCompliant"/> + <int value="1052" + label="RTCPeerConnectionSetLocalDescriptionLegacyNoSuccessCallback"/> + <int value="1053" + label="RTCPeerConnectionSetLocalDescriptionLegacyNoFailureCallback"/> + <int value="1054" + label="RTCPeerConnectionSetLocalDescriptionLegacyCompliant"/> + <int value="1055" + label="RTCPeerConnectionSetRemoteDescriptionLegacyNoSuccessCallback"/> + <int value="1056" + label="RTCPeerConnectionSetRemoteDescriptionLegacyNoFailureCallback"/> + <int value="1057" + label="RTCPeerConnectionSetRemoteDescriptionLegacyCompliant"/> + <int value="1058" label="RTCPeerConnectionGetStatsLegacyNonCompliant"/> </enum> <enum name="FetchRequestMode" type="int"> @@ -66575,6 +66685,13 @@ <int value="12" label="ERROR_SOURCE_NOT_FOUND"> Broker didn't have a channel of communication with the source process. </int> + <int value="13" label="ERROR_COULD_NOT_OPEN_SOURCE_OR_DEST"> + Broker could not open the source or destination process with extra + privileges. + </int> + <int value="14" label="ERROR_INVALID_PERMISSIONS"> + Broker was asked to transfer a HANDLE with invalid permissions. + </int> </enum> <enum name="IPCAttachmentBrokerUnprivilegedBrokerAttachmentError" type="int"> @@ -67579,6 +67696,7 @@ <int value="-2008272679" label="disable-webrtc-hw-encoding"/> <int value="-2003354337" label="enable-search-button-in-omnibox-for-str-or-iip"/> + <int value="-1999892428" label="force-ui-direction"/> <int value="-1998927516" label="enable-md-settings"/> <int value="-1985025593" label="file-manager-enable-new-gallery"/> <int value="-1980328793" label="trace-upload-url"/> @@ -77631,6 +77749,20 @@ <int value="10" label="Abnormal Termination"/> </enum> +<enum name="UpdateEngineCertificateCheckStatus" type="int"> + <int value="0" label="Valid certificate"> + The certificate is valid and the same as seen before or the first time we + see a certificate. + </int> + <int value="1" label="Changed certificate"> + The certificate is valid, but is different than a previously seen + certificate for the selected server. + </int> + <int value="2" label="Certificate check failed"> + The certificate validation failed. + </int> +</enum> + <enum name="UpdateEngineCheckReaction" type="int"> <int value="0" label="Updating"/> <int value="1" label="Ignoring"/>
diff --git a/tools/perf/benchmarks/smoothness.py b/tools/perf/benchmarks/smoothness.py index 769b679..be9c195 100644 --- a/tools/perf/benchmarks/smoothness.py +++ b/tools/perf/benchmarks/smoothness.py
@@ -2,6 +2,7 @@ # Use of this source code is governed by a BSD-style license that can be # found in the LICENSE file. + from core import perf_benchmark from benchmarks import silk_flags
diff --git a/tools/telemetry/bin/android/arm64-v8a/run_pie.sha1 b/tools/telemetry/bin/android/arm64-v8a/run_pie.sha1 deleted file mode 100644 index c22a415..0000000 --- a/tools/telemetry/bin/android/arm64-v8a/run_pie.sha1 +++ /dev/null
@@ -1 +0,0 @@ -30cdda413b6cdaf4646c0522f6032aa17a3ddeb6 \ No newline at end of file
diff --git a/tools/telemetry/bin/android/armeabi-v7a/run_pie.sha1 b/tools/telemetry/bin/android/armeabi-v7a/run_pie.sha1 deleted file mode 100644 index 1811d995..0000000 --- a/tools/telemetry/bin/android/armeabi-v7a/run_pie.sha1 +++ /dev/null
@@ -1 +0,0 @@ -464e2b4b72281b18ef1c312aa8d125e750c6c8b4 \ No newline at end of file
diff --git a/tools/telemetry/catapult_base/cloud_storage.py b/tools/telemetry/catapult_base/cloud_storage.py index f4dca2a..ae8223e2 100644 --- a/tools/telemetry/catapult_base/cloud_storage.py +++ b/tools/telemetry/catapult_base/cloud_storage.py
@@ -43,7 +43,7 @@ BUCKET_ALIAS_NAMES = BUCKET_ALIASES.keys() -_GSUTIL_PATH = os.path.join(path.GetTelemetryDir(), 'third_party', 'gsutilz', +_GSUTIL_PATH = os.path.join(util.GetCatapultDir(), 'third_party', 'gsutil', 'gsutil') # TODO(tbarzic): A workaround for http://crbug.com/386416 and
diff --git a/tools/telemetry/catapult_base/dependency_manager/cloud_storage_info.py b/tools/telemetry/catapult_base/dependency_manager/cloud_storage_info.py index 880cfe2..1e1c1d5 100644 --- a/tools/telemetry/catapult_base/dependency_manager/cloud_storage_info.py +++ b/tools/telemetry/catapult_base/dependency_manager/cloud_storage_info.py
@@ -2,6 +2,7 @@ # Use of this source code is governed by a BSD-style license that can be # found in the LICENSE file. +import errno import logging import os import stat @@ -63,7 +64,13 @@ download_dir = os.path.dirname(self._download_path) if not os.path.exists(download_dir): - os.makedirs(download_dir) + try: + os.makedirs(download_dir) + except OSError as e: + # The logic above is racy, and os.makedirs will raise an OSError if + # the directory exists. + if e.errno != errno.EEXIST: + raise dependency_path = self._download_path cloud_storage.GetIfHashChanged(
diff --git a/tools/telemetry/telemetry/android/shared_android_state.py b/tools/telemetry/telemetry/android/shared_android_state.py index f2ac14f5..bb813bd 100644 --- a/tools/telemetry/telemetry/android/shared_android_state.py +++ b/tools/telemetry/telemetry/android/shared_android_state.py
@@ -33,8 +33,10 @@ self._finder_options = finder_options self._android_app = None self._current_story = None + device = android_device.GetDevice(finder_options) + assert device, 'Android device required.' self._android_platform = platform.GetPlatformForDevice( - android_device.GetDevice(finder_options), finder_options) + device, finder_options) assert self._android_platform, 'Unable to create android platform.' assert isinstance( self._android_platform, android_platform.AndroidPlatform)
diff --git a/tools/telemetry/telemetry/core/util.py b/tools/telemetry/telemetry/core/util.py index 8d8f705c..26bdd486 100644 --- a/tools/telemetry/telemetry/core/util.py +++ b/tools/telemetry/telemetry/core/util.py
@@ -23,12 +23,11 @@ def GetTelemetryDir(): return os.path.normpath(os.path.join( - __file__, '..', '..', '..')) + os.path.abspath(__file__), '..', '..', '..')) def GetTelemetryThirdPartyDir(): - return os.path.normpath(os.path.join( - __file__, '..', '..', '..', 'third_party')) + return os.path.join(GetTelemetryDir(), 'third_party') def GetUnittestDataDir(): @@ -40,6 +39,12 @@ return os.path.normpath(os.path.join(GetTelemetryDir(), '..', '..')) +# TODO(aiolos): Move this over to the path in catapult after the migration. +def GetCatapultDir(): + return os.path.normpath(os.path.join( + GetTelemetryDir(), '..', '..', 'third_party', 'catapult')) + + _counter = [0] def _GetUniqueModuleName(): _counter[0] += 1
diff --git a/tools/telemetry/telemetry/internal/actions/repeatable_scroll.py b/tools/telemetry/telemetry/internal/actions/repeatable_scroll.py index ef33399..79ba4c4 100644 --- a/tools/telemetry/telemetry/internal/actions/repeatable_scroll.py +++ b/tools/telemetry/telemetry/internal/actions/repeatable_scroll.py
@@ -9,13 +9,14 @@ class RepeatableScrollAction(page_action.PageAction): def __init__(self, x_scroll_distance_ratio=0.0, y_scroll_distance_ratio=0.5, - repeat_count=0, repeat_delay_ms=250): + repeat_count=0, repeat_delay_ms=250, timeout=60): super(RepeatableScrollAction, self).__init__() self._x_scroll_distance_ratio = x_scroll_distance_ratio self._y_scroll_distance_ratio = y_scroll_distance_ratio self._repeat_count = repeat_count self._repeat_delay_ms = repeat_delay_ms self._windowsize = [] + self._timeout = timeout def WillRunAction(self, tab): # Get the dimensions of the screen. @@ -35,4 +36,5 @@ repeatCount=self._repeat_count, repeatDelayMs=self._repeat_delay_ms, interactionMarkerName=timeline_interaction_record.GetJavaScriptMarker( - 'Gesture_ScrollAction', [timeline_interaction_record.REPEATABLE])) + 'Gesture_ScrollAction', [timeline_interaction_record.REPEATABLE]), + timeout=self._timeout)
diff --git a/tools/telemetry/telemetry/internal/browser/web_contents.py b/tools/telemetry/telemetry/internal/browser/web_contents.py index 25f19806..d360f1d8 100644 --- a/tools/telemetry/telemetry/internal/browser/web_contents.py +++ b/tools/telemetry/telemetry/internal/browser/web_contents.py
@@ -300,7 +300,8 @@ xOverscroll=None, yOverscroll=None, preventFling=True, speed=None, gestureSourceType=None, repeatCount=None, - repeatDelayMs=None, interactionMarkerName=None): + repeatDelayMs=None, interactionMarkerName=None, + timeout=60): """Runs an inspector command that causes a repeatable browser driven scroll. Args: @@ -327,4 +328,5 @@ preventFling=preventFling, speed=speed, gestureSourceType=gestureSourceType, repeatCount=repeatCount, repeatDelayMs=repeatDelayMs, - interactionMarkerName=interactionMarkerName) + interactionMarkerName=interactionMarkerName, + timeout=timeout)
diff --git a/tools/telemetry/telemetry/internal/platform/android_device.py b/tools/telemetry/telemetry/internal/platform/android_device.py index 20608639..9b62989 100644 --- a/tools/telemetry/telemetry/internal/platform/android_device.py +++ b/tools/telemetry/telemetry/internal/platform/android_device.py
@@ -103,21 +103,21 @@ 'No adb command found. Will not try searching for Android browsers.') return None - if (finder_options.device - and finder_options.device in GetDeviceSerials(finder_options)): - return AndroidDevice( - finder_options.device, - enable_performance_mode=not finder_options.no_performance_mode) - if finder_options.android_blacklist_file: blacklist = device_blacklist.Blacklist( finder_options.android_blacklist_file) else: blacklist = None + if (finder_options.device + and finder_options.device in GetDeviceSerials(blacklist)): + return AndroidDevice( + finder_options.device, + enable_performance_mode=not finder_options.no_performance_mode) + devices = AndroidDevice.GetAllConnectedDevices(blacklist) if len(devices) == 0: - logging.info('No android devices found.') + logging.warn('No android devices found.') return None if len(devices) > 1: logging.warn( @@ -129,6 +129,9 @@ def CanDiscoverDevices(): """Returns true if devices are discoverable via adb.""" + if os.name != 'posix': + return False + adb_path = constants.GetAdbPath() if os.path.isabs(adb_path) and not os.path.exists(adb_path): return False
diff --git a/tools/telemetry/telemetry/internal/platform/android_device_unittest.py b/tools/telemetry/telemetry/internal/platform/android_device_unittest.py index f953b30..85eaadb 100644 --- a/tools/telemetry/telemetry/internal/platform/android_device_unittest.py +++ b/tools/telemetry/telemetry/internal/platform/android_device_unittest.py
@@ -4,19 +4,27 @@ import unittest +from telemetry import decorators from telemetry.internal.browser import browser_options from telemetry.internal.platform import android_device from telemetry.testing import system_stub import mock from devil.android import device_utils +from devil.android import device_blacklist class _BaseAndroidDeviceTest(unittest.TestCase): def setUp(self): + def check_blacklist_arg(blacklist): + self.assertTrue(blacklist is None + or isinstance(blacklist, device_blacklist.Blacklist)) + return mock.DEFAULT + self._healthy_device_patcher = mock.patch( 'devil.android.device_utils.DeviceUtils.HealthyDevices') self._healthy_device_mock = self._healthy_device_patcher.start() + self._healthy_device_mock.side_effect = check_blacklist_arg self._android_device_stub = system_stub.Override( android_device, ['subprocess', 'logging']) @@ -31,6 +39,7 @@ class AndroidDeviceTest(_BaseAndroidDeviceTest): + @decorators.Enabled('android') def testGetAllAttachedAndroidDevices(self): self._healthy_device_mock.return_value = [ self._GetMockDeviceUtils('01'), @@ -42,6 +51,7 @@ set(device.device_id for device in android_device.AndroidDevice.GetAllConnectedDevices(None))) + @decorators.Enabled('android') def testNoAdbReturnsNone(self): finder_options = browser_options.BrowserFinderOptions() with ( @@ -50,6 +60,7 @@ self.assertEquals([], self._android_device_stub.logging.warnings) self.assertIsNone(android_device.GetDevice(finder_options)) + @decorators.Enabled('android') def testAdbNoDevicesReturnsNone(self): finder_options = browser_options.BrowserFinderOptions() with mock.patch('os.path.isabs', return_value=False): @@ -57,6 +68,7 @@ self.assertEquals([], self._android_device_stub.logging.warnings) self.assertIsNone(android_device.GetDevice(finder_options)) + @decorators.Enabled('android') def testAdbTwoDevicesReturnsNone(self): finder_options = browser_options.BrowserFinderOptions() with mock.patch('os.path.isabs', return_value=False): @@ -71,6 +83,7 @@ self._android_device_stub.logging.warnings) self.assertIsNone(device) + @decorators.Enabled('android') def testAdbPickOneDeviceReturnsDeviceInstance(self): finder_options = browser_options.BrowserFinderOptions() finder_options.device = '555d14fecddddddd' # pick one @@ -82,6 +95,7 @@ self.assertEquals([], self._android_device_stub.logging.warnings) self.assertEquals('555d14fecddddddd', device.device_id) + @decorators.Enabled('android') def testAdbOneDeviceReturnsDeviceInstance(self): finder_options = browser_options.BrowserFinderOptions() with mock.patch('os.path.isabs', return_value=False): @@ -93,6 +107,7 @@ class FindAllAvailableDevicesTest(_BaseAndroidDeviceTest): + @decorators.Enabled('android') def testAdbNoDeviceReturnsEmptyList(self): finder_options = browser_options.BrowserFinderOptions() with mock.patch('os.path.isabs', return_value=False): @@ -102,6 +117,7 @@ self.assertIsNotNone(devices) self.assertEquals(len(devices), 0) + @decorators.Enabled('android') def testAdbOneDeviceReturnsListWithOneDeviceInstance(self): finder_options = browser_options.BrowserFinderOptions() with mock.patch('os.path.isabs', return_value=False): @@ -113,6 +129,7 @@ self.assertEquals(len(devices), 1) self.assertEquals('015d14fec128220c', devices[0].device_id) + @decorators.Enabled('android') def testAdbMultipleDevicesReturnsListWithAllDeviceInstances(self): finder_options = browser_options.BrowserFinderOptions() with mock.patch('os.path.isabs', return_value=False):
diff --git a/tools/telemetry/telemetry/internal/platform/android_platform_backend.py b/tools/telemetry/telemetry/internal/platform/android_platform_backend.py index 5c8f333..2d97821 100644 --- a/tools/telemetry/telemetry/internal/platform/android_platform_backend.py +++ b/tools/telemetry/telemetry/internal/platform/android_platform_backend.py
@@ -71,7 +71,6 @@ 'memtrack_helper', 'md5sum_dist/md5sum_bin', 'purge_ashmem', - 'run_pie', ] host_tools = [
diff --git a/tools/telemetry/telemetry/internal/util/binary_manager.py b/tools/telemetry/telemetry/internal/util/binary_manager.py index e277b70..fb89615 100644 --- a/tools/telemetry/telemetry/internal/util/binary_manager.py +++ b/tools/telemetry/telemetry/internal/util/binary_manager.py
@@ -10,6 +10,7 @@ from catapult_base import dependency_manager from telemetry.core import exceptions from telemetry.core import util +from devil import devil_env TELEMETRY_PROJECT_CONFIG = os.path.join( @@ -34,6 +35,8 @@ configs.insert(0, dependency_manager.BaseConfig(environment_config)) _dependency_manager = dependency_manager.DependencyManager(configs) + devil_env.config.Initialize() + def FetchPath(binary_name, arch, platform): """ Return a path to the appropriate executable for <binary_name>, downloading
diff --git a/tools/telemetry/telemetry/internal/util/path.py b/tools/telemetry/telemetry/internal/util/path.py index 5946a92..45c3ecb8 100644 --- a/tools/telemetry/telemetry/internal/util/path.py +++ b/tools/telemetry/telemetry/internal/util/path.py
@@ -7,7 +7,7 @@ from telemetry.core import util -# TODO(dtu): Move these functions from core.util to here. +# TODO(aiolos): Move these functions to catapult_base or here. GetBaseDir = util.GetBaseDir GetTelemetryDir = util.GetTelemetryDir GetUnittestDataDir = util.GetUnittestDataDir
diff --git a/tools/telemetry/telemetry/page/action_runner.py b/tools/telemetry/telemetry/page/action_runner.py index 805e62d6..d36a6c1 100644 --- a/tools/telemetry/telemetry/page/action_runner.py +++ b/tools/telemetry/telemetry/page/action_runner.py
@@ -362,7 +362,8 @@ def RepeatableBrowserDrivenScroll(self, x_scroll_distance_ratio=0.0, y_scroll_distance_ratio=0.5, repeat_count=0, - repeat_delay_ms=250): + repeat_delay_ms=250, + timeout=60): """Perform a browser driven repeatable scroll gesture. The scroll gesture is driven from the browser, this is useful because the @@ -381,7 +382,7 @@ x_scroll_distance_ratio=x_scroll_distance_ratio, y_scroll_distance_ratio=y_scroll_distance_ratio, repeat_count=repeat_count, - repeat_delay_ms=repeat_delay_ms)) + repeat_delay_ms=repeat_delay_ms, timeout=timeout)) def ScrollElement(self, selector=None, text=None, element_function=None, left_start_ratio=0.5, top_start_ratio=0.5,
diff --git a/ui/base/clipboard/clipboard.h b/ui/base/clipboard/clipboard.h index af8f439c..8a5e5dc 100644 --- a/ui/base/clipboard/clipboard.h +++ b/ui/base/clipboard/clipboard.h
@@ -5,6 +5,8 @@ #ifndef UI_BASE_CLIPBOARD_CLIPBOARD_H_ #define UI_BASE_CLIPBOARD_CLIPBOARD_H_ +#include <stdint.h> + #include <map> #include <string> #include <vector> @@ -148,7 +150,7 @@ // Returns a sequence number which uniquely identifies clipboard state. // This can be used to version the data on the clipboard and determine // whether it has changed. - virtual uint64 GetSequenceNumber(ClipboardType type) const = 0; + virtual uint64_t GetSequenceNumber(ClipboardType type) const = 0; // Tests whether the clipboard contains a certain format virtual bool IsFormatAvailable(const FormatType& format,
diff --git a/ui/base/clipboard/clipboard_aura.cc b/ui/base/clipboard/clipboard_aura.cc index e6823924..cfe4986 100644 --- a/ui/base/clipboard/clipboard_aura.cc +++ b/ui/base/clipboard/clipboard_aura.cc
@@ -4,9 +4,11 @@ #include "ui/base/clipboard/clipboard_aura.h" +#include <stdint.h> + +#include <limits> #include <list> -#include "base/basictypes.h" #include "base/files/file_path.h" #include "base/logging.h" #include "base/memory/scoped_ptr.h" @@ -210,8 +212,8 @@ // Reads HTML from the data at the top of clipboard stack. void ReadHTML(base::string16* markup, std::string* src_url, - uint32* fragment_start, - uint32* fragment_end) const { + uint32_t* fragment_start, + uint32_t* fragment_end) const { markup->clear(); if (src_url) src_url->clear(); @@ -226,8 +228,8 @@ *src_url = data->url(); *fragment_start = 0; - DCHECK_LE(markup->length(), kuint32max); - *fragment_end = static_cast<uint32>(markup->length()); + DCHECK_LE(markup->length(), std::numeric_limits<uint32_t>::max()); + *fragment_end = static_cast<uint32_t>(markup->length()); } // Reads RTF from the data at the top of clipboard stack. @@ -528,7 +530,7 @@ DeleteClipboard(); } -uint64 ClipboardAura::GetSequenceNumber(ClipboardType type) const { +uint64_t ClipboardAura::GetSequenceNumber(ClipboardType type) const { DCHECK(CalledOnValidThread()); return GetClipboard()->sequence_number(); } @@ -605,8 +607,8 @@ void ClipboardAura::ReadHTML(ClipboardType type, base::string16* markup, std::string* src_url, - uint32* fragment_start, - uint32* fragment_end) const { + uint32_t* fragment_start, + uint32_t* fragment_end) const { DCHECK(CalledOnValidThread()); GetClipboard()->ReadHTML(markup, src_url, fragment_start, fragment_end); }
diff --git a/ui/base/clipboard/clipboard_aura.h b/ui/base/clipboard/clipboard_aura.h index e5fbc34..39fd07e 100644 --- a/ui/base/clipboard/clipboard_aura.h +++ b/ui/base/clipboard/clipboard_aura.h
@@ -17,7 +17,7 @@ ~ClipboardAura() override; // Clipboard overrides: - uint64 GetSequenceNumber(ClipboardType type) const override; + uint64_t GetSequenceNumber(ClipboardType type) const override; bool IsFormatAvailable(const FormatType& format, ClipboardType type) const override; void Clear(ClipboardType type) override;
diff --git a/ui/base/clipboard/clipboard_aurax11.cc b/ui/base/clipboard/clipboard_aurax11.cc index b9b53f18..d9759b8d 100644 --- a/ui/base/clipboard/clipboard_aurax11.cc +++ b/ui/base/clipboard/clipboard_aurax11.cc
@@ -4,12 +4,14 @@ #include "ui/base/clipboard/clipboard_aurax11.h" +#include <stdint.h> #include <X11/extensions/Xfixes.h> #include <X11/Xatom.h> + +#include <limits> #include <list> #include <set> -#include "base/basictypes.h" #include "base/files/file_path.h" #include "base/logging.h" #include "base/memory/ref_counted_memory.h" @@ -65,10 +67,10 @@ public: static SelectionChangeObserver* GetInstance(); - uint64 clipboard_sequence_number() const { + uint64_t clipboard_sequence_number() const { return clipboard_sequence_number_; } - uint64 primary_sequence_number() const { return primary_sequence_number_; } + uint64_t primary_sequence_number() const { return primary_sequence_number_; } private: friend struct base::DefaultSingletonTraits<SelectionChangeObserver>; @@ -82,8 +84,8 @@ int event_base_; Atom clipboard_atom_; - uint64 clipboard_sequence_number_; - uint64 primary_sequence_number_; + uint64_t clipboard_sequence_number_; + uint64_t primary_sequence_number_; DISALLOW_COPY_AND_ASSIGN(SelectionChangeObserver); }; @@ -670,7 +672,7 @@ aurax11_details_->StoreCopyPasteDataAndWait(); } -uint64 ClipboardAuraX11::GetSequenceNumber(ClipboardType type) const { +uint64_t ClipboardAuraX11::GetSequenceNumber(ClipboardType type) const { DCHECK(CalledOnValidThread()); if (type == CLIPBOARD_TYPE_COPY_PASTE) return SelectionChangeObserver::GetInstance()->clipboard_sequence_number(); @@ -753,8 +755,8 @@ void ClipboardAuraX11::ReadHTML(ClipboardType type, base::string16* markup, std::string* src_url, - uint32* fragment_start, - uint32* fragment_end) const { + uint32_t* fragment_start, + uint32_t* fragment_end) const { DCHECK(CalledOnValidThread()); markup->clear(); if (src_url) @@ -768,8 +770,8 @@ *markup = data.GetHtml(); *fragment_start = 0; - DCHECK(markup->length() <= kuint32max); - *fragment_end = static_cast<uint32>(markup->length()); + DCHECK(markup->length() <= std::numeric_limits<uint32_t>::max()); + *fragment_end = static_cast<uint32_t>(markup->length()); } }
diff --git a/ui/base/clipboard/clipboard_mac.h b/ui/base/clipboard/clipboard_mac.h index d6a1d43..f14bd00 100644 --- a/ui/base/clipboard/clipboard_mac.h +++ b/ui/base/clipboard/clipboard_mac.h
@@ -17,7 +17,7 @@ ~ClipboardMac() override; // Clipboard overrides: - uint64 GetSequenceNumber(ClipboardType type) const override; + uint64_t GetSequenceNumber(ClipboardType type) const override; bool IsFormatAvailable(const FormatType& format, ClipboardType type) const override; void Clear(ClipboardType type) override;
diff --git a/ui/base/clipboard/clipboard_mac.mm b/ui/base/clipboard/clipboard_mac.mm index 306502f..05da58b 100644 --- a/ui/base/clipboard/clipboard_mac.mm +++ b/ui/base/clipboard/clipboard_mac.mm
@@ -5,8 +5,10 @@ #include "ui/base/clipboard/clipboard_mac.h" #import <Cocoa/Cocoa.h> +#include <stdint.h> -#include "base/basictypes.h" +#include <limits> + #include "base/files/file_path.h" #include "base/logging.h" #include "base/mac/mac_util.h" @@ -183,7 +185,7 @@ DCHECK(CalledOnValidThread()); } -uint64 ClipboardMac::GetSequenceNumber(ClipboardType type) const { +uint64_t ClipboardMac::GetSequenceNumber(ClipboardType type) const { DCHECK(CalledOnValidThread()); DCHECK_EQ(type, CLIPBOARD_TYPE_COPY_PASTE); @@ -264,8 +266,8 @@ void ClipboardMac::ReadHTML(ClipboardType type, base::string16* markup, std::string* src_url, - uint32* fragment_start, - uint32* fragment_end) const { + uint32_t* fragment_start, + uint32_t* fragment_end) const { DCHECK(CalledOnValidThread()); DCHECK_EQ(type, CLIPBOARD_TYPE_COPY_PASTE); @@ -288,8 +290,8 @@ } *fragment_start = 0; - DCHECK(markup->length() <= kuint32max); - *fragment_end = static_cast<uint32>(markup->length()); + DCHECK(markup->length() <= std::numeric_limits<uint32_t>::max()); + *fragment_end = static_cast<uint32_t>(markup->length()); } void ClipboardMac::ReadRTF(ClipboardType type, std::string* result) const {
diff --git a/ui/base/resource/resource_bundle.cc b/ui/base/resource/resource_bundle.cc index 6d042715..784f6e86 100644 --- a/ui/base/resource/resource_bundle.cc +++ b/ui/base/resource/resource_bundle.cc
@@ -39,6 +39,7 @@ #if defined(OS_ANDROID) #include "ui/base/resource/resource_bundle_android.h" +#include "ui/gfx/android/device_display_info.h" #endif #if defined(OS_CHROMEOS) @@ -608,9 +609,13 @@ supported_scale_factors.push_back(SCALE_FACTOR_100P); #endif #if defined(OS_ANDROID) - const gfx::Display display = - gfx::Screen::GetNativeScreen()->GetPrimaryDisplay(); - const float display_density = display.device_scale_factor(); + float display_density; + if (gfx::Display::HasForceDeviceScaleFactor()) { + display_density = gfx::Display::GetForcedDeviceScaleFactor(); + } else { + gfx::DeviceDisplayInfo device_info; + display_density = device_info.GetDIPScale(); + } const ScaleFactor closest = FindClosestScaleFactorUnsafe(display_density); if (closest != SCALE_FACTOR_100P) supported_scale_factors.push_back(closest);
diff --git a/ui/compositor/clip_recorder.cc b/ui/compositor/clip_recorder.cc index 0a3bc15..cec5c3d9 100644 --- a/ui/compositor/clip_recorder.cc +++ b/ui/compositor/clip_recorder.cc
@@ -10,59 +10,68 @@ #include "ui/compositor/paint_context.h" #include "ui/gfx/canvas.h" #include "ui/gfx/geometry/rect.h" +#include "ui/gfx/geometry/rect_conversions.h" #include "ui/gfx/path.h" +#include "ui/gfx/skia_util.h" namespace ui { -ClipRecorder::ClipRecorder(const PaintContext& context, - const gfx::Size& size_in_layer) - : context_(context), - bounds_in_layer_(context.ToLayerSpaceBounds(size_in_layer)), - num_closers_(0) {} +ClipRecorder::ClipRecorder(const PaintContext& context) + : context_(context), num_closers_(0) {} ClipRecorder::~ClipRecorder() { - for (size_t i = num_closers_; i > 0; --i) { - switch (closers_[i - 1]) { + for (int i = num_closers_ - 1; i >= 0; --i) { + const gfx::Rect& bounds_in_layer = bounds_in_layer_[i]; + switch (closers_[i]) { case CLIP_RECT: context_.list_->CreateAndAppendItem<cc::EndClipDisplayItem>( - bounds_in_layer_); + bounds_in_layer); break; case CLIP_PATH: context_.list_->CreateAndAppendItem<cc::EndClipPathDisplayItem>( - bounds_in_layer_); + bounds_in_layer); break; } } } +void ClipRecorder::RecordCloser(const gfx::Rect& bounds_in_layer, + Closer closer) { + DCHECK_LT(num_closers_, kMaxOpCount); + closers_[num_closers_] = closer; + bounds_in_layer_[num_closers_++] = bounds_in_layer; +} + +static gfx::Rect PathToEnclosingRect(const gfx::Path& path) { + return gfx::ToEnclosingRect(gfx::SkRectToRectF(path.getBounds())); +} + void ClipRecorder::ClipRect(const gfx::Rect& clip_rect) { gfx::Rect clip_in_layer_space = context_.ToLayerSpaceRect(clip_rect); auto* item = context_.list_->CreateAndAppendItem<cc::ClipDisplayItem>( clip_in_layer_space); item->SetNew(clip_rect, std::vector<SkRRect>()); - DCHECK_LT(num_closers_, arraysize(closers_)); - closers_[num_closers_++] = CLIP_RECT; + RecordCloser(clip_in_layer_space, CLIP_RECT); } void ClipRecorder::ClipPath(const gfx::Path& clip_path) { bool anti_alias = false; - // As a further optimization, consider passing a more granular visual rect. + gfx::Rect clip_in_layer_space = + context_.ToLayerSpaceRect(PathToEnclosingRect(clip_path)); auto* item = context_.list_->CreateAndAppendItem<cc::ClipPathDisplayItem>( - bounds_in_layer_); + clip_in_layer_space); item->SetNew(clip_path, SkRegion::kIntersect_Op, anti_alias); - DCHECK_LT(num_closers_, arraysize(closers_)); - closers_[num_closers_++] = CLIP_PATH; + RecordCloser(clip_in_layer_space, CLIP_PATH); } -void ClipRecorder::ClipPathWithAntiAliasing( - const gfx::Path& clip_path) { +void ClipRecorder::ClipPathWithAntiAliasing(const gfx::Path& clip_path) { bool anti_alias = true; - // As a further optimization, consider passing a more granular visual rect. + gfx::Rect clip_in_layer_space = + context_.ToLayerSpaceRect(PathToEnclosingRect(clip_path)); auto* item = context_.list_->CreateAndAppendItem<cc::ClipPathDisplayItem>( - bounds_in_layer_); + clip_in_layer_space); item->SetNew(clip_path, SkRegion::kIntersect_Op, anti_alias); - DCHECK_LT(num_closers_, arraysize(closers_)); - closers_[num_closers_++] = CLIP_PATH; + RecordCloser(clip_in_layer_space, CLIP_PATH); } } // namespace ui
diff --git a/ui/compositor/clip_recorder.h b/ui/compositor/clip_recorder.h index addd869..e1e4790 100644 --- a/ui/compositor/clip_recorder.h +++ b/ui/compositor/clip_recorder.h
@@ -24,13 +24,11 @@ // A class to provide scoped clips of painting to a DisplayItemList. The clip // provided will be applied to any DisplayItems added to the DisplayItemList -// while this object is alive. In other words, any nested PaintRecorders or -// other ClipRecorders will be clipped. +// while this object is alive. In other words, any nested recorders will be +// clipped. class COMPOSITOR_EXPORT ClipRecorder { public: - // |size_in_layer| is the size in layer space dimensions surrounding - // everything that's visible. - ClipRecorder(const PaintContext& context, const gfx::Size& size_in_layer); + explicit ClipRecorder(const PaintContext& context); ~ClipRecorder(); void ClipRect(const gfx::Rect& clip_rect); @@ -42,12 +40,16 @@ CLIP_RECT, CLIP_PATH, }; + + void RecordCloser(const gfx::Rect& bounds_in_layer, Closer); + const PaintContext& context_; - const gfx::Rect bounds_in_layer_; // If someone needs to do more than this many operations with a single - // ClipRecorder then increase the size of the closers_ array. - Closer closers_[4]; - size_t num_closers_; + // ClipRecorder then we'll increase this. + enum : int { kMaxOpCount = 4 }; + Closer closers_[kMaxOpCount]; + gfx::Rect bounds_in_layer_[kMaxOpCount]; + int num_closers_; DISALLOW_COPY_AND_ASSIGN(ClipRecorder); };
diff --git a/ui/compositor/compositing_recorder.cc b/ui/compositor/compositing_recorder.cc index fca8ad9..f3d49cff 100644 --- a/ui/compositor/compositing_recorder.cc +++ b/ui/compositor/compositing_recorder.cc
@@ -12,10 +12,10 @@ namespace ui { CompositingRecorder::CompositingRecorder(const PaintContext& context, - const gfx::Size& size_in_layer, + const gfx::Size& size_in_context, uint8_t alpha) : context_(context), - bounds_in_layer_(context.ToLayerSpaceBounds(size_in_layer)), + bounds_in_layer_(context.ToLayerSpaceBounds(size_in_context)), saved_(alpha < 255) { if (!saved_) return;
diff --git a/ui/compositor/compositing_recorder.h b/ui/compositor/compositing_recorder.h index 499f424b..e50f692 100644 --- a/ui/compositor/compositing_recorder.h +++ b/ui/compositor/compositing_recorder.h
@@ -25,10 +25,10 @@ class COMPOSITOR_EXPORT CompositingRecorder { public: // |alpha| is a value between 0 and 255, where 0 is transparent and 255 is - // opaque. |size_in_layer| is the size in layer space dimensions surrounding + // opaque. |size_in_context| is the size in the |context|'s space surrounding // everything that's visible. CompositingRecorder(const PaintContext& context, - const gfx::Size& size_in_layer, + const gfx::Size& size_in_context, uint8_t alpha); ~CompositingRecorder();
diff --git a/ui/compositor/paint_cache.cc b/ui/compositor/paint_cache.cc index b4db1ab3b..e9de88d1 100644 --- a/ui/compositor/paint_cache.cc +++ b/ui/compositor/paint_cache.cc
@@ -16,11 +16,11 @@ } bool PaintCache::UseCache(const PaintContext& context, - const gfx::Size& size_in_layer) { + const gfx::Size& size_in_context) { if (!has_cache_) return false; DCHECK(context.list_); - gfx::Rect bounds_in_layer = context.ToLayerSpaceBounds(size_in_layer); + gfx::Rect bounds_in_layer = context.ToLayerSpaceBounds(size_in_context); auto* item = context.list_->CreateAndAppendItem<cc::DrawingDisplayItem>( bounds_in_layer); display_item_.CloneTo(item);
diff --git a/ui/compositor/paint_cache.h b/ui/compositor/paint_cache.h index bb8159a..5161127 100644 --- a/ui/compositor/paint_cache.h +++ b/ui/compositor/paint_cache.h
@@ -24,7 +24,7 @@ // painting output into the PaintContext. If it returns false, the caller // needs to do the work of painting, which can be stored into the PaintCache // to be used next time. - bool UseCache(const PaintContext& context, const gfx::Size& size_in_layer); + bool UseCache(const PaintContext& context, const gfx::Size& size_in_context); private: // Only PaintRecorder can modify these.
diff --git a/ui/compositor/paint_context.cc b/ui/compositor/paint_context.cc index 2966676..f13db93 100644 --- a/ui/compositor/paint_context.cc +++ b/ui/compositor/paint_context.cc
@@ -55,8 +55,8 @@ } gfx::Rect PaintContext::ToLayerSpaceBounds( - const gfx::Size& size_in_layer) const { - return gfx::Rect(size_in_layer) + offset_; + const gfx::Size& size_in_context) const { + return gfx::Rect(size_in_context) + offset_; } gfx::Rect PaintContext::ToLayerSpaceRect(const gfx::Rect& rect) const {
diff --git a/ui/compositor/paint_context.h b/ui/compositor/paint_context.h index 9d42b55..afa1426 100644 --- a/ui/compositor/paint_context.h +++ b/ui/compositor/paint_context.h
@@ -82,7 +82,7 @@ // Returns a rect with the given size in the space of the context's // containing layer. - gfx::Rect ToLayerSpaceBounds(const gfx::Size& size_in_layer) const; + gfx::Rect ToLayerSpaceBounds(const gfx::Size& size_in_context) const; // Returns the given rect translated by the layer space offset. gfx::Rect ToLayerSpaceRect(const gfx::Rect& rect) const;
diff --git a/ui/compositor/transform_recorder.cc b/ui/compositor/transform_recorder.cc index 5eb4038..77448fd 100644 --- a/ui/compositor/transform_recorder.cc +++ b/ui/compositor/transform_recorder.cc
@@ -10,11 +10,8 @@ namespace ui { -TransformRecorder::TransformRecorder(const PaintContext& context, - const gfx::Size& size_in_layer) - : context_(context), - bounds_in_layer_(context.ToLayerSpaceBounds(size_in_layer)), - transformed_(false) {} +TransformRecorder::TransformRecorder(const PaintContext& context) + : context_(context), transformed_(false) {} TransformRecorder::~TransformRecorder() { if (transformed_) @@ -22,8 +19,10 @@ bounds_in_layer_); } -void TransformRecorder::Transform(const gfx::Transform& transform) { +void TransformRecorder::Transform(const gfx::Transform& transform, + const gfx::Size& size_in_context) { DCHECK(!transformed_); + bounds_in_layer_ = context_.ToLayerSpaceBounds(size_in_context); auto* item = context_.list_->CreateAndAppendItem<cc::TransformDisplayItem>( bounds_in_layer_); item->SetNew(transform);
diff --git a/ui/compositor/transform_recorder.h b/ui/compositor/transform_recorder.h index b7c95a83..c02738e8 100644 --- a/ui/compositor/transform_recorder.h +++ b/ui/compositor/transform_recorder.h
@@ -25,20 +25,20 @@ // A class to provide scoped transforms of painting to a DisplayItemList. The // transform provided will be applied to any DisplayItems added to the // DisplayItemList while this object is alive. In other words, any nested -// PaintRecorders or other TransformRecorders will be transformed. +// recorders will be transformed. class COMPOSITOR_EXPORT TransformRecorder { public: - // |size_in_layer| is the size in layer space dimensions surrounding - // everything that's visible. - TransformRecorder(const PaintContext& context, - const gfx::Size& size_in_layer); + explicit TransformRecorder(const PaintContext& context); ~TransformRecorder(); - void Transform(const gfx::Transform& transform); + // |size_in_context| is the size in the paint context's space surrounding + // everything that's visible. + void Transform(const gfx::Transform& transform, + const gfx::Size& size_in_context); private: const PaintContext& context_; - const gfx::Rect bounds_in_layer_; + gfx::Rect bounds_in_layer_; bool transformed_; DISALLOW_COPY_AND_ASSIGN(TransformRecorder);
diff --git a/ui/gfx/render_text.cc b/ui/gfx/render_text.cc index 27c9e5ad..07d0fb3 100644 --- a/ui/gfx/render_text.cc +++ b/ui/gfx/render_text.cc
@@ -93,16 +93,18 @@ return static_cast<SkTypeface::Style>(skia_style); } +int round(float value) { + return static_cast<int>(floor(value + 0.5f)); +} + // Given |font| and |display_width|, returns the width of the fade gradient. int CalculateFadeGradientWidth(const FontList& font_list, int display_width) { - // Fade in/out about 2.5 characters of the beginning/end of the string. - // The .5 here is helpful if one of the characters is a space. - // Use a quarter of the display width if the display width is very short. - const int average_character_width = font_list.GetExpectedTextWidth(1); - const double gradient_width = std::min(average_character_width * 2.5, - display_width / 4.0); - DCHECK_GE(gradient_width, 0.0); - return static_cast<int>(floor(gradient_width + 0.5)); + // Fade in/out about 3 characters of the beginning/end of the string. + // Use a 1/3 of the display width if the display width is very short. + const int narrow_width = font_list.GetExpectedTextWidth(3); + const int gradient_width = std::min(narrow_width, round(display_width / 3.f)); + DCHECK_GE(gradient_width, 0); + return gradient_width; } // Appends to |positions| and |colors| values corresponding to the fade over @@ -130,12 +132,22 @@ // Creates a SkShader to fade the text, with |left_part| specifying the left // fade effect, if any, and |right_part| specifying the right fade effect. -skia::RefPtr<SkShader> CreateFadeShader(const Rect& text_rect, +skia::RefPtr<SkShader> CreateFadeShader(const FontList& font_list, + const Rect& text_rect, const Rect& left_part, const Rect& right_part, SkColor color) { - // Fade alpha of 51/255 corresponds to a fade of 0.2 of the original color. - const SkColor fade_color = SkColorSetA(color, 51); + // In general, fade down to 0 alpha. But when the available width is less + // than four characters, linearly ramp up the fade target alpha to as high as + // 20% at zero width. This allows the user to see the last faded characters a + // little better when there are only a few characters shown. + const float width_fraction = + text_rect.width() / static_cast<float>(font_list.GetExpectedTextWidth(4)); + const SkAlpha kAlphaAtZeroWidth = 51; + const SkAlpha alpha = (width_fraction < 1) ? + static_cast<SkAlpha>(round((1 - width_fraction) * kAlphaAtZeroWidth)) : 0; + const SkColor fade_color = SkColorSetA(color, alpha); + std::vector<SkScalar> positions; std::vector<SkColor> colors; @@ -1209,8 +1221,9 @@ text_rect.Inset(GetAlignmentOffset(0).x(), 0, 0, 0); // TODO(msw): Use the actual text colors corresponding to each faded part. - skia::RefPtr<SkShader> shader = CreateFadeShader( - text_rect, left_part, right_part, colors_.breaks().front().second); + skia::RefPtr<SkShader> shader = + CreateFadeShader(font_list(), text_rect, left_part, right_part, + colors_.breaks().front().second); if (shader) renderer->SetShader(shader.get()); }
diff --git a/ui/gl/BUILD.gn b/ui/gl/BUILD.gn index 33a648d8..dda16eec 100644 --- a/ui/gl/BUILD.gn +++ b/ui/gl/BUILD.gn
@@ -59,6 +59,8 @@ "gl_fence_nv.h", "gl_gl_api_implementation.cc", "gl_gl_api_implementation.h", + "gl_helper.cc", + "gl_helper.h", "gl_image.h", "gl_image_memory.cc", "gl_image_memory.h", @@ -350,6 +352,10 @@ sources += [ "gl_image_ozone_native_pixmap_unittest.cc" ] } + if (is_mac) { + sources += [ "gl_image_io_surface_unittest.cc" ] + } + include_dirs = [ "//third_party/khronos" ] deps = [
diff --git a/ui/gl/generate_bindings.py b/ui/gl/generate_bindings.py index d5019b8b..c1d08a0 100755 --- a/ui/gl/generate_bindings.py +++ b/ui/gl/generate_bindings.py
@@ -79,12 +79,19 @@ 'arguments': 'GLenum target, GLuint index, GLuint buffer, GLintptr offset, ' 'GLsizeiptr size', }, { 'return_type': 'void', - 'names': ['glBindFragDataLocation'], + 'versions': [{ 'name': 'glBindFragDataLocation', + 'extensions': ['GL_ARB_blend_func_extended'] }, + { 'name': 'glBindFragDataLocationEXT', + 'extensions': ['GL_EXT_blend_func_extended'] }], 'arguments': 'GLuint program, GLuint colorNumber, const char* name', }, { 'return_type': 'void', - 'names': ['glBindFragDataLocationIndexed'], + 'versions': [{ 'name': 'glBindFragDataLocationIndexed', + 'extensions': ['GL_ARB_blend_func_extended'] }, + { 'name': 'glBindFragDataLocationIndexedEXT', + 'extensions': ['GL_EXT_blend_func_extended'] }], 'arguments': - 'GLuint program, GLuint colorNumber, GLuint index, const char* name', }, + 'GLuint program, GLuint colorNumber, GLuint index, const char* name', +}, { 'return_type': 'void', 'names': ['glBindFramebufferEXT', 'glBindFramebuffer'], 'arguments': 'GLenum target, GLuint framebuffer', }, @@ -543,6 +550,12 @@ 'names': ['glGetFloatv'], 'arguments': 'GLenum pname, GLfloat* params', }, { 'return_type': 'GLint', + 'versions': [{'name': 'glGetFragDataIndex', + 'extensions': ['GL_ARB_blend_func_extended']}, + {'name': 'glGetFragDataIndexEXT', + 'extensions': ['GL_EXT_blend_func_extended']}], + 'arguments': 'GLuint program, const char* name', }, +{ 'return_type': 'GLint', 'versions': [{ 'name': 'glGetFragDataLocation' }], 'arguments': 'GLuint program, const char* name', }, { 'return_type': 'void',
diff --git a/ui/gl/gl.gyp b/ui/gl/gl.gyp index 04221f1e0..903278e 100644 --- a/ui/gl/gl.gyp +++ b/ui/gl/gl.gyp
@@ -73,6 +73,8 @@ 'gl_fence_nv.h', 'gl_gl_api_implementation.cc', 'gl_gl_api_implementation.h', + 'gl_helper.cc', + 'gl_helper.h', 'gl_image.h', 'gl_image_memory.cc', 'gl_image_memory.h',
diff --git a/ui/gl/gl_bindings.h b/ui/gl/gl_bindings.h index b712d64..911cd9f 100644 --- a/ui/gl/gl_bindings.h +++ b/ui/gl/gl_bindings.h
@@ -135,6 +135,9 @@ // GL_CHROMIUM_ycbcr_422_image #define GL_RGB_YCBCR_422_CHROMIUM 0x78FB +// GL_CHROMIUM_ycbcr_420v_image +#define GL_RGB_YCBCR_420V_CHROMIUM 0x78FC + // GL_CHROMIUM_schedule_overlay_plane #define GL_OVERLAY_TRANSFORM_NONE_CHROMIUM 0x9245 #define GL_OVERLAY_TRANSFORM_FLIP_HORIZONTAL_CHROMIUM 0x9246 @@ -331,6 +334,16 @@ #define GL_FRAGMENT_INPUT_NV 0x936D #endif +#ifndef GL_EXT_blend_func_extended +#define GL_EXT_blend_func_extended 1 +#define GL_SRC_ALPHA_SATURATE_EXT 0x0308 +#define GL_SRC1_ALPHA_EXT 0x8589 // OpenGL 1.5 token value +#define GL_SRC1_COLOR_EXT 0x88F9 +#define GL_ONE_MINUS_SRC1_COLOR_EXT 0x88FA +#define GL_ONE_MINUS_SRC1_ALPHA_EXT 0x88FB +#define GL_MAX_DUAL_SOURCE_DRAW_BUFFERS_EXT 0x88FC +#endif /* GL_EXT_blend_func_extended */ + #define GL_GLEXT_PROTOTYPES 1 #if defined(OS_WIN)
diff --git a/ui/gl/gl_bindings_api_autogen_gl.h b/ui/gl/gl_bindings_api_autogen_gl.h index 4d86720..93039f6 100644 --- a/ui/gl/gl_bindings_api_autogen_gl.h +++ b/ui/gl/gl_bindings_api_autogen_gl.h
@@ -344,6 +344,7 @@ GLenum glGetErrorFn(void) override; void glGetFenceivNVFn(GLuint fence, GLenum pname, GLint* params) override; void glGetFloatvFn(GLenum pname, GLfloat* params) override; +GLint glGetFragDataIndexFn(GLuint program, const char* name) override; GLint glGetFragDataLocationFn(GLuint program, const char* name) override; void glGetFramebufferAttachmentParameterivEXTFn(GLenum target, GLenum attachment,
diff --git a/ui/gl/gl_bindings_autogen_gl.cc b/ui/gl/gl_bindings_autogen_gl.cc index e7482d7d..eabd4ae9 100644 --- a/ui/gl/gl_bindings_autogen_gl.cc +++ b/ui/gl/gl_bindings_autogen_gl.cc
@@ -202,6 +202,7 @@ fn.glGetFenceivNVFn = 0; fn.glGetFloatvFn = reinterpret_cast<glGetFloatvProc>(GetGLProcAddress("glGetFloatv")); + fn.glGetFragDataIndexFn = 0; fn.glGetFragDataLocationFn = 0; fn.glGetFramebufferAttachmentParameterivEXTFn = 0; fn.glGetGraphicsResetStatusARBFn = 0; @@ -481,6 +482,8 @@ extensions.find("GL_APPLE_fence ") != std::string::npos; ext.b_GL_APPLE_vertex_array_object = extensions.find("GL_APPLE_vertex_array_object ") != std::string::npos; + ext.b_GL_ARB_blend_func_extended = + extensions.find("GL_ARB_blend_func_extended ") != std::string::npos; ext.b_GL_ARB_draw_buffers = extensions.find("GL_ARB_draw_buffers ") != std::string::npos; ext.b_GL_ARB_draw_instanced = @@ -509,6 +512,8 @@ std::string::npos; ext.b_GL_CHROMIUM_glgetstringi_hack = extensions.find("GL_CHROMIUM_glgetstringi_hack ") != std::string::npos; + ext.b_GL_EXT_blend_func_extended = + extensions.find("GL_EXT_blend_func_extended ") != std::string::npos; ext.b_GL_EXT_debug_marker = extensions.find("GL_EXT_debug_marker ") != std::string::npos; ext.b_GL_EXT_direct_state_access = @@ -525,6 +530,8 @@ extensions.find("GL_EXT_framebuffer_multisample ") != std::string::npos; ext.b_GL_EXT_framebuffer_object = extensions.find("GL_EXT_framebuffer_object ") != std::string::npos; + ext.b_GL_EXT_gpu_shader4 = + extensions.find("GL_EXT_gpu_shader4 ") != std::string::npos; ext.b_GL_EXT_map_buffer_range = extensions.find("GL_EXT_map_buffer_range ") != std::string::npos; ext.b_GL_EXT_multisampled_render_to_texture = @@ -601,16 +608,23 @@ } debug_fn.glBindFragDataLocationFn = 0; - if (ver->IsAtLeastGL(3u, 0u)) { + if (ver->IsAtLeastGL(3u, 0u) || ext.b_GL_ARB_blend_func_extended) { fn.glBindFragDataLocationFn = reinterpret_cast<glBindFragDataLocationProc>( GetGLProcAddress("glBindFragDataLocation")); + } else if (ext.b_GL_EXT_gpu_shader4 || ext.b_GL_EXT_blend_func_extended) { + fn.glBindFragDataLocationFn = reinterpret_cast<glBindFragDataLocationProc>( + GetGLProcAddress("glBindFragDataLocationEXT")); } debug_fn.glBindFragDataLocationIndexedFn = 0; - if (ver->IsAtLeastGL(3u, 3u)) { + if (ver->IsAtLeastGL(3u, 3u) || ext.b_GL_ARB_blend_func_extended) { fn.glBindFragDataLocationIndexedFn = reinterpret_cast<glBindFragDataLocationIndexedProc>( GetGLProcAddress("glBindFragDataLocationIndexed")); + } else if (ext.b_GL_EXT_blend_func_extended) { + fn.glBindFragDataLocationIndexedFn = + reinterpret_cast<glBindFragDataLocationIndexedProc>( + GetGLProcAddress("glBindFragDataLocationIndexedEXT")); } debug_fn.glBindFramebufferEXTFn = 0; @@ -1157,6 +1171,15 @@ GetGLProcAddress("glGetFenceivNV")); } + debug_fn.glGetFragDataIndexFn = 0; + if (ver->IsAtLeastGL(3u, 3u) || ext.b_GL_ARB_blend_func_extended) { + fn.glGetFragDataIndexFn = reinterpret_cast<glGetFragDataIndexProc>( + GetGLProcAddress("glGetFragDataIndex")); + } else if (ext.b_GL_EXT_blend_func_extended) { + fn.glGetFragDataIndexFn = reinterpret_cast<glGetFragDataIndexProc>( + GetGLProcAddress("glGetFragDataIndexEXT")); + } + debug_fn.glGetFragDataLocationFn = 0; if (ver->IsAtLeastGL(3u, 0u) || ver->IsAtLeastGLES(3u, 0u)) { fn.glGetFragDataLocationFn = reinterpret_cast<glGetFragDataLocationProc>( @@ -3188,6 +3211,15 @@ g_driver_gl.debug_fn.glGetFloatvFn(pname, params); } +static GLint GL_BINDING_CALL Debug_glGetFragDataIndex(GLuint program, + const char* name) { + GL_SERVICE_LOG("glGetFragDataIndex" + << "(" << program << ", " << name << ")"); + GLint result = g_driver_gl.debug_fn.glGetFragDataIndexFn(program, name); + GL_SERVICE_LOG("GL_RESULT: " << result); + return result; +} + static GLint GL_BINDING_CALL Debug_glGetFragDataLocation(GLuint program, const char* name) { GL_SERVICE_LOG("glGetFragDataLocation" @@ -5591,6 +5623,10 @@ debug_fn.glGetFloatvFn = fn.glGetFloatvFn; fn.glGetFloatvFn = Debug_glGetFloatv; } + if (!debug_fn.glGetFragDataIndexFn) { + debug_fn.glGetFragDataIndexFn = fn.glGetFragDataIndexFn; + fn.glGetFragDataIndexFn = Debug_glGetFragDataIndex; + } if (!debug_fn.glGetFragDataLocationFn) { debug_fn.glGetFragDataLocationFn = fn.glGetFragDataLocationFn; fn.glGetFragDataLocationFn = Debug_glGetFragDataLocation; @@ -7103,6 +7139,10 @@ driver_->fn.glGetFloatvFn(pname, params); } +GLint GLApiBase::glGetFragDataIndexFn(GLuint program, const char* name) { + return driver_->fn.glGetFragDataIndexFn(program, name); +} + GLint GLApiBase::glGetFragDataLocationFn(GLuint program, const char* name) { return driver_->fn.glGetFragDataLocationFn(program, name); } @@ -9104,6 +9144,11 @@ gl_api_->glGetFloatvFn(pname, params); } +GLint TraceGLApi::glGetFragDataIndexFn(GLuint program, const char* name) { + TRACE_EVENT_BINARY_EFFICIENT0("gpu", "TraceGLAPI::glGetFragDataIndex") + return gl_api_->glGetFragDataIndexFn(program, name); +} + GLint TraceGLApi::glGetFragDataLocationFn(GLuint program, const char* name) { TRACE_EVENT_BINARY_EFFICIENT0("gpu", "TraceGLAPI::glGetFragDataLocation") return gl_api_->glGetFragDataLocationFn(program, name); @@ -11415,6 +11460,14 @@ LOG(ERROR) << "Trying to call glGetFloatv() without current GL context"; } +GLint NoContextGLApi::glGetFragDataIndexFn(GLuint program, const char* name) { + NOTREACHED() + << "Trying to call glGetFragDataIndex() without current GL context"; + LOG(ERROR) + << "Trying to call glGetFragDataIndex() without current GL context"; + return 0; +} + GLint NoContextGLApi::glGetFragDataLocationFn(GLuint program, const char* name) { NOTREACHED()
diff --git a/ui/gl/gl_bindings_autogen_gl.h b/ui/gl/gl_bindings_autogen_gl.h index 457c5e4..c568d21 100644 --- a/ui/gl/gl_bindings_autogen_gl.h +++ b/ui/gl/gl_bindings_autogen_gl.h
@@ -401,6 +401,8 @@ GLenum pname, GLint* params); typedef void(GL_BINDING_CALL* glGetFloatvProc)(GLenum pname, GLfloat* params); +typedef GLint(GL_BINDING_CALL* glGetFragDataIndexProc)(GLuint program, + const char* name); typedef GLint(GL_BINDING_CALL* glGetFragDataLocationProc)(GLuint program, const char* name); typedef void(GL_BINDING_CALL* glGetFramebufferAttachmentParameterivEXTProc)( @@ -1031,6 +1033,7 @@ bool b_GL_ANGLE_translated_shader_source; bool b_GL_APPLE_fence; bool b_GL_APPLE_vertex_array_object; + bool b_GL_ARB_blend_func_extended; bool b_GL_ARB_draw_buffers; bool b_GL_ARB_draw_instanced; bool b_GL_ARB_get_program_binary; @@ -1045,6 +1048,7 @@ bool b_GL_ARB_vertex_array_object; bool b_GL_CHROMIUM_gles_depth_binding_hack; bool b_GL_CHROMIUM_glgetstringi_hack; + bool b_GL_EXT_blend_func_extended; bool b_GL_EXT_debug_marker; bool b_GL_EXT_direct_state_access; bool b_GL_EXT_discard_framebuffer; @@ -1053,6 +1057,7 @@ bool b_GL_EXT_framebuffer_blit; bool b_GL_EXT_framebuffer_multisample; bool b_GL_EXT_framebuffer_object; + bool b_GL_EXT_gpu_shader4; bool b_GL_EXT_map_buffer_range; bool b_GL_EXT_multisampled_render_to_texture; bool b_GL_EXT_occlusion_query_boolean; @@ -1204,6 +1209,7 @@ glGetErrorProc glGetErrorFn; glGetFenceivNVProc glGetFenceivNVFn; glGetFloatvProc glGetFloatvFn; + glGetFragDataIndexProc glGetFragDataIndexFn; glGetFragDataLocationProc glGetFragDataLocationFn; glGetFramebufferAttachmentParameterivEXTProc glGetFramebufferAttachmentParameterivEXTFn; @@ -1740,6 +1746,7 @@ virtual GLenum glGetErrorFn(void) = 0; virtual void glGetFenceivNVFn(GLuint fence, GLenum pname, GLint* params) = 0; virtual void glGetFloatvFn(GLenum pname, GLfloat* params) = 0; + virtual GLint glGetFragDataIndexFn(GLuint program, const char* name) = 0; virtual GLint glGetFragDataLocationFn(GLuint program, const char* name) = 0; virtual void glGetFramebufferAttachmentParameterivEXTFn(GLenum target, GLenum attachment, @@ -2459,6 +2466,7 @@ #define glGetError ::gfx::g_current_gl_context->glGetErrorFn #define glGetFenceivNV ::gfx::g_current_gl_context->glGetFenceivNVFn #define glGetFloatv ::gfx::g_current_gl_context->glGetFloatvFn +#define glGetFragDataIndex ::gfx::g_current_gl_context->glGetFragDataIndexFn #define glGetFragDataLocation \ ::gfx::g_current_gl_context->glGetFragDataLocationFn #define glGetFramebufferAttachmentParameterivEXT \
diff --git a/ui/gl/gl_bindings_autogen_mock.cc b/ui/gl/gl_bindings_autogen_mock.cc index b356561..43baa49 100644 --- a/ui/gl/gl_bindings_autogen_mock.cc +++ b/ui/gl/gl_bindings_autogen_mock.cc
@@ -101,6 +101,14 @@ } void GL_BINDING_CALL +MockGLInterface::Mock_glBindFragDataLocationEXT(GLuint program, + GLuint colorNumber, + const char* name) { + MakeFunctionUnique("glBindFragDataLocationEXT"); + interface_->BindFragDataLocation(program, colorNumber, name); +} + +void GL_BINDING_CALL MockGLInterface::Mock_glBindFragDataLocationIndexed(GLuint program, GLuint colorNumber, GLuint index, @@ -110,6 +118,15 @@ } void GL_BINDING_CALL +MockGLInterface::Mock_glBindFragDataLocationIndexedEXT(GLuint program, + GLuint colorNumber, + GLuint index, + const char* name) { + MakeFunctionUnique("glBindFragDataLocationIndexedEXT"); + interface_->BindFragDataLocationIndexed(program, colorNumber, index, name); +} + +void GL_BINDING_CALL MockGLInterface::Mock_glBindFramebuffer(GLenum target, GLuint framebuffer) { MakeFunctionUnique("glBindFramebuffer"); interface_->BindFramebufferEXT(target, framebuffer); @@ -1188,6 +1205,18 @@ } GLint GL_BINDING_CALL +MockGLInterface::Mock_glGetFragDataIndex(GLuint program, const char* name) { + MakeFunctionUnique("glGetFragDataIndex"); + return interface_->GetFragDataIndex(program, name); +} + +GLint GL_BINDING_CALL +MockGLInterface::Mock_glGetFragDataIndexEXT(GLuint program, const char* name) { + MakeFunctionUnique("glGetFragDataIndexEXT"); + return interface_->GetFragDataIndex(program, name); +} + +GLint GL_BINDING_CALL MockGLInterface::Mock_glGetFragDataLocation(GLuint program, const char* name) { MakeFunctionUnique("glGetFragDataLocation"); return interface_->GetFragDataLocation(program, name); @@ -2857,8 +2886,12 @@ return reinterpret_cast<void*>(Mock_glBindBufferRange); if (strcmp(name, "glBindFragDataLocation") == 0) return reinterpret_cast<void*>(Mock_glBindFragDataLocation); + if (strcmp(name, "glBindFragDataLocationEXT") == 0) + return reinterpret_cast<void*>(Mock_glBindFragDataLocationEXT); if (strcmp(name, "glBindFragDataLocationIndexed") == 0) return reinterpret_cast<void*>(Mock_glBindFragDataLocationIndexed); + if (strcmp(name, "glBindFragDataLocationIndexedEXT") == 0) + return reinterpret_cast<void*>(Mock_glBindFragDataLocationIndexedEXT); if (strcmp(name, "glBindFramebuffer") == 0) return reinterpret_cast<void*>(Mock_glBindFramebuffer); if (strcmp(name, "glBindFramebufferEXT") == 0) @@ -3149,6 +3182,10 @@ return reinterpret_cast<void*>(Mock_glGetFenceivNV); if (strcmp(name, "glGetFloatv") == 0) return reinterpret_cast<void*>(Mock_glGetFloatv); + if (strcmp(name, "glGetFragDataIndex") == 0) + return reinterpret_cast<void*>(Mock_glGetFragDataIndex); + if (strcmp(name, "glGetFragDataIndexEXT") == 0) + return reinterpret_cast<void*>(Mock_glGetFragDataIndexEXT); if (strcmp(name, "glGetFragDataLocation") == 0) return reinterpret_cast<void*>(Mock_glGetFragDataLocation); if (strcmp(name, "glGetFramebufferAttachmentParameteriv") == 0)
diff --git a/ui/gl/gl_bindings_autogen_mock.h b/ui/gl/gl_bindings_autogen_mock.h index f97521e..52d4034 100644 --- a/ui/gl/gl_bindings_autogen_mock.h +++ b/ui/gl/gl_bindings_autogen_mock.h
@@ -30,11 +30,19 @@ static void GL_BINDING_CALL Mock_glBindFragDataLocation(GLuint program, GLuint colorNumber, const char* name); +static void GL_BINDING_CALL Mock_glBindFragDataLocationEXT(GLuint program, + GLuint colorNumber, + const char* name); static void GL_BINDING_CALL Mock_glBindFragDataLocationIndexed(GLuint program, GLuint colorNumber, GLuint index, const char* name); +static void GL_BINDING_CALL +Mock_glBindFragDataLocationIndexedEXT(GLuint program, + GLuint colorNumber, + GLuint index, + const char* name); static void GL_BINDING_CALL Mock_glBindFramebuffer(GLenum target, GLuint framebuffer); static void GL_BINDING_CALL Mock_glBindFramebufferEXT(GLenum target, @@ -447,6 +455,10 @@ GLenum pname, GLint* params); static void GL_BINDING_CALL Mock_glGetFloatv(GLenum pname, GLfloat* params); +static GLint GL_BINDING_CALL Mock_glGetFragDataIndex(GLuint program, + const char* name); +static GLint GL_BINDING_CALL Mock_glGetFragDataIndexEXT(GLuint program, + const char* name); static GLint GL_BINDING_CALL Mock_glGetFragDataLocation(GLuint program, const char* name); static void GL_BINDING_CALL
diff --git a/ui/gl/gl_enums_implementation_autogen.h b/ui/gl/gl_enums_implementation_autogen.h index a4812cb..a7e984a 100644 --- a/ui/gl/gl_enums_implementation_autogen.h +++ b/ui/gl/gl_enums_implementation_autogen.h
@@ -649,9 +649,18 @@ 0x8B6A, "GL_FLOAT_MAT4x3_NV", }, { + 0x88FA, "GL_ONE_MINUS_SRC1_COLOR_EXT", + }, + { 0x93D0, "GL_COMPRESSED_SRGB8_ALPHA8_ASTC_4x4_KHR", }, { + 0x88FC, "GL_MAX_DUAL_SOURCE_DRAW_BUFFERS_EXT", + }, + { + 0x78FC, "GL_RGB_YCBCR_420V_CHROMIUM", + }, + { 0x9143, "GL_MAX_DEBUG_MESSAGE_LENGTH_KHR", }, { @@ -829,6 +838,9 @@ 0x83F0, "GL_COMPRESSED_RGB_S3TC_DXT1_EXT", }, { + 0x88F9, "GL_SRC1_COLOR_EXT", + }, + { 0x8D6A, "GL_ANY_SAMPLES_PASSED_CONSERVATIVE_EXT", }, { @@ -2119,6 +2131,9 @@ 0x8519, "GL_TEXTURE_CUBE_MAP_POSITIVE_Z", }, { + 0x88FB, "GL_ONE_MINUS_SRC1_ALPHA_EXT", + }, + { 0x8514, "GL_TEXTURE_BINDING_CUBE_MAP", }, { @@ -2923,6 +2938,9 @@ 0x8C85, "GL_TRANSFORM_FEEDBACK_BUFFER_SIZE", }, { + 0x8589, "GL_SRC1_ALPHA_EXT", + }, + { 0x00008000, "GL_COVERAGE_BUFFER_BIT_NV", }, {
diff --git a/ui/gl/gl_helper.cc b/ui/gl/gl_helper.cc new file mode 100644 index 0000000..afaebad --- /dev/null +++ b/ui/gl/gl_helper.cc
@@ -0,0 +1,97 @@ +// 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. + +#include "ui/gl/gl_helper.h" + +#include <string> + +#include "base/logging.h" +#include "ui/gl/scoped_binders.h" + +namespace gfx { + +// static +GLuint GLHelper::CompileShader(GLenum type, const char* src) { + GLuint shader = glCreateShader(type); + // Load the shader source. + glShaderSource(shader, 1, &src, nullptr); + // Compile the shader. + glCompileShader(shader); + return shader; +} + +// static +GLuint GLHelper::LoadShader(GLenum type, const char* src) { + GLuint shader = CompileShader(type, src); + + // Check the compile status. + GLint value = 0; + glGetShaderiv(shader, GL_COMPILE_STATUS, &value); + if (!value) { + char buffer[1024]; + GLsizei length = 0; + glGetShaderInfoLog(shader, sizeof(buffer), &length, buffer); + std::string log(buffer, length); + DCHECK_EQ(1, value) << "Error compiling shader: " << log; + glDeleteShader(shader); + shader = 0; + } + return shader; +} + +// static +GLuint GLHelper::LinkProgram(GLuint vertex_shader, GLuint fragment_shader) { + // Create the program object. + GLuint program = glCreateProgram(); + glAttachShader(program, vertex_shader); + glAttachShader(program, fragment_shader); + // Link the program. + glLinkProgram(program); + return program; +} + +// static +GLuint GLHelper::SetupProgram(GLuint vertex_shader, GLuint fragment_shader) { + GLuint program = LinkProgram(vertex_shader, fragment_shader); + // Check the link status. + GLint linked = 0; + glGetProgramiv(program, GL_LINK_STATUS, &linked); + if (!linked) { + char buffer[1024]; + GLsizei length = 0; + glGetProgramInfoLog(program, sizeof(buffer), &length, buffer); + std::string log(buffer, length); + DCHECK_EQ(1, linked) << "Error linking program: " << log; + glDeleteProgram(program); + program = 0; + } + return program; +} + +// static +GLuint GLHelper::SetupQuadVertexBuffer() { + GLuint vertex_buffer = 0; + glGenBuffersARB(1, &vertex_buffer); + gfx::ScopedBufferBinder buffer_binder(GL_ARRAY_BUFFER, vertex_buffer); + GLfloat data[] = {-1.f, -1.f, 1.f, -1.f, -1.f, 1.f, 1.f, 1.f}; + glBufferData(GL_ARRAY_BUFFER, sizeof(data), data, GL_STATIC_DRAW); + return vertex_buffer; +} + +// static +void GLHelper::DrawQuad(GLuint vertex_buffer) { + gfx::ScopedBufferBinder buffer_binder(GL_ARRAY_BUFFER, vertex_buffer); + gfx::ScopedVertexAttribArray vertex_attrib_array(0, 2, GL_FLOAT, GL_FALSE, + sizeof(GLfloat) * 2, 0); + gfx::ScopedCapability disable_blending(GL_BLEND, GL_FALSE); + gfx::ScopedCapability disable_culling(GL_CULL_FACE, GL_FALSE); + gfx::ScopedCapability disable_dithering(GL_DITHER, GL_FALSE); + gfx::ScopedCapability disable_depth_test(GL_DEPTH_TEST, GL_FALSE); + gfx::ScopedCapability disable_scissor_test(GL_SCISSOR_TEST, GL_FALSE); + gfx::ScopedColorMask color_mask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE); + + glDrawArrays(GL_TRIANGLE_STRIP, 0, 4); +} + +} // namespace gfx
diff --git a/ui/gl/gl_helper.h b/ui/gl/gl_helper.h new file mode 100644 index 0000000..e38ecf1a --- /dev/null +++ b/ui/gl/gl_helper.h
@@ -0,0 +1,42 @@ +// 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. + +#ifndef UI_GL_GL_HELPER_H_ +#define UI_GL_GL_HELPER_H_ + +#include "base/basictypes.h" +#include "ui/gl/gl_bindings.h" +#include "ui/gl/gl_export.h" + +namespace gfx { + +class GL_EXPORT GLHelper { + public: + // Compiles a shader. + // Does not check for errors, always returns shader. + static GLuint CompileShader(GLenum type, const char* src); + + // Compiles a shader and checks for compilation errors. + // Returns shader, 0 on failure. + static GLuint LoadShader(GLenum type, const char* src); + + // Attaches 2 shaders and links them to a program. + // Does not check for errors, always returns program. + static GLuint LinkProgram(GLuint vertex_shader, GLuint fragment_shader); + + // Attaches 2 shaders, links them to a program, and checks for errors. + // Returns program, 0 on failure. + static GLuint SetupProgram(GLuint vertex_shader, GLuint fragment_shader); + + // Sets up a vertex buffer containing 4 vertices that can be used to draw + // a quad as a tri-strip. + static GLuint SetupQuadVertexBuffer(); + + // Draws a quad to the currently bound frame buffer. + static void DrawQuad(GLuint vertex_buffer); +}; + +} // namespace gfx + +#endif // UI_GL_GL_HELPER_H_
diff --git a/ui/gl/gl_image_io_surface.h b/ui/gl/gl_image_io_surface.h index 186f5a9..623ad21b 100644 --- a/ui/gl/gl_image_io_surface.h +++ b/ui/gl/gl_image_io_surface.h
@@ -53,6 +53,8 @@ static void SetLayerForWidget(gfx::AcceleratedWidget widget, CALayer* layer); + static unsigned GetInternalFormatForTesting(gfx::BufferFormat format); + protected: ~GLImageIOSurface() override; @@ -64,6 +66,15 @@ gfx::GenericSharedMemoryId io_surface_id_; base::ThreadChecker thread_checker_; + // GL state to support 420v IOSurface conversion to RGB. + unsigned framebuffer_ = 0; + unsigned vertex_shader_ = 0; + unsigned fragment_shader_ = 0; + unsigned program_ = 0; + int size_location_ = -1; + unsigned vertex_buffer_ = 0; + unsigned yuv_textures_[2] = {}; + DISALLOW_COPY_AND_ASSIGN(GLImageIOSurface); };
diff --git a/ui/gl/gl_image_io_surface.mm b/ui/gl/gl_image_io_surface.mm index dfd8df9..dc03cd7b 100644 --- a/ui/gl/gl_image_io_surface.mm +++ b/ui/gl/gl_image_io_surface.mm
@@ -8,11 +8,14 @@ #include "base/lazy_instance.h" #include "base/mac/foundation_util.h" +#include "base/strings/stringize_macros.h" #include "base/trace_event/memory_allocator_dump.h" #include "base/trace_event/memory_dump_manager.h" #include "base/trace_event/process_memory_dump.h" #include "ui/gl/gl_bindings.h" #include "ui/gl/gl_context.h" +#include "ui/gl/gl_helper.h" +#include "ui/gl/scoped_binders.h" // Note that this must be included after gl_bindings.h to avoid conflicts. #include <OpenGL/CGLIOSurface.h> @@ -26,11 +29,42 @@ using WidgetToLayerMap = std::map<gfx::AcceleratedWidget, CALayer*>; base::LazyInstance<WidgetToLayerMap> g_widget_to_layer_map; +// clang-format off +const char kVertexShader[] = +STRINGIZE( + attribute vec2 a_position; + uniform vec2 a_texScale; + varying vec2 v_texCoord; + void main() { + gl_Position = vec4(a_position.x, a_position.y, 0.0, 1.0); + v_texCoord = (a_position + vec2(1.0, 1.0)) * 0.5 * a_texScale; + } +); + +const char kFragmentShader[] = +STRINGIZE( + uniform sampler2DRect a_y_texture; + uniform sampler2DRect a_uv_texture; + varying vec2 v_texCoord; + void main() { + vec3 yuv_adj = vec3(-0.0625, -0.5, -0.5); + mat3 yuv_matrix = mat3(vec3(1.164, 1.164, 1.164), + vec3(0.0, -.391, 2.018), + vec3(1.596, -.813, 0.0)); + vec3 yuv = vec3( + texture2DRect(a_y_texture, v_texCoord).r, + texture2DRect(a_uv_texture, v_texCoord * 0.5).rg); + gl_FragColor = vec4(yuv_matrix * (yuv + yuv_adj), 1.0); + } +); +// clang-format on + bool ValidInternalFormat(unsigned internalformat) { switch (internalformat) { case GL_RED: case GL_BGRA_EXT: case GL_RGB: + case GL_RGB_YCBCR_420V_CHROMIUM: case GL_RGB_YCBCR_422_CHROMIUM: case GL_RGBA: return true; @@ -66,13 +100,14 @@ GLenum TextureFormat(BufferFormat format) { switch (format) { case BufferFormat::R_8: - case BufferFormat::YUV_420_BIPLANAR: return GL_RED; case BufferFormat::BGRA_8888: case BufferFormat::RGBA_8888: return GL_RGBA; case BufferFormat::UYVY_422: return GL_RGB; + case BufferFormat::YUV_420_BIPLANAR: + return GL_RGB_YCBCR_420V_CHROMIUM; case BufferFormat::ATC: case BufferFormat::ATCIA: case BufferFormat::DXT1: @@ -93,14 +128,12 @@ GLenum DataFormat(BufferFormat format) { switch (format) { case BufferFormat::R_8: - case BufferFormat::YUV_420_BIPLANAR: return GL_RED; case BufferFormat::BGRA_8888: case BufferFormat::RGBA_8888: return GL_BGRA; case BufferFormat::UYVY_422: return GL_YCBCR_422_APPLE; - break; case BufferFormat::ATC: case BufferFormat::ATCIA: case BufferFormat::DXT1: @@ -110,6 +143,7 @@ case BufferFormat::RGBX_8888: case BufferFormat::BGRX_8888: case BufferFormat::YUV_420: + case BufferFormat::YUV_420_BIPLANAR: NOTREACHED(); return 0; } @@ -121,7 +155,6 @@ GLenum DataType(BufferFormat format) { switch (format) { case BufferFormat::R_8: - case BufferFormat::YUV_420_BIPLANAR: return GL_UNSIGNED_BYTE; case BufferFormat::BGRA_8888: case BufferFormat::RGBA_8888: @@ -138,6 +171,7 @@ case BufferFormat::RGBX_8888: case BufferFormat::BGRX_8888: case BufferFormat::YUV_420: + case BufferFormat::YUV_420_BIPLANAR: NOTREACHED(); return 0; } @@ -183,6 +217,14 @@ void GLImageIOSurface::Destroy(bool have_context) { DCHECK(thread_checker_.CalledOnValidThread()); + if (have_context && framebuffer_) { + glDeleteProgram(program_); + glDeleteShader(vertex_shader_); + glDeleteShader(fragment_shader_); + glDeleteBuffersARB(1, &vertex_buffer_); + glDeleteFramebuffersEXT(1, &framebuffer_); + glDeleteTextures(2, yuv_textures_); + } io_surface_.reset(); } @@ -190,10 +232,19 @@ return size_; } -unsigned GLImageIOSurface::GetInternalFormat() { return internalformat_; } +unsigned GLImageIOSurface::GetInternalFormat() { + return internalformat_; +} bool GLImageIOSurface::BindTexImage(unsigned target) { DCHECK(thread_checker_.CalledOnValidThread()); + + // YUV_420_BIPLANAR is not supported by BindTexImage. + // CopyTexImage is supported by this format as that performs conversion to RGB + // as part of the copy operation. + if (format_ == BufferFormat::YUV_420_BIPLANAR) + return false; + if (target != GL_TEXTURE_RECTANGLE_ARB) { // This might be supported in the future. For now, perform strict // validation so we know what's going on. @@ -218,7 +269,96 @@ } bool GLImageIOSurface::CopyTexImage(unsigned target) { - return false; + DCHECK(thread_checker_.CalledOnValidThread()); + + if (format_ != BufferFormat::YUV_420_BIPLANAR) + return false; + + if (target != GL_TEXTURE_2D) { + LOG(ERROR) << "YUV_420_BIPLANAR requires TEXTURE_2D target"; + return false; + } + + if (!framebuffer_) { + glGenFramebuffersEXT(1, &framebuffer_); + vertex_buffer_ = gfx::GLHelper::SetupQuadVertexBuffer(); + vertex_shader_ = gfx::GLHelper::LoadShader(GL_VERTEX_SHADER, kVertexShader); + fragment_shader_ = + gfx::GLHelper::LoadShader(GL_FRAGMENT_SHADER, kFragmentShader); + program_ = gfx::GLHelper::SetupProgram(vertex_shader_, fragment_shader_); + gfx::ScopedUseProgram use_program(program_); + + size_location_ = glGetUniformLocation(program_, "a_texScale"); + DCHECK_NE(-1, size_location_); + int y_sampler_location = glGetUniformLocation(program_, "a_y_texture"); + DCHECK_NE(-1, y_sampler_location); + int uv_sampler_location = glGetUniformLocation(program_, "a_uv_texture"); + DCHECK_NE(-1, uv_sampler_location); + + glUniform1i(y_sampler_location, 0); + glUniform1i(uv_sampler_location, 1); + + glGenTextures(2, yuv_textures_); + DCHECK(yuv_textures_[0]); + DCHECK(yuv_textures_[1]); + } + + CGLContextObj cgl_context = + static_cast<CGLContextObj>(gfx::GLContext::GetCurrent()->GetHandle()); + + GLint target_texture = 0; + glGetIntegerv(GL_TEXTURE_BINDING_2D, &target_texture); + DCHECK(target_texture); + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, size_.width(), size_.height(), 0, + GL_RGB, GL_UNSIGNED_BYTE, nullptr); + + CGLError cgl_error = kCGLNoError; + { + DCHECK(io_surface_); + + gfx::ScopedActiveTexture active_texture0(GL_TEXTURE0); + gfx::ScopedTextureBinder texture_y_binder(GL_TEXTURE_RECTANGLE_ARB, + yuv_textures_[0]); + cgl_error = CGLTexImageIOSurface2D( + cgl_context, GL_TEXTURE_RECTANGLE_ARB, GL_RED, size_.width(), + size_.height(), GL_RED, GL_UNSIGNED_BYTE, io_surface_.get(), 0); + if (cgl_error != kCGLNoError) { + LOG(ERROR) << "Error in CGLTexImageIOSurface2D for the Y plane. " + << cgl_error; + return false; + } + { + gfx::ScopedActiveTexture active_texture1(GL_TEXTURE1); + gfx::ScopedTextureBinder texture_uv_binder(GL_TEXTURE_RECTANGLE_ARB, + yuv_textures_[1]); + cgl_error = CGLTexImageIOSurface2D( + cgl_context, GL_TEXTURE_RECTANGLE_ARB, GL_RG, size_.width() / 2, + size_.height() / 2, GL_RG, GL_UNSIGNED_BYTE, io_surface_.get(), 1); + if (cgl_error != kCGLNoError) { + LOG(ERROR) << "Error in CGLTexImageIOSurface2D for the UV plane. " + << cgl_error; + return false; + } + + gfx::ScopedFrameBufferBinder framebuffer_binder(framebuffer_); + gfx::ScopedViewport viewport(0, 0, size_.width(), size_.height()); + glViewport(0, 0, size_.width(), size_.height()); + glFramebufferTexture2DEXT(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, + GL_TEXTURE_2D, target_texture, 0); + DCHECK_EQ(static_cast<GLenum>(GL_FRAMEBUFFER_COMPLETE), + glCheckFramebufferStatusEXT(GL_FRAMEBUFFER)); + + gfx::ScopedUseProgram use_program(program_); + glUniform2f(size_location_, size_.width(), size_.height()); + + gfx::GLHelper::DrawQuad(vertex_buffer_); + + // Detach the output texture from the fbo. + glFramebufferTexture2DEXT(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, + GL_TEXTURE_2D, 0, 0); + } + } + return true; } bool GLImageIOSurface::CopyTexSubImage(unsigned target, @@ -268,4 +408,10 @@ g_widget_to_layer_map.Pointer()->erase(widget); } -} // namespace gfx +// static +unsigned GLImageIOSurface::GetInternalFormatForTesting( + gfx::BufferFormat format) { + DCHECK(ValidFormat(format)); + return TextureFormat(format); +} +} // namespace gl
diff --git a/ui/gl/gl_image_io_surface_unittest.cc b/ui/gl/gl_image_io_surface_unittest.cc new file mode 100644 index 0000000..c9ca715b --- /dev/null +++ b/ui/gl/gl_image_io_surface_unittest.cc
@@ -0,0 +1,56 @@ +// 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. + +#include "testing/gtest/include/gtest/gtest.h" +#include "ui/gfx/buffer_format_util.h" +#include "ui/gfx/mac/io_surface_manager.h" +#include "ui/gl/gl_image_io_surface.h" +#include "ui/gl/test/gl_image_test_template.h" + +namespace gl { +namespace { + +template <gfx::BufferFormat format> +class GLImageIOSurfaceTestDelegate { + public: + scoped_refptr<GLImage> CreateSolidColorImage(const gfx::Size& size, + const uint8_t color[4]) const { + scoped_refptr<GLImageIOSurface> image(new GLImageIOSurface( + size, GLImageIOSurface::GetInternalFormatForTesting(format))); + IOSurfaceRef surface_ref = + gfx::IOSurfaceManager::CreateIOSurface(size, format); + IOReturn status = IOSurfaceLock(surface_ref, 0, nullptr); + EXPECT_NE(status, kIOReturnCannotLock); + for (size_t plane = 0; plane < NumberOfPlanesForBufferFormat(format); + ++plane) { + void* data = IOSurfaceGetBaseAddressOfPlane(surface_ref, plane); + GLImageTestSupport::SetBufferDataToColor( + size.width(), size.height(), + IOSurfaceGetBytesPerRowOfPlane(surface_ref, plane), plane, format, + color, static_cast<uint8_t*>(data)); + } + IOSurfaceUnlock(surface_ref, 0, nullptr); + + bool rv = + image->Initialize(surface_ref, gfx::GenericSharedMemoryId(1), format); + EXPECT_TRUE(rv); + + return image; + } +}; + +using GLImageTestTypes = testing::Types< + GLImageIOSurfaceTestDelegate<gfx::BufferFormat::RGBA_8888>, + GLImageIOSurfaceTestDelegate<gfx::BufferFormat::BGRA_8888>, + GLImageIOSurfaceTestDelegate<gfx::BufferFormat::YUV_420_BIPLANAR>>; + +INSTANTIATE_TYPED_TEST_CASE_P(GLImageIOSurface, GLImageTest, GLImageTestTypes); + +INSTANTIATE_TYPED_TEST_CASE_P( + GLImageIOSurface, + GLImageCopyTest, + GLImageIOSurfaceTestDelegate<gfx::BufferFormat::YUV_420_BIPLANAR>); + +} // namespace +} // namespace gl
diff --git a/ui/gl/gl_image_ref_counted_memory_unittest.cc b/ui/gl/gl_image_ref_counted_memory_unittest.cc index 3bbe6aa..12f4fb8 100644 --- a/ui/gl/gl_image_ref_counted_memory_unittest.cc +++ b/ui/gl/gl_image_ref_counted_memory_unittest.cc
@@ -23,7 +23,7 @@ scoped_refptr<base::RefCountedBytes> bytes(new base::RefCountedBytes(data)); GLImageTestSupport::SetBufferDataToColor( size.width(), size.height(), - static_cast<int>(RowSizeForBufferFormat(size.width(), format, 0)), + static_cast<int>(RowSizeForBufferFormat(size.width(), format, 0)), 0, format, color, &bytes->data().front()); scoped_refptr<GLImageRefCountedMemory> image(new GLImageRefCountedMemory( size, gl::GLImageMemory::GetInternalFormatForTesting(format)));
diff --git a/ui/gl/gl_image_shared_memory_unittest.cc b/ui/gl/gl_image_shared_memory_unittest.cc index da6feac3..f0e88239 100644 --- a/ui/gl/gl_image_shared_memory_unittest.cc +++ b/ui/gl/gl_image_shared_memory_unittest.cc
@@ -24,7 +24,7 @@ DCHECK(rv); GLImageTestSupport::SetBufferDataToColor( size.width(), size.height(), - static_cast<int>(RowSizeForBufferFormat(size.width(), format, 0)), + static_cast<int>(RowSizeForBufferFormat(size.width(), format, 0)), 0, format, color, reinterpret_cast<uint8_t*>(shared_memory.memory())); scoped_refptr<gl::GLImageSharedMemory> image(new gl::GLImageSharedMemory( size, gl::GLImageMemory::GetInternalFormatForTesting(format))); @@ -71,7 +71,7 @@ // Place buffer at a non-zero non-page-aligned offset in shared memory. size_t buffer_offset = 3 * base::SysInfo::VMAllocationGranularity() / 2; GLImageTestSupport::SetBufferDataToColor( - size.width(), size.height(), static_cast<int>(stride), + size.width(), size.height(), static_cast<int>(stride), 0, gfx::BufferFormat::RGBA_8888, color, reinterpret_cast<uint8_t*>(shared_memory.memory()) + buffer_offset); scoped_refptr<gl::GLImageSharedMemory> image(
diff --git a/ui/gl/gl_mock_autogen_gl.h b/ui/gl/gl_mock_autogen_gl.h index 2a34acdf..fff4bc57 100644 --- a/ui/gl/gl_mock_autogen_gl.h +++ b/ui/gl/gl_mock_autogen_gl.h
@@ -340,6 +340,7 @@ MOCK_METHOD0(GetError, GLenum()); MOCK_METHOD3(GetFenceivNV, void(GLuint fence, GLenum pname, GLint* params)); MOCK_METHOD2(GetFloatv, void(GLenum pname, GLfloat* params)); +MOCK_METHOD2(GetFragDataIndex, GLint(GLuint program, const char* name)); MOCK_METHOD2(GetFragDataLocation, GLint(GLuint program, const char* name)); MOCK_METHOD4( GetFramebufferAttachmentParameterivEXT,
diff --git a/ui/gl/gl_tests.gyp b/ui/gl/gl_tests.gyp index cc06887..dfce746 100644 --- a/ui/gl/gl_tests.gyp +++ b/ui/gl/gl_tests.gyp
@@ -49,6 +49,11 @@ 'glx_api_unittest.cc', ], }], + ['OS == "mac"', { + 'sources': [ + 'gl_image_io_surface_unittest.cc', + ], + }], ['OS == "win"', { 'sources': [ 'wgl_api_unittest.cc',
diff --git a/ui/gl/scoped_binders.cc b/ui/gl/scoped_binders.cc index bb2b290..4480f80 100644 --- a/ui/gl/scoped_binders.cc +++ b/ui/gl/scoped_binders.cc
@@ -29,6 +29,16 @@ } } +ScopedActiveTexture::ScopedActiveTexture(unsigned int texture) + : old_texture_(-1) { + glGetIntegerv(GL_ACTIVE_TEXTURE, &old_texture_); + glActiveTexture(texture); +} + +ScopedActiveTexture::~ScopedActiveTexture() { + glActiveTexture(old_texture_); +} + ScopedTextureBinder::ScopedTextureBinder(unsigned int target, unsigned int id) : state_restorer_(!GLContext::GetCurrent() ? NULL @@ -47,8 +57,11 @@ case GL_TEXTURE_EXTERNAL_OES: target_getter = GL_TEXTURE_BINDING_EXTERNAL_OES; break; + case GL_TEXTURE_RECTANGLE_ARB: + target_getter = GL_TEXTURE_BINDING_RECTANGLE_ARB; + break; default: - NOTIMPLEMENTED() << "Target not part of OpenGL ES 2.0 spec."; + NOTIMPLEMENTED() << " Target not supported."; } glGetIntegerv(target_getter, &old_id_); } @@ -65,4 +78,102 @@ } } +ScopedUseProgram::ScopedUseProgram(unsigned int program) : old_program_(-1) { + glGetIntegerv(GL_CURRENT_PROGRAM, &old_program_); + glUseProgram(program); +} + +ScopedUseProgram::~ScopedUseProgram() { + glUseProgram(old_program_); +} + +ScopedVertexAttribArray::ScopedVertexAttribArray(unsigned int index, + int size, + unsigned int type, + char normalized, + int stride, + const void* pointer) + : buffer_(0), + enabled_(GL_FALSE), + index_(index), + size_(-1), + type_(-1), + normalized_(GL_FALSE), + stride_(0), + pointer_(0) { + glGetVertexAttribiv(index, GL_VERTEX_ATTRIB_ARRAY_BUFFER_BINDING, &buffer_); + glGetVertexAttribiv(index, GL_VERTEX_ATTRIB_ARRAY_ENABLED, &enabled_); + glEnableVertexAttribArray(index); + + glGetVertexAttribiv(index, GL_VERTEX_ATTRIB_ARRAY_SIZE, &size_); + glGetVertexAttribiv(index, GL_VERTEX_ATTRIB_ARRAY_TYPE, &type_); + glGetVertexAttribiv(index, GL_VERTEX_ATTRIB_ARRAY_NORMALIZED, &normalized_); + glGetVertexAttribiv(index, GL_VERTEX_ATTRIB_ARRAY_STRIDE, &stride_); + glGetVertexAttribPointerv(index, GL_VERTEX_ATTRIB_ARRAY_POINTER, &pointer_); + + glVertexAttribPointer(index, size, type, normalized, stride, pointer); +} + +ScopedVertexAttribArray::~ScopedVertexAttribArray() { + ScopedBufferBinder buffer_binder(GL_ARRAY_BUFFER, buffer_); + glVertexAttribPointer(index_, size_, type_, normalized_, stride_, pointer_); + if (enabled_ == GL_FALSE) { + glDisableVertexAttribArray(index_); + } +} + +ScopedBufferBinder::ScopedBufferBinder(unsigned int target, unsigned int id) + : target_(target), old_id_(-1) { + GLenum target_getter = 0; + switch (target) { + case GL_ARRAY_BUFFER: + target_getter = GL_ARRAY_BUFFER_BINDING; + break; + default: + NOTIMPLEMENTED() << " Target not supported."; + } + glGetIntegerv(target_getter, &old_id_); + glBindBuffer(target_, id); +} + +ScopedBufferBinder::~ScopedBufferBinder() { + glBindBuffer(target_, old_id_); +} + +ScopedViewport::ScopedViewport(int x, int y, int width, int height) { + glGetIntegerv(GL_VIEWPORT, data_); + glViewport(x, y, width, height); +} + +ScopedViewport::~ScopedViewport() { + glViewport(data_[0], data_[1], data_[2], data_[3]); +} + +ScopedColorMask::ScopedColorMask(char red, char green, char blue, char alpha) { + glGetBooleanv(GL_COLOR_WRITEMASK, colors_); + glColorMask(red, green, blue, alpha); +} + +ScopedColorMask::~ScopedColorMask() { + glColorMask(colors_[0], colors_[1], colors_[2], colors_[3]); +} + +ScopedCapability::ScopedCapability(unsigned capability, unsigned char enabled) + : capability_(capability) { + enabled_ = glIsEnabled(capability_); + if (enabled == GL_TRUE) { + glEnable(capability); + } else { + glDisable(capability); + } +} + +ScopedCapability::~ScopedCapability() { + if (enabled_ == GL_TRUE) { + glEnable(capability_); + } else { + glDisable(capability_); + } +} + } // namespace gfx
diff --git a/ui/gl/scoped_binders.h b/ui/gl/scoped_binders.h index dab7b31..102e47e 100644 --- a/ui/gl/scoped_binders.h +++ b/ui/gl/scoped_binders.h
@@ -27,6 +27,17 @@ DISALLOW_COPY_AND_ASSIGN(ScopedFrameBufferBinder); }; +class GL_EXPORT ScopedActiveTexture { + public: + ScopedActiveTexture(unsigned int texture); + ~ScopedActiveTexture(); + + private: + // TODO(dcastagna): Use GLStateRestorer. + int old_texture_; + + DISALLOW_COPY_AND_ASSIGN(ScopedActiveTexture); +}; class GL_EXPORT ScopedTextureBinder { public: @@ -45,6 +56,103 @@ DISALLOW_COPY_AND_ASSIGN(ScopedTextureBinder); }; +class GL_EXPORT ScopedUseProgram { + public: + ScopedUseProgram(unsigned int program); + ~ScopedUseProgram(); + + private: + // TODO(dcastagna): Use GLStateRestorer. + int old_program_; + + DISALLOW_COPY_AND_ASSIGN(ScopedUseProgram); +}; + +class GL_EXPORT ScopedVertexAttribArray { + public: + ScopedVertexAttribArray(unsigned int index, + int size, + unsigned int type, + char normalized, + int stride, + const void* pointer); + ~ScopedVertexAttribArray(); + + private: + // TODO(dcastagna): Use GLStateRestorer. + int buffer_; + int enabled_; + int index_; + int size_; + int type_; + int normalized_; + int stride_; + void* pointer_; + + DISALLOW_COPY_AND_ASSIGN(ScopedVertexAttribArray); +}; + +class GL_EXPORT ScopedBufferBinder { + public: + ScopedBufferBinder(unsigned int target, unsigned int index); + ~ScopedBufferBinder(); + + private: + // TODO(dcastagna): Use GLStateRestorer. + int target_; + int old_id_; + + DISALLOW_COPY_AND_ASSIGN(ScopedBufferBinder); +}; + +class GL_EXPORT ScopedViewport { + public: + ScopedViewport(int x, int y, int width, int height); + ~ScopedViewport(); + + private: + int data_[4] = {}; + + DISALLOW_COPY_AND_ASSIGN(ScopedViewport); +}; + +class GL_EXPORT ScopedVertexAttribPointer { + public: + ScopedVertexAttribPointer(unsigned index, + int size, + unsigned type, + char normalized, + int stride, + const void* pointer); + ~ScopedVertexAttribPointer(); + + private: + DISALLOW_COPY_AND_ASSIGN(ScopedVertexAttribPointer); +}; + +class GL_EXPORT ScopedColorMask { + public: + ScopedColorMask(char red, char green, char blue, char alpha); + ~ScopedColorMask(); + + private: + unsigned char colors_[4] = {}; + + DISALLOW_COPY_AND_ASSIGN(ScopedColorMask); +}; + +class GL_EXPORT ScopedCapability { + public: + ScopedCapability(unsigned capability, unsigned char enabled); + ~ScopedCapability(); + + private: + unsigned capability_; + unsigned char enabled_; + + DISALLOW_COPY_AND_ASSIGN(ScopedCapability); +}; + } // namespace gfx #endif // UI_GL_SCOPED_BINDERS_H_
diff --git a/ui/gl/test/gl_image_test_support.cc b/ui/gl/test/gl_image_test_support.cc index 7c964d3f..79996d5e 100644 --- a/ui/gl/test/gl_image_test_support.cc +++ b/ui/gl/test/gl_image_test_support.cc
@@ -39,11 +39,13 @@ void GLImageTestSupport::SetBufferDataToColor(int width, int height, int stride, + int plane, gfx::BufferFormat format, const uint8_t color[4], uint8_t* data) { switch (format) { case gfx::BufferFormat::RGBX_8888: + DCHECK_EQ(0, plane); for (int y = 0; y < height; ++y) { for (int x = 0; x < width; ++x) { data[y * stride + x * 4 + 0] = color[0]; @@ -54,6 +56,7 @@ } return; case gfx::BufferFormat::RGBA_8888: + DCHECK_EQ(0, plane); for (int y = 0; y < height; ++y) { for (int x = 0; x < width; ++x) { data[y * stride + x * 4 + 0] = color[0]; @@ -64,6 +67,7 @@ } return; case gfx::BufferFormat::BGRX_8888: + DCHECK_EQ(0, plane); for (int y = 0; y < height; ++y) { for (int x = 0; x < width; ++x) { data[y * stride + x * 4 + 0] = color[2]; @@ -74,6 +78,7 @@ } return; case gfx::BufferFormat::BGRA_8888: + DCHECK_EQ(0, plane); for (int y = 0; y < height; ++y) { for (int x = 0; x < width; ++x) { data[y * stride + x * 4 + 0] = color[2]; @@ -83,6 +88,33 @@ } } return; + case gfx::BufferFormat::YUV_420_BIPLANAR: { + DCHECK_LT(plane, 2); + DCHECK_EQ(0, height % 2); + DCHECK_EQ(0, width % 2); + // These values are used in the transformation from YUV to RGB color + // values. They are taken from the following webpage: + // http://www.fourcc.org/fccyvrgb.php + uint8_t yuv[] = { + (0.257 * color[0]) + (0.504 * color[1]) + (0.098 * color[2]) + 16, + -(0.148 * color[0]) - (0.291 * color[1]) + (0.439 * color[2]) + 128, + (0.439 * color[0]) - (0.368 * color[1]) - (0.071 * color[2]) + 128}; + if (plane == 0) { + for (int y = 0; y < height; ++y) { + for (int x = 0; x < width; ++x) { + data[stride * y + x] = yuv[0]; + } + } + } else { + for (int y = 0; y < height / 2; ++y) { + for (int x = 0; x < width / 2; ++x) { + data[stride * y + x * 2] = yuv[1]; + data[stride * y + x * 2 + 1] = yuv[2]; + } + } + } + return; + } case gfx::BufferFormat::ATC: case gfx::BufferFormat::ATCIA: case gfx::BufferFormat::DXT1: @@ -91,7 +123,6 @@ case gfx::BufferFormat::R_8: case gfx::BufferFormat::RGBA_4444: case gfx::BufferFormat::UYVY_422: - case gfx::BufferFormat::YUV_420_BIPLANAR: case gfx::BufferFormat::YUV_420: NOTREACHED(); return;
diff --git a/ui/gl/test/gl_image_test_support.h b/ui/gl/test/gl_image_test_support.h index de86465..41258fc0 100644 --- a/ui/gl/test/gl_image_test_support.h +++ b/ui/gl/test/gl_image_test_support.h
@@ -22,6 +22,7 @@ static void SetBufferDataToColor(int width, int height, int stride, + int plane, gfx::BufferFormat format, const uint8_t color[4], uint8_t* data);
diff --git a/ui/gl/test/gl_image_test_template.h b/ui/gl/test/gl_image_test_template.h index 799f252..8b146445 100644 --- a/ui/gl/test/gl_image_test_template.h +++ b/ui/gl/test/gl_image_test_template.h
@@ -17,6 +17,7 @@ #include "ui/gfx/buffer_types.h" #include "ui/gl/gl_bindings.h" #include "ui/gl/gl_context.h" +#include "ui/gl/gl_helper.h" #include "ui/gl/gl_image.h" #include "ui/gl/gl_implementation.h" #include "ui/gl/gl_surface.h" @@ -89,7 +90,10 @@ TYPED_TEST_P(GLImageCopyTest, CopyTexImage) { const gfx::Size image_size(256, 256); - const uint8_t image_color[] = {0xff, 0xff, 0, 0xff}; + // These values are picked so that RGB -> YUV on the CPU converted + // back to RGB on the GPU produces the original RGB values without + // any error. + const uint8_t image_color[] = {0x10, 0x20, 0, 0xff}; const uint8_t texture_color[] = {0, 0, 0xff, 0xff}; GLuint framebuffer = @@ -112,7 +116,7 @@ image_size.width(), image_size.height(), static_cast<int>(RowSizeForBufferFormat(image_size.width(), gfx::BufferFormat::RGBA_8888, 0)), - gfx::BufferFormat::RGBA_8888, texture_color, pixels.get()); + 0, gfx::BufferFormat::RGBA_8888, texture_color, pixels.get()); // Note: This test assume that |image| can be used with GL_TEXTURE_2D but // that might not be the case for some GLImage implementations. glBindTexture(GL_TEXTURE_2D, texture); @@ -126,11 +130,10 @@ // clang-format off const char kVertexShader[] = STRINGIZE( attribute vec2 a_position; - attribute vec2 a_texCoord; varying vec2 v_texCoord; void main() { gl_Position = vec4(a_position.x, a_position.y, 0.0, 1.0); - v_texCoord = a_texCoord; + v_texCoord = (a_position + vec2(1.0, 1.0)) * 0.5; } ); const char kFragmentShader[] = STRINGIZE( @@ -146,14 +149,14 @@ // clang-format on GLuint vertex_shader = - GLTestHelper::LoadShader(GL_VERTEX_SHADER, kVertexShader); + gfx::GLHelper::LoadShader(GL_VERTEX_SHADER, kVertexShader); bool is_gles = gfx::GetGLImplementation() == gfx::kGLImplementationEGLGLES2; - GLuint fragment_shader = GLTestHelper::LoadShader( + GLuint fragment_shader = gfx::GLHelper::LoadShader( GL_FRAGMENT_SHADER, base::StringPrintf("%s%s", is_gles ? kShaderFloatPrecision : "", kFragmentShader) .c_str()); - GLuint program = GLTestHelper::SetupProgram(vertex_shader, fragment_shader); + GLuint program = gfx::GLHelper::SetupProgram(vertex_shader, fragment_shader); EXPECT_NE(program, 0u); glUseProgram(program); @@ -161,33 +164,10 @@ ASSERT_NE(sampler_location, -1); glUniform1i(sampler_location, 0); - // clang-format off - static GLfloat vertices[] = { - -1.f, -1.f, 0.f, 0.f, - 1.f, -1.f, 1.f, 0.f, - -1.f, 1.f, 0.f, 1.f, - 1.f, 1.f, 1.f, 1.f - }; - // clang-format on - - GLuint vertex_buffer; - glGenBuffersARB(1, &vertex_buffer); - glBindBuffer(GL_ARRAY_BUFFER, vertex_buffer); - glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW); - GLint position_location = glGetAttribLocation(program, "a_position"); - ASSERT_NE(position_location, -1); - glEnableVertexAttribArray(position_location); - glVertexAttribPointer(position_location, 2, GL_FLOAT, GL_FALSE, - sizeof(GLfloat) * 4, 0); - GLint tex_coord_location = glGetAttribLocation(program, "a_texCoord"); - EXPECT_NE(tex_coord_location, -1); - glEnableVertexAttribArray(tex_coord_location); - glVertexAttribPointer(tex_coord_location, 2, GL_FLOAT, GL_FALSE, - sizeof(GLfloat) * 4, - reinterpret_cast<void*>(sizeof(GLfloat) * 2)); - + GLuint vertex_buffer = gfx::GLHelper::SetupQuadVertexBuffer(); // Draw |texture| to viewport and read back pixels to check expectations. - glDrawArrays(GL_TRIANGLE_STRIP, 0, 4); + gfx::GLHelper::DrawQuad(vertex_buffer); + GLTestHelper::CheckPixels(0, 0, image_size.width(), image_size.height(), image_color);
diff --git a/ui/gl/test/gl_test_helper.cc b/ui/gl/test/gl_test_helper.cc index 24b9b47..5f462a3 100644 --- a/ui/gl/test/gl_test_helper.cc +++ b/ui/gl/test/gl_test_helper.cc
@@ -10,7 +10,6 @@ #include "testing/gtest/include/gtest/gtest.h" namespace gl { - // static GLuint GLTestHelper::CreateTexture(GLenum target) { // Create the texture object. @@ -25,65 +24,6 @@ } // static -GLuint GLTestHelper::CompileShader(GLenum type, const char* src) { - GLuint shader = glCreateShader(type); - // Load the shader source. - glShaderSource(shader, 1, &src, nullptr); - // Compile the shader. - glCompileShader(shader); - return shader; -} - -// static -GLuint GLTestHelper::LoadShader(GLenum type, const char* src) { - GLuint shader = CompileShader(type, src); - - // Check the compile status. - GLint value = 0; - glGetShaderiv(shader, GL_COMPILE_STATUS, &value); - if (!value) { - char buffer[1024]; - GLsizei length = 0; - glGetShaderInfoLog(shader, sizeof(buffer), &length, buffer); - std::string log(buffer, length); - EXPECT_EQ(1, value) << "Error compiling shader: " << log; - glDeleteShader(shader); - shader = 0; - } - return shader; -} - -// static -GLuint GLTestHelper::LinkProgram(GLuint vertex_shader, GLuint fragment_shader) { - // Create the program object. - GLuint program = glCreateProgram(); - glAttachShader(program, vertex_shader); - glAttachShader(program, fragment_shader); - // Link the program. - glLinkProgram(program); - return program; -} - -// static -GLuint GLTestHelper::SetupProgram(GLuint vertex_shader, - GLuint fragment_shader) { - GLuint program = LinkProgram(vertex_shader, fragment_shader); - // Check the link status. - GLint linked = 0; - glGetProgramiv(program, GL_LINK_STATUS, &linked); - if (!linked) { - char buffer[1024]; - GLsizei length = 0; - glGetProgramInfoLog(program, sizeof(buffer), &length, buffer); - std::string log(buffer, length); - EXPECT_EQ(1, linked) << "Error linking program: " << log; - glDeleteProgram(program); - program = 0; - } - return program; -} - -// static GLuint GLTestHelper::SetupFramebuffer(int width, int height) { GLuint color_buffer_texture = CreateTexture(GL_TEXTURE_2D); glBindTexture(GL_TEXTURE_2D, color_buffer_texture);
diff --git a/ui/gl/test/gl_test_helper.h b/ui/gl/test/gl_test_helper.h index ac7be68..98b2e0e 100644 --- a/ui/gl/test/gl_test_helper.h +++ b/ui/gl/test/gl_test_helper.h
@@ -16,22 +16,6 @@ // Does not check for errors, always returns texture. static GLuint CreateTexture(GLenum target); - // Compiles a shader. - // Does not check for errors, always returns shader. - static GLuint CompileShader(GLenum type, const char* src); - - // Compiles a shader and checks for compilation errors. - // Returns shader, 0 on failure. - static GLuint LoadShader(GLenum type, const char* src); - - // Attaches 2 shaders and links them to a program. - // Does not check for errors, always returns program. - static GLuint LinkProgram(GLuint vertex_shader, GLuint fragment_shader); - - // Attaches 2 shaders, links them to a program, and checks for errors. - // Returns program, 0 on failure. - static GLuint SetupProgram(GLuint vertex_shader, GLuint fragment_shader); - // Creates a framebuffer, attaches a color buffer, and checks for errors. // Returns framebuffer, 0 on failure. static GLuint SetupFramebuffer(int width, int height);
diff --git a/ui/login/display_manager.js b/ui/login/display_manager.js index e94342a..a945bfef 100644 --- a/ui/login/display_manager.js +++ b/ui/login/display_manager.js
@@ -59,10 +59,9 @@ WRONG_HWID_WARNING: 3, SUPERVISED_USER_CREATION_FLOW: 4, SAML_PASSWORD_CONFIRM: 5, - CONSUMER_MANAGEMENT_ENROLLMENT: 6, - PASSWORD_CHANGED: 7, - ENROLLMENT: 8, - ERROR: 9 + PASSWORD_CHANGED: 6, + ENROLLMENT: 7, + ERROR: 8 }; /* Possible UI states of the error screen. */
diff --git a/ui/platform_window/android/platform_ime_controller_android.cc b/ui/platform_window/android/platform_ime_controller_android.cc index 58a04ec..67c8d32 100644 --- a/ui/platform_window/android/platform_ime_controller_android.cc +++ b/ui/platform_window/android/platform_ime_controller_android.cc
@@ -28,12 +28,14 @@ void PlatformImeControllerAndroid::UpdateTextInputState( const TextInputState& state) { - if (java_platform_ime_controller_android_.is_empty()) - return; JNIEnv* env = base::android::AttachCurrentThread(); + ScopedJavaLocalRef<jobject> scoped_obj = + java_platform_ime_controller_android_.get(env); + if (scoped_obj.is_null()) + return; Java_PlatformImeControllerAndroid_updateTextInputState( env, - java_platform_ime_controller_android_.get(env).obj(), + scoped_obj.obj(), state.type, state.flags, base::android::ConvertUTF8ToJavaString(env, state.text).obj(), @@ -44,13 +46,13 @@ } void PlatformImeControllerAndroid::SetImeVisibility(bool visible) { - if (java_platform_ime_controller_android_.is_empty()) - return; JNIEnv* env = base::android::AttachCurrentThread(); + ScopedJavaLocalRef<jobject> scoped_obj = + java_platform_ime_controller_android_.get(env); + if (scoped_obj.is_null()) + return; Java_PlatformImeControllerAndroid_setImeVisibility( - env, - java_platform_ime_controller_android_.get(env).obj(), - visible); + env, scoped_obj.obj(), visible); } } // namespace ui
diff --git a/ui/platform_window/android/platform_window_android.cc b/ui/platform_window/android/platform_window_android.cc index b9ee0519..0cfdc6bf 100644 --- a/ui/platform_window/android/platform_window_android.cc +++ b/ui/platform_window/android/platform_window_android.cc
@@ -62,10 +62,11 @@ PlatformWindowAndroid::~PlatformWindowAndroid() { if (window_) ReleaseWindow(); - if (!java_platform_window_android_.is_empty()) { - JNIEnv* env = base::android::AttachCurrentThread(); - Java_PlatformWindowAndroid_detach( - env, java_platform_window_android_.get(env).obj()); + JNIEnv* env = base::android::AttachCurrentThread(); + ScopedJavaLocalRef<jobject> scoped_obj = + java_platform_window_android_.get(env); + if (!scoped_obj.is_null()) { + Java_PlatformWindowAndroid_detach(env, scoped_obj.obj()); } }
diff --git a/ui/platform_window/x11/x11_window.cc b/ui/platform_window/x11/x11_window.cc index 073fe4da..c84135fa 100644 --- a/ui/platform_window/x11/x11_window.cc +++ b/ui/platform_window/x11/x11_window.cc
@@ -257,7 +257,9 @@ void X11Window::Restore() {} -void X11Window::SetCursor(PlatformCursor cursor) {} +void X11Window::SetCursor(PlatformCursor cursor) { + XDefineCursor(xdisplay_, xwindow_, cursor); +} void X11Window::MoveCursorTo(const gfx::Point& location) {}
diff --git a/ui/views/background.cc b/ui/views/background.cc index 62cdc3b..41e0277 100644 --- a/ui/views/background.cc +++ b/ui/views/background.cc
@@ -5,13 +5,15 @@ #include "ui/views/background.h" #include "base/logging.h" -#include "skia/ext/skia_utils_win.h" -#include "third_party/skia/include/core/SkPaint.h" #include "ui/gfx/canvas.h" #include "ui/gfx/color_utils.h" #include "ui/views/painter.h" #include "ui/views/view.h" +#if defined(OS_WIN) +#include "skia/ext/skia_utils_win.h" +#endif + namespace views { // SolidBackground is a trivial Background implementation that fills the
diff --git a/ui/views/controls/single_split_view.cc b/ui/views/controls/single_split_view.cc index fe50141..542d17f 100644 --- a/ui/views/controls/single_split_view.cc +++ b/ui/views/controls/single_split_view.cc
@@ -4,7 +4,6 @@ #include "ui/views/controls/single_split_view.h" -#include "skia/ext/skia_utils_win.h" #include "ui/accessibility/ax_view_state.h" #include "ui/base/cursor/cursor.h" #include "ui/gfx/canvas.h" @@ -12,6 +11,10 @@ #include "ui/views/controls/single_split_view_listener.h" #include "ui/views/native_cursor.h" +#if defined(OS_WIN) +#include "skia/ext/skia_utils_win.h" +#endif + namespace views { // static
diff --git a/ui/views/controls/table/table_view.cc b/ui/views/controls/table/table_view.cc index 7b4d5257..9a282e8 100644 --- a/ui/views/controls/table/table_view.cc +++ b/ui/views/controls/table/table_view.cc
@@ -542,7 +542,7 @@ GetRowBounds(i), canvas); } - if (selection_model_.active() == i && HasFocus()) + if (selection_model_.active() == model_index && HasFocus()) canvas->DrawFocusRect(GetRowBounds(i)); for (int j = region.min_column; j < region.max_column; ++j) { const gfx::Rect cell_bounds(GetCellBounds(i, j));
diff --git a/ui/views/mus/native_widget_mus.cc b/ui/views/mus/native_widget_mus.cc index 2402458..4a1d77da 100644 --- a/ui/views/mus/native_widget_mus.cc +++ b/ui/views/mus/native_widget_mus.cc
@@ -589,7 +589,14 @@ } void NativeWidgetMus::SetCursor(gfx::NativeCursor cursor) { - // NOTIMPLEMENTED(); + // TODO(erg): In aura, our incoming cursor is really two + // parts. cursor.native_type() is an integer for standard cursors and is all + // we support right now. If native_type() == kCursorCustom, than we should + // also send an image, but as the cursor code is currently written, the image + // is in a platform native format that's already uploaded to the window + // server. + window_tree_host_->platform_window()->SetCursorById( + mus::mojom::Cursor(cursor.native_type())); } bool NativeWidgetMus::IsMouseEventsEnabled() const {
diff --git a/ui/views/mus/platform_window_mus.cc b/ui/views/mus/platform_window_mus.cc index 132e4b4..5111b705 100644 --- a/ui/views/mus/platform_window_mus.cc +++ b/ui/views/mus/platform_window_mus.cc
@@ -23,6 +23,7 @@ : delegate_(delegate), mus_window_(mus_window), show_state_(mus::mojom::SHOW_STATE_RESTORED), + last_cursor_(mus::mojom::CURSOR_NULL), has_capture_(false) { DCHECK(delegate_); DCHECK(mus_window_); @@ -54,6 +55,17 @@ mus_window_->SetFocus(); } +void PlatformWindowMus::SetCursorById(mus::mojom::Cursor cursor) { + if (last_cursor_ != cursor) { + // The ui::PlatformWindow interface uses ui::PlatformCursor at this level, + // instead of ui::Cursor. All of the cursor abstractions in ui right now are + // sort of leaky; despite being nominally cross platform, they all drop down + // to platform types almost immediately, which makes them unusable as + // transport types. + mus_window_->SetPredefinedCursor(cursor); + } +} + void PlatformWindowMus::Show() { mus_window_->SetVisible(true); } @@ -147,6 +159,13 @@ delegate_->OnActivationChanged(false); } +void PlatformWindowMus::OnWindowPredefinedCursorChanged( + mus::Window* window, + mus::mojom::Cursor cursor) { + DCHECK_EQ(window, mus_window_); + last_cursor_ = cursor; +} + void PlatformWindowMus::OnWindowInputEvent(mus::Window* view, const mus::mojom::EventPtr& event) { scoped_ptr<ui::Event> ui_event(event.To<scoped_ptr<ui::Event>>());
diff --git a/ui/views/mus/platform_window_mus.h b/ui/views/mus/platform_window_mus.h index 0c16f98..69c6dd3d 100644 --- a/ui/views/mus/platform_window_mus.h +++ b/ui/views/mus/platform_window_mus.h
@@ -25,6 +25,8 @@ void Activate(); + void SetCursorById(mus::mojom::Cursor cursor); + // ui::PlatformWindow: void Show() override; void Hide() override; @@ -53,6 +55,8 @@ const gfx::Rect& new_bounds) override; void OnWindowFocusChanged(mus::Window* gained_focus, mus::Window* lost_focus) override; + void OnWindowPredefinedCursorChanged(mus::Window* window, + mus::mojom::Cursor cursor) override; void OnWindowInputEvent(mus::Window* view, const mus::mojom::EventPtr& event) override; void OnWindowSharedPropertyChanged( @@ -64,6 +68,7 @@ ui::PlatformWindowDelegate* delegate_; mus::Window* mus_window_; mus::mojom::ShowState show_state_; + mus::mojom::Cursor last_cursor_; bool has_capture_; DISALLOW_COPY_AND_ASSIGN(PlatformWindowMus);
diff --git a/ui/views/view.cc b/ui/views/view.cc index 4aa6d5a..d2bc11e6 100644 --- a/ui/views/view.cc +++ b/ui/views/view.cc
@@ -791,10 +791,9 @@ // rather than relative to its parent. bool paint_relative_to_parent = !layer(); - // TODO(wkorman): Rework clip and transform recorders to pass the size in the - // individual clip methods rather than in the constructor. - ui::ClipRecorder clip_recorder(parent_context, - parent() ? parent()->size() : size()); + // TODO(danakj): Rework clip and transform recorder usage here to use + // std::optional once we can do so. + ui::ClipRecorder clip_recorder(parent_context); if (paint_relative_to_parent) { // Set the clip rect to the bounds of this View. Note that the X (or left) // position we pass to ClipRect takes into consideration whether or not the @@ -808,7 +807,7 @@ clip_recorder.ClipRect(clip_rect_in_parent); } - ui::TransformRecorder transform_recorder(context, size()); + ui::TransformRecorder transform_recorder(context); if (paint_relative_to_parent) { // Translate the graphics such that 0,0 corresponds to where // this View is located relative to its parent. @@ -817,7 +816,7 @@ transform_from_parent.Translate(offset_from_parent.x(), offset_from_parent.y()); transform_from_parent.PreconcatTransform(GetTransform()); - transform_recorder.Transform(transform_from_parent); + transform_recorder.Transform(transform_from_parent, size()); } // Note that the cache is not aware of the offset of the view
diff --git a/ui/views/win/hwnd_message_handler.cc b/ui/views/win/hwnd_message_handler.cc index 035df76..b5bd8a8 100644 --- a/ui/views/win/hwnd_message_handler.cc +++ b/ui/views/win/hwnd_message_handler.cc
@@ -2265,9 +2265,6 @@ WPARAM w_param, LPARAM l_param, bool track_mouse) { - if (!touch_ids_.empty()) - return 0; - // We handle touch events on Windows Aura. Windows generates synthesized // mouse messages in response to touch which we should ignore. However touch // messages are only received for the client area. We need to ignore the @@ -2287,6 +2284,26 @@ return 0; } + // Windows does not reliably set the touch flag on mouse moves and nc + // mouse moves. We also ignore mouse leaves as they are an artificially + // generated message in response to the TrackMouseEvents API. + // The code below is primarily for validation that we don't receive + // other mouse messages while we are in a touch sequence. + switch (message) { + case WM_MOUSEMOVE: + case WM_NCMOUSEMOVE: + case WM_MOUSELEAVE: + case WM_NCMOUSELEAVE: + break; + + default: + // Remove this CHECK once we validate that our hypothesis about the above + // mouse events being the only ones on which the touch flag is not set + // is correct. + CHECK(touch_ids_.empty()); + break; + } + // Certain logitech drivers send the WM_MOUSEHWHEEL message to the parent // followed by WM_MOUSEWHEEL messages to the child window causing a vertical // scroll. We treat these WM_MOUSEWHEEL messages as WM_MOUSEHWHEEL