diff --git a/AUTHORS b/AUTHORS index 91d38d9..196012ab 100644 --- a/AUTHORS +++ b/AUTHORS
@@ -502,6 +502,7 @@ Vipul Bhasin <vipul.bhasin@gmail.com> Visa Putkinen <v.putkinen@partner.samsung.com> Vivek Galatage <vivek.vg@samsung.com> +Wesley Lancel <wesleylancel@gmail.com> Will Hirsch <chromium@willhirsch.co.uk> William Xie <william.xie@intel.com> Xiang Long <xiang.long@intel.com>
diff --git a/DEPS b/DEPS index decc1898..50c91ac 100644 --- a/DEPS +++ b/DEPS
@@ -34,7 +34,7 @@ 'llvm_url': 'http://src.chromium.org/llvm-project', 'llvm_git': 'https://llvm.googlesource.com', 'webkit_trunk': 'http://src.chromium.org/blink/trunk', - 'webkit_revision': 'ed228f8d2b2ef02da74b9fde69990da74643683c', # from svn revision 191074 + 'webkit_revision': '3094822896bcb215514b9144184acbd04b6a40a9', # from svn revision 191160 'chromium_git': 'https://chromium.googlesource.com', 'chromiumos_git': 'https://chromium.googlesource.com/chromiumos', 'pdfium_git': 'https://pdfium.googlesource.com', @@ -42,12 +42,12 @@ 'boringssl_git': 'https://boringssl.googlesource.com', 'libvpx_revision': '080710f043a2f85e100d508a53749cd321e4b57b', 'sfntly_revision': '1bdaae8fc788a5ac8936d68bf24f37d977a13dac', - 'skia_revision': 'b675a73c1f3f4a433c4893199a0bd11126dfe130', + 'skia_revision': '7ab42771859145884e1b28c8c45f0a5a728b22ac', # Three lines of non-changing comments so that # the commit queue can handle CLs rolling Skia # and V8 without interference from each other. 'v8_branch': 'trunk', - 'v8_revision': '369eb13a86b0529acd80b3b73b6c2a796224f3a7', + 'v8_revision': '3e7dee100ac4e951719ce264f79a214f6634cf11', # Three lines of non-changing comments so that # the commit queue can handle CLs rolling WebRTC # and V8 without interference from each other. @@ -207,7 +207,7 @@ Var('chromium_git') + '/chromium/third_party/ffmpeg.git' + '@' + 'f5698b4f3e3e8eacad18d77cf69882fe14015de5', 'src/third_party/libjingle/source/talk': - Var('chromium_git') + '/external/webrtc/trunk/talk.git' + '@' + 'fbd8fd2847eb747d88dac20b1d5d723bd41f8b08', + Var('chromium_git') + '/external/webrtc/trunk/talk.git' + '@' + 'bbfd3991a4a9b270c352ccba09b5d60b3222ef10', 'src/third_party/usrsctp/usrsctplib': Var('chromium_git') + '/external/usrsctplib.git' + '@' + '13718c7b9fd376fde092cbd3c5347d15059ac652', # from svn revision 9167 @@ -231,7 +231,7 @@ Var('chromium_git') + '/native_client/src/third_party/scons-2.0.1.git' + '@' + '1c1550e17fc26355d08627fbdec13d8291227067', 'src/third_party/webrtc': - Var('chromium_git') + '/external/webrtc/trunk/webrtc.git' + '@' + '093c83b9ef8dab80548107376ed82fbe44e277a7', + Var('chromium_git') + '/external/webrtc/trunk/webrtc.git' + '@' + '1e5b7f78e95daa0e0cb8a6ddfee20011208154b6', 'src/third_party/openmax_dl': Var('chromium_git') + '/external/webrtc/deps/third_party/openmax.git' + '@' + Var('openmax_dl_revision'),
diff --git a/PRESUBMIT_test.py b/PRESUBMIT_test.py index ad391d3c..8b642c4 100755 --- a/PRESUBMIT_test.py +++ b/PRESUBMIT_test.py
@@ -775,5 +775,39 @@ bot, master, PRESUBMIT.GetTryServerMasterForBot(bot))) +class UserMetricsActionTest(unittest.TestCase): + def testUserMetricsActionInActions(self): + input_api = MockInputApi() + file_with_user_action = 'file_with_user_action.cc' + contents_with_user_action = [ + 'base::UserMetricsAction("AboutChrome")' + ] + + input_api.files = [MockFile(file_with_user_action, + contents_with_user_action)] + + self.assertEqual( + [], PRESUBMIT._CheckUserActionUpdate(input_api, MockOutputApi())) + + + def testUserMetricsActionNotAddedToActions(self): + input_api = MockInputApi() + file_with_user_action = 'file_with_user_action.cc' + contents_with_user_action = [ + 'base::UserMetricsAction("NotInActionsXml")' + ] + + input_api.files = [MockFile(file_with_user_action, + contents_with_user_action)] + + output = PRESUBMIT._CheckUserActionUpdate(input_api, MockOutputApi()) + self.assertEqual( + ('File %s line %d: %s is missing in ' + 'tools/metrics/actions/actions.xml. Please run ' + 'tools/metrics/actions/extract_actions.py to update.' + % (file_with_user_action, 1, 'NotInActionsXml')), + output[0].message) + + if __name__ == '__main__': unittest.main()
diff --git a/PRESUBMIT_test_mocks.py b/PRESUBMIT_test_mocks.py index 03d9232..8e15d8c 100644 --- a/PRESUBMIT_test_mocks.py +++ b/PRESUBMIT_test_mocks.py
@@ -32,6 +32,9 @@ def AffectedSourceFiles(self, file_filter=None): return self.files + def LocalPaths(self): + return self.files + def PresubmitLocalPath(self): return os.path.dirname(__file__) @@ -62,22 +65,22 @@ return self.message class PresubmitError(PresubmitResult): - def __init__(self, message, items, long_text=''): + def __init__(self, message, items=None, long_text=''): MockOutputApi.PresubmitResult.__init__(self, message, items, long_text) self.type = 'error' class PresubmitPromptWarning(PresubmitResult): - def __init__(self, message, items, long_text=''): + def __init__(self, message, items=None, long_text=''): MockOutputApi.PresubmitResult.__init__(self, message, items, long_text) self.type = 'warning' class PresubmitNotifyResult(PresubmitResult): - def __init__(self, message, items, long_text=''): + def __init__(self, message, items=None, long_text=''): MockOutputApi.PresubmitResult.__init__(self, message, items, long_text) self.type = 'notify' class PresubmitPromptOrNotify(PresubmitResult): - def __init__(self, message, items, long_text=''): + def __init__(self, message, items=None, long_text=''): MockOutputApi.PresubmitResult.__init__(self, message, items, long_text) self.type = 'promptOrNotify' @@ -103,6 +106,14 @@ def LocalPath(self): return self._local_path + def rfind(self, p): + """os.path.basename is called on MockFile so we need an rfind method.""" + return self._local_path.rfind(p) + + def __getitem__(self, i): + """os.path.basename is called on MockFile so we need a get method.""" + return self._local_path[i] + class MockAffectedFile(MockFile): def AbsoluteLocalPath(self):
diff --git a/android_webview/glue/java/src/com/android/webview/chromium/ContentSettingsAdapter.java b/android_webview/glue/java/src/com/android/webview/chromium/ContentSettingsAdapter.java index 1826e78..3f0d514d 100644 --- a/android_webview/glue/java/src/com/android/webview/chromium/ContentSettingsAdapter.java +++ b/android_webview/glue/java/src/com/android/webview/chromium/ContentSettingsAdapter.java
@@ -584,6 +584,14 @@ return mAwSettings.getMixedContentMode(); } + public void setOffscreenPreRaster(boolean enabled) { + mAwSettings.setOffscreenPreRaster(enabled); + } + + public boolean getOffscreenPreRaster() { + return mAwSettings.getOffscreenPreRaster(); + } + @Override public void setVideoOverlayForEmbeddedEncryptedVideoEnabled(boolean flag) { mAwSettings.setVideoOverlayForEmbeddedVideoEnabled(flag);
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 ef65bfe..619979c9 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
@@ -21,7 +21,9 @@ import org.chromium.content.browser.test.util.CallbackHelper; import org.chromium.content.browser.test.util.Criteria; import org.chromium.content.browser.test.util.CriteriaHelper; +import org.chromium.content.browser.test.util.TestCallbackHelperContainer.OnPageFinishedHelper; import org.chromium.content_public.browser.LoadUrlParams; +import org.chromium.net.test.util.TestWebServer; import java.lang.annotation.Annotation; import java.lang.reflect.Method; @@ -509,4 +511,59 @@ }); } + /** + * Loads the main html then triggers the popup window. + */ + public void triggerPopup(final AwContents parentAwContents, + TestAwContentsClient parentAwContentsClient, TestWebServer testWebServer, + String mainHtml, String popupHtml, String popupPath, String triggerScript) + throws Exception { + enableJavaScriptOnUiThread(parentAwContents); + getInstrumentation().runOnMainSync(new Runnable() { + @Override + public void run() { + parentAwContents.getSettings().setSupportMultipleWindows(true); + parentAwContents.getSettings().setJavaScriptCanOpenWindowsAutomatically(true); + } + }); + + final String parentUrl = testWebServer.setResponse("/popupParent.html", mainHtml, null); + testWebServer.setResponse(popupPath, popupHtml, null); + + parentAwContentsClient.getOnCreateWindowHelper().setReturnValue(true); + loadUrlSync(parentAwContents, parentAwContentsClient.getOnPageFinishedHelper(), parentUrl); + + TestAwContentsClient.OnCreateWindowHelper onCreateWindowHelper = + parentAwContentsClient.getOnCreateWindowHelper(); + int currentCallCount = onCreateWindowHelper.getCallCount(); + parentAwContents.evaluateJavaScript(triggerScript, null); + onCreateWindowHelper.waitForCallback( + currentCallCount, 1, WAIT_TIMEOUT_MS, TimeUnit.MILLISECONDS); + } + + /** + * Supplies the popup window with AwContents then waits for the popup window to finish loading. + */ + public AwContents connectPendingPopup(final AwContents parentAwContents) throws Exception { + TestAwContentsClient popupContentsClient; + AwTestContainerView popupContainerView; + final AwContents popupContents; + popupContentsClient = new TestAwContentsClient(); + popupContainerView = createAwTestContainerViewOnMainSync(popupContentsClient); + popupContents = popupContainerView.getAwContents(); + enableJavaScriptOnUiThread(popupContents); + + getInstrumentation().runOnMainSync(new Runnable() { + @Override + public void run() { + parentAwContents.supplyContentsForPopup(popupContents); + } + }); + + OnPageFinishedHelper onPageFinishedHelper = popupContentsClient.getOnPageFinishedHelper(); + int callCount = onPageFinishedHelper.getCallCount(); + onPageFinishedHelper.waitForCallback(callCount, 1, WAIT_TIMEOUT_MS, TimeUnit.MILLISECONDS); + + return popupContents; + } }
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 a81e9070..3044ddc5 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
@@ -8,15 +8,11 @@ import android.test.suitebuilder.annotation.SmallTest; import org.chromium.android_webview.AwContents; -import org.chromium.android_webview.test.util.AwTestTouchUtils; import org.chromium.android_webview.test.util.CommonResources; import org.chromium.base.test.util.Feature; import org.chromium.base.test.util.MinAndroidSdkLevel; import org.chromium.net.test.util.TestWebServer; -import java.util.concurrent.Callable; -import java.util.concurrent.TimeUnit; - /** * Tests for pop up window flow. */ @@ -25,9 +21,6 @@ private TestAwContentsClient mParentContentsClient; private AwTestContainerView mParentContainerView; private AwContents mParentContents; - private TestAwContentsClient mPopupContentsClient; - private AwTestContainerView mPopupContainerView; - private AwContents mPopupContents; private TestWebServer mWebServer; private static final String POPUP_TITLE = "Popup Window"; @@ -49,67 +42,22 @@ super.tearDown(); } - private void triggerPopup() throws Throwable { - enableJavaScriptOnUiThread(mParentContents); - getInstrumentation().runOnMainSync(new Runnable() { - @Override - public void run() { - mParentContents.getSettings().setSupportMultipleWindows(true); - mParentContents.getSettings().setJavaScriptCanOpenWindowsAutomatically(true); - } - }); - + @SmallTest + @Feature({"AndroidWebView"}) + public void testPopupWindow() throws Throwable { final String popupPath = "/popup.html"; - - final String parentPageHtml = CommonResources.makeHtmlPageFrom("", - "<script>" + final String parentPageHtml = CommonResources.makeHtmlPageFrom("", "<script>" + "function tryOpenWindow() {" + " var newWindow = window.open('" + popupPath + "');" - + "}</script>" - + "<a class=\"full_view\" onclick=\"tryOpenWindow();\">Click me!</a>"); + + "}</script>"); + final String popupPageHtml = CommonResources.makeHtmlPageFrom( "<title>" + POPUP_TITLE + "</title>", "This is a popup window"); - final String parentUrl = mWebServer.setResponse("/popupParent.html", parentPageHtml, null); - mWebServer.setResponse(popupPath, popupPageHtml, null); - - mParentContentsClient.getOnCreateWindowHelper().setReturnValue(true); - loadUrlSync(mParentContents, - mParentContentsClient.getOnPageFinishedHelper(), - parentUrl); - - TestAwContentsClient.OnCreateWindowHelper onCreateWindowHelper = - mParentContentsClient.getOnCreateWindowHelper(); - int currentCallCount = onCreateWindowHelper.getCallCount(); - AwTestTouchUtils.simulateTouchCenterOfView(mParentContainerView); - onCreateWindowHelper.waitForCallback(currentCallCount, 1, WAIT_TIMEOUT_MS, - TimeUnit.MILLISECONDS); - } - - private void connectPendingPopup() throws Exception { - mPopupContentsClient = new TestAwContentsClient(); - mPopupContainerView = createAwTestContainerViewOnMainSync(mPopupContentsClient); - mPopupContents = mPopupContainerView.getAwContents(); - - getInstrumentation().runOnMainSync(new Runnable() { - @Override - public void run() { - mParentContents.supplyContentsForPopup(mPopupContents); - } - }); - } - - @SmallTest - @Feature({"AndroidWebView"}) - public void testPopupWindow() throws Throwable { - triggerPopup(); - connectPendingPopup(); - poll(new Callable<Boolean>() { - @Override - public Boolean call() throws Exception { - return POPUP_TITLE.equals(getTitleOnUiThread(mPopupContents)); - } - }); + triggerPopup(mParentContents, mParentContentsClient, mWebServer, parentPageHtml, + popupPageHtml, "/popup.html", "tryOpenWindow()"); + AwContents popupContents = connectPendingPopup(mParentContents); + assertEquals(POPUP_TITLE, getTitleOnUiThread(popupContents)); } }
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 6d86ef3..44db7f1 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
@@ -763,4 +763,90 @@ mMessageObject.waitForMessage(); assertEquals(WORKER_MESSAGE, mMessageObject.getData()); } + + private static final String POPUP_MESSAGE = "from_popup"; + private static final String POPUP_URL = "/popup.html"; + private static final String IFRAME_URL = "/iframe.html"; + private static final String MAIN_PAGE_FOR_POPUP_TEST = "<!DOCTYPE html><html>" + + "<head>" + + " <script>" + + " function createPopup() {" + + " var popupWindow = window.open('" + POPUP_URL + "');" + + " onmessage = function(e) {" + + " popupWindow.postMessage(e.data, '*', e.ports);" + + " };" + + " }" + + " </script>" + + "</head>" + + "</html>"; + + // Sends message and ports to the iframe. + private static final String POPUP_PAGE_WITH_IFRAME = "<!DOCTYPE html><html>" + + "<script>" + + " onmessage = function(e) {" + + " var iframe = document.getElementsByTagName('iframe')[0];" + + " iframe.contentWindow.postMessage('" + POPUP_MESSAGE + "', '*', e.ports);" + + " };" + + "</script>" + + "<body><iframe src='" + IFRAME_URL + "'></iframe></body>" + + "</html>"; + + // Test if WebView can post a message from/to a popup window owning a message port. + @SmallTest + @Feature({"AndroidWebView", "Android-PostMessage"}) + public void testPostMessageToPopup() throws Throwable { + triggerPopup(mAwContents, mContentsClient, mWebServer, MAIN_PAGE_FOR_POPUP_TEST, ECHO_PAGE, + POPUP_URL, "createPopup()"); + connectPendingPopup(mAwContents); + final ChannelContainer channelContainer = new ChannelContainer(); + + runTestOnUiThread(new Runnable() { + @Override + public void run() { + MessagePort[] channel = mAwContents.createMessageChannel(); + channelContainer.set(channel); + channel[0].setWebEventHandler(new MessagePort.WebEventHandler() { + @Override + public void onMessage(String message) { + channelContainer.setMessage(message); + } + }, null); + mAwContents.postMessageToFrame(null, WEBVIEW_MESSAGE, mWebServer.getBaseUrl(), + new MessagePort[] {channel[1]}); + channel[0].postMessage(HELLO, null); + } + }); + channelContainer.waitForMessage(); + assertEquals(HELLO + JS_MESSAGE, channelContainer.getMessage()); + } + + // Test if WebView can post a message from/to an iframe in a popup window. + @SmallTest + @Feature({"AndroidWebView", "Android-PostMessage"}) + public void testPostMessageToIframeInsidePopup() throws Throwable { + mWebServer.setResponse(IFRAME_URL, ECHO_PAGE, null); + triggerPopup(mAwContents, mContentsClient, mWebServer, MAIN_PAGE_FOR_POPUP_TEST, + POPUP_PAGE_WITH_IFRAME, POPUP_URL, "createPopup()"); + connectPendingPopup(mAwContents); + final ChannelContainer channelContainer = new ChannelContainer(); + + runTestOnUiThread(new Runnable() { + @Override + public void run() { + MessagePort[] channel = mAwContents.createMessageChannel(); + channelContainer.set(channel); + channel[0].setWebEventHandler(new MessagePort.WebEventHandler() { + @Override + public void onMessage(String message) { + channelContainer.setMessage(message); + } + }, null); + mAwContents.postMessageToFrame(null, WEBVIEW_MESSAGE, mWebServer.getBaseUrl(), + new MessagePort[] {channel[1]}); + channel[0].postMessage(HELLO, null); + } + }); + channelContainer.waitForMessage(); + assertEquals(HELLO + JS_MESSAGE, channelContainer.getMessage()); + } }
diff --git a/android_webview/native/aw_autofill_client.cc b/android_webview/native/aw_autofill_client.cc index c0427fa..b9210e5e 100644 --- a/android_webview/native/aw_autofill_client.cc +++ b/android_webview/native/aw_autofill_client.cc
@@ -199,7 +199,7 @@ NOTIMPLEMENTED(); } -void AwAutofillClient::OnUnmaskVerificationResult(bool success) { +void AwAutofillClient::OnUnmaskVerificationResult(GetRealPanResult result) { NOTIMPLEMENTED(); }
diff --git a/android_webview/native/aw_autofill_client.h b/android_webview/native/aw_autofill_client.h index 9881f8d..d8e4651 100644 --- a/android_webview/native/aw_autofill_client.h +++ b/android_webview/native/aw_autofill_client.h
@@ -65,7 +65,7 @@ void ShowUnmaskPrompt( const autofill::CreditCard& card, base::WeakPtr<autofill::CardUnmaskDelegate> delegate) override; - void OnUnmaskVerificationResult(bool success) override; + void OnUnmaskVerificationResult(GetRealPanResult result) override; void ConfirmSaveCreditCard(const base::Closure& save_card_callback) override; bool HasCreditCardScanFeature() override; void ScanCreditCard(const CreditCardScanCallback& callback) override;
diff --git a/ash/BUILD.gn b/ash/BUILD.gn index ed4cd13..7db48e06 100644 --- a/ash/BUILD.gn +++ b/ash/BUILD.gn
@@ -352,48 +352,46 @@ } } -if (!is_win || link_chrome_on_windows) { - executable("ash_shell") { - testonly = true - sources = [ - "shell/shell_main.cc", - ] +executable("ash_shell") { + testonly = true + sources = [ + "shell/shell_main.cc", + ] - deps = [ - ":ash_shell_lib", - "//components/user_manager", - ] + deps = [ + ":ash_shell_lib", + "//components/user_manager", + ] - if (is_win) { - configs -= [ "//build/config/win:console" ] - configs += [ "//build/config/win:windowed" ] - deps += [ "//sandbox" ] - } - - if (is_chromeos) { - deps += [ "//device/bluetooth" ] - } + if (is_win) { + configs -= [ "//build/config/win:console" ] + configs += [ "//build/config/win:windowed" ] + deps += [ "//sandbox" ] } - test("ash_shell_unittests") { - sources = [ - "shell/window_watcher_unittest.cc", - "test/ash_unittests.cc", - ] + if (is_chromeos) { + deps += [ "//device/bluetooth" ] + } +} - deps = [ - ":ash_shell_lib", - ":test_support", - "//base/test:test_support", - "//components/user_manager", - "//content/test:test_support", - "//skia", - "//testing/gtest", - "//ui/accessibility", - ] +test("ash_shell_unittests") { + sources = [ + "shell/window_watcher_unittest.cc", + "test/ash_unittests.cc", + ] - if (is_chromeos) { - deps += [ "//ui/display" ] - } + deps = [ + ":ash_shell_lib", + ":test_support", + "//base/test:test_support", + "//components/user_manager", + "//content/test:test_support", + "//skia", + "//testing/gtest", + "//ui/accessibility", + ] + + if (is_chromeos) { + deps += [ "//ui/display" ] } }
diff --git a/ash/ash_switches.cc b/ash/ash_switches.cc index a50a1ae..f11743dd 100644 --- a/ash/ash_switches.cc +++ b/ash/ash_switches.cc
@@ -64,10 +64,6 @@ // Enables software based mirroring. const char kAshEnableSoftwareMirroring[] = "ash-enable-software-mirroring"; -// Enables gesture swipe to close windows while in Overview mode. -const char kAshEnableSwipeToCloseInOverviewMode[] = - "ash-enable-swipe-to-close-in-overview-mode"; - // Enables touch view testing. // TODO(skuhne): Remove TOGGLE_TOUCH_VIEW_TESTING accelerator once this // flag is removed.
diff --git a/ash/ash_switches.h b/ash/ash_switches.h index 2442aff..4edb61e 100644 --- a/ash/ash_switches.h +++ b/ash/ash_switches.h
@@ -33,7 +33,6 @@ ASH_EXPORT extern const char kAshEnableMirroredScreen[]; ASH_EXPORT extern const char kAshEnablePowerButtonQuickLock[]; ASH_EXPORT extern const char kAshEnableSoftwareMirroring[]; -ASH_EXPORT extern const char kAshEnableSwipeToCloseInOverviewMode[]; ASH_EXPORT extern const char kAshEnableSystemSounds[]; ASH_EXPORT extern const char kAshEnableTouchViewTesting[]; ASH_EXPORT extern const char kAshHideNotificationsForFactory[];
diff --git a/ash/display/display_controller.cc b/ash/display/display_controller.cc index 7a3b6f9..5d5144b 100644 --- a/ash/display/display_controller.cc +++ b/ash/display/display_controller.cc
@@ -39,6 +39,7 @@ #include "ui/compositor/compositor_vsync_manager.h" #include "ui/gfx/display.h" #include "ui/gfx/screen.h" +#include "ui/wm/core/coordinate_conversion.h" #include "ui/wm/public/activation_client.h" #if defined(OS_CHROMEOS) @@ -266,6 +267,7 @@ focus_activation_store_(new FocusActivationStore()), cursor_window_controller_(new CursorWindowController()), mirror_window_controller_(new MirrorWindowController()), + cursor_display_id_for_restore_(gfx::Display::kInvalidDisplayID), weak_ptr_factory_(this) { #if defined(OS_CHROMEOS) if (base::SysInfo::IsRunningOnChromeOS()) @@ -569,18 +571,44 @@ if (closest_distance_squared < 0 || closest_distance_squared > distance_squared) { aura::Window* root_window = GetRootWindowForDisplayId(display.id()); - aura::client::ScreenPositionClient* client = - aura::client::GetScreenPositionClient(root_window); - client->ConvertPointFromScreen(root_window, ¢er); + ::wm::ConvertPointFromScreen(root_window, ¢er); root_window->GetHost()->ConvertPointToNativeScreen(¢er); dst_root_window = root_window; target_location_in_native = center; closest_distance_squared = distance_squared; } } + + gfx::Point target_location_in_root = target_location_in_native; dst_root_window->GetHost()->ConvertPointFromNativeScreen( - &target_location_in_native); - dst_root_window->MoveCursorTo(target_location_in_native); + &target_location_in_root); + +#if defined(USE_OZONE) + gfx::Point target_location_in_screen = target_location_in_root; + ::wm::ConvertPointToScreen(dst_root_window, &target_location_in_screen); + int64 target_display_id = + display_manager->FindDisplayContainingPoint(target_location_in_screen) + .id(); + + // Do not move the cursor if the cursor's location did not change. This avoids + // moving (and showing) the cursor on startup. + // - |cursor_location_in_screen_coords_for_restore_| is checked to ensure that + // the cursor is moved when the cursor's native position does not change but + // the scale factor or rotation of the display it is on have changed. + // - |cursor_display_id_for_restore_| is checked to ensure that the cursor is + // moved when the cursor's native position and screen position do not change + // but the display that it is on has changed. This occurs when swapping the + // primary display. + if (target_location_in_native != + cursor_location_in_native_coords_for_restore_ || + target_location_in_screen != + cursor_location_in_screen_coords_for_restore_ || + target_display_id != cursor_display_id_for_restore_) { + dst_root_window->MoveCursorTo(target_location_in_root); + } +#else + dst_root_window->MoveCursorTo(target_location_in_root); +#endif } bool DisplayController::UpdateWorkAreaOfDisplayNearestWindow( @@ -713,14 +741,16 @@ focus_activation_store_->Store(clear_focus); gfx::Screen* screen = Shell::GetScreen(); gfx::Point point_in_screen = screen->GetCursorScreenPoint(); - gfx::Display display = screen->GetDisplayNearestPoint(point_in_screen); - aura::Window* root_window = GetRootWindowForDisplayId(display.id()); + cursor_location_in_screen_coords_for_restore_ = point_in_screen; - aura::client::ScreenPositionClient* client = - aura::client::GetScreenPositionClient(root_window); - client->ConvertPointFromScreen(root_window, &point_in_screen); - root_window->GetHost()->ConvertPointToNativeScreen(&point_in_screen); - cursor_location_in_native_coords_for_restore_ = point_in_screen; + gfx::Display display = screen->GetDisplayNearestPoint(point_in_screen); + cursor_display_id_for_restore_ = display.id(); + + gfx::Point point_in_native = point_in_screen; + aura::Window* root_window = GetRootWindowForDisplayId(display.id()); + ::wm::ConvertPointFromScreen(root_window, &point_in_native); + root_window->GetHost()->ConvertPointToNativeScreen(&point_in_native); + cursor_location_in_native_coords_for_restore_ = point_in_native; } void DisplayController::PostDisplayConfigurationChange() {
diff --git a/ash/display/display_controller.h b/ash/display/display_controller.h index 73822e85..d9b2d63 100644 --- a/ash/display/display_controller.h +++ b/ash/display/display_controller.h
@@ -211,10 +211,16 @@ scoped_ptr<CursorWindowController> cursor_window_controller_; scoped_ptr<MirrorWindowController> mirror_window_controller_; - // Stores the curent cursor location (in native coordinates) used to - // restore the cursor location when display configuration - // changed. + // Stores the current cursor location (in native coordinates and screen + // coordinates respectively). The locations are used to restore the cursor + // location when the display configuration changes and to determine whether + // the mouse should be moved after a display configuration change. gfx::Point cursor_location_in_native_coords_for_restore_; + gfx::Point cursor_location_in_screen_coords_for_restore_; + + // Stores the cursor's display. The id is used to determine whether the mouse + // should be moved after a display configuration change. + int64 cursor_display_id_for_restore_; base::WeakPtrFactory<DisplayController> weak_ptr_factory_;
diff --git a/ash/touch/touch_transformer_controller.cc b/ash/touch/touch_transformer_controller.cc index aa6475b..d88416e 100644 --- a/ash/touch/touch_transformer_controller.cc +++ b/ash/touch/touch_transformer_controller.cc
@@ -204,8 +204,8 @@ RootWindowController::ForWindow(root)->ash_host()->UpdateDisplayID( display1_id, display2_id); DisplayInfo source_display = - gfx::Display::InternalDisplayId() == display1_id ? - display1 : display2; + display_controller->GetPrimaryDisplayId() == display1_id ? display1 + : display2; // Mapping from framebuffer size to the source display's native // resolution. device_manager->UpdateTouchInfoForDisplay(
diff --git a/ash/virtual_keyboard_controller.cc b/ash/virtual_keyboard_controller.cc index 3ecc0bc2..2f46e5c 100644 --- a/ash/virtual_keyboard_controller.cc +++ b/ash/virtual_keyboard_controller.cc
@@ -50,13 +50,19 @@ } void VirtualKeyboardController::OnMaximizeModeStarted() { - if (!IsSmartVirtualKeyboardEnabled()) + if (!IsSmartVirtualKeyboardEnabled()) { SetKeyboardEnabled(true); + } else { + UpdateKeyboardEnabled(); + } } void VirtualKeyboardController::OnMaximizeModeEnded() { - if (!IsSmartVirtualKeyboardEnabled()) + if (!IsSmartVirtualKeyboardEnabled()) { SetKeyboardEnabled(false); + } else { + UpdateKeyboardEnabled(); + } } void VirtualKeyboardController::OnTouchscreenDeviceConfigurationChanged() { @@ -103,11 +109,16 @@ ->IsMaximizeModeWindowManagerEnabled()); return; } - SetKeyboardEnabled(!has_internal_keyboard_ && has_touchscreen_ && + bool ignore_internal_keyboard = Shell::GetInstance() + ->maximize_mode_controller() + ->IsMaximizeModeWindowManagerEnabled(); + bool is_internal_keyboard_active = + has_internal_keyboard_ && !ignore_internal_keyboard; + SetKeyboardEnabled(!is_internal_keyboard_active && has_touchscreen_ && (!has_external_keyboard_ || ignore_external_keyboard_)); ash::Shell::GetInstance() ->system_tray_notifier() - ->NotifyVirtualKeyboardSuppressionChanged(!has_internal_keyboard_ && + ->NotifyVirtualKeyboardSuppressionChanged(!is_internal_keyboard_active && has_touchscreen_ && has_external_keyboard_); }
diff --git a/ash/virtual_keyboard_controller_unittest.cc b/ash/virtual_keyboard_controller_unittest.cc index f3d169b..7ca7a2a 100644 --- a/ash/virtual_keyboard_controller_unittest.cc +++ b/ash/virtual_keyboard_controller_unittest.cc
@@ -154,7 +154,7 @@ }; // Tests that the onscreen keyboard is disabled if an internal keyboard is -// present. +// present and maximized mode is disabled. TEST_F(VirtualKeyboardControllerAutoTest, DisabledIfInternalKeyboardPresent) { std::vector<ui::TouchscreenDevice> screens; screens.push_back(ui::TouchscreenDevice( @@ -235,6 +235,79 @@ ASSERT_FALSE(keyboard::IsKeyboardEnabled()); } +// Tests maximized mode interaction without disabling the internal keyboard. +TEST_F(VirtualKeyboardControllerAutoTest, EnabledDuringMaximizeMode) { + std::vector<ui::TouchscreenDevice> screens; + screens.push_back(ui::TouchscreenDevice( + 1, ui::InputDeviceType::INPUT_DEVICE_INTERNAL, gfx::Size(1024, 768), 0)); + UpdateTouchscreenDevices(screens); + std::vector<ui::KeyboardDevice> keyboards; + keyboards.push_back( + ui::KeyboardDevice(1, ui::InputDeviceType::INPUT_DEVICE_INTERNAL)); + UpdateKeyboardDevices(keyboards); + ASSERT_FALSE(keyboard::IsKeyboardEnabled()); + // Toggle maximized mode on. + Shell::GetInstance() + ->maximize_mode_controller() + ->EnableMaximizeModeWindowManager(true); + ASSERT_TRUE(keyboard::IsKeyboardEnabled()); + // Toggle maximized mode off. + Shell::GetInstance() + ->maximize_mode_controller() + ->EnableMaximizeModeWindowManager(false); + ASSERT_FALSE(keyboard::IsKeyboardEnabled()); +} + +// Tests that keyboard gets suppressed in maximized mode. +TEST_F(VirtualKeyboardControllerAutoTest, SuppressedInMaximizedMode) { + std::vector<ui::TouchscreenDevice> screens; + screens.push_back(ui::TouchscreenDevice( + 1, ui::InputDeviceType::INPUT_DEVICE_INTERNAL, gfx::Size(1024, 768), 0)); + UpdateTouchscreenDevices(screens); + std::vector<ui::KeyboardDevice> keyboards; + keyboards.push_back( + ui::KeyboardDevice(1, ui::InputDeviceType::INPUT_DEVICE_INTERNAL)); + keyboards.push_back( + ui::KeyboardDevice(2, ui::InputDeviceType::INPUT_DEVICE_EXTERNAL)); + UpdateKeyboardDevices(keyboards); + // Toggle maximized mode on. + Shell::GetInstance() + ->maximize_mode_controller() + ->EnableMaximizeModeWindowManager(true); + ASSERT_FALSE(keyboard::IsKeyboardEnabled()); + ASSERT_TRUE(notified()); + ASSERT_TRUE(IsVirtualKeyboardSuppressed()); + // Toggle show keyboard. Keyboard should be visible. + ResetObserver(); + Shell::GetInstance() + ->virtual_keyboard_controller() + ->ToggleIgnoreExternalKeyboard(); + ASSERT_TRUE(keyboard::IsKeyboardEnabled()); + ASSERT_TRUE(notified()); + ASSERT_TRUE(IsVirtualKeyboardSuppressed()); + // Toggle show keyboard. Keyboard should be hidden. + ResetObserver(); + Shell::GetInstance() + ->virtual_keyboard_controller() + ->ToggleIgnoreExternalKeyboard(); + ASSERT_FALSE(keyboard::IsKeyboardEnabled()); + ASSERT_TRUE(notified()); + ASSERT_TRUE(IsVirtualKeyboardSuppressed()); + // Remove external keyboard. Should be notified that the keyboard is not + // suppressed. + ResetObserver(); + keyboards.pop_back(); + UpdateKeyboardDevices(keyboards); + ASSERT_TRUE(keyboard::IsKeyboardEnabled()); + ASSERT_TRUE(notified()); + ASSERT_FALSE(IsVirtualKeyboardSuppressed()); + // Toggle maximized mode oFF. + Shell::GetInstance() + ->maximize_mode_controller() + ->EnableMaximizeModeWindowManager(false); + ASSERT_FALSE(keyboard::IsKeyboardEnabled()); +} + class VirtualKeyboardControllerAlwaysEnabledTest : public VirtualKeyboardControllerAutoTest { public:
diff --git a/ash/wm/overview/overview_animation_type.h b/ash/wm/overview/overview_animation_type.h index 5df51cb..dde3a15 100644 --- a/ash/wm/overview/overview_animation_type.h +++ b/ash/wm/overview/overview_animation_type.h
@@ -14,8 +14,6 @@ OVERVIEW_ANIMATION_NONE, // Used to fade in the close button and label. OVERVIEW_ANIMATION_ENTER_OVERVIEW_MODE_FADE_IN, - // Used to fade out the close button. - OVERVIEW_ANIMATION_ENTER_OVERVIEW_MODE_FADE_OUT, // Used to position windows when entering/exiting overview mode and when a // window is closed while overview mode is active. OVERVIEW_ANIMATION_LAY_OUT_SELECTOR_ITEMS, @@ -23,12 +21,7 @@ OVERVIEW_ANIMATION_HIDE_WINDOW, // Used to restore windows to their original position when exiting overview // mode. - OVERVIEW_ANIMATION_RESTORE_WINDOW, - // Used to animate windows when a user performs a touch drag gesture. - OVERVIEW_ANIMATION_SCROLL_SELECTOR_ITEM, - // Used to animate windows back in to position when a touch drag gesture is - // cancelled. - OVERVIEW_ANIMATION_CANCEL_SELECTOR_ITEM_SCROLL + OVERVIEW_ANIMATION_RESTORE_WINDOW }; } // namespace ash
diff --git a/ash/wm/overview/scoped_overview_animation_settings.cc b/ash/wm/overview/scoped_overview_animation_settings.cc index 3cb6bcb..e0cf977 100644 --- a/ash/wm/overview/scoped_overview_animation_settings.cc +++ b/ash/wm/overview/scoped_overview_animation_settings.cc
@@ -20,22 +20,15 @@ // The time duration for widgets to fade in. const int kFadeInMilliseconds = 80; -// The time duration for widgets to fade out. -const int kFadeOutMilliseconds = 100; - base::TimeDelta GetAnimationDuration(OverviewAnimationType animation_type) { switch (animation_type) { case OVERVIEW_ANIMATION_NONE: - case OVERVIEW_ANIMATION_SCROLL_SELECTOR_ITEM: return base::TimeDelta(); case OVERVIEW_ANIMATION_ENTER_OVERVIEW_MODE_FADE_IN: return base::TimeDelta::FromMilliseconds(kFadeInMilliseconds); - case OVERVIEW_ANIMATION_ENTER_OVERVIEW_MODE_FADE_OUT: - return base::TimeDelta::FromMilliseconds(kFadeOutMilliseconds); case OVERVIEW_ANIMATION_LAY_OUT_SELECTOR_ITEMS: case OVERVIEW_ANIMATION_RESTORE_WINDOW: case OVERVIEW_ANIMATION_HIDE_WINDOW: - case OVERVIEW_ANIMATION_CANCEL_SELECTOR_ITEM_SCROLL: return base::TimeDelta::FromMilliseconds(kTransitionMilliseconds); } NOTREACHED(); @@ -51,7 +44,6 @@ switch (animation_type) { case OVERVIEW_ANIMATION_NONE: - case OVERVIEW_ANIMATION_SCROLL_SELECTOR_ITEM: animation_settings_.SetPreemptionStrategy( ui::LayerAnimator::REPLACE_QUEUED_ANIMATIONS); break; @@ -63,10 +55,6 @@ animation_settings_.SetPreemptionStrategy( ui::LayerAnimator::REPLACE_QUEUED_ANIMATIONS); break; - case OVERVIEW_ANIMATION_ENTER_OVERVIEW_MODE_FADE_OUT: - animation_settings_.SetPreemptionStrategy( - ui::LayerAnimator::REPLACE_QUEUED_ANIMATIONS); - break; case OVERVIEW_ANIMATION_LAY_OUT_SELECTOR_ITEMS: case OVERVIEW_ANIMATION_RESTORE_WINDOW: animation_settings_.SetPreemptionStrategy( @@ -77,11 +65,6 @@ animation_settings_.SetPreemptionStrategy( ui::LayerAnimator::IMMEDIATELY_ANIMATE_TO_NEW_TARGET); break; - case OVERVIEW_ANIMATION_CANCEL_SELECTOR_ITEM_SCROLL: - animation_settings_.SetPreemptionStrategy( - ui::LayerAnimator::IMMEDIATELY_ANIMATE_TO_NEW_TARGET); - animation_settings_.SetTweenType(gfx::Tween::EASE_IN_OUT); - break; } animation_settings_.SetTransitionDuration( GetAnimationDuration(animation_type));
diff --git a/ash/wm/overview/window_selector_controller.cc b/ash/wm/overview/window_selector_controller.cc index 6f21c8f..df14d27 100644 --- a/ash/wm/overview/window_selector_controller.cc +++ b/ash/wm/overview/window_selector_controller.cc
@@ -6,7 +6,6 @@ #include <vector> -#include "ash/ash_switches.h" #include "ash/metrics/user_metrics_recorder.h" #include "ash/root_window_controller.h" #include "ash/session/session_state_delegate.h" @@ -16,15 +15,12 @@ #include "ash/wm/overview/window_selector.h" #include "ash/wm/window_state.h" #include "ash/wm/window_util.h" -#include "base/command_line.h" #include "base/metrics/histogram.h" #include "ui/aura/window.h" namespace ash { -WindowSelectorController::WindowSelectorController() - : swipe_to_close_enabled_(base::CommandLine::ForCurrentProcess()->HasSwitch( - switches::kAshEnableSwipeToCloseInOverviewMode)) { +WindowSelectorController::WindowSelectorController() { } WindowSelectorController::~WindowSelectorController() {
diff --git a/ash/wm/overview/window_selector_controller.h b/ash/wm/overview/window_selector_controller.h index 518d05de..8d4a625 100644 --- a/ash/wm/overview/window_selector_controller.h +++ b/ash/wm/overview/window_selector_controller.h
@@ -48,8 +48,6 @@ // are visible during overview mode. bool IsRestoringMinimizedWindows() const; - bool swipe_to_close_enabled() const { return swipe_to_close_enabled_; } - // WindowSelectorDelegate: void OnSelectionEnded() override; @@ -62,9 +60,6 @@ scoped_ptr<WindowSelector> window_selector_; base::Time last_selection_time_; - // Tracks whether the "Swipe-to-close" feature is enabled. - bool swipe_to_close_enabled_; - DISALLOW_COPY_AND_ASSIGN(WindowSelectorController); };
diff --git a/ash/wm/overview/window_selector_item.cc b/ash/wm/overview/window_selector_item.cc index 7e74caf..f3e8eca2 100644 --- a/ash/wm/overview/window_selector_item.cc +++ b/ash/wm/overview/window_selector_item.cc
@@ -37,13 +37,6 @@ namespace { -// The minimum fling velocity which will cause a window to be closed. Unit is -// pixels per second. -const float kMinimumFlingVelocity = 4000.0f; - -// The minimum opacity used during touch scroll gestures. -const float kMinimumOpacity = 0.2f; - // In the conceptual overview table, the window margin is the space reserved // around the window within the cell. This margin does not overlap so the // closest distance between adjacent windows will be twice this amount. @@ -91,24 +84,6 @@ layer->SetOpacity(1.0f); } -// Convenience method to fade out a window using the animation settings defined -// by OverviewAnimationType::OVERVIEW_ANIMATION_ENTER_OVERVIEW_MODE_FADE_OUT. -void SetupFadeOut(aura::Window* window) { - ScopedOverviewAnimationSettings animation_settings( - OverviewAnimationType::OVERVIEW_ANIMATION_ENTER_OVERVIEW_MODE_FADE_OUT, - window); - window->layer()->SetOpacity(0.0f); -} - -// Calculates the window opacity from the given scroll |distance| and the -// |min opacity_distance|. -float CalculateOpacityFromScrollDistance(int distance, - int min_opacity_distance) { - float opacity = - 1.0f - static_cast<float>(abs(distance)) / min_opacity_distance; - return std::min(1.0f, std::max(kMinimumOpacity, opacity)); -} - // An image button with a close window icon. class OverviewCloseButton : public views::ImageButton { public: @@ -136,10 +111,9 @@ } // namespace WindowSelectorItem::OverviewLabelButton::OverviewLabelButton( - WindowSelectorItem* selector_item, + views::ButtonListener* listener, const base::string16& text) - : LabelButton(selector_item, text), - selector_item_(selector_item), + : LabelButton(listener, text), top_padding_(0) { } @@ -152,12 +126,6 @@ return bounds; } -void WindowSelectorItem::OverviewLabelButton::OnGestureEvent( - ui::GestureEvent* event) { - selector_item_->OnGestureEvent(event); - views::LabelButton::OnGestureEvent(event); -} - WindowSelectorItem::WindowSelectorItem(aura::Window* window) : dimmed_(false), root_window_(window->GetRootWindow()), @@ -260,72 +228,6 @@ wm::GetWindowState(transform_window_.window())->Activate(); } -void WindowSelectorItem::OnGestureEvent(ui::GestureEvent* event) { - if (!Shell::GetInstance() - ->window_selector_controller() - ->swipe_to_close_enabled()) - return; - - int delta_x = 0; - if (event->type() == ui::ET_GESTURE_SCROLL_BEGIN) - scroll_x_origin_ = event->x(); - else - delta_x = event->x() - scroll_x_origin_; - - switch (event->type()) { - case ui::ET_GESTURE_SCROLL_BEGIN: { - // We need to call SetHandled() for the ET_GESTURE_SCROLL_BEGIN event so - // that future ET_GESTURE_SCROLL_* events are sent here. - event->SetHandled(); - close_button_->SetEnabled(false); - SetupFadeOut(close_button_widget_.GetNativeWindow()); - break; - } - case ui::ET_GESTURE_SCROLL_UPDATE: { - event->SetHandled(); - ScopedTransformOverviewWindow::ScopedAnimationSettings animation_settings; - transform_window_.BeginScopedAnimation( - OverviewAnimationType::OVERVIEW_ANIMATION_SCROLL_SELECTOR_ITEM, - &animation_settings); - - gfx::Transform new_transform; - new_transform.Translate(delta_x, 0); - new_transform.PreconcatTransform( - transform_window_.get_overview_transform()); - transform_window_.SetTransform(root_window(), new_transform); - - const float opacity = CalculateOpacityFromScrollDistance( - delta_x, GetMinimumCloseDistance()); - transform_window_.SetOpacity(opacity); - break; - } - case ui::ET_GESTURE_SCROLL_END: { - event->SetHandled(); - if (abs(delta_x) > GetMinimumCloseDistance()) { - transform_window_.Close(); - break; - } - ResetScrolledWindow(); - break; - } - case ui::ET_SCROLL_FLING_START: { - event->SetHandled(); - if (abs(delta_x) > GetMinimumCloseDistance() || - fabs(event->details().velocity_x()) > kMinimumFlingVelocity) { - transform_window_.Close(); - break; - } - ResetScrolledWindow(); - break; - } - case ui::ET_GESTURE_END: - scroll_x_origin_ = 0; - break; - default: - break; - } -} - void WindowSelectorItem::OnWindowDestroying(aura::Window* window) { window->RemoveObserver(this); transform_window_.OnWindowDestroyed(); @@ -338,20 +240,6 @@ UpdateCloseButtonAccessibilityName(); } -void WindowSelectorItem::ResetScrolledWindow() { - ScopedTransformOverviewWindow::ScopedAnimationSettings animation_settings; - transform_window_.BeginScopedAnimation( - OverviewAnimationType::OVERVIEW_ANIMATION_CANCEL_SELECTOR_ITEM_SCROLL, - &animation_settings); - - transform_window_.SetTransform(root_window(), - transform_window_.get_overview_transform()); - transform_window_.SetOpacity(1.0); - - SetupFadeInAfterLayout(close_button_widget_.GetNativeWindow()); - close_button_->SetEnabled(true); -} - void WindowSelectorItem::SetItemBounds(const gfx::Rect& target_bounds, OverviewAnimationType animation_type) { DCHECK(root_window_ == GetWindow()->GetRootWindow()); @@ -456,8 +344,4 @@ GetWindow()->title())); } -int WindowSelectorItem::GetMinimumCloseDistance() const { - return target_bounds_.size().width() / 2; -} - } // namespace ash
diff --git a/ash/wm/overview/window_selector_item.h b/ash/wm/overview/window_selector_item.h index 0e4aa8fa..063b141e 100644 --- a/ash/wm/overview/window_selector_item.h +++ b/ash/wm/overview/window_selector_item.h
@@ -33,25 +33,18 @@ public: class OverviewLabelButton : public views::LabelButton { public: - OverviewLabelButton(WindowSelectorItem* selector_item, + OverviewLabelButton(views::ButtonListener* listener, const base::string16& text); ~OverviewLabelButton() override; void set_top_padding(int top_padding) { top_padding_ = top_padding; } - // views::LabelButton: - void OnGestureEvent(ui::GestureEvent* event) override; - protected: // views::LabelButton: gfx::Rect GetChildAreaBounds() override; private: - // The WindowSelectorItem that the touch gestures are delegated to. - // Not owned. - WindowSelectorItem* selector_item_; - // Padding on top of the button. int top_padding_; @@ -101,9 +94,6 @@ const gfx::Rect& target_bounds() const { return target_bounds_; } - // Handles the gestures on the Window - void OnGestureEvent(ui::GestureEvent* event); - // views::ButtonListener: void ButtonPressed(views::Button* sender, const ui::Event& event) override; @@ -137,14 +127,6 @@ // Updates the close buttons accessibility name. void UpdateCloseButtonAccessibilityName(); - // Animates the |transform_window_| back to it's original overview mode - // position. - void ResetScrolledWindow(); - - // Returns the minimum distance at which a scroll gesture will cause this - // selector item to be closed. - int GetMinimumCloseDistance() const; - // True if the item is being shown in the overview, false if it's being // filtered. bool dimmed_; @@ -176,10 +158,6 @@ // close_button_widget_. views::ImageButton* close_button_; - // The original X location for a scroll begin event. |original_x_| is in the - // local coordinate space of |window_label_button_view_|. - float scroll_x_origin_; - DISALLOW_COPY_AND_ASSIGN(WindowSelectorItem); };
diff --git a/ash/wm/overview/window_selector_unittest.cc b/ash/wm/overview/window_selector_unittest.cc index ec60952..5ebf669 100644 --- a/ash/wm/overview/window_selector_unittest.cc +++ b/ash/wm/overview/window_selector_unittest.cc
@@ -3,11 +3,9 @@ // found in the LICENSE file. #include <algorithm> -#include <map> #include <vector> #include "ash/accessibility_delegate.h" -#include "ash/ash_switches.h" #include "ash/drag_drop/drag_drop_controller.h" #include "ash/root_window_controller.h" #include "ash/screen_util.h" @@ -73,18 +71,6 @@ } } -// A short drag distance that will not cause an overview item to close. -const int kShortDragDistance = 10; - -// A far drag distance that will cause an overview item to close. -const int kFarDragDistance = 200; - -// A slow fling velocity that should not cause selctor items to close. -const int kSlowFlingVelocity = 2000; - -// A fast fling velocity that should cause selector items to close. -const int kFastFlingVelocity = 5000; - } // namespace // TODO(bruthig): Move all non-simple method definitions out of class @@ -279,24 +265,6 @@ DISALLOW_COPY_AND_ASSIGN(WindowSelectorTest); }; -class WindowSelectorSwipeToCloseEnabledTest : public WindowSelectorTest { - public: - WindowSelectorSwipeToCloseEnabledTest() {} - ~WindowSelectorSwipeToCloseEnabledTest() override {} - - // WindowSelectorTest: - void SetUp() override; - - private: - DISALLOW_COPY_AND_ASSIGN(WindowSelectorSwipeToCloseEnabledTest); -}; - -void WindowSelectorSwipeToCloseEnabledTest::SetUp() { - base::CommandLine::ForCurrentProcess()->AppendSwitch( - switches::kAshEnableSwipeToCloseInOverviewMode); - WindowSelectorTest::SetUp(); -} - // Tests that an a11y alert is sent on entering overview mode. TEST_F(WindowSelectorTest, A11yAlertOnOverviewMode) { gfx::Rect bounds(0, 0, 400, 400); @@ -1274,210 +1242,4 @@ EXPECT_FALSE(IsSelecting()); } -// Verify swipe to close doesn't work when swipe to close is not enabled. -TEST_F(WindowSelectorTest, WindowTapDragFarDistance) { - scoped_ptr<views::Widget> widget = - CreateWindowWidget(gfx::Rect(0, 0, 400, 400)); - - ToggleOverview(); - ASSERT_TRUE(IsSelecting()); - - aura::Window* window = widget->GetNativeWindow(); - gfx::Rect bounds = ToNearestRect(GetTransformedBoundsInRootWindow(window)); - ui::test::EventGenerator event_generator(window->GetRootWindow()); - - ASSERT_FALSE(widget->IsClosed()); - - gfx::Point start(bounds.CenterPoint()); - gfx::Point end(start.x() - kFarDragDistance, start.y()); - event_generator.GestureScrollSequence( - start, end, base::TimeDelta::FromMilliseconds(10), 5); - - EXPECT_FALSE(widget->IsClosed()); - - RunAllPendingInMessageLoop(); - EXPECT_TRUE(IsSelecting()); -} - -// Verify the window moves and fades as it is dragged. -TEST_F(WindowSelectorSwipeToCloseEnabledTest, - VerifyWindowBehaviourDuringTapDrag) { - scoped_ptr<aura::Window> window(CreateWindow(gfx::Rect(0, 0, 400, 400))); - - ToggleOverview(); - - gfx::Rect bounds = - ToNearestRect(GetTransformedBoundsInRootWindow(window.get())); - ui::test::EventGenerator event_generator(window->GetRootWindow()); - - const gfx::Point drag_start_point(bounds.CenterPoint()); - const gfx::Point drag_left_point(drag_start_point.x() - kFarDragDistance, - drag_start_point.y()); - const gfx::Point drag_right_point(drag_start_point.x() + kFarDragDistance, - drag_start_point.y()); - - const int drag_left_delta_x = drag_start_point.x() - drag_left_point.x(); - const int drag_right_delta_x = drag_start_point.x() - drag_right_point.x(); - - const gfx::Rect original_bounds = window->GetBoundsInScreen(); - - ASSERT_EQ(1.0f, window->layer()->opacity()); - - event_generator.set_current_location(drag_start_point); - event_generator.PressTouch(); - - EXPECT_EQ(1.0f, window->layer()->opacity()); - - event_generator.MoveTouch(drag_left_point); - - EXPECT_EQ(original_bounds.x() - drag_left_delta_x, - window->GetBoundsInScreen().x()); - EXPECT_EQ(original_bounds.y(), window->GetBoundsInScreen().y()); - - EXPECT_LT(window->layer()->opacity(), 0.5f); - - event_generator.MoveTouch(drag_start_point); - - EXPECT_EQ(original_bounds.x(), window->GetBoundsInScreen().x()); - EXPECT_EQ(original_bounds.y(), window->GetBoundsInScreen().y()); - EXPECT_EQ(1.0f, window->layer()->opacity()); - - event_generator.MoveTouch(drag_right_point); - - EXPECT_EQ(original_bounds.x() - drag_right_delta_x, - window->GetBoundsInScreen().x()); - EXPECT_EQ(original_bounds.y(), window->GetBoundsInScreen().y()); - - EXPECT_LT(window->layer()->opacity(), 0.5f); -} - -// Test dragging a window a short distance. -TEST_F(WindowSelectorSwipeToCloseEnabledTest, WindowTapDragShortDistance) { - scoped_ptr<views::Widget> widget = - CreateWindowWidget(gfx::Rect(0, 0, 400, 400)); - - ToggleOverview(); - - aura::Window* window = widget->GetNativeWindow(); - gfx::Rect bounds = ToNearestRect(GetTransformedBoundsInRootWindow(window)); - ui::test::EventGenerator event_generator(window->GetRootWindow()); - - ASSERT_FALSE(widget->IsClosed()); - - gfx::Point start(bounds.CenterPoint()); - gfx::Point end(start.x() - kShortDragDistance, start.y()); - event_generator.GestureScrollSequence( - start, end, base::TimeDelta::FromMilliseconds(10), 5); - - EXPECT_FALSE(widget->IsClosed()); - - RunAllPendingInMessageLoop(); - EXPECT_TRUE(IsSelecting()); -} - -// Test dragging a window a far distance. -TEST_F(WindowSelectorSwipeToCloseEnabledTest, WindowTapDragFarDistance) { - scoped_ptr<views::Widget> widget = - CreateWindowWidget(gfx::Rect(0, 0, 400, 400)); - - ToggleOverview(); - ASSERT_TRUE(IsSelecting()); - - aura::Window* window = widget->GetNativeWindow(); - gfx::Rect bounds = ToNearestRect(GetTransformedBoundsInRootWindow(window)); - ui::test::EventGenerator event_generator(window->GetRootWindow()); - - ASSERT_FALSE(widget->IsClosed()); - - gfx::Point start(bounds.CenterPoint()); - gfx::Point end(start.x() - kFarDragDistance, start.y()); - event_generator.GestureScrollSequence( - start, end, base::TimeDelta::FromMilliseconds(10), 5); - - EXPECT_TRUE(widget->IsClosed()); - - RunAllPendingInMessageLoop(); - EXPECT_FALSE(IsSelecting()); -} - -// Test a slow velocity fling. -TEST_F(WindowSelectorSwipeToCloseEnabledTest, SlowVelocityFling) { - scoped_ptr<views::Widget> widget = - CreateWindowWidget(gfx::Rect(0, 0, 400, 400)); - - ToggleOverview(); - - aura::Window* window = widget->GetNativeWindow(); - gfx::RectF bounds = GetTransformedBoundsInRootWindow(window); - ui::test::EventGenerator event_generator(window->GetRootWindow()); - - ASSERT_FALSE(widget->IsClosed()); - - gfx::Point start(bounds.CenterPoint().x(), bounds.CenterPoint().y()); - gfx::Point end(start.x() - kShortDragDistance, start.y()); - const base::TimeDelta kScrollDuration = - event_generator.CalculateScrollDurationForFlingVelocity( - start, end, kSlowFlingVelocity, 10); - event_generator.GestureScrollSequence(start, end, kScrollDuration, 10); - - EXPECT_FALSE(widget->IsClosed()); - - RunAllPendingInMessageLoop(); - EXPECT_TRUE(IsSelecting()); -} - -// Test a fast velocity fling. -TEST_F(WindowSelectorSwipeToCloseEnabledTest, FastVelocityFling) { - scoped_ptr<views::Widget> widget = - CreateWindowWidget(gfx::Rect(0, 0, 400, 400)); - - ToggleOverview(); - ASSERT_TRUE(IsSelecting()); - - aura::Window* window = widget->GetNativeWindow(); - gfx::RectF bounds = GetTransformedBoundsInRootWindow(window); - ui::test::EventGenerator event_generator(window->GetRootWindow()); - - ASSERT_FALSE(widget->IsClosed()); - - gfx::Point start(bounds.CenterPoint().x(), bounds.CenterPoint().y()); - gfx::Point end(start.x() - kShortDragDistance, start.y()); - const base::TimeDelta kScrollDuration = - event_generator.CalculateScrollDurationForFlingVelocity( - start, end, kFastFlingVelocity, 10); - event_generator.GestureScrollSequence(start, end, kScrollDuration, 10); - - EXPECT_TRUE(widget->IsClosed()); - - RunAllPendingInMessageLoop(); - EXPECT_FALSE(IsSelecting()); -} - -// Test a fast velocity fling. -TEST_F(WindowSelectorSwipeToCloseEnabledTest, SlowVelocityFlingAtAFarDistance) { - scoped_ptr<views::Widget> widget = - CreateWindowWidget(gfx::Rect(0, 0, 400, 400)); - - ToggleOverview(); - ASSERT_TRUE(IsSelecting()); - - aura::Window* window = widget->GetNativeWindow(); - gfx::RectF bounds = GetTransformedBoundsInRootWindow(window); - ui::test::EventGenerator event_generator(window->GetRootWindow()); - - ASSERT_FALSE(widget->IsClosed()); - - gfx::Point start(bounds.CenterPoint().x(), bounds.CenterPoint().y()); - gfx::Point end(start.x() - kFarDragDistance, start.y()); - const base::TimeDelta kScrollDuration = - event_generator.CalculateScrollDurationForFlingVelocity( - start, end, kSlowFlingVelocity, 10); - event_generator.GestureScrollSequence(start, end, kScrollDuration, 10); - - EXPECT_TRUE(widget->IsClosed()); - - RunAllPendingInMessageLoop(); - EXPECT_FALSE(IsSelecting()); -} - } // namespace ash
diff --git a/base/mac/sdk_forward_declarations.h b/base/mac/sdk_forward_declarations.h index 2795b19..25d937e 100644 --- a/base/mac/sdk_forward_declarations.h +++ b/base/mac/sdk_forward_declarations.h
@@ -285,6 +285,10 @@ - (NSString*)UUIDString; @end +@interface NSControl (MountainLionSDK) +@property BOOL allowsExpansionToolTips; +@end + #endif // MAC_OS_X_VERSION_10_8
diff --git a/base/memory/discardable_shared_memory.h b/base/memory/discardable_shared_memory.h index 59c5d5b5..e3b437c 100644 --- a/base/memory/discardable_shared_memory.h +++ b/base/memory/discardable_shared_memory.h
@@ -74,7 +74,7 @@ // must have been mapped via Map(). void* memory() const; - // Returns the last know usage time for DiscardableSharedMemory object. This + // Returns the last known usage time for DiscardableSharedMemory object. This // may be earlier than the "true" usage time when memory has been used by a // different process. Returns NULL time if purged. Time last_known_usage() const { return last_known_usage_; } @@ -84,7 +84,7 @@ // for two reasons; object might be locked or our last known usage timestamp // might be out of date. Last known usage time is updated to |current_time| // if locked or the actual last usage timestamp if unlocked. It is often - // neccesary to call this function twice for the object to successfully be + // necessary to call this function twice for the object to successfully be // purged. First call, updates |last_known_usage_|. Second call, successfully // purges the object using the updated |last_known_usage_|. // Note: there is no guarantee that multiple calls to this function will
diff --git a/base/trace_event/memory_dump_manager.cc b/base/trace_event/memory_dump_manager.cc index 3430169..cbed238 100644 --- a/base/trace_event/memory_dump_manager.cc +++ b/base/trace_event/memory_dump_manager.cc
@@ -6,6 +6,7 @@ #include <algorithm> +#include "base/atomic_sequence_num.h" #include "base/compiler_specific.h" #include "base/trace_event/memory_dump_provider.h" #include "base/trace_event/process_memory_dump.h" @@ -15,7 +16,27 @@ namespace trace_event { namespace { + MemoryDumpManager* g_instance_for_testing = nullptr; +const int kTraceEventNumArgs = 1; +const char* kTraceEventArgNames[] = {"dumps"}; +const unsigned char kTraceEventArgTypes[] = {TRACE_VALUE_TYPE_CONVERTABLE}; +StaticAtomicSequenceNumber g_next_guid; + +const char* DumpPointTypeToString(const DumpPointType& dump_point_type) { + switch (dump_point_type) { + case DumpPointType::TASK_BEGIN: + return "TASK_BEGIN"; + case DumpPointType::TASK_END: + return "TASK_END"; + case DumpPointType::PERIODIC_INTERVAL: + return "PERIODIC_INTERVAL"; + case DumpPointType::EXPLICITLY_TRIGGERED: + return "EXPLICITLY_TRIGGERED"; + } + NOTREACHED(); + return "UNKNOWN"; +} } // TODO(primiano): this should be smarter and should do something similar to @@ -76,13 +97,18 @@ dump_providers_enabled_.erase(it); } -void MemoryDumpManager::RequestDumpPoint(DumpPointType type) { - // TODO(primiano): this will have more logic, IPC broadcast & co. +void MemoryDumpManager::RequestDumpPoint(DumpPointType dump_point_type) { + // TODO(primiano): this will have more logic to coordinate dump points across + // multiple processes via IPC. See crbug.com/462930. + // Bail out immediately if tracing is not enabled at all. if (!UNLIKELY(subtle::NoBarrier_Load(&memory_tracing_enabled_))) return; - CreateLocalDumpPoint(); + // TODO(primiano): Make guid actually unique (cross-process) by hashing it + // with the PID. See crbug.com/462931 for details. + const uint64 guid = g_next_guid.GetNext(); + CreateLocalDumpPoint(dump_point_type, guid); } void MemoryDumpManager::BroadcastDumpRequest() { @@ -90,23 +116,28 @@ } // Creates a dump point for the current process and appends it to the trace. -void MemoryDumpManager::CreateLocalDumpPoint() { - AutoLock lock(lock_); +void MemoryDumpManager::CreateLocalDumpPoint(DumpPointType dump_point_type, + uint64 guid) { bool did_any_provider_dump = false; scoped_ptr<ProcessMemoryDump> pmd(new ProcessMemoryDump()); - for (auto it = dump_providers_enabled_.begin(); - it != dump_providers_enabled_.end();) { - MemoryDumpProvider* dump_provider = *it; - if (!dump_provider->DumpInto(pmd.get())) { - LOG(ERROR) << "The memory dumper " << dump_provider->GetFriendlyName() - << " failed, possibly due to sandboxing (crbug.com/461788), " - "disabling it for current process. Try restarting chrome " - "with the --no-sandbox switch."; - it = dump_providers_enabled_.erase(it); - } else { - did_any_provider_dump = true; - ++it; + // Serialize dump point generation so that memory dump providers don't have to + // deal with thread safety. + { + AutoLock lock(lock_); + for (auto it = dump_providers_enabled_.begin(); + it != dump_providers_enabled_.end();) { + MemoryDumpProvider* dump_provider = *it; + if (dump_provider->DumpInto(pmd.get())) { + did_any_provider_dump = true; + ++it; + } else { + LOG(ERROR) << "The memory dumper " << dump_provider->GetFriendlyName() + << " failed, possibly due to sandboxing (crbug.com/461788), " + "disabling it for current process. Try restarting chrome " + "with the --no-sandbox switch."; + it = dump_providers_enabled_.erase(it); + } } } @@ -114,9 +145,15 @@ if (!did_any_provider_dump) return; - scoped_refptr<TracedValue> value(new TracedValue()); - pmd->AsValueInto(value.get()); - // TODO(primiano): add the dump point to the trace at this point. + scoped_refptr<ConvertableToTraceFormat> event_value(new TracedValue()); + pmd->AsValueInto(static_cast<TracedValue*>(event_value.get())); + const char* const event_name = DumpPointTypeToString(dump_point_type); + + TRACE_EVENT_API_ADD_TRACE_EVENT( + TRACE_EVENT_PHASE_MEMORY_DUMP, + TraceLog::GetCategoryGroupEnabled(kTraceCategory), event_name, guid, + kTraceEventNumArgs, kTraceEventArgNames, kTraceEventArgTypes, + NULL /* arg_values */, &event_value, TRACE_EVENT_FLAG_HAS_ID); } void MemoryDumpManager::OnTraceLogEnabled() {
diff --git a/base/trace_event/memory_dump_manager.h b/base/trace_event/memory_dump_manager.h index 1a22e61..8a9b3b7e 100644 --- a/base/trace_event/memory_dump_manager.h +++ b/base/trace_event/memory_dump_manager.h
@@ -43,7 +43,7 @@ // Requests a memory dump. The dump might happen or not depending on the // filters and categories specified when enabling tracing. - void RequestDumpPoint(DumpPointType type); + void RequestDumpPoint(DumpPointType dump_point_type); // TraceLog::EnabledStateObserver implementation. void OnTraceLogEnabled() override; @@ -65,7 +65,7 @@ void BroadcastDumpRequest(); // Creates a dump point for the current process and appends it to the trace. - void CreateLocalDumpPoint(); + void CreateLocalDumpPoint(DumpPointType dump_point_type, uint64 guid); std::vector<MemoryDumpProvider*> dump_providers_registered_; // Not owned. std::vector<MemoryDumpProvider*> dump_providers_enabled_; // Not owned.
diff --git a/base/trace_event/trace_event.h b/base/trace_event/trace_event.h index e12d8f42..c30a84a 100644 --- a/base/trace_event/trace_event.h +++ b/base/trace_event/trace_event.h
@@ -1039,6 +1039,7 @@ #define TRACE_EVENT_PHASE_CREATE_OBJECT ('N') #define TRACE_EVENT_PHASE_SNAPSHOT_OBJECT ('O') #define TRACE_EVENT_PHASE_DELETE_OBJECT ('D') +#define TRACE_EVENT_PHASE_MEMORY_DUMP ('v') // Flags for changing the behavior of TRACE_EVENT_API_ADD_TRACE_EVENT. #define TRACE_EVENT_FLAG_NONE (static_cast<unsigned char>(0))
diff --git a/build/android/findbugs_filter/findbugs_known_bugs.txt b/build/android/findbugs_filter/findbugs_known_bugs.txt index 42fef18..80d7096 100644 --- a/build/android/findbugs_filter/findbugs_known_bugs.txt +++ b/build/android/findbugs_filter/findbugs_known_bugs.txt
@@ -1,3 +1,4 @@ +H B Nm: The class name org.chromium.chrome.browser.UmaUtils shadows the simple name of the superclass org.chromium.chrome.browser.metrics.UmaUtils At UmaUtils.java M M LI: Incorrect lazy initialization of static field org.chromium.chrome.browser.download.DownloadManagerService.sDownloadManagerService in org.chromium.chrome.browser.download.DownloadManagerService.getDownloadManagerService(Context) At DownloadManagerService.java M D UrF: Unread public/protected field: org.chromium.chrome.browser.document.PendingDocumentData.extraHeaders At DocumentTabModelSelector.java M D UrF: Unread public/protected field: org.chromium.chrome.browser.document.PendingDocumentData.postData At DocumentTabModelSelector.java
diff --git a/build/android/lint/suppressions.xml b/build/android/lint/suppressions.xml index 5a169c1..3214623 100644 --- a/build/android/lint/suppressions.xml +++ b/build/android/lint/suppressions.xml
@@ -79,9 +79,6 @@ </issue> <issue id="SetJavaScriptEnabled" severity="ignore"/> <issue id="UnusedResources"> - <!-- TODO(aurimas): remove suppression once crbug.com/458328 is fixed. --> - <ignore path="content/public/android/java/res/layout/validation_message_bubble.xml" /> - <!-- These files are used by chrome_shell_apk and chrome_apk targets. --> <ignore path="chrome/android/java/res/layout/accessibility_tab_switcher.xml" /> <ignore path="chrome/android/java/res/drawable/btn_back.xml" />
diff --git a/build/android/provision_devices.py b/build/android/provision_devices.py index 6b3ea1d..6d63352 100755 --- a/build/android/provision_devices.py +++ b/build/android/provision_devices.py
@@ -125,7 +125,7 @@ as_root=True) -def WipeDeviceData(device): +def WipeDeviceData(device, options): """Wipes data from device, keeping only the adb_keys for authorization. After wiping data on a device that has been authorized, adb can still @@ -139,16 +139,22 @@ """ device_authorized = device.FileExists(constants.ADB_KEYS_FILE) if device_authorized: - adb_keys = device.ReadFile(constants.ADB_KEYS_FILE, as_root=True) + adb_keys = device.ReadFile(constants.ADB_KEYS_FILE, + as_root=True).splitlines() device.RunShellCommand('wipe data', as_root=True) if device_authorized: - WriteAdbKeysFile(device, adb_keys) + adb_keys_set = set(adb_keys) + for adb_key_file in options.adb_key_files or []: + with open(adb_key_file, 'r') as f: + adb_public_keys = f.readlines() + adb_keys_set.update(adb_public_keys) + WriteAdbKeysFile(device, '\n'.join(adb_keys_set)) -def WipeDeviceIfPossible(device, timeout): +def WipeDeviceIfPossible(device, timeout, options): try: device.EnableRoot() - WipeDeviceData(device) + WipeDeviceData(device, options) device.Reboot(True, timeout=timeout, retries=0) except (errors.DeviceUnresponsiveError, device_errors.CommandFailedError): pass @@ -177,17 +183,9 @@ else: reboot_timeout = _DEFAULT_TIMEOUTS.PRE_LOLLIPOP - if options.adb_key_files: - adb_keys = set() - for adb_key_file in options.adb_key_files: - with open(adb_key_file, 'r') as f: - adb_public_keys = f.readlines() - adb_keys.update(adb_public_keys) - WriteAdbKeysFile(device, '\n'.join(adb_keys)) - try: if not options.skip_wipe: - WipeDeviceIfPossible(device, reboot_timeout) + WipeDeviceIfPossible(device, reboot_timeout, options) try: device.EnableRoot() except device_errors.CommandFailedError as e:
diff --git a/build/android/pylib/gtest/filter/content_browsertests_disabled b/build/android/pylib/gtest/filter/content_browsertests_disabled index b05f7ee..e1a13666 100644 --- a/build/android/pylib/gtest/filter/content_browsertests_disabled +++ b/build/android/pylib/gtest/filter/content_browsertests_disabled
@@ -15,6 +15,10 @@ # Crashes RenderFrameHostManagerTest.IgnoreRendererDebugURLsWhenCrashed +# Crashes due to using --disable-gpu. +# Needs to investigate more in http://crbug.com/461624. +ScreenOrientationBrowserTest.* + # Plugins are not supported. BrowserPluginThreadedCompositorPixelTest.* BrowserPluginHostTest.* @@ -67,3 +71,7 @@ # http://crbug.com/343604 MSE_ClearKey/EncryptedMediaTest.ConfigChangeVideo/0 + +# http://crbug.com/463041 +ScreenOrientationBrowserTest.ScreenOrientationChange +ScreenOrientationBrowserTest.WindowOrientationCange
diff --git a/build/android/pylib/remote/device/remote_device_environment.py b/build/android/pylib/remote/device/remote_device_environment.py index 6e75afa3..3b0c029c 100644 --- a/build/android/pylib/remote/device/remote_device_environment.py +++ b/build/android/pylib/remote/device/remote_device_environment.py
@@ -183,6 +183,7 @@ os.environ['APPURIFY_API_PROTO'] = self._api_protocol os.environ['APPURIFY_API_HOST'] = self._api_address os.environ['APPURIFY_API_PORT'] = self._api_port + os.environ['APPURIFY_STATUS_BASE_URL'] = 'none' self._GetAccessToken() if self._trigger: self._SelectDevice()
diff --git a/build/config/BUILDCONFIG.gn b/build/config/BUILDCONFIG.gn index 7c06e59..3afba89 100644 --- a/build/config/BUILDCONFIG.gn +++ b/build/config/BUILDCONFIG.gn
@@ -113,11 +113,6 @@ # toolchains. cros_use_custom_toolchain = false } - - # TODO(brettw) remove this flag (and therefore enable linking all targets) on - # Windows when we have sufficient bot capacity. In the meantime, you can - # enable linking for local compiles. - link_chrome_on_windows = true } # TODO(dpranke): Remove these asserts when os and cpu_arch are removed.
diff --git a/build/config/features.gni b/build/config/features.gni index abafd1c..4d01a87 100644 --- a/build/config/features.gni +++ b/build/config/features.gni
@@ -49,6 +49,29 @@ # Enables proprietary codecs and demuxers; e.g. H264, MOV, AAC, and MP3. proprietary_codecs = false + + enable_configuration_policy = true + + # Enables support for background apps. + enable_background = !is_ios && !is_android + + enable_captive_portal_detection = !is_android && !is_ios + + # Enables use of the session service, which is enabled by default. + # Android stores them separately on the Java side. + enable_session_service = !is_android && !is_ios + + enable_plugin_installation = is_win || is_mac + + enable_app_list = !is_ios && !is_android + + enable_supervised_users = !is_ios + + enable_autofill_dialog = !is_ios && !(is_android && is_android_webview_build) + + enable_google_now = !is_ios && !is_android + + enable_one_click_signin = is_win || is_mac || (is_linux && !is_chromeos) } # Additional dependent variables ----------------------------------------------- @@ -113,11 +136,6 @@ safe_browsing_mode = 1 } -enable_configuration_policy = true - -# Enables support for background apps. -enable_background = !is_ios && !is_android - enable_task_manager = !is_ios && !is_android use_cups = is_desktop_linux || is_mac @@ -127,27 +145,14 @@ # TODO(scottmg) remove this when we've fixed printing. win_pdf_metafile_for_printing = true -enable_captive_portal_detection = !is_android && !is_ios - -# Enables use of the session service, which is enabled by default. -# Android stores them separately on the Java side. -enable_session_service = !is_android && !is_ios - # Whether we are using the rlz library or not. Platforms like Android send # rlz codes for searches but do not use the library. enable_rlz = is_chrome_branded && (is_win || is_mac || is_ios || is_chromeos) -enable_plugin_installation = is_win || is_mac - -enable_app_list = !is_ios && !is_android enable_settings_app = enable_app_list && !is_chromeos -enable_supervised_users = !is_ios - enable_service_discovery = enable_mdns || is_mac -enable_autofill_dialog = !is_ios && !(is_android && is_android_webview_build) - enable_wifi_bootstrapping = is_win || is_mac # Image loader extension is enabled on ChromeOS only. @@ -155,10 +160,6 @@ enable_remoting = !is_ios && !is_android -enable_google_now = !is_ios && !is_android - -enable_one_click_signin = is_win || is_mac || (is_linux && !is_chromeos) - # Chrome OS: whether to also build the upcoming version of # ChromeVox, which can then be enabled via a command-line switch. enable_chromevox_next = false
diff --git a/build/sanitizers/tsan_suppressions.cc b/build/sanitizers/tsan_suppressions.cc index 24c24d6..d1e2223f 100644 --- a/build/sanitizers/tsan_suppressions.cc +++ b/build/sanitizers/tsan_suppressions.cc
@@ -251,9 +251,6 @@ // http://crbug.com/364006 "race:gfx::ImageFamily::~ImageFamily\n" -// http://crbug.com/364014 -"race:WTF::Latin1Encoding()::globalLatin1Encoding\n" - // https://code.google.com/p/v8/issues/detail?id=3143 "race:v8::internal::FLAG_track_double_fields\n"
diff --git a/cc/BUILD.gn b/cc/BUILD.gn index 7a97d38..99a8208f 100644 --- a/cc/BUILD.gn +++ b/cc/BUILD.gn
@@ -731,162 +731,160 @@ } } -if (!is_win || link_chrome_on_windows) { - test("cc_unittests") { - sources = [ - "animation/animation_unittest.cc", - "animation/keyframed_animation_curve_unittest.cc", - "animation/layer_animation_controller_unittest.cc", - "animation/scroll_offset_animation_curve_unittest.cc", - "animation/scrollbar_animation_controller_linear_fade_unittest.cc", - "animation/scrollbar_animation_controller_thinning_unittest.cc", - "animation/transform_operations_unittest.cc", - "base/float_quad_unittest.cc", - "base/math_util_unittest.cc", - "base/region_unittest.cc", - "base/rolling_time_delta_history_unittest.cc", - "base/scoped_ptr_vector_unittest.cc", - "base/simple_enclosed_region_unittest.cc", - "base/tiling_data_unittest.cc", - "base/util_unittest.cc", - "debug/frame_timing_tracker_unittest.cc", - "debug/micro_benchmark_controller_unittest.cc", - "input/top_controls_manager_unittest.cc", - "layers/contents_scaling_layer_unittest.cc", - "layers/delegated_frame_provider_unittest.cc", - "layers/delegated_frame_resource_collection_unittest.cc", - "layers/delegated_renderer_layer_impl_unittest.cc", - "layers/delegated_renderer_layer_unittest.cc", - "layers/heads_up_display_layer_impl_unittest.cc", - "layers/heads_up_display_unittest.cc", - "layers/io_surface_layer_impl_unittest.cc", - "layers/layer_impl_unittest.cc", - "layers/layer_iterator_unittest.cc", - "layers/layer_position_constraint_unittest.cc", - "layers/layer_unittest.cc", - "layers/layer_utils_unittest.cc", - "layers/nine_patch_layer_impl_unittest.cc", - "layers/nine_patch_layer_unittest.cc", - "layers/painted_scrollbar_layer_impl_unittest.cc", - "layers/picture_image_layer_impl_unittest.cc", - "layers/picture_image_layer_unittest.cc", - "layers/picture_layer_impl_unittest.cc", - "layers/picture_layer_unittest.cc", - "layers/render_surface_impl_unittest.cc", - "layers/render_surface_unittest.cc", - "layers/scrollbar_layer_unittest.cc", - "layers/solid_color_layer_impl_unittest.cc", - "layers/solid_color_scrollbar_layer_impl_unittest.cc", - "layers/surface_layer_impl_unittest.cc", - "layers/surface_layer_unittest.cc", - "layers/texture_layer_impl_unittest.cc", - "layers/texture_layer_unittest.cc", - "layers/tiled_layer_impl_unittest.cc", - "layers/tiled_layer_unittest.cc", - "layers/ui_resource_layer_impl_unittest.cc", - "layers/ui_resource_layer_unittest.cc", - "layers/video_layer_impl_unittest.cc", - "output/begin_frame_args_unittest.cc", - "output/delegating_renderer_unittest.cc", - "output/filter_operations_unittest.cc", - "output/gl_renderer_unittest.cc", - "output/output_surface_unittest.cc", - "output/overlay_unittest.cc", - "output/renderer_pixeltest.cc", - "output/renderer_unittest.cc", - "output/shader_unittest.cc", - "output/software_renderer_unittest.cc", - "quads/draw_quad_unittest.cc", - "quads/list_container_unittest.cc", - "quads/render_pass_unittest.cc", - "resources/display_item_list_unittest.cc", - "resources/layer_quad_unittest.cc", - "resources/picture_layer_tiling_set_unittest.cc", - "resources/picture_layer_tiling_unittest.cc", - "resources/picture_pile_impl_unittest.cc", - "resources/picture_pile_unittest.cc", - "resources/picture_unittest.cc", - "resources/platform_color_unittest.cc", - "resources/prioritized_resource_unittest.cc", - "resources/resource_provider_unittest.cc", - "resources/resource_update_controller_unittest.cc", - "resources/scoped_gpu_raster_unittest.cc", - "resources/scoped_resource_unittest.cc", - "resources/task_graph_runner_unittest.cc", - "resources/texture_mailbox_deleter_unittest.cc", - "resources/texture_uploader_unittest.cc", - "resources/tile_manager_unittest.cc", - "resources/tile_priority_unittest.cc", - "resources/tile_task_worker_pool_unittest.cc", - "resources/video_resource_updater_unittest.cc", - "scheduler/begin_frame_source_unittest.cc", - "scheduler/delay_based_time_source_unittest.cc", - "scheduler/scheduler_state_machine_unittest.cc", - "scheduler/scheduler_unittest.cc", - "test/layer_tree_json_parser_unittest.cc", - "test/test_web_graphics_context_3d_unittest.cc", - "trees/blocking_task_runner_unittest.cc", - "trees/damage_tracker_unittest.cc", - "trees/layer_sorter_unittest.cc", - "trees/layer_tree_host_common_unittest.cc", - "trees/layer_tree_host_impl_unittest.cc", - "trees/layer_tree_host_pixeltest_blending.cc", - "trees/layer_tree_host_pixeltest_filters.cc", - "trees/layer_tree_host_pixeltest_masks.cc", - "trees/layer_tree_host_pixeltest_readback.cc", - "trees/layer_tree_host_pixeltest_synchronous.cc", - "trees/layer_tree_host_unittest.cc", - "trees/layer_tree_host_unittest_animation.cc", - "trees/layer_tree_host_unittest_context.cc", - "trees/layer_tree_host_unittest_copyrequest.cc", - "trees/layer_tree_host_unittest_damage.cc", - "trees/layer_tree_host_unittest_delegated.cc", - "trees/layer_tree_host_unittest_no_message_loop.cc", - "trees/layer_tree_host_unittest_occlusion.cc", - "trees/layer_tree_host_unittest_picture.cc", - "trees/layer_tree_host_unittest_proxy.cc", - "trees/layer_tree_host_unittest_scroll.cc", - "trees/layer_tree_host_unittest_video.cc", - "trees/layer_tree_impl_unittest.cc", - "trees/occlusion_tracker_unittest.cc", - "trees/occlusion_unittest.cc", - "trees/property_tree_unittest.cc", - "trees/tree_synchronizer_unittest.cc", +test("cc_unittests") { + sources = [ + "animation/animation_unittest.cc", + "animation/keyframed_animation_curve_unittest.cc", + "animation/layer_animation_controller_unittest.cc", + "animation/scroll_offset_animation_curve_unittest.cc", + "animation/scrollbar_animation_controller_linear_fade_unittest.cc", + "animation/scrollbar_animation_controller_thinning_unittest.cc", + "animation/transform_operations_unittest.cc", + "base/float_quad_unittest.cc", + "base/math_util_unittest.cc", + "base/region_unittest.cc", + "base/rolling_time_delta_history_unittest.cc", + "base/scoped_ptr_vector_unittest.cc", + "base/simple_enclosed_region_unittest.cc", + "base/tiling_data_unittest.cc", + "base/util_unittest.cc", + "debug/frame_timing_tracker_unittest.cc", + "debug/micro_benchmark_controller_unittest.cc", + "input/top_controls_manager_unittest.cc", + "layers/contents_scaling_layer_unittest.cc", + "layers/delegated_frame_provider_unittest.cc", + "layers/delegated_frame_resource_collection_unittest.cc", + "layers/delegated_renderer_layer_impl_unittest.cc", + "layers/delegated_renderer_layer_unittest.cc", + "layers/heads_up_display_layer_impl_unittest.cc", + "layers/heads_up_display_unittest.cc", + "layers/io_surface_layer_impl_unittest.cc", + "layers/layer_impl_unittest.cc", + "layers/layer_iterator_unittest.cc", + "layers/layer_position_constraint_unittest.cc", + "layers/layer_unittest.cc", + "layers/layer_utils_unittest.cc", + "layers/nine_patch_layer_impl_unittest.cc", + "layers/nine_patch_layer_unittest.cc", + "layers/painted_scrollbar_layer_impl_unittest.cc", + "layers/picture_image_layer_impl_unittest.cc", + "layers/picture_image_layer_unittest.cc", + "layers/picture_layer_impl_unittest.cc", + "layers/picture_layer_unittest.cc", + "layers/render_surface_impl_unittest.cc", + "layers/render_surface_unittest.cc", + "layers/scrollbar_layer_unittest.cc", + "layers/solid_color_layer_impl_unittest.cc", + "layers/solid_color_scrollbar_layer_impl_unittest.cc", + "layers/surface_layer_impl_unittest.cc", + "layers/surface_layer_unittest.cc", + "layers/texture_layer_impl_unittest.cc", + "layers/texture_layer_unittest.cc", + "layers/tiled_layer_impl_unittest.cc", + "layers/tiled_layer_unittest.cc", + "layers/ui_resource_layer_impl_unittest.cc", + "layers/ui_resource_layer_unittest.cc", + "layers/video_layer_impl_unittest.cc", + "output/begin_frame_args_unittest.cc", + "output/delegating_renderer_unittest.cc", + "output/filter_operations_unittest.cc", + "output/gl_renderer_unittest.cc", + "output/output_surface_unittest.cc", + "output/overlay_unittest.cc", + "output/renderer_pixeltest.cc", + "output/renderer_unittest.cc", + "output/shader_unittest.cc", + "output/software_renderer_unittest.cc", + "quads/draw_quad_unittest.cc", + "quads/list_container_unittest.cc", + "quads/render_pass_unittest.cc", + "resources/display_item_list_unittest.cc", + "resources/layer_quad_unittest.cc", + "resources/picture_layer_tiling_set_unittest.cc", + "resources/picture_layer_tiling_unittest.cc", + "resources/picture_pile_impl_unittest.cc", + "resources/picture_pile_unittest.cc", + "resources/picture_unittest.cc", + "resources/platform_color_unittest.cc", + "resources/prioritized_resource_unittest.cc", + "resources/resource_provider_unittest.cc", + "resources/resource_update_controller_unittest.cc", + "resources/scoped_gpu_raster_unittest.cc", + "resources/scoped_resource_unittest.cc", + "resources/task_graph_runner_unittest.cc", + "resources/texture_mailbox_deleter_unittest.cc", + "resources/texture_uploader_unittest.cc", + "resources/tile_manager_unittest.cc", + "resources/tile_priority_unittest.cc", + "resources/tile_task_worker_pool_unittest.cc", + "resources/video_resource_updater_unittest.cc", + "scheduler/begin_frame_source_unittest.cc", + "scheduler/delay_based_time_source_unittest.cc", + "scheduler/scheduler_state_machine_unittest.cc", + "scheduler/scheduler_unittest.cc", + "test/layer_tree_json_parser_unittest.cc", + "test/test_web_graphics_context_3d_unittest.cc", + "trees/blocking_task_runner_unittest.cc", + "trees/damage_tracker_unittest.cc", + "trees/layer_sorter_unittest.cc", + "trees/layer_tree_host_common_unittest.cc", + "trees/layer_tree_host_impl_unittest.cc", + "trees/layer_tree_host_pixeltest_blending.cc", + "trees/layer_tree_host_pixeltest_filters.cc", + "trees/layer_tree_host_pixeltest_masks.cc", + "trees/layer_tree_host_pixeltest_readback.cc", + "trees/layer_tree_host_pixeltest_synchronous.cc", + "trees/layer_tree_host_unittest.cc", + "trees/layer_tree_host_unittest_animation.cc", + "trees/layer_tree_host_unittest_context.cc", + "trees/layer_tree_host_unittest_copyrequest.cc", + "trees/layer_tree_host_unittest_damage.cc", + "trees/layer_tree_host_unittest_delegated.cc", + "trees/layer_tree_host_unittest_no_message_loop.cc", + "trees/layer_tree_host_unittest_occlusion.cc", + "trees/layer_tree_host_unittest_picture.cc", + "trees/layer_tree_host_unittest_proxy.cc", + "trees/layer_tree_host_unittest_scroll.cc", + "trees/layer_tree_host_unittest_video.cc", + "trees/layer_tree_impl_unittest.cc", + "trees/occlusion_tracker_unittest.cc", + "trees/occlusion_unittest.cc", + "trees/property_tree_unittest.cc", + "trees/tree_synchronizer_unittest.cc", - # Surfaces test files. - "surfaces/surface_aggregator_test_helpers.cc", - "surfaces/surface_aggregator_test_helpers.h", - "surfaces/surface_aggregator_unittest.cc", - "surfaces/surface_unittest.cc", - "surfaces/surfaces_pixeltest.cc", + # Surfaces test files. + "surfaces/surface_aggregator_test_helpers.cc", + "surfaces/surface_aggregator_test_helpers.h", + "surfaces/surface_aggregator_unittest.cc", + "surfaces/surface_unittest.cc", + "surfaces/surfaces_pixeltest.cc", - # Setup. - "test/cc_test_suite.cc", - "test/run_all_unittests.cc", - ] + # Setup. + "test/cc_test_suite.cc", + "test/run_all_unittests.cc", + ] - configs += [ "//build/config/compiler:no_size_t_to_int_warning" ] + configs += [ "//build/config/compiler:no_size_t_to_int_warning" ] - deps = [ - ":cc", - ":test_support", - "//base/test:test_support", - "//cc/surfaces", - "//cc/surfaces:surface_id", - "//gpu", - "//gpu:test_support", - "//gpu/command_buffer/client:gles2_interface", - "//gpu/command_buffer/common:gles2_utils", - "//media", - "//testing/gmock", - "//testing/gtest", - "//ui/events:events_base", - "//ui/gfx", - "//ui/gfx/geometry", - "//ui/gfx:test_support", - "//ui/gl", - ] - } + deps = [ + ":cc", + ":test_support", + "//base/test:test_support", + "//cc/surfaces", + "//cc/surfaces:surface_id", + "//gpu", + "//gpu:test_support", + "//gpu/command_buffer/client:gles2_interface", + "//gpu/command_buffer/common:gles2_utils", + "//media", + "//testing/gmock", + "//testing/gtest", + "//ui/events:events_base", + "//ui/gfx", + "//ui/gfx/geometry", + "//ui/gfx:test_support", + "//ui/gl", + ] } test("cc_perftests") {
diff --git a/cc/blink/BUILD.gn b/cc/blink/BUILD.gn index b9f86c0..1769efb 100644 --- a/cc/blink/BUILD.gn +++ b/cc/blink/BUILD.gn
@@ -72,7 +72,7 @@ # GYP version: //cc/blink/cc_blink_tests.gyp:cc_blink_unittests # TODO(GYP): make linking work on the mac. -if (!is_mac && (!is_win || link_chrome_on_windows)) { +if (!is_mac) { test("cc_blink_unittests") { sources = [ "web_animation_unittest.cc",
diff --git a/cc/debug/debug_rect_history.cc b/cc/debug/debug_rect_history.cc index cde77653..22a612c 100644 --- a/cc/debug/debug_rect_history.cc +++ b/cc/debug/debug_rect_history.cc
@@ -163,10 +163,9 @@ } void DebugRectHistory::SaveTouchEventHandlerRects(LayerImpl* layer) { - LayerTreeHostCommon::CallFunctionForSubtree<LayerImpl>( - layer, - base::Bind(&DebugRectHistory::SaveTouchEventHandlerRectsCallback, - base::Unretained(this))); + LayerTreeHostCommon::CallFunctionForSubtree(layer, [this](LayerImpl* layer) { + SaveTouchEventHandlerRectsCallback(layer); + }); } void DebugRectHistory::SaveTouchEventHandlerRectsCallback(LayerImpl* layer) { @@ -183,10 +182,9 @@ } void DebugRectHistory::SaveWheelEventHandlerRects(LayerImpl* layer) { - LayerTreeHostCommon::CallFunctionForSubtree<LayerImpl>( - layer, - base::Bind(&DebugRectHistory::SaveWheelEventHandlerRectsCallback, - base::Unretained(this))); + LayerTreeHostCommon::CallFunctionForSubtree(layer, [this](LayerImpl* layer) { + SaveWheelEventHandlerRectsCallback(layer); + }); } void DebugRectHistory::SaveWheelEventHandlerRectsCallback(LayerImpl* layer) { @@ -204,10 +202,9 @@ } void DebugRectHistory::SaveScrollEventHandlerRects(LayerImpl* layer) { - LayerTreeHostCommon::CallFunctionForSubtree<LayerImpl>( - layer, - base::Bind(&DebugRectHistory::SaveScrollEventHandlerRectsCallback, - base::Unretained(this))); + LayerTreeHostCommon::CallFunctionForSubtree(layer, [this](LayerImpl* layer) { + SaveScrollEventHandlerRectsCallback(layer); + }); } void DebugRectHistory::SaveScrollEventHandlerRectsCallback(LayerImpl* layer) { @@ -225,10 +222,9 @@ } void DebugRectHistory::SaveNonFastScrollableRects(LayerImpl* layer) { - LayerTreeHostCommon::CallFunctionForSubtree<LayerImpl>( - layer, - base::Bind(&DebugRectHistory::SaveNonFastScrollableRectsCallback, - base::Unretained(this))); + LayerTreeHostCommon::CallFunctionForSubtree(layer, [this](LayerImpl* layer) { + SaveNonFastScrollableRectsCallback(layer); + }); } void DebugRectHistory::SaveNonFastScrollableRectsCallback(LayerImpl* layer) {
diff --git a/cc/debug/invalidation_benchmark.cc b/cc/debug/invalidation_benchmark.cc index 1a6a2b8..bb98bcc 100644 --- a/cc/debug/invalidation_benchmark.cc +++ b/cc/debug/invalidation_benchmark.cc
@@ -64,11 +64,7 @@ void InvalidationBenchmark::DidUpdateLayers(LayerTreeHost* host) { LayerTreeHostCommon::CallFunctionForSubtree( host->root_layer(), - base::Bind(&InvalidationBenchmark::Run, base::Unretained(this))); -} - -void InvalidationBenchmark::Run(Layer* layer) { - layer->RunMicroBenchmark(this); + [this](Layer* layer) { layer->RunMicroBenchmark(this); }); } void InvalidationBenchmark::RunOnLayer(PictureLayer* layer) {
diff --git a/cc/debug/invalidation_benchmark.h b/cc/debug/invalidation_benchmark.h index f17fdbd..9423d5d8 100644 --- a/cc/debug/invalidation_benchmark.h +++ b/cc/debug/invalidation_benchmark.h
@@ -31,7 +31,6 @@ private: enum Mode { FIXED_SIZE, LAYER, VIEWPORT, RANDOM }; - void Run(Layer* layer); float LCGRandom(); Mode mode_;
diff --git a/cc/debug/picture_record_benchmark.cc b/cc/debug/picture_record_benchmark.cc index b1b8188..3ef4708 100644 --- a/cc/debug/picture_record_benchmark.cc +++ b/cc/debug/picture_record_benchmark.cc
@@ -57,7 +57,7 @@ void PictureRecordBenchmark::DidUpdateLayers(LayerTreeHost* host) { LayerTreeHostCommon::CallFunctionForSubtree( host->root_layer(), - base::Bind(&PictureRecordBenchmark::Run, base::Unretained(this))); + [this](Layer* layer) { layer->RunMicroBenchmark(this); }); scoped_ptr<base::ListValue> results(new base::ListValue()); for (std::map<std::pair<int, int>, TotalTime>::iterator it = times_.begin(); @@ -83,10 +83,6 @@ NotifyDone(results.Pass()); } -void PictureRecordBenchmark::Run(Layer* layer) { - layer->RunMicroBenchmark(this); -} - void PictureRecordBenchmark::RunOnLayer(PictureLayer* layer) { ContentLayerClient* painter = layer->client(); gfx::Size content_bounds = layer->content_bounds();
diff --git a/cc/debug/picture_record_benchmark.h b/cc/debug/picture_record_benchmark.h index d6330fe1..3710d83b 100644 --- a/cc/debug/picture_record_benchmark.h +++ b/cc/debug/picture_record_benchmark.h
@@ -27,8 +27,6 @@ void RunOnLayer(PictureLayer* layer) override; private: - void Run(Layer* layer); - typedef std::pair<base::TimeDelta, unsigned> TotalTime; std::map<std::pair<int, int>, TotalTime> times_; std::vector<std::pair<int, int>> dimensions_;
diff --git a/cc/debug/rasterize_and_record_benchmark.cc b/cc/debug/rasterize_and_record_benchmark.cc index e56a1e13..e46dcfe 100644 --- a/cc/debug/rasterize_and_record_benchmark.cc +++ b/cc/debug/rasterize_and_record_benchmark.cc
@@ -65,7 +65,7 @@ host_ = host; LayerTreeHostCommon::CallFunctionForSubtree( host->root_layer(), - base::Bind(&RasterizeAndRecordBenchmark::Run, base::Unretained(this))); + [this](Layer* layer) { layer->RunMicroBenchmark(this); }); DCHECK(!results_.get()); results_ = make_scoped_ptr(new base::DictionaryValue); @@ -102,10 +102,6 @@ weak_ptr_factory_.GetWeakPtr()))); } -void RasterizeAndRecordBenchmark::Run(Layer* layer) { - layer->RunMicroBenchmark(this); -} - void RasterizeAndRecordBenchmark::RunOnLayer(PictureLayer* layer) { DCHECK(host_);
diff --git a/cc/debug/rasterize_and_record_benchmark.h b/cc/debug/rasterize_and_record_benchmark.h index 30dcde0..bed446d 100644 --- a/cc/debug/rasterize_and_record_benchmark.h +++ b/cc/debug/rasterize_and_record_benchmark.h
@@ -37,7 +37,6 @@ scoped_refptr<base::MessageLoopProxy> origin_loop) override; private: - void Run(Layer* layer); void RunOnDisplayListLayer(PictureLayer* layer, const gfx::Rect& visible_content_rect); void RunOnPictureLayer(PictureLayer* layer,
diff --git a/cc/debug/rasterize_and_record_benchmark_impl.cc b/cc/debug/rasterize_and_record_benchmark_impl.cc index 5a9577b..443db8c 100644 --- a/cc/debug/rasterize_and_record_benchmark_impl.cc +++ b/cc/debug/rasterize_and_record_benchmark_impl.cc
@@ -132,9 +132,10 @@ void RasterizeAndRecordBenchmarkImpl::DidCompleteCommit( LayerTreeHostImpl* host) { LayerTreeHostCommon::CallFunctionForSubtree( - host->RootLayer(), - base::Bind(&RasterizeAndRecordBenchmarkImpl::Run, - base::Unretained(this))); + host->RootLayer(), [this](LayerImpl* layer) { + rasterize_results_.total_layers++; + layer->RunMicroBenchmark(this); + }); scoped_ptr<base::DictionaryValue> result(new base::DictionaryValue()); result->SetDouble("rasterize_time_ms", @@ -157,11 +158,6 @@ NotifyDone(result.Pass()); } -void RasterizeAndRecordBenchmarkImpl::Run(LayerImpl* layer) { - rasterize_results_.total_layers++; - layer->RunMicroBenchmark(this); -} - void RasterizeAndRecordBenchmarkImpl::RunOnLayer(PictureLayerImpl* layer) { rasterize_results_.total_picture_layers++; if (!layer->CanHaveTilings()) {
diff --git a/cc/debug/rasterize_and_record_benchmark_impl.h b/cc/debug/rasterize_and_record_benchmark_impl.h index e9ca27d..ae134ab2 100644 --- a/cc/debug/rasterize_and_record_benchmark_impl.h +++ b/cc/debug/rasterize_and_record_benchmark_impl.h
@@ -31,8 +31,6 @@ void RunOnLayer(PictureLayerImpl* layer) override; private: - void Run(LayerImpl* layer); - struct RasterizeResults { RasterizeResults(); ~RasterizeResults();
diff --git a/cc/trees/layer_tree_host.cc b/cc/trees/layer_tree_host.cc index abc63fc..92e9c259 100644 --- a/cc/trees/layer_tree_host.cc +++ b/cc/trees/layer_tree_host.cc
@@ -211,10 +211,6 @@ proxy_->SetLayerTreeHostClientReady(); } -static void LayerTreeHostOnOutputSurfaceCreatedCallback(Layer* layer) { - layer->OnOutputSurfaceCreated(); -} - void LayerTreeHost::DeleteContentsTexturesOnImplThread( ResourceProvider* resource_provider) { DCHECK(proxy_->IsImplThread()); @@ -427,7 +423,7 @@ if (root_layer()) { LayerTreeHostCommon::CallFunctionForSubtree( - root_layer(), base::Bind(&LayerTreeHostOnOutputSurfaceCreatedCallback)); + root_layer(), [](Layer* layer) { layer->OnOutputSurfaceCreated(); }); } client_->DidInitializeOutputSurface(); @@ -873,17 +869,12 @@ SetNeedsCommit(); } -static void LayerTreeHostReduceMemoryCallback(Layer* layer) { - layer->ReduceMemoryUsage(); -} - void LayerTreeHost::ReduceMemoryUsage() { if (!root_layer()) return; LayerTreeHostCommon::CallFunctionForSubtree( - root_layer(), - base::Bind(&LayerTreeHostReduceMemoryCallback)); + root_layer(), [](Layer* layer) { layer->ReduceMemoryUsage(); }); } void LayerTreeHost::SetPrioritiesForSurfaces(size_t surface_memory_bytes) {
diff --git a/cc/trees/layer_tree_host_common.h b/cc/trees/layer_tree_host_common.h index 86666176..6c03511 100644 --- a/cc/trees/layer_tree_host_common.h +++ b/cc/trees/layer_tree_host_common.h
@@ -125,10 +125,9 @@ static bool RenderSurfaceContributesToTarget(LayerType*, int target_surface_layer_id); - template <typename LayerType> - static void CallFunctionForSubtree( - LayerType* root_layer, - const base::Callback<void(LayerType* layer)>& function); + template <typename LayerType, typename Function> + static void CallFunctionForSubtree(LayerType* layer, + const Function& function); // Returns a layer with the given id if one exists in the subtree starting // from the given root layer (including mask and replica layers). @@ -205,22 +204,21 @@ return NULL; } -template <typename LayerType> -void LayerTreeHostCommon::CallFunctionForSubtree( - LayerType* root_layer, - const base::Callback<void(LayerType* layer)>& function) { - function.Run(root_layer); +template <typename LayerType, typename Function> +void LayerTreeHostCommon::CallFunctionForSubtree(LayerType* layer, + const Function& function) { + function(layer); - if (LayerType* mask_layer = root_layer->mask_layer()) - function.Run(mask_layer); - if (LayerType* replica_layer = root_layer->replica_layer()) { - function.Run(replica_layer); + if (LayerType* mask_layer = layer->mask_layer()) + function(mask_layer); + if (LayerType* replica_layer = layer->replica_layer()) { + function(replica_layer); if (LayerType* mask_layer = replica_layer->mask_layer()) - function.Run(mask_layer); + function(mask_layer); } - for (size_t i = 0; i < root_layer->children().size(); ++i) { - CallFunctionForSubtree(get_layer_as_raw_ptr(root_layer->children(), i), + for (size_t i = 0; i < layer->children().size(); ++i) { + CallFunctionForSubtree(get_layer_as_raw_ptr(layer->children(), i), function); } }
diff --git a/cc/trees/layer_tree_host_impl.cc b/cc/trees/layer_tree_host_impl.cc index eddbc60..c03f7f79 100644 --- a/cc/trees/layer_tree_host_impl.cc +++ b/cc/trees/layer_tree_host_impl.cc
@@ -1453,10 +1453,6 @@ return metadata; } -static void LayerTreeHostImplDidBeginTracingCallback(LayerImpl* layer) { - layer->DidBeginTracing(); -} - void LayerTreeHostImpl::DrawLayers(FrameData* frame, base::TimeTicks frame_begin_time) { TRACE_EVENT0("cc", "LayerTreeHostImpl::DrawLayers"); @@ -1506,11 +1502,11 @@ if (pending_tree_) { LayerTreeHostCommon::CallFunctionForSubtree( pending_tree_->root_layer(), - base::Bind(&LayerTreeHostImplDidBeginTracingCallback)); + [](LayerImpl* layer) { layer->DidBeginTracing(); }); } LayerTreeHostCommon::CallFunctionForSubtree( active_tree_->root_layer(), - base::Bind(&LayerTreeHostImplDidBeginTracingCallback)); + [](LayerImpl* layer) { layer->DidBeginTracing(); }); } {
diff --git a/cc/trees/layer_tree_impl.cc b/cc/trees/layer_tree_impl.cc index 62e4cd36..5114fdc 100644 --- a/cc/trees/layer_tree_impl.cc +++ b/cc/trees/layer_tree_impl.cc
@@ -121,13 +121,18 @@ } void LayerTreeImpl::ReleaseResources() { - if (root_layer_) - ProcessLayersRecursive(root_layer_.get(), &LayerImpl::ReleaseResources); + if (root_layer_) { + LayerTreeHostCommon::CallFunctionForSubtree( + root_layer_.get(), [](LayerImpl* layer) { layer->ReleaseResources(); }); + } } void LayerTreeImpl::RecreateResources() { - if (root_layer_) - ProcessLayersRecursive(root_layer_.get(), &LayerImpl::RecreateResources); + if (root_layer_) { + LayerTreeHostCommon::CallFunctionForSubtree( + root_layer_.get(), + [](LayerImpl* layer) { layer->RecreateResources(); }); + } } void LayerTreeImpl::SetRootLayer(scoped_ptr<LayerImpl> layer) { @@ -475,10 +480,6 @@ gfx::Rect(layer->content_bounds())); } -static void ApplySentScrollDeltasFromAbortedCommitTo(LayerImpl* layer) { - layer->ApplySentScrollDeltasFromAbortedCommit(); -} - void LayerTreeImpl::ApplySentScrollAndScaleDeltasFromAbortedCommit() { DCHECK(IsActiveTree()); @@ -490,7 +491,9 @@ return; LayerTreeHostCommon::CallFunctionForSubtree( - root_layer(), base::Bind(&ApplySentScrollDeltasFromAbortedCommitTo)); + root_layer(), [](LayerImpl* layer) { + layer->ApplySentScrollDeltasFromAbortedCommit(); + }); } void LayerTreeImpl::SetViewportLayersFromIds( @@ -748,17 +751,6 @@ currently_scrolling_layer_ ? currently_scrolling_layer_->id() : 0)); } -static void DidBecomeActiveRecursive(LayerImpl* layer) { - layer->DidBecomeActive(); - if (layer->mask_layer()) - layer->mask_layer()->DidBecomeActive(); - if (layer->replica_layer() && layer->replica_layer()->mask_layer()) - layer->replica_layer()->mask_layer()->DidBecomeActive(); - - for (size_t i = 0; i < layer->children().size(); ++i) - DidBecomeActiveRecursive(layer->children()[i]); -} - void LayerTreeImpl::DidBecomeActive() { if (next_activation_forces_redraw_) { layer_tree_host_impl_->SetFullRootLayerDamage(); @@ -774,8 +766,10 @@ // if we were in a good state. layer_tree_host_impl_->ResetRequiresHighResToDraw(); - if (root_layer()) - DidBecomeActiveRecursive(root_layer()); + if (root_layer()) { + LayerTreeHostCommon::CallFunctionForSubtree( + root_layer(), [](LayerImpl* layer) { layer->DidBecomeActive(); }); + } devtools_instrumentation::DidActivateLayerTree(layer_tree_host_impl_->id(), source_frame_number_); @@ -1267,18 +1261,6 @@ return layers_with_copy_output_request_; } -void LayerTreeImpl::ProcessLayersRecursive(LayerImpl* current, - void (LayerImpl::*function)()) { - DCHECK(current); - (current->*function)(); - if (current->mask_layer()) - ProcessLayersRecursive(current->mask_layer(), function); - if (current->replica_layer()) - ProcessLayersRecursive(current->replica_layer(), function); - for (size_t i = 0; i < current->children().size(); ++i) - ProcessLayersRecursive(current->children()[i], function); -} - template <typename LayerType> static inline bool LayerClipsSubtree(LayerType* layer) { return layer->masks_to_bounds() || layer->mask_layer();
diff --git a/cc/trees/layer_tree_impl.h b/cc/trees/layer_tree_impl.h index f7b6ee41..3105e6f4 100644 --- a/cc/trees/layer_tree_impl.h +++ b/cc/trees/layer_tree_impl.h
@@ -335,8 +335,6 @@ scoped_refptr<SyncedProperty<ScaleGroup>> page_scale_factor, scoped_refptr<SyncedTopControls> top_controls_shown_ratio, scoped_refptr<SyncedElasticOverscroll> elastic_overscroll); - void ProcessLayersRecursive(LayerImpl* current, - void (LayerImpl::*function)()); float ClampPageScaleFactorToLimits(float page_scale_factor) const; void PushPageScaleFactorAndLimits(const float* page_scale_factor, float min_page_scale_factor,
diff --git a/chrome/BUILD.gn b/chrome/BUILD.gn index 8b0e6a3..b410882 100644 --- a/chrome/BUILD.gn +++ b/chrome/BUILD.gn
@@ -12,16 +12,7 @@ import("//build/config/android/rules.gni") } -if (is_win && !link_chrome_on_windows) { - # When linking is disabled on Windows, create a dummy Chrome target to - # make targets work that depend on Chrome. - group("chrome") { - } - group("main_dll") { - } -} - -if (!is_android && (!is_win || link_chrome_on_windows)) { +if (!is_android) { # TODO(GYP) for Windows need to the the reorder-imports step which probably # means adding another target and renaming this to chrome_initial like in GYP. executable("chrome") { @@ -153,89 +144,87 @@ } } # !is_android -if (!is_win || link_chrome_on_windows) { - shared_library("main_dll") { - configs += [ "//build/config/compiler:wexit_time_destructors" ] +shared_library("main_dll") { + configs += [ "//build/config/compiler:wexit_time_destructors" ] - deps = [ - ":browser_dependencies", - "//base/allocator", + deps = [ + ":browser_dependencies", + "//base/allocator", + ] + if (is_win) { + output_name = "chrome" + + sources = [ + "//base/win/dllmain.cc", + "app/chrome_command_ids.h", + "app/chrome_dll.rc", + "app/chrome_dll_resource.h", + "app/chrome_main.cc", + "app/chrome_main_delegate.cc", + "app/chrome_main_delegate.h", + "app/close_handle_hook_win.cc", + "app/close_handle_hook_win.h", + "app/delay_load_hook_win.cc", + "app/delay_load_hook_win.h", ] - if (is_win) { - output_name = "chrome" - sources = [ - "//base/win/dllmain.cc", - "app/chrome_command_ids.h", - "app/chrome_dll.rc", - "app/chrome_dll_resource.h", - "app/chrome_main.cc", - "app/chrome_main_delegate.cc", - "app/chrome_main_delegate.h", - "app/close_handle_hook_win.cc", - "app/close_handle_hook_win.h", - "app/delay_load_hook_win.cc", - "app/delay_load_hook_win.h", - ] - - deps += [ - # On Windows, link the dependencies (libraries) that make up actual - # Chromium functionality into this .dll. - ":chrome_version_resources", - "//chrome/app/theme:chrome_unscaled_resources", - "//chrome_elf", - "//content/app/resources", - "//crypto", - "//net:net_resources", - "//third_party/wtl", - "//ui/views", - ] - if (enable_configuration_policy) { - deps += [ "//components/policy" ] - } - if (current_cpu == "x86") { - # Add a dependency to custom import library for user32 delay imports only - # in x86 builds. - #deps += [ 'chrome_user32_delay_imports' ] TODO(GYP) - } - - # TODO(GYP) incremental linking flags in debug builds - #'LinkIncremental': '<(msvs_large_module_debug_link_mode)', - - # TODO(GYP) Lots of VCLinkerTool stuff on Windows. - - # TODO(GYP) chrome_pgo_phase on Windows. + deps += [ + # On Windows, link the dependencies (libraries) that make up actual + # Chromium functionality into this .dll. + ":chrome_version_resources", + "//chrome/app/theme:chrome_unscaled_resources", + "//chrome_elf", + "//content/app/resources", + "//crypto", + "//net:net_resources", + "//third_party/wtl", + "//ui/views", + ] + if (enable_configuration_policy) { + deps += [ "//components/policy" ] + } + if (current_cpu == "x86") { + # Add a dependency to custom import library for user32 delay imports only + # in x86 builds. + #deps += [ 'chrome_user32_delay_imports' ] TODO(GYP) } - if (use_aura) { - deps += [ "//ui/compositor" ] - } + # TODO(GYP) incremental linking flags in debug builds + #'LinkIncremental': '<(msvs_large_module_debug_link_mode)', - #TODO(GYP) add chrome_multiple_dll support - if (false) { #chrome_multiple_dll) { - defines = [ "CHROME_MULTIPLE_DLL_BROWSER" ] - deps += [ "//content/public/app:browser" ] - } else { - deps += [ - ":child_dependencies", - "//content/public/app:both", - ] - } + # TODO(GYP) Lots of VCLinkerTool stuff on Windows. - if (cld_version == 0 || cld_version == 2) { - deps += [ "//third_party/cld_2" ] - } + # TODO(GYP) chrome_pgo_phase on Windows. + } - if (is_mac) { - #['OS=="mac" and component!="shared_library"', { TODO(GYP) - # 'includes': [ 'chrome_dll_bundle.gypi' ], - #}], - # TODO(GYP) Lots of other stuff in the OS=="mac" block. - } + if (use_aura) { + deps += [ "//ui/compositor" ] + } - if (enable_plugins) { - deps += [ "//pdf" ] - } + #TODO(GYP) add chrome_multiple_dll support + if (false) { #chrome_multiple_dll) { + defines = [ "CHROME_MULTIPLE_DLL_BROWSER" ] + deps += [ "//content/public/app:browser" ] + } else { + deps += [ + ":child_dependencies", + "//content/public/app:both", + ] + } + + if (cld_version == 0 || cld_version == 2) { + deps += [ "//third_party/cld_2" ] + } + + if (is_mac) { + #['OS=="mac" and component!="shared_library"', { TODO(GYP) + # 'includes': [ 'chrome_dll_bundle.gypi' ], + #}], + # TODO(GYP) Lots of other stuff in the OS=="mac" block. + } + + if (enable_plugins) { + deps += [ "//pdf" ] } }
diff --git a/chrome/VERSION b/chrome/VERSION index c42c9fd..99950b9 100644 --- a/chrome/VERSION +++ b/chrome/VERSION
@@ -1,4 +1,4 @@ MAJOR=43 MINOR=0 -BUILD=2320 +BUILD=2321 PATCH=0
diff --git a/chrome/android/java/res/layout/fre_choose_account.xml b/chrome/android/java/res/layout/fre_choose_account.xml index b5bcf65..82468b5c 100644 --- a/chrome/android/java/res/layout/fre_choose_account.xml +++ b/chrome/android/java/res/layout/fre_choose_account.xml
@@ -93,6 +93,7 @@ android:layout_gravity="bottom" android:orientation="horizontal" > + <!--suppress ButtonStyle --> <Button android:id="@+id/negative_button" android:layout_width="0dp" @@ -107,6 +108,7 @@ android:textColor="@color/light_normal_color" android:textSize="@dimen/fre_button_text_size" /> + <!--suppress ButtonStyle --> <Button android:id="@+id/positive_button" android:layout_width="0dp"
diff --git a/chrome/android/java/res/layout/homepage_preferences.xml b/chrome/android/java/res/layout/homepage_preferences.xml index b5c04a8..23452d9 100644 --- a/chrome/android/java/res/layout/homepage_preferences.xml +++ b/chrome/android/java/res/layout/homepage_preferences.xml
@@ -42,6 +42,7 @@ <ImageView android:layout_width="match_parent" android:layout_height="wrap_content" + android:contentDescription="@null" android:src="?android:attr/listDivider" android:scaleType="fitXY" />
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/BookmarkUtils.java b/chrome/android/java/src/org/chromium/chrome/browser/BookmarkUtils.java index e9b474b..9eaf0bb 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/BookmarkUtils.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/BookmarkUtils.java
@@ -4,6 +4,7 @@ package org.chromium.chrome.browser; +import android.annotation.TargetApi; import android.app.ActivityManager; import android.content.Context; import android.content.Intent; @@ -151,6 +152,7 @@ return bitmap; } + @TargetApi(Build.VERSION_CODES.ICE_CREAM_SANDWICH_MR1) private static Bitmap getBitmapFromResourceId(Context context, int id, int density) { Drawable drawable = null; if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.ICE_CREAM_SANDWICH_MR1) {
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/ChromeWebContentsDelegateAndroid.java b/chrome/android/java/src/org/chromium/chrome/browser/ChromeWebContentsDelegateAndroid.java index 316852a..a162c9e 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/ChromeWebContentsDelegateAndroid.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/ChromeWebContentsDelegateAndroid.java
@@ -71,4 +71,5 @@ protected static native boolean nativeIsCapturingAudio(WebContents webContents); protected static native boolean nativeIsCapturingVideo(WebContents webContents); + protected static native boolean nativeHasAudibleAudio(WebContents webContents); }
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/LollipopTtsPlatformImpl.java b/chrome/android/java/src/org/chromium/chrome/browser/LollipopTtsPlatformImpl.java index c011a6a..423456f 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/LollipopTtsPlatformImpl.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/LollipopTtsPlatformImpl.java
@@ -4,7 +4,9 @@ package org.chromium.chrome.browser; +import android.annotation.TargetApi; import android.content.Context; +import android.os.Build; import android.os.Bundle; import android.speech.tts.TextToSpeech; import android.speech.tts.UtteranceProgressListener; @@ -12,6 +14,7 @@ /** * Subclass of TtsPlatformImpl for Lollipop to make use of newer APIs. */ +@TargetApi(Build.VERSION_CODES.LOLLIPOP) class LollipopTtsPlatformImpl extends TtsPlatformImpl { protected LollipopTtsPlatformImpl(long nativeTtsPlatformImplAndroid, Context context) { super(nativeTtsPlatformImplAndroid, context);
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/UmaUtils.java b/chrome/android/java/src/org/chromium/chrome/browser/UmaUtils.java index ff2e9d5..e4e2d1d 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/UmaUtils.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/UmaUtils.java
@@ -4,51 +4,9 @@ package org.chromium.chrome.browser; -import org.chromium.base.CalledByNative; /** - * Utilities to support startup metrics - Android version. + * TODO(yfriedman): Remove this after rolling downstream. */ -public class UmaUtils { - - private static long sApplicationStartWallClockMs; - - private static boolean sRunningApplicationStart; - - /** - * Record the time at which the activity started. This should be called asap after - * the start of the activity's onCreate function. - */ - public static void recordMainEntryPointTime() { - // We can't simply pass this down through a JNI call, since the JNI for chrome - // isn't initialized until we start the native content browser component, and we - // then need the start time in the C++ side before we return to Java. As such we - // save it in a static that the C++ can fetch once it has initialized the JNI. - sApplicationStartWallClockMs = System.currentTimeMillis(); - } - - /** - * Whether the application is in the early stage since the browser process start. The - * "application start" ends right after the last histogram related to browser startup is - * recorded. Currently, the very first navigation commit in the lifetime of the process ends the - * "application start". - * Must only be called on the UI thread. - */ - public static boolean isRunningApplicationStart() { - return sRunningApplicationStart; - } - - /** - * Marks/unmarks the "application start" stage of the browser process lifetime. - * Must only be called on the UI thread. - */ - public static void setRunningApplicationStart(boolean isAppStart) { - sRunningApplicationStart = isAppStart; - } - - @CalledByNative - private static long getMainEntryPointTime() { - return sApplicationStartWallClockMs; - } - +public class UmaUtils extends org.chromium.chrome.browser.metrics.UmaUtils { }
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/appmenu/AppMenu.java b/chrome/android/java/src/org/chromium/chrome/browser/appmenu/AppMenu.java index 9b87940..bc1bcf1 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/appmenu/AppMenu.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/appmenu/AppMenu.java
@@ -5,6 +5,7 @@ package org.chromium.chrome.browser.appmenu; import android.animation.Animator; +import android.animation.Animator.AnimatorListener; import android.animation.AnimatorSet; import android.content.Context; import android.content.res.Resources; @@ -27,6 +28,7 @@ import android.widget.PopupWindow; import android.widget.PopupWindow.OnDismissListener; +import org.chromium.base.AnimationFrameTimeHistogram; import org.chromium.base.SysUtils; import org.chromium.chrome.R; @@ -53,6 +55,9 @@ private AppMenuHandler mHandler; private int mCurrentScreenRotation = -1; private boolean mIsByHardwareButton; + private AnimatorSet mMenuItemEnterAnimator; + private AnimatorListener mAnimationHistogramRecorder = AnimationFrameTimeHistogram + .getAnimatorRecorder("WrenchMenu.OpeningAnimationFrameTimes"); /** * Creates and sets up the App Menu. @@ -140,6 +145,10 @@ if (mPopup.getAnchorView() instanceof ImageButton) { ((ImageButton) mPopup.getAnchorView()).setSelected(false); } + + if (mMenuItemEnterAnimator != null) mMenuItemEnterAnimator.cancel(); + + mHandler.appMenuDismissed(); mHandler.onMenuVisibilityChanged(false); } }); @@ -299,7 +308,6 @@ * Dismisses the app menu and cancels the drag-to-scroll if it is taking place. */ void dismiss() { - mHandler.appMenuDismissed(); if (isShowing()) { mPopup.dismiss(); } @@ -361,7 +369,7 @@ } private void runMenuItemEnterAnimations() { - AnimatorSet animation = new AnimatorSet(); + mMenuItemEnterAnimator = new AnimatorSet(); AnimatorSet.Builder builder = null; ViewGroup list = mPopup.getListView(); @@ -370,13 +378,14 @@ Object animatorObject = view.getTag(R.id.menu_item_enter_anim_id); if (animatorObject != null) { if (builder == null) { - builder = animation.play((Animator) animatorObject); + builder = mMenuItemEnterAnimator.play((Animator) animatorObject); } else { builder.with((Animator) animatorObject); } } } - animation.start(); + mMenuItemEnterAnimator.addListener(mAnimationHistogramRecorder); + mMenuItemEnterAnimator.start(); } }
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/appmenu/AppMenuButtonHelper.java b/chrome/android/java/src/org/chromium/chrome/browser/appmenu/AppMenuButtonHelper.java index e6b58dcd..4471c971 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/appmenu/AppMenuButtonHelper.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/appmenu/AppMenuButtonHelper.java
@@ -9,7 +9,7 @@ import android.view.View; import android.view.View.OnTouchListener; -import org.chromium.chrome.browser.UmaBridge; +import org.chromium.chrome.browser.metrics.UmaBridge; /** * A helper class for a menu button to decide when to show the app menu and forward touch
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/appmenu/AppMenuDragHelper.java b/chrome/android/java/src/org/chromium/chrome/browser/appmenu/AppMenuDragHelper.java index 99d34c3..b41006cc 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/appmenu/AppMenuDragHelper.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/appmenu/AppMenuDragHelper.java
@@ -18,7 +18,7 @@ import android.widget.ListView; import org.chromium.chrome.R; -import org.chromium.chrome.browser.UmaBridge; +import org.chromium.chrome.browser.metrics.UmaBridge; import java.util.ArrayList;
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/appmenu/AppMenuHandler.java b/chrome/android/java/src/org/chromium/chrome/browser/appmenu/AppMenuHandler.java index 7229fc6..10e0ef55 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/appmenu/AppMenuHandler.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/appmenu/AppMenuHandler.java
@@ -17,7 +17,7 @@ import org.chromium.base.VisibleForTesting; import org.chromium.chrome.R; -import org.chromium.chrome.browser.UmaBridge; +import org.chromium.chrome.browser.metrics.UmaBridge; import java.util.ArrayList;
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/autofill/CardUnmaskPrompt.java b/chrome/android/java/src/org/chromium/chrome/browser/autofill/CardUnmaskPrompt.java index 9bd2b34..6865c439 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/autofill/CardUnmaskPrompt.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/autofill/CardUnmaskPrompt.java
@@ -12,6 +12,7 @@ import android.graphics.PorterDuffColorFilter; import android.os.Build; import android.os.Handler; +import android.support.v4.view.ViewCompat; import android.text.Editable; import android.text.TextWatcher; import android.view.LayoutInflater; @@ -101,8 +102,8 @@ .setView(v) .setNegativeButton(R.string.cancel, null) .setPositiveButton(R.string.card_unmask_confirm_button, null) - .setOnDismissListener(this) .create(); + mDialog.setOnDismissListener(this); mShouldRequestExpirationDate = shouldRequestExpirationDate; mThisYear = Calendar.getInstance().get(Calendar.YEAR); @@ -168,6 +169,7 @@ mVerificationView.setText("Your card is verified"); Handler h = new Handler(); h.postDelayed(new Runnable() { + @Override public void run() { dismiss(); } @@ -223,7 +225,7 @@ mMonthInput.setEnabled(enabled); mYearInput.setEnabled(enabled); mMainContents.setAlpha(enabled ? 1.0f : 0.15f); - mMainContents.setImportantForAccessibility( + ViewCompat.setImportantForAccessibility(mMainContents, enabled ? View.IMPORTANT_FOR_ACCESSIBILITY_AUTO : View.IMPORTANT_FOR_ACCESSIBILITY_NO_HIDE_DESCENDANTS); ((ViewGroup) mMainContents).setDescendantFocusability(
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/enhanced_bookmarks/EnhancedBookmarksModel.java b/chrome/android/java/src/org/chromium/chrome/browser/enhanced_bookmarks/EnhancedBookmarksModel.java index 2f5107ca..32d60d1 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/enhanced_bookmarks/EnhancedBookmarksModel.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/enhanced_bookmarks/EnhancedBookmarksModel.java
@@ -5,6 +5,7 @@ package org.chromium.chrome.browser.enhanced_bookmarks; import org.chromium.base.ObserverList; +import org.chromium.base.VisibleForTesting; import org.chromium.chrome.browser.BookmarksBridge; import org.chromium.chrome.browser.BookmarksBridge.BookmarkItem; import org.chromium.chrome.browser.BookmarksBridge.BookmarkModelObserver; @@ -63,6 +64,12 @@ this(); } + @VisibleForTesting + EnhancedBookmarksModel(Profile profile) { + mBookmarksBridge = new BookmarksBridge(profile); + mEnhancedBookmarksBridge = new EnhancedBookmarksBridge(profile); + } + /** * Clean up all the bridges. This must be called after done using this class. */ @@ -275,7 +282,8 @@ } /** - * @see EnhancedBookmarksBridge#moveBookmark(BookmarkId, BookmarkId) + * Calls {@link EnhancedBookmarksBridge#moveBookmark(BookmarkId, BookmarkId)} in a reversed + * order of the list, in order to let the last item appear at the top. */ public void moveBookmarks(List<BookmarkId> bookmarkIds, BookmarkId newParentId) { for (int i = bookmarkIds.size() - 1; i >= 0; i--) { @@ -394,4 +402,12 @@ public void removeSearchObserver(SearchServiceObserver observer) { mEnhancedBookmarksBridge.removeSearchObserver(observer); } + + /** + * @see BookmarksBridge#loadEmptyPartnerBookmarkShimForTesting() + */ + @VisibleForTesting + public void loadEmptyPartnerBookmarkShimForTesting() { + mBookmarksBridge.loadEmptyPartnerBookmarkShimForTesting(); + } }
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/infobar/AnimationHelper.java b/chrome/android/java/src/org/chromium/chrome/browser/infobar/AnimationHelper.java index 77b19ea..2725ec3 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/infobar/AnimationHelper.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/infobar/AnimationHelper.java
@@ -9,6 +9,7 @@ import android.animation.AnimatorSet; import android.animation.ObjectAnimator; import android.animation.PropertyValuesHolder; +import android.annotation.TargetApi; import android.os.Build; import android.view.View; import android.view.ViewTreeObserver; @@ -217,6 +218,7 @@ mTargetWrapperView.startTransition(); } + @TargetApi(Build.VERSION_CODES.JELLY_BEAN) @Override public void onAnimationEnd(Animator animation) { mTargetWrapperView.finishTransition();
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/infobar/AppBannerInfoBar.java b/chrome/android/java/src/org/chromium/chrome/browser/infobar/AppBannerInfoBar.java index 2f62227..970a51c 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/infobar/AppBannerInfoBar.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/infobar/AppBannerInfoBar.java
@@ -7,6 +7,7 @@ import android.content.Context; import android.content.res.Resources; import android.graphics.Bitmap; +import android.support.v4.view.ViewCompat; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; @@ -107,9 +108,9 @@ } // Hide uninteresting views from accessibility. - ratingView.setImportantForAccessibility(View.IMPORTANT_FOR_ACCESSIBILITY_NO); + ViewCompat.setImportantForAccessibility(ratingView, View.IMPORTANT_FOR_ACCESSIBILITY_NO); if (mIconView != null) { - mIconView.setImportantForAccessibility(View.IMPORTANT_FOR_ACCESSIBILITY_NO); + ViewCompat.setImportantForAccessibility(mIconView, View.IMPORTANT_FOR_ACCESSIBILITY_NO); } // Set up clicking on the controls to bring up the app details.
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/init/AsyncInitializationActivity.java b/chrome/android/java/src/org/chromium/chrome/browser/init/AsyncInitializationActivity.java index 1e94673..d7927eda 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/init/AsyncInitializationActivity.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/init/AsyncInitializationActivity.java
@@ -15,6 +15,8 @@ import android.view.ViewTreeObserver; import android.view.ViewTreeObserver.OnPreDrawListener; +import org.chromium.chrome.browser.metrics.MemoryUma; + /** * An activity that talks with application and activity level delegates for async initialization. */ @@ -30,6 +32,7 @@ private Bundle mSavedInstanceState; private boolean mDestroyed; private NativeInitializationController mNativeInitializationController; + private MemoryUma mMemoryUma; public AsyncInitializationActivity() { mHandler = new Handler(); @@ -71,6 +74,7 @@ @Override public void finishNativeInitialization() { + mMemoryUma = new MemoryUma(); mNativeInitializationController.onNativeInitializationComplete(); } @@ -146,6 +150,7 @@ @Override public void onStop() { super.onStop(); + if (mMemoryUma != null) mMemoryUma.onStop(); mNativeInitializationController.onStop(); } @@ -196,6 +201,19 @@ return false; } + @Override + public void onLowMemory() { + super.onLowMemory(); + if (mMemoryUma != null) mMemoryUma.onLowMemory(); + } + + @Override + public void onTrimMemory(int level) { + super.onTrimMemory(level); + if (mMemoryUma != null) mMemoryUma.onTrimMemory(level); + } + + /** * Extending classes should implement this and call {@link Activity#setContentView(int)} in it. */
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/metrics/MemoryUma.java b/chrome/android/java/src/org/chromium/chrome/browser/metrics/MemoryUma.java new file mode 100644 index 0000000..5deefaa --- /dev/null +++ b/chrome/android/java/src/org/chromium/chrome/browser/metrics/MemoryUma.java
@@ -0,0 +1,89 @@ +// 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.metrics; + +import static android.content.ComponentCallbacks2.TRIM_MEMORY_BACKGROUND; +import static android.content.ComponentCallbacks2.TRIM_MEMORY_COMPLETE; +import static android.content.ComponentCallbacks2.TRIM_MEMORY_MODERATE; +import static android.content.ComponentCallbacks2.TRIM_MEMORY_RUNNING_CRITICAL; +import static android.content.ComponentCallbacks2.TRIM_MEMORY_RUNNING_LOW; +import static android.content.ComponentCallbacks2.TRIM_MEMORY_RUNNING_MODERATE; +import static android.content.ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN; + +import android.os.Build; +import android.os.SystemClock; + +import org.chromium.base.metrics.RecordHistogram; + +import java.util.concurrent.TimeUnit; + +/** + * Centralizes UMA data collection for Android-specific memory conditions. + */ +public class MemoryUma { + // AndroidMemoryNotificationBackground defined in tools/metrics/histograms/histograms.xml. + private static final int BACKGROUND_TRIM_UI_HIDDEN = 0; + private static final int BACKGROUND_TRIM_BACKGROUND = 1; + private static final int BACKGROUND_TRIM_MODERATE = 2; + private static final int BACKGROUND_TRIM_COMPLETE = 3; + private static final int BACKGROUND_MAX = 4; + + // AndroidMemoryNotificationForeground defined in tools/metrics/histograms/histograms.xml. + private static final int FOREGROUND_TRIM_MODERATE = 0; + private static final int FOREGROUND_TRIM_LOW = 1; + private static final int FOREGROUND_TRIM_CRITICAL = 2; + private static final int FOREGROUND_LOW = 3; + private static final int FOREGROUND_MAX = 4; + + // Timestamp of the last time we received a LowMemory call since Chrome is in foreground. + private long mLastLowMemoryMsec = -1; + + public void onStop() { + mLastLowMemoryMsec = -1; + } + + public void onLowMemory() { + memoryNotificationForeground(FOREGROUND_LOW); + long now = SystemClock.elapsedRealtime(); + if (mLastLowMemoryMsec >= 0) { + RecordHistogram.recordCustomTimesHistogram("MemoryAndroid.LowMemoryTimeBetween", + now - mLastLowMemoryMsec, 0, TimeUnit.MINUTES.toMillis(10), + TimeUnit.MILLISECONDS, 50); + } + mLastLowMemoryMsec = now; + } + + public void onTrimMemory(int level) { + if (level >= TRIM_MEMORY_COMPLETE) { + memoryNotificationBackground(BACKGROUND_TRIM_COMPLETE); + } else if (level >= TRIM_MEMORY_MODERATE) { + memoryNotificationBackground(BACKGROUND_TRIM_MODERATE); + } else if (level >= TRIM_MEMORY_BACKGROUND) { + memoryNotificationBackground(BACKGROUND_TRIM_BACKGROUND); + } else if (level >= TRIM_MEMORY_UI_HIDDEN) { + memoryNotificationBackground(BACKGROUND_TRIM_UI_HIDDEN); + } else if (level >= TRIM_MEMORY_RUNNING_CRITICAL) { + memoryNotificationForeground(FOREGROUND_TRIM_CRITICAL); + } else if (level >= TRIM_MEMORY_RUNNING_LOW) { + memoryNotificationForeground(FOREGROUND_TRIM_LOW); + } else if (level >= TRIM_MEMORY_RUNNING_MODERATE) { + memoryNotificationForeground(FOREGROUND_TRIM_MODERATE); + } + } + + private static void memoryNotificationForeground(int notification) { + assert notification >= 0 && notification < FOREGROUND_MAX; + // Before Jelly Bean we have only LowMemory foreground notification. + if (Build.VERSION.SDK_INT < Build.VERSION_CODES.JELLY_BEAN) return; + RecordHistogram.recordEnumeratedHistogram("MemoryAndroid.NotificationForeground", + notification, FOREGROUND_MAX); + } + + private static void memoryNotificationBackground(int notification) { + assert notification >= 0 && notification < BACKGROUND_MAX; + RecordHistogram.recordEnumeratedHistogram("MemoryAndroid.NotificationBackground", + notification, BACKGROUND_MAX); + } +}
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/UmaBridge.java b/chrome/android/java/src/org/chromium/chrome/browser/metrics/UmaBridge.java similarity index 98% rename from chrome/android/java/src/org/chromium/chrome/browser/UmaBridge.java rename to chrome/android/java/src/org/chromium/chrome/browser/metrics/UmaBridge.java index 48a7f9c..75bad02 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/UmaBridge.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/metrics/UmaBridge.java
@@ -2,7 +2,7 @@ // 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; +package org.chromium.chrome.browser.metrics; import org.chromium.chrome.browser.preferences.bandwidth.BandwidthReductionPreferences; import org.chromium.chrome.browser.preferences.bandwidth.DataReductionPromoScreen;
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 new file mode 100644 index 0000000..e3de19b --- /dev/null +++ b/chrome/android/java/src/org/chromium/chrome/browser/metrics/UmaSessionStats.java
@@ -0,0 +1,189 @@ +// 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.metrics; + +import android.app.Activity; +import android.content.ComponentCallbacks; +import android.content.Context; +import android.content.res.Configuration; + +import org.chromium.base.ActivityState; +import org.chromium.base.ApplicationStatus; +import org.chromium.chrome.browser.Tab; +import org.chromium.chrome.browser.preferences.privacy.CrashReportingPermissionManager; +import org.chromium.chrome.browser.preferences.privacy.PrivacyPreferencesManager; +import org.chromium.chrome.browser.tabmodel.TabModel; +import org.chromium.chrome.browser.tabmodel.TabModelSelector; +import org.chromium.chrome.browser.tabmodel.TabModelSelectorTabObserver; +import org.chromium.content_public.browser.WebContents; +import org.chromium.net.NetworkChangeNotifier; + +/** + * Mainly sets up session stats for chrome. A session is defined as the duration when the + * application is in the foreground. Also used to communicate information between Chrome + * and the framework's MetricService. + */ +public class UmaSessionStats implements NetworkChangeNotifier.ConnectionTypeObserver { + private static final String SAMSUNG_MULTWINDOW_PACKAGE = "com.sec.feature.multiwindow"; + + private static long sNativeUmaSessionStats = 0; + + // TabModelSelector is needed to get the count of open tabs. We want to log the number of open + // tabs on every page load. + private TabModelSelector mTabModelSelector; + private TabModelSelectorTabObserver mTabModelSelectorTabObserver; + + private final Context mContext; + private final boolean mIsMultiWindowCapable; + private ComponentCallbacks mComponentCallbacks; + + private boolean mKeyboardConnected = false; + private final CrashReportingPermissionManager mReportingPermissionManager; + + public UmaSessionStats(Context context) { + mContext = context; + mIsMultiWindowCapable = context.getPackageManager().hasSystemFeature( + SAMSUNG_MULTWINDOW_PACKAGE); + mReportingPermissionManager = PrivacyPreferencesManager.getInstance(context); + } + + private void recordPageLoadStats(int tabId) { + Tab tab = mTabModelSelector.getTabById(tabId); + if (tab == null) return; + WebContents webContents = tab.getWebContents(); + boolean isDesktopUserAgent = webContents != null + && webContents.getNavigationController().getUseDesktopUserAgent(); + nativeRecordPageLoaded(isDesktopUserAgent); + if (mKeyboardConnected) { + nativeRecordPageLoadedWithKeyboard(); + } + + TabModel regularModel = mTabModelSelector.getModel(false); + nativeRecordTabCountPerLoad(getTabCountFromModel(regularModel)); + } + + private int getTabCountFromModel(TabModel model) { + return model == null ? 0 : model.getCount(); + } + + /** + * Starts a new session for logging. + * @param tabModelSelector A TabModelSelector instance for recording tab counts on page loads. + * If null, UmaSessionStats does not record page loads and tab counts. + */ + public void startNewSession(TabModelSelector tabModelSelector) { + ensureNativeInitialized(); + + mTabModelSelector = tabModelSelector; + if (mTabModelSelector != null) { + mComponentCallbacks = new ComponentCallbacks() { + @Override + public void onLowMemory() { + // Not required + } + + @Override + public void onConfigurationChanged(Configuration newConfig) { + mKeyboardConnected = newConfig.keyboard != Configuration.KEYBOARD_NOKEYS; + } + }; + mContext.registerComponentCallbacks(mComponentCallbacks); + mKeyboardConnected = mContext.getResources().getConfiguration() + .keyboard != Configuration.KEYBOARD_NOKEYS; + mTabModelSelectorTabObserver = new TabModelSelectorTabObserver(mTabModelSelector) { + @Override + public void onPageLoadFinished(Tab tab) { + recordPageLoadStats(tab.getId()); + } + }; + } + + nativeUmaResumeSession(sNativeUmaSessionStats); + NetworkChangeNotifier.addConnectionTypeObserver(this); + updateMetricsServiceState(); + } + + private static void ensureNativeInitialized() { + // Lazily create the native object and the notification handler. These objects are never + // destroyed. + if (sNativeUmaSessionStats == 0) { + sNativeUmaSessionStats = nativeInit(); + } + } + + /** + * Logs screen ratio on Samsung MultiWindow devices. + */ + public void logMultiWindowStats(int windowArea, int displayArea, int instanceCount) { + if (mIsMultiWindowCapable) { + if (displayArea == 0) return; + int areaPercent = (windowArea * 100) / displayArea; + int safePercent = areaPercent > 0 ? areaPercent : 0; + nativeRecordMultiWindowSession(safePercent, instanceCount); + } + } + + /** + * Logs the current session. + */ + public void logAndEndSession() { + if (mTabModelSelector != null) { + mContext.unregisterComponentCallbacks(mComponentCallbacks); + mTabModelSelectorTabObserver.destroy(); + mTabModelSelector = null; + } + + nativeUmaEndSession(sNativeUmaSessionStats); + NetworkChangeNotifier.removeConnectionTypeObserver(this); + } + + public static void logRendererCrash(Activity activity) { + int activityState = ApplicationStatus.getStateForActivity(activity); + nativeLogRendererCrash( + activityState == ActivityState.PAUSED + || activityState == ActivityState.STOPPED + || activityState == ActivityState.DESTROYED); + } + + /** + * Updates the state of the MetricsService to account for the user's preferences. + */ + public void updateMetricsServiceState() { + boolean mayRecordStats = !PrivacyPreferencesManager.getInstance(mContext) + .isNeverUploadCrashDump(); + boolean mayUploadStats = mReportingPermissionManager.isUploadPermitted(); + + // Re-start the MetricsService with the given parameters. + nativeUpdateMetricsServiceState(mayRecordStats, mayUploadStats); + } + + @Override + public void onConnectionTypeChanged(int connectionType) { + updateMetricsServiceState(); + } + + public static void registerExternalExperiment(int studyId, int experimentId) { + nativeRegisterExternalExperiment(studyId, experimentId); + } + + public static void registerSyntheticFieldTrial(String trialName, String groupName) { + nativeRegisterSyntheticFieldTrial(trialName, groupName); + } + + private static native long nativeInit(); + private native void nativeUpdateMetricsServiceState(boolean mayRecord, boolean mayUpload); + private native void nativeUmaResumeSession(long nativeUmaSessionStats); + private native void nativeUmaEndSession(long nativeUmaSessionStats); + private static native void nativeLogRendererCrash(boolean isPaused); + private static native void nativeRegisterExternalExperiment(int studyId, + int experimentId); + private static native void nativeRegisterSyntheticFieldTrial( + String trialName, String groupName); + private static native void nativeRecordMultiWindowSession(int areaPercent, int instanceCount); + private static native void nativeRecordTabCountPerLoad(int numTabsOpen); + private static native void nativeRecordPageLoaded(boolean isDesktopUserAgent); + private static native void nativeRecordPageLoadedWithKeyboard(); + +}
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/metrics/UmaUtils.java b/chrome/android/java/src/org/chromium/chrome/browser/metrics/UmaUtils.java new file mode 100644 index 0000000..5dc4d296 --- /dev/null +++ b/chrome/android/java/src/org/chromium/chrome/browser/metrics/UmaUtils.java
@@ -0,0 +1,54 @@ +// 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. + +package org.chromium.chrome.browser.metrics; + +import org.chromium.base.CalledByNative; + +/** + * Utilities to support startup metrics - Android version. + */ +public class UmaUtils { + + private static long sApplicationStartWallClockMs; + + private static boolean sRunningApplicationStart; + + /** + * Record the time at which the activity started. This should be called asap after + * the start of the activity's onCreate function. + */ + public static void recordMainEntryPointTime() { + // We can't simply pass this down through a JNI call, since the JNI for chrome + // isn't initialized until we start the native content browser component, and we + // then need the start time in the C++ side before we return to Java. As such we + // save it in a static that the C++ can fetch once it has initialized the JNI. + sApplicationStartWallClockMs = System.currentTimeMillis(); + } + + /** + * Whether the application is in the early stage since the browser process start. The + * "application start" ends right after the last histogram related to browser startup is + * recorded. Currently, the very first navigation commit in the lifetime of the process ends the + * "application start". + * Must only be called on the UI thread. + */ + public static boolean isRunningApplicationStart() { + return sRunningApplicationStart; + } + + /** + * Marks/unmarks the "application start" stage of the browser process lifetime. + * Must only be called on the UI thread. + */ + public static void setRunningApplicationStart(boolean isAppStart) { + sRunningApplicationStart = isAppStart; + } + + @CalledByNative + private static long getMainEntryPointTime() { + return sApplicationStartWallClockMs; + } + +}
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/net/spdyproxy/OWNERS b/chrome/android/java/src/org/chromium/chrome/browser/net/spdyproxy/OWNERS new file mode 100644 index 0000000..845f1d7b --- /dev/null +++ b/chrome/android/java/src/org/chromium/chrome/browser/net/spdyproxy/OWNERS
@@ -0,0 +1 @@ +bengr@chromium.org
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/nfc/BeamCallback.java b/chrome/android/java/src/org/chromium/chrome/browser/nfc/BeamCallback.java index 4811d20..5603de7a 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/nfc/BeamCallback.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/nfc/BeamCallback.java
@@ -18,7 +18,7 @@ import org.chromium.base.ThreadUtils; import org.chromium.chrome.R; -import org.chromium.chrome.browser.UmaBridge; +import org.chromium.chrome.browser.metrics.UmaBridge; import java.net.MalformedURLException; import java.net.URL;
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/preferences/autofill/AutofillPreferences.java b/chrome/android/java/src/org/chromium/chrome/browser/preferences/autofill/AutofillPreferences.java index 1eb5516..b84dbdb 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/preferences/autofill/AutofillPreferences.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/preferences/autofill/AutofillPreferences.java
@@ -37,6 +37,8 @@ private static final String PREF_AUTOFILL_CREDIT_CARDS = "autofill_credit_cards"; private static final String PREF_AUTOFILL_WALLET = "autofill_wallet"; + ChromeBasePreference mWalletPref; + @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); @@ -57,23 +59,13 @@ } }); - ChromeBasePreference walletPref = - (ChromeBasePreference) findPreference(PREF_AUTOFILL_WALLET); - if (!PersonalDataManager.isWalletImportFeatureAvailable()) { - getPreferenceScreen().removePreference(walletPref); - autofillSwitch.setDrawDivider(true); - } else { - walletPref.setSummary(getResources().getString( - PersonalDataManager.isWalletImportEnabled() ? R.string.text_on - : R.string.text_off)); - } - + mWalletPref = (ChromeBasePreference) findPreference(PREF_AUTOFILL_WALLET); setPreferenceCategoryIcons(); } @Override public boolean onPreferenceChange(Preference preference, Object newValue) { - rebuildLists(); + refreshState(); return true; } @@ -92,9 +84,10 @@ } /** - * Rebuild all the profile and credit card lists. + * Refresh state (profile and credit card lists, preference summaries, etc.). */ - private void rebuildLists() { + private void refreshState() { + updateSummaries(); rebuildProfileList(); rebuildCreditCardList(); } @@ -140,6 +133,24 @@ } } + private void updateSummaries() { + ChromeSwitchPreference autofillSwitch = + (ChromeSwitchPreference) findPreference(PREF_AUTOFILL_SWITCH); + if (!PersonalDataManager.isWalletImportFeatureAvailable()) { + getPreferenceScreen().removePreference(mWalletPref); + autofillSwitch.setDrawDivider(true); + } else { + if (getPreferenceScreen().findPreference(PREF_AUTOFILL_WALLET) == null) { + getPreferenceScreen().addPreference(mWalletPref); + } + + mWalletPref.setSummary(getResources().getString( + PersonalDataManager.isWalletImportEnabled() ? R.string.text_on + : R.string.text_off)); + autofillSwitch.setDrawDivider(false); + } + } + @Override public void onResume() { super.onResume(); @@ -147,12 +158,12 @@ // detect if profiles are added or deleted (GUID list // changes), the profile summary (name+addr) might be // different. To be safe, we update all. - rebuildLists(); + refreshState(); } @Override public void onPersonalDataChanged() { - rebuildLists(); + refreshState(); } @Override
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/preferences/bandwidth/BandwidthReductionPreferences.java b/chrome/android/java/src/org/chromium/chrome/browser/preferences/bandwidth/BandwidthReductionPreferences.java index abe2309..43d89378 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/preferences/bandwidth/BandwidthReductionPreferences.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/preferences/bandwidth/BandwidthReductionPreferences.java
@@ -16,9 +16,9 @@ import android.text.format.DateUtils; import org.chromium.chrome.R; -import org.chromium.chrome.browser.UmaBridge; import org.chromium.chrome.browser.firstrun.FirstRunStatus; import org.chromium.chrome.browser.infobar.DataReductionProxyInfoBar; +import org.chromium.chrome.browser.metrics.UmaBridge; import org.chromium.chrome.browser.net.spdyproxy.DataReductionProxySettings; import org.chromium.chrome.browser.preferences.ChromeSwitchPreference; import org.chromium.chrome.browser.preferences.ManagedPreferenceDelegate;
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/preferences/bandwidth/DataReductionPromoScreen.java b/chrome/android/java/src/org/chromium/chrome/browser/preferences/bandwidth/DataReductionPromoScreen.java index 60a379c..a3b3e753 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/preferences/bandwidth/DataReductionPromoScreen.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/preferences/bandwidth/DataReductionPromoScreen.java
@@ -19,7 +19,7 @@ import org.chromium.base.ApplicationStatus; import org.chromium.chrome.R; import org.chromium.chrome.browser.ChromiumApplication; -import org.chromium.chrome.browser.UmaBridge; +import org.chromium.chrome.browser.metrics.UmaBridge; import org.chromium.chrome.browser.net.spdyproxy.DataReductionProxySettings; import org.chromium.chrome.browser.preferences.PreferencesLauncher;
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/preferences/website/AddExceptionPreference.java b/chrome/android/java/src/org/chromium/chrome/browser/preferences/website/AddExceptionPreference.java index 3cd23a4..be8e2d6 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/preferences/website/AddExceptionPreference.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/preferences/website/AddExceptionPreference.java
@@ -16,14 +16,12 @@ import android.preference.Preference.OnPreferenceClickListener; import android.provider.Settings; import android.text.Editable; -import android.text.Spannable; -import android.text.SpannableString; import android.text.TextWatcher; -import android.text.style.ForegroundColorSpan; import android.view.LayoutInflater; import android.view.View; import android.widget.Button; import android.widget.EditText; +import android.widget.TextView; import android.widget.Toast; import org.chromium.chrome.R; @@ -36,6 +34,7 @@ public class AddExceptionPreference extends Preference implements OnPreferenceClickListener { // The callback to notify when the user adds a site. private SiteAddedCallback mSiteAddedCallback; + private int mPrefAccentColor; /** * An interface to implement to get a callback when a site has been added. @@ -57,20 +56,22 @@ setKey(key); Resources resources = getContext().getResources(); + mPrefAccentColor = resources.getColor(R.color.pref_accent_color); + Drawable plusIcon = resources.getDrawable(R.drawable.plus); plusIcon.mutate(); - plusIcon.setColorFilter( - resources.getColor(R.color.pref_accent_color), - PorterDuff.Mode.SRC_IN); + plusIcon.setColorFilter(mPrefAccentColor, PorterDuff.Mode.SRC_IN); setIcon(plusIcon); - SpannableString titleSpan = new SpannableString( - resources.getString( - R.string.website_settings_add_site).toUpperCase()); - titleSpan.setSpan(new ForegroundColorSpan( - resources.getColor(R.color.pref_accent_color)), 0, titleSpan.length(), - Spannable.SPAN_INCLUSIVE_INCLUSIVE); - setTitle(titleSpan); + setTitle(resources.getString(R.string.website_settings_add_site)); + } + + @Override + protected void onBindView(View view) { + super.onBindView(view); + TextView titleView = (TextView) view.findViewById(android.R.id.title); + titleView.setAllCaps(true); + titleView.setTextColor(mPrefAccentColor); } @Override @@ -89,6 +90,7 @@ final EditText input = (EditText) view.findViewById(R.id.site); DialogInterface.OnClickListener onClickListener = new DialogInterface.OnClickListener() { + @Override public void onClick(DialogInterface dialog, int button) { if (button == AlertDialog.BUTTON_POSITIVE) { String hostname = input.getText().toString().trim();
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/preferences/website/SingleWebsitePreferences.java b/chrome/android/java/src/org/chromium/chrome/browser/preferences/website/SingleWebsitePreferences.java index 2417954..5a11bae9 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/preferences/website/SingleWebsitePreferences.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/preferences/website/SingleWebsitePreferences.java
@@ -391,8 +391,13 @@ new Website.StoredDataClearedCallback() { @Override public void onStoredDataCleared() { - getPreferenceScreen().removePreference( - getPreferenceScreen().findPreference(PREF_CLEAR_DATA)); + PreferenceScreen preferenceScreen = getPreferenceScreen(); + preferenceScreen.removePreference( + preferenceScreen.findPreference(PREF_CLEAR_DATA)); + if (!hasUsagePreferences()) { + preferenceScreen.removePreference( + preferenceScreen.findPreference(PREF_USAGE)); + } popBackIfNoSettings(); } });
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/preferences/website/WebsitePreference.java b/chrome/android/java/src/org/chromium/chrome/browser/preferences/website/WebsitePreference.java index 2158617..17dab5a6 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/preferences/website/WebsitePreference.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/preferences/website/WebsitePreference.java
@@ -14,7 +14,6 @@ import android.text.format.Formatter; import android.view.View; import android.widget.ImageView; -import android.widget.LinearLayout; import android.widget.TextView; import org.chromium.base.annotations.SuppressFBWarnings; @@ -46,12 +45,9 @@ // Metrics for favicon processing. private static final int FAVICON_CORNER_RADIUS_DP = 2; private static final int FAVICON_SIZE_DP = 16; + private static final int FAVICON_PADDING_DP = 4; private static final int FAVICON_TEXT_SIZE_SP = 10; private static final int FAVICON_BACKGROUND_COLOR = 0xff969696; - // The minimum width of the preference icon parent field. - private static final int FAVICON_PARENT_MINWIDTH_DP = 55; - // The padding for the preference icon parent field. - private static final int FAVICON_PARENT_PADDING_DP = 12; WebsitePreference(Context context, Website site, String categoryFilter) { super(context); @@ -61,15 +57,11 @@ setWidgetLayoutResource(R.layout.website_features); // To make sure the layout stays stable throughout, we assign a - // transparent drawable of the same size as the favicon. This is so that + // transparent drawable as the icon initially. This is so that // we can fetch the favicon in the background and not have to worry // about the title appearing to jump (http://crbug.com/453626) when the // favicon becomes available. - ColorDrawable drawable = new ColorDrawable(Color.TRANSPARENT); - int size = Math.round(FAVICON_SIZE_DP - * getContext().getResources().getDisplayMetrics().density); - drawable.setBounds(0, 0, size, size); - setIcon(drawable); + setIcon(new ColorDrawable(Color.TRANSPARENT)); refresh(); } @@ -146,8 +138,8 @@ TextView usageText = (TextView) view.findViewById(R.id.usage_text); usageText.setVisibility(View.GONE); - long totalUsage = mSite.getTotalUsage(); if (mFilter.showStorageSites(mCategoryFilter)) { + long totalUsage = mSite.getTotalUsage(); if (totalUsage > 0) { usageText.setText(Formatter.formatShortFileSize(getContext(), totalUsage)); usageText.setTextSize(TEXT_SIZE_SP); @@ -181,15 +173,9 @@ mFaviconFetched = true; } - ImageView icon = (ImageView) view.findViewById(android.R.id.icon); - View parent = (View) icon.getParent(); - if (parent instanceof LinearLayout) { - LinearLayout parentLayout = (LinearLayout) parent; - int minWidth = Math.round(FAVICON_PARENT_MINWIDTH_DP * density); - int padding = Math.round(FAVICON_PARENT_PADDING_DP * density); - parentLayout.setMinimumWidth(minWidth); - parentLayout.setPadding(padding, 0, padding, 0); - } + int iconPadding = Math.round(FAVICON_PADDING_DP * density); + View iconView = view.findViewById(android.R.id.icon); + iconView.setPadding(iconPadding, iconPadding, iconPadding, iconPadding); } /**
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/widget/ButtonCompat.java b/chrome/android/java/src/org/chromium/chrome/browser/widget/ButtonCompat.java index 93b3c81..1385f1ad 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/widget/ButtonCompat.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/widget/ButtonCompat.java
@@ -38,6 +38,7 @@ * Note: To ensure the button's shadow is fully visible, you may need to set * android:clipToPadding="false" on the button's parent view. */ +@TargetApi(Build.VERSION_CODES.LOLLIPOP) public class ButtonCompat extends Button { private static final float PRE_L_PRESSED_BRIGHTNESS = 0.85f;
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/enhanced_bookmarks/EnhancedBookmarksModelTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/enhanced_bookmarks/EnhancedBookmarksModelTest.java new file mode 100644 index 0000000..c4630fd --- /dev/null +++ b/chrome/android/javatests/src/org/chromium/chrome/browser/enhanced_bookmarks/EnhancedBookmarksModelTest.java
@@ -0,0 +1,229 @@ +// 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.enhanced_bookmarks; + +import android.test.UiThreadTest; +import android.test.suitebuilder.annotation.SmallTest; + +import org.chromium.base.ThreadUtils; +import org.chromium.base.test.util.Feature; +import org.chromium.chrome.browser.BookmarksBridge.BookmarkItem; +import org.chromium.chrome.browser.profiles.Profile; +import org.chromium.chrome.shell.ChromeShellActivity; +import org.chromium.chrome.shell.ChromeShellTab; +import org.chromium.chrome.shell.ChromeShellTestBase; +import org.chromium.components.bookmarks.BookmarkId; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.HashSet; +import java.util.List; +import java.util.Stack; + +/** + * Tests for {@link EnhancedBookmarksModel}, the data layer of Enhanced Bookmarks. + */ +public class EnhancedBookmarksModelTest extends ChromeShellTestBase{ + + private ChromeShellActivity mActivity; + private EnhancedBookmarksModel mBookmarksModel; + private BookmarkId mMobileNode; + private BookmarkId mOtherNode; + private BookmarkId mDesktopNode; + + @Override + protected void setUp() throws Exception { + super.setUp(); + mActivity = launchChromeShellWithBlankPage(); + assertTrue(waitForActiveShellToBeDoneLoading()); + ThreadUtils.runOnUiThreadBlocking(new Runnable() { + @Override + public void run() { + ChromeShellTab tab = mActivity.getActiveTab(); + Profile profile = tab.getProfile(); + mBookmarksModel = new EnhancedBookmarksModel(profile); + mBookmarksModel.loadEmptyPartnerBookmarkShimForTesting(); + mMobileNode = mBookmarksModel.getMobileFolderId(); + mDesktopNode = mBookmarksModel.getDesktopFolderId(); + mOtherNode = mBookmarksModel.getOtherFolderId(); + } + }); + } + + @UiThreadTest + @SmallTest + @Feature({"Bookmark"}) + public void testGetAllBookmarkIDsOrderedByCreationDate() throws InterruptedException { + BookmarkId folderA = mBookmarksModel.addFolder(mMobileNode, 0, "a"); + BookmarkId folderB = mBookmarksModel.addFolder(mDesktopNode, 0, "b"); + + Stack<BookmarkId> stack = new Stack<BookmarkId>(); + stack.push(mBookmarksModel.addBookmark(folderA, 0, "a", "http://www.medium.com")); + // If add bookmarks too fast, eventually some bookmarks will have the same timestamp, which + // confuses the bookmark model. + Thread.sleep(20); + stack.push(mBookmarksModel.addBookmark(folderB, 0, "b", "http://aurimas.com")); + Thread.sleep(20); + stack.push(mBookmarksModel.addBookmark(mMobileNode, 0, "c", "http://www.aurimas.com")); + Thread.sleep(20); + stack.push(mBookmarksModel.addBookmark(mDesktopNode, 0, "d", "http://www.aurimas.org")); + Thread.sleep(20); + stack.push(mBookmarksModel.addBookmark(mOtherNode, 0, "e", "http://www.google.com")); + Thread.sleep(20); + stack.push(mBookmarksModel.addBookmark(folderA, 0, "f", "http://www.newt.com")); + Thread.sleep(20); + stack.push(mBookmarksModel.addBookmark(folderB, 0, "g", "http://kkimlabs.com")); + + List<BookmarkId> bookmarks = mBookmarksModel.getAllBookmarkIDsOrderedByCreationDate(); + assertEquals(bookmarks.size(), stack.size()); + for (BookmarkId returnedBookmark : bookmarks) { + assertEquals(stack.pop(), returnedBookmark); + } + } + + @UiThreadTest + @SmallTest + @Feature({"Bookmark"}) + public void testBookmarkPropertySetters() { + BookmarkId folderA = mBookmarksModel.addFolder(mMobileNode, 0, "a"); + + BookmarkId bookmarkA = mBookmarksModel.addBookmark(mDesktopNode, 0, "a", "http://a.com"); + BookmarkId bookmarkB = mBookmarksModel.addBookmark(mMobileNode, 0, "a", "http://a.com"); + BookmarkId bookmarkC = mBookmarksModel.addBookmark(mOtherNode, 0, "a", "http://a.com"); + BookmarkId bookmarkD = mBookmarksModel.addBookmark(folderA, 0, "a", "http://a.com"); + + mBookmarksModel.setBookmarkTitle(folderA, "hauri"); + assertEquals("hauri", mBookmarksModel.getBookmarkTitle(folderA)); + + mBookmarksModel.setBookmarkTitle(bookmarkA, "auri"); + mBookmarksModel.setBookmarkUrl(bookmarkA, "http://auri.org/"); + mBookmarksModel.setBookmarkDescription(bookmarkA, "auri"); + verifyBookmark(bookmarkA, "auri", "http://auri.org/", false, mDesktopNode, "auri"); + + mBookmarksModel.setBookmarkTitle(bookmarkB, "lauri"); + mBookmarksModel.setBookmarkUrl(bookmarkB, "http://lauri.org/"); + mBookmarksModel.setBookmarkDescription(bookmarkB, "lauri"); + verifyBookmark(bookmarkB, "lauri", "http://lauri.org/", false, mMobileNode, "lauri"); + + mBookmarksModel.setBookmarkTitle(bookmarkC, "mauri"); + mBookmarksModel.setBookmarkUrl(bookmarkC, "http://mauri.org/"); + mBookmarksModel.setBookmarkDescription(bookmarkC, "mauri"); + verifyBookmark(bookmarkC, "mauri", "http://mauri.org/", false, mOtherNode, "mauri"); + + mBookmarksModel.setBookmarkTitle(bookmarkD, "kauri"); + mBookmarksModel.setBookmarkUrl(bookmarkD, "http://kauri.org/"); + mBookmarksModel.setBookmarkDescription(bookmarkD, "kauri"); + verifyBookmark(bookmarkD, "kauri", "http://kauri.org/", false, folderA, "kauri"); + } + + @UiThreadTest + @SmallTest + @Feature({"Bookmark"}) + public void testMoveBookmarks() { + BookmarkId bookmarkA = mBookmarksModel.addBookmark(mDesktopNode, 0, "a", "http://a.com"); + BookmarkId bookmarkB = mBookmarksModel.addBookmark(mOtherNode, 0, "b", "http://b.com"); + BookmarkId bookmarkC = mBookmarksModel.addBookmark(mMobileNode, 0, "c", "http://c.com"); + BookmarkId folderA = mBookmarksModel.addFolder(mOtherNode, 0, "fa"); + BookmarkId folderB = mBookmarksModel.addFolder(mDesktopNode, 0, "fb"); + BookmarkId folderC = mBookmarksModel.addFolder(mMobileNode, 0, "fc"); + BookmarkId bookmarkAA = mBookmarksModel.addBookmark(folderA, 0, "aa", "http://aa.com"); + BookmarkId bookmarkCA = mBookmarksModel.addBookmark(folderC, 0, "ca", "http://ca.com"); + BookmarkId folderAA = mBookmarksModel.addFolder(folderA, 0, "faa"); + + HashSet<BookmarkId> movedBookmarks = new HashSet<BookmarkId>(6); + movedBookmarks.add(bookmarkA); + movedBookmarks.add(bookmarkB); + movedBookmarks.add(bookmarkC); + movedBookmarks.add(folderC); + movedBookmarks.add(folderB); + movedBookmarks.add(bookmarkAA); + mBookmarksModel.moveBookmarks(new ArrayList<BookmarkId>(movedBookmarks), folderAA); + + // Order of the moved bookmarks is not tested. + verifyBookmarkListNoOrder(mBookmarksModel.getChildIDs(folderAA, true, true), + movedBookmarks); + } + + @UiThreadTest + @SmallTest + @Feature({"Bookmark"}) + public void testGetChildIDs() { + BookmarkId folderA = mBookmarksModel.addFolder(mMobileNode, 0, "fa"); + HashSet<BookmarkId> expectedChildren = new HashSet<>(); + expectedChildren.add(mBookmarksModel.addBookmark(folderA, 0, "a", "http://a.com")); + expectedChildren.add(mBookmarksModel.addBookmark(folderA, 0, "a", "http://a.com")); + expectedChildren.add(mBookmarksModel.addBookmark(folderA, 0, "a", "http://a.com")); + expectedChildren.add(mBookmarksModel.addBookmark(folderA, 0, "a", "http://a.com")); + BookmarkId folderAA = mBookmarksModel.addFolder(folderA, 0, "faa"); + // urls only + verifyBookmarkListNoOrder(mBookmarksModel.getChildIDs(folderA, false, true), + expectedChildren); + // folders only + verifyBookmarkListNoOrder(mBookmarksModel.getChildIDs(folderA, true, false), + new HashSet<BookmarkId>(Arrays.asList(folderAA))); + // folders and urls + expectedChildren.add(folderAA); + verifyBookmarkListNoOrder(mBookmarksModel.getChildIDs(folderA, true, true), + expectedChildren); + } + + // Moved from BookmarksBridgeTest + @UiThreadTest + @SmallTest + @Feature({"Bookmark"}) + public void testAddBookmarksAndFolders() { + BookmarkId bookmarkA = mBookmarksModel.addBookmark(mDesktopNode, 0, "a", "http://a.com"); + verifyBookmark(bookmarkA, "a", "http://a.com/", false, mDesktopNode, ""); + + BookmarkId bookmarkB = mBookmarksModel.addBookmark(mOtherNode, 0, "b", "http://b.com"); + verifyBookmark(bookmarkB, "b", "http://b.com/", false, mOtherNode, ""); + + BookmarkId bookmarkC = mBookmarksModel.addBookmark(mMobileNode, 0, "c", "http://c.com"); + verifyBookmark(bookmarkC, "c", "http://c.com/", false, mMobileNode, ""); + + BookmarkId folderA = mBookmarksModel.addFolder(mOtherNode, 0, "fa"); + verifyBookmark(folderA, "fa", null, true, mOtherNode, ""); + + BookmarkId folderB = mBookmarksModel.addFolder(mDesktopNode, 0, "fb"); + verifyBookmark(folderB, "fb", null, true, mDesktopNode, ""); + + BookmarkId folderC = mBookmarksModel.addFolder(mMobileNode, 0, "fc"); + verifyBookmark(folderC, "fc", null, true, mMobileNode, ""); + + BookmarkId bookmarkAA = mBookmarksModel.addBookmark(folderA, 0, "aa", "http://aa.com"); + verifyBookmark(bookmarkAA, "aa", "http://aa.com/", false, folderA, ""); + + BookmarkId folderAA = mBookmarksModel.addFolder(folderA, 0, "faa"); + verifyBookmark(folderAA, "faa", null, true, folderA, ""); + } + + private void verifyBookmark(BookmarkId idToVerify, String expectedTitle, + String expectedUrl, boolean isFolder, BookmarkId expectedParent, + String expectedDescription) { + assertNotNull(idToVerify); + BookmarkItem item = mBookmarksModel.getBookmarkById(idToVerify); + assertEquals(expectedTitle, item.getTitle()); + assertEquals(isFolder, item.isFolder()); + if (!isFolder) assertEquals(expectedUrl, item.getUrl()); + assertEquals(expectedParent, item.getParentId()); + assertEquals(expectedDescription, mBookmarksModel.getBookmarkDescription(idToVerify)); + } + + /** + * Before using this helper method, always make sure @param listToVerify does not contain + * duplicates. + */ + private void verifyBookmarkListNoOrder(List<BookmarkId> listToVerify, + HashSet<BookmarkId> expectedIds) { + HashSet<BookmarkId> expectedIdsCopy = new HashSet<>(expectedIds); + assertEquals(expectedIdsCopy.size(), listToVerify.size()); + for (BookmarkId id : listToVerify) { + assertNotNull(id); + assertTrue("List contains wrong element: ", expectedIdsCopy.contains(id)); + expectedIdsCopy.remove(id); + } + assertTrue("List does not contain some expected bookmarks: ", expectedIdsCopy.isEmpty()); + } +}
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 5201bd10..77169a25 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
@@ -7,6 +7,7 @@ import android.app.Notification; import android.graphics.Bitmap; import android.os.Build; +import android.test.suitebuilder.annotation.LargeTest; import android.test.suitebuilder.annotation.MediumTest; import android.util.SparseArray; @@ -34,7 +35,6 @@ public class NotificationUIManagerTest extends ChromeShellTestBase { private static final String NOTIFICATION_TEST_PAGE = TestHttpServerClient.getUrl("chrome/test/data/notifications/android_test.html"); - private static final String PERMISSION_GRANTED = "\"granted\""; private MockNotificationManagerProxy mMockNotificationManager; @@ -48,7 +48,8 @@ /** * Sets the permission to use Web Notifications for the test HTTP server's origin to |setting|. */ - private void setNotificationContentSettingForCurrentOrigin(final ContentSetting setting) { + private void setNotificationContentSettingForCurrentOrigin(final ContentSetting setting) + throws InterruptedException, TimeoutException { final String origin = getOrigin(); ThreadUtils.runOnUiThreadBlocking(new Runnable() { @@ -59,6 +60,15 @@ pushNotificationInfo.setContentSetting(setting); } }); + + String permission = runJavaScriptCodeInCurrentTab("Notification.permission"); + if (setting == ContentSetting.ALLOW) { + assertEquals("\"granted\"", permission); + } else if (setting == ContentSetting.BLOCK) { + assertEquals("\"denied\"", permission); + } else { + assertEquals("\"default\"", permission); + } } /** @@ -133,10 +143,8 @@ @Feature({"Browser", "Notifications"}) public void testDefaultNotificationProperties() throws Exception { setNotificationContentSettingForCurrentOrigin(ContentSetting.ALLOW); - assertEquals(PERMISSION_GRANTED, runJavaScriptCodeInCurrentTab("Notification.permission")); Notification notification = showAndGetNotification("MyNotification", "{ body: 'Hello' }"); - assertNotNull(notification); // Validate the contents of the notification. assertEquals("MyNotification", notification.extras.getString(Notification.EXTRA_TITLE)); @@ -165,10 +173,8 @@ @Feature({"Browser", "Notifications"}) public void testShowNotificationWithIcon() throws Exception { setNotificationContentSettingForCurrentOrigin(ContentSetting.ALLOW); - assertEquals(PERMISSION_GRANTED, runJavaScriptCodeInCurrentTab("Notification.permission")); Notification notification = showAndGetNotification("MyNotification", "{icon: 'icon.png'}"); - assertNotNull(notification); assertEquals("MyNotification", notification.extras.getString(Notification.EXTRA_TITLE)); assertNotNull(notification.largeIcon); @@ -187,10 +193,8 @@ @Feature({"Browser", "Notifications"}) public void testShowNotificationWithoutIcon() throws Exception { setNotificationContentSettingForCurrentOrigin(ContentSetting.ALLOW); - assertEquals(PERMISSION_GRANTED, runJavaScriptCodeInCurrentTab("Notification.permission")); Notification notification = showAndGetNotification("NoIconNotification", "{}"); - assertNotNull(notification); assertEquals("NoIconNotification", notification.extras.getString(Notification.EXTRA_TITLE)); assertNotNull(notification.largeIcon); @@ -207,4 +211,51 @@ assertEquals(generatedIcon.getWidth(), notification.largeIcon.getWidth()); assertEquals(generatedIcon.getHeight(), notification.largeIcon.getHeight()); } + + /* + * Verifies that starting the PendingIntent stored as the notification's content intent will + * start up the associated Service Worker, where the JavaScript code will close the notification + * by calling event.notification.close(). + */ + @LargeTest + @Feature({"Browser", "Notifications"}) + public void testNotificationContentIntentClosesNotification() throws Exception { + setNotificationContentSettingForCurrentOrigin(ContentSetting.ALLOW); + + Notification notification = showAndGetNotification("MyNotification", "{}"); + + // Sending the PendingIntent resembles activating the notification. + assertNotNull(notification.contentIntent); + notification.contentIntent.send(); + + // 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()); + + SparseArray<Notification> notifications = mMockNotificationManager.getNotifications(); + assertEquals(0, notifications.size()); + } + + /** + * Verifies that creating a notification with an associated "tag" will cause any previous + * notification with the same tag to be dismissed prior to being shown. + */ + @MediumTest + @Feature({"Browser", "Notifications"}) + public void testNotificationTagReplacement() throws Exception { + setNotificationContentSettingForCurrentOrigin(ContentSetting.ALLOW); + + Notification notification = showAndGetNotification("MyNotification", "{tag: 'myTag'}"); + + // Show the second notification with the same tag. We can't use showAndGetNotification for + // this purpose since a second notification would be shown. + runJavaScriptCodeInCurrentTab("showNotification('SecondNotification', {tag: 'myTag'});"); + assertTrue(waitForNotificationManagerMutation()); + + // Verify that the notification was successfully replaced. + SparseArray<Notification> notifications = mMockNotificationManager.getNotifications(); + assertEquals(1, notifications.size()); + assertEquals("SecondNotification", + notifications.valueAt(0).extras.getString(Notification.EXTRA_TITLE)); + } }
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/partnercustomizations/BasePartnerBrowserCustomizationUnitTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/partnercustomizations/BasePartnerBrowserCustomizationUnitTest.java index 9d071cf..9b18925 100644 --- a/chrome/android/javatests/src/org/chromium/chrome/browser/partnercustomizations/BasePartnerBrowserCustomizationUnitTest.java +++ b/chrome/android/javatests/src/org/chromium/chrome/browser/partnercustomizations/BasePartnerBrowserCustomizationUnitTest.java
@@ -9,6 +9,7 @@ import android.net.Uri; import android.test.AndroidTestCase; +import org.chromium.base.CommandLine; import org.chromium.chrome.test.partnercustomizations.TestPartnerBrowserCustomizationsDelayedProvider; import org.chromium.chrome.test.partnercustomizations.TestPartnerBrowserCustomizationsProvider; @@ -50,6 +51,12 @@ } @Override + protected void setUp() throws Exception { + super.setUp(); + CommandLine.init(null); + } + + @Override public Context getContext() { ContextWrapper context = new ContextWrapper(super.getContext()) { @Override
diff --git a/chrome/app/android/chrome_main_delegate_android.cc b/chrome/app/android/chrome_main_delegate_android.cc index e0bd8e4..840b66b 100644 --- a/chrome/app/android/chrome_main_delegate_android.cc +++ b/chrome/app/android/chrome_main_delegate_android.cc
@@ -8,7 +8,7 @@ #include "base/trace_event/trace_event.h" #include "chrome/browser/android/chrome_jni_registrar.h" #include "chrome/browser/android/chrome_startup_flags.h" -#include "chrome/browser/android/uma_utils.h" +#include "chrome/browser/android/metrics/uma_utils.h" #include "components/startup_metric_utils/startup_metric_utils.h" #include "content/public/browser/browser_main_runner.h"
diff --git a/chrome/app/chromeos_strings.grdp b/chrome/app/chromeos_strings.grdp index a34c349..47742aa 100644 --- a/chrome/app/chromeos_strings.grdp +++ b/chrome/app/chromeos_strings.grdp
@@ -1985,9 +1985,6 @@ <message name="IDS_OPTIONS_SETTINGS_STORAGE_DESCRIPTION" desc="The 'Storage' button on the chrome://settings page."> Stored data... </message> - <message name="IDS_OPTIONS_SETTINGS_TIME_SYNCED_EXPLANATION" desc="In the settings tab, the text indicating that the date and time are set automatically."> - Date and time are set automatically. - </message> <message name="IDS_OPTIONS_SETTINGS_SET_TIME_BUTTON" desc="In the settings tab, the prompt on the button to open a dialog to set date and time."> Set date and time </message>
diff --git a/chrome/app/generated_resources.grd b/chrome/app/generated_resources.grd index 0e02897d..1ade4ba 100644 --- a/chrome/app/generated_resources.grd +++ b/chrome/app/generated_resources.grd
@@ -6174,12 +6174,6 @@ <message name="IDS_FLAGS_DISABLE_TOUCH_FEEDBACK_DESCRIPTION" desc="Description for the flag that disables additional visual feedback for touch."> Certain UI components will stop displaying visual feedback upon touch interactions. </message> - <message name="IDS_FLAGS_ASH_ENABLE_SWIPE_TO_CLOSE_IN_OVERVIEW_MODE_NAME" desc="Title for the flag to enable swipe gestures to close windows while in overview mode."> - Swipe to dismiss windows in overview mode. - </message> - <message name="IDS_FLAGS_ASH_ENABLE_SWIPE_TO_CLOSE_IN_OVERVIEW_MODE_DESCRIPTION" desc="Description for the flag to enable swipe gestures to close windows while in overview mode."> - Enable swipe gesture to dismiss windows in overview mode. - </message> <message name="IDS_FLAGS_ASH_DISABLE_TEXT_FILTERING_IN_OVERVIEW_MODE_NAME" desc="Title for the flag to disable window filtering in overview mode by inputing text"> Disable text filtering in Overview Mode. </message> @@ -9389,7 +9383,7 @@ </message> <message name="IDS_ERRORPAGES_ERROR_CODE" desc="At the bottom of error pages, a non-internationalized string or numeric code is displayed for debugging purposes"> - Error code: <ph name="ERROR_NAME">$1<ex>ERR_FILE_NOT_FOUND</ex></ph> + <ph name="ERROR_NAME">$1<ex>ERR_FILE_NOT_FOUND</ex></ph> </message> <message name="IDS_ERRORPAGES_DETAILS_TIMED_OUT" desc="The error message displayed when a page takes too long to load."> @@ -11185,6 +11179,15 @@ <message name="IDS_AUTOFILL_CARD_UNMASK_PROMPT_STORAGE_CHECKBOX" desc="Text for checkbox in card unmasking dialog that allows user to store a Wallet card on their local device. If checked, the dialog won't show up again for the given credit card."> Don't ask again for this card </message> + <message name="IDS_AUTOFILL_CARD_UNMASK_PROMPT_ERROR_TRY_AGAIN" desc="Error message that encourages the user to try to re-enter their credit card CVC after a previous failed attempt."> + There was a problem verifying your card. Check your information and try again. + </message> + <message name="IDS_AUTOFILL_CARD_UNMASK_PROMPT_ERROR_PERMANENT" desc="Error message to show when a credit card cannot be verified and the user isn't allowed to retry."> + Chrome was unable to verify your card at this time. Please try again later. + </message> + <message name="IDS_AUTOFILL_CARD_UNMASK_PROMPT_ERROR_NETWORK" desc="Error message to show when a credit card cannot be verified because Wallet servers can't be reached."> + There was a problem verifying your card. Check your internet connection and try again. + </message> <message name="IDS_APPEARANCE_GROUP_NAME" desc="The title of the appearance group"> Appearance
diff --git a/chrome/browser/BUILD.gn b/chrome/browser/BUILD.gn index 975c68c..ce8af0fc 100644 --- a/chrome/browser/BUILD.gn +++ b/chrome/browser/BUILD.gn
@@ -93,6 +93,7 @@ "//components/enhanced_bookmarks", "//components/favicon_base", "//components/favicon/core", + "//components/feedback", "//components/gcm_driver", "//components/google/core/browser", "//components/handoff", @@ -582,7 +583,6 @@ ".", "//chrome") deps += [ - "//components/feedback", "//device/core", "//device/usb", ] @@ -603,6 +603,7 @@ ] deps -= [ "//third_party/libaddressinput", + "//components/feedback", "//components/storage_monitor", "//components/web_modal", ]
diff --git a/chrome/browser/about_flags.cc b/chrome/browser/about_flags.cc index 577ad8e..7f41b7f 100644 --- a/chrome/browser/about_flags.cc +++ b/chrome/browser/about_flags.cc
@@ -953,14 +953,6 @@ kOsAll, SINGLE_VALUE_TYPE(ash::switches::kAshDebugShortcuts), }, - { - "ash-enable-swipe-to-close-in-overview-mode", - IDS_FLAGS_ASH_ENABLE_SWIPE_TO_CLOSE_IN_OVERVIEW_MODE_NAME, - IDS_FLAGS_ASH_ENABLE_SWIPE_TO_CLOSE_IN_OVERVIEW_MODE_DESCRIPTION, - // TODO(bruthig): Add kOsWin when http://crbug.com/333758 is resolved. - kOsCrOS, - SINGLE_VALUE_TYPE(ash::switches::kAshEnableSwipeToCloseInOverviewMode), - }, { "ash-enable-touch-view-testing", IDS_FLAGS_ASH_ENABLE_TOUCH_VIEW_TESTING_NAME, IDS_FLAGS_ASH_ENABLE_TOUCH_VIEW_TESTING_DESCRIPTION,
diff --git a/chrome/browser/android/chrome_jni_registrar.cc b/chrome/browser/android/chrome_jni_registrar.cc index 62091e0b6..0ff52278 100644 --- a/chrome/browser/android/chrome_jni_registrar.cc +++ b/chrome/browser/android/chrome_jni_registrar.cc
@@ -32,6 +32,9 @@ #include "chrome/browser/android/intent_helper.h" #include "chrome/browser/android/location_settings_impl.h" #include "chrome/browser/android/logo_bridge.h" +#include "chrome/browser/android/metrics/uma_bridge.h" +#include "chrome/browser/android/metrics/uma_session_stats.h" +#include "chrome/browser/android/metrics/uma_utils.h" #include "chrome/browser/android/most_visited_sites.h" #include "chrome/browser/android/new_tab_page_prefs.h" #include "chrome/browser/android/omnibox/answers_image_bridge.h" @@ -50,8 +53,6 @@ #include "chrome/browser/android/signin/signin_manager_android.h" #include "chrome/browser/android/tab_android.h" #include "chrome/browser/android/tab_state.h" -#include "chrome/browser/android/uma_bridge.h" -#include "chrome/browser/android/uma_utils.h" #include "chrome/browser/android/url_utilities.h" #include "chrome/browser/android/voice_search_tab_helper.h" #include "chrome/browser/autofill/android/personal_data_manager_android.h" @@ -229,6 +230,7 @@ {"TranslateInfoBarDelegate", RegisterTranslateInfoBarDelegate}, {"TtsPlatformImpl", TtsPlatformImplAndroid::Register}, {"UmaBridge", RegisterUmaBridge}, + {"UmaSessionStats", RegisterUmaSessionStats}, {"UrlUtilities", RegisterUrlUtilities}, {"Variations", variations::android::RegisterVariations}, {"VoiceSearchTabHelper", RegisterVoiceSearchTabHelper},
diff --git a/chrome/browser/android/chrome_web_contents_delegate_android.cc b/chrome/browser/android/chrome_web_contents_delegate_android.cc index 8194f89d..ecc988d 100644 --- a/chrome/browser/android/chrome_web_contents_delegate_android.cc +++ b/chrome/browser/android/chrome_web_contents_delegate_android.cc
@@ -371,3 +371,10 @@ return indicator->IsCapturingVideo(web_contents); } +jboolean HasAudibleAudio(JNIEnv* env, + jclass clazz, + jobject java_web_contents) { + content::WebContents* web_contents = + content::WebContents::FromJavaWebContents(java_web_contents); + return web_contents->WasRecentlyAudible(); +}
diff --git a/chrome/browser/android/metrics/OWNERS b/chrome/browser/android/metrics/OWNERS new file mode 100644 index 0000000..7755f6b --- /dev/null +++ b/chrome/browser/android/metrics/OWNERS
@@ -0,0 +1,4 @@ +asvitkine@chromium.org +dfalcantara@chromium.org +mariakhomenko@chromium.org +
diff --git a/chrome/browser/android/uma_bridge.cc b/chrome/browser/android/metrics/uma_bridge.cc similarity index 97% rename from chrome/browser/android/uma_bridge.cc rename to chrome/browser/android/metrics/uma_bridge.cc index 2b27ee5..9577106 100644 --- a/chrome/browser/android/uma_bridge.cc +++ b/chrome/browser/android/metrics/uma_bridge.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 "chrome/browser/android/uma_bridge.h" +#include "chrome/browser/android/metrics/uma_bridge.h" #include <jni.h>
diff --git a/chrome/browser/android/uma_bridge.h b/chrome/browser/android/metrics/uma_bridge.h similarity index 68% rename from chrome/browser/android/uma_bridge.h rename to chrome/browser/android/metrics/uma_bridge.h index c68c841..0badc05d 100644 --- a/chrome/browser/android/uma_bridge.h +++ b/chrome/browser/android/metrics/uma_bridge.h
@@ -2,8 +2,8 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#ifndef CHROME_BROWSER_ANDROID_UMA_BRIDGE_H_ -#define CHROME_BROWSER_ANDROID_UMA_BRIDGE_H_ +#ifndef CHROME_BROWSER_ANDROID_METRICS_UMA_BRIDGE_H_ +#define CHROME_BROWSER_ANDROID_METRICS_UMA_BRIDGE_H_ #include <jni.h> @@ -16,4 +16,4 @@ } // namespace android } // namespace chrome -#endif // CHROME_BROWSER_ANDROID_UMA_BRIDGE_H_ +#endif // CHROME_BROWSER_ANDROID_METRICS_UMA_BRIDGE_H_
diff --git a/chrome/browser/android/metrics/uma_session_stats.cc b/chrome/browser/android/metrics/uma_session_stats.cc new file mode 100644 index 0000000..f4b2981 --- /dev/null +++ b/chrome/browser/android/metrics/uma_session_stats.cc
@@ -0,0 +1,199 @@ +// 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/android/metrics/uma_session_stats.h" + +#include "base/android/jni_string.h" +#include "base/command_line.h" +#include "base/metrics/histogram.h" +#include "base/prefs/pref_service.h" +#include "base/strings/string_number_conversions.h" +#include "base/time/time.h" +#include "chrome/browser/browser_process.h" +#include "chrome/browser/metrics/chrome_metrics_service_accessor.h" +#include "chrome/browser/metrics/metrics_services_manager.h" +#include "chrome/common/chrome_switches.h" +#include "chrome/common/pref_names.h" +#include "chrome/installer/util/google_update_settings.h" +#include "components/metrics/metrics_service.h" +#include "components/variations/metrics_util.h" +#include "components/variations/variations_associated_data.h" +#include "content/public/browser/browser_thread.h" +#include "content/public/browser/user_metrics.h" +#include "jni/UmaSessionStats_jni.h" + +using base::android::ConvertJavaStringToUTF8; +using base::UserMetricsAction; + +namespace { +UmaSessionStats* g_uma_session_stats = NULL; +} // namespace + +UmaSessionStats::UmaSessionStats() + : active_session_count_(0) { +} + +UmaSessionStats::~UmaSessionStats() { +} + +void UmaSessionStats::UmaResumeSession(JNIEnv* env, jobject obj) { + DCHECK(g_browser_process); + + if (active_session_count_ == 0) { + session_start_time_ = base::TimeTicks::Now(); + + // Tell the metrics service that the application resumes. + metrics::MetricsService* metrics = g_browser_process->metrics_service(); + if (metrics) { + metrics->OnAppEnterForeground(); + } + } + ++active_session_count_; +} + +void UmaSessionStats::UmaEndSession(JNIEnv* env, jobject obj) { + --active_session_count_; + DCHECK(active_session_count_ >= 0); + + if (active_session_count_ == 0) { + base::TimeDelta duration = base::TimeTicks::Now() - session_start_time_; + UMA_HISTOGRAM_LONG_TIMES("Session.TotalDuration", duration); + + DCHECK(g_browser_process); + // Tell the metrics service it was cleanly shutdown. + metrics::MetricsService* metrics = g_browser_process->metrics_service(); + if (metrics) { + metrics->OnAppEnterBackground(); + } + } +} + +// static +void UmaSessionStats::RegisterSyntheticFieldTrialWithNameHash( + uint32_t trial_name_hash, + const std::string& group_name) { + ChromeMetricsServiceAccessor::RegisterSyntheticFieldTrialWithNameHash( + trial_name_hash, group_name); +} + +// static +void UmaSessionStats::RegisterSyntheticFieldTrial( + const std::string& trial_name, + const std::string& group_name) { + ChromeMetricsServiceAccessor::RegisterSyntheticFieldTrial(trial_name, + group_name); +} + +// Starts/stops the MetricsService when permissions have changed. +// There are three possible states: +// * Logs are being recorded and being uploaded to the server. +// * Logs are being recorded, but not being uploaded to the server. +// This happens when we've got permission to upload on Wi-Fi but we're on a +// mobile connection (for example). +// * Logs are neither being recorded or uploaded. +static void UpdateMetricsServiceState(JNIEnv* env, jobject obj, + jboolean may_record, jboolean may_upload) { + metrics::MetricsService* metrics = g_browser_process->metrics_service(); + DCHECK(metrics); + + if (metrics->recording_active() != may_record) { + // This function puts a consent file with the ClientID in the + // data directory. The ID is passed to the renderer for crash + // reporting when things go wrong. + content::BrowserThread::GetBlockingPool()->PostTask(FROM_HERE, + base::Bind( + base::IgnoreResult(GoogleUpdateSettings::SetCollectStatsConsent), + may_record)); + } + + g_browser_process->GetMetricsServicesManager()->UpdatePermissions( + may_record, may_upload); +} + +// Renderer process crashed in the foreground. +static void LogRendererCrash(JNIEnv* env, jclass clazz, jboolean is_paused) { + DCHECK(g_browser_process); + + if (!is_paused) { + // Increment the renderer crash count in stability metrics. + PrefService* pref = g_browser_process->local_state(); + DCHECK(pref); + int value = pref->GetInteger(prefs::kStabilityRendererCrashCount); + pref->SetInteger(prefs::kStabilityRendererCrashCount, value + 1); + } + + // Note: When we are paused, any UI metric we increment may not make it to + // the disk before we are killed. Treat the count below as a lower bound. + content::RecordAction(base::UserMetricsAction("MobileRendererCrashed")); +} + +static void RegisterExternalExperiment(JNIEnv* env, + jclass clazz, + jint study_id, + jint experiment_id) { + const std::string group_name_utf8 = base::IntToString(experiment_id); + + variations::ActiveGroupId active_group; + active_group.name = static_cast<uint32>(study_id); + active_group.group = metrics::HashName(group_name_utf8); + variations::AssociateGoogleVariationIDForceHashes( + variations::GOOGLE_WEB_PROPERTIES, active_group, + static_cast<variations::VariationID>(experiment_id)); + + UmaSessionStats::RegisterSyntheticFieldTrialWithNameHash( + static_cast<uint32_t>(study_id), group_name_utf8); +} + +static void RegisterSyntheticFieldTrial(JNIEnv* env, + jclass clazz, + jstring jtrial_name, + jstring jgroup_name) { + std::string trial_name(ConvertJavaStringToUTF8(env, jtrial_name)); + std::string group_name(ConvertJavaStringToUTF8(env, jgroup_name)); + UmaSessionStats::RegisterSyntheticFieldTrial(trial_name, group_name); +} + +static void RecordMultiWindowSession(JNIEnv*, jclass, + jint area_percent, + jint instance_count) { + UMA_HISTOGRAM_PERCENTAGE("MobileStartup.MobileMultiWindowSession", + area_percent); + // Make sure the bucket count is the same as the range. This currently + // expects no more than 10 simultaneous multi window instances. + UMA_HISTOGRAM_CUSTOM_COUNTS("MobileStartup.MobileMultiWindowInstances", + instance_count, + 1 /* min */, + 10 /* max */, + 10 /* bucket count */); +} + +static void RecordTabCountPerLoad(JNIEnv*, jclass, jint num_tabs) { + // Record how many tabs total are open. + UMA_HISTOGRAM_CUSTOM_COUNTS("Tabs.TabCountPerLoad", num_tabs, 1, 200, 50); +} + +static void RecordPageLoaded(JNIEnv*, jclass, jboolean is_desktop_user_agent) { + // Should be called whenever a page has been loaded. + content::RecordAction(UserMetricsAction("MobilePageLoaded")); + if (is_desktop_user_agent) { + content::RecordAction( + UserMetricsAction("MobilePageLoadedDesktopUserAgent")); + } +} + +static void RecordPageLoadedWithKeyboard(JNIEnv*, jclass) { + content::RecordAction(UserMetricsAction("MobilePageLoadedWithKeyboard")); +} + +static jlong Init(JNIEnv* env, jclass obj) { + // We should have only one UmaSessionStats instance. + DCHECK(!g_uma_session_stats); + g_uma_session_stats = new UmaSessionStats(); + return reinterpret_cast<intptr_t>(g_uma_session_stats); +} + +// Register native methods +bool RegisterUmaSessionStats(JNIEnv* env) { + return RegisterNativesImpl(env); +}
diff --git a/chrome/browser/android/metrics/uma_session_stats.h b/chrome/browser/android/metrics/uma_session_stats.h new file mode 100644 index 0000000..173d342 --- /dev/null +++ b/chrome/browser/android/metrics/uma_session_stats.h
@@ -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. + +#ifndef CHROME_BROWSER_ANDROID_METRICS_UMA_SESSION_STATS_H_ +#define CHROME_BROWSER_ANDROID_METRICS_UMA_SESSION_STATS_H_ + +#include <jni.h> +#include <string> + +#include "base/memory/scoped_ptr.h" +#include "base/time/time.h" + +class UserActionRateCounter; + +// The native part of java UmaSessionStats class. +class UmaSessionStats { + public: + UmaSessionStats(); + + void UmaResumeSession(JNIEnv* env, jobject obj); + void UmaEndSession(JNIEnv* env, jobject obj); + + static void RegisterSyntheticFieldTrialWithNameHash( + uint32_t trial_name_hash, + const std::string& group_name); + + static void RegisterSyntheticFieldTrial( + const std::string& trial_name, + const std::string& group_name); + + private: + ~UmaSessionStats(); + + // Start of the current session, used for UMA. + base::TimeTicks session_start_time_; + int active_session_count_; + + DISALLOW_COPY_AND_ASSIGN(UmaSessionStats); +}; + +// Registers the native methods through jni +bool RegisterUmaSessionStats(JNIEnv* env); + +#endif // CHROME_BROWSER_ANDROID_METRICS_UMA_SESSION_STATS_H_
diff --git a/chrome/browser/android/uma_utils.cc b/chrome/browser/android/metrics/uma_utils.cc similarity index 91% rename from chrome/browser/android/uma_utils.cc rename to chrome/browser/android/metrics/uma_utils.cc index 0e9152d..12d9f18 100644 --- a/chrome/browser/android/uma_utils.cc +++ b/chrome/browser/android/metrics/uma_utils.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 "chrome/browser/android/uma_utils.h" +#include "chrome/browser/android/metrics/uma_utils.h" #include "jni/UmaUtils_jni.h"
diff --git a/chrome/browser/android/uma_utils.h b/chrome/browser/android/metrics/uma_utils.h similarity index 70% rename from chrome/browser/android/uma_utils.h rename to chrome/browser/android/metrics/uma_utils.h index 0853033..d455b126 100644 --- a/chrome/browser/android/uma_utils.h +++ b/chrome/browser/android/metrics/uma_utils.h
@@ -2,8 +2,8 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#ifndef CHROME_BROWSER_ANDROID_UMA_UTILS_H_ -#define CHROME_BROWSER_ANDROID_UMA_UTILS_H_ +#ifndef CHROME_BROWSER_ANDROID_METRICS_UMA_UTILS_H_ +#define CHROME_BROWSER_ANDROID_METRICS_UMA_UTILS_H_ #include <jni.h> @@ -18,4 +18,4 @@ } // namespace android } // namespace chrome -#endif // CHROME_BROWSER_ANDROID_UMA_UTILS_H_ +#endif // CHROME_BROWSER_ANDROID_METRICS_UMA_UTILS_H_
diff --git a/chrome/browser/android/tab_android.cc b/chrome/browser/android/tab_android.cc index 66369ac..e9289de 100644 --- a/chrome/browser/android/tab_android.cc +++ b/chrome/browser/android/tab_android.cc
@@ -12,7 +12,7 @@ #include "cc/layers/layer.h" #include "chrome/browser/android/chrome_web_contents_delegate_android.h" #include "chrome/browser/android/compositor/tab_content_manager.h" -#include "chrome/browser/android/uma_utils.h" +#include "chrome/browser/android/metrics/uma_utils.h" #include "chrome/browser/bookmarks/bookmark_model_factory.h" #include "chrome/browser/bookmarks/chrome_bookmark_client.h" #include "chrome/browser/bookmarks/chrome_bookmark_client_factory.h"
diff --git a/chrome/browser/app_controller_mac.mm b/chrome/browser/app_controller_mac.mm index 01feef4d..866f7c0 100644 --- a/chrome/browser/app_controller_mac.mm +++ b/chrome/browser/app_controller_mac.mm
@@ -897,7 +897,9 @@ // already loaded a new one, so the pointer needs to be updated; // otherwise we will try to start up a browser window with a pointer // to the old profile. - if (lastProfile_ && profilePath == lastProfile_->GetPath()) + // In a browser test, the application is not brought to the front, so + // |lastProfile_| might be null. + if (!lastProfile_ || profilePath == lastProfile_->GetPath()) lastProfile_ = g_browser_process->profile_manager()->GetLastUsedProfile(); auto it = profileBookmarkMenuBridgeMap_.find(profilePath);
diff --git a/chrome/browser/apps/custom_launcher_page_browsertest_views.cc b/chrome/browser/apps/custom_launcher_page_browsertest_views.cc index 8f4fb35..561280b 100644 --- a/chrome/browser/apps/custom_launcher_page_browsertest_views.cc +++ b/chrome/browser/apps/custom_launcher_page_browsertest_views.cc
@@ -20,8 +20,11 @@ #include "ui/app_list/views/app_list_main_view.h" #include "ui/app_list/views/app_list_view.h" #include "ui/app_list/views/contents_view.h" +#include "ui/app_list/views/search_box_view.h" #include "ui/events/test/event_generator.h" +#include "ui/views/controls/textfield/textfield.h" #include "ui/views/controls/webview/webview.h" +#include "ui/views/focus/focus_manager.h" namespace { @@ -383,3 +386,43 @@ EXPECT_TRUE(model->custom_launcher_page_enabled()); EXPECT_TRUE(custom_page_view->visible()); } + +IN_PROC_BROWSER_TEST_F(CustomLauncherPageBrowserTest, + LauncherPageFocusTraversal) { + LoadAndLaunchPlatformApp(kCustomLauncherPagePath, "Launched"); + app_list::AppListView* app_list_view = GetAppListView(); + app_list::ContentsView* contents_view = + app_list_view->app_list_main_view()->contents_view(); + app_list::SearchBoxView* search_box_view = + app_list_view->app_list_main_view()->search_box_view(); + + ASSERT_TRUE( + contents_view->IsStateActive(app_list::AppListModel::STATE_START)); + EXPECT_EQ(app_list_view->GetFocusManager()->GetFocusedView(), + search_box_view->search_box()); + + { + ExtensionTestMessageListener listener("onPageProgressAt1", false); + contents_view->SetActivePage(contents_view->GetPageIndexForState( + app_list::AppListModel::STATE_CUSTOM_LAUNCHER_PAGE)); + listener.WaitUntilSatisfied(); + EXPECT_TRUE(contents_view->IsStateActive( + app_list::AppListModel::STATE_CUSTOM_LAUNCHER_PAGE)); + EXPECT_EQ(app_list_view->GetFocusManager()->GetFocusedView(), + search_box_view->search_box()); + } + { + ExtensionTestMessageListener listener("textfieldFocused", false); + app_list_view->GetFocusManager()->AdvanceFocus(false); + listener.WaitUntilSatisfied(); + EXPECT_NE(app_list_view->GetFocusManager()->GetFocusedView(), + search_box_view->search_box()); + } + { + ExtensionTestMessageListener listener("textfieldBlurred", false); + app_list_view->GetFocusManager()->AdvanceFocus(false); + listener.WaitUntilSatisfied(); + EXPECT_EQ(app_list_view->GetFocusManager()->GetFocusedView(), + search_box_view->search_box()); + } +}
diff --git a/chrome/browser/apps/ephemeral_app_browsertest.cc b/chrome/browser/apps/ephemeral_app_browsertest.cc index 04c96fe..fd1d298 100644 --- a/chrome/browser/apps/ephemeral_app_browsertest.cc +++ b/chrome/browser/apps/ephemeral_app_browsertest.cc
@@ -23,7 +23,7 @@ #include "content/public/browser/power_save_blocker.h" #include "content/public/test/browser_test.h" #include "content/public/test/test_utils.h" -#include "extensions/browser/api/power/power_api_manager.h" +#include "extensions/browser/api/power/power_api.h" #include "extensions/browser/app_sorting.h" #include "extensions/browser/event_router.h" #include "extensions/browser/extension_prefs.h" @@ -1028,9 +1028,7 @@ // chrome.power.releaseKeepAwake() themselves. IN_PROC_BROWSER_TEST_F(EphemeralAppBrowserTest, ReleasePowerKeepAwake) { PowerSettingsMock power_settings; - extensions::PowerApiManager* power_manager = - extensions::PowerApiManager::Get(profile()); - power_manager->SetCreateBlockerFunctionForTesting( + extensions::PowerAPI::Get(profile())->SetCreateBlockerFunctionForTesting( base::Bind(&PowerSaveBlockerStub::Create, &power_settings)); const Extension* app = InstallAndLaunchEphemeralApp(kPowerTestApp);
diff --git a/chrome/browser/autofill/form_structure_browsertest.cc b/chrome/browser/autofill/form_structure_browsertest.cc index 455325b..52bcb4d 100644 --- a/chrome/browser/autofill/form_structure_browsertest.cc +++ b/chrome/browser/autofill/form_structure_browsertest.cc
@@ -46,16 +46,6 @@ } const std::vector<base::FilePath> GetTestFiles() { - static const base::FilePath::CharType* const kFilesToSkip[] = { - FILE_PATH_LITERAL("bug_459132.html"), - FILE_PATH_LITERAL("bug_454366b.html"), - FILE_PATH_LITERAL("bug_454366.html"), - FILE_PATH_LITERAL("25_checkout_m_llbean.com.html"), - }; - std::set<base::FilePath> set_of_files_to_skip; - for (size_t i = 0; i < arraysize(kFilesToSkip); ++i) - set_of_files_to_skip.insert(base::FilePath(kFilesToSkip[i])); - base::FilePath dir; CHECK(PathService::Get(base::DIR_SOURCE_ROOT, &dir)); dir = dir.AppendASCII("chrome/test/data/autofill") @@ -65,8 +55,7 @@ std::vector<base::FilePath> files; for (base::FilePath input_file = input_files.Next(); !input_file.empty(); input_file = input_files.Next()) { - if (!ContainsKey(set_of_files_to_skip, input_file.BaseName())) - files.push_back(input_file); + files.push_back(input_file); } std::sort(files.begin(), files.end());
diff --git a/chrome/browser/chrome_browser_main.cc b/chrome/browser/chrome_browser_main.cc index 3af4c61..d0e92847 100644 --- a/chrome/browser/chrome_browser_main.cc +++ b/chrome/browser/chrome_browser_main.cc
@@ -144,18 +144,18 @@ #include "chrome/browser/metrics/thread_watcher_android.h" #else #include "chrome/browser/feedback/feedback_profile_observer.h" -#endif +#endif // defined(OS_ANDROID) #if defined(OS_LINUX) && !defined(OS_CHROMEOS) #include "chrome/browser/first_run/upgrade_util_linux.h" #include "chrome/browser/sxs_linux.h" -#endif +#endif // defined(OS_LINUX) && !defined(OS_CHROMEOS) #if defined(OS_CHROMEOS) #include "chrome/browser/chromeos/settings/cros_settings.h" #include "chromeos/chromeos_switches.h" #include "chromeos/settings/cros_settings_names.h" -#endif +#endif // defined(OS_CHROMEOS) // TODO(port): several win-only methods have been pulled out of this, but // BrowserMain() as a whole needs to be broken apart so that it's usable by @@ -188,38 +188,38 @@ #include "base/mac/scoped_nsautorelease_pool.h" #include "chrome/browser/mac/keystone_glue.h" -#endif +#endif // defined(OS_MACOSX) #if !defined(OS_IOS) #include "chrome/browser/ui/app_modal/chrome_javascript_native_dialog_factory.h" -#endif +#endif // !defined(OS_IOS) #if !defined(DISABLE_NACL) #include "chrome/browser/component_updater/pnacl/pnacl_component_installer.h" #include "components/nacl/browser/nacl_process_host.h" -#endif +#endif // !defined(DISABLE_NACL) #if defined(ENABLE_EXTENSIONS) #include "chrome/browser/extensions/startup_helper.h" #include "extensions/browser/extension_protocols.h" #include "extensions/components/javascript_dialog_extensions_client/javascript_dialog_extension_client_impl.h" -#endif +#endif // defined(ENABLE_EXTENSIONS) #if defined(ENABLE_PRINT_PREVIEW) && !defined(OFFICIAL_BUILD) #include "printing/printed_document.h" -#endif +#endif // defined(ENABLE_PRINT_PREVIEW) && !defined(OFFICIAL_BUILD) #if defined(ENABLE_RLZ) #include "chrome/browser/rlz/rlz.h" -#endif +#endif // defined(ENABLE_RLZ) #if defined(ENABLE_WEBRTC) #include "chrome/browser/media/webrtc_log_util.h" -#endif +#endif // defined(ENABLE_WEBRTC) #if defined(USE_AURA) #include "ui/aura/env.h" -#endif +#endif // defined(USE_AURA) using content::BrowserThread; @@ -318,7 +318,7 @@ local_state->SetString(prefs::kApplicationLocale, owner_locale); } } -#endif +#endif // defined(OS_CHROMEOS) return local_state; } @@ -379,7 +379,7 @@ profile = g_browser_process->profile_manager()->GetProfile( ProfileManager::GetGuestProfilePath()); } -#endif +#endif // defined(OS_CHROMEOS) || defined(OS_ANDROID) if (profile) { UMA_HISTOGRAM_LONG_TIMES( "Startup.CreateFirstProfile", base::Time::Now() - start); @@ -391,7 +391,7 @@ // user_data_dir. It is better to CHECK-fail here than it is to // silently exit because of missing code in the above test. CHECK(profile) << "Cannot get default profile."; -#endif +#endif // !defined(OS_WIN) return NULL; } @@ -401,7 +401,7 @@ SecKeychainCallbackInfo* info, void* context) { return noErr; } -#endif +#endif // defined(OS_MACOSX) void RegisterComponentsForUpdate() { component_updater::ComponentUpdateService* cus = @@ -415,7 +415,7 @@ RegisterPepperFlashComponent(cus); RegisterSwiftShaderComponent(cus); RegisterWidevineCdmComponent(cus); -#endif +#endif // !defined(OS_CHROMEOS) && !defined(OS_ANDROID) #if !defined(DISABLE_NACL) && !defined(OS_ANDROID) #if defined(OS_CHROMEOS) @@ -423,9 +423,9 @@ // Chrome4ChromeOS on Linux doesn't contain PNaCl so enable component // installer when running on Linux. See crbug.com/422121 for more details. if (!base::SysInfo::IsRunningOnChromeOS()) -#endif +#endif // defined(OS_CHROMEOS) g_browser_process->pnacl_component_installer()->RegisterPnaclComponent(cus); -#endif +#endif // !defined(DISABLE_NACL) && !defined(OS_ANDROID) // Registration of the CLD Component is a no-op unless the CLD data source has // been configured to be the "Component" data source. @@ -450,13 +450,13 @@ // 1. Android: Because it currently does not have the EV indicator. // 2. Chrome OS: On Chrome OS this registration is delayed until user login. RegisterEVWhitelistComponent(cus, path); -#endif +#endif // defined(OS_ANDROID) } #if defined(OS_WIN) RegisterSwReporterComponent(cus, g_browser_process->local_state()); RegisterCAPSComponent(cus); -#endif +#endif // defined(OS_WIN) cus->Start(); } @@ -471,7 +471,7 @@ browser_watcher::ExitFunnel::RecordSingleEvent( chrome::kBrowserExitCodesRegistryPath, L"ProcessSingletonIsShuttingDown"); -#endif +#endif // defined(OS_WIN) return false; } @@ -556,13 +556,13 @@ // localization data files. #if defined(OS_WIN) const char kMissingLocaleDataTitle[] = "Missing File Error"; -#endif +#endif // defined(OS_WIN) #if defined(OS_WIN) // TODO(port) This should be used on Linux Aura as well. http://crbug.com/338969 const char kMissingLocaleDataMessage[] = "Unable to find locale data files. Please reinstall."; -#endif +#endif // defined(OS_WIN) } // namespace chrome_browser @@ -702,7 +702,7 @@ bool is_first_run = false; #else bool is_first_run = first_run::IsChromeFirstRun(); -#endif +#endif // defined(OS_ANDROID) // CurrentProcessInfo::CreationTime() is currently only implemented on some // platforms. @@ -787,7 +787,7 @@ // These members must be initialized before exiting this function normally. DCHECK(master_prefs_.get()); DCHECK(browser_creator_.get()); -#endif +#endif // !defined(OS_ANDROID) for (size_t i = 0; i < chrome_extra_parts_.size(); ++i) chrome_extra_parts_[i]->PreCreateThreads(); } @@ -800,7 +800,7 @@ run_message_loop_ = false; #if !defined(OS_ANDROID) chrome::MaybeShowInvalidUserDataDirWarningDialog(); -#endif +#endif // !defined(OS_ANDROID) if (!PathService::Get(chrome::DIR_USER_DATA, &user_data_dir_)) return chrome::RESULT_CODE_MISSING_DATA; @@ -814,7 +814,7 @@ // Cache first run state early. first_run::IsChromeFirstRun(); -#endif +#endif // !defined(OS_ANDROID) scoped_refptr<base::SequencedTaskRunner> local_state_task_runner = JsonPrefStore::GetTaskRunnerForFile( @@ -860,7 +860,7 @@ browser_creator_.reset(new StartupBrowserCreator); // TODO(yfriedman): Refactor Android to re-use UMABrowsingActivityObserver chrome::UMABrowsingActivityObserver::Init(); -#endif +#endif // !defined(OS_ANDROID) #if !defined(OS_CHROMEOS) // Convert active labs into switches. This needs to be done before @@ -877,7 +877,7 @@ base::CommandLine::ForCurrentProcess(), about_flags::kAddSentinels); } -#endif +#endif // !defined(OS_CHROMEOS) local_state_->UpdateCommandLinePrefStore( new CommandLinePrefStore(base::CommandLine::ForCurrentProcess())); @@ -982,13 +982,13 @@ master_prefs_->suppress_default_browser_prompt_for_version); } } -#endif +#endif // !defined(OS_ANDROID) && !defined(OS_CHROMEOS) #if defined(OS_LINUX) || defined(OS_OPENBSD) || defined(OS_MACOSX) // Set the product channel for crash reports. base::debug::SetCrashKeyValue(crash_keys::kChannel, chrome::VersionInfo::GetVersionStringModifier()); -#endif +#endif // defined(OS_LINUX) || defined(OS_OPENBSD) || defined(OS_MACOSX) // Initialize tracking synchronizer system. tracking_synchronizer_ = new metrics::TrackingSynchronizer(); @@ -1001,13 +1001,13 @@ // (Note that the callback mask here is empty. I don't want to register for // any callbacks, I just want to initialize the mechanism.) SecKeychainAddCallback(&KeychainCallback, 0, NULL); -#endif +#endif // defined(OS_MACOSX) #if defined(OS_CHROMEOS) // Must be done after g_browser_process is constructed, before // SetupMetricsAndFieldTrials(). chromeos::CrosSettings::Initialize(); -#endif +#endif // defined(OS_CHROMEOS) // Now the command line has been mutated based on about:flags, we can setup // metrics and initialize field trials. The field trials are needed by @@ -1073,15 +1073,15 @@ BrowserThread::FILE, FROM_HERE, base::Bind(&ProfileManager::CleanUpStaleProfiles, profiles_to_delete)); } -#endif // OS_ANDROID +#endif // !defined(OS_ANDROID) #if defined(ENABLE_EXTENSIONS) javascript_dialog_extensions_client::InstallClient(); -#endif +#endif // defined(ENABLE_EXTENSIONS) #if !defined(OS_IOS) InstallChromeJavaScriptNativeDialogFactory(); -#endif +#endif // !defined(OS_IOS) } void ChromeBrowserMainParts::PostProfileInit() { @@ -1106,7 +1106,7 @@ #if !defined(OS_ANDROID) // Allow ProcessSingleton to process messages. process_singleton_->Unlock(); -#endif +#endif // !defined(OS_ANDROID) #if defined(ENABLE_WEBRTC) // Set up a task to delete old WebRTC log files for all profiles. Use a delay // to reduce the impact on startup time. @@ -1115,18 +1115,19 @@ FROM_HERE, base::Bind(&WebRtcLogUtil::DeleteOldWebRtcLogFilesForAllProfiles), base::TimeDelta::FromMinutes(1)); -#endif +#endif // defined(ENABLE_WEBRTC) } int ChromeBrowserMainParts::PreMainMessageLoopRunImpl() { TRACE_EVENT0("startup", "ChromeBrowserMainParts::PreMainMessageLoopRunImpl"); SCOPED_UMA_HISTOGRAM_LONG_TIMER("Startup.PreMainMessageLoopRunImplLongTime"); + const base::TimeTicks start_time_step1 = base::TimeTicks::Now(); // Android updates the metrics service dynamically depending on whether the // application is in the foreground or not. Do not start here. #if !defined(OS_ANDROID) // Now that the file thread has been started, start recording. StartMetricsRecording(); -#endif +#endif // !defined(OS_ANDROID) if (!base::debug::BeingDebugged()) { // Create watchdog thread after creating all other threads because it will @@ -1161,7 +1162,7 @@ ui::SelectFileDialog::SetFactory(new ChromeSelectFileDialogFactory( BrowserThread::GetMessageLoopProxyForThread(BrowserThread::IO))); -#endif +#endif // defined(OS_WIN) if (parsed_command_line().HasSwitch(switches::kMakeDefaultBrowser)) { return ShellIntegration::SetAsDefaultBrowser() ? @@ -1172,7 +1173,7 @@ #if defined(USE_AURA) // Make sure aura::Env has been initialized. CHECK(aura::Env::GetInstance()); -#endif +#endif // defined(USE_AURA) // Android doesn't support extensions and doesn't implement ProcessSingleton. #if !defined(OS_ANDROID) @@ -1203,9 +1204,11 @@ case ProcessSingleton::PROCESS_NOTIFIED: #if defined(OS_POSIX) && !defined(OS_MACOSX) + // On POSIX systems, print a message notifying the process is running. printf("%s\n", base::SysWideToNativeMB(base::UTF16ToWide( l10n_util::GetStringUTF16(IDS_USED_EXISTING_BROWSER))).c_str()); -#endif +#endif // defined(OS_POSIX) && !defined(OS_MACOSX) + // Having a differentiated return type for testing allows for tests to // verify proper handling of some switches. When not testing, stick to // the standard Unix convention of returning zero when things went as @@ -1293,6 +1296,12 @@ metrics::MetricsService::SetExecutionPhase( metrics::MetricsService::CREATE_PROFILE, g_browser_process->local_state()); + + UMA_HISTOGRAM_TIMES("Startup.PreMainMessageLoopRunImplStep1Time", + base::TimeTicks::Now() - start_time_step1); + + // This step is costly and is already measured in Startup.CreateFirstProfile + // and more directly Profile.CreateAndInitializeProfile. profile_ = CreatePrimaryProfile(parameters(), user_data_dir_, parsed_command_line()); @@ -1300,6 +1309,7 @@ return content::RESULT_CODE_NORMAL_EXIT; #if !defined(OS_ANDROID) + 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(); @@ -1309,7 +1319,7 @@ // Autoload any profiles which are running background apps. // TODO(rlp): Do this on a separate thread. See http://crbug.com/99075. browser_process_->profile_manager()->AutoloadProfiles(); -#endif +#endif // defined(ENABLE_BACKGROUND) // Post-profile init --------------------------------------------------------- TranslateService::Initialize(); @@ -1325,7 +1335,7 @@ NaClBrowserDelegateImpl* delegate = new NaClBrowserDelegateImpl(browser_process_->profile_manager()); nacl::NaClBrowser::SetDelegate(delegate); -#endif +#endif // !defined(DISABLE_NACL) // TODO(stevenjb): Move WIN and MACOSX specific code to appropriate Parts. // (requires supporting early exit). @@ -1389,7 +1399,7 @@ base::Bind(&NetworkProfileBubble::CheckNetworkProfile, profile_->GetPath())); } -#endif // OS_WIN +#endif // defined(OS_WIN) #if defined(ENABLE_RLZ) && !defined(OS_CHROMEOS) // Init the RLZ library. This just binds the dll and schedules a task on the @@ -1446,7 +1456,7 @@ parsed_command_line().GetSwitchValuePath(switches::kDebugPrint); printing::PrintedDocument::set_debug_dump_path(path); } -#endif +#endif // defined(ENABLE_PRINT_PREVIEW) && !defined(OFFICIAL_BUILD) HandleTestParameters(parsed_command_line()); browser_process_->metrics_service()->RecordBreakpadHasDebugger( @@ -1471,7 +1481,7 @@ #if !defined(OS_ANDROID) // Start watching for a hang. browser_process_->metrics_service()->LogNeedForCleanShutdown(); -#endif +#endif // !defined(OS_ANDROID) #if defined(ENABLE_PRINT_PREVIEW) // Create the instance of the cloud print proxy service so that it can launch @@ -1481,7 +1491,7 @@ // BrowserContextKeyedServiceFactory::ServiceIsCreatedWithBrowserContext() // instead? CloudPrintProxyServiceFactory::GetForProfile(profile_); -#endif +#endif // defined(ENABLE_PRINT_PREVIEW) // Start watching all browser threads for responsiveness. metrics::MetricsService::SetExecutionPhase( @@ -1491,14 +1501,14 @@ #if defined(OS_ANDROID) ThreadWatcherAndroid::RegisterApplicationStatusListener(); -#endif +#endif // defined(OS_ANDROID) #if !defined(DISABLE_NACL) BrowserThread::PostTask( BrowserThread::IO, FROM_HERE, base::Bind(nacl::NaClProcessHost::EarlyStartup)); -#endif +#endif // !defined(DISABLE_NACL) // Make sure initial prefs are recorded PrefMetricsService::Factory::GetForProfile(profile_); @@ -1544,17 +1554,24 @@ #else std::vector<Profile*> last_opened_profiles = g_browser_process->profile_manager()->GetLastOpenedProfiles(); -#endif +#endif // defined(OS_CHROMEOS) - if (browser_creator_->Start(parsed_command_line(), base::FilePath(), - profile_, last_opened_profiles)) { + UMA_HISTOGRAM_TIMES("Startup.PreMainMessageLoopRunImplStep2Time", + base::TimeTicks::Now() - start_time_step2); + + // This step is costly and is already measured in + // Startup.StartupBrowserCreator_Start. + bool started = browser_creator_->Start( + parsed_command_line(), base::FilePath(), profile_, last_opened_profiles); + const base::TimeTicks start_time_step3 = base::TimeTicks::Now(); + if (started) { #if defined(OS_WIN) || (defined(OS_LINUX) && !defined(OS_CHROMEOS)) // Initialize autoupdate timer. Timer callback costs basically nothing // when browser is not in persistent mode, so it's OK to let it ride on // the main thread. This needs to be done here because we don't want // to start the timer when Chrome is run inside a test harness. browser_process_->StartAutoupdateTimer(); -#endif +#endif // defined(OS_WIN) || (defined(OS_LINUX) && !defined(OS_CHROMEOS)) #if defined(OS_LINUX) && !defined(OS_CHROMEOS) // On Linux, the running exe will be updated if an upgrade becomes @@ -1562,7 +1579,7 @@ // modified time of the exe, so we can compare to determine if there is // an upgrade while the browser is kept alive by a persistent extension. upgrade_util::SaveLastModifiedTimeOfExe(); -#endif +#endif // defined(OS_LINUX) && !defined(OS_CHROMEOS) // Record now as the last successful chrome start. GoogleUpdateSettings::SetLastRunTime(); @@ -1572,7 +1589,7 @@ // because Start() will add things to it while creating the main window. if (parameters().autorelease_pool) parameters().autorelease_pool->Recycle(); -#endif +#endif // defined(OS_MACOSX) base::TimeDelta delay = base::TimeTicks::Now() - browser_open_start; UMA_HISTOGRAM_LONG_TIMES_100("Startup.BrowserOpenTabs", delay); @@ -1589,7 +1606,7 @@ #if defined(OS_WIN) variations_service->StartGoogleUpdateRegistrySync(); -#endif +#endif // defined(OS_WIN) } translate::TranslateDownloadManager::RequestLanguageList( @@ -1605,7 +1622,7 @@ #if !defined(OS_LINUX) || defined(OS_CHROMEOS) // http://crbug.com/426393 if (g_browser_process->metrics_service()->reporting_active()) content::StartPowerUsageMonitor(); -#endif +#endif // !defined(OS_LINUX) || defined(OS_CHROMEOS) process_power_collector_.reset(new ProcessPowerCollector); process_power_collector_->Initialize(); @@ -1621,11 +1638,17 @@ #if defined(OS_ANDROID) // We never run the C++ main loop on Android, since the UI thread message // loop is controlled by the OS, so this is as close as we can get to - // the start of the main loop + // the start of the main loop. if (result_code_ <= 0) { RecordBrowserStartupTime(); } -#endif +#endif // defined(OS_ANDROID) + +#if !defined(OS_ANDROID) + UMA_HISTOGRAM_TIMES("Startup.PreMainMessageLoopRunImplStep3Time", + base::TimeTicks::Now() - start_time_step3); +#endif // !defined(OS_ANDROID) + return result_code_; } @@ -1658,7 +1681,7 @@ run_loop.Run(); return true; -#endif +#endif // defined(OS_ANDROID) } void ChromeBrowserMainParts::PostMainMessageLoopRun() { @@ -1701,7 +1724,7 @@ restart_last_session_ = browser_shutdown::ShutdownPreThreadsStop(); browser_process_->StartTearDown(); -#endif +#endif // defined(OS_ANDROID) } void ChromeBrowserMainParts::PostDestroyThreads() { @@ -1728,8 +1751,8 @@ #if defined(OS_CHROMEOS) chromeos::CrosSettings::Shutdown(); -#endif -#endif +#endif // defined(OS_CHROMEOS) +#endif // defined(OS_ANDROID) } // Public members:
diff --git a/chrome/browser/chromeos/device/input_service_proxy.cc b/chrome/browser/chromeos/device/input_service_proxy.cc index 861ef6c9..3d27ab1 100644 --- a/chrome/browser/chromeos/device/input_service_proxy.cc +++ b/chrome/browser/chromeos/device/input_service_proxy.cc
@@ -15,6 +15,9 @@ namespace chromeos { +// static +BrowserThread::ID InputServiceProxy::thread_identifier_ = BrowserThread::FILE; + class InputServiceProxy::ServiceObserver : public InputServiceLinux::Observer { public: ServiceObserver() { DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); } @@ -73,7 +76,7 @@ private: bool CalledOnValidThread() const { - return BrowserThread::CurrentlyOn(BrowserThread::FILE); + return BrowserThread::CurrentlyOn(InputServiceProxy::thread_identifier_); } base::WeakPtr<InputServiceProxy> proxy_; @@ -82,10 +85,12 @@ }; InputServiceProxy::InputServiceProxy() - : service_observer_(new ServiceObserver()), weak_factory_(this) { + : service_observer_(new ServiceObserver()), + task_runner_(BrowserThread::GetMessageLoopProxyForThread( + thread_identifier_)), + weak_factory_(this) { DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); - BrowserThread::PostTask( - BrowserThread::FILE, + task_runner_->PostTask( FROM_HERE, base::Bind(&InputServiceProxy::ServiceObserver::Initialize, base::Unretained(service_observer_.get()), @@ -94,8 +99,7 @@ InputServiceProxy::~InputServiceProxy() { DCHECK(thread_checker_.CalledOnValidThread()); - BrowserThread::PostTask( - BrowserThread::FILE, + task_runner_->PostTask( FROM_HERE, base::Bind(&InputServiceProxy::ServiceObserver::Shutdown, base::Unretained(service_observer_.release()))); @@ -104,7 +108,7 @@ // static void InputServiceProxy::WarmUp() { content::BrowserThread::PostTask( - content::BrowserThread::FILE, + thread_identifier_, FROM_HERE, base::Bind(base::IgnoreResult(&InputServiceLinux::GetInstance))); } @@ -123,8 +127,8 @@ void InputServiceProxy::GetDevices(const GetDevicesCallback& callback) { DCHECK(thread_checker_.CalledOnValidThread()); - BrowserThread::PostTaskAndReplyWithResult( - BrowserThread::FILE, + base::PostTaskAndReplyWithResult( + task_runner_.get(), FROM_HERE, base::Bind(&InputServiceProxy::ServiceObserver::GetDevices, base::Unretained(service_observer_.get())), @@ -134,8 +138,7 @@ void InputServiceProxy::GetDeviceInfo(const std::string& id, const GetDeviceInfoCallback& callback) { DCHECK(thread_checker_.CalledOnValidThread()); - BrowserThread::PostTask( - BrowserThread::FILE, + task_runner_->PostTask( FROM_HERE, base::Bind(&InputServiceProxy::ServiceObserver::GetDeviceInfo, base::Unretained(service_observer_.release()), @@ -143,6 +146,11 @@ callback)); } +// static +void InputServiceProxy::SetThreadIdForTesting(BrowserThread::ID thread_id) { + InputServiceProxy::thread_identifier_ = thread_id; +} + void InputServiceProxy::OnDeviceAdded( const InputServiceLinux::InputDeviceInfo& info) { DCHECK(thread_checker_.CalledOnValidThread());
diff --git a/chrome/browser/chromeos/device/input_service_proxy.h b/chrome/browser/chromeos/device/input_service_proxy.h index e41196f..44a0a63 100644 --- a/chrome/browser/chromeos/device/input_service_proxy.h +++ b/chrome/browser/chromeos/device/input_service_proxy.h
@@ -11,7 +11,9 @@ #include "base/memory/scoped_ptr.h" #include "base/memory/weak_ptr.h" #include "base/observer_list.h" +#include "base/task_runner.h" #include "base/threading/thread_checker.h" +#include "content/public/browser/browser_thread.h" #include "device/hid/input_service_linux.h" namespace chromeos { @@ -47,7 +49,12 @@ void GetDeviceInfo(const std::string& id, const GetDeviceInfoCallback& callback); + // Should be called once before any InputServiceProxy instance is created. + static void SetThreadIdForTesting(content::BrowserThread::ID thread_id); + private: + static content::BrowserThread::ID thread_identifier_; + class ServiceObserver; void OnDeviceAdded(const device::InputServiceLinux::InputDeviceInfo& info); @@ -58,6 +65,8 @@ base::ThreadChecker thread_checker_; + scoped_refptr<base::TaskRunner> task_runner_; + base::WeakPtrFactory<InputServiceProxy> weak_factory_; DISALLOW_COPY_AND_ASSIGN(InputServiceProxy);
diff --git a/chrome/browser/chromeos/extensions/file_system_provider/file_system_provider_apitest.cc b/chrome/browser/chromeos/extensions/file_system_provider/file_system_provider_apitest.cc index c96dff0..65206db6b 100644 --- a/chrome/browser/chromeos/extensions/file_system_provider/file_system_provider_apitest.cc +++ b/chrome/browser/chromeos/extensions/file_system_provider/file_system_provider_apitest.cc
@@ -56,7 +56,7 @@ << message_; } -IN_PROC_BROWSER_TEST_F(FileSystemProviderApiTest, DISABLED_BigFile) { +IN_PROC_BROWSER_TEST_F(FileSystemProviderApiTest, BigFile) { ASSERT_TRUE(RunPlatformAppTestWithFlags("file_system_provider/big_file", kFlagLoadAsComponent)) << message_;
diff --git a/chrome/browser/chromeos/file_manager/file_manager_jstest.cc b/chrome/browser/chromeos/file_manager/file_manager_jstest.cc index 45890d0..41effc9c 100644 --- a/chrome/browser/chromeos/file_manager/file_manager_jstest.cc +++ b/chrome/browser/chromeos/file_manager/file_manager_jstest.cc
@@ -124,9 +124,9 @@ "foreground/js/metadata/metadata_cache_set_unittest.html"))); } -IN_PROC_BROWSER_TEST_F(FileManagerJsTest, NewMetadataProvider) { +IN_PROC_BROWSER_TEST_F(FileManagerJsTest, MultiMetadataProvider) { RunTest(base::FilePath(FILE_PATH_LITERAL( - "foreground/js/metadata/new_metadata_provider_unittest.html"))); + "foreground/js/metadata/multi_metadata_provider_unittest.html"))); } IN_PROC_BROWSER_TEST_F(FileManagerJsTest, ListThumbnailLoader) { @@ -149,9 +149,9 @@ "foreground/js/metadata/content_metadata_provider_unittest.html"))); } -IN_PROC_BROWSER_TEST_F(FileManagerJsTest, FileSystemMetadata) { +IN_PROC_BROWSER_TEST_F(FileManagerJsTest, MetadataModel) { RunTest(base::FilePath(FILE_PATH_LITERAL( - "foreground/js/metadata/file_system_metadata_unittest.html"))); + "foreground/js/metadata/metadata_model_unittest.html"))); } IN_PROC_BROWSER_TEST_F(FileManagerJsTest, ThumbnailModel) {
diff --git a/chrome/browser/chromeos/login/chrome_restart_request.cc b/chrome/browser/chromeos/login/chrome_restart_request.cc index d747f2a..7a10b51 100644 --- a/chrome/browser/chromeos/login/chrome_restart_request.cc +++ b/chrome/browser/chromeos/login/chrome_restart_request.cc
@@ -90,6 +90,7 @@ ::switches::kDisablePanelFitting, ::switches::kDisableSeccompFilterSandbox, ::switches::kDisableSetuidSandbox, + ::switches::kDisableSurfaces, ::switches::kDisableTextBlobs, ::switches::kDisableThreadedGpuRasterization, ::switches::kDisableThreadedScrolling,
diff --git a/chrome/browser/chromeos/login/default_pinned_apps_field_trial.cc b/chrome/browser/chromeos/login/default_pinned_apps_field_trial.cc deleted file mode 100644 index 4b21f533..0000000 --- a/chrome/browser/chromeos/login/default_pinned_apps_field_trial.cc +++ /dev/null
@@ -1,32 +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. - -#include "chrome/browser/chromeos/login/default_pinned_apps_field_trial.h" - -#include "base/basictypes.h" -#include "base/prefs/pref_registry_simple.h" -#include "base/prefs/pref_service.h" - -namespace chromeos { -namespace default_pinned_apps_field_trial { - -namespace { - -// Name of a local state pref to store the list of users that participate -// the experiment. -const char kExperimentUsers[] = "DefaultPinnedAppsExperimentUsers"; - -} // namespace - -void RegisterPrefs(PrefRegistrySimple* registry) { - registry->RegisterListPref(kExperimentUsers); -} - -void MigratePrefs(PrefService* local_state) { - // TODO(xiyuan): Remove everything in M34. - local_state->ClearPref(kExperimentUsers); -} - -} // namespace default_pinned_apps_field_trial -} // namespace chromeos
diff --git a/chrome/browser/chromeos/login/default_pinned_apps_field_trial.h b/chrome/browser/chromeos/login/default_pinned_apps_field_trial.h deleted file mode 100644 index 5a1c6aa..0000000 --- a/chrome/browser/chromeos/login/default_pinned_apps_field_trial.h +++ /dev/null
@@ -1,29 +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 CHROME_BROWSER_CHROMEOS_LOGIN_DEFAULT_PINNED_APPS_FIELD_TRIAL_H_ -#define CHROME_BROWSER_CHROMEOS_LOGIN_DEFAULT_PINNED_APPS_FIELD_TRIAL_H_ - -#include <string> - -namespace base { -class ListValue; -} - -class PrefRegistrySimple; -class PrefService; - -namespace chromeos { -namespace default_pinned_apps_field_trial { - -// Registers a local state that keeps track of users in experiment. -void RegisterPrefs(PrefRegistrySimple* registry); - -// Migrate by removing the old local state. -void MigratePrefs(PrefService* local_state); - -} // namespace default_pinned_apps_field_trial -} // namespace chromeos - -#endif // CHROME_BROWSER_CHROMEOS_LOGIN_DEFAULT_PINNED_APPS_FIELD_TRIAL_H_
diff --git a/chrome/browser/chromeos/login/hid_detection_browsertest.cc b/chrome/browser/chromeos/login/hid_detection_browsertest.cc new file mode 100644 index 0000000..ebb23d20 --- /dev/null +++ b/chrome/browser/chromeos/login/hid_detection_browsertest.cc
@@ -0,0 +1,124 @@ +// 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 "base/bind.h" +#include "base/memory/ref_counted.h" +#include "base/memory/scoped_ptr.h" +#include "base/memory/weak_ptr.h" +#include "chrome/browser/chromeos/login/test/oobe_base_test.h" +#include "chrome/browser/chromeos/login/test/oobe_screen_waiter.h" +#include "chrome/browser/chromeos/login/ui/oobe_display.h" +#include "content/public/browser/browser_thread.h" +#include "device/bluetooth/bluetooth_adapter_factory.h" +#include "device/bluetooth/test/mock_bluetooth_adapter.h" +#include "device/hid/fake_input_service_linux.h" +#include "device/hid/input_service_linux.h" +#include "testing/gmock/include/gmock/gmock.h" + +using content::BrowserThread; +using device::InputServiceLinux; +using testing::_; + +using InputDeviceInfo = InputServiceLinux::InputDeviceInfo; + +namespace { + +void SetUpBluetoothMock( + scoped_refptr< + testing::NiceMock<device::MockBluetoothAdapter> > mock_adapter, + bool is_present) { + device::BluetoothAdapterFactory::SetAdapterForTesting(mock_adapter); + + EXPECT_CALL(*mock_adapter, IsPresent()) + .WillRepeatedly(testing::Return(is_present)); + + EXPECT_CALL(*mock_adapter, IsPowered()) + .WillRepeatedly(testing::Return(true)); + EXPECT_CALL(*mock_adapter, GetDevices()).WillRepeatedly( + testing::Return(device::BluetoothAdapter::ConstDeviceList())); +} + +} // namespace + +namespace chromeos { + +class HidDetectionTest : public OobeBaseTest { + public: + typedef device::InputServiceLinux::InputDeviceInfo InputDeviceInfo; + + HidDetectionTest() : weak_ptr_factory_(this) { + InputServiceProxy::SetThreadIdForTesting(content::BrowserThread::UI); + HidDetectionTest::InitInputService(); + } + + ~HidDetectionTest() override {} + + void InitInputService() { + input_service_linux_.reset(new device::FakeInputServiceLinux); + InputServiceLinux::SetForTesting(input_service_linux_.get()); + } + + void SetUpOnMainThread() override { + OobeBaseTest::SetUpOnMainThread(); + } + + void SetUpInProcessBrowserTestFixture() override { + OobeBaseTest::SetUpInProcessBrowserTestFixture(); + + mock_adapter_ = new testing::NiceMock<device::MockBluetoothAdapter>(); + SetUpBluetoothMock(mock_adapter_, true); + } + + void AddUsbMouse(const std::string& mouse_id) { + InputDeviceInfo mouse; + mouse.id = mouse_id; + mouse.subsystem = InputDeviceInfo::SUBSYSTEM_INPUT; + mouse.type = InputDeviceInfo::TYPE_USB; + mouse.is_mouse = true; + LOG(ERROR) << input_service_linux_.get(); + input_service_linux_->AddDeviceForTesting(mouse); + } + + void AddUsbKeyboard(const std::string& keyboard_id) { + InputDeviceInfo keyboard; + keyboard.id = keyboard_id; + keyboard.subsystem = InputDeviceInfo::SUBSYSTEM_INPUT; + keyboard.type = InputDeviceInfo::TYPE_USB; + keyboard.is_keyboard = true; + input_service_linux_->AddDeviceForTesting(keyboard); + } + + private: + scoped_refptr< + testing::NiceMock<device::MockBluetoothAdapter> > mock_adapter_; + + scoped_ptr<device::FakeInputServiceLinux> input_service_linux_; + + base::WeakPtrFactory<HidDetectionTest> weak_ptr_factory_; + + DISALLOW_COPY_AND_ASSIGN(HidDetectionTest); +}; + +class HidDetectionSkipTest : public HidDetectionTest { + public: + HidDetectionSkipTest() { + AddUsbMouse("mouse"); + AddUsbKeyboard("keyboard"); + } + + void SetUpOnMainThread() override { + HidDetectionTest::SetUpOnMainThread(); + } +}; + +IN_PROC_BROWSER_TEST_F(HidDetectionTest, NoDevicesConnected) { + OobeScreenWaiter(OobeDisplay::SCREEN_OOBE_HID_DETECTION).Wait(); +} + +IN_PROC_BROWSER_TEST_F(HidDetectionSkipTest, BothDevicesPreConnected) { + OobeScreenWaiter(OobeDisplay::SCREEN_OOBE_NETWORK).Wait(); + +} + +} // namespace chromeos
diff --git a/chrome/browser/chromeos/login/users/wallpaper/wallpaper_manager.cc b/chrome/browser/chromeos/login/users/wallpaper/wallpaper_manager.cc index 20a9d98..ef44c39 100644 --- a/chrome/browser/chromeos/login/users/wallpaper/wallpaper_manager.cc +++ b/chrome/browser/chromeos/login/users/wallpaper/wallpaper_manager.cc
@@ -307,6 +307,8 @@ base::SequencedWorkerPool::CONTINUE_ON_SHUTDOWN); wallpaper_loader_ = new UserImageLoader(ImageDecoder::ROBUST_JPEG_CODEC, task_runner_); + + user_manager::UserManager::Get()->AddSessionStateObserver(this); } WallpaperManager::~WallpaperManager() { @@ -314,6 +316,8 @@ // http://crbug.com/171694 DCHECK(!show_user_name_on_signin_subscription_); + user_manager::UserManager::Get()->RemoveSessionStateObserver(this); + ClearObsoleteWallpaperPrefs(); weak_factory_.InvalidateWeakPtrs(); } @@ -966,6 +970,10 @@ return loading_.size(); } +void WallpaperManager::UserChangedChildStatus(user_manager::User* user) { + SetUserWallpaperNow(user->email()); +} + void WallpaperManager::OnDefaultWallpaperDecoded( const base::FilePath& path, const wallpaper::WallpaperLayout layout,
diff --git a/chrome/browser/chromeos/login/users/wallpaper/wallpaper_manager.h b/chrome/browser/chromeos/login/users/wallpaper/wallpaper_manager.h index 14eec18..536d752d 100644 --- a/chrome/browser/chromeos/login/users/wallpaper/wallpaper_manager.h +++ b/chrome/browser/chromeos/login/users/wallpaper/wallpaper_manager.h
@@ -21,6 +21,7 @@ #include "chrome/browser/chromeos/settings/cros_settings.h" #include "components/user_manager/user.h" #include "components/user_manager/user_image/user_image.h" +#include "components/user_manager/user_manager.h" #include "components/wallpaper/wallpaper_layout.h" #include "components/wallpaper/wallpaper_manager_base.h" #include "content/public/browser/notification_observer.h" @@ -30,7 +31,9 @@ namespace chromeos { -class WallpaperManager : public wallpaper::WallpaperManagerBase { +class WallpaperManager : + public wallpaper::WallpaperManagerBase, + public user_manager::UserManager::UserSessionStateObserver { public: class PendingWallpaper; @@ -115,6 +118,9 @@ // Returns queue size. size_t GetPendingListSizeForTesting() const override; + // Overridden from user_manager::UserManager::UserSessionStateObserver: + void UserChangedChildStatus(user_manager::User* user) override; + private: friend class TestApi; friend class WallpaperManagerBrowserTest;
diff --git a/chrome/browser/chromeos/policy/power_policy_browsertest.cc b/chrome/browser/chromeos/policy/power_policy_browsertest.cc index 37b89884..4345ab3 100644 --- a/chrome/browser/chromeos/policy/power_policy_browsertest.cc +++ b/chrome/browser/chromeos/policy/power_policy_browsertest.cc
@@ -49,7 +49,7 @@ #include "content/public/browser/notification_service.h" #include "content/public/browser/notification_source.h" #include "content/public/test/test_utils.h" -#include "extensions/browser/api/power/power_api_manager.h" +#include "extensions/browser/api/power/power_api.h" #include "extensions/common/api/power.h" #include "policy/proto/device_management_backend.pb.h" #include "testing/gmock/include/gmock/gmock.h" @@ -482,8 +482,8 @@ // Pretend an extension grabs a screen wake lock. const char kExtensionId[] = "abcdefghijklmnopabcdefghijlkmnop"; - extensions::PowerApiManager::Get(browser()->profile())->AddRequest( - kExtensionId, extensions::core_api::power::LEVEL_DISPLAY); + extensions::PowerAPI::Get(browser()->profile()) + ->AddRequest(kExtensionId, extensions::core_api::power::LEVEL_DISPLAY); base::RunLoop().RunUntilIdle(); // Check that the lock is in effect (ignoring ac_idle_action,
diff --git a/chrome/browser/devtools/devtools_window.cc b/chrome/browser/devtools/devtools_window.cc index b7f0f9d..a517f18b 100644 --- a/chrome/browser/devtools/devtools_window.cc +++ b/chrome/browser/devtools/devtools_window.cc
@@ -857,6 +857,8 @@ if (target_url.SchemeIs(content::kChromeDevToolsScheme) && target_url.path().rfind("toolbox.html") != std::string::npos) { CHECK(can_dock_); + if (toolbox_web_contents_) + delete toolbox_web_contents_; toolbox_web_contents_ = new_contents; } }
diff --git a/chrome/browser/download/download_ui_controller.cc b/chrome/browser/download/download_ui_controller.cc index 5c249cd..c94b842 100644 --- a/chrome/browser/download/download_ui_controller.cc +++ b/chrome/browser/download/download_ui_controller.cc
@@ -7,7 +7,6 @@ #include "base/callback.h" #include "base/stl_util.h" #include "chrome/browser/download/download_item_model.h" -#include "chrome/browser/ui/browser_finder.h" #include "chrome/browser/ui/browser_tabstrip.h" #include "content/public/browser/download_item.h" #include "content/public/browser/web_contents.h" @@ -17,6 +16,8 @@ #include "content/public/browser/android/download_controller_android.h" #else #include "chrome/browser/profiles/profile.h" +#include "chrome/browser/ui/browser_finder.h" +#include "chrome/browser/ui/host_desktop.h" #endif namespace {
diff --git a/chrome/browser/errorpage_browsertest.cc b/chrome/browser/errorpage_browsertest.cc index 6c4708a..2ae8dbe 100644 --- a/chrome/browser/errorpage_browsertest.cc +++ b/chrome/browser/errorpage_browsertest.cc
@@ -941,7 +941,7 @@ EXPECT_EQ(2, interceptor()->requests()); ToggleHelpBox(browser()); - EXPECT_TRUE(IsDisplayingNetError(browser(), net::ERR_CONNECTION_RESET)); + EXPECT_TRUE(IsDisplayingText(browser(), "error.page.auto.reload")); content::WebContents* web_contents = browser()->tab_strip_model()->GetActiveWebContents(); @@ -949,7 +949,7 @@ web_contents->GetMainFrame()->ExecuteJavaScript( base::ASCIIToUTF16("document.getElementById('reload-button').click();")); nav_observer.Wait(); - EXPECT_FALSE(IsDisplayingNetError(browser(), net::ERR_CONNECTION_RESET)); + EXPECT_FALSE(IsDisplayingText(browser(), "error.page.auto.reload")); } // Interceptor that fails all requests with net::ERR_ADDRESS_UNREACHABLE.
diff --git a/chrome/browser/extensions/api/developer_private/developer_private_api.cc b/chrome/browser/extensions/api/developer_private/developer_private_api.cc index 337f58e1f..f2e9ac6f 100644 --- a/chrome/browser/extensions/api/developer_private/developer_private_api.cc +++ b/chrome/browser/extensions/api/developer_private/developer_private_api.cc
@@ -96,6 +96,10 @@ "Cannot modify the extension by policy."; const char kRequiresUserGestureError[] = "This action requires a user gesture."; +const char kCouldNotShowSelectFileDialogError[] = + "Could not show a file chooser."; +const char kFileSelectionCanceled[] = + "File selection was canceled."; const char kUnpackedAppsFolder[] = "apps_target"; @@ -867,67 +871,59 @@ DeveloperPrivateInspectFunction::~DeveloperPrivateInspectFunction() {} -bool DeveloperPrivateLoadUnpackedFunction::RunAsync() { - base::string16 select_title = - l10n_util::GetStringUTF16(IDS_EXTENSION_LOAD_FROM_DIRECTORY); +ExtensionFunction::ResponseAction DeveloperPrivateLoadUnpackedFunction::Run() { + if (!ShowPicker( + ui::SelectFileDialog::SELECT_FOLDER, + l10n_util::GetStringUTF16(IDS_EXTENSION_LOAD_FROM_DIRECTORY), + ui::SelectFileDialog::FileTypeInfo(), + 0 /* file_type_index */)) { + return RespondNow(Error(kCouldNotShowSelectFileDialogError)); + } - // Balanced in FileSelected / FileSelectionCanceled. - AddRef(); - bool result = ShowPicker( - ui::SelectFileDialog::SELECT_FOLDER, - DeveloperPrivateAPI::Get(GetProfile())->GetLastUnpackedDirectory(), - select_title, - ui::SelectFileDialog::FileTypeInfo(), - 0); - return result; + AddRef(); // Balanced in FileSelected / FileSelectionCanceled. + return RespondLater(); } void DeveloperPrivateLoadUnpackedFunction::FileSelected( const base::FilePath& path) { - ExtensionService* service = GetExtensionService(GetProfile()); - UnpackedInstaller::Create(service)->Load(path); - DeveloperPrivateAPI::Get(GetProfile())->SetLastUnpackedDirectory(path); - SendResponse(true); - Release(); + UnpackedInstaller::Create(GetExtensionService(browser_context()))->Load(path); + DeveloperPrivateAPI::Get(browser_context())->SetLastUnpackedDirectory(path); + // TODO(devlin): Shouldn't we wait until the extension is loaded? + Respond(NoArguments()); + Release(); // Balanced in Run(). } void DeveloperPrivateLoadUnpackedFunction::FileSelectionCanceled() { - SendResponse(false); - Release(); + // This isn't really an error, but we should keep it like this for + // backward compatability. + Respond(Error(kFileSelectionCanceled)); + Release(); // Balanced in Run(). } bool DeveloperPrivateChooseEntryFunction::ShowPicker( ui::SelectFileDialog::Type picker_type, - const base::FilePath& last_directory, const base::string16& select_title, const ui::SelectFileDialog::FileTypeInfo& info, int file_type_index) { - AppWindowRegistry* registry = AppWindowRegistry::Get(GetProfile()); - DCHECK(registry); - AppWindow* app_window = - registry->GetAppWindowForRenderViewHost(render_view_host()); - if (!app_window) { + content::WebContents* web_contents = GetSenderWebContents(); + if (!web_contents) return false; - } // The entry picker will hold a reference to this function instance, // and subsequent sending of the function response) until the user has // selected a file or cancelled the picker. At that point, the picker will // delete itself. new EntryPicker(this, - app_window->web_contents(), + web_contents, picker_type, - last_directory, + DeveloperPrivateAPI::Get(browser_context())-> + GetLastUnpackedDirectory(), select_title, info, file_type_index); return true; } -bool DeveloperPrivateChooseEntryFunction::RunAsync() { - return false; -} - DeveloperPrivateChooseEntryFunction::~DeveloperPrivateChooseEntryFunction() {} void DeveloperPrivatePackDirectoryFunction::OnPackSuccess( @@ -937,9 +933,8 @@ response.message = base::UTF16ToUTF8( PackExtensionJob::StandardSuccessMessage(crx_file, pem_file)); response.status = developer::PACK_STATUS_SUCCESS; - results_ = developer::PackDirectory::Results::Create(response); - SendResponse(true); - Release(); + Respond(OneArgument(response.ToValue().release())); + Release(); // Balanced in Run(). } void DeveloperPrivatePackDirectoryFunction::OnPackFailure( @@ -955,15 +950,14 @@ } else { response.status = developer::PACK_STATUS_ERROR; } - results_ = developer::PackDirectory::Results::Create(response); - SendResponse(true); - Release(); + Respond(OneArgument(response.ToValue().release())); + Release(); // Balanced in Run(). } -bool DeveloperPrivatePackDirectoryFunction::RunAsync() { +ExtensionFunction::ResponseAction DeveloperPrivatePackDirectoryFunction::Run() { scoped_ptr<PackDirectory::Params> params( PackDirectory::Params::Create(*args_)); - EXTENSION_FUNCTION_VALIDATE(params.get()); + EXTENSION_FUNCTION_VALIDATE(params); int flags = params->flags ? *params->flags : 0; item_path_str_ = params->path; @@ -972,7 +966,6 @@ base::FilePath root_directory = base::FilePath::FromUTF8Unsafe(item_path_str_); - base::FilePath key_file = base::FilePath::FromUTF8Unsafe(key_path_str_); developer::PackDirectoryResponse response; @@ -985,33 +978,29 @@ IDS_EXTENSION_PACK_DIALOG_ERROR_ROOT_INVALID); response.status = developer::PACK_STATUS_ERROR; - results_ = developer::PackDirectory::Results::Create(response); - SendResponse(true); - return true; + return RespondNow(OneArgument(response.ToValue().release())); } if (!key_path_str_.empty() && key_file.empty()) { response.message = l10n_util::GetStringUTF8( IDS_EXTENSION_PACK_DIALOG_ERROR_KEY_INVALID); response.status = developer::PACK_STATUS_ERROR; - results_ = developer::PackDirectory::Results::Create(response); - SendResponse(true); - return true; + return RespondNow(OneArgument(response.ToValue().release())); } - // Balanced in OnPackSuccess / OnPackFailure. - AddRef(); + AddRef(); // Balanced in OnPackSuccess / OnPackFailure. + // TODO(devlin): Why is PackExtensionJob ref-counted? pack_job_ = new PackExtensionJob(this, root_directory, key_file, flags); pack_job_->Start(); - return true; + return RespondLater(); } -DeveloperPrivatePackDirectoryFunction::DeveloperPrivatePackDirectoryFunction() -{} +DeveloperPrivatePackDirectoryFunction::DeveloperPrivatePackDirectoryFunction() { +} -DeveloperPrivatePackDirectoryFunction::~DeveloperPrivatePackDirectoryFunction() -{} +DeveloperPrivatePackDirectoryFunction:: +~DeveloperPrivatePackDirectoryFunction() {} DeveloperPrivateLoadUnpackedFunction::~DeveloperPrivateLoadUnpackedFunction() {} @@ -1246,16 +1235,16 @@ DeveloperPrivateLoadDirectoryFunction::~DeveloperPrivateLoadDirectoryFunction() {} -bool DeveloperPrivateChoosePathFunction::RunAsync() { +ExtensionFunction::ResponseAction DeveloperPrivateChoosePathFunction::Run() { scoped_ptr<developer::ChoosePath::Params> params( developer::ChoosePath::Params::Create(*args_)); - EXTENSION_FUNCTION_VALIDATE(params.get() != NULL); + EXTENSION_FUNCTION_VALIDATE(params); ui::SelectFileDialog::Type type = ui::SelectFileDialog::SELECT_FOLDER; ui::SelectFileDialog::FileTypeInfo info; - if (params->select_type == developer::SELECT_TYPE_FILE) { + + if (params->select_type == developer::SELECT_TYPE_FILE) type = ui::SelectFileDialog::SELECT_OPEN_FILE; - } base::string16 select_title; int file_type_index = 0; @@ -1264,8 +1253,8 @@ } else if (params->file_type == developer::FILE_TYPE_PEM) { select_title = l10n_util::GetStringUTF16( IDS_EXTENSION_PACK_DIALOG_SELECT_KEY); - info.extensions.push_back(std::vector<base::FilePath::StringType>()); - info.extensions.front().push_back(FILE_PATH_LITERAL("pem")); + info.extensions.push_back(std::vector<base::FilePath::StringType>( + 1, FILE_PATH_LITERAL("pem"))); info.extension_description_overrides.push_back( l10n_util::GetStringUTF16( IDS_EXTENSION_PACK_DIALOG_KEY_FILE_TYPE_DESCRIPTION)); @@ -1275,26 +1264,28 @@ NOTREACHED(); } - // Balanced by FileSelected / FileSelectionCanceled. - AddRef(); - bool result = ShowPicker( - type, - DeveloperPrivateAPI::Get(GetProfile())->GetLastUnpackedDirectory(), - select_title, - info, - file_type_index); - return result; + if (!ShowPicker( + type, + select_title, + info, + file_type_index)) { + return RespondNow(Error(kCouldNotShowSelectFileDialogError)); + } + + AddRef(); // Balanced by FileSelected / FileSelectionCanceled. + return RespondLater(); } void DeveloperPrivateChoosePathFunction::FileSelected( const base::FilePath& path) { - SetResult(new base::StringValue(base::UTF16ToUTF8(path.LossyDisplayName()))); - SendResponse(true); + Respond(OneArgument(new base::StringValue(path.LossyDisplayName()))); Release(); } void DeveloperPrivateChoosePathFunction::FileSelectionCanceled() { - SendResponse(false); + // This isn't really an error, but we should keep it like this for + // backward compatability. + Respond(Error(kFileSelectionCanceled)); Release(); }
diff --git a/chrome/browser/extensions/api/developer_private/developer_private_api.h b/chrome/browser/extensions/api/developer_private/developer_private_api.h index 2164d14..be0c25e 100644 --- a/chrome/browser/extensions/api/developer_private/developer_private_api.h +++ b/chrome/browser/extensions/api/developer_private/developer_private_api.h
@@ -296,20 +296,14 @@ std::string extension_id_; }; -class DeveloperPrivateChooseEntryFunction : public ChromeAsyncExtensionFunction, +class DeveloperPrivateChooseEntryFunction : public UIThreadExtensionFunction, public EntryPickerClient { protected: ~DeveloperPrivateChooseEntryFunction() override; - bool RunAsync() override; bool ShowPicker(ui::SelectFileDialog::Type picker_type, - const base::FilePath& last_directory, const base::string16& select_title, const ui::SelectFileDialog::FileTypeInfo& info, int file_type_index); - - // EntryPickerClient functions. - void FileSelected(const base::FilePath& path) override = 0; - void FileSelectionCanceled() override = 0; }; @@ -321,9 +315,9 @@ protected: ~DeveloperPrivateLoadUnpackedFunction() override; - bool RunAsync() override; + ResponseAction Run() override; - // EntryPickerCLient implementation. + // EntryPickerClient: void FileSelected(const base::FilePath& path) override; void FileSelectionCanceled() override; }; @@ -336,15 +330,15 @@ protected: ~DeveloperPrivateChoosePathFunction() override; - bool RunAsync() override; + ResponseAction Run() override; - // EntryPickerClient functions. + // EntryPickerClient: void FileSelected(const base::FilePath& path) override; void FileSelectionCanceled() override; }; class DeveloperPrivatePackDirectoryFunction - : public ChromeAsyncExtensionFunction, + : public DeveloperPrivateAPIFunction, public PackExtensionJob::Client { public: @@ -361,7 +355,7 @@ protected: ~DeveloperPrivatePackDirectoryFunction() override; - bool RunAsync() override; + ResponseAction Run() override; private: scoped_refptr<PackExtensionJob> pack_job_;
diff --git a/chrome/browser/extensions/api/developer_private/developer_private_api_unittest.cc b/chrome/browser/extensions/api/developer_private/developer_private_api_unittest.cc index 59bac37..43b9f20 100644 --- a/chrome/browser/extensions/api/developer_private/developer_private_api_unittest.cc +++ b/chrome/browser/extensions/api/developer_private/developer_private_api_unittest.cc
@@ -12,6 +12,7 @@ #include "chrome/browser/extensions/unpacked_installer.h" #include "chrome/browser/ui/browser.h" #include "chrome/browser/ui/host_desktop.h" +#include "chrome/common/extensions/api/developer_private.h" #include "chrome/test/base/test_browser_window.h" #include "extensions/browser/extension_prefs.h" #include "extensions/browser/extension_registry.h" @@ -43,6 +44,11 @@ void TestExtensionPrefSetting( bool (*has_pref)(const std::string&, content::BrowserContext*)); + testing::AssertionResult TestPackExtensionFunction( + const base::ListValue& args, + api::developer_private::PackStatus expected_status, + int expected_flags); + Browser* browser() { return browser_.get(); } private: @@ -134,6 +140,37 @@ EXPECT_FALSE(has_pref(extension_id, profile())); } +testing::AssertionResult DeveloperPrivateApiUnitTest::TestPackExtensionFunction( + const base::ListValue& args, + api::developer_private::PackStatus expected_status, + int expected_flags) { + scoped_refptr<UIThreadExtensionFunction> function( + new api::DeveloperPrivatePackDirectoryFunction()); + if (!RunFunction(function, args)) + return testing::AssertionFailure() << "Could not run function."; + + // Extract the result. We don't have to test this here, since it's verified as + // part of the general extension api system. + const base::Value* response_value = nullptr; + CHECK(function->GetResultList()->Get(0u, &response_value)); + scoped_ptr<api::developer_private::PackDirectoryResponse> response = + api::developer_private::PackDirectoryResponse::FromValue(*response_value); + CHECK(response); + + if (response->status != expected_status) { + return testing::AssertionFailure() << "Expected status: " << + expected_status << ", found status: " << response->status << + ", message: " << response->message; + } + + if (response->override_flags != expected_flags) { + return testing::AssertionFailure() << "Expected flags: " << + expected_flags << ", found flags: " << response->override_flags; + } + + return testing::AssertionSuccess(); +} + void DeveloperPrivateApiUnitTest::SetUp() { ExtensionServiceTestBase::SetUp(); InitializeEmptyExtensionService(); @@ -183,4 +220,48 @@ &util::AllowFileAccess); } +// Test developerPrivate.packDirectory. +TEST_F(DeveloperPrivateApiUnitTest, DeveloperPrivatePackFunction) { + ResetThreadBundle(content::TestBrowserThreadBundle::DEFAULT); + + base::FilePath root_path = data_dir().AppendASCII("good_unpacked"); + base::FilePath crx_path = data_dir().AppendASCII("good_unpacked.crx"); + base::FilePath pem_path = data_dir().AppendASCII("good_unpacked.pem"); + + // First, test a directory that should pack properly. + base::ListValue pack_args; + pack_args.AppendString(root_path.AsUTF8Unsafe()); + EXPECT_TRUE(TestPackExtensionFunction( + pack_args, api::developer_private::PACK_STATUS_SUCCESS, 0)); + + // Should have created crx file and pem file. + EXPECT_TRUE(base::PathExists(crx_path)); + EXPECT_TRUE(base::PathExists(pem_path)); + + // Deliberately don't cleanup the files, and append the pem path. + pack_args.AppendString(pem_path.AsUTF8Unsafe()); + + // Try to pack again - we should get a warning abot overwriting the crx. + EXPECT_TRUE(TestPackExtensionFunction( + pack_args, + api::developer_private::PACK_STATUS_WARNING, + ExtensionCreator::kOverwriteCRX)); + + // Try to pack again, with the overwrite flag; this should succeed. + pack_args.AppendInteger(ExtensionCreator::kOverwriteCRX); + EXPECT_TRUE(TestPackExtensionFunction( + pack_args, api::developer_private::PACK_STATUS_SUCCESS, 0)); + + // Try to pack a final time when omitting (an existing) pem file. We should + // get an error. + base::DeleteFile(crx_path, false); + EXPECT_TRUE(pack_args.Remove(1u, nullptr)); // Remove the pem key argument. + EXPECT_TRUE(pack_args.Remove(1u, nullptr)); // Remove the flags argument. + EXPECT_TRUE(TestPackExtensionFunction( + pack_args, api::developer_private::PACK_STATUS_ERROR, 0)); + + base::DeleteFile(crx_path, false); + base::DeleteFile(pem_path, false); +} + } // namespace extensions
diff --git a/chrome/browser/extensions/api/developer_private/entry_picker.cc b/chrome/browser/extensions/api/developer_private/entry_picker.cc index 9e3b6af..9baaa1e 100644 --- a/chrome/browser/extensions/api/developer_private/entry_picker.cc +++ b/chrome/browser/extensions/api/developer_private/entry_picker.cc
@@ -79,6 +79,13 @@ delete this; } +void EntryPicker::MultiFilesSelected(const std::vector<base::FilePath>& files, + void* params) { + NOTREACHED(); + client_->FileSelectionCanceled(); + delete this; +} + // static void EntryPicker::SkipPickerAndAlwaysSelectPathForTest( base::FilePath* path) {
diff --git a/chrome/browser/extensions/api/developer_private/entry_picker.h b/chrome/browser/extensions/api/developer_private/entry_picker.h index 5fafbc64..da4421c 100644 --- a/chrome/browser/extensions/api/developer_private/entry_picker.h +++ b/chrome/browser/extensions/api/developer_private/entry_picker.h
@@ -42,12 +42,13 @@ ~EntryPicker() override; private: - // ui::SelectFileDialog::Listener implementation. + // ui::SelectFileDialog::Listener: void FileSelected(const base::FilePath& path, int index, void* params) override; - void FileSelectionCanceled(void* params) override; + void MultiFilesSelected(const std::vector<base::FilePath>& files, + void* params) override; scoped_refptr<ui::SelectFileDialog> select_file_dialog_; EntryPickerClient* client_;
diff --git a/chrome/browser/extensions/browser_context_keyed_service_factories.cc b/chrome/browser/extensions/browser_context_keyed_service_factories.cc index 86d48df..5830c48 100644 --- a/chrome/browser/extensions/browser_context_keyed_service_factories.cc +++ b/chrome/browser/extensions/browser_context_keyed_service_factories.cc
@@ -55,7 +55,7 @@ #include "extensions/browser/api/bluetooth/bluetooth_private_api.h" #include "extensions/browser/api/bluetooth_low_energy/bluetooth_low_energy_api.h" #include "extensions/browser/api/bluetooth_socket/bluetooth_socket_event_dispatcher.h" -#include "extensions/browser/api/power/power_api_manager.h" +#include "extensions/browser/api/power/power_api.h" #include "extensions/browser/api/usb/usb_device_resource.h" #include "extensions/browser/api/virtual_keyboard_private/virtual_keyboard_private_api.h" #include "extensions/browser/api/web_request/web_request_api.h" @@ -121,7 +121,7 @@ #if defined(ENABLE_PLUGINS) extensions::PluginManager::GetFactoryInstance(); #endif // defined(ENABLE_PLUGINS) - extensions::PowerApiManager::GetFactoryInstance(); + extensions::PowerAPI::GetFactoryInstance(); extensions::PreferenceAPI::GetFactoryInstance(); extensions::ProcessesAPI::GetFactoryInstance(); extensions::PushMessagingAPI::GetFactoryInstance();
diff --git a/chrome/browser/extensions/extension_bindings_apitest.cc b/chrome/browser/extensions/extension_bindings_apitest.cc index ca0f4d4..c78fb200 100644 --- a/chrome/browser/extensions/extension_bindings_apitest.cc +++ b/chrome/browser/extensions/extension_bindings_apitest.cc
@@ -92,5 +92,9 @@ << message_; } +IN_PROC_BROWSER_TEST_F(ExtensionBindingsApiTest, ApiEnums) { + ASSERT_TRUE(RunExtensionTest("bindings/api_enums")) << message_; +}; + } // namespace } // namespace extensions
diff --git a/chrome/browser/extensions/extension_view_host.cc b/chrome/browser/extensions/extension_view_host.cc index ee79eba..1d0ef9cf 100644 --- a/chrome/browser/extensions/extension_view_host.cc +++ b/chrome/browser/extensions/extension_view_host.cc
@@ -107,9 +107,9 @@ if (!ExtensionSystem::Get(browser_context())-> runtime_data()->IsBackgroundPageReady(extension())) { // Make sure the background page loads before any others. - registrar()->Add(this, - extensions::NOTIFICATION_EXTENSION_BACKGROUND_PAGE_READY, - content::Source<Extension>(extension())); + registrar_.Add(this, + extensions::NOTIFICATION_EXTENSION_BACKGROUND_PAGE_READY, + content::Source<Extension>(extension())); return; } @@ -296,13 +296,11 @@ void ExtensionViewHost::Observe(int type, const content::NotificationSource& source, const content::NotificationDetails& details) { - if (type == extensions::NOTIFICATION_EXTENSION_BACKGROUND_PAGE_READY) { - DCHECK(ExtensionSystem::Get(browser_context())-> - runtime_data()->IsBackgroundPageReady(extension())); - LoadInitialURL(); - return; - } - ExtensionHost::Observe(type, source, details); + DCHECK_EQ(type, extensions::NOTIFICATION_EXTENSION_BACKGROUND_PAGE_READY); + DCHECK(ExtensionSystem::Get(browser_context()) + ->runtime_data() + ->IsBackgroundPageReady(extension())); + LoadInitialURL(); } } // namespace extensions
diff --git a/chrome/browser/extensions/extension_view_host.h b/chrome/browser/extensions/extension_view_host.h index 63cb61e..861d6be9 100644 --- a/chrome/browser/extensions/extension_view_host.h +++ b/chrome/browser/extensions/extension_view_host.h
@@ -9,6 +9,8 @@ #include "components/web_modal/popup_manager.h" #include "components/web_modal/web_contents_modal_dialog_host.h" #include "components/web_modal/web_contents_modal_dialog_manager_delegate.h" +#include "content/public/browser/notification_observer.h" +#include "content/public/browser/notification_registrar.h" #include "extensions/browser/extension_host.h" class Browser; @@ -29,7 +31,8 @@ class ExtensionViewHost : public ExtensionHost, public web_modal::WebContentsModalDialogManagerDelegate, - public web_modal::WebContentsModalDialogHost { + public web_modal::WebContentsModalDialogHost, + public content::NotificationObserver { public: ExtensionViewHost(const Extension* extension, content::SiteInstance* site_instance, @@ -127,6 +130,8 @@ // a parent window. scoped_ptr<web_modal::PopupManager> popup_manager_; + content::NotificationRegistrar registrar_; + DISALLOW_COPY_AND_ASSIGN(ExtensionViewHost); };
diff --git a/chrome/browser/extensions/external_provider_impl.cc b/chrome/browser/extensions/external_provider_impl.cc index 9966755..b517af5 100644 --- a/chrome/browser/extensions/external_provider_impl.cc +++ b/chrome/browser/extensions/external_provider_impl.cc
@@ -498,7 +498,7 @@ oem_extension_creation_flags))); } #elif defined(OS_LINUX) - if (!profile->IsSupervised()) { + if (!profile->IsLegacySupervised()) { provider_list->push_back( linked_ptr<ExternalProviderInterface>( new ExternalProviderImpl( @@ -514,7 +514,7 @@ } #endif - if (!profile->IsSupervised()) { + if (!profile->IsLegacySupervised()) { #if defined(OS_WIN) provider_list->push_back( linked_ptr<ExternalProviderInterface>( @@ -570,17 +570,17 @@ Extension::FROM_WEBSTORE | Extension::WAS_INSTALLED_BY_DEFAULT))); #endif - - provider_list->push_back( - linked_ptr<ExternalProviderInterface>( - new ExternalProviderImpl( - service, - new ExternalComponentLoader(profile), - profile, - Manifest::INVALID_LOCATION, - Manifest::EXTERNAL_COMPONENT, - Extension::FROM_WEBSTORE | Extension::WAS_INSTALLED_BY_DEFAULT))); } + + provider_list->push_back( + linked_ptr<ExternalProviderInterface>( + new ExternalProviderImpl( + service, + new ExternalComponentLoader(profile), + profile, + Manifest::INVALID_LOCATION, + Manifest::EXTERNAL_COMPONENT, + Extension::FROM_WEBSTORE | Extension::WAS_INSTALLED_BY_DEFAULT))); } } // namespace extensions
diff --git a/chrome/browser/mac/keystone_glue.h b/chrome/browser/mac/keystone_glue.h index 5c21c36..c6295a5 100644 --- a/chrome/browser/mac/keystone_glue.h +++ b/chrome/browser/mac/keystone_glue.h
@@ -87,6 +87,7 @@ // And the Keystone registration itself, with the active timer KSRegistration* registration_; // strong NSTimer* timer_; // strong + Class ksUnsignedReportingAttributeClass_; // The most recent kAutoupdateStatusNotification notification posted. base::scoped_nsobject<NSNotification> recentNotification_; @@ -101,6 +102,10 @@ // YES if an update was ever successfully installed by -installUpdate. BOOL updateSuccessfullyInstalled_; + + // Profile count information. + uint32_t numProfiles_; + uint32_t numSignedInProfiles_; } // Return the default Keystone Glue object. @@ -172,6 +177,10 @@ // at the installed copy. - (void)setAppPath:(NSString*)appPath; +// Sets the total number of profiles and the number of signed in profiles. +- (void)updateProfileCountsWithNumProfiles:(uint32_t)profiles + numSignedInProfiles:(uint32_t)signedInProfiles; + @end // @interface KeystoneGlue @interface KeystoneGlue(ExposedForTesting)
diff --git a/chrome/browser/mac/keystone_glue.mm b/chrome/browser/mac/keystone_glue.mm index bd0e12e8..42b6b49e 100644 --- a/chrome/browser/mac/keystone_glue.mm +++ b/chrome/browser/mac/keystone_glue.mm
@@ -119,6 +119,9 @@ // Called when Keystone registration completes. - (void)registrationComplete:(NSNotification*)notification; +// Set the registration active and pass profile count parameters. +- (void)setRegistrationActive; + // Called periodically to announce activity by pinging the Keystone server. - (void)markActive:(NSTimer*)timer; @@ -445,6 +448,8 @@ return NO; registration_ = [ksr retain]; + ksUnsignedReportingAttributeClass_ = + [ksrBundle classNamed:@"KSUnsignedReportingAttribute"]; return YES; } @@ -491,6 +496,47 @@ nil]; } +- (void)setRegistrationActive { + if (!registration_) + return; + + // Should never have zero profiles. Do not report this value. + if (!numProfiles_) { + [registration_ setActive]; + return; + } + + NSError* reportingError = nil; + + KSReportingAttribute* numAccountsAttr = + [ksUnsignedReportingAttributeClass_ + reportingAttributeWithValue:numProfiles_ + name:@"_NumAccounts" + aggregationType:kKSReportingAggregationSum + error:&reportingError]; + if (reportingError != nil) + VLOG(1) << [reportingError localizedDescription]; + reportingError = nil; + + KSReportingAttribute* numSignedInAccountsAttr = + [ksUnsignedReportingAttributeClass_ + reportingAttributeWithValue:numSignedInProfiles_ + name:@"_NumSignedIn" + aggregationType:kKSReportingAggregationSum + error:&reportingError]; + if (reportingError != nil) + VLOG(1) << [reportingError localizedDescription]; + reportingError = nil; + + NSArray* profileCountsInformation = + [NSArray arrayWithObjects:numAccountsAttr, numSignedInAccountsAttr, nil]; + + if (![registration_ setActiveWithReportingAttributes:profileCountsInformation + error:&reportingError]) { + VLOG(1) << [reportingError localizedDescription]; + } +} + - (void)registerWithKeystone { [self updateStatus:kAutoupdateRegistering version:nil]; @@ -512,13 +558,13 @@ // posted, and -registrationComplete: will be called. // Mark an active RIGHT NOW; don't wait an hour for the first one. - [registration_ setActive]; + [self setRegistrationActive]; // Set up hourly activity pings. timer_ = [NSTimer scheduledTimerWithTimeInterval:60 * 60 // One hour target:self selector:@selector(markActive:) - userInfo:registration_ + userInfo:nil repeats:YES]; } @@ -541,8 +587,7 @@ } - (void)markActive:(NSTimer*)timer { - KSRegistration* ksr = [timer userInfo]; - [ksr setActive]; + [self setRegistrationActive]; } - (void)checkForUpdate { @@ -1049,6 +1094,13 @@ return tagSuffix; } + +- (void)updateProfileCountsWithNumProfiles:(uint32_t)profiles + numSignedInProfiles:(uint32_t)signedInProfiles { + numProfiles_ = profiles; + numSignedInProfiles_ = signedInProfiles; +} + @end // @implementation KeystoneGlue namespace {
diff --git a/chrome/browser/mac/keystone_glue_unittest.mm b/chrome/browser/mac/keystone_glue_unittest.mm index 0021e84..3128fe9e 100644 --- a/chrome/browser/mac/keystone_glue_unittest.mm +++ b/chrome/browser/mac/keystone_glue_unittest.mm
@@ -39,6 +39,11 @@ return NO; } +- (BOOL)setActiveWithReportingAttributes:(NSArray*)reportingAttributes + error:(NSError**)error { + return NO; +} + - (void)checkForUpdateWasUserInitiated:(BOOL)userInitiated { }
diff --git a/chrome/browser/mac/keystone_registration.h b/chrome/browser/mac/keystone_registration.h index 056dde1..3fa9197 100644 --- a/chrome/browser/mac/keystone_registration.h +++ b/chrome/browser/mac/keystone_registration.h
@@ -48,10 +48,19 @@ extern NSString* KSUpdateCheckSuccessfullyInstalledKey; extern NSString* KSRegistrationRemoveExistingTag; + +extern NSString* KSReportingAttributeValueKey; +extern NSString* KSReportingAttributeExpirationDateKey; +extern NSString* KSReportingAttributeAggregationTypeKey; #define KSRegistrationPreserveExistingTag nil } // namespace keystone_registration +typedef enum { + kKSReportingAggregationSum = 0, // Adds attribute value across user accounts + kKSReportingAggregationDefault = kKSReportingAggregationSum, +} KSReportingAggregationType; + @interface KSRegistration : NSObject + (id)registrationWithProductID:(NSString*)productID; @@ -62,10 +71,30 @@ authorization:(AuthorizationRef)authorization; - (BOOL)setActive; +- (BOOL)setActiveWithReportingAttributes:(NSArray*)reportingAttributes + error:(NSError**)error; - (void)checkForUpdateWasUserInitiated:(BOOL)userInitiated; - (void)startUpdate; - (keystone_registration::KSRegistrationTicketType)ticketType; @end // @interface KSRegistration + +// Declarations of the Keystone attribute reporting bits needed here. +// Full definition is at: +// //depot/googlemac/opensource/update-engine/Common/KSReportingAttribute.h +@interface KSReportingAttribute : NSObject + +@end // @interface KSReportingAttribute + +@interface KSUnsignedReportingAttribute : KSReportingAttribute + ++ (KSUnsignedReportingAttribute *)reportingAttributeWithValue:(uint32_t)value + name:(NSString *)name + aggregationType:(KSReportingAggregationType)aggregationType + error:(NSError **)error; + +@end // @interface KSUnsignedReportingAttribute + + #endif // CHROME_BROWSER_MAC_KEYSTONE_REGISTRATION_H_
diff --git a/chrome/browser/mac/keystone_registration.mm b/chrome/browser/mac/keystone_registration.mm index 779ec94..82e26599 100644 --- a/chrome/browser/mac/keystone_registration.mm +++ b/chrome/browser/mac/keystone_registration.mm
@@ -39,4 +39,8 @@ NSString* KSRegistrationRemoveExistingTag = @""; +NSString* KSReportingAttributeValueKey = @"value"; +NSString* KSReportingAttributeExpirationDateKey = @"expiresAt"; +NSString* KSReportingAttributeAggregationTypeKey = @"aggregation"; + } // namespace keystone_registration
diff --git a/chrome/browser/prefs/browser_prefs.cc b/chrome/browser/prefs/browser_prefs.cc index a913c1c9..2480526 100644 --- a/chrome/browser/prefs/browser_prefs.cc +++ b/chrome/browser/prefs/browser_prefs.cc
@@ -162,7 +162,6 @@ #include "chrome/browser/chromeos/extensions/echo_private_api.h" #include "chrome/browser/chromeos/file_system_provider/registry.h" #include "chrome/browser/chromeos/first_run/first_run.h" -#include "chrome/browser/chromeos/login/default_pinned_apps_field_trial.h" #include "chrome/browser/chromeos/login/saml/saml_offline_signin_limiter.h" #include "chrome/browser/chromeos/login/session/user_session_manager.h" #include "chrome/browser/chromeos/login/startup_utils.h" @@ -223,19 +222,6 @@ namespace { -enum MigratedPreferences { - NO_PREFS = 0, - DNS_PREFS = 1 << 0, - WINDOWS_PREFS = 1 << 1, -}; - -// A previous feature (see -// chrome/browser/protector/protected_prefs_watcher.cc in source -// control history) used this string as a prefix for various prefs it -// registered. We keep it here for now to clear out those old prefs in -// MigrateUserPrefs. -const char kBackupPref[] = "backup"; - #if !defined(OS_ANDROID) // The AutomaticProfileResetter service used this preference to save that the // profile reset prompt had already been shown, however, the preference has been @@ -250,8 +236,6 @@ namespace chrome { void RegisterLocalState(PrefRegistrySimple* registry) { - // Prefs in Local State. - registry->RegisterIntegerPref(prefs::kMultipleProfilePrefMigration, 0); // Please keep this list alphabetized. AppListService::RegisterPrefs(registry); @@ -328,7 +312,6 @@ chromeos::DataPromoNotification::RegisterPrefs(registry); chromeos::DeviceOAuth2TokenService::RegisterPrefs(registry); chromeos::device_settings_cache::RegisterPrefs(registry); - chromeos::default_pinned_apps_field_trial::RegisterPrefs(registry); chromeos::EnableDebuggingScreenHandler::RegisterPrefs(registry); chromeos::language_prefs::RegisterPrefs(registry); chromeos::KioskAppManager::RegisterPrefs(registry); @@ -528,13 +511,6 @@ #if defined(USE_ASH) ash::RegisterChromeLauncherUserPrefs(registry); #endif - - // Preferences registered only for migration (clearing or moving to a new key) - // go here. - registry->RegisterDictionaryPref( - kBackupPref, - new base::DictionaryValue(), - user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF); } void RegisterUserProfilePrefs(user_prefs::PrefRegistrySyncable* registry) { @@ -557,82 +533,47 @@ } #endif -void MigrateUserPrefs(Profile* profile) { - PrefService* prefs = profile->GetPrefs(); - - // Cleanup prefs from now-removed protector feature. - prefs->ClearPref(kBackupPref); +// This method should be periodically pruned of year+ old migrations. +void MigrateObsoleteBrowserPrefs(Profile* profile, PrefService* local_state) { +#if defined(TOOLKIT_VIEWS) + // Added 05/2014. + MigrateBrowserTabStripPrefs(local_state); +#endif #if !defined(OS_ANDROID) + // Added 08/2014. + local_state->ClearPref(kLegacyProfileResetPromptMemento); +#endif +} + +// This method should be periodically pruned of year+ old migrations. +void MigrateObsoleteProfilePrefs(Profile* profile) { + PrefService* profile_prefs = profile->GetPrefs(); + +#if defined(OS_MACOSX) && !defined(OS_IOS) + // Added 06/2014. + autofill::AutofillManager::MigrateUserPrefs(profile_prefs); +#endif // defined(OS_MACOSX) && !defined(OS_IOS) + + // Added 07/2014. + translate::TranslatePrefs::MigrateUserPrefs(profile_prefs, + prefs::kAcceptLanguages); + +#if !defined(OS_ANDROID) + // Added 08/2014. // Migrate kNetworkPredictionEnabled to kNetworkPredictionOptions when not on // Android. On Android, platform-specific code performs preference migration. // TODO(bnc): https://crbug.com/401970 Remove migration code one year after // M38. - chrome_browser_net::MigrateNetworkPredictionUserPrefs(prefs); + chrome_browser_net::MigrateNetworkPredictionUserPrefs(profile_prefs); #endif - PromoResourceService::MigrateUserPrefs(prefs); - translate::TranslatePrefs::MigrateUserPrefs(prefs, prefs::kAcceptLanguages); - -#if defined(OS_MACOSX) && !defined(OS_IOS) - autofill::AutofillManager::MigrateUserPrefs(prefs); -#endif // defined(OS_MACOSX) && !defined(OS_IOS) - #if defined(OS_CHROMEOS) && defined(ENABLE_APP_LIST) + // Added 02/2015. MigrateGoogleNowPrefs(profile); #endif } -void MigrateBrowserPrefs(Profile* profile, PrefService* local_state) { - // Copy pref values which have been migrated to user_prefs from local_state, - // or remove them from local_state outright, if copying is not required. - int current_version = - local_state->GetInteger(prefs::kMultipleProfilePrefMigration); - PrefRegistrySimple* registry = static_cast<PrefRegistrySimple*>( - local_state->DeprecatedGetPrefRegistry()); - - if (!(current_version & DNS_PREFS)) { - registry->RegisterListPref(prefs::kDnsStartupPrefetchList); - local_state->ClearPref(prefs::kDnsStartupPrefetchList); - - registry->RegisterListPref(prefs::kDnsHostReferralList); - local_state->ClearPref(prefs::kDnsHostReferralList); - - current_version |= DNS_PREFS; - local_state->SetInteger(prefs::kMultipleProfilePrefMigration, - current_version); - } - - PrefService* user_prefs = profile->GetPrefs(); - if (!(current_version & WINDOWS_PREFS)) { - registry->RegisterDictionaryPref(prefs::kBrowserWindowPlacement); - if (local_state->HasPrefPath(prefs::kBrowserWindowPlacement)) { - const PrefService::Preference* pref = - local_state->FindPreference(prefs::kBrowserWindowPlacement); - DCHECK(pref); - user_prefs->Set(prefs::kBrowserWindowPlacement, - *(pref->GetValue())); - } - local_state->ClearPref(prefs::kBrowserWindowPlacement); - - current_version |= WINDOWS_PREFS; - local_state->SetInteger(prefs::kMultipleProfilePrefMigration, - current_version); - } - -#if !defined(OS_ANDROID) - local_state->ClearPref(kLegacyProfileResetPromptMemento); -#endif - -#if defined(OS_CHROMEOS) - chromeos::default_pinned_apps_field_trial::MigratePrefs(local_state); -#endif - -#if defined(TOOLKIT_VIEWS) - MigrateBrowserTabStripPrefs(local_state); -#endif -} - // As part of the migration from per-profile to per-partition HostZoomMaps, // we need to detect if an existing per-profile set of preferences exist, and // if so convert them to be per-partition. We migrate any per-profile zoom
diff --git a/chrome/browser/prefs/browser_prefs.h b/chrome/browser/prefs/browser_prefs.h index 9fa2829..122ebe4 100644 --- a/chrome/browser/prefs/browser_prefs.h +++ b/chrome/browser/prefs/browser_prefs.h
@@ -30,11 +30,17 @@ void RegisterLoginProfilePrefs(user_prefs::PrefRegistrySyncable* registry); #endif -// Migrates prefs from |local_state| to |profile|'s pref store. -void MigrateBrowserPrefs(Profile* profile, PrefService* local_state); +// Migrate/cleanup deprecated prefs in |local_state|. Over time, long deprecated +// prefs should be removed as new ones are added, but this call should never go +// away (even if it becomes an empty call for some time) as it should remain +// *the* place to drop deprecated browser prefs at. +void MigrateObsoleteBrowserPrefs(Profile* profile, PrefService* local_state); -// Migrates prefs in |profile|'s pref store. -void MigrateUserPrefs(Profile* profile); +// Migrate/cleanup deprecated prefs in |profile|'s pref store. Over time, long +// deprecated prefs should be removed as new ones are added, but this call +// should never go away (even if it becomes an empty call for some time) as it +// should remain *the* place to drop deprecated profile prefs at. +void MigrateObsoleteProfilePrefs(Profile* profile); // Migrates zoom level prefs in |profile|'s pref store to a per-StoragePartition // set of prefs.
diff --git a/chrome/browser/prefs/pref_service_browsertest.cc b/chrome/browser/prefs/pref_service_browsertest.cc index ba72e21..1a87b041 100644 --- a/chrome/browser/prefs/pref_service_browsertest.cc +++ b/chrome/browser/prefs/pref_service_browsertest.cc
@@ -52,41 +52,29 @@ class PreferenceServiceTest : public InProcessBrowserTest { public: - explicit PreferenceServiceTest(bool new_profile) : new_profile_(new_profile) { - } - bool SetUpUserDataDirectory() override { base::FilePath user_data_directory; PathService::Get(chrome::DIR_USER_DATA, &user_data_directory); - if (new_profile_) { - original_pref_file_ = ui_test_utils::GetTestFilePath( - base::FilePath().AppendASCII("profiles"). - AppendASCII("window_placement"). - AppendASCII("Default"), - base::FilePath().Append(chrome::kPreferencesFilename)); - tmp_pref_file_ = - user_data_directory.AppendASCII(TestingProfile::kTestUserProfileDir); - CHECK(base::CreateDirectory(tmp_pref_file_)); - tmp_pref_file_ = tmp_pref_file_.Append(chrome::kPreferencesFilename); - } else { - original_pref_file_ = ui_test_utils::GetTestFilePath( - base::FilePath().AppendASCII("profiles"). - AppendASCII("window_placement"), - base::FilePath().Append(chrome::kLocalStateFilename)); - tmp_pref_file_ = user_data_directory.Append(chrome::kLocalStateFilename); - } + original_pref_file_ = ui_test_utils::GetTestFilePath( + base::FilePath() + .AppendASCII("profiles") + .AppendASCII("window_placement") + .AppendASCII("Default"), + base::FilePath().Append(chrome::kPreferencesFilename)); + tmp_pref_file_ = + user_data_directory.AppendASCII(TestingProfile::kTestUserProfileDir); + EXPECT_TRUE(base::CreateDirectory(tmp_pref_file_)); + tmp_pref_file_ = tmp_pref_file_.Append(chrome::kPreferencesFilename); - CHECK(base::PathExists(original_pref_file_)); - // Copy only the Preferences file if |new_profile_|, or Local State if not, - // and the rest will be automatically created. - CHECK(base::CopyFile(original_pref_file_, tmp_pref_file_)); + EXPECT_TRUE(base::PathExists(original_pref_file_)); + EXPECT_TRUE(base::CopyFile(original_pref_file_, tmp_pref_file_)); #if defined(OS_WIN) // Make the copy writable. On POSIX we assume the umask allows files // we create to be writable. - CHECK(::SetFileAttributesW(tmp_pref_file_.value().c_str(), - FILE_ATTRIBUTE_NORMAL)); + EXPECT_TRUE(::SetFileAttributesW(tmp_pref_file_.value().c_str(), + FILE_ATTRIBUTE_NORMAL)); #endif return true; } @@ -94,9 +82,6 @@ protected: base::FilePath original_pref_file_; base::FilePath tmp_pref_file_; - - private: - bool new_profile_; }; #if defined(OS_WIN) || defined(OS_MACOSX) @@ -106,13 +91,7 @@ // might be able to make this work on buildbots. // TODO(port): revisit this. -class PreservedWindowPlacementIsLoaded : public PreferenceServiceTest { - public: - PreservedWindowPlacementIsLoaded() : PreferenceServiceTest(true) { - } -}; - -IN_PROC_BROWSER_TEST_F(PreservedWindowPlacementIsLoaded, Test) { +IN_PROC_BROWSER_TEST_F(PreferenceServiceTest, Test) { #if defined(OS_WIN) && defined(USE_ASH) // Disable this test in Metro+Ash for now (http://crbug.com/262796). if (base::CommandLine::ForCurrentProcess()->HasSwitch( @@ -164,69 +143,3 @@ EXPECT_EQ(is_maximized, is_window_maximized); } #endif - -#if defined(OS_WIN) || defined(OS_MACOSX) - -class PreservedWindowPlacementIsMigrated : public PreferenceServiceTest { - public: - PreservedWindowPlacementIsMigrated() : PreferenceServiceTest(false) { - } -}; - -IN_PROC_BROWSER_TEST_F(PreservedWindowPlacementIsMigrated, Test) { -#if defined(OS_WIN) && defined(USE_ASH) - // Disable this test in Metro+Ash for now (http://crbug.com/262796). - if (base::CommandLine::ForCurrentProcess()->HasSwitch( - switches::kAshBrowserTests)) - return; -#endif - - // The window should open with the old reference profile, with window - // placement values stored in Local State. - - JSONFileValueSerializer deserializer(original_pref_file_); - scoped_ptr<base::Value> root(deserializer.Deserialize(NULL, NULL)); - - ASSERT_TRUE(root.get()); - ASSERT_TRUE(root->IsType(base::Value::TYPE_DICTIONARY)); - - // Retrieve the screen rect for the launched window - gfx::Rect bounds = browser()->window()->GetRestoredBounds(); - - // Values from old reference profile in Local State should have been - // correctly migrated to the user's Preferences -- if so, the window - // should be set to values taken from the user's Local State. - base::DictionaryValue* root_dict = - static_cast<base::DictionaryValue*>(root.get()); - - // Retrieve the expected rect values from User Preferences, where they - // should have been migrated from Local State. - int bottom = 0; - std::string kBrowserWindowPlacement(prefs::kBrowserWindowPlacement); - EXPECT_TRUE(root_dict->GetInteger(kBrowserWindowPlacement + ".bottom", - &bottom)); - EXPECT_EQ(bottom, bounds.y() + bounds.height()); - - int top = 0; - EXPECT_TRUE(root_dict->GetInteger(kBrowserWindowPlacement + ".top", - &top)); - EXPECT_EQ(top, bounds.y()); - - int left = 0; - EXPECT_TRUE(root_dict->GetInteger(kBrowserWindowPlacement + ".left", - &left)); - EXPECT_EQ(left, bounds.x()); - - int right = 0; - EXPECT_TRUE(root_dict->GetInteger(kBrowserWindowPlacement + ".right", - &right)); - EXPECT_EQ(right, bounds.x() + bounds.width()); - - // Find if launched window is maximized. - bool is_window_maximized = browser()->window()->IsMaximized(); - bool is_maximized = false; - EXPECT_TRUE(root_dict->GetBoolean(kBrowserWindowPlacement + ".maximized", - &is_maximized)); - EXPECT_EQ(is_maximized, is_window_maximized); -} -#endif
diff --git a/chrome/browser/profiles/profile_impl.cc b/chrome/browser/profiles/profile_impl.cc index 9b7389f..05bd533 100644 --- a/chrome/browser/profiles/profile_impl.cc +++ b/chrome/browser/profiles/profile_impl.cc
@@ -851,11 +851,10 @@ return; } - // TODO(mirandac): remove migration code after 6 months (crbug.com/69995). + // Migrate obsolete prefs. if (g_browser_process->local_state()) - chrome::MigrateBrowserPrefs(this, g_browser_process->local_state()); - // TODO(ivankr): remove cleanup code eventually (crbug.com/165672). - chrome::MigrateUserPrefs(this); + chrome::MigrateObsoleteBrowserPrefs(this, g_browser_process->local_state()); + chrome::MigrateObsoleteProfilePrefs(this); // |kSessionExitType| was added after |kSessionExitedCleanly|. If the pref // value is empty fallback to checking for |kSessionExitedCleanly|.
diff --git a/chrome/browser/profiles/profile_manager.cc b/chrome/browser/profiles/profile_manager.cc index 36ee8e3d..7d3f1fb 100644 --- a/chrome/browser/profiles/profile_manager.cc +++ b/chrome/browser/profiles/profile_manager.cc
@@ -558,8 +558,8 @@ Profile* ProfileManager::GetProfileByPath(const base::FilePath& path) const { TRACE_EVENT0("browser", "ProfileManager::GetProfileByPath"); ProfileInfo* profile_info = GetProfileInfoByPath(path); - return profile_info && profile_info->created ? profile_info->profile.get() - : nullptr; + return (profile_info && profile_info->created) ? profile_info->profile.get() + : nullptr; } // static @@ -650,7 +650,6 @@ service->CancelDownloads(); } - PrefService* local_state = g_browser_process->local_state(); ProfileInfoCache& cache = GetProfileInfoCache(); // If we're deleting the last (non-legacy-supervised) profile, then create a @@ -682,51 +681,42 @@ new_path = GenerateNextProfileDirectoryPath(); CreateProfileAsync(new_path, - callback, + base::Bind(&ProfileManager::OnNewActiveProfileLoaded, + base::Unretained(this), + profile_dir, + new_path, + callback), new_profile_name, new_avatar_url, std::string()); ProfileMetrics::LogProfileAddNewUser( ProfileMetrics::ADD_NEW_USER_LAST_DELETED); + return; } - // Update the last used profile pref before closing browser windows. This - // way the correct last used profile is set for any notification observers. +#if defined(OS_MACOSX) + // On the Mac, the browser process is not killed when all browser windows are + // closed, so just in case we are deleting the active profile, and no other + // profile has been loaded, we must pre-load a next one. const std::string last_used_profile = - local_state->GetString(prefs::kProfileLastUsed); + g_browser_process->local_state()->GetString(prefs::kProfileLastUsed); if (last_used_profile == profile_dir.BaseName().MaybeAsASCII() || last_used_profile == GetGuestProfilePath().BaseName().MaybeAsASCII()) { - const std::string last_non_supervised_profile = - last_non_supervised_profile_path.BaseName().MaybeAsASCII(); - if (last_non_supervised_profile.empty()) { - DCHECK(!new_path.empty()); - local_state->SetString(prefs::kProfileLastUsed, - new_path.BaseName().MaybeAsASCII()); - } else { - // On the Mac, the browser process is not killed when all browser windows - // are closed, so just in case we are deleting the active profile, and no - // other profile has been loaded, we must pre-load a next one. -#if defined(OS_MACOSX) - CreateProfileAsync(last_non_supervised_profile_path, - base::Bind(&ProfileManager::OnNewActiveProfileLoaded, - base::Unretained(this), - profile_dir, - last_non_supervised_profile_path, - callback), - base::string16(), - base::string16(), - std::string()); - return; -#else - // For OS_MACOSX the pref is updated in the callback to make sure that - // it isn't used before the profile is actually loaded. - local_state->SetString(prefs::kProfileLastUsed, - last_non_supervised_profile); -#endif - } + CreateProfileAsync(last_non_supervised_profile_path, + base::Bind(&ProfileManager::OnNewActiveProfileLoaded, + base::Unretained(this), + profile_dir, + last_non_supervised_profile_path, + callback), + base::string16(), + base::string16(), + std::string()); + return; } - FinishDeletingProfile(profile_dir); +#endif // defined(OS_MACOSX) + + FinishDeletingProfile(profile_dir, last_non_supervised_profile_path); } // static @@ -1160,7 +1150,15 @@ return profile; } -void ProfileManager::FinishDeletingProfile(const base::FilePath& profile_dir) { +void ProfileManager::FinishDeletingProfile( + const base::FilePath& profile_dir, + const base::FilePath& new_active_profile_dir) { + // Update the last used profile pref before closing browser windows. This + // way the correct last used profile is set for any notification observers. + g_browser_process->local_state()->SetString( + prefs::kProfileLastUsed, + new_active_profile_dir.BaseName().MaybeAsASCII()); + ProfileInfoCache& cache = GetProfileInfoCache(); // TODO(sail): Due to bug 88586 we don't delete the profile instance. Once we // start deleting the profile instance we need to close background apps too. @@ -1372,10 +1370,9 @@ } #endif // !defined(OS_ANDROID) && !defined(OS_IOS) -#if defined(OS_MACOSX) void ProfileManager::OnNewActiveProfileLoaded( const base::FilePath& profile_to_delete_path, - const base::FilePath& last_non_supervised_profile_path, + const base::FilePath& new_active_profile_path, const CreateCallback& original_callback, Profile* loaded_profile, Profile::CreateStatus status) { @@ -1383,22 +1380,21 @@ status != Profile::CREATE_STATUS_REMOTE_FAIL); // Only run the code if the profile initialization has finished completely. - if (status == Profile::CREATE_STATUS_INITIALIZED) { - if (IsProfileMarkedForDeletion(last_non_supervised_profile_path)) { - // If the profile we tried to load as the next active profile has been - // deleted, then retry deleting this profile to redo the logic to load - // the next available profile. - ScheduleProfileForDeletion(profile_to_delete_path, original_callback); - } else { - // Update the local state as promised in the ScheduleProfileForDeletion. - g_browser_process->local_state()->SetString( - prefs::kProfileLastUsed, - last_non_supervised_profile_path.BaseName().MaybeAsASCII()); - FinishDeletingProfile(profile_to_delete_path); - } + if (status != Profile::CREATE_STATUS_INITIALIZED) + return; + + if (IsProfileMarkedForDeletion(new_active_profile_path)) { + // If the profile we tried to load as the next active profile has been + // deleted, then retry deleting this profile to redo the logic to load + // the next available profile. + ScheduleProfileForDeletion(profile_to_delete_path, original_callback); + return; } + + FinishDeletingProfile(profile_to_delete_path, new_active_profile_path); + if (!original_callback.is_null()) + original_callback.Run(loaded_profile, status); } -#endif ProfileManagerWithoutInit::ProfileManagerWithoutInit( const base::FilePath& user_data_dir) : ProfileManager(user_data_dir) {
diff --git a/chrome/browser/profiles/profile_manager.h b/chrome/browser/profiles/profile_manager.h index ff28e3d1..9436a459e 100644 --- a/chrome/browser/profiles/profile_manager.h +++ b/chrome/browser/profiles/profile_manager.h
@@ -265,8 +265,10 @@ // creation and adds it to the set managed by this ProfileManager. Profile* CreateAndInitializeProfile(const base::FilePath& profile_dir); - // Schedules the profile at the given path to be deleted on shutdown. - void FinishDeletingProfile(const base::FilePath& profile_dir); + // Schedules the profile at the given path to be deleted on shutdown, + // and marks the new profile as active. + void FinishDeletingProfile(const base::FilePath& profile_dir, + const base::FilePath& new_active_profile_dir); // Registers profile with given info. Returns pointer to created ProfileInfo // entry. @@ -317,7 +319,6 @@ }; #endif // !defined(OS_ANDROID) && !defined(OS_IOS) -#if defined(OS_MACOSX) // If the |loaded_profile| has been loaded successfully (according to // |status|) and isn't already scheduled for deletion, then finishes adding // |profile_to_delete_dir| to the queue of profiles to be deleted, and updates @@ -329,7 +330,6 @@ const CreateCallback& original_callback, Profile* loaded_profile, Profile::CreateStatus status); -#endif content::NotificationRegistrar registrar_;
diff --git a/chrome/browser/profiles/profile_manager_browsertest.cc b/chrome/browser/profiles/profile_manager_browsertest.cc index 820eb18..43df0d4b 100644 --- a/chrome/browser/profiles/profile_manager_browsertest.cc +++ b/chrome/browser/profiles/profile_manager_browsertest.cc
@@ -40,10 +40,11 @@ // An observer that returns back to test code after a new profile is // initialized. -void OnUnblockOnProfileCreation(Profile* profile, +void OnUnblockOnProfileCreation(base::RunLoop* run_loop, + Profile* profile, Profile::CreateStatus status) { if (status == Profile::CREATE_STATUS_INITIALIZED) - base::MessageLoop::current()->Quit(); + run_loop->Quit(); } void ProfileCreationComplete(Profile* profile, Profile::CreateStatus status) { @@ -91,26 +92,26 @@ // The class serves to retrieve passwords from PasswordStore asynchronously. It // used by ProfileManagerBrowserTest.DeletePasswords on some platforms. -class PasswordStoreConsumerVerifier : - public password_manager::PasswordStoreConsumer { +class PasswordStoreConsumerVerifier + : public password_manager::PasswordStoreConsumer { public: - PasswordStoreConsumerVerifier() : called_(false) {} - void OnGetPasswordStoreResults( ScopedVector<autofill::PasswordForm> results) override { - EXPECT_FALSE(called_); - called_ = true; password_entries_.swap(results); + run_loop_.Quit(); } - bool IsCalled() const { return called_; } + void Wait() { + run_loop_.Run(); + } const std::vector<autofill::PasswordForm*>& GetPasswords() const { return password_entries_.get(); } + private: + base::RunLoop run_loop_; ScopedVector<autofill::PasswordForm> password_entries_; - bool called_; }; static base::FilePath GetFirstNonSigninProfile(const ProfileInfoCache& cache) { @@ -160,20 +161,23 @@ // Delete singleton profile. base::FilePath singleton_profile_path = cache.GetPathOfProfileAtIndex(0); EXPECT_FALSE(singleton_profile_path.empty()); - profile_manager->ScheduleProfileForDeletion(singleton_profile_path, - ProfileManager::CreateCallback()); + base::RunLoop run_loop; + profile_manager->ScheduleProfileForDeletion( + singleton_profile_path, + base::Bind(&OnUnblockOnProfileCreation, &run_loop)); - // Spin things till profile is actually deleted. - content::RunAllPendingInMessageLoop(); + // Run the message loop until the profile is actually deleted (as indicated + // by the callback above being called). + run_loop.Run(); // Make sure a new profile was created automatically. EXPECT_EQ(cache.GetNumberOfProfiles(), 1U); base::FilePath new_profile_path = cache.GetPathOfProfileAtIndex(0); - EXPECT_NE(new_profile_path, singleton_profile_path); + EXPECT_NE(new_profile_path.value(), singleton_profile_path.value()); // Make sure that last used profile preference is set correctly. Profile* last_used = ProfileManager::GetLastUsedProfile(); - EXPECT_EQ(new_profile_path, last_used->GetPath()); + EXPECT_EQ(new_profile_path.value(), last_used->GetPath().value()); // Make sure the last used profile was set correctly before the notification // was sent. @@ -191,14 +195,14 @@ // Create an additional profile. base::FilePath new_path = profile_manager->GenerateNextProfileDirectoryPath(); - profile_manager->CreateProfileAsync(new_path, - base::Bind(&OnUnblockOnProfileCreation), - base::string16(), base::string16(), - std::string()); + base::RunLoop run_loop; + profile_manager->CreateProfileAsync( + new_path, base::Bind(&OnUnblockOnProfileCreation, &run_loop), + base::string16(), base::string16(), std::string()); - // Spin to allow profile creation to take place, loop is terminated - // by OnUnblockOnProfileCreation when the profile is created. - content::RunMessageLoop(); + // Run the message loop to allow profile creation to take place; the loop is + // terminated by OnUnblockOnProfileCreation when the profile is created. + run_loop.Run(); ASSERT_EQ(cache.GetNumberOfProfiles(), 2U); @@ -306,14 +310,14 @@ // Create an additional profile. base::FilePath path_profile2 = profile_manager->GenerateNextProfileDirectoryPath(); - profile_manager->CreateProfileAsync(path_profile2, - base::Bind(&OnUnblockOnProfileCreation), - base::string16(), base::string16(), - std::string()); + base::RunLoop run_loop; + profile_manager->CreateProfileAsync( + path_profile2, base::Bind(&OnUnblockOnProfileCreation, &run_loop), + base::string16(), base::string16(), std::string()); - // Spin to allow profile creation to take place, loop is terminated - // by OnUnblockOnProfileCreation when the profile is created. - content::RunMessageLoop(); + // Run the message loop to allow profile creation to take place; the loop is + // terminated by OnUnblockOnProfileCreation when the profile is created. + run_loop.Run(); chrome::HostDesktopType desktop_type = chrome::GetActiveDesktop(); BrowserList* browser_list = BrowserList::GetInstance(desktop_type); @@ -445,27 +449,18 @@ password_store->AddLogin(form); PasswordStoreConsumerVerifier verify_add; password_store->GetAutofillableLogins(&verify_add); + verify_add.Wait(); + EXPECT_EQ(1u, verify_add.GetPasswords().size()); ProfileManager* profile_manager = g_browser_process->profile_manager(); - profile_manager->ScheduleProfileForDeletion(profile->GetPath(), - ProfileManager::CreateCallback()); - content::RunAllPendingInMessageLoop(); - PasswordStoreConsumerVerifier verify_delete; - password_store->GetAutofillableLogins(&verify_delete); - - // Run the password background thread. base::RunLoop run_loop; - base::Closure task = base::Bind( - base::IgnoreResult(&content::BrowserThread::PostTask), - content::BrowserThread::UI, - FROM_HERE, - run_loop.QuitClosure()); - EXPECT_TRUE(password_store->ScheduleTask(task)); + profile_manager->ScheduleProfileForDeletion( + profile->GetPath(), base::Bind(&OnUnblockOnProfileCreation, &run_loop)); run_loop.Run(); - EXPECT_TRUE(verify_add.IsCalled()); - EXPECT_EQ(1u, verify_add.GetPasswords().size()); - EXPECT_TRUE(verify_delete.IsCalled()); + PasswordStoreConsumerVerifier verify_delete; + password_store->GetAutofillableLogins(&verify_delete); + verify_delete.Wait(); EXPECT_EQ(0u, verify_delete.GetPasswords().size()); } #endif // !defined(OS_WIN) && !defined(OS_ANDROID) && !defined(OS_CHROMEOS)
diff --git a/chrome/browser/profiles/profile_metrics.cc b/chrome/browser/profiles/profile_metrics.cc index 6dfcf73c..f9b3046 100644 --- a/chrome/browser/profiles/profile_metrics.cc +++ b/chrome/browser/profiles/profile_metrics.cc
@@ -20,7 +20,10 @@ namespace { +#if defined(OS_WIN) || defined(OS_MACOSX) const int kMaximumReportedProfileCount = 5; +#endif + const int kMaximumDaysOfDisuse = 4 * 7; // Should be integral number of weeks. size_t number_of_profile_switches_ = 0; @@ -67,12 +70,6 @@ return metric; } -void UpdateReportedOSProfileStatistics(int active, int signedin) { -#if defined(OS_WIN) - GoogleUpdateSettings::UpdateProfileCounts(active, signedin); -#endif -} - void LogLockedProfileInformation(ProfileManager* manager) { const ProfileInfoCache& info_cache = manager->GetProfileInfoCache(); size_t number_of_profiles = info_cache.GetNumberOfProfiles(); @@ -177,10 +174,11 @@ } void ProfileMetrics::UpdateReportedProfilesStatistics(ProfileManager* manager) { +#if defined(OS_WIN) || defined(OS_MACOSX) ProfileCounts counts; if (CountProfileInformation(manager, &counts)) { - int limited_total = counts.total; - int limited_signedin = counts.signedin; + size_t limited_total = counts.total; + size_t limited_signedin = counts.signedin; if (limited_total > kMaximumReportedProfileCount) { limited_total = kMaximumReportedProfileCount + 1; limited_signedin = @@ -189,6 +187,7 @@ } UpdateReportedOSProfileStatistics(limited_total, limited_signedin); } +#endif } void ProfileMetrics::LogNumberOfProfileSwitches() { @@ -196,6 +195,14 @@ number_of_profile_switches_); } +// The OS_MACOSX implementation of this function is in profile_metrics_mac.mm. +#if defined(OS_WIN) +void ProfileMetrics::UpdateReportedOSProfileStatistics( + size_t active, size_t signedin) { + GoogleUpdateSettings::UpdateProfileCounts(active, signedin); +} +#endif + void ProfileMetrics::LogNumberOfProfiles(ProfileManager* manager) { ProfileCounts counts; bool success = CountProfileInformation(manager, &counts); @@ -217,7 +224,10 @@ counts.auth_errors); LogLockedProfileInformation(manager); + +#if defined(OS_WIN) || defined(OS_MACOSX) UpdateReportedOSProfileStatistics(counts.total, counts.signedin); +#endif } }
diff --git a/chrome/browser/profiles/profile_metrics.h b/chrome/browser/profiles/profile_metrics.h index 8feb60f..85ae5af 100644 --- a/chrome/browser/profiles/profile_metrics.h +++ b/chrome/browser/profiles/profile_metrics.h
@@ -208,6 +208,11 @@ ProfileCounts* counts); static void LogNumberOfProfileSwitches(); +#if defined(OS_WIN) || defined(OS_MACOSX) + // Update OS level tracking of profile counts. + static void UpdateReportedOSProfileStatistics(size_t active, size_t signedin); +#endif + static void LogNumberOfProfiles(ProfileManager* manager); static void LogProfileAddNewUser(ProfileAdd metric); static void LogProfileAvatarSelection(size_t icon_index);
diff --git a/chrome/browser/profiles/profile_metrics_mac.mm b/chrome/browser/profiles/profile_metrics_mac.mm new file mode 100644 index 0000000..8b12871 --- /dev/null +++ b/chrome/browser/profiles/profile_metrics_mac.mm
@@ -0,0 +1,18 @@ +// 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/profiles/profile_metrics.h" + +#include "base/numerics/safe_conversions.h" +#include "chrome/browser/mac/keystone_glue.h" + +void ProfileMetrics::UpdateReportedOSProfileStatistics( + size_t active, size_t signedin) { + if (base::IsValueInRangeForNumericType<uint32_t>(active) && + base::IsValueInRangeForNumericType<uint32_t>(signedin)) { + [[KeystoneGlue defaultKeystoneGlue] + updateProfileCountsWithNumProfiles:active + numSignedInProfiles:signedin]; + } +}
diff --git a/chrome/browser/resources/chromeos/network_ui/network_ui.css b/chrome/browser/resources/chromeos/network_ui/network_ui.css index c3fbf87..874e916a 100644 --- a/chrome/browser/resources/chromeos/network_ui/network_ui.css +++ b/chrome/browser/resources/chromeos/network_ui/network_ui.css
@@ -50,6 +50,11 @@ font-weight: bold; } +.state-table-icon-cell { + display: flex; + justify-content: center; +} + .state-table-expand-button-cell { text-align: center; }
diff --git a/chrome/browser/resources/extensions/extension_list.js b/chrome/browser/resources/extensions/extension_list.js index c185b29b..16b1132 100644 --- a/chrome/browser/resources/extensions/extension_list.js +++ b/chrome/browser/resources/extensions/extension_list.js
@@ -384,8 +384,7 @@ // The 'allow file:// access' checkbox. row.setupColumn('.file-access-control input', 'localUrls', 'click', function(e) { - chrome.send('extensionSettingsAllowFileAccess', - [extension.id, String(e.target.checked)]); + chrome.developerPrivate.allowFileAccess(extension.id, e.target.checked); }); // The 'Options' button or link, depending on its behaviour. @@ -467,6 +466,17 @@ function() { // TODO(devlin): What should we do if the uninstall fails? this.uninstallIsShowing_ = false; + + if (trash.classList.contains('mouse-clicked')) + trash.blur(); + + if (chrome.runtime.lastError) { + // The uninstall failed (e.g. a cancel). Allow the trash to close. + trash.classList.remove('open'); + } else { + // Leave the trash open if the uninstall succeded. Otherwise it can + // half-close right before it's removed when the DOM is modified. + } }.bind(this)); }.bind(this)); row.querySelector('.enable-controls').appendChild(trash); @@ -900,13 +910,6 @@ }, }; - ExtensionList.uninstallCancel = function() { - var trash = document.querySelector('.trash.open'); - if (trash.classList.contains('mouse-clicked')) - trash.blur(); - trash.classList.remove('open'); - }; - return { ExtensionList: ExtensionList };
diff --git a/chrome/browser/resources/extensions/extensions.js b/chrome/browser/resources/extensions/extensions.js index 20b486f6..6500f07c 100644 --- a/chrome/browser/resources/extensions/extensions.js +++ b/chrome/browser/resources/extensions/extensions.js
@@ -343,28 +343,6 @@ ExtensionList.decorate($('extension-settings-list')); }; - // Indicate that warning |message| has occured for pack of |crx_path| and - // |pem_path| files. Ask if user wants override the warning. Send - // |overrideFlags| to repeated 'pack' call to accomplish the override. - ExtensionSettings.askToOverrideWarning = - function(message, crx_path, pem_path, overrideFlags) { - var closeAlert = function() { - ExtensionSettings.showOverlay(null); - }; - - alertOverlay.setValues( - loadTimeData.getString('packExtensionWarningTitle'), - message, - loadTimeData.getString('packExtensionProceedAnyway'), - loadTimeData.getString('cancel'), - function() { - chrome.send('pack', [crx_path, pem_path, overrideFlags]); - closeAlert(); - }, - closeAlert); - ExtensionSettings.showOverlay($('alertOverlay')); - }; - /** * Returns the current overlay or null if one does not exist. * @return {Element} The overlay element.
diff --git a/chrome/browser/resources/extensions/pack_extension_overlay.js b/chrome/browser/resources/extensions/pack_extension_overlay.js index 186f841..8cb7725 100644 --- a/chrome/browser/resources/extensions/pack_extension_overlay.js +++ b/chrome/browser/resources/extensions/pack_extension_overlay.js
@@ -48,24 +48,24 @@ handleCommit_: function(e) { var extensionPath = $('extension-root-dir').value; var privateKeyPath = $('extension-private-key').value; - chrome.send('pack', [extensionPath, privateKeyPath, 0]); + chrome.developerPrivate.packDirectory( + extensionPath, privateKeyPath, 0, this.onPackResponse_.bind(this)); }, /** * Utility function which asks the C++ to show a platform-specific file - * select dialog, and fire |callback| with the |filePath| that resulted. - * |selectType| can be either 'file' or 'folder'. |operation| can be 'load' - * or 'pem' which are signals to the C++ to do some operation-specific - * configuration. + * select dialog, and set the value property of |node| to the selected path. + * @param {SelectType} selectType The type of selection to use. + * @param {FileType} fileType The type of file to select. + * @param {HTMLInputElement} node The node to set the value of. * @private */ - showFileDialog_: function(selectType, operation, callback) { - window.handleFilePathSelected = function(filePath) { - callback(filePath); - window.handleFilePathSelected = function() {}; - }; - - chrome.send('packExtensionSelectFilePath', [selectType, operation]); + showFileDialog_: function(selectType, fileType, node) { + chrome.developerPrivate.choosePath(selectType, fileType, function(path) { + // Last error is set if the user canceled the dialog. + if (!chrome.runtime.lastError && path) + node.value = path; + }); }, /** @@ -74,9 +74,10 @@ * @private */ handleBrowseExtensionDir_: function(e) { - this.showFileDialog_('folder', 'load', function(filePath) { - $('extension-root-dir').value = filePath; - }); + this.showFileDialog_( + 'FOLDER', + 'LOAD', + /** @type {HTMLInputElement} */ ($('extension-root-dir'))); }, /** @@ -85,44 +86,78 @@ * @private */ handleBrowsePrivateKey_: function(e) { - this.showFileDialog_('file', 'pem', function(filePath) { - $('extension-private-key').value = filePath; - }); + this.showFileDialog_( + 'FILE', + 'PEM', + /** @type {HTMLInputElement} */ ($('extension-private-key'))); }, - }; - /** - * Wrap up the pack process by showing the success |message| and closing - * the overlay. - * @param {string} message The message to show to the user. - */ - PackExtensionOverlay.showSuccessMessage = function(message) { - alertOverlay.setValues( - loadTimeData.getString('packExtensionOverlay'), - message, - loadTimeData.getString('ok'), - '', - function() { - extensions.ExtensionSettings.showOverlay(null); - }); - extensions.ExtensionSettings.showOverlay($('alertOverlay')); - }; + /** + * Handles a response from a packDirectory call. + * @param {PackDirectoryResponse} response The response of the pack call. + * @private + */ + onPackResponse_: function(response) { + /** @type {string} */ + var alertTitle; + /** @type {string} */ + var alertOk; + /** @type {string} */ + var alertCancel; + /** @type {function()} */ + var alertOkCallback; + /** @type {function()} */ + var alertCancelCallback; - /** - * Post an alert overlay showing |message|, and upon acknowledgement, close - * the alert overlay and return to showing the PackExtensionOverlay. - * @param {string} message The error message. - */ - PackExtensionOverlay.showError = function(message) { - alertOverlay.setValues( - loadTimeData.getString('packExtensionErrorTitle'), - message, - loadTimeData.getString('ok'), - '', - function() { - extensions.ExtensionSettings.showOverlay($('pack-extension-overlay')); - }); - extensions.ExtensionSettings.showOverlay($('alertOverlay')); + var closeAlert = function() { + extensions.ExtensionSettings.showOverlay(null); + }; + + // TODO(devlin): Once we expose enums on extension APIs, we should use + // those objects, instead of a string. + switch (response.status) { + case 'SUCCESS': + alertTitle = loadTimeData.getString('packExtensionOverlay'); + alertOk = loadTimeData.getString('ok'); + alertOkCallback = closeAlert; + // No 'Cancel' option. + break; + case 'WARNING': + alertTitle = loadTimeData.getString('packExtensionWarningTitle'); + alertOk = loadTimeData.getString('packExtensionProceedAnyway'); + alertCancel = loadTimeData.getString('cancel'); + alertOkCallback = function() { + chrome.developerPrivate.packDirectory( + response.item_path, + response.pem_path, + response.override_flags, + this.onPackResponse_.bind(this)); + closeAlert(); + }.bind(this); + alertCancelCallback = closeAlert; + break; + case 'ERROR': + alertTitle = loadTimeData.getString('packExtensionErrorTitle'); + alertOk = loadTimeData.getString('ok'); + alertOkCallback = function() { + extensions.ExtensionSettings.showOverlay( + $('pack-extension-overlay')); + }; + // No 'Cancel' option. + break; + default: + assertNotReached(); + return; + } + + alertOverlay.setValues(alertTitle, + response.message, + alertOk, + alertCancel, + alertOkCallback, + alertCancelCallback); + extensions.ExtensionSettings.showOverlay($('alertOverlay')); + }, }; // Export
diff --git a/chrome/browser/resources/md_settings/md_settings.html b/chrome/browser/resources/md_settings/md_settings.html index c3b5842..7e33367 100644 --- a/chrome/browser/resources/md_settings/md_settings.html +++ b/chrome/browser/resources/md_settings/md_settings.html
@@ -8,6 +8,7 @@ <link rel="import" href="chrome://resources/polymer/core-menu/core-menu.html"> <link rel="import" href="chrome://resources/cr_elements/cr_checkbox/cr_checkbox.html"> <link rel="import" href="chrome://resources/cr_elements/cr_collapse/cr_collapse.html"> + <link rel="import" href="chrome://resources/cr_elements/cr_input/cr_input.html"> <link rel="import" href="chrome://resources/cr_elements/cr_toggle_button/cr_toggle_button.html"> <link rel="import" href="chrome://resources/cr_elements/cr_button/cr_button.html"> <link rel="import" href="chrome://resources/cr_elements/cr_dropdown_menu/cr_dropdown_menu.html"> @@ -39,7 +40,7 @@ </cr-dropdown-menu> </section> <section> - <h2>cr-collapse</h2> + <h3>cr-collapse</h3> <paper-button id="manage-button" raised onclick="toggleCollapse();"> Toggle Collapse </paper-button> @@ -52,6 +53,10 @@ <cr-button>Flat button</cr-button> <cr-button raised>Raised Button</cr-button> </section> + <section> + <h3>cr-input</h3> + <cr-input label="Enter Something!"></cr-input> + </section> </div> <script> var collapse = document.getElementById('collapse');
diff --git a/chrome/browser/resources/options/browser_options.html b/chrome/browser/resources/options/browser_options.html index 7c800e5e..ccf90c0 100644 --- a/chrome/browser/resources/options/browser_options.html +++ b/chrome/browser/resources/options/browser_options.html
@@ -306,11 +306,6 @@ </div> </div> <div class="checkbox settings-row"> - <label> - <input id="use-24hour-clock" pref="settings.clock.use_24hour_clock" - metric="Options_Use24HourClockCheckbox" type="checkbox"> - <span i18n-content="use24HourClock"></span> - </label> <div id="resolve-timezone-by-geolocation-selection" hidden> <label> <input id="resolve-timezone-by-geolocation" @@ -319,9 +314,12 @@ <span i18n-content="resolveTimezoneByGeoLocation"></span> </label> </div> + <label> + <input id="use-24hour-clock" pref="settings.clock.use_24hour_clock" + metric="Options_Use24HourClockCheckbox" type="checkbox"> + <span i18n-content="use24HourClock"></span> + </label> </div> - <div id="time-synced-explanation" class="settings-row" - i18n-content="timeSyncedExplanation"></div> <div id="set-time" class="settings-row" hidden> <button id="set-time-button" i18n-content="setTimeButton"></button>
diff --git a/chrome/browser/resources/options/browser_options.js b/chrome/browser/resources/options/browser_options.js index 3efebf9f..8ba30db 100644 --- a/chrome/browser/resources/options/browser_options.js +++ b/chrome/browser/resources/options/browser_options.js
@@ -407,6 +407,8 @@ if (loadTimeData.getBoolean('enableTimeZoneTrackingOption')) { $('resolve-timezone-by-geolocation-selection').hidden = false; this.setSystemTimezoneManaged_(false); + $('timezone-value-select').disabled = loadTimeData.getBoolean( + 'resolveTimezoneByGeolocationInitialValue'); } } @@ -2113,7 +2115,6 @@ */ setCanSetTime_: function(canSetTime) { // If the time has been network-synced, it cannot be set manually. - $('time-synced-explanation').hidden = canSetTime; $('set-time').hidden = !canSetTime; }, @@ -2192,6 +2193,7 @@ 'setMetricsReportingSettingVisibility', 'setProfilesInfo', 'setSpokenFeedbackCheckboxState', + 'setSystemTimezoneManaged', 'setThemesResetButtonEnabled', 'setVirtualKeyboardCheckboxState', 'setupPageZoomSelector',
diff --git a/chrome/browser/resources/security_warnings/images/1x/brokenssl_red.png b/chrome/browser/resources/security_warnings/images/1x/brokenssl_red.png index 433b026..ddaabb1 100644 --- a/chrome/browser/resources/security_warnings/images/1x/brokenssl_red.png +++ b/chrome/browser/resources/security_warnings/images/1x/brokenssl_red.png Binary files differ
diff --git a/chrome/browser/resources/security_warnings/interstitial_v2.css b/chrome/browser/resources/security_warnings/interstitial_v2.css index a847191..920b644 100644 --- a/chrome/browser/resources/security_warnings/interstitial_v2.css +++ b/chrome/browser/resources/security_warnings/interstitial_v2.css
@@ -31,9 +31,8 @@ cursor: pointer; float: right; font-size: .875em; - height: 36px; - margin: -6px 0 0; - padding: 8px 24px; + margin: 0; + padding: 10px 24px; transition: box-shadow 200ms cubic-bezier(0.4, 0, 0.2, 1); } @@ -51,13 +50,14 @@ } #debugging { + display: inline; overflow: auto; } .debugging-content { line-height: 1em; margin-bottom: 0; - margin-top: 0; + margin-top: 1em; } .debugging-title { @@ -77,8 +77,8 @@ background: inherit; border: 0; float: none; - margin: -6px 0 0; - padding: 0; + margin: 0; + padding: 10px 0; text-decoration: underline; } @@ -86,16 +86,17 @@ box-shadow: inherit; } -#error-code { - color: black; - font-size: .825em; - opacity: .35; +.error-code { + color: #777; + display: inline; + font-size: .86667em; + margin-top: 15px; + opacity: .5; text-transform: uppercase; } #error-debugging-info { font-size: 0.8em; - overflow: auto; } h1 { @@ -141,6 +142,10 @@ width: 100%; } +#main-message > p { + display: inline; +} + #malware-opt-in { font-size: .875em; margin-top: 39px; @@ -178,18 +183,16 @@ box-shadow: 0 2px 3px rgba(0, 0, 0, .5); } +.safe-browsing .error-code { + display: none; +} + .safe-browsing .icon { background-image: -webkit-image-set( url(images/1x/stop_sign.png) 1x, url(images/2x/stop_sign.png) 2x); } -.secondary-button { - -webkit-margin-end: 16px; - background: #d9d9d9; - color: #696969; -} - .small-link { color: #696969; font-size: .875em; @@ -239,7 +242,7 @@ content: ''; height: 4px; left: 2px; - opacity: 0.3; + opacity: 0; position: absolute; top: 3px; transform: rotate(-45deg); @@ -254,9 +257,17 @@ .interstitial-wrapper { padding: 0 10%; } + + #error-debugging-info { + overflow: auto; + } } @media (max-height: 600px) { + .error-code { + margin-top: 10px; + } + .interstitial-wrapper { margin-top: 13%; } @@ -358,6 +369,10 @@ width: 100%; } + .error-code { + margin-top: 0; + } + #details { box-sizing: border-box; height: auto;
diff --git a/chrome/browser/resources/security_warnings/interstitial_v2.html b/chrome/browser/resources/security_warnings/interstitial_v2.html index e285441..b06fe1f 100644 --- a/chrome/browser/resources/security_warnings/interstitial_v2.html +++ b/chrome/browser/resources/security_warnings/interstitial_v2.html
@@ -20,6 +20,10 @@ <div id="main-message"> <h1 i18n-content="heading"></h1> <p i18n-values=".innerHTML:primaryParagraph"></p> + <div id="debugging"> + <div id="error-code" class="error-code"></div> + <div id="error-debugging-info" class="hidden"></div> + </div> </div> <div id="malware-opt-in" class="hidden"> <div class="styled-checkbox"> @@ -39,10 +43,6 @@ <div id="details" class="hidden"> <p i18n-values=".innerHTML:explanationParagraph"></p> <p i18n-values=".innerHTML:finalParagraph" id="final-paragraph"></p> - <div id="debugging"> - <p id="error-code"></p> - <div id="error-debugging-info" class="hidden"></div> - </div> </div> </div> </body>
diff --git a/chrome/browser/resources/security_warnings/interstitial_v2_mobile.js b/chrome/browser/resources/security_warnings/interstitial_v2_mobile.js index af0a21d..c482d6f 100644 --- a/chrome/browser/resources/security_warnings/interstitial_v2_mobile.js +++ b/chrome/browser/resources/security_warnings/interstitial_v2_mobile.js
@@ -15,6 +15,7 @@ '(orientation: portrait), (max-width: 736px) and ' + '(max-height: 420px) and (orientation: landscape)'; var detailsHidden = helpOuterBox.classList.contains('hidden'); + var runnerContainer = document.querySelector('.runner-container'); // Check for change in nav status. if (mobileNav != window.matchMedia(mediaQuery).matches) { @@ -24,10 +25,16 @@ if (mobileNav) { mainContent.classList.toggle('hidden', !detailsHidden); helpOuterBox.classList.toggle('hidden', detailsHidden); + if (runnerContainer) { + runnerContainer.classList.toggle('hidden', !detailsHidden); + } } else if (!detailsHidden) { // Non mobile nav with visible details. mainContent.classList.remove('hidden'); helpOuterBox.classList.remove('hidden'); + if (runnerContainer) { + runnerContainer.classList.remove('hidden'); + } } } }
diff --git a/chrome/browser/ui/BUILD.gn b/chrome/browser/ui/BUILD.gn index 237b239bb..538f50a 100644 --- a/chrome/browser/ui/BUILD.gn +++ b/chrome/browser/ui/BUILD.gn
@@ -47,6 +47,7 @@ "//components/app_modal", "//components/auto_login_parser", "//components/dom_distiller/webui", + "//components/feedback/proto", "//components/history/core/browser:proto", "//components/invalidation", "//components/onc", @@ -134,7 +135,6 @@ "//chrome") deps += [ "//components/copresence", - "//components/feedback/proto", "//device/bluetooth", "//third_party/libusb", ] @@ -228,15 +228,28 @@ } if (is_mac) { if (mac_views_browser) { + sources += [ "views/apps/chrome_app_window_client_views_mac.mm" ] sources -= [ + "cocoa/apps/chrome_app_window_client_cocoa.mm", "cocoa/bookmarks/bookmark_drag_drop_cocoa.mm", "cocoa/browser_window_factory_cocoa.mm", "cocoa/tab_dialogs_cocoa.mm", ] + deps += [ "//extensions/components/native_app_window" ] } else { sources -= [ + "views/apps/chrome_native_app_window_views.cc", + "views/apps/chrome_native_app_window_views.h", + "views/apps/desktop_keyboard_capture.cc", + "views/apps/desktop_keyboard_capture.h", + "views/apps/keyboard_hook_handler.cc", + "views/apps/keyboard_hook_handler.h", "views/bookmarks/bookmark_drag_drop_views.cc", + "views/extensions/extension_keybinding_registry_views.cc", + "views/extensions/extension_keybinding_registry_views.h", "views/frame/browser_window_factory.cc", + "views/frame/taskbar_decorator.cc", + "views/frame/taskbar_decorator.h", "views/tab_dialogs_views.cc", ] } @@ -313,6 +326,7 @@ ] deps -= [ "//chrome/browser/ui/views", + "//components/feedback/proto", "//ui/events", ] sources += rebase_path(gypi_values.chrome_browser_ui_android_sources, @@ -345,7 +359,10 @@ if (is_win) { sources += rebase_path(gypi_values.chrome_browser_ui_win_sources, ".", "//chrome") - sources -= [ "views/frame/taskbar_decorator.cc" ] + sources -= [ + "views/apps/keyboard_hook_handler.cc", + "views/frame/taskbar_decorator.cc", + ] public_deps += [ "//ui/views", "//ui/views/controls/webview",
diff --git a/chrome/browser/ui/android/autofill/card_unmask_prompt_view_android.cc b/chrome/browser/ui/android/autofill/card_unmask_prompt_view_android.cc index efaa710..40a960e 100644 --- a/chrome/browser/ui/android/autofill/card_unmask_prompt_view_android.cc +++ b/chrome/browser/ui/android/autofill/card_unmask_prompt_view_android.cc
@@ -88,9 +88,13 @@ Java_CardUnmaskBridge_disableAndWaitForVerification(env, java_object_.obj()); } -void CardUnmaskPromptViewAndroid::GotVerificationResult(bool success) { +void CardUnmaskPromptViewAndroid::GotVerificationResult( + const base::string16& error_message, + bool allow_retry) { JNIEnv* env = base::android::AttachCurrentThread(); - Java_CardUnmaskBridge_verificationFinished(env, java_object_.obj(), success); + // TODO(estade): pass |error_message| and |allow_retry|. + Java_CardUnmaskBridge_verificationFinished(env, java_object_.obj(), + error_message.empty()); } // static
diff --git a/chrome/browser/ui/android/autofill/card_unmask_prompt_view_android.h b/chrome/browser/ui/android/autofill/card_unmask_prompt_view_android.h index 21281f8..66d3e2d 100644 --- a/chrome/browser/ui/android/autofill/card_unmask_prompt_view_android.h +++ b/chrome/browser/ui/android/autofill/card_unmask_prompt_view_android.h
@@ -32,7 +32,8 @@ // CardUnmaskPromptView implementation. void ControllerGone() override; void DisableAndWaitForVerification() override; - void GotVerificationResult(bool success) override; + void GotVerificationResult(const base::string16& error_message, + bool allow_retry) override; static bool Register(JNIEnv* env);
diff --git a/chrome/browser/ui/ash/launcher/app_window_launcher_controller.cc b/chrome/browser/ui/ash/launcher/app_window_launcher_controller.cc index f07f122..ac0ae5f 100644 --- a/chrome/browser/ui/ash/launcher/app_window_launcher_controller.cc +++ b/chrome/browser/ui/ash/launcher/app_window_launcher_controller.cc
@@ -145,6 +145,11 @@ } void AppWindowLauncherController::RegisterApp(AppWindow* app_window) { + // Windows created by IME extension should be treated the same way as the + // virtual keyboard window, which does not register itself in launcher. + if (app_window->is_ime_window()) + return; + aura::Window* window = app_window->GetNativeWindow(); // Get the app's shelf identifier and add an entry to the map. DCHECK(window_to_app_shelf_id_map_.find(window) ==
diff --git a/chrome/browser/ui/ash/multi_user/multi_user_notification_blocker_chromeos_unittest.cc b/chrome/browser/ui/ash/multi_user/multi_user_notification_blocker_chromeos_unittest.cc index 28bed7c..7373454 100644 --- a/chrome/browser/ui/ash/multi_user/multi_user_notification_blocker_chromeos_unittest.cc +++ b/chrome/browser/ui/ash/multi_user/multi_user_notification_blocker_chromeos_unittest.cc
@@ -8,10 +8,12 @@ #include "ash/test/ash_test_base.h" #include "ash/test/test_session_state_delegate.h" #include "ash/test/test_shell_delegate.h" +#include "chrome/browser/chromeos/login/users/scoped_user_manager_enabler.h" #include "chrome/browser/ui/ash/multi_user/multi_user_notification_blocker_chromeos.h" #include "chrome/browser/ui/ash/multi_user/multi_user_window_manager_chromeos.h" #include "chrome/test/base/testing_browser_process.h" #include "chrome/test/base/testing_profile_manager.h" +#include "components/user_manager/fake_user_manager.h" #include "components/user_manager/user_info.h" #include "ui/message_center/message_center.h" #include "ui/message_center/notification.h" @@ -23,7 +25,9 @@ MultiUserNotificationBlockerChromeOSTest() : state_changed_count_(0), testing_profile_manager_(TestingBrowserProcess::GetGlobal()), - window_id_(0) {} + window_id_(0), + fake_user_manager_(new user_manager::FakeUserManager), + user_manager_enabler_(fake_user_manager_) {} ~MultiUserNotificationBlockerChromeOSTest() override {} // ash::test::AshTestBase overrides: @@ -128,6 +132,10 @@ TestingProfileManager testing_profile_manager_; int window_id_; + user_manager::FakeUserManager* fake_user_manager_; // Not owned. + + chromeos::ScopedUserManagerEnabler user_manager_enabler_; + DISALLOW_COPY_AND_ASSIGN(MultiUserNotificationBlockerChromeOSTest); };
diff --git a/chrome/browser/ui/ash/multi_user/multi_user_window_manager_chromeos_unittest.cc b/chrome/browser/ui/ash/multi_user/multi_user_window_manager_chromeos_unittest.cc index badf4a53..e6834781b 100644 --- a/chrome/browser/ui/ash/multi_user/multi_user_window_manager_chromeos_unittest.cc +++ b/chrome/browser/ui/ash/multi_user/multi_user_window_manager_chromeos_unittest.cc
@@ -18,10 +18,12 @@ #include "base/logging.h" #include "base/strings/string_util.h" #include "base/time/time.h" +#include "chrome/browser/chromeos/login/users/scoped_user_manager_enabler.h" #include "chrome/browser/ui/ash/multi_user/multi_user_window_manager.h" #include "chrome/browser/ui/ash/multi_user/multi_user_window_manager_chromeos.h" #include "chrome/browser/ui/ash/multi_user/user_switch_animator_chromeos.h" #include "chrome/test/base/testing_profile.h" +#include "components/user_manager/fake_user_manager.h" #include "components/user_manager/user_info.h" #include "ui/aura/client/aura_constants.h" #include "ui/aura/window_event_dispatcher.h" @@ -39,7 +41,9 @@ public: MultiUserWindowManagerChromeOSTest() : multi_user_window_manager_(NULL), - session_state_delegate_(NULL) {} + session_state_delegate_(NULL), + fake_user_manager_(new user_manager::FakeUserManager), + user_manager_enabler_(fake_user_manager_) {} void SetUp() override; void TearDown() override; @@ -158,6 +162,10 @@ // The session state delegate. ash::test::TestSessionStateDelegate* session_state_delegate_; + user_manager::FakeUserManager* fake_user_manager_; // Not owned. + + chromeos::ScopedUserManagerEnabler user_manager_enabler_; + // The maximized window manager (if enabled). scoped_ptr<MaximizeModeWindowManager> maximize_mode_window_manager_;
diff --git a/chrome/browser/ui/autofill/card_unmask_prompt_controller_impl.cc b/chrome/browser/ui/autofill/card_unmask_prompt_controller_impl.cc index 62b044a0..9b5335cc 100644 --- a/chrome/browser/ui/autofill/card_unmask_prompt_controller_impl.cc +++ b/chrome/browser/ui/autofill/card_unmask_prompt_controller_impl.cc
@@ -44,9 +44,39 @@ card_unmask_view_ = CardUnmaskPromptView::CreateAndShow(this); } -void CardUnmaskPromptControllerImpl::OnVerificationResult(bool success) { - if (card_unmask_view_) - card_unmask_view_->GotVerificationResult(success); +void CardUnmaskPromptControllerImpl::OnVerificationResult( + AutofillClient::GetRealPanResult result) { + if (!card_unmask_view_) + return; + + base::string16 error_message; + bool allow_retry = true; + switch (result) { + case AutofillClient::SUCCESS: + break; + + case AutofillClient::TRY_AGAIN_FAILURE: { + error_message = l10n_util::GetStringUTF16( + IDS_AUTOFILL_CARD_UNMASK_PROMPT_ERROR_TRY_AGAIN); + break; + } + + case AutofillClient::PERMANENT_FAILURE: { + error_message = l10n_util::GetStringUTF16( + IDS_AUTOFILL_CARD_UNMASK_PROMPT_ERROR_PERMANENT); + allow_retry = false; + break; + } + + case AutofillClient::NETWORK_ERROR: { + error_message = l10n_util::GetStringUTF16( + IDS_AUTOFILL_CARD_UNMASK_PROMPT_ERROR_NETWORK); + allow_retry = false; + break; + } + } + + card_unmask_view_->GotVerificationResult(error_message, allow_retry); } void CardUnmaskPromptControllerImpl::OnUnmaskDialogClosed() {
diff --git a/chrome/browser/ui/autofill/card_unmask_prompt_controller_impl.h b/chrome/browser/ui/autofill/card_unmask_prompt_controller_impl.h index e2d1b975..a991c7d73 100644 --- a/chrome/browser/ui/autofill/card_unmask_prompt_controller_impl.h +++ b/chrome/browser/ui/autofill/card_unmask_prompt_controller_impl.h
@@ -8,6 +8,7 @@ #include "base/memory/scoped_ptr.h" #include "base/memory/weak_ptr.h" #include "chrome/browser/ui/autofill/card_unmask_prompt_controller.h" +#include "components/autofill/core/browser/autofill_client.h" #include "components/autofill/core/browser/card_unmask_delegate.h" #include "components/autofill/core/browser/credit_card.h" @@ -24,7 +25,7 @@ void ShowPrompt(const CreditCard& card, base::WeakPtr<CardUnmaskDelegate> delegate); // The CVC the user entered went through validation. - void OnVerificationResult(bool success); + void OnVerificationResult(AutofillClient::GetRealPanResult result); // CardUnmaskPromptController implementation. void OnUnmaskDialogClosed() override;
diff --git a/chrome/browser/ui/autofill/card_unmask_prompt_view.h b/chrome/browser/ui/autofill/card_unmask_prompt_view.h index de3a2ff..6754856f 100644 --- a/chrome/browser/ui/autofill/card_unmask_prompt_view.h +++ b/chrome/browser/ui/autofill/card_unmask_prompt_view.h
@@ -19,7 +19,8 @@ virtual void ControllerGone() = 0; virtual void DisableAndWaitForVerification() = 0; - virtual void GotVerificationResult(bool success) = 0; + virtual void GotVerificationResult(const base::string16& error_message, + bool allow_retry) = 0; protected: CardUnmaskPromptView() {}
diff --git a/chrome/browser/ui/autofill/chrome_autofill_client.cc b/chrome/browser/ui/autofill/chrome_autofill_client.cc index 37c8c48..23983d92 100644 --- a/chrome/browser/ui/autofill/chrome_autofill_client.cc +++ b/chrome/browser/ui/autofill/chrome_autofill_client.cc
@@ -136,8 +136,8 @@ unmask_controller_.ShowPrompt(card, delegate); } -void ChromeAutofillClient::OnUnmaskVerificationResult(bool success) { - unmask_controller_.OnVerificationResult(success); +void ChromeAutofillClient::OnUnmaskVerificationResult(GetRealPanResult result) { + unmask_controller_.OnVerificationResult(result); } void ChromeAutofillClient::ConfirmSaveCreditCard(
diff --git a/chrome/browser/ui/autofill/chrome_autofill_client.h b/chrome/browser/ui/autofill/chrome_autofill_client.h index 3bc63aa4..1ce82b7 100644 --- a/chrome/browser/ui/autofill/chrome_autofill_client.h +++ b/chrome/browser/ui/autofill/chrome_autofill_client.h
@@ -51,7 +51,7 @@ void ShowAutofillSettings() override; void ShowUnmaskPrompt(const CreditCard& card, base::WeakPtr<CardUnmaskDelegate> delegate) override; - void OnUnmaskVerificationResult(bool success) override; + void OnUnmaskVerificationResult(GetRealPanResult result) override; void ConfirmSaveCreditCard(const base::Closure& save_card_callback) override; bool HasCreditCardScanFeature() override; void ScanCreditCard(const CreditCardScanCallback& callback) override;
diff --git a/chrome/browser/ui/browser.cc b/chrome/browser/ui/browser.cc index 53dfccd..1dc929de 100644 --- a/chrome/browser/ui/browser.cc +++ b/chrome/browser/ui/browser.cc
@@ -1339,8 +1339,7 @@ return; // GetDownloadShelf creates the download shelf if it was not yet created. - DownloadShelf* shelf = window()->GetDownloadShelf(); - shelf->AddDownload(download); + window()->GetDownloadShelf()->AddDownload(download); } ///////////////////////////////////////////////////////////////////////////////
diff --git a/chrome/browser/ui/cocoa/autofill/card_unmask_prompt_view_bridge.h b/chrome/browser/ui/cocoa/autofill/card_unmask_prompt_view_bridge.h index 02ff9cf..88d1e630 100644 --- a/chrome/browser/ui/cocoa/autofill/card_unmask_prompt_view_bridge.h +++ b/chrome/browser/ui/cocoa/autofill/card_unmask_prompt_view_bridge.h
@@ -27,7 +27,8 @@ // CardUnmaskPromptView implementation: void ControllerGone() override; void DisableAndWaitForVerification() override; - void GotVerificationResult(bool success) override; + void GotVerificationResult(const base::string16& error_message, + bool allow_retry) override; // ConstrainedWindowMacDelegate implementation: void OnConstrainedWindowClosed(ConstrainedWindowMac* window) override;
diff --git a/chrome/browser/ui/cocoa/autofill/card_unmask_prompt_view_bridge.mm b/chrome/browser/ui/cocoa/autofill/card_unmask_prompt_view_bridge.mm index cc8897d4..5d30a79 100644 --- a/chrome/browser/ui/cocoa/autofill/card_unmask_prompt_view_bridge.mm +++ b/chrome/browser/ui/cocoa/autofill/card_unmask_prompt_view_bridge.mm
@@ -49,7 +49,9 @@ void CardUnmaskPromptViewBridge::DisableAndWaitForVerification() { } -void CardUnmaskPromptViewBridge::GotVerificationResult(bool success) { +void CardUnmaskPromptViewBridge::GotVerificationResult( + const base::string16& error_message, + bool allow_retry) { } void CardUnmaskPromptViewBridge::OnConstrainedWindowClosed(
diff --git a/chrome/browser/ui/cocoa/certificate_viewer_mac.mm b/chrome/browser/ui/cocoa/certificate_viewer_mac.mm index 02995b5..e5f6a9a 100644 --- a/chrome/browser/ui/cocoa/certificate_viewer_mac.mm +++ b/chrome/browser/ui/cocoa/certificate_viewer_mac.mm
@@ -197,6 +197,10 @@ // NOOP } +- (NSWindow*)sheetWindow { + return panel_; +} + - (void)onConstrainedWindowClosed { panel_.reset(); constrainedWindow_.reset();
diff --git a/chrome/browser/ui/cocoa/constrained_web_dialog_delegate_mac.mm b/chrome/browser/ui/cocoa/constrained_web_dialog_delegate_mac.mm index d515508..2b5c1407 100644 --- a/chrome/browser/ui/cocoa/constrained_web_dialog_delegate_mac.mm +++ b/chrome/browser/ui/cocoa/constrained_web_dialog_delegate_mac.mm
@@ -72,9 +72,7 @@ void ReleaseWebContentsOnDialogClose() override { return impl_->ReleaseWebContentsOnDialogClose(); } - NativeWebContentsModalDialog GetNativeDialog() override { - return constrained_window_->GetNativeDialog(); - } + NativeWebContentsModalDialog GetNativeDialog() override { return window_; } WebContents* GetWebContents() override { return impl_->GetWebContents(); } gfx::Size GetMinimumSize() const override { NOTIMPLEMENTED();
diff --git a/chrome/browser/ui/cocoa/constrained_window/constrained_window_custom_sheet.mm b/chrome/browser/ui/cocoa/constrained_window/constrained_window_custom_sheet.mm index 4300036..d6d12c9 100644 --- a/chrome/browser/ui/cocoa/constrained_window/constrained_window_custom_sheet.mm +++ b/chrome/browser/ui/cocoa/constrained_window/constrained_window_custom_sheet.mm
@@ -73,4 +73,8 @@ [customWindow_ setFrameOrigin:origin]; } +- (NSWindow*)sheetWindow { + return customWindow_; +} + @end
diff --git a/chrome/browser/ui/cocoa/constrained_window/constrained_window_mac.h b/chrome/browser/ui/cocoa/constrained_window/constrained_window_mac.h index 6f3f222..e3d981e 100644 --- a/chrome/browser/ui/cocoa/constrained_window/constrained_window_mac.h +++ b/chrome/browser/ui/cocoa/constrained_window/constrained_window_mac.h
@@ -7,13 +7,11 @@ #import <Cocoa/Cocoa.h> -#include "base/mac/scoped_nsobject.h" -#include "components/web_modal/native_web_contents_modal_dialog.h" - namespace content { class WebContents; } class ConstrainedWindowMac; +class SingleWebContentsDialogManagerCocoa; @protocol ConstrainedWindowSheet; // A delegate for a constrained window. The delegate is notified when the @@ -28,29 +26,25 @@ // should delete the instance when the window is closed. class ConstrainedWindowMac { public: - ConstrainedWindowMac( - ConstrainedWindowMacDelegate* delegate, - content::WebContents* web_contents, - id<ConstrainedWindowSheet> sheet); - virtual ~ConstrainedWindowMac(); + ConstrainedWindowMac(ConstrainedWindowMacDelegate* delegate, + content::WebContents* web_contents, + id<ConstrainedWindowSheet> sheet); + ~ConstrainedWindowMac(); - void ShowWebContentsModalDialog(); - // Closes the constrained window and deletes this instance. + // Closes the constrained window. void CloseWebContentsModalDialog(); - void FocusWebContentsModalDialog(); - void PulseWebContentsModalDialog(); - web_modal::NativeWebContentsModalDialog GetNativeDialog(); + + SingleWebContentsDialogManagerCocoa* manager() const { return manager_; } + void set_manager(SingleWebContentsDialogManagerCocoa* manager) { + manager_ = manager; + } + + // Called by |manager_| when the dialog is closing. + void OnDialogClosing(); private: ConstrainedWindowMacDelegate* delegate_; // weak, owns us. - - // The WebContents that owns and constrains this ConstrainedWindowMac. Weak. - content::WebContents* web_contents_; - - base::scoped_nsprotocol<id<ConstrainedWindowSheet>> sheet_; - - // This is true if the constrained window has been shown. - bool shown_; + SingleWebContentsDialogManagerCocoa* manager_; // weak, owned by WCMDM. }; #endif // CHROME_BROWSER_UI_COCOA_CONSTRAINED_WINDOW_CONSTRAINED_WINDOW_MAC_
diff --git a/chrome/browser/ui/cocoa/constrained_window/constrained_window_mac.mm b/chrome/browser/ui/cocoa/constrained_window/constrained_window_mac.mm index 3c9dc59..1da08e0 100644 --- a/chrome/browser/ui/cocoa/constrained_window/constrained_window_mac.mm +++ b/chrome/browser/ui/cocoa/constrained_window/constrained_window_mac.mm
@@ -4,89 +4,46 @@ #include "chrome/browser/ui/cocoa/constrained_window/constrained_window_mac.h" +#include "base/memory/scoped_ptr.h" #include "base/logging.h" -#include "chrome/browser/ui/browser_finder.h" -#include "chrome/browser/ui/browser_window.h" #import "chrome/browser/ui/cocoa/constrained_window/constrained_window_sheet.h" -#import "chrome/browser/ui/cocoa/constrained_window/constrained_window_sheet_controller.h" -#import "chrome/browser/ui/cocoa/tabs/tab_strip_controller.h" -#include "components/web_modal/popup_manager.h" +#import "chrome/browser/ui/cocoa/single_web_contents_dialog_manager_cocoa.h" #include "components/web_modal/web_contents_modal_dialog_manager.h" #include "content/public/browser/browser_thread.h" -#include "content/public/browser/web_contents.h" #include "extensions/browser/guest_view/guest_view_base.h" using web_modal::WebContentsModalDialogManager; -using web_modal::NativeWebContentsModalDialog; ConstrainedWindowMac::ConstrainedWindowMac( ConstrainedWindowMacDelegate* delegate, content::WebContents* web_contents, id<ConstrainedWindowSheet> sheet) - : delegate_(delegate), - web_contents_(NULL), - sheet_([sheet retain]), - shown_(false) { - DCHECK(web_contents); + : delegate_(delegate) { + DCHECK(sheet); extensions::GuestViewBase* guest_view = extensions::GuestViewBase::FromWebContents(web_contents); // For embedded WebContents, use the embedder's WebContents for constrained // window. - web_contents_ = guest_view && guest_view->embedder_web_contents() ? - guest_view->embedder_web_contents() : web_contents; - DCHECK(sheet_.get()); - web_modal::PopupManager* popup_manager = - web_modal::PopupManager::FromWebContents(web_contents_); - if (popup_manager) - popup_manager->ShowModalDialog(this, web_contents_); + web_contents = guest_view && guest_view->embedder_web_contents() ? + guest_view->embedder_web_contents() : web_contents; + + auto manager = WebContentsModalDialogManager::FromWebContents(web_contents); + scoped_ptr<SingleWebContentsDialogManagerCocoa> native_manager( + new SingleWebContentsDialogManagerCocoa(this, sheet, manager)); + manager->ShowDialogWithManager([sheet sheetWindow], native_manager.Pass()); } ConstrainedWindowMac::~ConstrainedWindowMac() { CHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI)); -} - -void ConstrainedWindowMac::ShowWebContentsModalDialog() { - if (shown_) - return; - - NSWindow* parent_window = web_contents_->GetTopLevelNativeWindow(); - NSView* parent_view = GetSheetParentViewForWebContents(web_contents_); - if (!parent_window || !parent_view) - return; - - shown_ = true; - ConstrainedWindowSheetController* controller = - [ConstrainedWindowSheetController - controllerForParentWindow:parent_window]; - [controller showSheet:sheet_ forParentView:parent_view]; + DCHECK(!manager_); } void ConstrainedWindowMac::CloseWebContentsModalDialog() { - [[ConstrainedWindowSheetController controllerForSheet:sheet_] - closeSheet:sheet_]; - // TODO(gbillock): get this object in config, not from a global. - WebContentsModalDialogManager* web_contents_modal_dialog_manager = - WebContentsModalDialogManager::FromWebContents(web_contents_); + if (manager_) + manager_->Close(); +} - // Will result in the delegate being deleted. +void ConstrainedWindowMac::OnDialogClosing() { if (delegate_) delegate_->OnConstrainedWindowClosed(this); - - // Will cause this object to be deleted. - web_contents_modal_dialog_manager->WillClose(this); -} - -void ConstrainedWindowMac::FocusWebContentsModalDialog() { -} - -void ConstrainedWindowMac::PulseWebContentsModalDialog() { - [[ConstrainedWindowSheetController controllerForSheet:sheet_] - pulseSheet:sheet_]; -} - -NativeWebContentsModalDialog ConstrainedWindowMac::GetNativeDialog() { - // TODO(wittman): Ultimately this should be changed to the - // ConstrainedWindowSheet pointer, in conjunction with the corresponding - // changes to NativeWebContentsModalDialogManagerCocoa. - return this; }
diff --git a/chrome/browser/ui/cocoa/constrained_window/constrained_window_sheet.h b/chrome/browser/ui/cocoa/constrained_window/constrained_window_sheet.h index 2352af0..4549556 100644 --- a/chrome/browser/ui/cocoa/constrained_window/constrained_window_sheet.h +++ b/chrome/browser/ui/cocoa/constrained_window/constrained_window_sheet.h
@@ -24,6 +24,8 @@ - (void)updateSheetPosition; +@property(readonly, nonatomic) NSWindow* sheetWindow; + @end #endif // CHROME_BROWSER_UI_COCOA_CONSTRAINED_WINDOW_CONSTRAINED_WINDOW_SHEET_H_
diff --git a/chrome/browser/ui/cocoa/constrained_window/constrained_window_sheet_controller_unittest.mm b/chrome/browser/ui/cocoa/constrained_window/constrained_window_sheet_controller_unittest.mm index e8939b8e..aeeeb92 100644 --- a/chrome/browser/ui/cocoa/constrained_window/constrained_window_sheet_controller_unittest.mm +++ b/chrome/browser/ui/cocoa/constrained_window/constrained_window_sheet_controller_unittest.mm
@@ -56,6 +56,10 @@ - (void)updateSheetPosition { } +- (NSWindow*)sheetWindow { + return [alert_ window]; +} + - (void)alertDidEnd:(NSAlert *)alert returnCode:(NSInteger)returnCode ctxInfo:(void *)contextInfo {
diff --git a/chrome/browser/ui/cocoa/download/download_item_mac.mm b/chrome/browser/ui/cocoa/download/download_item_mac.mm index bf1ebc9..b39137c 100644 --- a/chrome/browser/ui/cocoa/download/download_item_mac.mm +++ b/chrome/browser/ui/cocoa/download/download_item_mac.mm
@@ -30,6 +30,11 @@ void DownloadItemMac::OnDownloadUpdated(content::DownloadItem* download) { DCHECK_EQ(download, download_model_.download()); + if (!download_model_.ShouldShowInShelf()) { + [item_controller_ remove]; // We're deleted now! + return; + } + if ([item_controller_ isDangerousMode] && !download_model_.IsDangerous()) { // We have been approved. [item_controller_ clearDangerousMode];
diff --git a/chrome/browser/ui/cocoa/profiles/avatar_base_controller.mm b/chrome/browser/ui/cocoa/profiles/avatar_base_controller.mm index 12ee052..4c5aac73 100644 --- a/chrome/browser/ui/cocoa/profiles/avatar_base_controller.mm +++ b/chrome/browser/ui/cocoa/profiles/avatar_base_controller.mm
@@ -178,7 +178,7 @@ NSMaxX([anchor bounds]) - kMenuXOffsetAdjust : NSMidX([anchor bounds]); NSPoint point = NSMakePoint(anchorX, - NSMaxY([anchor bounds]) - kMenuYOffsetAdjust); + NSMaxY([anchor bounds]) + kMenuYOffsetAdjust); point = [anchor convertPoint:point toView:nil]; point = [[anchor window] convertBaseToScreen:point];
diff --git a/chrome/browser/ui/cocoa/profiles/avatar_menu_bubble_controller.mm b/chrome/browser/ui/cocoa/profiles/avatar_menu_bubble_controller.mm index 588fdea..3d0f39d8 100644 --- a/chrome/browser/ui/cocoa/profiles/avatar_menu_bubble_controller.mm +++ b/chrome/browser/ui/cocoa/profiles/avatar_menu_bubble_controller.mm
@@ -5,6 +5,7 @@ #import "chrome/browser/ui/cocoa/profiles/avatar_menu_bubble_controller.h" #include "base/mac/bundle_locations.h" +#include "base/mac/sdk_forward_declarations.h" #include "base/strings/sys_string_conversions.h" #include "chrome/browser/browser_process.h" #include "chrome/browser/profiles/avatar_menu.h" @@ -159,6 +160,8 @@ NSRect frame = [nameField frame]; frame.size.width = kMaxItemTextWidth; [nameField setFrame:frame]; + if ([nameField respondsToSelector:@selector(setAllowsExpansionToolTips:)]) + [nameField setAllowsExpansionToolTips:YES]; } *widthAdjust = std::max(*widthAdjust, delta.width);
diff --git a/chrome/browser/ui/cocoa/profiles/profile_chooser_controller.mm b/chrome/browser/ui/cocoa/profiles/profile_chooser_controller.mm index 6844522..27dccbc 100644 --- a/chrome/browser/ui/cocoa/profiles/profile_chooser_controller.mm +++ b/chrome/browser/ui/cocoa/profiles/profile_chooser_controller.mm
@@ -701,6 +701,13 @@ IDS_PROFILES_NEW_AVATAR_MENU_EDIT_NAME_ACCESSIBLE_NAME, base::SysNSStringToUTF16(profileName)) forAttribute:NSAccessibilityTitleAttribute]; + + NSSize textSize = [profileName sizeWithAttributes:@{ + NSFontAttributeName : [profileNameTextField_ font] + }]; + + if (textSize.width > frameRect.size.width - [hoverImage size].width * 2) + [self setToolTip:profileName]; } [[self cell] accessibilitySetOverrideValue:NSAccessibilityButtonRole @@ -1805,6 +1812,16 @@ [profileButton setTarget:self]; [profileButton setAction:@selector(switchToProfile:)]; + NSSize textSize = [[profileButton title] sizeWithAttributes:@{ + NSFontAttributeName : [profileButton font] + }]; + + CGFloat availableWidth = rect.size.width - kSmallImageSide - + kImageTitleSpacing - kHorizontalSpacing; + + if (std::ceil(textSize.width) > availableWidth) + [profileButton setToolTip:[profileButton title]]; + return profileButton.autorelease(); }
diff --git a/chrome/browser/ui/cocoa/single_web_contents_dialog_manager_cocoa.h b/chrome/browser/ui/cocoa/single_web_contents_dialog_manager_cocoa.h new file mode 100644 index 0000000..55efe46 --- /dev/null +++ b/chrome/browser/ui/cocoa/single_web_contents_dialog_manager_cocoa.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 CHROME_BROWSER_UI_COCOA_SINGLE_WEB_CONTENTS_DIALOG_MANAGER_COCOA_H_ +#define CHROME_BROWSER_UI_COCOA_SINGLE_WEB_CONTENTS_DIALOG_MANAGER_COCOA_H_ + +#import "base/mac/scoped_nsobject.h" +#include "components/web_modal/single_web_contents_dialog_manager.h" + +class ConstrainedWindowMac; +@protocol ConstrainedWindowSheet; + +// Cocoa implementation of web_modal::SingleWebContentsDialogManager. +class SingleWebContentsDialogManagerCocoa + : public web_modal::SingleWebContentsDialogManager { + public: + SingleWebContentsDialogManagerCocoa( + ConstrainedWindowMac* client, + id<ConstrainedWindowSheet> sheet, + web_modal::SingleWebContentsDialogManagerDelegate* delegate); + ~SingleWebContentsDialogManagerCocoa() override; + + // SingleWebContentsDialogManager overrides. + void Show() override; + void Hide() override; + void Close() override; + void Focus() override; + void Pulse() override; + void HostChanged(web_modal::WebContentsModalDialogHost* new_host) override; + web_modal::NativeWebContentsModalDialog dialog() override; + + private: + ConstrainedWindowMac* client_; // Weak. Can be null. + base::scoped_nsprotocol<id<ConstrainedWindowSheet>> sheet_; + // Weak. Owns this. + web_modal::SingleWebContentsDialogManagerDelegate* delegate_; + bool shown_; + + DISALLOW_COPY_AND_ASSIGN(SingleWebContentsDialogManagerCocoa); +}; + +#endif // CHROME_BROWSER_UI_COCOA_SINGLE_WEB_CONTENTS_DIALOG_MANAGER_COCOA_H_
diff --git a/chrome/browser/ui/cocoa/single_web_contents_dialog_manager_cocoa.mm b/chrome/browser/ui/cocoa/single_web_contents_dialog_manager_cocoa.mm new file mode 100644 index 0000000..3bd76bd --- /dev/null +++ b/chrome/browser/ui/cocoa/single_web_contents_dialog_manager_cocoa.mm
@@ -0,0 +1,87 @@ +// 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 "chrome/browser/ui/cocoa/single_web_contents_dialog_manager_cocoa.h" + +#import "chrome/browser/ui/cocoa/constrained_window/constrained_window_custom_sheet.h" +#import "chrome/browser/ui/cocoa/constrained_window/constrained_window_mac.h" +#import "chrome/browser/ui/cocoa/constrained_window/constrained_window_sheet_controller.h" +#import "chrome/browser/ui/cocoa/tabs/tab_strip_controller.h" +#include "components/web_modal/web_contents_modal_dialog_manager.h" + +using web_modal::NativeWebContentsModalDialog; +using web_modal::SingleWebContentsDialogManagerDelegate; + +SingleWebContentsDialogManagerCocoa::SingleWebContentsDialogManagerCocoa( + ConstrainedWindowMac* client, + id<ConstrainedWindowSheet> sheet, + web_modal::SingleWebContentsDialogManagerDelegate* delegate) + : client_(client), + sheet_([sheet retain]), + delegate_(delegate), + shown_(false) { + if (client) + client->set_manager(this); +} + +SingleWebContentsDialogManagerCocoa::~SingleWebContentsDialogManagerCocoa() { +} + +void SingleWebContentsDialogManagerCocoa::Show() { + if (shown_) + return; + + content::WebContents* web_contents = delegate_->GetWebContents(); + NSWindow* parent_window = web_contents->GetTopLevelNativeWindow(); + NSView* parent_view = GetSheetParentViewForWebContents(web_contents); + if (!parent_window || !parent_view) + return; + + shown_ = true; + [[ConstrainedWindowSheetController controllerForParentWindow:parent_window] + showSheet:sheet_ forParentView:parent_view]; +} + +void SingleWebContentsDialogManagerCocoa::Hide() { +} + +void SingleWebContentsDialogManagerCocoa::Close() { + [[ConstrainedWindowSheetController controllerForSheet:sheet_] + closeSheet:sheet_]; + if (client_) { + client_->set_manager(nullptr); + client_->OnDialogClosing(); // |client_| might delete itself here. + client_ = nullptr; + } + delegate_->WillClose(dialog()); +} + +void SingleWebContentsDialogManagerCocoa::Focus() { +} + +void SingleWebContentsDialogManagerCocoa::Pulse() { + [[ConstrainedWindowSheetController controllerForSheet:sheet_] + pulseSheet:sheet_]; +} + +void SingleWebContentsDialogManagerCocoa::HostChanged( + web_modal::WebContentsModalDialogHost* new_host) { +} + +NativeWebContentsModalDialog SingleWebContentsDialogManagerCocoa::dialog() { + return [sheet_ sheetWindow]; +} + +namespace web_modal { + +SingleWebContentsDialogManager* +WebContentsModalDialogManager::CreateNativeWebModalManager( + NativeWebContentsModalDialog dialog, + SingleWebContentsDialogManagerDelegate* delegate) { + base::scoped_nsobject<CustomConstrainedWindowSheet> sheet( + [[CustomConstrainedWindowSheet alloc] initWithCustomWindow:dialog]); + return new SingleWebContentsDialogManagerCocoa(nullptr, sheet, delegate); +} + +} // namespace web_modal
diff --git a/chrome/browser/ui/cocoa/ssl_client_certificate_selector_cocoa.mm b/chrome/browser/ui/cocoa/ssl_client_certificate_selector_cocoa.mm index 9d471b9..a8d7912 100644 --- a/chrome/browser/ui/cocoa/ssl_client_certificate_selector_cocoa.mm +++ b/chrome/browser/ui/cocoa/ssl_client_certificate_selector_cocoa.mm
@@ -227,6 +227,10 @@ // NOOP } +- (NSWindow*)sheetWindow { + return panel_; +} + - (void)onConstrainedWindowClosed { observer_->StopObserving(); panel_.reset();
diff --git a/chrome/browser/ui/cocoa/status_bubble_mac.mm b/chrome/browser/ui/cocoa/status_bubble_mac.mm index 667d952..7273b0d 100644 --- a/chrome/browser/ui/cocoa/status_bubble_mac.mm +++ b/chrome/browser/ui/cocoa/status_bubble_mac.mm
@@ -177,16 +177,18 @@ url_ = url; languages_ = languages; - NSRect frame = [window_ frame]; + CGFloat bubble_width = NSWidth([window_ frame]); // Reset frame size when bubble is hidden. if (state_ == kBubbleHidden) { is_expanded_ = false; - frame.size.width = NSWidth(CalculateWindowFrame(/*expand=*/false)); + NSRect frame = [window_ frame]; + frame.size = ui::kWindowSizeDeterminedLater.size; [window_ setFrame:frame display:NO]; + bubble_width = NSWidth(CalculateWindowFrame(/*expand=*/false)); } - int text_width = static_cast<int>(NSWidth(frame) - + int text_width = static_cast<int>(bubble_width - kBubbleViewTextPositionX - kTextPadding); @@ -260,8 +262,10 @@ show = false; if (show) { - UpdateSizeAndPosition(); + // Call StartShowing() first to update the current bubble state before + // calculating a new size. StartShowing(); + UpdateSizeAndPosition(); } else { StartHiding(); } @@ -284,21 +288,22 @@ } } + NSRect frame = CalculateWindowFrame(/*expand=*/false); if (!fade_out) { // No animation is in progress, so the opacity can be set directly. [window_ setAlphaValue:0.0]; SetState(kBubbleHidden); + frame.size = ui::kWindowSizeDeterminedLater.size; } // Stop any width animation and reset the bubble size. if (!immediate_) { [NSAnimationContext beginGrouping]; [[NSAnimationContext currentContext] setDuration:kMinimumTimeInterval]; - [[window_ animator] setFrame:CalculateWindowFrame(/*expand=*/false) - display:NO]; + [[window_ animator] setFrame:frame display:NO]; [NSAnimationContext endGrouping]; } else { - [window_ setFrame:CalculateWindowFrame(/*expand=*/false) display:NO]; + [window_ setFrame:frame display:NO]; } [status_text_ release]; @@ -717,6 +722,14 @@ if (!window_) return; + // Hidden bubbles always have size equal to ui::kWindowSizeDeterminedLater. + if (state_ == kBubbleHidden) { + NSRect frame = [window_ frame]; + frame.size = ui::kWindowSizeDeterminedLater.size; + [window_ setFrame:frame display:YES]; + return; + } + SetFrameAvoidingMouse(CalculateWindowFrame(/*expand=*/false), GetMouseLocation()); }
diff --git a/chrome/browser/ui/cocoa/tab_modal_confirm_dialog_mac.h b/chrome/browser/ui/cocoa/tab_modal_confirm_dialog_mac.h index 48d2f40..19ff9d2a4 100644 --- a/chrome/browser/ui/cocoa/tab_modal_confirm_dialog_mac.h +++ b/chrome/browser/ui/cocoa/tab_modal_confirm_dialog_mac.h
@@ -7,6 +7,7 @@ #import <Cocoa/Cocoa.h> +#import "base/mac/scoped_nsobject.h" #include "base/memory/scoped_ptr.h" #include "chrome/browser/ui/cocoa/constrained_window/constrained_window_mac.h" #include "chrome/browser/ui/tab_modal_confirm_dialog.h"
diff --git a/chrome/browser/ui/cocoa/web_contents_modal_dialog_manager_cocoa.mm b/chrome/browser/ui/cocoa/web_contents_modal_dialog_manager_cocoa.mm deleted file mode 100644 index 5d025f6c..0000000 --- a/chrome/browser/ui/cocoa/web_contents_modal_dialog_manager_cocoa.mm +++ /dev/null
@@ -1,71 +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 "components/web_modal/web_contents_modal_dialog_manager.h" - -#include "chrome/browser/ui/cocoa/constrained_window/constrained_window_mac.h" -#include "components/web_modal/single_web_contents_dialog_manager.h" - -using web_modal::NativeWebContentsModalDialog; - -namespace { - -class NativeWebContentsModalDialogManagerCocoa - : public web_modal::SingleWebContentsDialogManager { - public: - NativeWebContentsModalDialogManagerCocoa( - NativeWebContentsModalDialog dialog) - : dialog_(dialog) { - } - - ~NativeWebContentsModalDialogManagerCocoa() override {} - - // SingleWebContentsDialogManager overrides - void Show() override { - GetConstrainedWindowMac(dialog())->ShowWebContentsModalDialog(); - } - - void Hide() override {} - - void Close() override { - GetConstrainedWindowMac(dialog())->CloseWebContentsModalDialog(); - } - - void Focus() override { - GetConstrainedWindowMac(dialog())->FocusWebContentsModalDialog(); - } - - void Pulse() override { - GetConstrainedWindowMac(dialog())->PulseWebContentsModalDialog(); - } - - void HostChanged(web_modal::WebContentsModalDialogHost* new_host) override {} - - NativeWebContentsModalDialog dialog() override { return dialog_; } - - private: - static ConstrainedWindowMac* GetConstrainedWindowMac( - NativeWebContentsModalDialog dialog) { - return static_cast<ConstrainedWindowMac*>(dialog); - } - - // In mac this is a pointer to a ConstrainedWindowMac. - // TODO(gbillock): Replace this casting system with a more typesafe call path. - NativeWebContentsModalDialog dialog_; - - DISALLOW_COPY_AND_ASSIGN(NativeWebContentsModalDialogManagerCocoa); -}; - -} // namespace - -namespace web_modal { - -SingleWebContentsDialogManager* - WebContentsModalDialogManager::CreateNativeWebModalManager( - NativeWebContentsModalDialog dialog, - SingleWebContentsDialogManagerDelegate* native_delegate) { - return new NativeWebContentsModalDialogManagerCocoa(dialog); -} - -} // namespace web_modal
diff --git a/chrome/browser/ui/content_settings/content_setting_bubble_model.cc b/chrome/browser/ui/content_settings/content_setting_bubble_model.cc index 0df4fa7..23c1275 100644 --- a/chrome/browser/ui/content_settings/content_setting_bubble_model.cc +++ b/chrome/browser/ui/content_settings/content_setting_bubble_model.cc
@@ -1199,6 +1199,7 @@ return; // Reset this embedder's entry to default for each of the requesting // origins currently on the page. + const GURL& embedder_url = web_contents()->GetURL(); TabSpecificContentSettings* content_settings = TabSpecificContentSettings::FromWebContents(web_contents()); const ContentSettingsUsagesState::StateMap& state_map = @@ -1210,7 +1211,7 @@ state_map.begin(); it != state_map.end(); ++it) { settings_map->SetContentSetting( ContentSettingsPattern::FromURLNoWildcard(it->first), - ContentSettingsPattern::Wildcard(), + ContentSettingsPattern::FromURLNoWildcard(embedder_url), CONTENT_SETTINGS_TYPE_MIDI_SYSEX, std::string(), CONTENT_SETTING_DEFAULT);
diff --git a/chrome/browser/ui/views/apps/chrome_apps_client_views.cc b/chrome/browser/ui/views/apps/chrome_app_window_client_views.cc similarity index 100% rename from chrome/browser/ui/views/apps/chrome_apps_client_views.cc rename to chrome/browser/ui/views/apps/chrome_app_window_client_views.cc
diff --git a/chrome/browser/ui/views/apps/chrome_app_window_client_views_mac.mm b/chrome/browser/ui/views/apps/chrome_app_window_client_views_mac.mm new file mode 100644 index 0000000..c87fc4f --- /dev/null +++ b/chrome/browser/ui/views/apps/chrome_app_window_client_views_mac.mm
@@ -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 "chrome/browser/ui/apps/chrome_app_window_client.h" + +#include "chrome/browser/ui/views/apps/chrome_native_app_window_views.h" + +// static +extensions::NativeAppWindow* ChromeAppWindowClient::CreateNativeAppWindowImpl( + extensions::AppWindow* app_window, + const extensions::AppWindow::CreateParams& params) { + ChromeNativeAppWindowViews* window = new ChromeNativeAppWindowViews; + window->Init(app_window, params); + return window; +}
diff --git a/chrome/browser/ui/views/apps/chrome_apps_client_views_win.cc b/chrome/browser/ui/views/apps/chrome_app_window_client_views_win.cc similarity index 100% rename from chrome/browser/ui/views/apps/chrome_apps_client_views_win.cc rename to chrome/browser/ui/views/apps/chrome_app_window_client_views_win.cc
diff --git a/chrome/browser/ui/views/autofill/card_unmask_prompt_views.cc b/chrome/browser/ui/views/autofill/card_unmask_prompt_views.cc index 83223c6..e5903371 100644 --- a/chrome/browser/ui/views/autofill/card_unmask_prompt_views.cc +++ b/chrome/browser/ui/views/autofill/card_unmask_prompt_views.cc
@@ -11,6 +11,9 @@ #include "chrome/browser/ui/views/autofill/decorated_textfield.h" #include "chrome/grit/generated_resources.h" #include "components/constrained_window/constrained_window_views.h" +#include "components/web_modal/web_contents_modal_dialog_host.h" +#include "components/web_modal/web_contents_modal_dialog_manager.h" +#include "components/web_modal/web_contents_modal_dialog_manager_delegate.h" #include "grit/theme_resources.h" #include "third_party/skia/include/core/SkColor.h" #include "ui/base/l10n/l10n_util.h" @@ -70,29 +73,48 @@ Layout(); } - void GotVerificationResult(bool success) override { - if (success) { + void GotVerificationResult(const base::string16& error_message, + bool allow_retry) override { + if (!error_message.empty()) { progress_label_->SetText(base::ASCIIToUTF16("Success!")); base::MessageLoop::current()->PostDelayedTask( FROM_HERE, base::Bind(&CardUnmaskPromptViews::ClosePrompt, base::Unretained(this)), base::TimeDelta::FromSeconds(1)); } else { - SetInputsEnabled(true); - SetInputsInvalid(true); + SetInputsEnabled(allow_retry); + + // If there is more than one input showing, don't mark anything as invalid + // since we don't know the location of the problem. + if (controller_->ShouldRequestExpirationDate()) + cvc_input_->SetInvalid(true); + // TODO(estade): it's somewhat jarring when the error comes back too // quickly. progress_overlay_->SetVisible(false); // TODO(estade): When do we hide |error_label_|? - error_label_->SetText( - base::ASCIIToUTF16("Verification error. Please try again.")); + error_label_->SetMultiLine(true); + error_label_->SetText(error_message); + + // Update the dialog's size, which may change depending on + // |error_message|. + if (GetWidget() && controller_->GetWebContents()) { + constrained_window::UpdateWebContentsModalDialogPosition( + GetWidget(), + web_modal::WebContentsModalDialogManager::FromWebContents( + controller_->GetWebContents()) + ->delegate() + ->GetWebContentsModalDialogHost()); + } GetDialogClientView()->UpdateDialogButtons(); } + Layout(); } void SetInputsEnabled(bool enabled) { cvc_input_->SetEnabled(enabled); + storage_checkbox_->SetEnabled(enabled); if (month_input_) month_input_->SetEnabled(enabled); @@ -100,15 +122,6 @@ year_input_->SetEnabled(enabled); } - void SetInputsInvalid(bool invalid) { - cvc_input_->SetInvalid(invalid); - - if (month_input_) - month_input_->SetInvalid(invalid); - if (year_input_) - year_input_->SetInvalid(invalid); - } - // views::DialogDelegateView View* GetContentsView() override { InitIfNecessary(); @@ -120,7 +133,7 @@ // Must hardcode a width so the label knows where to wrap. TODO(estade): // This can lead to a weird looking dialog if we end up getting allocated // more width than we ask for, e.g. if the title is super long. - const int kWidth = 250; + const int kWidth = 450; return gfx::Size(kWidth, GetHeightForWidth(kWidth)); } @@ -209,17 +222,13 @@ // views::TextfieldController void ContentsChanged(views::Textfield* sender, const base::string16& new_contents) override { - // Sets all inputs back to valid since we don't know which one was - // actually invalid to begin with. - SetInputsInvalid(false); + cvc_input_->SetInvalid(false); GetDialogClientView()->UpdateDialogButtons(); } // views::ComboboxListener void OnPerformAction(views::Combobox* combobox) override { - // Sets all inputs back to valid since we don't know which one was - // actually invalid to begin with. - SetInputsInvalid(false); + combobox->SetInvalid(false); GetDialogClientView()->UpdateDialogButtons(); } @@ -268,7 +277,7 @@ input_row->AddChildView(cvc_image); - // Reserve vertical space. + // Reserve vertical space for the error label, assuming it's one line. error_label_ = new views::Label(base::ASCIIToUTF16(" ")); error_label_->SetHorizontalAlignment(gfx::ALIGN_LEFT); error_label_->SetEnabledColor(kWarningColor);
diff --git a/chrome/browser/ui/views/constrained_web_dialog_delegate_views.cc b/chrome/browser/ui/views/constrained_web_dialog_delegate_views.cc index 37b6391..3b20f0e 100644 --- a/chrome/browser/ui/views/constrained_web_dialog_delegate_views.cc +++ b/chrome/browser/ui/views/constrained_web_dialog_delegate_views.cc
@@ -125,7 +125,7 @@ // ConstrainedWebDialogDelegate: web_modal::NativeWebContentsModalDialog GetNativeDialog() override { - return view_->GetWidget()->GetNativeView(); + return view_->GetWidget()->GetNativeWindow(); } private: @@ -246,7 +246,7 @@ web_modal::PopupManager* popup_manager = web_modal::PopupManager::FromWebContents( initiator_observer_.web_contents()); - popup_manager->ShowModalDialog(GetWidget()->GetNativeView(), + popup_manager->ShowModalDialog(GetWidget()->GetNativeWindow(), initiator_observer_.web_contents()); } }
diff --git a/chrome/browser/ui/views/download/download_item_view.cc b/chrome/browser/ui/views/download/download_item_view.cc index 457e4d49f..7a7f269 100644 --- a/chrome/browser/ui/views/download/download_item_view.cc +++ b/chrome/browser/ui/views/download/download_item_view.cc
@@ -274,6 +274,11 @@ void DownloadItemView::OnDownloadUpdated(DownloadItem* download_item) { DCHECK_EQ(download(), download_item); + if (!model_.ShouldShowInShelf()) { + shelf_->RemoveDownloadView(this); // This will delete us! + return; + } + if (IsShowingWarningDialog() && !model_.IsDangerous()) { // We have been approved. ClearWarningDialog();
diff --git a/chrome/browser/ui/views/download/download_shelf_view.cc b/chrome/browser/ui/views/download/download_shelf_view.cc index 9f7d42c..4b6552b 100644 --- a/chrome/browser/ui/views/download/download_shelf_view.cc +++ b/chrome/browser/ui/views/download/download_shelf_view.cc
@@ -127,8 +127,7 @@ } void DownloadShelfView::DoAddDownload(DownloadItem* download) { - DownloadItemView* view = new DownloadItemView(download, this); - AddDownloadView(view); + AddDownloadView(new DownloadItemView(download, this)); } void DownloadShelfView::MouseMovedOutOfHost() {
diff --git a/chrome/browser/ui/views/toolbar/toolbar_action_view_unittest.cc b/chrome/browser/ui/views/toolbar/toolbar_action_view_unittest.cc index fe711579..6bbacf87 100644 --- a/chrome/browser/ui/views/toolbar/toolbar_action_view_unittest.cc +++ b/chrome/browser/ui/views/toolbar/toolbar_action_view_unittest.cc
@@ -11,84 +11,13 @@ #include "chrome/browser/ui/views/toolbar/toolbar_action_view.h" #include "chrome/test/base/testing_profile.h" #include "content/public/test/test_browser_thread.h" -#include "content/public/test/test_renderer_host.h" -#include "content/public/test/web_contents_tester.h" +#include "content/public/test/test_web_contents_factory.h" #include "ui/accessibility/ax_view_state.h" #include "ui/events/test/event_generator.h" #include "ui/views/test/views_test_base.h" -#if defined(USE_AURA) -#include "ui/aura/env.h" -#endif - namespace { -// A helper class to create test web contents (tabs) for unit tests, without -// inheriting from RenderViewTestHarness. Can create web contents, and will -// clean up after itself upon destruction. Owns all created web contents. -// A few notes: -// - Works well allocated on the stack, because it should be destroyed before -// associated browser context. -// - Doesn't play nice with web contents created any other way (because of -// the implementation of RenderViewHostTestEnabler). But if you are creating -// web contents already, what do you need this for? ;) -// TODO(devlin): Look around and see if this class is needed elsewhere; if so, -// move it there and expand the API a bit (methods to, e.g., delete/close a -// web contents, access existing web contents, etc). -class TestWebContentsFactory { - public: - // |init_aura| initializes the aura environment (and cleans it up at - // shutdown, which is necessary for web contents. Since this method should - // only be called once, this should only be true if no other part of the test - // has initialized the environment. - explicit TestWebContentsFactory(bool init_aura); - ~TestWebContentsFactory(); - - // Creates a new WebContents with the given |context|, and returns it. - content::WebContents* CreateWebContents(content::BrowserContext* context); - private: - // The test factory (and friends) for creating test web contents. - scoped_ptr<content::RenderViewHostTestEnabler> rvh_enabler_; - // The vector of web contents that this class created. - ScopedVector<content::WebContents> web_contents_; - - // True if the factory initialized aura (and should thus tear it down). - bool init_aura_; - - DISALLOW_COPY_AND_ASSIGN(TestWebContentsFactory); -}; - -TestWebContentsFactory::TestWebContentsFactory(bool init_aura) - : rvh_enabler_(new content::RenderViewHostTestEnabler()), - init_aura_(init_aura) { -#if defined(USE_AURA) - if (init_aura) - aura::Env::CreateInstance(true); -#endif -} - -TestWebContentsFactory::~TestWebContentsFactory() { - web_contents_.clear(); - // Let any posted tasks for web contents deletion run. - base::RunLoop().RunUntilIdle(); - rvh_enabler_.reset(); - // Let any posted tasks for RenderProcess/ViewHost deletion run. - base::RunLoop().RunUntilIdle(); -#if defined(USE_AURA) - if (init_aura_) - aura::Env::DeleteInstance(); -#endif -} - -content::WebContents* TestWebContentsFactory::CreateWebContents( - content::BrowserContext* context) { - scoped_ptr<content::WebContents> web_contents( - content::WebContentsTester::CreateTestWebContents(context, nullptr)); - DCHECK(web_contents); - web_contents_.push_back(web_contents.release()); - return web_contents_.back(); -} - // A test delegate for a toolbar action view. class TestToolbarActionViewDelegate : public ToolbarActionView::Delegate { public: @@ -181,7 +110,7 @@ TestingProfile profile; // ViewsTestBase initializees the aura environment, so the factory shouldn't. - TestWebContentsFactory web_contents_factory(false); + content::TestWebContentsFactory web_contents_factory; TestToolbarActionViewController controller("fake controller"); TestToolbarActionViewDelegate action_view_delegate;
diff --git a/chrome/browser/ui/views/web_contents_modal_dialog_manager_views.cc b/chrome/browser/ui/views/web_contents_modal_dialog_manager_views.cc index 1664dfa..f2e6930 100644 --- a/chrome/browser/ui/views/web_contents_modal_dialog_manager_views.cc +++ b/chrome/browser/ui/views/web_contents_modal_dialog_manager_views.cc
@@ -220,7 +220,7 @@ #endif // Will cause this object to be deleted. - native_delegate_->WillClose(widget->GetNativeView()); + native_delegate_->WillClose(widget->GetNativeWindow()); } SingleWebContentsDialogManagerDelegate* native_delegate_;
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 ace8995..b5e8a5c 100644 --- a/chrome/browser/ui/webui/chromeos/login/gaia_screen_handler.cc +++ b/chrome/browser/ui/webui/chromeos/login/gaia_screen_handler.cc
@@ -246,10 +246,12 @@ } } - if (StartupUtils::IsWebviewSigninEnabled()) { + if (!command_line->HasSwitch(::switches::kGaiaUrl) && + StartupUtils::IsWebviewSigninEnabled()) { // We can't use switch --gaia-url in this case cause we need get // auth_code from staging gaia and make all the other auths against prod // gaia so user could use all the google services. + // TODO(dpolukhin): crbug.com/462204 const GURL gaia_url = GURL(kStagingGaiaUrl); params.SetString("gaiaUrl", gaia_url.spec()); } else {
diff --git a/chrome/browser/ui/webui/downloads_dom_handler.cc b/chrome/browser/ui/webui/downloads_dom_handler.cc index 83c753e..1a1dbc90 100644 --- a/chrome/browser/ui/webui/downloads_dom_handler.cc +++ b/chrome/browser/ui/webui/downloads_dom_handler.cc
@@ -77,35 +77,6 @@ DOWNLOADS_DOM_EVENT_MAX }; -static const char kKey[] = "DownloadsDOMHandlerData"; - -class DownloadsDOMHandlerData : public base::SupportsUserData::Data { - public: - static DownloadsDOMHandlerData* Get(content::DownloadItem* item) { - return static_cast<DownloadsDOMHandlerData*>(item->GetUserData(kKey)); - } - - static const DownloadsDOMHandlerData* Get(const content::DownloadItem* item) { - return static_cast<DownloadsDOMHandlerData*>(item->GetUserData(kKey)); - } - - static void Set(content::DownloadItem* item, DownloadsDOMHandlerData* data) { - item->SetUserData(kKey, data); - } - - static DownloadsDOMHandlerData* Create(content::DownloadItem* item) { - DownloadsDOMHandlerData* data = new DownloadsDOMHandlerData; - item->SetUserData(kKey, data); - return data; - } - - void set_is_removed(bool is_removed) { is_removed_ = is_removed; } - bool is_removed() const { return is_removed_; } - - private: - bool is_removed_; -}; - void CountDownloadsDOMEvents(DownloadsDOMEvent event) { UMA_HISTOGRAM_ENUMERATION("Download.DOMEvent", event, @@ -267,18 +238,14 @@ return file_value; } -bool IsRemoved(const content::DownloadItem& item) { - const DownloadsDOMHandlerData* data = DownloadsDOMHandlerData::Get(&item); - return data && data->is_removed(); -} - // Filters out extension downloads and downloads that don't have a filename yet. bool IsDownloadDisplayable(const content::DownloadItem& item) { return !download_crx_util::IsExtensionDownload(item) && !item.IsTemporary() && !item.GetFileNameToReportUser().empty() && !item.GetTargetFilePath().empty() && - !IsRemoved(item); + DownloadItemModel( + const_cast<content::DownloadItem*>(&item)).ShouldShowInShelf(); } } // namespace @@ -299,16 +266,7 @@ } DownloadsDOMHandler::~DownloadsDOMHandler() { - while (!removes_.empty()) { - const std::set<uint32> remove = removes_.back(); - removes_.pop_back(); - - for (const auto id : remove) { - content::DownloadItem* download = GetDownloadById(id); - if (download) - download->Remove(); - } - } + FinalizeRemovals(); } // DownloadsDOMHandler, public: ----------------------------------------------- @@ -398,7 +356,7 @@ void DownloadsDOMHandler::OnDownloadRemoved( content::DownloadManager* manager, content::DownloadItem* download_item) { - if (IsRemoved(*download_item)) + if (!DownloadItemModel(download_item).ShouldShowInShelf()) return; // This relies on |download_item| being removed from DownloadManager in this @@ -503,17 +461,17 @@ void DownloadsDOMHandler::HandleUndo(const base::ListValue* args) { // TODO(dbeam): handle more than removed downloads someday? - if (removes_.empty()) + if (removals_.empty()) return; - const std::set<uint32> last_removed_ids = removes_.back(); - removes_.pop_back(); + const std::set<uint32> last_removed_ids = removals_.back(); + removals_.pop_back(); for (auto id : last_removed_ids) { content::DownloadItem* download = GetDownloadById(id); if (!download) continue; - DownloadsDOMHandlerData::Set(download, nullptr); + DownloadItemModel(download).SetShouldShowInShelf(true); download->UpdateObservers(); } } @@ -543,16 +501,18 @@ const std::vector<content::DownloadItem*>& to_remove) { std::set<uint32> ids; for (auto* download : to_remove) { - if (IsRemoved(*download) || + DownloadItemModel item_model(download); + if (!item_model.ShouldShowInShelf() || download->GetState() == content::DownloadItem::IN_PROGRESS) { continue; } - DownloadsDOMHandlerData::Create(download)->set_is_removed(true); + item_model.SetShouldShowInShelf(false); ids.insert(download->GetId()); download->UpdateObservers(); } - removes_.push_back(ids); + if (!ids.empty()) + removals_.push_back(ids); } void DownloadsDOMHandler::HandleOpenDownloadsFolder( @@ -585,6 +545,19 @@ return main_notifier_.GetManager(); } +void DownloadsDOMHandler::FinalizeRemovals() { + while (!removals_.empty()) { + const std::set<uint32> remove = removals_.back(); + removals_.pop_back(); + + for (const auto id : remove) { + content::DownloadItem* download = GetDownloadById(id); + if (download) + download->Remove(); + } + } +} + void DownloadsDOMHandler::SendCurrentDownloads() { update_scheduled_ = false; content::DownloadManager::DownloadVector all_items, filtered_items; @@ -670,8 +643,8 @@ content::DownloadItem* DownloadsDOMHandler::GetDownloadById(uint32 id) { content::DownloadItem* item = NULL; - if (main_notifier_.GetManager()) - item = main_notifier_.GetManager()->GetDownload(id); + if (GetMainNotifierManager()) + item = GetMainNotifierManager()->GetDownload(id); if (!item && original_notifier_.get() && original_notifier_->GetManager()) item = original_notifier_->GetManager()->GetDownload(id); return item;
diff --git a/chrome/browser/ui/webui/downloads_dom_handler.h b/chrome/browser/ui/webui/downloads_dom_handler.h index 06890acd..85fdbd8a 100644 --- a/chrome/browser/ui/webui/downloads_dom_handler.h +++ b/chrome/browser/ui/webui/downloads_dom_handler.h
@@ -106,6 +106,9 @@ // Protected for testing. virtual content::DownloadManager* GetMainNotifierManager(); + // Actually remove downloads with an ID in |removals_|. This cannot be undone. + void FinalizeRemovals(); + private: // Shorthand for |observing_items_|, which tracks all items that this is // observing so that RemoveObserver will be called for all of them. @@ -150,7 +153,7 @@ scoped_ptr<AllDownloadItemNotifier> original_notifier_; // IDs of downloads to remove when this handler gets deleted. - std::vector<std::set<uint32>> removes_; + std::vector<std::set<uint32>> removals_; // Whether a call to SendCurrentDownloads() is currently scheduled. bool update_scheduled_;
diff --git a/chrome/browser/ui/webui/downloads_dom_handler_browsertest.cc b/chrome/browser/ui/webui/downloads_dom_handler_browsertest.cc index 4d8c060..ed0193a 100644 --- a/chrome/browser/ui/webui/downloads_dom_handler_browsertest.cc +++ b/chrome/browser/ui/webui/downloads_dom_handler_browsertest.cc
@@ -7,6 +7,7 @@ #include "base/json/json_reader.h" #include "base/prefs/pref_service.h" #include "base/values.h" +#include "chrome/browser/download/download_item_model.h" #include "chrome/browser/profiles/profile.h" #include "chrome/browser/ui/browser.h" #include "chrome/browser/ui/webui/downloads_dom_handler.h" @@ -85,6 +86,8 @@ void set_manager(content::DownloadManager* manager) { manager_ = manager; } + using DownloadsDOMHandler::FinalizeRemovals; + protected: content::WebContents* GetWebUIWebContents() override { return NULL; } @@ -247,6 +250,7 @@ testing::SetArgPointee<0>(items)); mock_handler_->HandleClearAll(NULL); + EXPECT_TRUE(DownloadItemModel(&item).ShouldShowInShelf()); } // Tests that DownloadsDOMHandler detects new downloads and relays them to the @@ -270,6 +274,34 @@ EXPECT_EQ(0, static_cast<int>(mock_handler_->downloads_list()->GetSize())); } +// Tests that DownloadsDOMHandler actually calls DownloadItem::Remove() when +// it's closed (and removals can no longer be undone). +IN_PROC_BROWSER_TEST_F(DownloadsDOMHandlerTest, RemoveCalledOnPageClose) { + content::MockDownloadManager manager; + mock_handler_->set_manager(&manager); + + content::MockDownloadItem item; + EXPECT_CALL(item, GetId()).WillRepeatedly(testing::Return(1)); + EXPECT_CALL(item, GetState()).WillRepeatedly( + testing::Return(content::DownloadItem::COMPLETE)); + + DownloadItemModel model(&item); + EXPECT_TRUE(model.ShouldShowInShelf()); + + EXPECT_CALL(manager, GetDownload(1)).WillRepeatedly(testing::Return(&item)); + + base::ListValue remove; + remove.AppendString("1"); + EXPECT_CALL(item, UpdateObservers()).Times(1); + mock_handler_->HandleRemove(&remove); + EXPECT_FALSE(model.ShouldShowInShelf()); + + EXPECT_CALL(item, Remove()).Times(1); + // Call |mock_handler_->FinalizeRemovals()| instead of |mock_handler_.reset()| + // because the vtable is affected during destruction and the fake manager + // rigging doesn't work. + mock_handler_->FinalizeRemovals(); +} // TODO(benjhayden): Test the extension downloads filter for both // mock_handler_.downloads_list() and mock_handler_.download_updated().
diff --git a/chrome/browser/ui/webui/extensions/extension_settings_handler.cc b/chrome/browser/ui/webui/extensions/extension_settings_handler.cc index b7ea12f..c21555f 100644 --- a/chrome/browser/ui/webui/extensions/extension_settings_handler.cc +++ b/chrome/browser/ui/webui/extensions/extension_settings_handler.cc
@@ -636,6 +636,30 @@ // uber extensions. source->AddString("extensionUninstall", l10n_util::GetStringUTF16(IDS_EXTENSIONS_UNINSTALL)); + + // Pack Extension Overlay: + source->AddString("packExtensionOverlay", + l10n_util::GetStringUTF16(IDS_EXTENSION_PACK_DIALOG_TITLE)); + source->AddString("packExtensionHeading", + l10n_util::GetStringUTF16(IDS_EXTENSION_PACK_DIALOG_HEADING)); + source->AddString("packExtensionCommit", + l10n_util::GetStringUTF16(IDS_EXTENSION_PACK_BUTTON)); + source->AddString("ok", l10n_util::GetStringUTF16(IDS_OK)); + source->AddString("cancel", l10n_util::GetStringUTF16(IDS_CANCEL)); + source->AddString("packExtensionRootDir", + l10n_util::GetStringUTF16( + IDS_EXTENSION_PACK_DIALOG_ROOT_DIRECTORY_LABEL)); + source->AddString("packExtensionPrivateKey", + l10n_util::GetStringUTF16(IDS_EXTENSION_PACK_DIALOG_PRIVATE_KEY_LABEL)); + source->AddString("packExtensionBrowseButton", + l10n_util::GetStringUTF16(IDS_EXTENSION_PACK_DIALOG_BROWSE)); + source->AddString("packExtensionProceedAnyway", + l10n_util::GetStringUTF16(IDS_EXTENSION_PROCEED_ANYWAY)); + source->AddString("packExtensionWarningTitle", + l10n_util::GetStringUTF16(IDS_EXTENSION_PACK_WARNING_TITLE)); + source->AddString("packExtensionErrorTitle", + l10n_util::GetStringUTF16(IDS_EXTENSION_PACK_ERROR_TITLE)); + } void ExtensionSettingsHandler::RenderViewDeleted(
diff --git a/chrome/browser/ui/webui/extensions/extensions_ui.cc b/chrome/browser/ui/webui/extensions/extensions_ui.cc index d99e809..88252e0 100644 --- a/chrome/browser/ui/webui/extensions/extensions_ui.cc +++ b/chrome/browser/ui/webui/extensions/extensions_ui.cc
@@ -10,7 +10,6 @@ #include "chrome/browser/ui/webui/extensions/extension_loader_handler.h" #include "chrome/browser/ui/webui/extensions/extension_settings_handler.h" #include "chrome/browser/ui/webui/extensions/install_extension_handler.h" -#include "chrome/browser/ui/webui/extensions/pack_extension_handler.h" #include "chrome/browser/ui/webui/metrics_handler.h" #include "chrome/common/url_constants.h" #include "content/public/browser/web_ui.h" @@ -51,10 +50,6 @@ handler->GetLocalizedValues(source); web_ui->AddMessageHandler(handler); - PackExtensionHandler* pack_handler = new PackExtensionHandler(); - pack_handler->GetLocalizedValues(source); - web_ui->AddMessageHandler(pack_handler); - CommandHandler* commands_handler = new CommandHandler(profile); commands_handler->GetLocalizedValues(source); web_ui->AddMessageHandler(commands_handler);
diff --git a/chrome/browser/ui/webui/extensions/pack_extension_handler.cc b/chrome/browser/ui/webui/extensions/pack_extension_handler.cc deleted file mode 100644 index 12a4c07..0000000 --- a/chrome/browser/ui/webui/extensions/pack_extension_handler.cc +++ /dev/null
@@ -1,207 +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 "chrome/browser/ui/webui/extensions/pack_extension_handler.h" - -#include "base/bind.h" -#include "base/strings/utf_string_conversions.h" -#include "chrome/browser/extensions/extension_creator.h" -#include "chrome/browser/ui/chrome_select_file_policy.h" -#include "chrome/grit/generated_resources.h" -#include "content/public/browser/web_contents.h" -#include "content/public/browser/web_ui.h" -#include "content/public/browser/web_ui_data_source.h" -#include "ui/base/l10n/l10n_util.h" - -namespace extensions { - -PackExtensionHandler::PackExtensionHandler() { -} - -PackExtensionHandler::~PackExtensionHandler() { - // There may be pending file dialogs, we need to tell them that we've gone - // away so they don't try and call back to us. - if (load_extension_dialog_.get()) - load_extension_dialog_->ListenerDestroyed(); - - if (pack_job_.get()) - pack_job_->ClearClient(); -} - -void PackExtensionHandler::GetLocalizedValues( - content::WebUIDataSource* source) { - source->AddString("packExtensionOverlay", - l10n_util::GetStringUTF16(IDS_EXTENSION_PACK_DIALOG_TITLE)); - source->AddString("packExtensionHeading", - l10n_util::GetStringUTF16(IDS_EXTENSION_PACK_DIALOG_HEADING)); - source->AddString("packExtensionCommit", - l10n_util::GetStringUTF16(IDS_EXTENSION_PACK_BUTTON)); - source->AddString("ok", l10n_util::GetStringUTF16(IDS_OK)); - source->AddString("cancel", l10n_util::GetStringUTF16(IDS_CANCEL)); - source->AddString("packExtensionRootDir", - l10n_util::GetStringUTF16( - IDS_EXTENSION_PACK_DIALOG_ROOT_DIRECTORY_LABEL)); - source->AddString("packExtensionPrivateKey", - l10n_util::GetStringUTF16(IDS_EXTENSION_PACK_DIALOG_PRIVATE_KEY_LABEL)); - source->AddString("packExtensionBrowseButton", - l10n_util::GetStringUTF16(IDS_EXTENSION_PACK_DIALOG_BROWSE)); - source->AddString("packExtensionProceedAnyway", - l10n_util::GetStringUTF16(IDS_EXTENSION_PROCEED_ANYWAY)); - source->AddString("packExtensionWarningTitle", - l10n_util::GetStringUTF16(IDS_EXTENSION_PACK_WARNING_TITLE)); - source->AddString("packExtensionErrorTitle", - l10n_util::GetStringUTF16(IDS_EXTENSION_PACK_ERROR_TITLE)); -} - -void PackExtensionHandler::RegisterMessages() { - web_ui()->RegisterMessageCallback( - "pack", - base::Bind(&PackExtensionHandler::HandlePackMessage, - base::Unretained(this))); - web_ui()->RegisterMessageCallback( - "packExtensionSelectFilePath", - base::Bind(&PackExtensionHandler::HandleSelectFilePathMessage, - base::Unretained(this))); -} - -void PackExtensionHandler::OnPackSuccess(const base::FilePath& crx_file, - const base::FilePath& pem_file) { - base::ListValue arguments; - arguments.Append(new base::StringValue(base::UTF16ToUTF8( - PackExtensionJob::StandardSuccessMessage(crx_file, pem_file)))); - web_ui()->CallJavascriptFunction( - "extensions.PackExtensionOverlay.showSuccessMessage", arguments); -} - -void PackExtensionHandler::OnPackFailure(const std::string& error, - ExtensionCreator::ErrorType type) { - if (type == ExtensionCreator::kCRXExists) { - base::StringValue error_str(error); - base::StringValue extension_path_str(extension_path_.value()); - base::StringValue key_path_str(private_key_path_.value()); - base::FundamentalValue overwrite_flag(ExtensionCreator::kOverwriteCRX); - - web_ui()->CallJavascriptFunction( - "extensions.ExtensionSettings.askToOverrideWarning", - error_str, extension_path_str, key_path_str, overwrite_flag); - } else { - ShowAlert(error); - } -} - -void PackExtensionHandler::FileSelected(const base::FilePath& path, int index, - void* params) { - base::ListValue results; - results.Append(new base::StringValue(path.value())); - web_ui()->CallJavascriptFunction("window.handleFilePathSelected", results); -} - -void PackExtensionHandler::MultiFilesSelected( - const std::vector<base::FilePath>& files, void* params) { - NOTREACHED(); -} - -void PackExtensionHandler::HandlePackMessage(const base::ListValue* args) { - DCHECK_EQ(3U, args->GetSize()); - - double flags_double = 0.0; - base::FilePath::StringType extension_path_str; - base::FilePath::StringType private_key_path_str; - if (!args->GetString(0, &extension_path_str) || - !args->GetString(1, &private_key_path_str) || - !args->GetDouble(2, &flags_double)) { - NOTREACHED(); - return; - } - - extension_path_ = base::FilePath(extension_path_str); - private_key_path_ = base::FilePath(private_key_path_str); - - int run_flags = static_cast<int>(flags_double); - - base::FilePath root_directory = extension_path_; - base::FilePath key_file = private_key_path_; - last_used_path_ = extension_path_; - - if (root_directory.empty()) { - if (extension_path_.empty()) { - ShowAlert(l10n_util::GetStringUTF8( - IDS_EXTENSION_PACK_DIALOG_ERROR_ROOT_REQUIRED)); - } else { - ShowAlert(l10n_util::GetStringUTF8( - IDS_EXTENSION_PACK_DIALOG_ERROR_ROOT_INVALID)); - } - - return; - } - - if (!private_key_path_.empty() && key_file.empty()) { - ShowAlert(l10n_util::GetStringUTF8( - IDS_EXTENSION_PACK_DIALOG_ERROR_KEY_INVALID)); - return; - } - - pack_job_ = new PackExtensionJob(this, root_directory, key_file, run_flags); - pack_job_->Start(); -} - -void PackExtensionHandler::HandleSelectFilePathMessage( - const base::ListValue* args) { - DCHECK_EQ(2U, args->GetSize()); - - std::string select_type; - if (!args->GetString(0, &select_type)) - NOTREACHED(); - - std::string operation; - if (!args->GetString(1, &operation)) - NOTREACHED(); - - ui::SelectFileDialog::Type type = ui::SelectFileDialog::SELECT_FOLDER; - ui::SelectFileDialog::FileTypeInfo info; - int file_type_index = 0; - base::FilePath path_to_use = last_used_path_; - if (select_type == "file") { - type = ui::SelectFileDialog::SELECT_OPEN_FILE; - path_to_use = base::FilePath(); - } - - base::string16 select_title; - if (operation == "load") { - select_title = l10n_util::GetStringUTF16(IDS_EXTENSION_LOAD_FROM_DIRECTORY); - } else if (operation == "pem") { - select_title = l10n_util::GetStringUTF16( - IDS_EXTENSION_PACK_DIALOG_SELECT_KEY); - info.extensions.push_back(std::vector<base::FilePath::StringType>()); - info.extensions.front().push_back(FILE_PATH_LITERAL("pem")); - info.extension_description_overrides.push_back( - l10n_util::GetStringUTF16( - IDS_EXTENSION_PACK_DIALOG_KEY_FILE_TYPE_DESCRIPTION)); - info.include_all_files = true; - file_type_index = 1; - } else { - NOTREACHED(); - } - - load_extension_dialog_ = ui::SelectFileDialog::Create( - this, new ChromeSelectFilePolicy(web_ui()->GetWebContents())); - load_extension_dialog_->SelectFile( - type, - select_title, - path_to_use, - &info, - file_type_index, - base::FilePath::StringType(), - web_ui()->GetWebContents()->GetTopLevelNativeWindow(), - NULL); -} - -void PackExtensionHandler::ShowAlert(const std::string& message) { - base::ListValue arguments; - arguments.Append(new base::StringValue(message)); - web_ui()->CallJavascriptFunction( - "extensions.PackExtensionOverlay.showError", arguments); -} - -} // namespace extensions
diff --git a/chrome/browser/ui/webui/extensions/pack_extension_handler.h b/chrome/browser/ui/webui/extensions/pack_extension_handler.h deleted file mode 100644 index 36a27b3..0000000 --- a/chrome/browser/ui/webui/extensions/pack_extension_handler.h +++ /dev/null
@@ -1,86 +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 CHROME_BROWSER_UI_WEBUI_EXTENSIONS_PACK_EXTENSION_HANDLER_H_ -#define CHROME_BROWSER_UI_WEBUI_EXTENSIONS_PACK_EXTENSION_HANDLER_H_ - -#include <string> - -#include "base/files/file_path.h" -#include "chrome/browser/browsing_data/browsing_data_remover.h" -#include "chrome/browser/extensions/pack_extension_job.h" -#include "chrome/browser/plugins/plugin_data_remover_helper.h" -#include "content/public/browser/web_ui_message_handler.h" -#include "ui/shell_dialogs/select_file_dialog.h" - -namespace content { -class WebUIDataSource; -} - -namespace extensions { - -// Clear browser data handler page UI handler. -class PackExtensionHandler : public content::WebUIMessageHandler, - public ui::SelectFileDialog::Listener, - public PackExtensionJob::Client { - public: - PackExtensionHandler(); - ~PackExtensionHandler() override; - - void GetLocalizedValues(content::WebUIDataSource* source); - - // WebUIMessageHandler implementation. - void RegisterMessages() override; - - // ExtensionPackJob::Client implementation. - void OnPackSuccess(const base::FilePath& crx_file, - const base::FilePath& key_file) override; - - void OnPackFailure(const std::string& error, - ExtensionCreator::ErrorType) override; - - private: - // SelectFileDialog::Listener implementation. - void FileSelected(const base::FilePath& path, - int index, - void* params) override; - void MultiFilesSelected(const std::vector<base::FilePath>& files, - void* params) override; - void FileSelectionCanceled(void* params) override {} - - // JavaScript callback to start packing an extension. - void HandlePackMessage(const base::ListValue* args); - - // JavaScript callback to show a file browse dialog. - // |args[0]| must be a string that specifies the file dialog type: file or - // folder. - // |args[1]| must be a string that specifies the operation to perform: load - // or pem. - void HandleSelectFilePathMessage(const base::ListValue* args); - - // A function to ask the page to show an alert. - void ShowAlert(const std::string& message); - - // Used to package the extension. - scoped_refptr<PackExtensionJob> pack_job_; - - // Returned by the SelectFileDialog machinery. Used to initiate the selection - // dialog. - scoped_refptr<ui::SelectFileDialog> load_extension_dialog_; - - // Path to root directory of extension. - base::FilePath extension_path_; - - // Path to private key file, or null if none specified. - base::FilePath private_key_path_; - - // Path to the last used folder to load an extension. - base::FilePath last_used_path_; - - DISALLOW_COPY_AND_ASSIGN(PackExtensionHandler); -}; - -} // namespace extensions - -#endif // CHROME_BROWSER_UI_WEBUI_EXTENSIONS_PACK_EXTENSION_HANDLER_H_
diff --git a/chrome/browser/ui/webui/options/browser_options_handler.cc b/chrome/browser/ui/webui/options/browser_options_handler.cc index e3d05b1..a40eb9ef 100644 --- a/chrome/browser/ui/webui/options/browser_options_handler.cc +++ b/chrome/browser/ui/webui/options/browser_options_handler.cc
@@ -681,6 +681,9 @@ values->SetBoolean("enableTimeZoneTrackingOption", !have_disable_time_zone_tracking_option_switch && !chromeos::system::HasSystemTimezonePolicy()); + values->SetBoolean("resolveTimezoneByGeolocationInitialValue", + Profile::FromWebUI(web_ui())->GetPrefs()->GetBoolean( + prefs::kResolveTimezoneByGeolocation)); #endif }
diff --git a/chrome/browser/ui/webui/options/chromeos/date_time_options_browsertest.js b/chrome/browser/ui/webui/options/chromeos/date_time_options_browsertest.js index 937af8b..4033599 100644 --- a/chrome/browser/ui/webui/options/chromeos/date_time_options_browsertest.js +++ b/chrome/browser/ui/webui/options/chromeos/date_time_options_browsertest.js
@@ -26,14 +26,12 @@ TEST_F('DateTimeOptionsWebUITest', 'testShowSetTimeButton', function() { assertEquals(this.browsePreload, document.location.href); - // Hide label and show button. + // Show button. BrowserOptions.setCanSetTime(true); - expectTrue($('time-synced-explanation').hidden); expectFalse($('set-time').hidden); - // Show label and hide button. + // Hide button. BrowserOptions.setCanSetTime(false); - expectFalse($('time-synced-explanation').hidden); expectTrue($('set-time').hidden); });
diff --git a/chrome/browser/ui/webui/options/chromeos/date_time_options_handler.cc b/chrome/browser/ui/webui/options/chromeos/date_time_options_handler.cc index ef55e5f..bbb4b0c 100644 --- a/chrome/browser/ui/webui/options/chromeos/date_time_options_handler.cc +++ b/chrome/browser/ui/webui/options/chromeos/date_time_options_handler.cc
@@ -33,9 +33,6 @@ localized_strings->SetString( "setTimeButton", l10n_util::GetStringUTF16(IDS_OPTIONS_SETTINGS_SET_TIME_BUTTON)); - localized_strings->SetString( - "timeSyncedExplanation", - l10n_util::GetStringUTF16(IDS_OPTIONS_SETTINGS_TIME_SYNCED_EXPLANATION)); } void DateTimeOptionsHandler::InitializeHandler() {
diff --git a/chrome/browser/ui/webui/options/chromeos/shared_options_browsertest.cc b/chrome/browser/ui/webui/options/chromeos/shared_options_browsertest.cc index df7f7d1..d51fd41 100644 --- a/chrome/browser/ui/webui/options/chromeos/shared_options_browsertest.cc +++ b/chrome/browser/ui/webui/options/chromeos/shared_options_browsertest.cc
@@ -118,11 +118,17 @@ browser->tab_strip_model()->GetActiveWebContents(); for (size_t i = 0; i < sizeof(kPrefTests) / sizeof(kPrefTests[0]); i++) { - CheckPreference(contents, - kPrefTests[i].pref_name, - !is_owner && kPrefTests[i].owner_only, - !is_owner && kPrefTests[i].indicator ? "owner" : - std::string()); + bool disabled = !is_owner && kPrefTests[i].owner_only; + if (strcmp(kPrefTests[i].pref_name, kSystemTimezone) == 0) { + disabled = ProfileHelper::Get() + ->GetProfileByUserUnsafe(user) + ->GetPrefs() + ->GetBoolean(prefs::kResolveTimezoneByGeolocation); + } + + CheckPreference( + contents, kPrefTests[i].pref_name, disabled, + !is_owner && kPrefTests[i].indicator ? "owner" : std::string()); } CheckBanner(contents, is_primary); CheckSharedSections(contents, is_primary);
diff --git a/chrome/chrome_browser.gypi b/chrome/chrome_browser.gypi index 501a602..5a552b6 100644 --- a/chrome/chrome_browser.gypi +++ b/chrome/chrome_browser.gypi
@@ -101,6 +101,12 @@ 'browser/android/logo_service.h', 'browser/android/manifest_icon_selector.cc', 'browser/android/manifest_icon_selector.h', + 'browser/android/metrics/uma_bridge.cc', + 'browser/android/metrics/uma_bridge.h', + 'browser/android/metrics/uma_session_stats.cc', + 'browser/android/metrics/uma_session_stats.h', + 'browser/android/metrics/uma_utils.cc', + 'browser/android/metrics/uma_utils.h', 'browser/android/most_visited_sites.cc', 'browser/android/most_visited_sites.h', 'browser/android/new_tab_page_prefs.cc', @@ -154,10 +160,6 @@ 'browser/android/thumbnail/thumbnail.h', 'browser/android/thumbnail/thumbnail_store.cc', 'browser/android/thumbnail/thumbnail_store.h', - 'browser/android/uma_bridge.cc', - 'browser/android/uma_bridge.h', - 'browser/android/uma_utils.cc', - 'browser/android/uma_utils.h', 'browser/android/url_utilities.cc', 'browser/android/url_utilities.h', 'browser/android/voice_search_tab_helper.cc', @@ -1599,6 +1601,9 @@ 'android/java/src/org/chromium/chrome/browser/NewTabPagePrefs.java', 'android/java/src/org/chromium/chrome/browser/IntentHelper.java', 'android/java/src/org/chromium/chrome/browser/JavascriptAppModalDialog.java', + 'android/java/src/org/chromium/chrome/browser/metrics/UmaBridge.java', + 'android/java/src/org/chromium/chrome/browser/metrics/UmaSessionStats.java', + 'android/java/src/org/chromium/chrome/browser/metrics/UmaUtils.java', 'android/java/src/org/chromium/chrome/browser/NavigationPopup.java', 'android/java/src/org/chromium/chrome/browser/net/spdyproxy/DataReductionProxySettings.java', 'android/java/src/org/chromium/chrome/browser/notifications/NotificationUIManager.java', @@ -1631,8 +1636,6 @@ 'android/java/src/org/chromium/chrome/browser/Tab.java', 'android/java/src/org/chromium/chrome/browser/TabState.java', 'android/java/src/org/chromium/chrome/browser/TtsPlatformImpl.java', - 'android/java/src/org/chromium/chrome/browser/UmaBridge.java', - 'android/java/src/org/chromium/chrome/browser/UmaUtils.java', 'android/java/src/org/chromium/chrome/browser/UrlUtilities.java', 'android/java/src/org/chromium/chrome/browser/util/FeatureUtilities.java', 'android/java/src/org/chromium/chrome/browser/VoiceSearchTabHelper.java', @@ -2241,6 +2244,7 @@ 'browser/profiles/profile_metrics.cc', 'browser/profiles/profile_metrics.h', 'browser/profiles/profile_metrics_list.h', + 'browser/profiles/profile_metrics_mac.mm', 'browser/profiles/profile_shortcut_manager_win.cc', 'browser/profiles/profile_shortcut_manager_win.h', 'browser/profiles/profiles_state.cc', @@ -2896,6 +2900,7 @@ '../components/components.gyp:enhanced_bookmarks', '../components/components.gyp:favicon_base', '../components/components.gyp:favicon_core', + '../components/components.gyp:feedback_component', '../components/components.gyp:gcm_driver', '../components/components.gyp:google_core_browser', '../components/components.gyp:handoff', @@ -3366,7 +3371,6 @@ }, { # OS!="android" and OS!="ios" 'sources': [ '<@(chrome_browser_non_mobile_sources)' ], 'dependencies': [ - '../components/components.gyp:feedback_component', '../device/core/core.gyp:device_core', '../device/usb/usb.gyp:device_usb', ] @@ -3383,6 +3387,7 @@ 'chrome_browser_jni_headers', ], 'dependencies!': [ + '../components/components.gyp:feedback_component', '../components/components.gyp:storage_monitor', '../components/components.gyp:web_modal', '../third_party/libaddressinput/libaddressinput.gyp:libaddressinput',
diff --git a/chrome/chrome_browser_chromeos.gypi b/chrome/chrome_browser_chromeos.gypi index 11d50ac..0714c13 100644 --- a/chrome/chrome_browser_chromeos.gypi +++ b/chrome/chrome_browser_chromeos.gypi
@@ -421,8 +421,6 @@ 'browser/chromeos/login/auth/chrome_login_performer.h', 'browser/chromeos/login/chrome_restart_request.cc', 'browser/chromeos/login/chrome_restart_request.h', - 'browser/chromeos/login/default_pinned_apps_field_trial.cc', - 'browser/chromeos/login/default_pinned_apps_field_trial.h', 'browser/chromeos/login/demo_mode/demo_app_launcher.cc', 'browser/chromeos/login/demo_mode/demo_app_launcher.h', 'browser/chromeos/login/easy_unlock/easy_unlock_create_keys_operation.cc',
diff --git a/chrome/chrome_browser_ui.gypi b/chrome/chrome_browser_ui.gypi index 28e210e4..5bb7f3a3 100644 --- a/chrome/chrome_browser_ui.gypi +++ b/chrome/chrome_browser_ui.gypi
@@ -651,6 +651,8 @@ 'browser/ui/cocoa/screen_capture_notification_ui_cocoa.h', 'browser/ui/cocoa/screen_capture_notification_ui_cocoa.mm', 'browser/ui/cocoa/simple_message_box_mac.mm', + 'browser/ui/cocoa/single_web_contents_dialog_manager_cocoa.h', + 'browser/ui/cocoa/single_web_contents_dialog_manager_cocoa.mm', 'browser/ui/cocoa/sprite_view.h', 'browser/ui/cocoa/sprite_view.mm', 'browser/ui/cocoa/ssl_client_certificate_selector_cocoa.h', @@ -731,7 +733,6 @@ 'browser/ui/cocoa/view_id_util.h', 'browser/ui/cocoa/view_id_util.mm', 'browser/ui/cocoa/view_resizer.h', - 'browser/ui/cocoa/web_contents_modal_dialog_manager_cocoa.mm', 'browser/ui/cocoa/web_dialog_window_controller.h', 'browser/ui/cocoa/web_dialog_window_controller.mm', 'browser/ui/cocoa/website_settings/permission_bubble_cocoa.h', @@ -1344,8 +1345,7 @@ # Counts desktop Linux and ChromeOS. 'chrome_browser_ui_linux_sources': [ 'browser/ui/startup/autolaunch_prompt.cc', - 'browser/ui/views/apps/chrome_apps_client_views.cc', - 'browser/ui/views/apps/keyboard_hook_handler.cc', + 'browser/ui/views/apps/chrome_app_window_client_views.cc', 'browser/ui/webui/certificate_viewer_ui.cc', 'browser/ui/webui/certificate_viewer_ui.h', 'browser/ui/webui/certificate_viewer_webui.cc', @@ -1841,6 +1841,12 @@ 'browser/ui/app_list/app_list_service_views.h', 'browser/ui/app_list/app_list_shower_views.cc', 'browser/ui/app_list/app_list_shower_views.h', + 'browser/ui/views/apps/chrome_native_app_window_views.cc', + 'browser/ui/views/apps/chrome_native_app_window_views.h', + 'browser/ui/views/apps/desktop_keyboard_capture.cc', + 'browser/ui/views/apps/desktop_keyboard_capture.h', + 'browser/ui/views/apps/keyboard_hook_handler.cc', + 'browser/ui/views/apps/keyboard_hook_handler.h', 'browser/ui/views/chrome_browser_main_extra_parts_views.cc', 'browser/ui/views/chrome_browser_main_extra_parts_views.h', 'browser/ui/views/chrome_constrained_window_views_client.cc', @@ -1851,10 +1857,14 @@ 'browser/ui/views/collected_cookies_views.h', 'browser/ui/views/cookie_info_view.cc', 'browser/ui/views/cookie_info_view.h', + 'browser/ui/views/extensions/extension_keybinding_registry_views.cc', + 'browser/ui/views/extensions/extension_keybinding_registry_views.h', 'browser/ui/views/find_bar_host.cc', 'browser/ui/views/find_bar_host.h', 'browser/ui/views/find_bar_view.cc', 'browser/ui/views/find_bar_view.h', + 'browser/ui/views/frame/taskbar_decorator.cc', + 'browser/ui/views/frame/taskbar_decorator.h', 'browser/ui/views/hung_renderer_view.cc', 'browser/ui/views/hung_renderer_view.h', 'browser/ui/views/infobars/confirm_infobar.cc', @@ -1953,18 +1963,13 @@ 'browser/ui/views/apps/app_window_desktop_native_widget_aura_win.h', 'browser/ui/views/apps/app_window_desktop_window_tree_host_win.cc', 'browser/ui/views/apps/app_window_desktop_window_tree_host_win.h', - 'browser/ui/views/apps/chrome_apps_client_views_win.cc', - 'browser/ui/views/apps/chrome_native_app_window_views.cc', - 'browser/ui/views/apps/chrome_native_app_window_views.h', + 'browser/ui/views/apps/chrome_app_window_client_views_win.cc', 'browser/ui/views/apps/chrome_native_app_window_views_aura.cc', 'browser/ui/views/apps/chrome_native_app_window_views_aura.h', 'browser/ui/views/apps/chrome_native_app_window_views_win.cc', 'browser/ui/views/apps/chrome_native_app_window_views_win.h', - 'browser/ui/views/apps/desktop_keyboard_capture.cc', - 'browser/ui/views/apps/desktop_keyboard_capture.h', 'browser/ui/views/apps/glass_app_window_frame_view_win.cc', 'browser/ui/views/apps/glass_app_window_frame_view_win.h', - 'browser/ui/views/apps/keyboard_hook_handler.h', 'browser/ui/views/apps/keyboard_hook_handler_win.cc', 'browser/ui/views/apps/shaped_app_window_targeter.cc', 'browser/ui/views/apps/shaped_app_window_targeter.h', @@ -2078,8 +2083,6 @@ 'browser/ui/views/extensions/extension_install_dialog_view.cc', 'browser/ui/views/extensions/extension_installed_bubble_view.cc', 'browser/ui/views/extensions/extension_installed_bubble_view.h', - 'browser/ui/views/extensions/extension_keybinding_registry_views.cc', - 'browser/ui/views/extensions/extension_keybinding_registry_views.h', 'browser/ui/views/extensions/extension_message_bubble_view.cc', 'browser/ui/views/extensions/extension_message_bubble_view.h', 'browser/ui/views/extensions/extension_popup.cc', @@ -2147,8 +2150,6 @@ 'browser/ui/views/frame/system_menu_model_builder.h', 'browser/ui/views/frame/system_menu_model_delegate.cc', 'browser/ui/views/frame/system_menu_model_delegate.h', - 'browser/ui/views/frame/taskbar_decorator.cc', - 'browser/ui/views/frame/taskbar_decorator.h', 'browser/ui/views/frame/taskbar_decorator_win.cc', 'browser/ui/views/frame/top_container_view.cc', 'browser/ui/views/frame/top_container_view.h', @@ -2504,8 +2505,6 @@ 'browser/ui/webui/extensions/extension_error_ui_util.h', 'browser/ui/webui/extensions/extension_icon_source.cc', 'browser/ui/webui/extensions/extension_icon_source.h', - 'browser/ui/webui/extensions/pack_extension_handler.cc', - 'browser/ui/webui/extensions/pack_extension_handler.h', 'browser/ui/webui/voice_search_ui.cc', 'browser/ui/webui/voice_search_ui.h', ], @@ -2668,6 +2667,7 @@ '../components/components.gyp:device_event_log_component', '../components/components.gyp:dom_distiller_core', '../components/components.gyp:dom_distiller_webui', + '../components/components.gyp:feedback_proto', '../components/components.gyp:history_core_browser_proto', '../components/components.gyp:invalidation', '../components/components.gyp:onc_component', @@ -2852,16 +2852,33 @@ ['OS=="mac"', { 'conditions': [ ['mac_views_browser==1', { + 'sources': [ + 'browser/ui/views/apps/chrome_app_window_client_views_mac.mm', + ], 'sources!': [ + 'browser/ui/cocoa/apps/chrome_app_window_client_cocoa.mm', 'browser/ui/cocoa/bookmarks/bookmark_drag_drop_cocoa.mm', 'browser/ui/cocoa/browser_window_factory_cocoa.mm', 'browser/ui/cocoa/infobars/confirm_infobar_controller.mm', 'browser/ui/cocoa/tab_dialogs_cocoa.mm', ], + 'dependencies': [ + '<(DEPTH)/extensions/components/extensions_components.gyp:native_app_window', + ], }, { 'sources!': [ + 'browser/ui/views/apps/chrome_native_app_window_views.cc', + 'browser/ui/views/apps/chrome_native_app_window_views.h', + 'browser/ui/views/apps/desktop_keyboard_capture.cc', + 'browser/ui/views/apps/desktop_keyboard_capture.h', + 'browser/ui/views/apps/keyboard_hook_handler.cc', + 'browser/ui/views/apps/keyboard_hook_handler.h', 'browser/ui/views/bookmarks/bookmark_drag_drop_views.cc', + 'browser/ui/views/extensions/extension_keybinding_registry_views.cc', + 'browser/ui/views/extensions/extension_keybinding_registry_views.h', 'browser/ui/views/frame/browser_window_factory.cc', + 'browser/ui/views/frame/taskbar_decorator.cc', + 'browser/ui/views/frame/taskbar_decorator.h', 'browser/ui/views/infobar/confirm_infobar.cc' 'browser/ui/views/tab_dialogs_views.cc', ], @@ -2928,6 +2945,7 @@ 'chrome_browser_jni_headers', ], 'dependencies!': [ + '../components/components.gyp:feedback_proto', '../ui/events/events.gyp:events', 'chrome_browser_ui_views.gyp:browser_ui_views', ], @@ -3001,6 +3019,7 @@ ], 'sources': [ '<@(chrome_browser_ui_win_sources)' ], 'sources!': [ + 'browser/ui/views/apps/keyboard_hook_handler.cc', 'browser/ui/views/frame/taskbar_decorator.cc' ], 'conditions': [ @@ -3124,7 +3143,6 @@ }], ['OS!="android" and OS!="ios"', { 'dependencies': [ - '../components/components.gyp:feedback_proto', '../device/bluetooth/bluetooth.gyp:device_bluetooth', '../third_party/libusb/libusb.gyp:libusb', ],
diff --git a/chrome/chrome_common.gypi b/chrome/chrome_common.gypi index 0ecfd4f4..6a80c5b 100644 --- a/chrome/chrome_common.gypi +++ b/chrome/chrome_common.gypi
@@ -51,6 +51,8 @@ 'common/custom_handlers/protocol_handler.cc', 'common/custom_handlers/protocol_handler.h', 'common/descriptors_android.h', + 'common/favicon/fallback_icon_url_parser.cc', + 'common/favicon/fallback_icon_url_parser.h', 'common/favicon/favicon_url_parser.cc', 'common/favicon/favicon_url_parser.h', 'common/icon_with_badge_image_source.cc', @@ -317,6 +319,7 @@ '<(DEPTH)/crypto/crypto.gyp:crypto', '<(DEPTH)/net/net.gyp:net', '<(DEPTH)/skia/skia.gyp:skia', + '<(DEPTH)/skia/skia.gyp:skia_library', '<(DEPTH)/third_party/icu/icu.gyp:icui18n', '<(DEPTH)/third_party/icu/icu.gyp:icuuc', '<(DEPTH)/third_party/libxml/libxml.gyp:libxml',
diff --git a/chrome/chrome_tests.gypi b/chrome/chrome_tests.gypi index 015a219a..593f2e6f70 100644 --- a/chrome/chrome_tests.gypi +++ b/chrome/chrome_tests.gypi
@@ -657,6 +657,7 @@ 'browser/chromeos/login/enrollment/mock_enrollment_screen.cc', 'browser/chromeos/login/enrollment/mock_enrollment_screen.h', 'browser/chromeos/login/existing_user_controller_browsertest.cc', + 'browser/chromeos/login/hid_detection_browsertest.cc', 'browser/chromeos/login/kiosk_browsertest.cc', 'browser/chromeos/login/lock/screen_locker_tester.cc', 'browser/chromeos/login/lock/screen_locker_tester.h',
diff --git a/chrome/chrome_tests_unit.gypi b/chrome/chrome_tests_unit.gypi index e49743e..21b25630 100644 --- a/chrome/chrome_tests_unit.gypi +++ b/chrome/chrome_tests_unit.gypi
@@ -541,6 +541,7 @@ 'common/chrome_paths_unittest.cc', 'common/cloud_print/cloud_print_helpers_unittest.cc', 'common/crash_keys_unittest.cc', + 'common/favicon/fallback_icon_url_parser_unittest.cc', 'common/favicon/favicon_url_parser_unittest.cc', 'common/ini_parser_unittest.cc', 'common/instant_types_unittest.cc',
diff --git a/chrome/common/extensions/api/_permission_features.json b/chrome/common/extensions/api/_permission_features.json index c08ea657..902b803 100644 --- a/chrome/common/extensions/api/_permission_features.json +++ b/chrome/common/extensions/api/_permission_features.json
@@ -989,8 +989,7 @@ "extension_types": ["extension", "legacy_packaged_app", "hosted_app"], "whitelist": [ "B44D08FD98F1523ED5837D78D0A606EA9D6206E5", // Web Store - "2653F6F6C39BC6EEBD36A09AFB92A19782FF7EB4", // Enterprise Web Store - "2779FA8B45841D61A37207CCFAC9CB393964FE5B" // Login Proxy (prototype) + "2653F6F6C39BC6EEBD36A09AFB92A19782FF7EB4" // Enterprise Web Store ] } }
diff --git a/chrome/common/favicon/fallback_icon_url_parser.cc b/chrome/common/favicon/fallback_icon_url_parser.cc new file mode 100644 index 0000000..418617f --- /dev/null +++ b/chrome/common/favicon/fallback_icon_url_parser.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/common/favicon/fallback_icon_url_parser.h" + +#include "base/logging.h" +#include "base/strings/string_number_conversions.h" +#include "base/strings/string_split.h" +#include "third_party/skia/include/utils/SkParse.h" +#include "ui/gfx/favicon_size.h" + +namespace chrome { + +ParsedFallbackIconPath::ParsedFallbackIconPath() + : size_in_pixels_(gfx::kFaviconSize) { +} + +ParsedFallbackIconPath::~ParsedFallbackIconPath() { +} + +bool ParsedFallbackIconPath::Parse(const std::string& path) { + if (path.empty()) + return false; + + size_t slash = path.find("/", 0); + if (slash == std::string::npos) + return false; + std::string spec_str = path.substr(0, slash); + if (!ParseSpecs(spec_str, &size_in_pixels_, &style_)) + return false; // Parse failed. + + // Extract URL, which may be empty (if first slash appears at the end). + std::string url_str = path.substr(slash + 1); + url_ = GURL(url_str); + return url_str.empty() || url_.is_valid(); // Allow empty URL. +} + +// static +bool ParsedFallbackIconPath::ParseSpecs( + const std::string& specs_str, + int *size, + favicon_base::FallbackIconStyle* style) { + DCHECK(size); + DCHECK(style); + + std::vector<std::string> tokens; + base::SplitStringDontTrim(specs_str, ',', &tokens); + if (tokens.size() != 5) // Force "," for empty fields. + return false; + + *size = gfx::kFaviconSize; + if (!tokens[0].empty() && !base::StringToInt(tokens[0], size)) + return false; + if (*size <= 0) + return false; + + if (!tokens[1].empty() && !ParseColor(tokens[1], &style->background_color)) + return false; + + if (tokens[2].empty()) + favicon_base::MatchFallbackIconTextColorAgainstBackgroundColor(style); + else if (!ParseColor(tokens[2], &style->text_color)) + return false; + + if (!tokens[3].empty() && + !base::StringToDouble(tokens[3], &style->font_size_ratio)) + return false; + + if (!tokens[4].empty() && !base::StringToDouble(tokens[4], &style->roundness)) + return false; + + return favicon_base::ValidateFallbackIconStyle(*style); +} + +// static +bool ParsedFallbackIconPath::ParseColor(const std::string& color_str, + SkColor* color) { + const char* end = SkParse::FindColor(color_str.c_str(), color); + // Return true if FindColor() succeeds and |color_str| is entirely consumed. + return end && !*end; +} + +} // namespace chrome
diff --git a/chrome/common/favicon/fallback_icon_url_parser.h b/chrome/common/favicon/fallback_icon_url_parser.h new file mode 100644 index 0000000..12a068f4 --- /dev/null +++ b/chrome/common/favicon/fallback_icon_url_parser.h
@@ -0,0 +1,67 @@ +// 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_COMMON_FAVICON_FALLBACK_ICON_URL_PARSER_H_ +#define CHROME_COMMON_FAVICON_FALLBACK_ICON_URL_PARSER_H_ + +#include <string> + +#include "base/gtest_prod_util.h" +#include "base/macros.h" +#include "components/favicon_base/fallback_icon_style.h" +#include "third_party/skia/include/core/SkColor.h" +#include "url/gurl.h" + +namespace chrome { + +class ParsedFallbackIconPath { + public: + ParsedFallbackIconPath(); + ~ParsedFallbackIconPath(); + + const GURL& url() const { return url_; } + + int size_in_pixels() const { return size_in_pixels_; } + + const favicon_base::FallbackIconStyle& style() const { return style_; } + + // Parses |path|, which should be in the format described at the top of the + // file "chrome/browser/ui/webui/fallback_icon_source.h". + bool Parse(const std::string& path); + + private: + // Parses |specs_str|, which should be the comma-separated value portion + // in the format described at the top of the file + // "chrome/browser/ui/webui/fallback_icon_source.h". + static bool ParseSpecs(const std::string& specs_str, + int *size, + favicon_base::FallbackIconStyle* style); + + // Helper to parse color string (e.g., "red", "#f00", "#fF0000"). Returns true + // on success. + static bool ParseColor(const std::string& color_str, SkColor* color); + + friend class FallbackIconUrlParserTest; + FRIEND_TEST_ALL_PREFIXES(FallbackIconUrlParserTest, ParseColorSuccess); + FRIEND_TEST_ALL_PREFIXES(FallbackIconUrlParserTest, ParseColorFailure); + FRIEND_TEST_ALL_PREFIXES(FallbackIconUrlParserTest, ParseSpecsEmpty); + FRIEND_TEST_ALL_PREFIXES(FallbackIconUrlParserTest, ParseSpecsPartial); + FRIEND_TEST_ALL_PREFIXES(FallbackIconUrlParserTest, ParseSpecsFull); + FRIEND_TEST_ALL_PREFIXES(FallbackIconUrlParserTest, ParseSpecsFailure); + + // The page URL the fallback icon is requested for. + GURL url_; + + // The size of the requested fallback icon in pixels. + int size_in_pixels_; + + // Styling specifications of fallback icon. + favicon_base::FallbackIconStyle style_; + + DISALLOW_COPY_AND_ASSIGN(ParsedFallbackIconPath); +}; + +} // namespace chrome + +#endif // CHROME_COMMON_FAVICON_FALLBACK_ICON_URL_PARSER_H_
diff --git a/chrome/common/favicon/fallback_icon_url_parser_unittest.cc b/chrome/common/favicon/fallback_icon_url_parser_unittest.cc new file mode 100644 index 0000000..76a761c0 --- /dev/null +++ b/chrome/common/favicon/fallback_icon_url_parser_unittest.cc
@@ -0,0 +1,267 @@ +// 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/common/favicon/fallback_icon_url_parser.h" + +#include "base/memory/scoped_ptr.h" +#include "components/favicon_base/fallback_icon_style.h" +#include "testing/gtest/include/gtest/gtest.h" +#include "third_party/skia/include/core/SkColor.h" +#include "ui/gfx/favicon_size.h" +#include "url/gurl.h" + +using chrome::ParsedFallbackIconPath; +using favicon_base::FallbackIconStyle; + +namespace chrome { + +namespace { + +// Default values for FallbackIconStyle, from +// /components/favicon_base/fallback_icon_style.h +SkColor kDefaultBackgroundColor = SkColorSetRGB(0x80, 0x80, 0x80); +SkColor kDefaultTextColorDark = SK_ColorBLACK; +SkColor kDefaultTextColorLight = SK_ColorWHITE; +double kDefaultFontSizeRatio = 0.8; +double kDefaultRoundness = 0.125; // 1 / 8. + +const char kTestUrlStr[] = "https://www.google.ca/imghp?hl=en&tab=wi"; + +} // namespace + +class FallbackIconUrlParserTest : public testing::Test { + public: + FallbackIconUrlParserTest() { + } + + bool ParseSpecs(const std::string& specs_str, + int *size, + favicon_base::FallbackIconStyle* style) { + return ParsedFallbackIconPath::ParseSpecs(specs_str, size, style); + } + + bool ParseColor(const std::string& color_str, SkColor* color) { + int size_dummy; + favicon_base::FallbackIconStyle style; + std::string spec_str = "16," + color_str + ",,,"; + if (!ParseSpecs(spec_str, &size_dummy, &style)) + return false; + *color = style.background_color; + return true; + } + + private: + DISALLOW_COPY_AND_ASSIGN(FallbackIconUrlParserTest); +}; + +TEST_F(FallbackIconUrlParserTest, ParseColorSuccess) { + SkColor c; + EXPECT_TRUE(ParseColor("#01aBf0f4", &c)); + EXPECT_EQ(SkColorSetARGB(0x01, 0xAB, 0xF0, 0xF4), c); + EXPECT_TRUE(ParseColor("#01aBf0", &c)); + EXPECT_EQ(SkColorSetRGB(0x01, 0xAB, 0xF0), c); + EXPECT_TRUE(ParseColor("#01a", &c)); + EXPECT_EQ(SkColorSetRGB(0x00, 0x11, 0xAA), c); + EXPECT_TRUE(ParseColor("#000000", &c)); + EXPECT_EQ(SkColorSetARGB(0xFF, 0x00, 0x00, 0x00), c); + EXPECT_TRUE(ParseColor("red", &c)); + EXPECT_EQ(SkColorSetARGB(0xFF, 0xFF, 0x00, 0x00), c); +} + +TEST_F(FallbackIconUrlParserTest, ParseColorFailure) { + const char* test_cases[] = { + "#00000", + "#000000000", + " #000000", + "#ABCDEFG", + "000000", + "#000000 ", + }; + for (size_t i = 0; i < arraysize(test_cases); ++i) { + SkColor c; + EXPECT_FALSE(ParseColor(test_cases[i], &c)) + << "test_cases[" << i << "]"; + } +} + +TEST_F(FallbackIconUrlParserTest, ParseSpecsEmpty) { + int size; + FallbackIconStyle style; + EXPECT_TRUE(ParseSpecs(",,,,", &size, &style)); + EXPECT_EQ(16, size); + EXPECT_EQ(kDefaultBackgroundColor, style.background_color); + EXPECT_EQ(kDefaultTextColorLight, style.text_color); + EXPECT_EQ(kDefaultFontSizeRatio, style.font_size_ratio); + EXPECT_EQ(kDefaultRoundness, style.roundness); +} + +TEST_F(FallbackIconUrlParserTest, ParseSpecsPartial) { + int size; + FallbackIconStyle style; + EXPECT_TRUE(ParseSpecs(",,#aCE,,0.1", &size, &style)); + EXPECT_EQ(16, size); + EXPECT_EQ(kDefaultBackgroundColor, style.background_color); + EXPECT_EQ(SkColorSetRGB(0xAA, 0xCC, 0xEE), style.text_color); + EXPECT_EQ(kDefaultFontSizeRatio, style.font_size_ratio); + EXPECT_EQ(0.1, style.roundness); +} + +TEST_F(FallbackIconUrlParserTest, ParseSpecsFull) { + int size; + + { + FallbackIconStyle style; + EXPECT_TRUE(ParseSpecs("16,#000,#f01,0.75,0.25", &size, &style)); + EXPECT_EQ(16, size); + EXPECT_EQ(SkColorSetRGB(0x00, 0x00, 0x00), style.background_color); + EXPECT_EQ(SkColorSetRGB(0xff, 0x00, 0x11), style.text_color); + EXPECT_EQ(0.75, style.font_size_ratio); + EXPECT_EQ(0.25, style.roundness); + } + + { + FallbackIconStyle style; + EXPECT_TRUE(ParseSpecs("48,black,#123456,0.5,0.3", &size, &style)); + EXPECT_EQ(48, size); + EXPECT_EQ(SkColorSetRGB(0x00, 0x00, 0x00), style.background_color); + EXPECT_EQ(SkColorSetRGB(0x12, 0x34, 0x56), style.text_color); + EXPECT_EQ(0.5, style.font_size_ratio); + EXPECT_EQ(0.3, style.roundness); + } + + { + FallbackIconStyle style; + EXPECT_TRUE(ParseSpecs("1,#000,red,0,0", &size, &style)); + EXPECT_EQ(1, size); + EXPECT_EQ(SkColorSetRGB(0x00, 0x00, 0x00), style.background_color); + EXPECT_EQ(SkColorSetRGB(0xFF, 0x00, 0x00), style.text_color); + EXPECT_EQ(0, style.font_size_ratio); + EXPECT_EQ(0, style.roundness); + } +} + +TEST_F(FallbackIconUrlParserTest, ParseSpecsDefaultTextColor) { + int size; + + { + // Dark background -> Light text. + FallbackIconStyle style; + EXPECT_TRUE(ParseSpecs(",#000,,,", &size, &style)); + EXPECT_EQ(kDefaultTextColorLight, style.text_color); + } + + { + // Light background -> Dark text. + FallbackIconStyle style; + EXPECT_TRUE(ParseSpecs(",#fff,,,", &size, &style)); + EXPECT_EQ(kDefaultTextColorDark, style.text_color); + } + + { + // Light background -> Dark text, more params don't matter. + FallbackIconStyle style; + EXPECT_TRUE(ParseSpecs("107,#fff,,0.3,0.5", &size, &style)); + EXPECT_EQ(kDefaultTextColorDark, style.text_color); + } +} + +TEST_F(FallbackIconUrlParserTest, ParseSpecsFailure) { + const char* test_cases[] = { + // Need exactly 5 params. + "", + "16", + "16,black", + "16,black,#fff", + "16,black,#fff,0.75", + ",,," + ",,,,,", + "16,black,#fff,0.75,0.25,junk", + // Don't allow any space. + "16,black,#fff, 0.75,0.25", + "16,black ,#fff,0.75,0.25", + "16,black,#fff,0.75,0.25 ", + // Adding junk text. + "16,black,#fff,0.75,0.25junk", + "junk,black,#fff,0.75,0.25", + "16,#junk,#fff,0.75,0.25", + "16,black,#junk,0.75,0.25", + "16,black,#fff,junk,0.25", + "16,black,#fff,0.75,junk", + // Out of bound. + "0,black,#fff,0.75,0.25", // size. + "4294967296,black,#fff,0.75,0.25", // size. + "-1,black,#fff,0.75,0.25", // size. + "16,black,#fff,-0.1,0.25", // font_size_ratio. + "16,black,#fff,1.1,0.25", // font_size_ratio. + "16,black,#fff,0.75,-0.1", // roundness. + "16,black,#fff,0.75,1.1", // roundness. + }; + for (size_t i = 0; i < arraysize(test_cases); ++i) { + int size; + FallbackIconStyle style; + EXPECT_FALSE(ParseSpecs(test_cases[i], &size, &style)) + << "test_cases[" << i << "]"; + + } +} + +TEST_F(FallbackIconUrlParserTest, ParseFallbackIconPathSuccess) { + const std::string specs = "31,black,#fff,0.75,0.25"; + + // Everything populated. + { + chrome::ParsedFallbackIconPath parsed; + EXPECT_TRUE(parsed.Parse(specs + "/" + kTestUrlStr)); + EXPECT_EQ(GURL(kTestUrlStr), parsed.url()); + EXPECT_EQ(31, parsed.size_in_pixels()); + const favicon_base::FallbackIconStyle& style = parsed.style(); + EXPECT_EQ(SkColorSetRGB(0x00, 0x00, 0x00), style.background_color); + EXPECT_EQ(SkColorSetRGB(0xFF, 0xFF, 0xFF), style.text_color); + EXPECT_EQ(0.75, style.font_size_ratio); + EXPECT_EQ(0.25, style.roundness); + } + + // Empty URL. + { + chrome::ParsedFallbackIconPath parsed; + EXPECT_TRUE(parsed.Parse(specs + "/")); + EXPECT_EQ(GURL(), parsed.url()); + EXPECT_EQ(31, parsed.size_in_pixels()); + const favicon_base::FallbackIconStyle& style = parsed.style(); + EXPECT_EQ(SkColorSetRGB(0x00, 0x00, 0x00), style.background_color); + EXPECT_EQ(SkColorSetRGB(0xFF, 0xFF, 0xFF), style.text_color); + EXPECT_EQ(0.75, style.font_size_ratio); + EXPECT_EQ(0.25, style.roundness); + } + + // Size and style are default. + { + chrome::ParsedFallbackIconPath parsed; + EXPECT_TRUE(parsed.Parse(std::string(",,,,/") + kTestUrlStr)); + EXPECT_EQ(GURL(kTestUrlStr), parsed.url()); + EXPECT_EQ(gfx::kFaviconSize, parsed.size_in_pixels()); + const favicon_base::FallbackIconStyle& style = parsed.style(); + EXPECT_EQ(kDefaultBackgroundColor, style.background_color); + EXPECT_EQ(kDefaultTextColorLight, style.text_color); + EXPECT_EQ(kDefaultFontSizeRatio, style.font_size_ratio); + EXPECT_EQ(kDefaultRoundness, style.roundness); + } +} + +TEST_F(FallbackIconUrlParserTest, ParseFallbackIconPathFailure) { + const char* test_cases[] = { + // Bad size. + "-1,#000,#fff,0.75,0.25/http://www.google.com/", + // Bad specs. + "32,#junk,#fff,0.75,0.25/http://www.google.com/", + // Bad URL. + "32,#000,#fff,0.75,0.25/NOT A VALID URL", + }; + for (size_t i = 0; i < arraysize(test_cases); ++i) { + chrome::ParsedFallbackIconPath parsed; + EXPECT_FALSE(parsed.Parse(test_cases[i])) << "test_cases[" << i << "]"; + } +} + +} // namespace chrome
diff --git a/chrome/common/pref_names.cc b/chrome/common/pref_names.cc index 518c0ae3..46cc10ae 100644 --- a/chrome/common/pref_names.cc +++ b/chrome/common/pref_names.cc
@@ -361,14 +361,6 @@ // window when the user is attempting to quit. Mac only. const char kConfirmToQuitEnabled[] = "browser.confirm_to_quit"; -// OBSOLETE. Enum that specifies whether to enforce a third-party cookie -// blocking policy. This has been superseded by kDefaultContentSettings + -// kBlockThirdPartyCookies. -// 0 - allow all cookies. -// 1 - block third-party cookies -// 2 - block all cookies -const char kCookieBehavior[] = "security.cookie_behavior"; - // Boolean which specifies whether we should ask the user if we should download // a file (true) or just download it automatically. const char kPromptForDownload[] = "download.prompt_for_download"; @@ -376,18 +368,10 @@ // A boolean pref set to true if we're using Link Doctor error pages. const char kAlternateErrorPagesEnabled[] = "alternate_error_pages.enabled"; -// OBSOLETE: new pref now stored with user prefs instead of profile, as -// kDnsPrefetchingStartupList. -const char kDnsStartupPrefetchList[] = "StartupDNSPrefetchList"; - // An adaptively identified list of domain names to be pre-fetched during the // next startup, based on what was actually needed during this startup. const char kDnsPrefetchingStartupList[] = "dns_prefetching.startup_list"; -// OBSOLETE: new pref now stored with user prefs instead of profile, as -// kDnsPrefetchingHostReferralList. -const char kDnsHostReferralList[] = "HostReferralList"; - // A list of host names used to fetch web pages, and their commonly used // sub-resource hostnames (and expected latency benefits from pre-resolving, or // preconnecting to, such sub-resource hostnames). @@ -421,16 +405,6 @@ const char kInstantUIZeroSuggestUrlPrefix[] = "instant_ui.zero_suggest_url_prefix"; -// Used to migrate preferences from local state to user preferences to -// enable multiple profiles. -// BITMASK with possible values (see browser_prefs.cc for enum): -// 0: No preferences migrated. -// 1: DNS preferences migrated: kDnsPrefetchingStartupList and HostReferralList -// 2: Browser window preferences migrated: kDevToolsSplitLocation and -// kBrowserWindowPlacement -const char kMultipleProfilePrefMigration[] = - "local_state.multiple_profile_prefs_version"; - // A boolean pref set to true if prediction of network actions is allowed. // Actions include DNS prefetching, TCP and SSL preconnection, prerendering // of web pages, and resource prefetching.
diff --git a/chrome/common/pref_names.h b/chrome/common/pref_names.h index 29875f2..379cfbd 100644 --- a/chrome/common/pref_names.h +++ b/chrome/common/pref_names.h
@@ -149,12 +149,9 @@ extern const char kContextualSearchEnabled[]; #endif extern const char kConfirmToQuitEnabled[]; -extern const char kCookieBehavior[]; // OBSOLETE extern const char kPromptForDownload[]; extern const char kAlternateErrorPagesEnabled[]; -extern const char kDnsStartupPrefetchList[]; // OBSOLETE extern const char kDnsPrefetchingStartupList[]; -extern const char kDnsHostReferralList[]; // OBSOLETE extern const char kDnsPrefetchingHostReferralList[]; extern const char kDisableSpdy[]; extern const char kHttpServerProperties[]; @@ -165,7 +162,6 @@ extern const char kLastPolicyCheckTime[]; #endif extern const char kInstantUIZeroSuggestUrlPrefix[]; -extern const char kMultipleProfilePrefMigration[]; extern const char kNetworkPredictionEnabled[]; extern const char kNetworkPredictionOptions[]; extern const char kDefaultAppsInstallState[];
diff --git a/chrome/installer/util/google_update_settings.cc b/chrome/installer/util/google_update_settings.cc index 7b2fbc3..b3467bc2 100644 --- a/chrome/installer/util/google_update_settings.cc +++ b/chrome/installer/util/google_update_settings.cc
@@ -5,6 +5,7 @@ #include "chrome/installer/util/google_update_settings.h" #include <algorithm> +#include <limits> #include "base/command_line.h" #include "base/files/file_path.h" @@ -70,7 +71,7 @@ bool WriteGoogleUpdateAggregateNumKeyInternal( const AppRegistrationData& app_reg_data, const wchar_t* const name, - int value, + size_t value, const wchar_t* const aggregate) { DCHECK(aggregate); DCHECK(GoogleUpdateSettings::IsSystemInstall()); @@ -90,7 +91,11 @@ reg_path.append(name); RegKey key(HKEY_LOCAL_MACHINE, reg_path.c_str(), kAccess); key.WriteValue(google_update::kRegAggregateMethod, aggregate); - return (key.WriteValue(uniquename.c_str(), value) == ERROR_SUCCESS); + + DWORD dword_value = (value > std::numeric_limits<DWORD>::max() ? + std::numeric_limits<DWORD>::max() : + static_cast<DWORD>(value)); + return (key.WriteValue(uniquename.c_str(), dword_value) == ERROR_SUCCESS); } // Updates a registry key |name| to be |value| for the given |app_reg_data|. @@ -546,8 +551,8 @@ return modified; } -void GoogleUpdateSettings::UpdateProfileCounts(int profiles_active, - int profiles_signedin) { +void GoogleUpdateSettings::UpdateProfileCounts(size_t profiles_active, + size_t profiles_signedin) { BrowserDistribution* dist = BrowserDistribution::GetDistribution(); // System-level installs must write into the ClientStateMedium key shared by // all users. Special treatment is used to aggregate across those users. @@ -569,10 +574,10 @@ // user-level installs. WriteGoogleUpdateStrKeyInternal(dist->GetAppRegistrationData(), google_update::kRegProfilesActive, - base::IntToString16(profiles_active)); + base::SizeTToString16(profiles_active)); WriteGoogleUpdateStrKeyInternal(dist->GetAppRegistrationData(), google_update::kRegProfilesSignedIn, - base::IntToString16(profiles_signedin)); + base::SizeTToString16(profiles_signedin)); } }
diff --git a/chrome/installer/util/google_update_settings.h b/chrome/installer/util/google_update_settings.h index ea5a7d58..e3a0168 100644 --- a/chrome/installer/util/google_update_settings.h +++ b/chrome/installer/util/google_update_settings.h
@@ -218,7 +218,8 @@ // This method updates the values that report how many profiles are in use // and how many of those are signed-in. - static void UpdateProfileCounts(int profiles_active, int profiles_signedin); + static void UpdateProfileCounts(size_t profiles_active, + size_t profiles_signedin); // For system-level installs, we need to be able to communicate the results // of the Toast Experiments back to Google Update. The problem is just that
diff --git a/chrome/renderer/autofill/autofill_renderer_browsertest.cc b/chrome/renderer/autofill/autofill_renderer_browsertest.cc index 26840bb..49a83665 100644 --- a/chrome/renderer/autofill/autofill_renderer_browsertest.cc +++ b/chrome/renderer/autofill/autofill_renderer_browsertest.cc
@@ -250,7 +250,7 @@ // Shouldn't crash. } -TEST_F(AutofillRendererTest, DISABLED_DynamicallyAddedUnownedFormElements) { +TEST_F(AutofillRendererTest, DynamicallyAddedUnownedFormElements) { std::string html_data; base::FilePath test_path = ui_test_utils::GetTestFilePath( base::FilePath(FILE_PATH_LITERAL("autofill")),
diff --git a/chrome/renderer/autofill/form_autofill_browsertest.cc b/chrome/renderer/autofill/form_autofill_browsertest.cc index a447229..24b5f05c 100644 --- a/chrome/renderer/autofill/form_autofill_browsertest.cc +++ b/chrome/renderer/autofill/form_autofill_browsertest.cc
@@ -2393,7 +2393,7 @@ false); } -TEST_F(FormAutofillTest, DISABLED_FindFormForInputElementForUnownedForm) { +TEST_F(FormAutofillTest, FindFormForInputElementForUnownedForm) { TestFindFormForInputElement( "<INPUT type='text' id='firstname' value='John'/>" "<INPUT type='text' id='lastname' value='Smith'/>" @@ -2420,7 +2420,7 @@ false); } -TEST_F(FormAutofillTest, DISABLED_FindFormForTextAreaElementForUnownedForm) { +TEST_F(FormAutofillTest, FindFormForTextAreaElementForUnownedForm) { TestFindFormForTextAreaElement( "<INPUT type='text' id='firstname' value='John'/>" "<INPUT type='text' id='lastname' value='Smith'/>" @@ -2439,7 +2439,7 @@ TestFillForm(kFormHtml, false); } -TEST_F(FormAutofillTest, DISABLED_FillFormForUnownedForm) { +TEST_F(FormAutofillTest, FillFormForUnownedForm) { TestFillForm(kUnownedFormHtml, true); } @@ -2531,7 +2531,7 @@ TestPreviewForm(kFormHtml, false); } -TEST_F(FormAutofillTest, DISABLED_PreviewFormForUnownedForm) { +TEST_F(FormAutofillTest, PreviewFormForUnownedForm) { TestPreviewForm(kUnownedFormHtml, true); } @@ -3406,7 +3406,7 @@ false); } -TEST_F(FormAutofillTest, DISABLED_FillFormMaxLengthForUnownedForm) { +TEST_F(FormAutofillTest, FillFormMaxLengthForUnownedForm) { TestFillFormMaxLength( "<INPUT type='text' id='firstname' maxlength='5'/>" "<INPUT type='text' id='lastname' maxlength='7'/>" @@ -3429,7 +3429,7 @@ false); } -TEST_F(FormAutofillTest, DISABLED_FillFormNegativeMaxLengthForUnownedForm) { +TEST_F(FormAutofillTest, FillFormNegativeMaxLengthForUnownedForm) { TestFillFormNegativeMaxLength( "<INPUT type='text' id='firstname' maxlength='-1'/>" "<INPUT type='text' id='lastname' maxlength='-10'/>" @@ -3449,7 +3449,7 @@ false); } -TEST_F(FormAutofillTest, DISABLED_FillFormEmptyNameForUnownedForm) { +TEST_F(FormAutofillTest, FillFormEmptyNameForUnownedForm) { TestFillFormEmptyName( "<INPUT type='text' id='firstname'/>" "<INPUT type='text' id='lastname'/>" @@ -3475,7 +3475,7 @@ false); } -TEST_F(FormAutofillTest, DISABLED_FillFormEmptyFormNamesForUnownedForm) { +TEST_F(FormAutofillTest, FillFormEmptyFormNamesForUnownedForm) { TestFillFormEmptyFormNames( "<INPUT type='text' id='firstname'/>" "<INPUT type='text' id='middlename'/>" @@ -3631,7 +3631,7 @@ false); } -TEST_F(FormAutofillTest, DISABLED_FillFormNonEmptyFieldForUnownedForm) { +TEST_F(FormAutofillTest, FillFormNonEmptyFieldForUnownedForm) { TestFillFormNonEmptyField("<INPUT type='text' id='firstname'/>" "<INPUT type='text' id='lastname'/>" "<INPUT type='text' id='email'/>" @@ -3659,7 +3659,7 @@ false); } -TEST_F(FormAutofillTest, DISABLED_ClearFormWithNodeForUnownedForm) { +TEST_F(FormAutofillTest, ClearFormWithNodeForUnownedForm) { TestClearFormWithNode( " <!-- Indented on purpose //-->" " <INPUT type='text' id='firstname' value='Wyatt'/>" @@ -3694,8 +3694,7 @@ false); } -TEST_F(FormAutofillTest, - DISABLED_ClearFormWithNodeContainingSelectOneForUnownedForm) { +TEST_F(FormAutofillTest, ClearFormWithNodeContainingSelectOneForUnownedForm) { TestClearFormWithNodeContainingSelectOne( "<INPUT type='text' id='firstname' value='Wyatt'/>" "<INPUT type='text' id='lastname' value='Earp'/>" @@ -3721,7 +3720,7 @@ "</FORM>"); } -TEST_F(FormAutofillTest, DISABLED_ClearPreviewedFormWithElementForUnownedForm) { +TEST_F(FormAutofillTest, ClearPreviewedFormWithElementForUnownedForm) { TestClearPreviewedFormWithElement( "<INPUT type='text' id='firstname' value='Wyatt'/>" "<INPUT type='text' id='lastname'/>" @@ -3744,7 +3743,7 @@ } TEST_F(FormAutofillTest, - DISABLED_ClearPreviewedFormWithNonEmptyInitiatingNodeForUnownedForm) { + ClearPreviewedFormWithNonEmptyInitiatingNodeForUnownedForm) { TestClearPreviewedFormWithNonEmptyInitiatingNode( "<INPUT type='text' id='firstname' value='W'/>" "<INPUT type='text' id='lastname'/>" @@ -3767,7 +3766,7 @@ } TEST_F(FormAutofillTest, - DISABLED_ClearPreviewedFormWithAutofilledInitiatingNodeForUnownedForm) { + ClearPreviewedFormWithAutofilledInitiatingNodeForUnownedForm) { TestClearPreviewedFormWithAutofilledInitiatingNode( "<INPUT type='text' id='firstname' value='W'/>" "<INPUT type='text' id='lastname'/>" @@ -3789,7 +3788,7 @@ "</FORM>"); } -TEST_F(FormAutofillTest, DISABLED_ClearOnlyAutofilledFieldsForUnownedForm) { +TEST_F(FormAutofillTest, ClearOnlyAutofilledFieldsForUnownedForm) { TestClearOnlyAutofilledFields( "<INPUT type='text' id='firstname' value='Wyatt'/>" "<INPUT type='text' id='lastname' value='Earp'/>" @@ -3948,7 +3947,7 @@ } TEST_F(FormAutofillTest, - DISABLED_UnownedFormElementsAndFieldSetsToFormDataFieldsets) { + UnownedFormElementsAndFieldSetsToFormDataFieldsets) { std::vector<WebElement> fieldsets; std::vector<WebFormControlElement> control_elements; @@ -4010,7 +4009,7 @@ } TEST_F(FormAutofillTest, - DISABLED_UnownedFormElementsAndFieldSetsToFormDataControlOutsideOfFieldset) { + UnownedFormElementsAndFieldSetsToFormDataControlOutsideOfFieldset) { std::vector<WebElement> fieldsets; std::vector<WebFormControlElement> control_elements; @@ -4069,8 +4068,7 @@ EXPECT_FORM_FIELD_DATA_EQUALS(expected, fields[2]); } -TEST_F(FormAutofillTest, - DISABLED_UnownedFormElementsAndFieldSetsToFormDataWithForm) { +TEST_F(FormAutofillTest, UnownedFormElementsAndFieldSetsToFormDataWithForm) { std::vector<WebElement> fieldsets; std::vector<WebFormControlElement> control_elements;
diff --git a/chrome/renderer/resources/neterror.css b/chrome/renderer/resources/neterror.css index e93543c..a630a5a1 100644 --- a/chrome/renderer/resources/neterror.css +++ b/chrome/renderer/resources/neterror.css
@@ -58,6 +58,10 @@ position: relative; } +.error-code { + display: block; +} + #content-top { margin: 20px; } @@ -130,6 +134,12 @@ margin: auto; } +.secondary-button { + -webkit-margin-end: 16px; + background: #d9d9d9; + color: #696969; +} + .hidden { display: none; } @@ -147,12 +157,6 @@ color: #777; } -.error-code { - color: #A0A0A0; - font-size: .825em; - margin-top: 15px; -} - /* Increase line height at higher resolutions. */ @media (min-width: 641px) and (min-height: 641px) { #help-box-inner { @@ -240,26 +244,28 @@ /* details-button is special; it's a <button> element that looks like a link. */ #details-button { - background-color: inherit; - background-image: none; - border: none; box-shadow: none; min-width: 0; - padding: 0; - text-decoration: underline; } /* Styles for platform dependent separation of controls and details button. */ .suggested-left > #control-buttons, -.suggested-right > #details-button { +.suggested-left #stale-load-button, +.suggested-right > #details-button { float: left; } .suggested-right > #control-buttons, -.suggested-left > #details-button { +.suggested-right #stale-load-button, +.suggested-left > #details-button { float: right; } +.suggested-left .secondary-button { + -webkit-margin-end: 0px; + -webkit-margin-start: 16px; +} + #details-button.singular { float: none; }
diff --git a/chrome/renderer/resources/neterror.html b/chrome/renderer/resources/neterror.html index d397f4a4..bf1f1b47 100644 --- a/chrome/renderer/resources/neterror.html +++ b/chrome/renderer/resources/neterror.html
@@ -19,6 +19,7 @@ <div id="main-message"> <h1 i18n-content="heading"></h1> <p hidden></p> + <div class="error-code" jscontent="errorCode"></div> </div> </div> <div id="buttons" class="nav-wrapper"> @@ -66,7 +67,6 @@ </button> </div> </form> - <div class="error-code" jscontent="errorCode"></div> </div> </div> <div id="sub-frame-error">
diff --git a/chrome/renderer/resources/neterror.js b/chrome/renderer/resources/neterror.js index 5929643..cee640f 100644 --- a/chrome/renderer/resources/neterror.js +++ b/chrome/renderer/resources/neterror.js
@@ -12,8 +12,13 @@ detailsButton.innerText = detailsButton.hideDetailsText; // Details appears over the main content on small screens. - if (mobileNav) + if (mobileNav) { document.getElementById('main-content').classList.toggle('hidden'); + var runnerContainer = document.querySelector('.runner-container'); + if (runnerContainer) { + runnerContainer.classList.toggle('hidden'); + } + } } function diagnoseErrors() { @@ -142,7 +147,6 @@ if (loadTimeData.valueExists('summary') && !loadTimeData.getValue('summary').msg) { detailsButton.style.display = 'none'; - document.getElementById('details').style.display = 'block'; } </if>
diff --git a/chrome/renderer/resources/offline.js b/chrome/renderer/resources/offline.js index fbf46d9..75404cc 100644 --- a/chrome/renderer/resources/offline.js +++ b/chrome/renderer/resources/offline.js
@@ -793,6 +793,11 @@ // our canvas element. context.scale(ratio, ratio); return true; + } else if (devicePixelRatio == 1) { + // Reset the canvas width / height. Fixes scaling bug when the page is + // zoomed and the devicePixelRatio changes accordingly. + canvas.style.width = canvas.width + 'px'; + canvas.style.height = canvas.height + 'px'; } return false; };
diff --git a/chrome/test/BUILD.gn b/chrome/test/BUILD.gn index 7082051..8341315 100644 --- a/chrome/test/BUILD.gn +++ b/chrome/test/BUILD.gn
@@ -215,7 +215,7 @@ ] } -if (!is_android && (!is_win || link_chrome_on_windows)) { +if (!is_android) { import("//chrome/chrome_tests.gni") test("interactive_ui_tests") {
diff --git a/chrome/test/data/extensions/api_test/bindings/api_enums/background.js b/chrome/test/data/extensions/api_test/bindings/api_enums/background.js new file mode 100644 index 0000000..c795e4e --- /dev/null +++ b/chrome/test/data/extensions/api_test/bindings/api_enums/background.js
@@ -0,0 +1,40 @@ +// 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. + +chrome.test.runTests([ + function() { + // Test management (backed by a json file) api enums. + + // The enum should be declared on the API object. + chrome.test.assertTrue( + 'LaunchType' in chrome.management, + '"LaunchType" is not present on chrome.management.'); + // The object should have entries for each enum entry. Note that we don't + // test all entries here because we don't want to update this test if the + // management api changes. + chrome.test.assertTrue( + 'OPEN_AS_REGULAR_TAB' in chrome.management.LaunchType, + '"OPEN_AS_REGULAR_TAB" is not present on management.LaunchType'); + // The value of the enum should be its string value. + chrome.test.assertEq(chrome.management.LaunchType.OPEN_AS_REGULAR_TAB, + 'OPEN_AS_REGULAR_TAB'); + // There should be more than one value for the enum. + chrome.test.assertTrue( + Object.keys(chrome.management.LaunchType).length > 1); + + // Perform an analogous test for the notifications api (backed by an idl). + chrome.test.assertTrue( + 'PermissionLevel' in chrome.notifications, + '"PermissionLevel" is not present on chrome.notifications.'); + chrome.test.assertTrue( + 'granted' in chrome.notifications.PermissionLevel, + '"granted" is not present on notifications.PermissionLevel'); + chrome.test.assertEq(chrome.notifications.PermissionLevel.granted, + 'granted'); + chrome.test.assertTrue( + Object.keys(chrome.notifications.PermissionLevel).length > 1); + + chrome.test.succeed(); + } +]);
diff --git a/chrome/test/data/extensions/api_test/bindings/api_enums/manifest.json b/chrome/test/data/extensions/api_test/bindings/api_enums/manifest.json new file mode 100644 index 0000000..49c3850 --- /dev/null +++ b/chrome/test/data/extensions/api_test/bindings/api_enums/manifest.json
@@ -0,0 +1,9 @@ +{ + "name": "bindings/api_enums", + "manifest_version": 2, + "version": "1", + "background": { + "scripts": ["background.js"] + }, + "permissions": ["management", "notifications"] +}
diff --git a/chrome/test/data/extensions/platform_apps/custom_launcher_page/main.html b/chrome/test/data/extensions/platform_apps/custom_launcher_page/main.html index 8060cb2..f7d49cd 100644 --- a/chrome/test/data/extensions/platform_apps/custom_launcher_page/main.html +++ b/chrome/test/data/extensions/platform_apps/custom_launcher_page/main.html
@@ -6,6 +6,7 @@ <html> <body> +<input id="textfield" type="text"> <script src="main.js"></script> </body> </html>
diff --git a/chrome/test/data/extensions/platform_apps/custom_launcher_page/main.js b/chrome/test/data/extensions/platform_apps/custom_launcher_page/main.js index bd16ca6..ce4fdc07 100644 --- a/chrome/test/data/extensions/platform_apps/custom_launcher_page/main.js +++ b/chrome/test/data/extensions/platform_apps/custom_launcher_page/main.js
@@ -31,4 +31,15 @@ }); } -chrome.test.sendMessage('Launched'); +document.addEventListener('DOMContentLoaded', function() { + chrome.test.sendMessage('Launched'); +}); + +var textfield = document.getElementById('textfield'); +textfield.onfocus = function() { + chrome.test.sendMessage('textfieldFocused'); +}; + +textfield.onblur = function() { + chrome.test.sendMessage('textfieldBlurred'); +};
diff --git a/chrome/test/data/notifications/android_test_worker.js b/chrome/test/data/notifications/android_test_worker.js index 421494a..f2a2de5 100644 --- a/chrome/test/data/notifications/android_test_worker.js +++ b/chrome/test/data/notifications/android_test_worker.js
@@ -8,3 +8,7 @@ messagePort = event.data; messagePort.postMessage('ready'); }); + +addEventListener('notificationclick', function(event) { + event.notification.close(); +});
diff --git a/chromecast/media/cma/filters/cma_renderer.cc b/chromecast/media/cma/filters/cma_renderer.cc index 799dd61..a8a46f5 100644 --- a/chromecast/media/cma/filters/cma_renderer.cc +++ b/chromecast/media/cma/filters/cma_renderer.cc
@@ -75,7 +75,8 @@ const ::media::BufferingStateCB& buffering_state_cb, const PaintCB& paint_cb, const base::Closure& ended_cb, - const ::media::PipelineStatusCB& error_cb) { + const ::media::PipelineStatusCB& error_cb, + const base::Closure& waiting_for_decryption_key_cb) { CMALOG(kLogControl) << __FUNCTION__; DCHECK(thread_checker_.CalledOnValidThread()); DCHECK_EQ(state_, kUninitialized) << state_; @@ -84,6 +85,7 @@ DCHECK(!ended_cb.is_null()); DCHECK(!error_cb.is_null()); DCHECK(!buffering_state_cb.is_null()); + DCHECK(!waiting_for_decryption_key_cb.is_null()); DCHECK(demuxer_stream_provider->GetStream(::media::DemuxerStream::AUDIO) || demuxer_stream_provider->GetStream(::media::DemuxerStream::VIDEO)); @@ -95,6 +97,8 @@ paint_cb_ = paint_cb; ended_cb_ = ended_cb; error_cb_ = error_cb; + // TODO(erickung): wire up waiting_for_decryption_key_cb. + waiting_for_decryption_key_cb_ = waiting_for_decryption_key_cb; MediaPipelineClient media_pipeline_client; media_pipeline_client.error_cb = error_cb_;
diff --git a/chromecast/media/cma/filters/cma_renderer.h b/chromecast/media/cma/filters/cma_renderer.h index 33fc2b1..62efd7c 100644 --- a/chromecast/media/cma/filters/cma_renderer.h +++ b/chromecast/media/cma/filters/cma_renderer.h
@@ -45,7 +45,8 @@ const ::media::BufferingStateCB& buffering_state_cb, const PaintCB& paint_cb, const base::Closure& ended_cb, - const ::media::PipelineStatusCB& error_cb) override; + const ::media::PipelineStatusCB& error_cb, + const base::Closure& waiting_for_decryption_key_cb) override; void Flush(const base::Closure& flush_cb) override; void StartPlayingFrom(base::TimeDelta time) override; void SetPlaybackRate(float playback_rate) override; @@ -108,6 +109,7 @@ ::media::PipelineStatusCB error_cb_; ::media::BufferingStateCB buffering_state_cb_; base::Closure flush_cb_; + base::Closure waiting_for_decryption_key_cb_; // Renderer state. // Used mostly for checking that transitions are correct.
diff --git a/chromeos/CHROMEOS_LKGM b/chromeos/CHROMEOS_LKGM index 6297834..c5ff1e2 100644 --- a/chromeos/CHROMEOS_LKGM +++ b/chromeos/CHROMEOS_LKGM
@@ -1 +1 @@ -6835.0.0 \ No newline at end of file +6836.0.0 \ No newline at end of file
diff --git a/chromeos/chromeos_switches.cc b/chromeos/chromeos_switches.cc index 9549971..3c945b1 100644 --- a/chromeos/chromeos_switches.cc +++ b/chromeos/chromeos_switches.cc
@@ -261,6 +261,7 @@ // Overrides network stub behavior. By default, ethernet, wifi and vpn are // enabled, and transitions occur instantaneously. Multiple options can be // comma separated (no spaces). Note: all options are in the format 'foo=x'. +// Values are case sensitive and based on Shill names in service_constants.h. // See FakeShillManagerClient::SetInitialNetworkState for implementation. // Examples: // 'clear=1' - Clears all default configurations @@ -270,6 +271,7 @@ // 'wifi=none' - Wifi is unavailable // 'wifi=portal' - Wifi connection will be in Portal state // 'cellular=1' - Cellular is initially connected +// 'cellular=LTE' - Cellular is initially connected, technology is LTE // 'interactive=3' - Interactive mode, connect/scan/etc requests take 3 secs const char kShillStub[] = "shill-stub";
diff --git a/chromeos/dbus/fake_shill_manager_client.cc b/chromeos/dbus/fake_shill_manager_client.cc index 72dedef..2702ad9 100644 --- a/chromeos/dbus/fake_shill_manager_client.cc +++ b/chromeos/dbus/fake_shill_manager_client.cc
@@ -105,6 +105,19 @@ base::StringValue(shill::kStatePortal)); } +bool IsCellularTechnology(const std::string& type) { + return (type == shill::kNetworkTechnology1Xrtt || + type == shill::kNetworkTechnologyEvdo || + type == shill::kNetworkTechnologyGsm || + type == shill::kNetworkTechnologyGprs || + type == shill::kNetworkTechnologyEdge || + type == shill::kNetworkTechnologyUmts || + type == shill::kNetworkTechnologyHspa || + type == shill::kNetworkTechnologyHspaPlus || + type == shill::kNetworkTechnologyLte || + type == shill::kNetworkTechnologyLteAdvanced); +} + const char* kTechnologyUnavailable = "unavailable"; const char* kNetworkActivated = "activated"; const char* kNetworkDisabled = "disabled"; @@ -118,6 +131,7 @@ FakeShillManagerClient::FakeShillManagerClient() : interactive_delay_(0), + cellular_technology_(shill::kNetworkTechnologyGsm), weak_ptr_factory_(this) { ParseCommandLineSwitch(); } @@ -776,7 +790,7 @@ shill::kTypeCellular, state, add_to_visible); - base::StringValue technology_value(shill::kNetworkTechnologyGsm); + base::StringValue technology_value(cellular_technology_); devices->SetDeviceProperty("/device/cellular1", shill::kTechnologyFamilyProperty, technology_value); @@ -1066,7 +1080,6 @@ bool FakeShillManagerClient::SetInitialNetworkState(std::string type_arg, std::string state_arg) { std::string state; - state_arg = base::StringToLowerASCII(state_arg); if (state_arg.empty() || state_arg == "1" || state_arg == "on" || state_arg == "enabled" || state_arg == "connected" || state_arg == "online") { @@ -1088,12 +1101,20 @@ } else if (state_arg == "active" || state_arg == "activated") { // Technology is enabled, a service is connected and Activated. state = kNetworkActivated; + } else if (type_arg == shill::kTypeCellular && + IsCellularTechnology(state_arg)) { + state = shill::kStateOnline; + cellular_technology_ = state_arg; + } else if (type_arg == shill::kTypeCellular && state_arg == "LTEAdvanced") { + // Special case, Shill name contains a ' '. + state = shill::kStateOnline; + cellular_technology_ = shill::kNetworkTechnologyLteAdvanced; } else { - LOG(ERROR) << "Unrecognized initial state: " << state_arg; + LOG(ERROR) << "Unrecognized initial state: " << type_arg << "=" + << state_arg; return false; } - type_arg = base::StringToLowerASCII(type_arg); // Special cases if (type_arg == "wireless") { shill_initial_state_map_[shill::kTypeWifi] = state;
diff --git a/chromeos/dbus/fake_shill_manager_client.h b/chromeos/dbus/fake_shill_manager_client.h index b21b2a1..61d1809 100644 --- a/chromeos/dbus/fake_shill_manager_client.h +++ b/chromeos/dbus/fake_shill_manager_client.h
@@ -142,6 +142,9 @@ // Initial state for fake services. std::map<std::string, std::string> shill_initial_state_map_; + // Technology type for fake cellular service. + std::string cellular_technology_; + // Roaming state for fake cellular service. std::string roaming_state_;
diff --git a/components/BUILD.gn b/components/BUILD.gn index 95b02c9..39548d7a 100644 --- a/components/BUILD.gn +++ b/components/BUILD.gn
@@ -40,6 +40,7 @@ "//components/enhanced_bookmarks", "//components/favicon/core", "//components/favicon_base", + "//components/feedback", "//components/gcm_driver", "//components/google/core/browser", "//components/history/content/browser", @@ -161,6 +162,7 @@ "//components/domain_reliability", # Blocked on content. "//components/favicon_base", # Should work, needs checking. "//components/favicon/core", # Blocked on keyed service. + "//components/feedback", # Blocked on content. "//components/gcm_driver", # Should work, needs checking. "//components/google/core/browser", # Should work, needs checking. "//components/history/core/browser", # Should work, needs checking. @@ -202,7 +204,6 @@ if (!is_ios && !is_android) { deps += [ "//components/copresence", - "//components/feedback", "//components/storage_monitor", ] } @@ -220,89 +221,87 @@ # component (it's important to use a source_set instead of a static library or # no tests will run) and add a reference here. You can add more than one unit # test target if convenient. -if (!is_win || link_chrome_on_windows) { - test("components_unittests") { - sources = [ - "test/run_all_unittests.cc", - ] +test("components_unittests") { + sources = [ + "test/run_all_unittests.cc", + ] - # Add only ":unit_tests" dependencies here. If your tests have dependencies - # (this would at least include the component itself), they should be on the - # test source set and not here. - deps = [ - "//components/auto_login_parser:unit_tests", - "//components/autofill/content/browser:unit_tests", - "//components/autofill/core/browser:unit_tests", - "//components/autofill/core/common:unit_tests", - "//components/bookmarks/browser:unit_tests", - "//components/captive_portal:unit_tests", - "//components/cloud_devices/common:unit_tests", - "//components/content_settings/core/browser:unit_tests", - "//components/content_settings/core/common:unit_tests", - "//components/crx_file:unit_tests", - "//components/data_reduction_proxy/core/browser:unit_tests", - "//components/data_reduction_proxy/core/common:unit_tests", - "//components/device_event_log:unit_tests", - "//components/dom_distiller/core:unit_tests", - "//components/domain_reliability:unit_tests", - "//components/favicon_base:unit_tests", - "//components/google/core/browser:unit_tests", - "//components/invalidation:unittests", - "//components/login:unit_tests", - "//components/metrics:unit_tests", - "//components/omnibox:unit_tests", - "//components/ownership:unit_tests", - "//components/packed_ct_ev_whitelist:unit_tests", - "//components/proximity_auth:unit_tests", - "//components/update_client:unit_tests", - "//components/variations:unit_tests", - "//components/web_resource:unit_tests", - "//components/webdata/common:unit_tests", + # Add only ":unit_tests" dependencies here. If your tests have dependencies + # (this would at least include the component itself), they should be on the + # test source set and not here. + deps = [ + "//components/auto_login_parser:unit_tests", + "//components/autofill/content/browser:unit_tests", + "//components/autofill/core/browser:unit_tests", + "//components/autofill/core/common:unit_tests", + "//components/bookmarks/browser:unit_tests", + "//components/captive_portal:unit_tests", + "//components/cloud_devices/common:unit_tests", + "//components/content_settings/core/browser:unit_tests", + "//components/content_settings/core/common:unit_tests", + "//components/crx_file:unit_tests", + "//components/data_reduction_proxy/core/browser:unit_tests", + "//components/data_reduction_proxy/core/common:unit_tests", + "//components/device_event_log:unit_tests", + "//components/dom_distiller/core:unit_tests", + "//components/domain_reliability:unit_tests", + "//components/favicon_base:unit_tests", + "//components/google/core/browser:unit_tests", + "//components/invalidation:unittests", + "//components/login:unit_tests", + "//components/metrics:unit_tests", + "//components/omnibox:unit_tests", + "//components/ownership:unit_tests", + "//components/packed_ct_ev_whitelist:unit_tests", + "//components/proximity_auth:unit_tests", + "//components/update_client:unit_tests", + "//components/variations:unit_tests", + "//components/web_resource:unit_tests", + "//components/webdata/common:unit_tests", - # These are the deps required by the code in this target. - "//base", - "//base/test:test_support", - "//content/test:test_support", - "//ui/base", - ] - data_deps = [ ":components_tests_pak" ] + # These are the deps required by the code in this target. + "//base", + "//base/test:test_support", + "//content/test:test_support", + "//ui/base", + ] + data_deps = [ ":components_tests_pak" ] - if (is_android) { - deps += [ "//components/data_reduction_proxy/content/browser:unit_tests" ] - } - - # TODO(GYP) need this target. - #'breakpad/app/crash_keys_win_unittest.cc', - - # Precache tests need these defines. - #configs += [ "//components/precache/core:precache_config" ] - - if (toolkit_views) { - # TODO(GYP) enable this as above. - #deps += [ "//components/constrained_window:unit_tests" ] - } - if (is_win) { - deps += [ "//components/browser_watcher:unit_tests" ] - } + if (is_android) { + deps += [ "//components/data_reduction_proxy/content/browser:unit_tests" ] } - repack("components_tests_pak") { - sources = [ - "$root_gen_dir/components/components_resources.pak", - "$root_gen_dir/components/strings/components_strings_en-US.pak", - "$root_gen_dir/ui/resources/ui_resources_100_percent.pak", - "$root_gen_dir/ui/resources/webui_resources.pak", - "$root_gen_dir/ui/strings/app_locale_settings_en-US.pak", - "$root_gen_dir/ui/strings/ui_strings_en-US.pak", - ] + # TODO(GYP) need this target. + #'breakpad/app/crash_keys_win_unittest.cc', - output = "$root_out_dir/components_tests_resources.pak" + # Precache tests need these defines. + #configs += [ "//components/precache/core:precache_config" ] - deps = [ - "//components/resources", - "//components/strings", - "//ui/resources", - "//ui/strings", - ] + if (toolkit_views) { + # TODO(GYP) enable this as above. + #deps += [ "//components/constrained_window:unit_tests" ] } + if (is_win) { + deps += [ "//components/browser_watcher:unit_tests" ] + } +} + +repack("components_tests_pak") { + sources = [ + "$root_gen_dir/components/components_resources.pak", + "$root_gen_dir/components/strings/components_strings_en-US.pak", + "$root_gen_dir/ui/resources/ui_resources_100_percent.pak", + "$root_gen_dir/ui/resources/webui_resources.pak", + "$root_gen_dir/ui/strings/app_locale_settings_en-US.pak", + "$root_gen_dir/ui/strings/ui_strings_en-US.pak", + ] + + output = "$root_out_dir/components_tests_resources.pak" + + deps = [ + "//components/resources", + "//components/strings", + "//ui/resources", + "//ui/strings", + ] }
diff --git a/components/autofill.gypi b/components/autofill.gypi index 21d98fd..e8c6d153 100644 --- a/components/autofill.gypi +++ b/components/autofill.gypi
@@ -459,5 +459,26 @@ }, ], }], + ['OS == "ios"', { + 'targets': [ + { + 'target_name': 'autofill_ios_browser', + 'type': 'static_library', + 'include_dirs': [ + '..', + ], + 'dependencies': [ + 'autofill_core_browser', + '../ios/provider/ios_provider_web.gyp:ios_provider_web', + '../ios/web/ios_web.gyp:ios_web', + ], + 'sources': [ + 'autofill/ios/browser/autofill_driver_ios.h', + 'autofill/ios/browser/autofill_driver_ios.mm', + 'autofill/ios/browser/autofill_driver_ios_bridge.h', + ], + }, + ], + }], ], }
diff --git a/components/autofill/content/renderer/form_cache.cc b/components/autofill/content/renderer/form_cache.cc index 3f27c39..9bc97e2f 100644 --- a/components/autofill/content/renderer/form_cache.cc +++ b/components/autofill/content/renderer/form_cache.cc
@@ -119,10 +119,41 @@ parsed_forms_.insert(form); } } + + // Look for more parseable fields outside of forms. + std::vector<WebElement> fieldsets; + std::vector<WebFormControlElement> control_elements = + GetUnownedAutofillableFormFieldElements(document.all(), &fieldsets); + + size_t num_editable_elements = + ScanFormControlElements(control_elements, log_deprecation_messages); + + if (ShouldIgnoreForm(num_editable_elements, control_elements.size())) + return forms; + + FormData synthetic_form; + if (!UnownedFormElementsAndFieldSetsToFormData(fieldsets, control_elements, + nullptr, document.url(), + REQUIRE_NONE, extract_mask, + &synthetic_form, nullptr)) { + return forms; + } + + num_fields_seen += synthetic_form.fields.size(); + if (num_fields_seen > kMaxParseableFields) + return forms; + + if (synthetic_form.fields.size() >= kRequiredAutofillFields && + !parsed_forms_.count(synthetic_form)) { + forms.push_back(synthetic_form); + parsed_forms_.insert(synthetic_form); + synthetic_form_ = synthetic_form; + } return forms; } void FormCache::Reset() { + synthetic_form_ = FormData(); parsed_forms_.clear(); initial_select_values_.clear(); initial_checked_state_.clear(); @@ -191,7 +222,15 @@ std::vector<WebFormControlElement> control_elements; + // First check the synthetic form. bool found_synthetic_form = false; + if (form.data.SameFormAs(synthetic_form_)) { + found_synthetic_form = true; + WebDocument document = frame_.document(); + control_elements = + GetUnownedAutofillableFormFieldElements(document.all(), nullptr); + } + if (!found_synthetic_form) { // Find the real form by searching through the WebDocuments. bool found_form = false;
diff --git a/components/autofill/content/renderer/form_cache.h b/components/autofill/content/renderer/form_cache.h index f37a981..d0c29cd 100644 --- a/components/autofill/content/renderer/form_cache.h +++ b/components/autofill/content/renderer/form_cache.h
@@ -64,6 +64,10 @@ // The cached forms. Used to prevent re-extraction of forms. std::set<FormData> parsed_forms_; + // The synthetic FormData is for all the fieldsets in the document without a + // form owner. + FormData synthetic_form_; + // The cached initial values for <select> elements. std::map<const blink::WebSelectElement, base::string16> initial_select_values_;
diff --git a/components/autofill/core/browser/autofill_client.h b/components/autofill/core/browser/autofill_client.h index 534aa68..ef3039b 100644 --- a/components/autofill/core/browser/autofill_client.h +++ b/components/autofill/core/browser/autofill_client.h
@@ -55,6 +55,21 @@ AutocompleteResultErrorInvalid, }; + enum GetRealPanResult { + // Request succeeded. + SUCCESS, + + // Request failed; try again. + TRY_AGAIN_FAILURE, + + // Request failed; don't try again. + PERMANENT_FAILURE, + + // Unable to connect to Wallet servers. Prompt user to check internet + // connection. + NETWORK_ERROR, + }; + typedef base::Callback<void(RequestAutocompleteResult, const base::string16&, const FormStructure*)> ResultCallback; @@ -87,7 +102,7 @@ // information to proceed. virtual void ShowUnmaskPrompt(const CreditCard& card, base::WeakPtr<CardUnmaskDelegate> delegate) = 0; - virtual void OnUnmaskVerificationResult(bool success) = 0; + virtual void OnUnmaskVerificationResult(GetRealPanResult result) = 0; // Run |save_card_callback| if the credit card should be imported as personal // data. |metric_logger| can be used to log user actions.
diff --git a/components/autofill/core/browser/autofill_manager.cc b/components/autofill/core/browser/autofill_manager.cc index ca6399a..20121fc 100644 --- a/components/autofill/core/browser/autofill_manager.cc +++ b/components/autofill/core/browser/autofill_manager.cc
@@ -778,8 +778,10 @@ return client()->GetIdentityProvider(); } -void AutofillManager::OnDidGetRealPan(const std::string& real_pan) { +void AutofillManager::OnDidGetRealPan(AutofillClient::GetRealPanResult result, + const std::string& real_pan) { if (!real_pan.empty()) { + DCHECK_EQ(AutofillClient::SUCCESS, result); credit_card_form_event_logger_->OnDidFillSuggestion(unmasking_card_); unmasking_card_.set_record_type(CreditCard::FULL_SERVER_CARD); unmasking_card_.SetNumber(base::UTF8ToUTF16(real_pan)); @@ -790,7 +792,7 @@ unmasking_card_); } - client()->OnUnmaskVerificationResult(!real_pan.empty()); + client()->OnUnmaskVerificationResult(result); } void AutofillManager::OnDidEndTextFieldEditing() {
diff --git a/components/autofill/core/browser/autofill_manager.h b/components/autofill/core/browser/autofill_manager.h index e9bbb44..5f8b67b 100644 --- a/components/autofill/core/browser/autofill_manager.h +++ b/components/autofill/core/browser/autofill_manager.h
@@ -237,7 +237,8 @@ // wallet::RealPanWalletClient::Delegate: IdentityProvider* GetIdentityProvider() override; - void OnDidGetRealPan(const std::string& real_pan) override; + void OnDidGetRealPan(AutofillClient::GetRealPanResult result, + const std::string& real_pan) override; // Returns false if Autofill is disabled or if no Autofill data is available. bool RefreshDataModels();
diff --git a/components/autofill/core/browser/autofill_metrics_unittest.cc b/components/autofill/core/browser/autofill_metrics_unittest.cc index f249d08..04ff306 100644 --- a/components/autofill/core/browser/autofill_metrics_unittest.cc +++ b/components/autofill/core/browser/autofill_metrics_unittest.cc
@@ -1186,7 +1186,8 @@ AutofillDriver::FORM_DATA_ACTION_FILL, 0, form, form.fields.front(), autofill_manager_->MakeFrontendID(guid, SuggestionBackendID())); - autofill_manager_->OnDidGetRealPan("6011000990139424"); + autofill_manager_->OnDidGetRealPan(AutofillClient::SUCCESS, + "6011000990139424"); histogram_tester.ExpectBucketCount( "Autofill.FormEvents.CreditCard", AutofillMetrics::FORM_EVENT_MASKED_SERVER_CARD_SUGGESTION_FILLED, 1); @@ -1348,7 +1349,8 @@ AutofillDriver::FORM_DATA_ACTION_FILL, 0, form, form.fields.front(), autofill_manager_->MakeFrontendID(guid, SuggestionBackendID())); - autofill_manager_->OnDidGetRealPan("6011000990139424"); + autofill_manager_->OnDidGetRealPan(AutofillClient::SUCCESS, + "6011000990139424"); histogram_tester.ExpectBucketCount( "Autofill.FormEvents.CreditCard", AutofillMetrics::FORM_EVENT_MASKED_SERVER_CARD_SUGGESTION_FILLED, 1);
diff --git a/components/autofill/core/browser/test_autofill_client.cc b/components/autofill/core/browser/test_autofill_client.cc index abcfb53..eef879d 100644 --- a/components/autofill/core/browser/test_autofill_client.cc +++ b/components/autofill/core/browser/test_autofill_client.cc
@@ -42,7 +42,7 @@ base::WeakPtr<CardUnmaskDelegate> delegate) { } -void TestAutofillClient::OnUnmaskVerificationResult(bool success) { +void TestAutofillClient::OnUnmaskVerificationResult(GetRealPanResult result) { } void TestAutofillClient::ConfirmSaveCreditCard(
diff --git a/components/autofill/core/browser/test_autofill_client.h b/components/autofill/core/browser/test_autofill_client.h index 1d5ab7ae..fcafd98 100644 --- a/components/autofill/core/browser/test_autofill_client.h +++ b/components/autofill/core/browser/test_autofill_client.h
@@ -30,7 +30,7 @@ void ShowAutofillSettings() override; void ShowUnmaskPrompt(const CreditCard& card, base::WeakPtr<CardUnmaskDelegate> delegate) override; - void OnUnmaskVerificationResult(bool success) override; + void OnUnmaskVerificationResult(GetRealPanResult result) override; void ConfirmSaveCreditCard(const base::Closure& save_card_callback) override; bool HasCreditCardScanFeature() override; void ScanCreditCard(const CreditCardScanCallback& callback) override;
diff --git a/components/autofill/core/browser/wallet/real_pan_wallet_client.cc b/components/autofill/core/browser/wallet/real_pan_wallet_client.cc index 37083c8..3934685 100644 --- a/components/autofill/core/browser/wallet/real_pan_wallet_client.cc +++ b/components/autofill/core/browser/wallet/real_pan_wallet_client.cc
@@ -129,8 +129,8 @@ std::string data; source->GetResponseAsString(&data); - // TODO(estade): OAuth2 may fail due to an expired access token, in which case - // we should invalidate the token and try again. How is that failure reported? + std::string real_pan; + AutofillClient::GetRealPanResult result = AutofillClient::SUCCESS; switch (response_code) { // Valid response. @@ -140,24 +140,19 @@ message_value->IsType(base::Value::TYPE_DICTIONARY)) { response_dict.reset( static_cast<base::DictionaryValue*>(message_value.release())); + response_dict->GetString("pan", &real_pan); + if (real_pan.empty()) + result = AutofillClient::TRY_AGAIN_FAILURE; + // TODO(estade): check response for allow_retry. } break; } - // HTTP_BAD_REQUEST means the arguments are invalid. No point retrying. - case net::HTTP_BAD_REQUEST: { - break; - } - - // Response contains an error to show the user. - case net::HTTP_FORBIDDEN: - case net::HTTP_INTERNAL_SERVER_ERROR: { - break; - } - case net::HTTP_UNAUTHORIZED: { - if (has_retried_authorization_) + if (has_retried_authorization_) { + result = AutofillClient::PERMANENT_FAILURE; break; + } has_retried_authorization_ = true; CreateRequest(); @@ -165,21 +160,27 @@ return; } - // Handle anything else as a generic error. - default: + // TODO(estade): is this actually how network connectivity issues are + // reported? + case net::HTTP_REQUEST_TIMEOUT: { + result = AutofillClient::NETWORK_ERROR; break; - } + } - std::string real_pan; - if (response_dict) - response_dict->GetString("pan", &real_pan); + // Handle anything else as a generic (permanent) failure. + default: { + result = AutofillClient::PERMANENT_FAILURE; + break; + } + } if (real_pan.empty()) { - NOTIMPLEMENTED() << "Unhandled error: " << response_code - << " with data: " << data; + LOG(ERROR) << "Wallet returned error: " << response_code + << " with data: " << data; } - delegate_->OnDidGetRealPan(real_pan); + DCHECK_EQ(result != AutofillClient::SUCCESS, real_pan.empty()); + delegate_->OnDidGetRealPan(result, real_pan); } void RealPanWalletClient::OnGetTokenSuccess( @@ -198,13 +199,12 @@ const OAuth2TokenService::Request* request, const GoogleServiceAuthError& error) { DCHECK_EQ(request, access_token_request_.get()); + LOG(ERROR) << "Unhandled OAuth2 error: " << error.ToString(); if (request_) { request_.reset(); - delegate_->OnDidGetRealPan(std::string()); + delegate_->OnDidGetRealPan(AutofillClient::PERMANENT_FAILURE, + std::string()); } - // TODO(estade): what do we do in the failure case? - NOTIMPLEMENTED() << "Unhandled OAuth2 error: " << error.ToString(); - access_token_request_.reset(); } @@ -257,7 +257,7 @@ void RealPanWalletClient::SetOAuth2TokenAndStartRequest() { request_->AddExtraRequestHeader(net::HttpRequestHeaders::kAuthorization + - std::string(": Bearer ") + access_token_); + std::string(": Bearer ") + access_token_); request_->Start(); }
diff --git a/components/autofill/core/browser/wallet/real_pan_wallet_client.h b/components/autofill/core/browser/wallet/real_pan_wallet_client.h index 82dc0b72d..6dd7a2d7 100644 --- a/components/autofill/core/browser/wallet/real_pan_wallet_client.h +++ b/components/autofill/core/browser/wallet/real_pan_wallet_client.h
@@ -7,6 +7,7 @@ #include "base/memory/ref_counted.h" #include "base/memory/weak_ptr.h" +#include "components/autofill/core/browser/autofill_client.h" #include "components/autofill/core/browser/card_unmask_delegate.h" #include "components/autofill/core/browser/credit_card.h" #include "google_apis/gaia/oauth2_token_service.h" @@ -36,7 +37,8 @@ // Returns the real PAN retrieved from Wallet. |real_pan| will be empty // on failure. - virtual void OnDidGetRealPan(const std::string& real_pan) = 0; + virtual void OnDidGetRealPan(AutofillClient::GetRealPanResult result, + const std::string& real_pan) = 0; }; // |context_getter| is reference counted so it has no lifetime or ownership
diff --git a/components/autofill/core/browser/webdata/autofill_table.cc b/components/autofill/core/browser/webdata/autofill_table.cc index 14fd62e..ea047585 100644 --- a/components/autofill/core/browser/webdata/autofill_table.cc +++ b/components/autofill/core/browser/webdata/autofill_table.cc
@@ -189,37 +189,6 @@ return credit_card.Pass(); } -// Obsolete version of AddAutofillProfileNamesToProfile, but still needed -// for MigrateToVersion37MergeAndCullOlderProfiles(). -bool AddAutofillProfileNamesToProfileForVersion37(sql::Connection* db, - AutofillProfile* profile) { - sql::Statement s(db->GetUniqueStatement( - "SELECT guid, first_name, middle_name, last_name " - "FROM autofill_profile_names " - "WHERE guid=?")); - s.BindString(0, profile->guid()); - - if (!s.is_valid()) - return false; - - std::vector<base::string16> first_names; - std::vector<base::string16> middle_names; - std::vector<base::string16> last_names; - while (s.Step()) { - DCHECK_EQ(profile->guid(), s.ColumnString(0)); - first_names.push_back(s.ColumnString16(1)); - middle_names.push_back(s.ColumnString16(2)); - last_names.push_back(s.ColumnString16(3)); - } - if (!s.Succeeded()) - return false; - - profile->SetRawMultiInfo(NAME_FIRST, first_names); - profile->SetRawMultiInfo(NAME_MIDDLE, middle_names); - profile->SetRawMultiInfo(NAME_LAST, last_names); - return true; -} - bool AddAutofillProfileNamesToProfile(sql::Connection* db, AutofillProfile* profile) { sql::Statement s(db->GetUniqueStatement( @@ -298,38 +267,6 @@ return true; } -// Obsolete version of AddAutofillProfileNames needed for -// MigrateToVersion33ProfilesBasedOnFirstName() and -// MigrateToVersion37MergeAndCullOlderProfiles(). -bool AddAutofillProfileNamesForVersion3x( - const AutofillProfile& profile, - sql::Connection* db) { - std::vector<base::string16> first_names; - profile.GetRawMultiInfo(NAME_FIRST, &first_names); - std::vector<base::string16> middle_names; - profile.GetRawMultiInfo(NAME_MIDDLE, &middle_names); - std::vector<base::string16> last_names; - profile.GetRawMultiInfo(NAME_LAST, &last_names); - DCHECK_EQ(first_names.size(), middle_names.size()); - DCHECK_EQ(first_names.size(), last_names.size()); - - for (size_t i = 0; i < first_names.size(); ++i) { - // Add the new name. - sql::Statement s(db->GetUniqueStatement( - "INSERT INTO autofill_profile_names" - " (guid, first_name, middle_name, last_name) " - "VALUES (?,?,?,?)")); - s.BindString(0, profile.guid()); - s.BindString16(1, first_names[i]); - s.BindString16(2, middle_names[i]); - s.BindString16(3, last_names[i]); - - if (!s.Run()) - return false; - } - return true; -} - bool AddAutofillProfileNames(const AutofillProfile& profile, sql::Connection* db) { std::vector<base::string16> first_names; @@ -511,48 +448,6 @@ bool* update_compatible_version) { // Migrate if necessary. switch (version) { - case 22: - return MigrateToVersion22ClearAutofillEmptyValueElements(); - case 23: - return MigrateToVersion23AddCardNumberEncryptedColumn(); - case 24: - return MigrateToVersion24CleanupOversizedStringFields(); - case 27: - *update_compatible_version = true; - return MigrateToVersion27UpdateLegacyCreditCards(); - case 30: - *update_compatible_version = true; - return MigrateToVersion30AddDateModifed(); - case 31: - *update_compatible_version = true; - return MigrateToVersion31AddGUIDToCreditCardsAndProfiles(); - case 32: - *update_compatible_version = true; - return MigrateToVersion32UpdateProfilesAndCreditCards(); - case 33: - *update_compatible_version = true; - return MigrateToVersion33ProfilesBasedOnFirstName(); - case 34: - *update_compatible_version = true; - return MigrateToVersion34ProfilesBasedOnCountryCode(); - case 35: - *update_compatible_version = true; - return MigrateToVersion35GreatBritainCountryCodes(); - // Combine migrations 36 and 37. This is due to enhancements to the merge - // step when migrating profiles. The original migration from 35 to 36 did - // not merge profiles with identical addresses, but the migration from 36 to - // 37 does. The step from 35 to 36 should only happen on the Chrome 12 dev - // channel. Chrome 12 beta and release users will jump from 35 to 37 - // directly getting the full benefits of the multi-valued merge as well as - // the culling of bad data. - case 37: - *update_compatible_version = true; - return MigrateToVersion37MergeAndCullOlderProfiles(); - case 51: - // Combine migrations 50 and 51. The migration code from version 49 to 50 - // worked correctly for users with existing 'origin' columns, but failed - // to create these columns for new users. - return MigrateToVersion51AddOriginColumn(); case 54: *update_compatible_version = true; return MigrateToVersion54AddI18nFieldsAndRemoveDeprecatedFields(); @@ -574,6 +469,9 @@ case 62: *update_compatible_version = false; return MigrateToVersion62AddUsageStatsForUnmaskedCards(); + case 63: + *update_compatible_version = false; + return MigrateToVersion63AddServerRecipientName(); } return true; } @@ -1004,6 +902,7 @@ sql::Statement s(db_->GetUniqueStatement( "SELECT " "id," + "recipient_name," "company_name," "street_address," "address_1," // ADDRESS_HOME_STATE @@ -1021,6 +920,7 @@ scoped_ptr<AutofillProfile> profile(new AutofillProfile( AutofillProfile::SERVER_PROFILE, s.ColumnString(index++))); + profile->SetRawInfo(NAME_FULL, s.ColumnString16(index++)); profile->SetRawInfo(COMPANY_NAME, s.ColumnString16(index++)); profile->SetRawInfo(ADDRESS_HOME_STREET_ADDRESS, s.ColumnString16(index++)); profile->SetRawInfo(ADDRESS_HOME_STATE, s.ColumnString16(index++)); @@ -1049,6 +949,7 @@ sql::Statement insert(db_->GetUniqueStatement( "INSERT INTO server_addresses(" "id," + "recipient_name," "company_name," "street_address," "address_1," // ADDRESS_HOME_STATE @@ -1059,12 +960,13 @@ "sorting_code," // ADDRESS_HOME_SORTING_CODE "country_code," // ADDRESS_HOME_COUNTRY "language_code) " - "VALUES (?,?,?,?,?,?,?,?,?,?,?)")); + "VALUES (?,?,?,?,?,?,?,?,?,?,?,?)")); for (const auto& profile : profiles) { DCHECK(profile.record_type() == AutofillProfile::SERVER_PROFILE); int index = 0; insert.BindString(index++, profile.server_id()); + insert.BindString16(index++, profile.GetRawInfo(NAME_FULL)); insert.BindString16(index++, profile.GetRawInfo(COMPANY_NAME)); insert.BindString16(index++, profile.GetRawInfo(ADDRESS_HOME_STREET_ADDRESS)); @@ -1776,6 +1678,8 @@ bool AutofillTable::InitServerAddressesTable() { if (!db_->DoesTableExist("server_addresses")) { + // The space after language_code is necessary to match what sqlite does + // when it appends the column in migration. if (!db_->Execute("CREATE TABLE server_addresses (" "id VARCHAR," "company_name VARCHAR," @@ -1787,7 +1691,8 @@ "postal_code VARCHAR," "sorting_code VARCHAR," "country_code VARCHAR," - "language_code VARCHAR)")) { + "language_code VARCHAR, " // Space required. + "recipient_name VARCHAR)")) { NOTREACHED(); return false; } @@ -1795,778 +1700,6 @@ return true; } -bool AutofillTable::MigrateToVersion22ClearAutofillEmptyValueElements() { - if (!db_->DoesTableExist("autofill") && - (!db_->Execute("CREATE TABLE autofill (" - " name VARCHAR," - " value VARCHAR," - " value_lower VARCHAR," - " pair_id INTEGER PRIMARY KEY," - " count INTEGER DEFAULT 1)") || - !db_->Execute("CREATE INDEX autofill_name ON autofill (name)") || - !db_->Execute("CREATE INDEX autofill_name_value_lower ON" - " autofill (name, value_lower)") || - !db_->Execute("CREATE TABLE autofill_dates (" - " pair_id INTEGER DEFAULT 0," - " date_created INTEGER DEFAULT 0)") || - !db_->Execute("CREATE INDEX autofill_dates_pair_id ON" - " autofill (pair_id)"))) - return false; - - - sql::Statement s(db_->GetUniqueStatement( - "SELECT pair_id FROM autofill WHERE TRIM(value) = \"\"")); - if (!s.is_valid()) - return false; - - std::set<int64> ids; - while (s.Step()) - ids.insert(s.ColumnInt64(0)); - if (!s.Succeeded()) - return false; - - if (!db_->Execute("DELETE FROM autofill WHERE TRIM(value) = \"\"")) - return false; - - for (std::set<int64>::const_iterator it = ids.begin(); it != ids.end(); - ++it) { - sql::Statement s(db_->GetUniqueStatement( - "DELETE FROM autofill_dates WHERE pair_id = ?")); - s.BindInt64(0, *it); - if (!s.Run()) - return false; - } - - return true; -} - -// Add the card_number_encrypted column if credit card table was not -// created in this build (otherwise the column already exists). -// WARNING: Do not change the order of the execution of the SQL -// statements in this case! Profile corruption and data migration -// issues WILL OCCUR. See http://crbug.com/10913 -// -// The problem is that if a user has a profile which was created before -// r37036, when the credit_cards table was added, and then failed to -// update this profile between the credit card addition and the addition -// of the "encrypted" columns (44963), the next data migration will put -// the user's profile in an incoherent state: The user will update from -// a data profile set to be earlier than 22, and therefore pass through -// this update case. But because the user did not have a credit_cards -// table before starting Chrome, it will have just been initialized -// above, and so already have these columns -- and thus this data -// update step will have failed. -// -// The false assumption in this case is that at this step in the -// migration, the user has a credit card table, and that this -// table does not include encrypted columns! -// Because this case does not roll back the complete set of SQL -// transactions properly in case of failure (that is, it does not -// roll back the table initialization done above), the incoherent -// profile will now see itself as being at version 22 -- but include a -// fully initialized credit_cards table. Every time Chrome runs, it -// will try to update the web database and fail at this step, unless -// we allow for the faulty assumption described above by checking for -// the existence of the columns only AFTER we've executed the commands -// to add them. -bool AutofillTable::MigrateToVersion23AddCardNumberEncryptedColumn() { - if (!db_->DoesTableExist("autofill_profiles") && - (!db_->Execute("CREATE TABLE autofill_profiles ( " - "label VARCHAR, " - "unique_id INTEGER PRIMARY KEY, " - "first_name VARCHAR, " - "middle_name VARCHAR, " - "last_name VARCHAR, " - "email VARCHAR, " - "company_name VARCHAR, " - "address_line_1 VARCHAR, " - "address_line_2 VARCHAR, " - "city VARCHAR, " - "state VARCHAR, " - "zipcode VARCHAR, " - "country VARCHAR, " - "phone VARCHAR, " - "fax VARCHAR)") || - !db_->Execute("CREATE INDEX autofill_profiles_label_index" - " ON autofill_profiles (label)"))) - return false; - - if (!db_->DoesTableExist("credit_cards") && - (!db_->Execute("CREATE TABLE credit_cards ( " - "label VARCHAR, " - "unique_id INTEGER PRIMARY KEY, " - "name_on_card VARCHAR, " - "type VARCHAR, " - "card_number VARCHAR, " - "expiration_month INTEGER, " - "expiration_year INTEGER, " - "verification_code VARCHAR, " - "billing_address VARCHAR, " - "shipping_address VARCHAR)") || - !db_->Execute("CREATE INDEX credit_cards_label_index" - " ON credit_cards (label)"))) - return false; - - if (!db_->DoesColumnExist("credit_cards", "card_number_encrypted")) { - if (!db_->Execute("ALTER TABLE credit_cards ADD COLUMN " - "card_number_encrypted BLOB DEFAULT NULL")) { - return false; - } - } - - if (!db_->DoesColumnExist("credit_cards", "verification_code_encrypted")) { - if (!db_->Execute("ALTER TABLE credit_cards ADD COLUMN " - "verification_code_encrypted BLOB DEFAULT NULL")) { - return false; - } - } - - return true; -} - -// One-time cleanup for http://crbug.com/38364 - In the presence of -// multi-byte UTF-8 characters, that bug could cause Autofill strings -// to grow larger and more corrupt with each save. The cleanup removes -// any row with a string field larger than a reasonable size. The string -// fields examined here are precisely the ones that were subject to -// corruption by the original bug. -bool AutofillTable::MigrateToVersion24CleanupOversizedStringFields() { - const std::string autofill_is_too_big = - "max(length(name), length(value)) > 500"; - - const std::string credit_cards_is_too_big = - "max(length(label), length(name_on_card), length(type), " - " length(expiration_month), length(expiration_year), " - " length(billing_address), length(shipping_address) " - ") > 500"; - - const std::string autofill_profiles_is_too_big = - "max(length(label), length(first_name), " - " length(middle_name), length(last_name), length(email), " - " length(company_name), length(address_line_1), " - " length(address_line_2), length(city), length(state), " - " length(zipcode), length(country), length(phone)) > 500"; - - std::string query = "DELETE FROM autofill_dates WHERE pair_id IN (" - "SELECT pair_id FROM autofill WHERE " + autofill_is_too_big + ")"; - - if (!db_->Execute(query.c_str())) - return false; - - query = "DELETE FROM autofill WHERE " + autofill_is_too_big; - - if (!db_->Execute(query.c_str())) - return false; - - // Only delete from legacy credit card tables where specific columns exist. - if (db_->DoesColumnExist("credit_cards", "label") && - db_->DoesColumnExist("credit_cards", "name_on_card") && - db_->DoesColumnExist("credit_cards", "type") && - db_->DoesColumnExist("credit_cards", "expiration_month") && - db_->DoesColumnExist("credit_cards", "expiration_year") && - db_->DoesColumnExist("credit_cards", "billing_address") && - db_->DoesColumnExist("credit_cards", "shipping_address") && - db_->DoesColumnExist("autofill_profiles", "label")) { - query = "DELETE FROM credit_cards WHERE (" + credit_cards_is_too_big + - ") OR label IN (SELECT label FROM autofill_profiles WHERE " + - autofill_profiles_is_too_big + ")"; - - if (!db_->Execute(query.c_str())) - return false; - } - - if (db_->DoesColumnExist("autofill_profiles", "label")) { - query = "DELETE FROM autofill_profiles WHERE " + - autofill_profiles_is_too_big; - - if (!db_->Execute(query.c_str())) - return false; - } - - return true; -} - -// Change the credit_cards.billing_address column from a string to an -// int. The stored string is the label of an address, so we have to -// select the unique ID of this address using the label as a foreign -// key into the |autofill_profiles| table. -bool AutofillTable::MigrateToVersion27UpdateLegacyCreditCards() { - // Only migrate from legacy credit card tables where specific columns - // exist. - if (!(db_->DoesColumnExist("credit_cards", "unique_id") && - db_->DoesColumnExist("credit_cards", "billing_address") && - db_->DoesColumnExist("autofill_profiles", "unique_id"))) { - return true; - } - - std::string stmt = - "SELECT credit_cards.unique_id, autofill_profiles.unique_id " - "FROM autofill_profiles, credit_cards " - "WHERE credit_cards.billing_address = autofill_profiles.label"; - sql::Statement s(db_->GetUniqueStatement(stmt.c_str())); - - std::map<int, int> cc_billing_map; - while (s.Step()) - cc_billing_map[s.ColumnInt(0)] = s.ColumnInt(1); - if (!s.Succeeded()) - return false; - - // Windows already stores the IDs as strings in |billing_address|. Try - // to convert those. - if (cc_billing_map.empty()) { - std::string stmt = "SELECT unique_id,billing_address FROM credit_cards"; - sql::Statement s(db_->GetUniqueStatement(stmt.c_str())); - - while (s.Step()) { - int id = 0; - if (base::StringToInt(s.ColumnString(1), &id)) - cc_billing_map[s.ColumnInt(0)] = id; - } - if (!s.Succeeded()) - return false; - } - - if (!db_->Execute("CREATE TABLE credit_cards_temp ( " - "label VARCHAR, " - "unique_id INTEGER PRIMARY KEY, " - "name_on_card VARCHAR, " - "type VARCHAR, " - "card_number VARCHAR, " - "expiration_month INTEGER, " - "expiration_year INTEGER, " - "verification_code VARCHAR, " - "billing_address INTEGER, " - "shipping_address VARCHAR, " - "card_number_encrypted BLOB, " - "verification_code_encrypted BLOB)")) { - return false; - } - - if (!db_->Execute( - "INSERT INTO credit_cards_temp " - "SELECT label,unique_id,name_on_card,type,card_number," - "expiration_month,expiration_year,verification_code,0," - "shipping_address,card_number_encrypted," - "verification_code_encrypted FROM credit_cards")) { - return false; - } - - if (!db_->Execute("DROP TABLE credit_cards")) - return false; - - if (!db_->Execute("ALTER TABLE credit_cards_temp RENAME TO credit_cards")) - return false; - - for (std::map<int, int>::const_iterator iter = cc_billing_map.begin(); - iter != cc_billing_map.end(); ++iter) { - sql::Statement s(db_->GetCachedStatement( - SQL_FROM_HERE, - "UPDATE credit_cards SET billing_address=? WHERE unique_id=?")); - s.BindInt(0, (*iter).second); - s.BindInt(1, (*iter).first); - - if (!s.Run()) - return false; - } - - return true; -} - -bool AutofillTable::MigrateToVersion30AddDateModifed() { - // Add date_modified to autofill_profiles. - if (!db_->DoesColumnExist("autofill_profiles", "date_modified")) { - if (!db_->Execute("ALTER TABLE autofill_profiles ADD COLUMN " - "date_modified INTEGER NON NULL DEFAULT 0")) { - return false; - } - - sql::Statement s(db_->GetUniqueStatement( - "UPDATE autofill_profiles SET date_modified=?")); - s.BindInt64(0, Time::Now().ToTimeT()); - - if (!s.Run()) - return false; - } - - // Add date_modified to credit_cards. - if (!db_->DoesColumnExist("credit_cards", "date_modified")) { - if (!db_->Execute("ALTER TABLE credit_cards ADD COLUMN " - "date_modified INTEGER NON NULL DEFAULT 0")) { - return false; - } - - sql::Statement s(db_->GetUniqueStatement( - "UPDATE credit_cards SET date_modified=?")); - s.BindInt64(0, Time::Now().ToTimeT()); - - if (!s.Run()) - return false; - } - - return true; -} - -bool AutofillTable::MigrateToVersion31AddGUIDToCreditCardsAndProfiles() { - // Note that we need to check for the guid column's existence due to the - // fact that for a version 22 database the |autofill_profiles| table - // gets created fresh with |InitAutofillProfilesTable|. - if (!db_->DoesColumnExist("autofill_profiles", "guid")) { - if (!db_->Execute("ALTER TABLE autofill_profiles ADD COLUMN " - "guid VARCHAR NOT NULL DEFAULT \"\"")) { - return false; - } - - // Set all the |guid| fields to valid values. - - sql::Statement s(db_->GetUniqueStatement("SELECT unique_id " - "FROM autofill_profiles")); - - while (s.Step()) { - sql::Statement update_s( - db_->GetUniqueStatement("UPDATE autofill_profiles " - "SET guid=? WHERE unique_id=?")); - update_s.BindString(0, base::GenerateGUID()); - update_s.BindInt(1, s.ColumnInt(0)); - - if (!update_s.Run()) - return false; - } - if (!s.Succeeded()) - return false; - } - - // Note that we need to check for the guid column's existence due to the - // fact that for a version 22 database the |autofill_profiles| table - // gets created fresh with |InitAutofillProfilesTable|. - if (!db_->DoesColumnExist("credit_cards", "guid")) { - if (!db_->Execute("ALTER TABLE credit_cards ADD COLUMN " - "guid VARCHAR NOT NULL DEFAULT \"\"")) { - return false; - } - - // Set all the |guid| fields to valid values. - - sql::Statement s(db_->GetUniqueStatement("SELECT unique_id " - "FROM credit_cards")); - - while (s.Step()) { - sql::Statement update_s( - db_->GetUniqueStatement("UPDATE credit_cards " - "set guid=? WHERE unique_id=?")); - update_s.BindString(0, base::GenerateGUID()); - update_s.BindInt(1, s.ColumnInt(0)); - - if (!update_s.Run()) - return false; - } - if (!s.Succeeded()) - return false; - } - - return true; -} - -bool AutofillTable::MigrateToVersion32UpdateProfilesAndCreditCards() { - if (db_->DoesColumnExist("autofill_profiles", "unique_id")) { - if (!db_->Execute("CREATE TABLE autofill_profiles_temp ( " - "guid VARCHAR PRIMARY KEY, " - "label VARCHAR, " - "first_name VARCHAR, " - "middle_name VARCHAR, " - "last_name VARCHAR, " - "email VARCHAR, " - "company_name VARCHAR, " - "address_line_1 VARCHAR, " - "address_line_2 VARCHAR, " - "city VARCHAR, " - "state VARCHAR, " - "zipcode VARCHAR, " - "country VARCHAR, " - "phone VARCHAR, " - "date_modified INTEGER NOT NULL DEFAULT 0)")) { - return false; - } - - if (!db_->Execute( - "INSERT INTO autofill_profiles_temp " - "SELECT guid, label, first_name, middle_name, last_name, email, " - "company_name, address_line_1, address_line_2, city, state, " - "zipcode, country, phone, date_modified " - "FROM autofill_profiles")) { - return false; - } - - if (!db_->Execute("DROP TABLE autofill_profiles")) - return false; - - if (!db_->Execute( - "ALTER TABLE autofill_profiles_temp RENAME TO autofill_profiles")) { - return false; - } - } - - if (db_->DoesColumnExist("credit_cards", "unique_id")) { - if (!db_->Execute("CREATE TABLE credit_cards_temp ( " - "guid VARCHAR PRIMARY KEY, " - "label VARCHAR, " - "name_on_card VARCHAR, " - "expiration_month INTEGER, " - "expiration_year INTEGER, " - "card_number_encrypted BLOB, " - "date_modified INTEGER NOT NULL DEFAULT 0)")) { - return false; - } - - if (!db_->Execute( - "INSERT INTO credit_cards_temp " - "SELECT guid, label, name_on_card, expiration_month, " - "expiration_year, card_number_encrypted, date_modified " - "FROM credit_cards")) { - return false; - } - - if (!db_->Execute("DROP TABLE credit_cards")) - return false; - - if (!db_->Execute("ALTER TABLE credit_cards_temp RENAME TO credit_cards")) - return false; - } - - return true; -} - -// Test the existence of the |first_name| column as an indication that -// we need a migration. It is possible that the new |autofill_profiles| -// schema is in place because the table was newly created when migrating -// from a pre-version-22 database. -bool AutofillTable::MigrateToVersion33ProfilesBasedOnFirstName() { - if (!db_->DoesTableExist("autofill_profile_names") && - !db_->Execute("CREATE TABLE autofill_profile_names ( " - "guid VARCHAR, " - "first_name VARCHAR, " - "middle_name VARCHAR, " - "last_name VARCHAR)")) - return false; - - if (!db_->DoesTableExist("autofill_profile_emails") && - !db_->Execute("CREATE TABLE autofill_profile_emails ( " - "guid VARCHAR, " - "email VARCHAR)")) - return false; - - if (!db_->DoesTableExist("autofill_profile_phones") && - !db_->Execute("CREATE TABLE autofill_profile_phones ( " - "guid VARCHAR, " - "type INTEGER DEFAULT 0, " - "number VARCHAR)")) - return false; - - if (db_->DoesColumnExist("autofill_profiles", "first_name")) { - // Create autofill_profiles_temp table that will receive the data. - if (!db_->DoesTableExist("autofill_profiles_temp")) { - if (!db_->Execute("CREATE TABLE autofill_profiles_temp ( " - "guid VARCHAR PRIMARY KEY, " - "company_name VARCHAR, " - "address_line_1 VARCHAR, " - "address_line_2 VARCHAR, " - "city VARCHAR, " - "state VARCHAR, " - "zipcode VARCHAR, " - "country VARCHAR, " - "date_modified INTEGER NOT NULL DEFAULT 0)")) { - return false; - } - } - - sql::Statement s(db_->GetUniqueStatement( - "SELECT guid, first_name, middle_name, last_name, email, " - "company_name, address_line_1, address_line_2, city, state, " - "zipcode, country, phone, date_modified " - "FROM autofill_profiles")); - - while (s.Step()) { - AutofillProfile profile; - int index = 0; - profile.set_guid(s.ColumnString(index++)); - DCHECK(base::IsValidGUID(profile.guid())); - - profile.SetRawInfo(NAME_FIRST, s.ColumnString16(index++)); - profile.SetRawInfo(NAME_MIDDLE, s.ColumnString16(index++)); - profile.SetRawInfo(NAME_LAST, s.ColumnString16(index++)); - profile.SetRawInfo(EMAIL_ADDRESS, s.ColumnString16(index++)); - profile.SetRawInfo(COMPANY_NAME, s.ColumnString16(index++)); - profile.SetRawInfo(ADDRESS_HOME_LINE1, s.ColumnString16(index++)); - profile.SetRawInfo(ADDRESS_HOME_LINE2, s.ColumnString16(index++)); - profile.SetRawInfo(ADDRESS_HOME_CITY, s.ColumnString16(index++)); - profile.SetRawInfo(ADDRESS_HOME_STATE, s.ColumnString16(index++)); - profile.SetRawInfo(ADDRESS_HOME_ZIP, s.ColumnString16(index++)); - profile.SetInfo(AutofillType(ADDRESS_HOME_COUNTRY), - s.ColumnString16(index++), app_locale_); - profile.SetRawInfo(PHONE_HOME_WHOLE_NUMBER, s.ColumnString16(index++)); - int64 date_modified = s.ColumnInt64(index++); - - sql::Statement s_insert(db_->GetUniqueStatement( - "INSERT INTO autofill_profiles_temp" - "(guid, company_name, address_line_1, address_line_2, city," - " state, zipcode, country, date_modified)" - "VALUES (?,?,?,?,?,?,?,?,?)")); - index = 0; - s_insert.BindString(index++, profile.guid()); - s_insert.BindString16(index++, profile.GetRawInfo(COMPANY_NAME)); - s_insert.BindString16(index++, profile.GetRawInfo(ADDRESS_HOME_LINE1)); - s_insert.BindString16(index++, profile.GetRawInfo(ADDRESS_HOME_LINE2)); - s_insert.BindString16(index++, profile.GetRawInfo(ADDRESS_HOME_CITY)); - s_insert.BindString16(index++, profile.GetRawInfo(ADDRESS_HOME_STATE)); - s_insert.BindString16(index++, profile.GetRawInfo(ADDRESS_HOME_ZIP)); - s_insert.BindString16(index++, profile.GetRawInfo(ADDRESS_HOME_COUNTRY)); - s_insert.BindInt64(index++, date_modified); - - if (!s_insert.Run()) - return false; - - // Add the other bits: names, emails, and phone numbers. - if (!AddAutofillProfileNamesForVersion3x(profile, db_) || - !AddAutofillProfileEmails(profile, db_) || - !AddAutofillProfilePhones(profile, db_)) { - return false; - } - } // endwhile - if (!s.Succeeded()) - return false; - - if (!db_->Execute("DROP TABLE autofill_profiles")) - return false; - - if (!db_->Execute( - "ALTER TABLE autofill_profiles_temp RENAME TO autofill_profiles")) { - return false; - } - } - - // Remove the labels column from the credit_cards table. - if (db_->DoesColumnExist("credit_cards", "label")) { - if (!db_->Execute("CREATE TABLE credit_cards_temp ( " - "guid VARCHAR PRIMARY KEY, " - "name_on_card VARCHAR, " - "expiration_month INTEGER, " - "expiration_year INTEGER, " - "card_number_encrypted BLOB, " - "date_modified INTEGER NOT NULL DEFAULT 0)")) { - return false; - } - - if (!db_->Execute( - "INSERT INTO credit_cards_temp " - "SELECT guid, name_on_card, expiration_month, " - "expiration_year, card_number_encrypted, date_modified " - "FROM credit_cards")) { - return false; - } - - if (!db_->Execute("DROP TABLE credit_cards")) - return false; - - if (!db_->Execute("ALTER TABLE credit_cards_temp RENAME TO credit_cards")) - return false; - } - - return true; -} - -// Test the existence of the |country_code| column as an indication that -// we need a migration. It is possible that the new |autofill_profiles| -// schema is in place because the table was newly created when migrating -// from a pre-version-22 database. -bool AutofillTable::MigrateToVersion34ProfilesBasedOnCountryCode() { - if (!db_->DoesColumnExist("autofill_profiles", "country_code")) { - if (!db_->Execute("ALTER TABLE autofill_profiles ADD COLUMN " - "country_code VARCHAR")) { - return false; - } - - // Set all the |country_code| fields to match existing |country| values. - sql::Statement s(db_->GetUniqueStatement("SELECT guid, country " - "FROM autofill_profiles")); - - while (s.Step()) { - sql::Statement update_s( - db_->GetUniqueStatement("UPDATE autofill_profiles " - "SET country_code=? WHERE guid=?")); - - base::string16 country = s.ColumnString16(1); - update_s.BindString(0, AutofillCountry::GetCountryCode(country, - app_locale_)); - update_s.BindString(1, s.ColumnString(0)); - - if (!update_s.Run()) - return false; - } - if (!s.Succeeded()) - return false; - } - - return true; -} - -// Correct all country codes with value "UK" to be "GB". This data -// was mistakenly introduced in build 686.0. This migration is to clean -// it up. See http://crbug.com/74511 for details. -bool AutofillTable::MigrateToVersion35GreatBritainCountryCodes() { - sql::Statement s(db_->GetUniqueStatement( - "UPDATE autofill_profiles SET country_code=\"GB\" " - "WHERE country_code=\"UK\"")); - - return s.Run(); -} - -// Merge and cull older profiles where possible. -bool AutofillTable::MigrateToVersion37MergeAndCullOlderProfiles() { - if (!db_->DoesTableExist("autofill_profiles_trash") && - !db_->Execute("CREATE TABLE autofill_profiles_trash (guid VARCHAR)")) - return false; - - sql::Statement s(db_->GetUniqueStatement( - "SELECT guid, date_modified FROM autofill_profiles")); - - // Accumulate the good profiles. - std::vector<AutofillProfile> accumulated_profiles; - std::vector<AutofillProfile*> accumulated_profiles_p; - std::map<std::string, int64> modification_map; - while (s.Step()) { - std::string guid = s.ColumnString(0); - int64 date_modified = s.ColumnInt64(1); - modification_map.insert( - std::pair<std::string, int64>(guid, date_modified)); - - sql::Statement s(db_->GetUniqueStatement( - "SELECT guid, company_name, address_line_1, address_line_2, city, " - " state, zipcode, country, country_code, date_modified " - "FROM autofill_profiles " - "WHERE guid=?")); - s.BindString(0, guid); - - if (!s.Step()) - return false; - - scoped_ptr<AutofillProfile> profile(new AutofillProfile); - int index = 0; - profile->set_guid(s.ColumnString(index++)); - DCHECK(base::IsValidGUID(profile->guid())); - - profile->SetRawInfo(COMPANY_NAME, s.ColumnString16(index++)); - profile->SetRawInfo(ADDRESS_HOME_LINE1, s.ColumnString16(index++)); - profile->SetRawInfo(ADDRESS_HOME_LINE2, s.ColumnString16(index++)); - profile->SetRawInfo(ADDRESS_HOME_CITY, s.ColumnString16(index++)); - profile->SetRawInfo(ADDRESS_HOME_STATE, s.ColumnString16(index++)); - profile->SetRawInfo(ADDRESS_HOME_ZIP, s.ColumnString16(index++)); - // Intentionally skip column 7, which stores the localized country name. - index++; - profile->SetRawInfo(ADDRESS_HOME_COUNTRY, s.ColumnString16(index++)); - profile->set_modification_date( - base::Time::FromTimeT(s.ColumnInt64(index++))); - profile->set_origin(s.ColumnString(index++)); - - // Get associated name info. - AddAutofillProfileNamesToProfileForVersion37(db_, profile.get()); - - // Get associated email info. - AddAutofillProfileEmailsToProfile(db_, profile.get()); - - // Get associated phone info. - AddAutofillProfilePhonesToProfile(db_, profile.get()); - - if (PersonalDataManager::IsValidLearnableProfile(*profile, app_locale_)) { - std::vector<AutofillProfile> merged_profiles; - std::string merged_guid = PersonalDataManager::MergeProfile( - *profile, accumulated_profiles_p, app_locale_, &merged_profiles); - - std::swap(accumulated_profiles, merged_profiles); - - accumulated_profiles_p.clear(); - accumulated_profiles_p.resize(accumulated_profiles.size()); - std::transform(accumulated_profiles.begin(), - accumulated_profiles.end(), - accumulated_profiles_p.begin(), - address_of<AutofillProfile>); - - // If the profile got merged trash the original. - if (merged_guid != profile->guid()) - AddAutofillGUIDToTrash(profile->guid()); - } else { - // An invalid profile, so trash it. - AddAutofillGUIDToTrash(profile->guid()); - } - } // endwhile - if (!s.Succeeded()) - return false; - - // Drop the current profiles. - if (!ClearAutofillProfiles()) - return false; - - // Add the newly merged profiles back in. - for (std::vector<AutofillProfile>::const_iterator - iter = accumulated_profiles.begin(); - iter != accumulated_profiles.end(); - ++iter) { - // Save the profile with its original modification date. - std::map<std::string, int64>::const_iterator date_item = - modification_map.find(iter->guid()); - if (date_item == modification_map.end()) - return false; - - sql::Statement s(db_->GetUniqueStatement( - "INSERT INTO autofill_profiles" - "(guid, company_name, address_line_1, address_line_2, city, state," - " zipcode, country, country_code, date_modified)" - "VALUES (?,?,?,?,?,?,?,?,?,?)")); - int index = 0; - s.BindString(index++, iter->guid()); - s.BindString16(index++, GetInfo(*iter, COMPANY_NAME)); - s.BindString16(index++, GetInfo(*iter, ADDRESS_HOME_LINE1)); - s.BindString16(index++, GetInfo(*iter, ADDRESS_HOME_LINE2)); - s.BindString16(index++, GetInfo(*iter, ADDRESS_HOME_CITY)); - s.BindString16(index++, GetInfo(*iter, ADDRESS_HOME_STATE)); - s.BindString16(index++, GetInfo(*iter, ADDRESS_HOME_ZIP)); - s.BindString16(index++, base::string16()); // This column is deprecated. - s.BindString16(index++, GetInfo(*iter, ADDRESS_HOME_COUNTRY)); - s.BindInt64(index++, date_item->second); - - if (!s.Run()) - return false; - - if (!AddAutofillProfileNamesForVersion3x(*iter, db_) || - !AddAutofillProfileEmails(*iter, db_) || - !AddAutofillProfilePhones(*iter, db_)) { - return false; - } - } - - return true; -} - -bool AutofillTable::MigrateToVersion51AddOriginColumn() { - sql::Transaction transaction(db_); - if (!transaction.Begin()) - return false; - - // Add origin to autofill_profiles. - if (!db_->DoesColumnExist("autofill_profiles", "origin") && - !db_->Execute("ALTER TABLE autofill_profiles " - "ADD COLUMN origin VARCHAR DEFAULT ''")) { - return false; - } - - // Add origin to credit_cards. - if (!db_->DoesColumnExist("credit_cards", "origin") && - !db_->Execute("ALTER TABLE credit_cards " - "ADD COLUMN origin VARCHAR DEFAULT ''")) { - return false; - } - - return transaction.Commit(); -} - bool AutofillTable::MigrateToVersion54AddI18nFieldsAndRemoveDeprecatedFields() { sql::Transaction transaction(db_); if (!transaction.Begin()) @@ -2843,4 +1976,13 @@ return transaction.Commit(); } +bool AutofillTable::MigrateToVersion63AddServerRecipientName() { + if (!db_->DoesColumnExist("server_addresses", "recipient_name") && + !db_->Execute("ALTER TABLE server_addresses ADD COLUMN " + "recipient_name VARCHAR")) { + return false; + } + return true; +} + } // namespace autofill
diff --git a/components/autofill/core/browser/webdata/autofill_table.h b/components/autofill/core/browser/webdata/autofill_table.h index a25006a7..221cbe8 100644 --- a/components/autofill/core/browser/webdata/autofill_table.h +++ b/components/autofill/core/browser/webdata/autofill_table.h
@@ -174,6 +174,7 @@ // // id String assigned by the server to identify this address. // This is opaque to the client. +// recipient_name Added in v63. // company_name // street_address The combined lines of the street address. // address_1 Also known as "administrative area". This is normally @@ -358,20 +359,6 @@ bool ClearAutofillProfiles(); // Table migration functions. - // Removes empty values for autofill that were incorrectly stored in the DB - // See bug http://crbug.com/6111 - bool MigrateToVersion22ClearAutofillEmptyValueElements(); - bool MigrateToVersion23AddCardNumberEncryptedColumn(); - bool MigrateToVersion24CleanupOversizedStringFields(); - bool MigrateToVersion27UpdateLegacyCreditCards(); - bool MigrateToVersion30AddDateModifed(); - bool MigrateToVersion31AddGUIDToCreditCardsAndProfiles(); - bool MigrateToVersion32UpdateProfilesAndCreditCards(); - bool MigrateToVersion33ProfilesBasedOnFirstName(); - bool MigrateToVersion34ProfilesBasedOnCountryCode(); - bool MigrateToVersion35GreatBritainCountryCodes(); - bool MigrateToVersion37MergeAndCullOlderProfiles(); - bool MigrateToVersion51AddOriginColumn(); bool MigrateToVersion54AddI18nFieldsAndRemoveDeprecatedFields(); bool MigrateToVersion55MergeAutofillDatesTable(); bool MigrateToVersion56AddProfileLanguageCodeForFormatting(); @@ -379,6 +366,7 @@ bool MigrateToVersion60AddServerCards(); bool MigrateToVersion61AddUsageStats(); bool MigrateToVersion62AddUsageStatsForUnmaskedCards(); + bool MigrateToVersion63AddServerRecipientName(); // Max data length saved in the table; static const size_t kMaxDataLength;
diff --git a/components/autofill/core/browser/webdata/autofill_wallet_syncable_service.cc b/components/autofill/core/browser/webdata/autofill_wallet_syncable_service.cc index a99b3751..7be33a9 100644 --- a/components/autofill/core/browser/webdata/autofill_wallet_syncable_service.cc +++ b/components/autofill/core/browser/webdata/autofill_wallet_syncable_service.cc
@@ -84,6 +84,7 @@ profile.SetRawInfo(ADDRESS_HOME_STREET_ADDRESS, base::UTF8ToUTF16(JoinString(street_address, '\n'))); + profile.SetRawInfo(NAME_FULL, base::UTF8ToUTF16(address.recipient_name())); profile.SetRawInfo(COMPANY_NAME, base::UTF8ToUTF16(address.company_name())); profile.SetRawInfo(ADDRESS_HOME_STATE, base::UTF8ToUTF16(address.address_1()));
diff --git a/components/autofill/ios/DEPS b/components/autofill/ios/DEPS new file mode 100644 index 0000000..450c6e9 --- /dev/null +++ b/components/autofill/ios/DEPS
@@ -0,0 +1,4 @@ +include_rules = [ + "+ios/public/provider/web", + "+ios/web/public", +]
diff --git a/components/autofill/ios/OWNERS b/components/autofill/ios/OWNERS new file mode 100644 index 0000000..ca512d20e --- /dev/null +++ b/components/autofill/ios/OWNERS
@@ -0,0 +1 @@ +jdonnelly@chromium.org
diff --git a/components/autofill/ios/browser/autofill_driver_ios.h b/components/autofill/ios/browser/autofill_driver_ios.h new file mode 100644 index 0000000..1b670f7 --- /dev/null +++ b/components/autofill/ios/browser/autofill_driver_ios.h
@@ -0,0 +1,87 @@ +// 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 COMPONENTS_AUTOFILL_CONTENT_BROWSER_AUTOFILL_DRIVER_IOS_H_ +#define COMPONENTS_AUTOFILL_CONTENT_BROWSER_AUTOFILL_DRIVER_IOS_H_ + +#include <string> + +#include "components/autofill/core/browser/autofill_client.h" +#include "components/autofill/core/browser/autofill_driver.h" +#include "components/autofill/core/browser/autofill_external_delegate.h" +#include "components/autofill/core/browser/autofill_manager.h" +#include "ios/web/public/web_state/web_state_user_data.h" + +namespace web { +class WebState; +} + +@protocol AutofillDriverIOSBridge; + +namespace autofill { + +class AutofillManagerDelegate; + +// Class that drives autofill flow on iOS. There is one instance per +// WebContents. +class AutofillDriverIOS : public AutofillDriver, + public web::WebStateUserData<AutofillDriverIOS> { + public: + static void CreateForWebStateAndDelegate( + web::WebState* web_state, + AutofillClient* client, + id<AutofillDriverIOSBridge> bridge, + const std::string& app_locale, + AutofillManager::AutofillDownloadManagerState enable_download_manager); + + // AutofillDriver: + bool IsOffTheRecord() const override; + net::URLRequestContextGetter* GetURLRequestContext() override; + bool RendererIsAvailable() override; + void SendFormDataToRenderer(int query_id, + RendererFormDataAction action, + const FormData& data) override; + void PingRenderer() override; + void DetectAccountCreationForms( + const std::vector<autofill::FormStructure*>& forms) override; + void SendAutofillTypePredictionsToRenderer( + const std::vector<FormStructure*>& forms) override; + void RendererShouldClearFilledForm() override; + void RendererShouldClearPreviewedForm() override; + void RendererShouldAcceptDataListSuggestion( + const base::string16& value) override; + base::SequencedWorkerPool* GetBlockingPool() override; + + AutofillManager* autofill_manager() { return &autofill_manager_; } + + void RendererShouldFillFieldWithValue(const base::string16& value) override; + void RendererShouldPreviewFieldWithValue( + const base::string16& value) override; + void PopupHidden() override; + + private: + AutofillDriverIOS( + web::WebState* web_state, + AutofillClient* client, + id<AutofillDriverIOSBridge> bridge, + const std::string& app_locale, + AutofillManager::AutofillDownloadManagerState enable_download_manager); + ~AutofillDriverIOS() override; + + // The WebState with which this object is associated. + web::WebState* web_state_; + + // AutofillDriverIOSBridge instance that is passed in. + id<AutofillDriverIOSBridge> bridge_; + + // AutofillManager instance via which this object drives the shared Autofill + // code. + AutofillManager autofill_manager_; + // AutofillExternalDelegate instance that is passed to the AutofillManager. + AutofillExternalDelegate autofill_external_delegate_; +}; + +} // namespace autofill + +#endif // COMPONENTS_AUTOFILL_CONTENT_BROWSER_AUTOFILL_DRIVER_IOS_H_
diff --git a/components/autofill/ios/browser/autofill_driver_ios.mm b/components/autofill/ios/browser/autofill_driver_ios.mm new file mode 100644 index 0000000..1087f9dd --- /dev/null +++ b/components/autofill/ios/browser/autofill_driver_ios.mm
@@ -0,0 +1,104 @@ +// Copyright 2013 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "components/autofill/ios/browser/autofill_driver_ios.h" + +#include "components/autofill/ios/browser/autofill_driver_ios_bridge.h" +#include "ios/web/public/browser_state.h" +#include "ios/web/public/web_state/web_state.h" +#include "ios/web/public/web_thread.h" + +DEFINE_WEB_STATE_USER_DATA_KEY(autofill::AutofillDriverIOS); + +namespace autofill { + +// static +void AutofillDriverIOS::CreateForWebStateAndDelegate( + web::WebState* web_state, + AutofillClient* client, + id<AutofillDriverIOSBridge> bridge, + const std::string& app_locale, + AutofillManager::AutofillDownloadManagerState enable_download_manager) { + if (FromWebState(web_state)) + return; + + web_state->SetUserData( + UserDataKey(), + new AutofillDriverIOS(web_state, client, bridge, app_locale, + enable_download_manager)); +} + +AutofillDriverIOS::AutofillDriverIOS( + web::WebState* web_state, + AutofillClient* client, + id<AutofillDriverIOSBridge> bridge, + const std::string& app_locale, + AutofillManager::AutofillDownloadManagerState enable_download_manager) + : web_state_(web_state), + bridge_(bridge), + autofill_manager_(this, client, app_locale, enable_download_manager), + autofill_external_delegate_(&autofill_manager_, this) { + autofill_manager_.SetExternalDelegate(&autofill_external_delegate_); +} + +AutofillDriverIOS::~AutofillDriverIOS() {} + +bool AutofillDriverIOS::IsOffTheRecord() const { + return web_state_->GetBrowserState()->IsOffTheRecord(); +} + +net::URLRequestContextGetter* AutofillDriverIOS::GetURLRequestContext() { + return web_state_->GetBrowserState()->GetRequestContext(); +} + +base::SequencedWorkerPool* AutofillDriverIOS::GetBlockingPool() { + return web::WebThread::GetBlockingPool(); +} + +bool AutofillDriverIOS::RendererIsAvailable() { + return true; +} + +void AutofillDriverIOS::SendFormDataToRenderer( + int query_id, + RendererFormDataAction action, + const FormData& data) { + [bridge_ onFormDataFilled:query_id result:data]; +} + +void AutofillDriverIOS::PingRenderer() { +} + +void AutofillDriverIOS::DetectAccountCreationForms( + const std::vector<autofill::FormStructure*>& forms) { + autofill_manager_.client()->DetectAccountCreationForms(nullptr, forms); +}; + +void AutofillDriverIOS::SendAutofillTypePredictionsToRenderer( + const std::vector<FormStructure*>& forms) { + [bridge_ sendAutofillTypePredictionsToRenderer:forms]; +} + +void AutofillDriverIOS::RendererShouldAcceptDataListSuggestion( + const base::string16& value) { +} + +void AutofillDriverIOS::RendererShouldClearFilledForm() { +} + +void AutofillDriverIOS::RendererShouldClearPreviewedForm() { +} + +void AutofillDriverIOS::RendererShouldFillFieldWithValue( + const base::string16& value) { +} + +void AutofillDriverIOS::RendererShouldPreviewFieldWithValue( + const base::string16& value) { +} + +void AutofillDriverIOS::PopupHidden() { +} + +} // namespace autofill
diff --git a/components/autofill/ios/browser/autofill_driver_ios_bridge.h b/components/autofill/ios/browser/autofill_driver_ios_bridge.h new file mode 100644 index 0000000..6a00cc85 --- /dev/null +++ b/components/autofill/ios/browser/autofill_driver_ios_bridge.h
@@ -0,0 +1,23 @@ +// 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_AUTOFILL_IOS_BROWSER_AUTOFILL_DRIVER_IOS_BRIDGE_H_ +#define COMPONENTS_AUTOFILL_IOS_BROWSER_AUTOFILL_DRIVER_IOS_BRIDGE_H_ + +namespace autofill { +struct FormData; +class FormStructure; +} + +@protocol AutofillDriverIOSBridge + +- (void)onFormDataFilled:(uint16)query_id + result:(const autofill::FormData&)result; + +- (void)sendAutofillTypePredictionsToRenderer: + (const std::vector<autofill::FormStructure*>&)forms; + +@end + +#endif // COMPONENTS_AUTOFILL_IOS_BROWSER_AUTOFILL_DRIVER_IOS_BRIDGE_H_
diff --git a/components/components.gyp b/components/components.gyp index 17e4235b..db6d9b0 100644 --- a/components/components.gyp +++ b/components/components.gyp
@@ -88,11 +88,15 @@ 'webp_transcode.gypi', ], }], + ['OS != "android"', { + 'includes': [ + 'feedback.gypi', + ] + }], ['OS != "ios" and OS != "android"', { 'includes': [ 'audio_modem.gypi', 'copresence.gypi', - 'feedback.gypi', 'proximity_auth.gypi', 'storage_monitor.gypi', ]
diff --git a/components/components_tests.gyp b/components/components_tests.gyp index 4f44e2b..4a2f56d 100644 --- a/components/components_tests.gyp +++ b/components/components_tests.gyp
@@ -165,6 +165,10 @@ 'enhanced_bookmarks/image_store_ios_unittest.mm', 'enhanced_bookmarks/image_store_unittest.cc', 'enhanced_bookmarks/item_position_unittest.cc', + 'feedback/feedback_common_unittest.cc', + 'feedback/feedback_data_unittest.cc', + 'feedback/feedback_uploader_chrome_unittest.cc', + 'feedback/feedback_uploader_unittest.cc', 'gcm_driver/gcm_account_mapper_unittest.cc', 'gcm_driver/gcm_channel_status_request_unittest.cc', 'gcm_driver/gcm_client_impl_unittest.cc', @@ -397,6 +401,7 @@ 'components.gyp:enhanced_bookmarks', 'components.gyp:enhanced_bookmarks_test_support', 'components.gyp:favicon_base', + 'components.gyp:feedback_component', 'components.gyp:gcm_driver', 'components.gyp:gcm_driver_test_support', 'components.gyp:google_core_browser', @@ -532,43 +537,87 @@ 'webp_transcode/webp_decoder_unittest.mm', ], 'sources/': [ + # First start by excluding all tests on iOS. ['exclude', '\\.cc$'], ['exclude', '\\.mm$'], + + # Include the test runner. ['include', '^test/run_all_unittests\\.cc$'], + + # Include tests for all components that are built on iOS. ['include', '^auto_login_parser/'], - ['include', '^autofill/core/'], + ['include', '^autofill/'], ['include', '^bookmarks/'], + ['include', '^captive_portal/'], + ['include', '^cloud_devices/'], ['include', '^component_updater/'], - ['include', '^crash/'], ['include', '^content_settings/'], + ['include', '^crash/'], + ['include', '^cronet/'], + ['include', '^crx_file/'], ['include', '^data_reduction_proxy/'], + ['include', '^device_event_log/'], ['include', '^dom_distiller/'], + ['include', '^domain_reliability/'], ['include', '^enhanced_bookmarks/'], + ['include', '^error_page/'], + ['include', '^favicon/'], + ['include', '^favicon_base/'], ['include', '^gcm_driver/'], ['include', '^google/'], + ['include', '^handoff/'], ['include', '^history/'], + ['include', '^infobars/'], ['include', '^invalidation/'], ['include', '^json_schema/'], - ['include', '^keyed_service/core/'], + ['include', '^keyed_service/'], ['include', '^language_usage_metrics/'], ['include', '^leveldb_proto/'], + ['include', '^login/'], ['include', '^metrics/'], + ['include', '^navigation_metrics/'], + ['include', '^network_hints/'], ['include', '^network_time/'], + ['include', '^omnibox/'], + ['include', '^onc/'], + ['include', '^open_from_clipboard/'], + ['include', '^os_crypt/'], + ['include', '^ownership/'], + ['include', '^packed_ct_ev_whitelist/'], ['include', '^password_manager/'], - ['include', '^precache/core/'], + ['include', '^policy/'], + ['include', '^precache/'], + ['include', '^pref_registry/'], ['include', '^query_parser/'], + ['include', '^rappor/'], + ['include', '^renderer_context_menu/'], ['include', '^search/'], ['include', '^search_engines/'], ['include', '^search_provider_logos/'], - ['include', '^sessions/ios/'], - ['include', '^sessions/serialized_navigation_entry_unittest\\.cc$'], - ['exclude', '^signin/core/browser/mutable_profile_oauth2_token_service_unittest\\.cc$'], + ['include', '^sessions/'], + ['include', '^signin/'], + ['include', '^startup_metric_utils/'], ['include', '^suggestions/'], ['include', '^sync_driver/'], ['include', '^translate/'], + ['include', '^ui_zoom/'], + ['include', '^update_client/'], ['include', '^url_fixer/'], + ['include', '^url_matcher/'], + ['include', '^user_prefs/'], ['include', '^variations/'], + ['include', '^wallpaper/'], + ['include', '^web_resource/'], + ['include', '^webdata/'], + ['include', '^webdata_services/'], ['include', '^webp_transcode/'], + + # Exclude individual tests that are known not to work on iOS. + ['exclude', '^signin/core/browser/mutable_profile_oauth2_token_service_unittest\\.cc$'], + + # Exclude all tests that depends on //content (based on layered- + # component directory structure). + ['exclude', '^[^/]*/content/'], ], 'dependencies': [ '../ios/ios_tests.gyp:test_support_ios', @@ -634,6 +683,10 @@ 'invalidation/invalidation_service_android_unittest.cc', ], 'sources!': [ + 'feedback/feedback_common_unittest.cc', + 'feedback/feedback_data_unittest.cc', + 'feedback/feedback_uploader_chrome_unittest.cc', + 'feedback/feedback_uploader_unittest.cc', 'gcm_driver/gcm_account_mapper_unittest.cc', 'gcm_driver/gcm_channel_status_request_unittest.cc', 'gcm_driver/gcm_client_impl_unittest.cc', @@ -651,6 +704,7 @@ '../testing/android/native_test.gyp:native_test_native_code', ], 'dependencies!': [ + 'components.gyp:feedback_component', 'components.gyp:storage_monitor', 'components.gyp:storage_monitor_test_support', 'components.gyp:web_modal', @@ -688,10 +742,6 @@ 'copresence/rpc/http_post_unittest.cc', 'copresence/rpc/rpc_handler_unittest.cc', 'copresence/timed_map_unittest.cc', - 'feedback/feedback_common_unittest.cc', - 'feedback/feedback_data_unittest.cc', - 'feedback/feedback_uploader_chrome_unittest.cc', - 'feedback/feedback_uploader_unittest.cc', 'proximity_auth/base64url_unittest.cc', 'proximity_auth/bluetooth_connection_finder_unittest.cc', 'proximity_auth/bluetooth_connection_unittest.cc', @@ -713,7 +763,6 @@ 'components.gyp:copresence', 'components.gyp:copresence_test_support', 'components.gyp:cryptauth', - 'components.gyp:feedback_component', 'components.gyp:proximity_auth', ], }],
diff --git a/components/content_settings/core/browser/content_settings_pref_provider.cc b/components/content_settings/core/browser/content_settings_pref_provider.cc index 1c0dcc35..c506051 100644 --- a/components/content_settings/core/browser/content_settings_pref_provider.cc +++ b/components/content_settings/core/browser/content_settings_pref_provider.cc
@@ -96,7 +96,7 @@ } // Read content settings exceptions. - ReadContentSettingsFromPref(false); + ReadContentSettingsFromPref(); if (!is_incognito_) { UMA_HISTOGRAM_COUNTS("ContentSettings.NumberOfExceptions", @@ -352,7 +352,7 @@ } } -void PrefProvider::ReadContentSettingsFromPref(bool overwrite) { +void PrefProvider::ReadContentSettingsFromPref() { // |DictionaryPrefUpdate| sends out notifications when destructed. This // construction order ensures |AutoLock| gets destroyed first and |lock_| is // not held when the notifications are sent. Also, |auto_reset| must be still @@ -365,8 +365,7 @@ const base::DictionaryValue* all_settings_dictionary = prefs_->GetDictionary(prefs::kContentSettingsPatternPairs); - if (overwrite) - value_map_.clear(); + value_map_.clear(); // Careful: The returned value could be NULL if the pref has never been set. if (!all_settings_dictionary) @@ -491,7 +490,7 @@ if (updating_preferences_) return; - ReadContentSettingsFromPref(true); + ReadContentSettingsFromPref(); NotifyObservers(ContentSettingsPattern(), ContentSettingsPattern(),
diff --git a/components/content_settings/core/browser/content_settings_pref_provider.h b/components/content_settings/core/browser/content_settings_pref_provider.h index 9d715897..0727e10 100644 --- a/components/content_settings/core/browser/content_settings_pref_provider.h +++ b/components/content_settings/core/browser/content_settings_pref_provider.h
@@ -68,9 +68,8 @@ private: friend class DeadlockCheckerThread; // For testing. // Reads all content settings exceptions from the preference and load them - // into the |value_map_|. The |value_map_| is cleared first if |overwrite| is - // true. - void ReadContentSettingsFromPref(bool overwrite); + // into the |value_map_|. The |value_map_| is cleared first. + void ReadContentSettingsFromPref(); // Callback for changes in the pref with the same name. void OnContentSettingsPatternPairsChanged();
diff --git a/components/metrics/metrics_service.cc b/components/metrics/metrics_service.cc index b7aa20e3..54e4deb 100644 --- a/components/metrics/metrics_service.cc +++ b/components/metrics/metrics_service.cc
@@ -248,11 +248,6 @@ } } -bool NewInitialMetricsTimingEnabled() { - return base::FieldTrialList::FindFullName("UMAInitialMetricsTiming") == - "Enabled"; -} - void MarkAppCleanShutdownAndCommit(CleanExitBeacon* clean_exit_beacon, PrefService* local_state) { clean_exit_beacon->WriteBeaconValue(true); @@ -889,30 +884,17 @@ return; case INIT_TASK_DONE: - if (NewInitialMetricsTimingEnabled()) { - PrepareInitialMetricsLog(); - // Stage the first log, which could be a stability log (either one - // for created in this session or from a previous session) or the - // initial metrics log that was just created. - log_manager_.StageNextLogForUpload(); - if (has_initial_stability_log_) { - // The initial stability log was just staged. - has_initial_stability_log_ = false; - state_ = SENDING_INITIAL_STABILITY_LOG; - } else { - state_ = SENDING_INITIAL_METRICS_LOG; - } + PrepareInitialMetricsLog(); + // Stage the first log, which could be a stability log (either one + // for created in this session or from a previous session) or the + // initial metrics log that was just created. + log_manager_.StageNextLogForUpload(); + if (has_initial_stability_log_) { + // The initial stability log was just staged. + has_initial_stability_log_ = false; + state_ = SENDING_INITIAL_STABILITY_LOG; } else { - if (has_initial_stability_log_) { - // There's an initial stability log, ready to send. - log_manager_.StageNextLogForUpload(); - has_initial_stability_log_ = false; - state_ = SENDING_INITIAL_STABILITY_LOG; - } else { - PrepareInitialMetricsLog(); - log_manager_.StageNextLogForUpload(); - state_ = SENDING_INITIAL_METRICS_LOG; - } + state_ = SENDING_INITIAL_METRICS_LOG; } break; @@ -1047,8 +1029,6 @@ ResponseCodeToStatus(response_code), NUM_RESPONSE_STATUSES); - bool suppress_reschedule = false; - bool upload_succeeded = response_code == 200; // Provide boolean for error recovery (allow us to ignore response_code). @@ -1074,16 +1054,8 @@ if (!log_manager_.has_staged_log()) { switch (state_) { case SENDING_INITIAL_STABILITY_LOG: - if (NewInitialMetricsTimingEnabled()) { - // The initial metrics log is already in the queue of unsent logs. - state_ = SENDING_OLD_LOGS; - } else { - PrepareInitialMetricsLog(); - log_manager_.StageNextLogForUpload(); - SendStagedLog(); - state_ = SENDING_INITIAL_METRICS_LOG; - suppress_reschedule = true; - } + // The initial metrics log is already in the queue of unsent logs. + state_ = SENDING_OLD_LOGS; break; case SENDING_INITIAL_METRICS_LOG: @@ -1111,13 +1083,7 @@ // Error 400 indicates a problem with the log, not with the server, so // don't consider that a sign that the server is in trouble. bool server_is_healthy = upload_succeeded || response_code == 400; - // Don't notify the scheduler that the upload is finished if we've only just - // sent the initial stability log, but not yet the initial metrics log (treat - // the two as a single unit of work as far as the scheduler is concerned). - if (!suppress_reschedule) { - scheduler_->UploadFinished(server_is_healthy, - log_manager_.has_unsent_logs()); - } + scheduler_->UploadFinished(server_is_healthy, log_manager_.has_unsent_logs()); if (server_is_healthy) client_->OnLogUploadComplete();
diff --git a/components/search_engines/keyword_table.cc b/components/search_engines/keyword_table.cc index 08dea92..59dff732 100644 --- a/components/search_engines/keyword_table.cc +++ b/components/search_engines/keyword_table.cc
@@ -193,45 +193,6 @@ bool* update_compatible_version) { // Migrate if necessary. switch (version) { - case 21: - *update_compatible_version = true; - return MigrateToVersion21AutoGenerateKeywordColumn(); - case 25: - *update_compatible_version = true; - return MigrateToVersion25AddLogoIDColumn(); - case 26: - *update_compatible_version = true; - return MigrateToVersion26AddCreatedByPolicyColumn(); - case 28: - *update_compatible_version = true; - return MigrateToVersion28SupportsInstantColumn(); - case 29: - *update_compatible_version = true; - return MigrateToVersion29InstantURLToSupportsInstant(); - case 38: - *update_compatible_version = true; - return MigrateToVersion38AddLastModifiedColumn(); - case 39: - *update_compatible_version = true; - return MigrateToVersion39AddSyncGUIDColumn(); - case 44: - *update_compatible_version = true; - return MigrateToVersion44AddDefaultSearchProviderBackup(); - case 45: - *update_compatible_version = true; - return MigrateToVersion45RemoveLogoIDAndAutogenerateColumns(); - case 47: - *update_compatible_version = true; - return MigrateToVersion47AddAlternateURLsColumn(); - case 48: - *update_compatible_version = true; - return MigrateToVersion48RemoveKeywordsBackup(); - case 49: - *update_compatible_version = true; - return MigrateToVersion49AddSearchTermsReplacementKeyColumn(); - case 52: - *update_compatible_version = true; - return MigrateToVersion52AddImageSearchAndPOSTSupport(); case 53: *update_compatible_version = true; return MigrateToVersion53AddNewTabURLColumn(); @@ -315,140 +276,6 @@ return ColumnsForVersion(WebDatabase::kCurrentVersionNumber, false); } -bool KeywordTable::MigrateToVersion21AutoGenerateKeywordColumn() { - return db_->Execute("ALTER TABLE keywords ADD COLUMN autogenerate_keyword " - "INTEGER DEFAULT 0"); -} - -bool KeywordTable::MigrateToVersion25AddLogoIDColumn() { - return db_->Execute( - "ALTER TABLE keywords ADD COLUMN logo_id INTEGER DEFAULT 0"); -} - -bool KeywordTable::MigrateToVersion26AddCreatedByPolicyColumn() { - return db_->Execute("ALTER TABLE keywords ADD COLUMN created_by_policy " - "INTEGER DEFAULT 0"); -} - -bool KeywordTable::MigrateToVersion28SupportsInstantColumn() { - return db_->Execute("ALTER TABLE keywords ADD COLUMN supports_instant " - "INTEGER DEFAULT 0"); -} - -bool KeywordTable::MigrateToVersion29InstantURLToSupportsInstant() { - sql::Transaction transaction(db_); - return transaction.Begin() && - db_->Execute("ALTER TABLE keywords ADD COLUMN instant_url VARCHAR") && - db_->Execute("CREATE TABLE keywords_temp (" - "id INTEGER PRIMARY KEY," - "short_name VARCHAR NOT NULL," - "keyword VARCHAR NOT NULL," - "favicon_url VARCHAR NOT NULL," - "url VARCHAR NOT NULL," - "safe_for_autoreplace INTEGER," - "originating_url VARCHAR," - "date_created INTEGER DEFAULT 0," - "usage_count INTEGER DEFAULT 0," - "input_encodings VARCHAR," - "show_in_default_list INTEGER," - "suggest_url VARCHAR," - "prepopulate_id INTEGER DEFAULT 0," - "autogenerate_keyword INTEGER DEFAULT 0," - "logo_id INTEGER DEFAULT 0," - "created_by_policy INTEGER DEFAULT 0," - "instant_url VARCHAR)") && - db_->Execute("INSERT INTO keywords_temp SELECT id, short_name, keyword, " - "favicon_url, url, safe_for_autoreplace, originating_url, " - "date_created, usage_count, input_encodings, " - "show_in_default_list, suggest_url, prepopulate_id, " - "autogenerate_keyword, logo_id, created_by_policy, " - "instant_url FROM keywords") && - db_->Execute("DROP TABLE keywords") && - db_->Execute("ALTER TABLE keywords_temp RENAME TO keywords") && - transaction.Commit(); -} - -bool KeywordTable::MigrateToVersion38AddLastModifiedColumn() { - return db_->Execute( - "ALTER TABLE keywords ADD COLUMN last_modified INTEGER DEFAULT 0"); -} - -bool KeywordTable::MigrateToVersion39AddSyncGUIDColumn() { - return db_->Execute("ALTER TABLE keywords ADD COLUMN sync_guid VARCHAR"); -} - -bool KeywordTable::MigrateToVersion44AddDefaultSearchProviderBackup() { - std::string query("CREATE TABLE keywords_backup AS SELECT " + - ColumnsForVersion(44, false) + " FROM keywords ORDER BY id ASC"); - sql::Transaction transaction(db_); - return transaction.Begin() && - meta_table_->SetValue("Default Search Provider ID Backup", - GetDefaultSearchProviderID()) && - (!db_->DoesTableExist("keywords_backup") || - db_->Execute("DROP TABLE keywords_backup")) && - db_->Execute(query.c_str()) && - transaction.Commit(); -} - -bool KeywordTable::MigrateToVersion45RemoveLogoIDAndAutogenerateColumns() { - sql::Transaction transaction(db_); - if (!transaction.Begin()) - return false; - - // The version 43 migration should have been written to do this, but since it - // wasn't, we'll do it now. Unfortunately a previous change deleted this for - // some users, so we can't be sure this will succeed (so don't bail on error). - meta_table_->DeleteKey("Default Search Provider Backup"); - - return MigrateKeywordsTableForVersion45("keywords") && - MigrateKeywordsTableForVersion45("keywords_backup") && - meta_table_->SetValue("Default Search Provider ID Backup Signature", - std::string()) && - transaction.Commit(); -} - -bool KeywordTable::MigrateToVersion47AddAlternateURLsColumn() { - sql::Transaction transaction(db_); - return transaction.Begin() && - db_->Execute("ALTER TABLE keywords ADD COLUMN " - "alternate_urls VARCHAR DEFAULT ''") && - db_->Execute("ALTER TABLE keywords_backup ADD COLUMN " - "alternate_urls VARCHAR DEFAULT ''") && - meta_table_->SetValue("Default Search Provider ID Backup Signature", - std::string()) && - transaction.Commit(); -} - -bool KeywordTable::MigrateToVersion48RemoveKeywordsBackup() { - sql::Transaction transaction(db_); - return transaction.Begin() && - meta_table_->DeleteKey("Default Search Provider ID Backup") && - meta_table_->DeleteKey("Default Search Provider ID Backup Signature") && - db_->Execute("DROP TABLE keywords_backup") && - transaction.Commit(); -} - -bool KeywordTable::MigrateToVersion49AddSearchTermsReplacementKeyColumn() { - return db_->Execute("ALTER TABLE keywords ADD COLUMN " - "search_terms_replacement_key VARCHAR DEFAULT ''"); -} - -bool KeywordTable::MigrateToVersion52AddImageSearchAndPOSTSupport() { - sql::Transaction transaction(db_); - return transaction.Begin() && - db_->Execute("ALTER TABLE keywords ADD COLUMN image_url " - "VARCHAR DEFAULT ''") && - db_->Execute("ALTER TABLE keywords ADD COLUMN search_url_post_params " - "VARCHAR DEFAULT ''") && - db_->Execute("ALTER TABLE keywords ADD COLUMN suggest_url_post_params " - "VARCHAR DEFAULT ''") && - db_->Execute("ALTER TABLE keywords ADD COLUMN instant_url_post_params " - "VARCHAR DEFAULT ''") && - db_->Execute("ALTER TABLE keywords ADD COLUMN image_url_post_params " - "VARCHAR DEFAULT ''") && - transaction.Commit(); -} - bool KeywordTable::MigrateToVersion53AddNewTabURLColumn() { return db_->Execute("ALTER TABLE keywords ADD COLUMN new_tab_url " "VARCHAR DEFAULT ''");
diff --git a/components/search_engines/keyword_table.h b/components/search_engines/keyword_table.h index 62e7e79..ef45694 100644 --- a/components/search_engines/keyword_table.h +++ b/components/search_engines/keyword_table.h
@@ -126,19 +126,6 @@ static std::string GetKeywordColumns(); // Table migration functions. - bool MigrateToVersion21AutoGenerateKeywordColumn(); - bool MigrateToVersion25AddLogoIDColumn(); - bool MigrateToVersion26AddCreatedByPolicyColumn(); - bool MigrateToVersion28SupportsInstantColumn(); - bool MigrateToVersion29InstantURLToSupportsInstant(); - bool MigrateToVersion38AddLastModifiedColumn(); - bool MigrateToVersion39AddSyncGUIDColumn(); - bool MigrateToVersion44AddDefaultSearchProviderBackup(); - bool MigrateToVersion45RemoveLogoIDAndAutogenerateColumns(); - bool MigrateToVersion47AddAlternateURLsColumn(); - bool MigrateToVersion48RemoveKeywordsBackup(); - bool MigrateToVersion49AddSearchTermsReplacementKeyColumn(); - bool MigrateToVersion52AddImageSearchAndPOSTSupport(); bool MigrateToVersion53AddNewTabURLColumn(); bool MigrateToVersion59RemoveExtensionKeywords();
diff --git a/components/test/data/web_database/version_20.sql b/components/test/data/web_database/version_20.sql deleted file mode 100644 index c3913ef2..0000000 --- a/components/test/data/web_database/version_20.sql +++ /dev/null
@@ -1,23 +0,0 @@ -PRAGMA foreign_keys=OFF; -BEGIN TRANSACTION; -CREATE TABLE meta(key LONGVARCHAR NOT NULL UNIQUE PRIMARY KEY, value LONGVARCHAR); -INSERT INTO "meta" VALUES('version','20'); -INSERT INTO "meta" VALUES('last_compatible_version','20'); -INSERT INTO "meta" VALUES('Builtin Keyword Version','27'); -INSERT INTO "meta" VALUES('Default Search Provider ID','7'); -CREATE TABLE keywords (id INTEGER PRIMARY KEY,short_name VARCHAR NOT NULL, keyword VARCHAR NOT NULL,favicon_url VARCHAR NOT NULL,url VARCHAR NOT NULL,show_in_default_list INTEGER,safe_for_autoreplace INTEGER,originating_url VARCHAR,date_created INTEGER DEFAULT 0,usage_count INTEGER DEFAULT 0,input_encodings VARCHAR,suggest_url VARCHAR,prepopulate_id INTEGER DEFAULT 0); -INSERT INTO "keywords" VALUES(2,'Google','google.com','http://www.google.com/favicon.ico','{google:baseURL}search?{google:RLZ}{google:acceptedSuggestion}{google:originalQueryForSuggestion}sourceid=chrome&ie={inputEncoding}&q={searchTerms}',1,1,'',0,0,'UTF-8','{google:baseSuggestURL}search?client=chrome&hl={language}&q={searchTerms}',1); -INSERT INTO "keywords" VALUES(3,'Yahoo!','yahoo.com','http://search.yahoo.com/favicon.ico','http://search.yahoo.com/search?ei={inputEncoding}&fr=crmas&p={searchTerms}',1,1,'',0,0,'UTF-8','http://ff.search.yahoo.com/gossip?output=fxjson&command={searchTerms}',2); -INSERT INTO "keywords" VALUES(4,'Bing','bing.com','http://www.bing.com/s/wlflag.ico','http://www.bing.com/search?setmkt=en-US&q={searchTerms}',1,1,'',0,0,'UTF-8','http://api.bing.com/osjson.aspx?query={searchTerms}&language={language}',3); -INSERT INTO "keywords" VALUES(5,'Wikipedia (en)','en.wikipedia.org','','http://en.wikipedia.org/w/index.php?title=Special:Search&search={searchTerms}',1,0,'',1283287335,0,'','',0); -INSERT INTO "keywords" VALUES(6,'NYTimes','query.nytimes.com','','http://query.nytimes.com/gst/handler.html?query={searchTerms}&opensearch=1',1,0,'',1283287335,0,'','',0); -INSERT INTO "keywords" VALUES(7,'eBay','rover.ebay.com','','http://rover.ebay.com/rover/1/711-43047-14818-1/4?satitle={searchTerms}',1,0,'',1283287335,0,'','',0); -INSERT INTO "keywords" VALUES(8,'ff','ff','','http://ff{searchTerms}',0,0,'',1283287356,0,'','',0); -CREATE TABLE logins (origin_url VARCHAR NOT NULL, action_url VARCHAR, username_element VARCHAR, username_value VARCHAR, password_element VARCHAR, password_value BLOB, submit_element VARCHAR,signon_realm VARCHAR NOT NULL,ssl_valid INTEGER NOT NULL,preferred INTEGER NOT NULL,date_created INTEGER NOT NULL,blacklisted_by_user INTEGER NOT NULL,scheme INTEGER NOT NULL,UNIQUE (origin_url, username_element, username_value, password_element, submit_element, signon_realm)); -CREATE TABLE ie7_logins (url_hash VARCHAR NOT NULL, password_value BLOB, date_created INTEGER NOT NULL,UNIQUE (url_hash)); -CREATE TABLE web_app_icons (url LONGVARCHAR,width int,height int,image BLOB, UNIQUE (url, width, height)); -CREATE TABLE web_apps (url LONGVARCHAR UNIQUE,has_all_images INTEGER NOT NULL); -CREATE INDEX logins_signon ON logins (signon_realm); -CREATE INDEX ie7_logins_hash ON ie7_logins (url_hash); -CREATE INDEX web_apps_url_index ON web_apps (url); -COMMIT;
diff --git a/components/test/data/web_database/version_21.sql b/components/test/data/web_database/version_21.sql deleted file mode 100644 index a77ab7e..0000000 --- a/components/test/data/web_database/version_21.sql +++ /dev/null
@@ -1,40 +0,0 @@ -PRAGMA foreign_keys=OFF; -BEGIN TRANSACTION; -CREATE TABLE meta(key LONGVARCHAR NOT NULL UNIQUE PRIMARY KEY, value LONGVARCHAR); -INSERT INTO "meta" VALUES('version','21'); -INSERT INTO "meta" VALUES('last_compatible_version','21'); -INSERT INTO "meta" VALUES('Builtin Keyword Version','27'); -INSERT INTO "meta" VALUES('Default Search Provider ID','7'); -CREATE TABLE keywords (id INTEGER PRIMARY KEY,short_name VARCHAR NOT NULL, keyword VARCHAR NOT NULL,favicon_url VARCHAR NOT NULL,url VARCHAR NOT NULL,show_in_default_list INTEGER,safe_for_autoreplace INTEGER,originating_url VARCHAR,date_created INTEGER DEFAULT 0,usage_count INTEGER DEFAULT 0,input_encodings VARCHAR,suggest_url VARCHAR,prepopulate_id INTEGER DEFAULT 0,autogenerate_keyword INTEGER DEFAULT 0); -INSERT INTO "keywords" VALUES(2,'Google','google.com','http://www.google.com/favicon.ico','{google:baseURL}search?{google:RLZ}{google:acceptedSuggestion}{google:originalQueryForSuggestion}sourceid=chrome&ie={inputEncoding}&q={searchTerms}',1,1,'',0,0,'UTF-8','{google:baseSuggestURL}search?client=chrome&hl={language}&q={searchTerms}',1,1); -INSERT INTO "keywords" VALUES(3,'Yahoo!','yahoo.com','http://search.yahoo.com/favicon.ico','http://search.yahoo.com/search?ei={inputEncoding}&fr=crmas&p={searchTerms}',1,1,'',0,0,'UTF-8','http://ff.search.yahoo.com/gossip?output=fxjson&command={searchTerms}',2,0); -INSERT INTO "keywords" VALUES(4,'Bing','bing.com','http://www.bing.com/s/wlflag.ico','http://www.bing.com/search?setmkt=en-US&q={searchTerms}',1,1,'',0,0,'UTF-8','http://api.bing.com/osjson.aspx?query={searchTerms}&language={language}',3,0); -INSERT INTO "keywords" VALUES(5,'Wikipedia (en)','en.wikipedia.org','','http://en.wikipedia.org/w/index.php?title=Special:Search&search={searchTerms}',1,0,'',1283287335,0,'','',0,0); -INSERT INTO "keywords" VALUES(6,'NYTimes','query.nytimes.com','','http://query.nytimes.com/gst/handler.html?query={searchTerms}&opensearch=1',1,0,'',1283287335,0,'','',0,0); -INSERT INTO "keywords" VALUES(7,'eBay','rover.ebay.com','','http://rover.ebay.com/rover/1/711-43047-14818-1/4?satitle={searchTerms}',1,0,'',1283287335,0,'','',0,0); -INSERT INTO "keywords" VALUES(8,'ff','ff','','http://ff{searchTerms}',0,0,'',1283287356,0,'','',0,0); -CREATE TABLE logins (origin_url VARCHAR NOT NULL, action_url VARCHAR, username_element VARCHAR, username_value VARCHAR, password_element VARCHAR, password_value BLOB, submit_element VARCHAR,signon_realm VARCHAR NOT NULL,ssl_valid INTEGER NOT NULL,preferred INTEGER NOT NULL,date_created INTEGER NOT NULL,blacklisted_by_user INTEGER NOT NULL,scheme INTEGER NOT NULL,UNIQUE (origin_url, username_element, username_value, password_element, submit_element, signon_realm)); -CREATE TABLE ie7_logins (url_hash VARCHAR NOT NULL, password_value BLOB, date_created INTEGER NOT NULL,UNIQUE (url_hash)); -CREATE TABLE web_app_icons (url LONGVARCHAR,width int,height int,image BLOB, UNIQUE (url, width, height)); -CREATE TABLE web_apps (url LONGVARCHAR UNIQUE,has_all_images INTEGER NOT NULL); -CREATE TABLE autofill (name VARCHAR, value VARCHAR, value_lower VARCHAR, pair_id INTEGER PRIMARY KEY, count INTEGER DEFAULT 1); -INSERT INTO "autofill" VALUES('Name','John Doe','john doe',10,1); -INSERT INTO "autofill" VALUES('Name','','',11,1); -INSERT INTO "autofill" VALUES('Email','jane@example.com','jane@example.com',20,3); -INSERT INTO "autofill" VALUES('Email','','',21,4); -CREATE TABLE autofill_dates ( pair_id INTEGER DEFAULT 0,date_created INTEGER DEFAULT 0); -INSERT INTO "autofill_dates" VALUES(10,1384299100); -INSERT INTO "autofill_dates" VALUES(11,1384299200); -INSERT INTO "autofill_dates" VALUES(20,1384299300); -INSERT INTO "autofill_dates" VALUES(20,1384299301); -INSERT INTO "autofill_dates" VALUES(21,1384299401); -INSERT INTO "autofill_dates" VALUES(21,1384299400); -INSERT INTO "autofill_dates" VALUES(21,1384299403); -INSERT INTO "autofill_dates" VALUES(21,1384299402); -CREATE INDEX logins_signon ON logins (signon_realm); -CREATE INDEX ie7_logins_hash ON ie7_logins (url_hash); -CREATE INDEX web_apps_url_index ON web_apps (url); -CREATE INDEX autofill_name ON autofill (name); -CREATE INDEX autofill_name_value_lower ON autofill (name, value_lower); -CREATE INDEX autofill_dates_pair_id ON autofill_dates (pair_id); -COMMIT;
diff --git a/components/test/data/web_database/version_22.sql b/components/test/data/web_database/version_22.sql deleted file mode 100644 index c7cc8b5..0000000 --- a/components/test/data/web_database/version_22.sql +++ /dev/null
@@ -1,28 +0,0 @@ -PRAGMA foreign_keys=OFF; -BEGIN TRANSACTION; -CREATE TABLE meta(key LONGVARCHAR NOT NULL UNIQUE PRIMARY KEY, value LONGVARCHAR); -INSERT INTO "meta" VALUES('version','22'); -INSERT INTO "meta" VALUES('last_compatible_version','21'); -INSERT INTO "meta" VALUES('Builtin Keyword Version','27'); -INSERT INTO "meta" VALUES('Default Search Provider ID','7'); -CREATE TABLE keywords (id INTEGER PRIMARY KEY,short_name VARCHAR NOT NULL, keyword VARCHAR NOT NULL,favicon_url VARCHAR NOT NULL,url VARCHAR NOT NULL,show_in_default_list INTEGER,safe_for_autoreplace INTEGER,originating_url VARCHAR,date_created INTEGER DEFAULT 0,usage_count INTEGER DEFAULT 0,input_encodings VARCHAR,suggest_url VARCHAR,prepopulate_id INTEGER DEFAULT 0,autogenerate_keyword INTEGER DEFAULT 0); -INSERT INTO "keywords" VALUES(2,'Google','google.com','http://www.google.com/favicon.ico','{google:baseURL}search?{google:RLZ}{google:acceptedSuggestion}{google:originalQueryForSuggestion}sourceid=chrome&ie={inputEncoding}&q={searchTerms}',1,1,'',0,0,'UTF-8','{google:baseSuggestURL}search?client=chrome&hl={language}&q={searchTerms}',1,1); -INSERT INTO "keywords" VALUES(3,'Yahoo!','yahoo.com','http://search.yahoo.com/favicon.ico','http://search.yahoo.com/search?ei={inputEncoding}&fr=crmas&p={searchTerms}',1,1,'',0,0,'UTF-8','http://ff.search.yahoo.com/gossip?output=fxjson&command={searchTerms}',2,0); -INSERT INTO "keywords" VALUES(4,'Bing','bing.com','http://www.bing.com/s/wlflag.ico','http://www.bing.com/search?setmkt=en-US&q={searchTerms}',1,1,'',0,0,'UTF-8','http://api.bing.com/osjson.aspx?query={searchTerms}&language={language}',3,0); -INSERT INTO "keywords" VALUES(5,'Wikipedia (en)','en.wikipedia.org','','http://en.wikipedia.org/w/index.php?title=Special:Search&search={searchTerms}',1,0,'',1283287335,0,'','',0,0); -INSERT INTO "keywords" VALUES(6,'NYTimes','query.nytimes.com','','http://query.nytimes.com/gst/handler.html?query={searchTerms}&opensearch=1',1,0,'',1283287335,0,'','',0,0); -INSERT INTO "keywords" VALUES(7,'eBay','rover.ebay.com','','http://rover.ebay.com/rover/1/711-43047-14818-1/4?satitle={searchTerms}',1,0,'',1283287335,0,'','',0,0); -INSERT INTO "keywords" VALUES(8,'ff','ff','','http://ff{searchTerms}',0,0,'',1283287356,0,'','',0,0); -CREATE TABLE logins (origin_url VARCHAR NOT NULL, action_url VARCHAR, username_element VARCHAR, username_value VARCHAR, password_element VARCHAR, password_value BLOB, submit_element VARCHAR,signon_realm VARCHAR NOT NULL,ssl_valid INTEGER NOT NULL,preferred INTEGER NOT NULL,date_created INTEGER NOT NULL,blacklisted_by_user INTEGER NOT NULL,scheme INTEGER NOT NULL,UNIQUE (origin_url, username_element, username_value, password_element, submit_element, signon_realm)); -CREATE TABLE ie7_logins (url_hash VARCHAR NOT NULL, password_value BLOB, date_created INTEGER NOT NULL,UNIQUE (url_hash)); -CREATE TABLE web_app_icons (url LONGVARCHAR,width int,height int,image BLOB, UNIQUE (url, width, height)); -CREATE TABLE web_apps (url LONGVARCHAR UNIQUE,has_all_images INTEGER NOT NULL); -CREATE TABLE autofill (name VARCHAR, value VARCHAR, value_lower VARCHAR, pair_id INTEGER PRIMARY KEY, count INTEGER DEFAULT 1); -CREATE TABLE autofill_dates ( pair_id INTEGER DEFAULT 0,date_created INTEGER DEFAULT 0); -CREATE INDEX logins_signon ON logins (signon_realm); -CREATE INDEX ie7_logins_hash ON ie7_logins (url_hash); -CREATE INDEX web_apps_url_index ON web_apps (url); -CREATE INDEX autofill_name ON autofill (name); -CREATE INDEX autofill_name_value_lower ON autofill (name, value_lower); -CREATE INDEX autofill_dates_pair_id ON autofill_dates (pair_id); -COMMIT;
diff --git a/components/test/data/web_database/version_22_corrupt.sql b/components/test/data/web_database/version_22_corrupt.sql deleted file mode 100644 index 82d9b3f..0000000 --- a/components/test/data/web_database/version_22_corrupt.sql +++ /dev/null
@@ -1,32 +0,0 @@ -PRAGMA foreign_keys=OFF; -BEGIN TRANSACTION; -CREATE TABLE meta(key LONGVARCHAR NOT NULL UNIQUE PRIMARY KEY,value LONGVARCHAR); -INSERT INTO "meta" VALUES('version','22'); -INSERT INTO "meta" VALUES('last_compatible_version','21'); -INSERT INTO "meta" VALUES('Default Search Provider ID','2'); -INSERT INTO "meta" VALUES('Builtin Keyword Version','29'); -CREATE TABLE keywords (id INTEGER PRIMARY KEY,short_name VARCHAR NOT NULL,keyword VARCHAR NOT NULL,favicon_url VARCHAR NOT NULL,url VARCHAR NOT NULL,show_in_default_list INTEGER,safe_for_autoreplace INTEGER,originating_url VARCHAR,date_created INTEGER DEFAULT 0,usage_count INTEGER DEFAULT 0,input_encodings VARCHAR,suggest_url VARCHAR,prepopulate_id INTEGER DEFAULT 0,autogenerate_keyword INTEGER DEFAULT 0); -INSERT INTO "keywords" VALUES(2,'Google','google.com','http://www.google.com/favicon.ico','{google:baseURL}search?{google:RLZ}{google:acceptedSuggestion}{google:originalQueryForSuggestion}sourceid=chrome&ie={inputEncoding}&q={searchTerms}',1,1,'',0,0,'UTF-8','{google:baseSuggestURL}search?client=chrome&hl={language}&q={searchTerms}',1,1); -INSERT INTO "keywords" VALUES(3,'Yahoo!','yahoo.com','http://search.yahoo.com/favicon.ico','http://search.yahoo.com/search?ei={inputEncoding}&fr=crmas&p={searchTerms}',1,1,'',0,0,'UTF-8','http://ff.search.yahoo.com/gossip?output=fxjson&command={searchTerms}',2,0); -INSERT INTO "keywords" VALUES(4,'Bing','bing.com','http://www.bing.com/s/wlflag.ico','http://www.bing.com/search?setmkt=en-US&q={searchTerms}',1,1,'',0,0,'UTF-8','http://api.bing.com/osjson.aspx?query={searchTerms}&language={language}',3,0); -INSERT INTO "keywords" VALUES(5,'Wikipedia (en)','en.wikipedia.org','','http://en.wikipedia.org/w/index.php?title=Special:Search&search={searchTerms}',1,0,'',1283287335,0,'','',0,0); -INSERT INTO "keywords" VALUES(6,'NYTimes','query.nytimes.com','','http://query.nytimes.com/gst/handler.html?query={searchTerms}&opensearch=1',1,0,'',1283287335,0,'','',0,0); -INSERT INTO "keywords" VALUES(7,'eBay','rover.ebay.com','','http://rover.ebay.com/rover/1/711-43047-14818-1/4?satitle={searchTerms}',1,0,'',1283287335,0,'','',0,0); -INSERT INTO "keywords" VALUES(8,'ff','ff','','http://ff{searchTerms}',0,0,'',1283287356,0,'','',0,0); -CREATE TABLE logins (origin_url VARCHAR NOT NULL, action_url VARCHAR, username_element VARCHAR, username_value VARCHAR, password_element VARCHAR, password_value BLOB, submit_element VARCHAR, signon_realm VARCHAR NOT NULL, ssl_valid INTEGER NOT NULL,preferred INTEGER NOT NULL, date_created INTEGER NOT NULL,blacklisted_by_user INTEGER NOT NULL, scheme INTEGER NOT NULL,UNIQUE (origin_url, username_element, username_value, password_element, submit_element, signon_realm)); -CREATE TABLE ie7_logins (url_hash VARCHAR NOT NULL, password_value BLOB,date_created INTEGER NOT NULL,UNIQUE (url_hash)); -CREATE TABLE web_app_icons (url LONGVARCHAR,width int,height int,image BLOB, UNIQUE (url, width, height)); -CREATE TABLE web_apps (url LONGVARCHAR UNIQUE,has_all_images INTEGER NOT NULL); -CREATE TABLE autofill (name VARCHAR, value VARCHAR, value_lower VARCHAR, pair_id INTEGER PRIMARY KEY, count INTEGER DEFAULT 1); -CREATE TABLE autofill_dates ( pair_id INTEGER DEFAULT 0,date_created INTEGER DEFAULT 0); -CREATE TABLE autofill_profiles ( label VARCHAR, unique_id INTEGER PRIMARY KEY, first_name VARCHAR, middle_name VARCHAR, last_name VARCHAR, email VARCHAR, company_name VARCHAR, address_line_1 VARCHAR, address_line_2 VARCHAR, city VARCHAR, state VARCHAR, zipcode VARCHAR, country VARCHAR, phone VARCHAR, fax VARCHAR); -CREATE TABLE credit_cards ( label VARCHAR, unique_id INTEGER PRIMARY KEY, name_on_card VARCHAR, type VARCHAR,card_number VARCHAR, expiration_month INTEGER, expiration_year INTEGER, verification_code VARCHAR, billing_address VARCHAR, shipping_address VARCHAR, card_number_encrypted BLOB, verification_code_encrypted BLOB); -CREATE INDEX logins_signon ON logins (signon_realm); -CREATE INDEX ie7_logins_hash ON ie7_logins (url_hash); -CREATE INDEX web_apps_url_index ON web_apps (url); -CREATE INDEX autofill_name ON autofill (name); -CREATE INDEX autofill_name_value_lower ON autofill (name, value_lower); -CREATE INDEX autofill_dates_pair_id ON autofill_dates (pair_id); -CREATE INDEX autofill_profiles_label_index ON autofill_profiles (label); -CREATE INDEX credit_cards_label_index ON credit_cards (label); -COMMIT;
diff --git a/components/test/data/web_database/version_25.sql b/components/test/data/web_database/version_25.sql deleted file mode 100644 index 986ca9f..0000000 --- a/components/test/data/web_database/version_25.sql +++ /dev/null
@@ -1,23 +0,0 @@ -PRAGMA foreign_keys=OFF; -BEGIN TRANSACTION; -CREATE TABLE meta(key LONGVARCHAR NOT NULL UNIQUE PRIMARY KEY,value LONGVARCHAR); -INSERT INTO "meta" VALUES('version','25'); -INSERT INTO "meta" VALUES('last_compatible_version','25'); -INSERT INTO "meta" VALUES('Builtin Keyword Version','29'); -CREATE TABLE keywords (id INTEGER PRIMARY KEY,short_name VARCHAR NOT NULL,keyword VARCHAR NOT NULL,favicon_url VARCHAR NOT NULL,url VARCHAR NOT NULL,show_in_default_list INTEGER,safe_for_autoreplace INTEGER,originating_url VARCHAR,date_created INTEGER DEFAULT 0,usage_count INTEGER DEFAULT 0,input_encodings VARCHAR,suggest_url VARCHAR,prepopulate_id INTEGER DEFAULT 0,autogenerate_keyword INTEGER DEFAULT 0,logo_id INTEGER DEFAULT 0); -CREATE TABLE logins (origin_url VARCHAR NOT NULL, action_url VARCHAR,username_element VARCHAR, username_value VARCHAR,password_element VARCHAR, password_value BLOB, submit_element VARCHAR,signon_realm VARCHAR NOT NULL,ssl_valid INTEGER NOT NULL,preferred INTEGER NOT NULL,date_created INTEGER NOT NULL,blacklisted_by_user INTEGER NOT NULL,scheme INTEGER NOT NULL,UNIQUE (origin_url, username_element,username_value, password_element, submit_element, signon_realm)); -CREATE TABLE web_app_icons (url LONGVARCHAR,width int,height int,image BLOB, UNIQUE (url, width, height)); -CREATE TABLE web_apps (url LONGVARCHAR UNIQUE,has_all_images INTEGER NOT NULL); -CREATE TABLE autofill (name VARCHAR, value VARCHAR, value_lower VARCHAR,pair_id INTEGER PRIMARY KEY, count INTEGER DEFAULT 1); -CREATE TABLE autofill_dates ( pair_id INTEGER DEFAULT 0,date_created INTEGER DEFAULT 0); -CREATE TABLE autofill_profiles ( label VARCHAR,unique_id INTEGER PRIMARY KEY, first_name VARCHAR,middle_name VARCHAR, last_name VARCHAR, email VARCHAR,company_name VARCHAR, address_line_1 VARCHAR, address_line_2 VARCHAR,city VARCHAR, state VARCHAR, zipcode VARCHAR, country VARCHAR,phone VARCHAR, fax VARCHAR); -CREATE TABLE credit_cards ( label VARCHAR, unique_id INTEGER PRIMARY KEY,name_on_card VARCHAR, type VARCHAR, card_number VARCHAR,expiration_month INTEGER, expiration_year INTEGER,verification_code VARCHAR, billing_address VARCHAR,shipping_address VARCHAR, card_number_encrypted BLOB,verification_code_encrypted BLOB); -CREATE TABLE token_service (service VARCHAR PRIMARY KEY NOT NULL,encrypted_token BLOB); -CREATE INDEX logins_signon ON logins (signon_realm); -CREATE INDEX web_apps_url_index ON web_apps (url); -CREATE INDEX autofill_name ON autofill (name); -CREATE INDEX autofill_name_value_lower ON autofill (name, value_lower); -CREATE INDEX autofill_dates_pair_id ON autofill_dates (pair_id); -CREATE INDEX autofill_profiles_label_index ON autofill_profiles (label); -CREATE INDEX credit_cards_label_index ON credit_cards (label); -COMMIT;
diff --git a/components/test/data/web_database/version_26.sql b/components/test/data/web_database/version_26.sql deleted file mode 100644 index 5cf1a97..0000000 --- a/components/test/data/web_database/version_26.sql +++ /dev/null
@@ -1,23 +0,0 @@ -PRAGMA foreign_keys=OFF; -BEGIN TRANSACTION; -CREATE TABLE meta(key LONGVARCHAR NOT NULL UNIQUE PRIMARY KEY,value LONGVARCHAR); -INSERT INTO "meta" VALUES('version','26'); -INSERT INTO "meta" VALUES('last_compatible_version','26'); -INSERT INTO "meta" VALUES('Builtin Keyword Version','29'); -CREATE TABLE keywords (id INTEGER PRIMARY KEY,short_name VARCHAR NOT NULL,keyword VARCHAR NOT NULL,favicon_url VARCHAR NOT NULL,url VARCHAR NOT NULL,show_in_default_list INTEGER,safe_for_autoreplace INTEGER,originating_url VARCHAR,date_created INTEGER DEFAULT 0,usage_count INTEGER DEFAULT 0,input_encodings VARCHAR,suggest_url VARCHAR,prepopulate_id INTEGER DEFAULT 0,autogenerate_keyword INTEGER DEFAULT 0,logo_id INTEGER DEFAULT 0,created_by_policy INTEGER DEFAULT 0); -CREATE TABLE logins (origin_url VARCHAR NOT NULL, action_url VARCHAR,username_element VARCHAR, username_value VARCHAR,password_element VARCHAR, password_value BLOB, submit_element VARCHAR,signon_realm VARCHAR NOT NULL,ssl_valid INTEGER NOT NULL,preferred INTEGER NOT NULL,date_created INTEGER NOT NULL,blacklisted_by_user INTEGER NOT NULL,scheme INTEGER NOT NULL,UNIQUE (origin_url, username_element,username_value, password_element, submit_element, signon_realm)); -CREATE TABLE web_app_icons (url LONGVARCHAR,width int,height int,image BLOB, UNIQUE (url, width, height)); -CREATE TABLE web_apps (url LONGVARCHAR UNIQUE,has_all_images INTEGER NOT NULL); -CREATE TABLE autofill (name VARCHAR, value VARCHAR, value_lower VARCHAR,pair_id INTEGER PRIMARY KEY, count INTEGER DEFAULT 1); -CREATE TABLE autofill_dates ( pair_id INTEGER DEFAULT 0,date_created INTEGER DEFAULT 0); -CREATE TABLE autofill_profiles ( label VARCHAR,unique_id INTEGER PRIMARY KEY, first_name VARCHAR,middle_name VARCHAR, last_name VARCHAR, email VARCHAR,company_name VARCHAR, address_line_1 VARCHAR, address_line_2 VARCHAR,city VARCHAR, state VARCHAR, zipcode VARCHAR, country VARCHAR,phone VARCHAR, fax VARCHAR); -CREATE TABLE credit_cards ( label VARCHAR, unique_id INTEGER PRIMARY KEY,name_on_card VARCHAR, type VARCHAR, card_number VARCHAR,expiration_month INTEGER, expiration_year INTEGER,verification_code VARCHAR, billing_address VARCHAR,shipping_address VARCHAR, card_number_encrypted BLOB,verification_code_encrypted BLOB); -CREATE TABLE token_service (service VARCHAR PRIMARY KEY NOT NULL,encrypted_token BLOB); -CREATE INDEX logins_signon ON logins (signon_realm); -CREATE INDEX web_apps_url_index ON web_apps (url); -CREATE INDEX autofill_name ON autofill (name); -CREATE INDEX autofill_name_value_lower ON autofill (name, value_lower); -CREATE INDEX autofill_dates_pair_id ON autofill_dates (pair_id); -CREATE INDEX autofill_profiles_label_index ON autofill_profiles (label); -CREATE INDEX credit_cards_label_index ON credit_cards (label); -COMMIT;
diff --git a/components/test/data/web_database/version_27.sql b/components/test/data/web_database/version_27.sql deleted file mode 100644 index 4733afa..0000000 --- a/components/test/data/web_database/version_27.sql +++ /dev/null
@@ -1,26 +0,0 @@ -PRAGMA foreign_keys=OFF; -BEGIN TRANSACTION; -CREATE TABLE meta(key LONGVARCHAR NOT NULL UNIQUE PRIMARY KEY,value LONGVARCHAR); -INSERT INTO "meta" VALUES('version','27'); -INSERT INTO "meta" VALUES('last_compatible_version','27'); -INSERT INTO "meta" VALUES('Builtin Keyword Version','29'); -CREATE TABLE keywords (id INTEGER PRIMARY KEY,short_name VARCHAR NOT NULL,keyword VARCHAR NOT NULL,favicon_url VARCHAR NOT NULL,url VARCHAR NOT NULL,show_in_default_list INTEGER,safe_for_autoreplace INTEGER,originating_url VARCHAR,date_created INTEGER DEFAULT 0,usage_count INTEGER DEFAULT 0,input_encodings VARCHAR,suggest_url VARCHAR,prepopulate_id INTEGER DEFAULT 0,autogenerate_keyword INTEGER DEFAULT 0,logo_id INTEGER DEFAULT 0,created_by_policy INTEGER DEFAULT 0); -INSERT INTO "keywords" VALUES(2,'Google','google.com','http://www.google.com/favicon.ico','{google:baseURL}search?{google:RLZ}{google:acceptedSuggestion}{google:originalQueryForSuggestion}sourceid=chrome&ie={inputEncoding}&q={searchTerms}',1,1,'',0,0,'UTF-8','{google:baseSuggestURL}search?client=chrome&hl={language}&q={searchTerms}',1,1,6245,0); -CREATE TABLE logins (origin_url VARCHAR NOT NULL, action_url VARCHAR, username_element VARCHAR, username_value VARCHAR, password_element VARCHAR, password_value BLOB, submit_element VARCHAR, signon_realm VARCHAR NOT NULL,ssl_valid INTEGER NOT NULL,preferred INTEGER NOT NULL,date_created INTEGER NOT NULL,blacklisted_by_user INTEGER NOT NULL,scheme INTEGER NOT NULL,UNIQUE (origin_url, username_element, username_value, password_element, submit_element, signon_realm)); -CREATE TABLE ie7_logins (url_hash VARCHAR NOT NULL, password_value BLOB, date_created INTEGER NOT NULL,UNIQUE (url_hash)); -CREATE TABLE web_app_icons (url LONGVARCHAR,width int,height int,image BLOB, UNIQUE (url, width, height)); -CREATE TABLE web_apps (url LONGVARCHAR UNIQUE,has_all_images INTEGER NOT NULL); -CREATE TABLE autofill (name VARCHAR, value VARCHAR, value_lower VARCHAR, pair_id INTEGER PRIMARY KEY, count INTEGER DEFAULT 1); -CREATE TABLE autofill_dates ( pair_id INTEGER DEFAULT 0, date_created INTEGER DEFAULT 0); -CREATE TABLE autofill_profiles ( label VARCHAR, unique_id INTEGER PRIMARY KEY, first_name VARCHAR, middle_name VARCHAR, last_name VARCHAR, email VARCHAR, company_name VARCHAR, address_line_1 VARCHAR, address_line_2 VARCHAR, city VARCHAR, state VARCHAR, zipcode VARCHAR, country VARCHAR, phone VARCHAR, fax VARCHAR); -CREATE TABLE credit_cards ( label VARCHAR, unique_id INTEGER PRIMARY KEY, name_on_card VARCHAR, type VARCHAR, card_number VARCHAR, expiration_month INTEGER, expiration_year INTEGER, verification_code VARCHAR, billing_address VARCHAR, shipping_address VARCHAR, card_number_encrypted BLOB, verification_code_encrypted BLOB); -CREATE TABLE token_service (service VARCHAR PRIMARY KEY NOT NULL,encrypted_token BLOB); -CREATE INDEX logins_signon ON logins (signon_realm); -CREATE INDEX ie7_logins_hash ON ie7_logins (url_hash); -CREATE INDEX web_apps_url_index ON web_apps (url); -CREATE INDEX autofill_name ON autofill (name); -CREATE INDEX autofill_name_value_lower ON autofill (name, value_lower); -CREATE INDEX autofill_dates_pair_id ON autofill_dates (pair_id); -CREATE INDEX autofill_profiles_label_index ON autofill_profiles (label); -CREATE INDEX credit_cards_label_index ON credit_cards (label); -COMMIT;
diff --git a/components/test/data/web_database/version_29.sql b/components/test/data/web_database/version_29.sql deleted file mode 100644 index ab03275..0000000 --- a/components/test/data/web_database/version_29.sql +++ /dev/null
@@ -1,29 +0,0 @@ -PRAGMA foreign_keys=OFF; -BEGIN TRANSACTION; -CREATE TABLE meta(key LONGVARCHAR NOT NULL UNIQUE PRIMARY KEY,value LONGVARCHAR); -INSERT INTO "meta" VALUES('version','29'); -INSERT INTO "meta" VALUES('last_compatible_version','29'); -INSERT INTO "meta" VALUES('Default Search Provider ID','2'); -INSERT INTO "meta" VALUES('Builtin Keyword Version','29'); -CREATE TABLE keywords (id INTEGER PRIMARY KEY,short_name VARCHAR NOT NULL,keyword VARCHAR NOT NULL,favicon_url VARCHAR NOT NULL,url VARCHAR NOT NULL,show_in_default_list INTEGER,safe_for_autoreplace INTEGER,originating_url VARCHAR,date_created INTEGER DEFAULT 0,usage_count INTEGER DEFAULT 0,input_encodings VARCHAR,suggest_url VARCHAR,prepopulate_id INTEGER DEFAULT 0,autogenerate_keyword INTEGER DEFAULT 0,logo_id INTEGER DEFAULT 0,created_by_policy INTEGER DEFAULT 0,instant_url VARCHAR); -INSERT INTO "keywords" VALUES(2,'Google','google.com','http://www.google.com/favicon.ico','{google:baseURL}search?{google:RLZ}{google:acceptedSuggestion}{google:originalQueryForSuggestion}sourceid=chrome&ie={inputEncoding}&q={searchTerms}',1,1,'',0,0,'UTF-8','{google:baseSuggestURL}search?client=chrome&hl={language}&q={searchTerms}',1,1,6245,0,'{google:baseURL}search?{google:RLZ}sourceid=chrome-instant&ie={inputEncoding}&q={searchTerms}'); -INSERT INTO "keywords" VALUES(3,'Yahoo!','yahoo.com','http://search.yahoo.com/favicon.ico','http://search.yahoo.com/search?ei={inputEncoding}&fr=crmas&p={searchTerms}',1,1,'',0,0,'UTF-8','http://ff.search.yahoo.com/gossip?output=fxjson&command={searchTerms}',2,0,6262,0,''); -INSERT INTO "keywords" VALUES(4,'Bing','bing.com','http://www.bing.com/s/wlflag.ico','http://www.bing.com/search?setmkt=en-US&q={searchTerms}',1,1,'',0,0,'UTF-8','http://api.bing.com/osjson.aspx?query={searchTerms}&language={language}',3,0,6239,0,''); -CREATE TABLE logins (origin_url VARCHAR NOT NULL, action_url VARCHAR, username_element VARCHAR, username_value VARCHAR, password_element VARCHAR, password_value BLOB, submit_element VARCHAR, signon_realm VARCHAR NOT NULL,ssl_valid INTEGER NOT NULL,preferred INTEGER NOT NULL,date_created INTEGER NOT NULL,blacklisted_by_user INTEGER NOT NULL,scheme INTEGER NOT NULL,UNIQUE (origin_url, username_element, username_value, password_element, submit_element, signon_realm)); -CREATE TABLE web_app_icons (url LONGVARCHAR,width int,height int,image BLOB, UNIQUE (url, width, height)); -CREATE TABLE web_apps (url LONGVARCHAR UNIQUE,has_all_images INTEGER NOT NULL); -CREATE TABLE autofill (name VARCHAR, value VARCHAR, value_lower VARCHAR, pair_id INTEGER PRIMARY KEY, count INTEGER DEFAULT 1); -CREATE TABLE autofill_dates ( pair_id INTEGER DEFAULT 0, date_created INTEGER DEFAULT 0); -CREATE TABLE autofill_profiles ( label VARCHAR, unique_id INTEGER PRIMARY KEY, first_name VARCHAR, middle_name VARCHAR, last_name VARCHAR, email VARCHAR, company_name VARCHAR, address_line_1 VARCHAR, address_line_2 VARCHAR, city VARCHAR, state VARCHAR, zipcode VARCHAR, country VARCHAR, phone VARCHAR, fax VARCHAR); -INSERT INTO "autofill_profiles" VALUES('Santa Claus, 1 Reindeer Lane',1,'Santa','','Claus','','','1 Reindeer Lane','P.O. Box 56009','North Pole','','H0H 0H0','CANADA','',''); -CREATE TABLE credit_cards ( label VARCHAR, unique_id INTEGER PRIMARY KEY, name_on_card VARCHAR, type VARCHAR, card_number VARCHAR, expiration_month INTEGER, expiration_year INTEGER, verification_code VARCHAR, billing_address VARCHAR, shipping_address VARCHAR, card_number_encrypted BLOB, verification_code_encrypted BLOB); -INSERT INTO "credit_cards" VALUES('',2,'Kris Kringle','','',12,2020,'','1','',X'',X''); -CREATE TABLE token_service (service VARCHAR PRIMARY KEY NOT NULL,encrypted_token BLOB); -CREATE INDEX logins_signon ON logins (signon_realm); -CREATE INDEX web_apps_url_index ON web_apps (url); -CREATE INDEX autofill_name ON autofill (name); -CREATE INDEX autofill_name_value_lower ON autofill (name, value_lower); -CREATE INDEX autofill_dates_pair_id ON autofill_dates (pair_id); -CREATE INDEX autofill_profiles_label_index ON autofill_profiles (label); -CREATE INDEX credit_cards_label_index ON credit_cards (label); -COMMIT;
diff --git a/components/test/data/web_database/version_30.sql b/components/test/data/web_database/version_30.sql deleted file mode 100644 index 698605c..0000000 --- a/components/test/data/web_database/version_30.sql +++ /dev/null
@@ -1,31 +0,0 @@ -PRAGMA foreign_keys=OFF; -BEGIN TRANSACTION; -CREATE TABLE meta(key LONGVARCHAR NOT NULL UNIQUE PRIMARY KEY,value LONGVARCHAR); -INSERT INTO "meta" VALUES('version','30'); -INSERT INTO "meta" VALUES('last_compatible_version','30'); -INSERT INTO "meta" VALUES('Default Search Provider ID','2'); -INSERT INTO "meta" VALUES('Builtin Keyword Version','30'); -CREATE TABLE keywords (id INTEGER PRIMARY KEY,short_name VARCHAR NOT NULL,keyword VARCHAR NOT NULL,favicon_url VARCHAR NOT NULL,url VARCHAR NOT NULL,show_in_default_list INTEGER,safe_for_autoreplace INTEGER,originating_url VARCHAR,date_created INTEGER DEFAULT 0,usage_count INTEGER DEFAULT 0,input_encodings VARCHAR,suggest_url VARCHAR,prepopulate_id INTEGER DEFAULT 0,autogenerate_keyword INTEGER DEFAULT 0,logo_id INTEGER DEFAULT 0,created_by_policy INTEGER DEFAULT 0,instant_url VARCHAR); -INSERT INTO "keywords" VALUES(2,'Google','google.com','http://www.google.com/favicon.ico','{google:baseURL}search?{google:RLZ}{google:acceptedSuggestion}{google:originalQueryForSuggestion}sourceid=chrome&ie={inputEncoding}&q={searchTerms}',1,1,'',0,0,'UTF-8','{google:baseSuggestURL}search?client=chrome&hl={language}&q={searchTerms}',1,1,6245,0,'{google:baseURL}search?{google:RLZ}sourceid=chrome-instant&ie={inputEncoding}&q={searchTerms}'); -INSERT INTO "keywords" VALUES(3,'Yahoo!','yahoo.com','http://search.yahoo.com/favicon.ico','http://search.yahoo.com/search?ei={inputEncoding}&fr=crmas&p={searchTerms}',1,1,'',0,0,'UTF-8','http://ff.search.yahoo.com/gossip?output=fxjson&command={searchTerms}',2,0,6262,0,''); -INSERT INTO "keywords" VALUES(4,'Bing','bing.com','http://www.bing.com/s/wlflag.ico','http://www.bing.com/search?setmkt=en-US&q={searchTerms}',1,1,'',0,0,'UTF-8','http://api.bing.com/osjson.aspx?query={searchTerms}&language={language}',3,0,6239,0,''); -CREATE TABLE logins (origin_url VARCHAR NOT NULL, action_url VARCHAR, username_element VARCHAR, username_value VARCHAR, password_element VARCHAR, password_value BLOB, submit_element VARCHAR, signon_realm VARCHAR NOT NULL,ssl_valid INTEGER NOT NULL,preferred INTEGER NOT NULL,date_created INTEGER NOT NULL,blacklisted_by_user INTEGER NOT NULL,scheme INTEGER NOT NULL,UNIQUE (origin_url, username_element, username_value, password_element, submit_element, signon_realm)); -CREATE TABLE web_app_icons (url LONGVARCHAR,width int,height int,image BLOB, UNIQUE (url, width, height)); -CREATE TABLE web_apps (url LONGVARCHAR UNIQUE,has_all_images INTEGER NOT NULL); -CREATE TABLE autofill (name VARCHAR, value VARCHAR, value_lower VARCHAR, pair_id INTEGER PRIMARY KEY, count INTEGER DEFAULT 1); -CREATE TABLE autofill_dates ( pair_id INTEGER DEFAULT 0, date_created INTEGER DEFAULT 0); -CREATE TABLE autofill_profiles ( label VARCHAR, unique_id INTEGER PRIMARY KEY, first_name VARCHAR, middle_name VARCHAR, last_name VARCHAR, email VARCHAR, company_name VARCHAR, address_line_1 VARCHAR, address_line_2 VARCHAR, city VARCHAR, state VARCHAR, zipcode VARCHAR, country VARCHAR, phone VARCHAR, fax VARCHAR, date_modified INTEGER NOT NULL DEFAULT 0); -INSERT INTO "autofill_profiles" VALUES('Jim Johnson, 789 4th Street',1,'Jim','','Johnson','jim@acme.com','Acme Inc.','789 4th Street','Apt. #4','San Francisco','CA','94102','USA','4155512255','4155512233',1287508123); -INSERT INTO "autofill_profiles" VALUES('Billy Jean, 1 Ghost Blvd.',3,'Billy','','Jean','billy@thriller.com','Thriller Inc.','1 Ghost Blvd.','','Santa Monica','CA','98990','USA','4431110000','',1287508123); -CREATE TABLE credit_cards ( label VARCHAR, unique_id INTEGER PRIMARY KEY, name_on_card VARCHAR, type VARCHAR, card_number VARCHAR, expiration_month INTEGER, expiration_year INTEGER, verification_code VARCHAR, billing_address VARCHAR, shipping_address VARCHAR, card_number_encrypted BLOB, verification_code_encrypted BLOB, date_modified INTEGER NOT NULL DEFAULT 0); -INSERT INTO "credit_cards" VALUES('',2,'Jim X Johnson','','',1,2011,'','1','',X'763130B83A1BEE0CFD7C447C270685B5E2BFF5EC0BC700B38F4C4DD60CDD5D8D66EB09',X'',1287508123); -INSERT INTO "credit_cards" VALUES('2',4,'Billy X Jean','','',7,2017,'','3','',X'763130EB3DC27FA61AAC9EAC92B303978DD7B62E901B4D9DFB459905E09AAAE7AE7BA1',X'',1287508123); -CREATE TABLE token_service (service VARCHAR PRIMARY KEY NOT NULL,encrypted_token BLOB); -CREATE INDEX logins_signon ON logins (signon_realm); -CREATE INDEX web_apps_url_index ON web_apps (url); -CREATE INDEX autofill_name ON autofill (name); -CREATE INDEX autofill_name_value_lower ON autofill (name, value_lower); -CREATE INDEX autofill_dates_pair_id ON autofill_dates (pair_id); -CREATE INDEX autofill_profiles_label_index ON autofill_profiles (label); -CREATE INDEX credit_cards_label_index ON credit_cards (label); -COMMIT;
diff --git a/components/test/data/web_database/version_31.sql b/components/test/data/web_database/version_31.sql deleted file mode 100644 index bfa7443..0000000 --- a/components/test/data/web_database/version_31.sql +++ /dev/null
@@ -1,29 +0,0 @@ -PRAGMA foreign_keys=OFF; -BEGIN TRANSACTION; -CREATE TABLE meta(key LONGVARCHAR NOT NULL UNIQUE PRIMARY KEY,value LONGVARCHAR); -INSERT INTO "meta" VALUES('version','31'); -INSERT INTO "meta" VALUES('last_compatible_version','31'); -INSERT INTO "meta" VALUES('Default Search Provider ID','2'); -INSERT INTO "meta" VALUES('Builtin Keyword Version','32'); -CREATE TABLE keywords (id INTEGER PRIMARY KEY,short_name VARCHAR NOT NULL,keyword VARCHAR NOT NULL,favicon_url VARCHAR NOT NULL,url VARCHAR NOT NULL,show_in_default_list INTEGER,safe_for_autoreplace INTEGER,originating_url VARCHAR,date_created INTEGER DEFAULT 0,usage_count INTEGER DEFAULT 0,input_encodings VARCHAR,suggest_url VARCHAR,prepopulate_id INTEGER DEFAULT 0,autogenerate_keyword INTEGER DEFAULT 0,logo_id INTEGER DEFAULT 0,created_by_policy INTEGER DEFAULT 0,instant_url VARCHAR); -INSERT INTO "keywords" VALUES(2,'Google','google.com','http://www.google.com/favicon.ico','{google:baseURL}search?{google:RLZ}{google:acceptedSuggestion}{google:originalQueryForSuggestion}sourceid=chrome&ie={inputEncoding}&q={searchTerms}',1,1,'',0,0,'UTF-8','{google:baseSuggestURL}search?client=chrome&hl={language}&q={searchTerms}',1,1,6247,0,'{google:baseURL}webhp?{google:RLZ}sourceid=chrome-instant&ie={inputEncoding}&ion=1{searchTerms}'); -INSERT INTO "keywords" VALUES(3,'Yahoo!','yahoo.com','http://search.yahoo.com/favicon.ico','http://search.yahoo.com/search?ei={inputEncoding}&fr=crmas&p={searchTerms}',1,1,'',0,0,'UTF-8','http://ff.search.yahoo.com/gossip?output=fxjson&command={searchTerms}',2,0,6264,0,''); -INSERT INTO "keywords" VALUES(4,'Bing','bing.com','http://www.bing.com/s/wlflag.ico','http://www.bing.com/search?q={searchTerms}',1,1,'',0,0,'UTF-8','http://api.bing.com/osjson.aspx?query={searchTerms}&language={language}',3,0,6241,0,''); -CREATE TABLE logins (origin_url VARCHAR NOT NULL, action_url VARCHAR, username_element VARCHAR, username_value VARCHAR, password_element VARCHAR, password_value BLOB, submit_element VARCHAR, signon_realm VARCHAR NOT NULL,ssl_valid INTEGER NOT NULL,preferred INTEGER NOT NULL,date_created INTEGER NOT NULL,blacklisted_by_user INTEGER NOT NULL,scheme INTEGER NOT NULL,UNIQUE (origin_url, username_element, username_value, password_element, submit_element, signon_realm)); -CREATE TABLE web_app_icons (url LONGVARCHAR,width int,height int,image BLOB, UNIQUE (url, width, height)); -CREATE TABLE web_apps (url LONGVARCHAR UNIQUE,has_all_images INTEGER NOT NULL); -CREATE TABLE autofill (name VARCHAR, value VARCHAR, value_lower VARCHAR, pair_id INTEGER PRIMARY KEY, count INTEGER DEFAULT 1); -CREATE TABLE autofill_dates ( pair_id INTEGER DEFAULT 0, date_created INTEGER DEFAULT 0); -CREATE TABLE autofill_profiles ( label VARCHAR, unique_id INTEGER PRIMARY KEY, first_name VARCHAR, middle_name VARCHAR, last_name VARCHAR, email VARCHAR, company_name VARCHAR, address_line_1 VARCHAR, address_line_2 VARCHAR, city VARCHAR, state VARCHAR, zipcode VARCHAR, country VARCHAR, phone VARCHAR, fax VARCHAR, date_modified INTEGER NOT NULL DEFAULT 0, guid VARCHAR NOT NULL DEFAULT ""); -INSERT INTO "autofill_profiles" VALUES('Elvis Presley, 1122 PBJ Lane',1,'Elvis','','Presley','elvis@elvis.com','Hip Shake Inc.','1122 PBJ Lane','Suite 1','Memphis','TN','38116','UK','9013323322','',1288642516,'A4FF32F6-EF3F-379A-87F2-40A8811182A7'); -CREATE TABLE credit_cards ( label VARCHAR, unique_id INTEGER PRIMARY KEY, name_on_card VARCHAR, type VARCHAR, card_number VARCHAR, expiration_month INTEGER, expiration_year INTEGER, verification_code VARCHAR, billing_address VARCHAR, shipping_address VARCHAR, card_number_encrypted BLOB, verification_code_encrypted BLOB, date_modified INTEGER NOT NULL DEFAULT 0, guid VARCHAR NOT NULL DEFAULT ""); -INSERT INTO "credit_cards" VALUES('',2,'Jim J Jones','','',1,2011,'','0','',X'7631309863E9F1F33C2BDBFBFC86708448BDD8B37A495B628C8459A60D0CCD1047E69F',X'',1288642516,'B77F749C-8B0E-44B2-D299-3C80A95E0ADD'); -CREATE TABLE token_service (service VARCHAR PRIMARY KEY NOT NULL,encrypted_token BLOB); -CREATE INDEX logins_signon ON logins (signon_realm); -CREATE INDEX web_apps_url_index ON web_apps (url); -CREATE INDEX autofill_name ON autofill (name); -CREATE INDEX autofill_name_value_lower ON autofill (name, value_lower); -CREATE INDEX autofill_dates_pair_id ON autofill_dates (pair_id); -CREATE INDEX autofill_profiles_label_index ON autofill_profiles (label); -CREATE INDEX credit_cards_label_index ON credit_cards (label); -COMMIT;
diff --git a/components/test/data/web_database/version_32.sql b/components/test/data/web_database/version_32.sql deleted file mode 100644 index 7030608..0000000 --- a/components/test/data/web_database/version_32.sql +++ /dev/null
@@ -1,33 +0,0 @@ -PRAGMA foreign_keys=OFF; -BEGIN TRANSACTION; -CREATE TABLE meta(key LONGVARCHAR NOT NULL UNIQUE PRIMARY KEY,value LONGVARCHAR); -INSERT INTO "meta" VALUES('version','32'); -INSERT INTO "meta" VALUES('last_compatible_version','32'); -INSERT INTO "meta" VALUES('Default Search Provider ID','2'); -INSERT INTO "meta" VALUES('Builtin Keyword Version','33'); -CREATE TABLE keywords (id INTEGER PRIMARY KEY,short_name VARCHAR NOT NULL,keyword VARCHAR NOT NULL,favicon_url VARCHAR NOT NULL,url VARCHAR NOT NULL,show_in_default_list INTEGER,safe_for_autoreplace INTEGER,originating_url VARCHAR,date_created INTEGER DEFAULT 0,usage_count INTEGER DEFAULT 0,input_encodings VARCHAR,suggest_url VARCHAR,prepopulate_id INTEGER DEFAULT 0,autogenerate_keyword INTEGER DEFAULT 0,logo_id INTEGER DEFAULT 0,created_by_policy INTEGER DEFAULT 0,instant_url VARCHAR); -INSERT INTO "keywords" VALUES(2,'Google','google.com','http://www.google.com/favicon.ico','{google:baseURL}search?{google:RLZ}{google:acceptedSuggestion}{google:originalQueryForSuggestion}sourceid=chrome&ie={inputEncoding}&q={searchTerms}',1,1,'',0,0,'UTF-8','{google:baseSuggestURL}search?client=chrome&hl={language}&q={searchTerms}',1,1,6256,0,'{google:baseURL}webhp?{google:RLZ}sourceid=chrome-instant&ie={inputEncoding}&ion=1{searchTerms}&nord=1'); -INSERT INTO "keywords" VALUES(3,'Yahoo!','yahoo.com','http://search.yahoo.com/favicon.ico','http://search.yahoo.com/search?ei={inputEncoding}&fr=crmas&p={searchTerms}',1,1,'',0,0,'UTF-8','http://ff.search.yahoo.com/gossip?output=fxjson&command={searchTerms}',2,0,6273,0,''); -INSERT INTO "keywords" VALUES(4,'Bing','bing.com','http://www.bing.com/s/wlflag.ico','http://www.bing.com/search?setmkt=en-US&q={searchTerms}',1,1,'',0,0,'UTF-8','http://api.bing.com/osjson.aspx?query={searchTerms}&language={language}',3,0,6250,0,''); -CREATE TABLE logins (origin_url VARCHAR NOT NULL, action_url VARCHAR, username_element VARCHAR, username_value VARCHAR, password_element VARCHAR, password_value BLOB, submit_element VARCHAR, signon_realm VARCHAR NOT NULL,ssl_valid INTEGER NOT NULL,preferred INTEGER NOT NULL,date_created INTEGER NOT NULL,blacklisted_by_user INTEGER NOT NULL,scheme INTEGER NOT NULL,UNIQUE (origin_url, username_element, username_value, password_element, submit_element, signon_realm)); -CREATE TABLE web_app_icons (url LONGVARCHAR,width int,height int,image BLOB, UNIQUE (url, width, height)); -CREATE TABLE web_apps (url LONGVARCHAR UNIQUE,has_all_images INTEGER NOT NULL); -CREATE TABLE autofill (name VARCHAR, value VARCHAR, value_lower VARCHAR, pair_id INTEGER PRIMARY KEY, count INTEGER DEFAULT 1); -CREATE TABLE autofill_dates ( pair_id INTEGER DEFAULT 0, date_created INTEGER DEFAULT 0); -CREATE TABLE autofill_profiles ( guid VARCHAR PRIMARY KEY, label VARCHAR, first_name VARCHAR, middle_name VARCHAR, last_name VARCHAR, email VARCHAR, company_name VARCHAR, address_line_1 VARCHAR, address_line_2 VARCHAR, city VARCHAR, state VARCHAR, zipcode VARCHAR, country VARCHAR, phone VARCHAR, fax VARCHAR, date_modified INTEGER NOT NULL DEFAULT 0); -INSERT INTO "autofill_profiles" VALUES('00580526-FF81-EE2A-0546-1AC593A32E2F','John Doe, 1 Main St','John','','Doe','john@doe.com','Doe Enterprises','1 Main St','Apt 1','Los Altos','CA','94022','USA','4151112222','4153334444',1297882100); -INSERT INTO "autofill_profiles" VALUES('589636FD-9037-3053-200C-80ABC97D7344','John P. Doe, 1 Main St','John','P.','Doe','john@doe.com','Doe Enterprises','1 Main St','Apt 1','Los Altos','CA','94022','USA','4151112222','4153334444',1297882100); -INSERT INTO "autofill_profiles" VALUES('4C74A9D8-7EEE-423E-F9C2-E7FA70ED1396','Dave Smith, 2 Main Street','Dave','','Smith','','','2 Main Street','','Los Altos','CA','94022','USA','','',1297882100); -INSERT INTO "autofill_profiles" VALUES('722DF5C4-F74A-294A-46F0-31FFDED0D635','Dave Smith, 2 Main St','Dave','','Smith','','','2 Main St','','Los Altos','CA','94022','USA','','',1297882100); -INSERT INTO "autofill_profiles" VALUES('584282AC-5D21-8D73-A2DB-4F892EF61F3F','Alfred E Newman, a@e.com','Alfred','E','Newman','a@e.com','','','','','','','','','',1297882100); -INSERT INTO "autofill_profiles" VALUES('9E5FE298-62C7-83DF-6293-381BC589183F','3 Main St, Los Altos','','','','','','3 Main St','','Los Altos','CA','94022','USA','','',1297882100); -CREATE TABLE credit_cards ( guid VARCHAR PRIMARY KEY, label VARCHAR, name_on_card VARCHAR, expiration_month INTEGER, expiration_year INTEGER, card_number_encrypted BLOB, date_modified INTEGER NOT NULL DEFAULT 0); -CREATE TABLE token_service (service VARCHAR PRIMARY KEY NOT NULL,encrypted_token BLOB); -CREATE INDEX logins_signon ON logins (signon_realm); -CREATE INDEX web_apps_url_index ON web_apps (url); -CREATE INDEX autofill_name ON autofill (name); -CREATE INDEX autofill_name_value_lower ON autofill (name, value_lower); -CREATE INDEX autofill_dates_pair_id ON autofill_dates (pair_id); -CREATE INDEX autofill_profiles_label_index ON autofill_profiles (label); -CREATE INDEX credit_cards_label_index ON credit_cards (label); -COMMIT;
diff --git a/components/test/data/web_database/version_33.sql b/components/test/data/web_database/version_33.sql deleted file mode 100644 index a5eb2ae9..0000000 --- a/components/test/data/web_database/version_33.sql +++ /dev/null
@@ -1,32 +0,0 @@ -PRAGMA foreign_keys=OFF; -BEGIN TRANSACTION; -CREATE TABLE meta(key LONGVARCHAR NOT NULL UNIQUE PRIMARY KEY,value LONGVARCHAR); -INSERT INTO "meta" VALUES('version','33'); -INSERT INTO "meta" VALUES('last_compatible_version','33'); -INSERT INTO "meta" VALUES('Default Search Provider ID','2'); -INSERT INTO "meta" VALUES('Builtin Keyword Version','33'); -CREATE TABLE keywords (id INTEGER PRIMARY KEY,short_name VARCHAR NOT NULL,keyword VARCHAR NOT NULL,favicon_url VARCHAR NOT NULL,url VARCHAR NOT NULL,show_in_default_list INTEGER,safe_for_autoreplace INTEGER,originating_url VARCHAR,date_created INTEGER DEFAULT 0,usage_count INTEGER DEFAULT 0,input_encodings VARCHAR,suggest_url VARCHAR,prepopulate_id INTEGER DEFAULT 0,autogenerate_keyword INTEGER DEFAULT 0,logo_id INTEGER DEFAULT 0,created_by_policy INTEGER DEFAULT 0,instant_url VARCHAR); -INSERT INTO "keywords" VALUES(2,'Google','google.com','http://www.google.com/favicon.ico','{google:baseURL}search?{google:RLZ}{google:acceptedSuggestion}{google:originalQueryForSuggestion}sourceid=chrome&ie={inputEncoding}&q={searchTerms}',1,1,'',0,0,'UTF-8','{google:baseSuggestURL}search?client=chrome&hl={language}&q={searchTerms}',1,1,6256,0,'{google:baseURL}webhp?{google:RLZ}sourceid=chrome-instant&ie={inputEncoding}&ion=1{searchTerms}&nord=1'); -INSERT INTO "keywords" VALUES(3,'Yahoo!','yahoo.com','http://search.yahoo.com/favicon.ico','http://search.yahoo.com/search?ei={inputEncoding}&fr=crmas&p={searchTerms}',1,1,'',0,0,'UTF-8','http://ff.search.yahoo.com/gossip?output=fxjson&command={searchTerms}',2,0,6273,0,''); -INSERT INTO "keywords" VALUES(4,'Bing','bing.com','http://www.bing.com/s/wlflag.ico','http://www.bing.com/search?setmkt=en-US&q={searchTerms}',1,1,'',0,0,'UTF-8','http://api.bing.com/osjson.aspx?query={searchTerms}&language={language}',3,0,6250,0,''); -CREATE TABLE logins (origin_url VARCHAR NOT NULL, action_url VARCHAR, username_element VARCHAR, username_value VARCHAR, password_element VARCHAR, password_value BLOB, submit_element VARCHAR, signon_realm VARCHAR NOT NULL,ssl_valid INTEGER NOT NULL,preferred INTEGER NOT NULL,date_created INTEGER NOT NULL,blacklisted_by_user INTEGER NOT NULL,scheme INTEGER NOT NULL,UNIQUE (origin_url, username_element, username_value, password_element, submit_element, signon_realm)); -CREATE TABLE web_app_icons (url LONGVARCHAR,width int,height int,image BLOB, UNIQUE (url, width, height)); -CREATE TABLE web_apps (url LONGVARCHAR UNIQUE,has_all_images INTEGER NOT NULL); -CREATE TABLE autofill (name VARCHAR, value VARCHAR, value_lower VARCHAR, pair_id INTEGER PRIMARY KEY, count INTEGER DEFAULT 1); -CREATE TABLE autofill_dates ( pair_id INTEGER DEFAULT 0, date_created INTEGER DEFAULT 0); -CREATE TABLE autofill_profiles ( guid VARCHAR PRIMARY KEY, company_name VARCHAR, address_line_1 VARCHAR, address_line_2 VARCHAR, city VARCHAR, state VARCHAR, zipcode VARCHAR, country VARCHAR, date_modified INTEGER NOT NULL DEFAULT 0); -INSERT INTO "autofill_profiles" VALUES('45285F35-4A04-5F47-DBCC-CA8C2F2A5944','Hip Shake Inc.','1122 PBJ Lane','Suite 1','Memphis','TN','38116','United States',1298621949); -CREATE TABLE autofill_profile_names ( guid VARCHAR, first_name VARCHAR, middle_name VARCHAR, last_name VARCHAR); -INSERT INTO "autofill_profile_names" VALUES('45285F35-4A04-5F47-DBCC-CA8C2F2A5944','Elvis','','Presley'); -CREATE TABLE autofill_profile_emails ( guid VARCHAR, email VARCHAR); -INSERT INTO "autofill_profile_emails" VALUES('45285F35-4A04-5F47-DBCC-CA8C2F2A5944','elvis@elvis.com'); -CREATE TABLE autofill_profile_phones ( guid VARCHAR, type INTEGER DEFAULT 0, number VARCHAR); -INSERT INTO "autofill_profile_phones" VALUES('45285F35-4A04-5F47-DBCC-CA8C2F2A5944',0,'9013323322'); -CREATE TABLE credit_cards ( guid VARCHAR PRIMARY KEY, name_on_card VARCHAR, expiration_month INTEGER, expiration_year INTEGER, card_number_encrypted BLOB, date_modified INTEGER NOT NULL DEFAULT 0); -CREATE TABLE token_service (service VARCHAR PRIMARY KEY NOT NULL,encrypted_token BLOB); -CREATE INDEX logins_signon ON logins (signon_realm); -CREATE INDEX web_apps_url_index ON web_apps (url); -CREATE INDEX autofill_name ON autofill (name); -CREATE INDEX autofill_name_value_lower ON autofill (name, value_lower); -CREATE INDEX autofill_dates_pair_id ON autofill_dates (pair_id); -COMMIT;
diff --git a/components/test/data/web_database/version_34.sql b/components/test/data/web_database/version_34.sql deleted file mode 100644 index 8a29a95..0000000 --- a/components/test/data/web_database/version_34.sql +++ /dev/null
@@ -1,54 +0,0 @@ -PRAGMA foreign_keys=OFF; -BEGIN TRANSACTION; -CREATE TABLE meta(key LONGVARCHAR NOT NULL UNIQUE PRIMARY KEY,value LONGVARCHAR); -INSERT INTO "meta" VALUES('Default Search Provider ID','2'); -INSERT INTO "meta" VALUES('Builtin Keyword Version','33'); -INSERT INTO "meta" VALUES('version','34'); -INSERT INTO "meta" VALUES('last_compatible_version','34'); -CREATE TABLE keywords (id INTEGER PRIMARY KEY,short_name VARCHAR NOT NULL,keyword VARCHAR NOT NULL,favicon_url VARCHAR NOT NULL,url VARCHAR NOT NULL,show_in_default_list INTEGER,safe_for_autoreplace INTEGER,originating_url VARCHAR,date_created INTEGER DEFAULT 0,usage_count INTEGER DEFAULT 0,input_encodings VARCHAR,suggest_url VARCHAR,prepopulate_id INTEGER DEFAULT 0,autogenerate_keyword INTEGER DEFAULT 0,logo_id INTEGER DEFAULT 0,created_by_policy INTEGER DEFAULT 0,instant_url VARCHAR); -INSERT INTO "keywords" VALUES(2,'Google','google.com','http://www.google.com/favicon.ico','{google:baseURL}search?{google:RLZ}{google:acceptedSuggestion}{google:originalQueryForSuggestion}sourceid=chrome&ie={inputEncoding}&q={searchTerms}',1,1,'',0,0,'UTF-8','{google:baseSuggestURL}search?client=chrome&hl={language}&q={searchTerms}',1,1,6256,0,'{google:baseURL}webhp?{google:RLZ}sourceid=chrome-instant&ie={inputEncoding}&ion=1{searchTerms}&nord=1'); -INSERT INTO "keywords" VALUES(3,'Yahoo!','yahoo.com','http://search.yahoo.com/favicon.ico','http://search.yahoo.com/search?ei={inputEncoding}&fr=crmas&p={searchTerms}',1,1,'',0,0,'UTF-8','http://ff.search.yahoo.com/gossip?output=fxjson&command={searchTerms}',2,0,6273,0,''); -INSERT INTO "keywords" VALUES(4,'Bing','bing.com','http://www.bing.com/s/wlflag.ico','http://www.bing.com/search?setmkt=en-US&q={searchTerms}',1,1,'',0,0,'UTF-8','http://api.bing.com/osjson.aspx?query={searchTerms}&language={language}',3,0,6250,0,''); -INSERT INTO "keywords" VALUES(5,'Search the web (Babylon)','search.babylon.com','','http://search.babylon.com/web/{searchTerms}?babsrc=browsersearch',1,0,'',1299093361,0,'','',0,0,0,0,''); -CREATE TABLE logins (origin_url VARCHAR NOT NULL, action_url VARCHAR, username_element VARCHAR, username_value VARCHAR, password_element VARCHAR, password_value BLOB, submit_element VARCHAR, signon_realm VARCHAR NOT NULL,ssl_valid INTEGER NOT NULL,preferred INTEGER NOT NULL,date_created INTEGER NOT NULL,blacklisted_by_user INTEGER NOT NULL,scheme INTEGER NOT NULL,UNIQUE (origin_url, username_element, username_value, password_element, submit_element, signon_realm)); -CREATE TABLE ie7_logins (url_hash VARCHAR NOT NULL, password_value BLOB, date_created INTEGER NOT NULL,UNIQUE (url_hash)); -CREATE TABLE web_app_icons (url LONGVARCHAR,width int,height int,image BLOB, UNIQUE (url, width, height)); -CREATE TABLE web_apps (url LONGVARCHAR UNIQUE,has_all_images INTEGER NOT NULL); -CREATE TABLE autofill (name VARCHAR, value VARCHAR, value_lower VARCHAR, pair_id INTEGER PRIMARY KEY, count INTEGER DEFAULT 1); -INSERT INTO "autofill" VALUES('firstname','David','david',1,1); -INSERT INTO "autofill" VALUES('lastname','Holloway','holloway',2,1); -INSERT INTO "autofill" VALUES('email','d@gmail.com','d@gmail.com',3,1); -INSERT INTO "autofill" VALUES('phone','415-551-2222','415-551-2222',4,1); -INSERT INTO "autofill" VALUES('fax','415-551-2222','415-551-2222',5,1); -INSERT INTO "autofill" VALUES('address','1122 Boogie Boogie Avenue','1122 boogie boogie avenue',6,1); -INSERT INTO "autofill" VALUES('city','San Francisco','san francisco',7,1); -INSERT INTO "autofill" VALUES('zipcode','11001','11001',8,1); -INSERT INTO "autofill" VALUES('country','UK','uk',9,1); -CREATE TABLE autofill_dates ( pair_id INTEGER DEFAULT 0, date_created INTEGER DEFAULT 0); -INSERT INTO "autofill_dates" VALUES(1,1299093389); -INSERT INTO "autofill_dates" VALUES(2,1299093389); -INSERT INTO "autofill_dates" VALUES(3,1299093389); -INSERT INTO "autofill_dates" VALUES(4,1299093389); -INSERT INTO "autofill_dates" VALUES(5,1299093389); -INSERT INTO "autofill_dates" VALUES(6,1299093389); -INSERT INTO "autofill_dates" VALUES(7,1299093389); -INSERT INTO "autofill_dates" VALUES(8,1299093389); -INSERT INTO "autofill_dates" VALUES(9,1299093389); -CREATE TABLE autofill_profiles ( guid VARCHAR PRIMARY KEY, company_name VARCHAR, address_line_1 VARCHAR, address_line_2 VARCHAR, city VARCHAR, state VARCHAR, zipcode VARCHAR, country VARCHAR, date_modified INTEGER NOT NULL DEFAULT 0, country_code VARCHAR); -INSERT INTO "autofill_profiles" VALUES('F19484ED-363F-4506-997E-E0F23EA834AB','','1122 Boogie Boogie Avenue','','San Francisco','?','11001','UK',1299093389,'UK'); -CREATE TABLE autofill_profile_names ( guid VARCHAR, first_name VARCHAR, middle_name VARCHAR, last_name VARCHAR); -INSERT INTO "autofill_profile_names" VALUES('F19484ED-363F-4506-997E-E0F23EA834AB','David','','Holloway'); -CREATE TABLE autofill_profile_emails ( guid VARCHAR, email VARCHAR); -INSERT INTO "autofill_profile_emails" VALUES('F19484ED-363F-4506-997E-E0F23EA834AB','d@gmail.com'); -CREATE TABLE autofill_profile_phones ( guid VARCHAR, type INTEGER DEFAULT 0, number VARCHAR); -INSERT INTO "autofill_profile_phones" VALUES('F19484ED-363F-4506-997E-E0F23EA834AB',0,'4155512222'); -INSERT INTO "autofill_profile_phones" VALUES('F19484ED-363F-4506-997E-E0F23EA834AB',1,'4155512222'); -CREATE TABLE credit_cards ( guid VARCHAR PRIMARY KEY, name_on_card VARCHAR, expiration_month INTEGER, expiration_year INTEGER, card_number_encrypted BLOB, date_modified INTEGER NOT NULL DEFAULT 0); -CREATE TABLE token_service (service VARCHAR PRIMARY KEY NOT NULL,encrypted_token BLOB); -CREATE INDEX logins_signon ON logins (signon_realm); -CREATE INDEX ie7_logins_hash ON ie7_logins (url_hash); -CREATE INDEX web_apps_url_index ON web_apps (url); -CREATE INDEX autofill_name ON autofill (name); -CREATE INDEX autofill_name_value_lower ON autofill (name, value_lower); -CREATE INDEX autofill_dates_pair_id ON autofill_dates (pair_id); -COMMIT;
diff --git a/components/test/data/web_database/version_35.sql b/components/test/data/web_database/version_35.sql deleted file mode 100644 index 2c0738cb..0000000 --- a/components/test/data/web_database/version_35.sql +++ /dev/null
@@ -1,59 +0,0 @@ -PRAGMA foreign_keys=OFF; -BEGIN TRANSACTION; -CREATE TABLE meta(key LONGVARCHAR NOT NULL UNIQUE PRIMARY KEY,value LONGVARCHAR); -INSERT INTO "meta" VALUES('version','35'); -INSERT INTO "meta" VALUES('last_compatible_version','35'); -INSERT INTO "meta" VALUES('Default Search Provider ID','2'); -INSERT INTO "meta" VALUES('Builtin Keyword Version','33'); -CREATE TABLE keywords (id INTEGER PRIMARY KEY,short_name VARCHAR NOT NULL,keyword VARCHAR NOT NULL,favicon_url VARCHAR NOT NULL,url VARCHAR NOT NULL,show_in_default_list INTEGER,safe_for_autoreplace INTEGER,originating_url VARCHAR,date_created INTEGER DEFAULT 0,usage_count INTEGER DEFAULT 0,input_encodings VARCHAR,suggest_url VARCHAR,prepopulate_id INTEGER DEFAULT 0,autogenerate_keyword INTEGER DEFAULT 0,logo_id INTEGER DEFAULT 0,created_by_policy INTEGER DEFAULT 0,instant_url VARCHAR); -INSERT INTO "keywords" VALUES(2,'Google','google.com','http://www.google.com/favicon.ico','{google:baseURL}search?{google:RLZ}{google:acceptedSuggestion}{google:originalQueryForSuggestion}sourceid=chrome&ie={inputEncoding}&q={searchTerms}',1,1,'',0,0,'UTF-8','{google:baseSuggestURL}search?client=chrome&hl={language}&q={searchTerms}',1,1,6262,0,'{google:baseURL}webhp?{google:RLZ}sourceid=chrome-instant&ie={inputEncoding}&ion=1{searchTerms}&nord=1'); -INSERT INTO "keywords" VALUES(3,'Yahoo!','yahoo.com','http://search.yahoo.com/favicon.ico','http://search.yahoo.com/search?ei={inputEncoding}&fr=crmas&p={searchTerms}',1,1,'',0,0,'UTF-8','http://ff.search.yahoo.com/gossip?output=fxjson&command={searchTerms}',2,0,6279,0,''); -INSERT INTO "keywords" VALUES(4,'Bing','bing.com','http://www.bing.com/s/wlflag.ico','http://www.bing.com/search?setmkt=en-US&q={searchTerms}',1,1,'',0,0,'UTF-8','http://api.bing.com/osjson.aspx?query={searchTerms}&language={language}',3,0,6256,0,''); -CREATE TABLE logins (origin_url VARCHAR NOT NULL, action_url VARCHAR, username_element VARCHAR, username_value VARCHAR, password_element VARCHAR, password_value BLOB, submit_element VARCHAR, signon_realm VARCHAR NOT NULL,ssl_valid INTEGER NOT NULL,preferred INTEGER NOT NULL,date_created INTEGER NOT NULL,blacklisted_by_user INTEGER NOT NULL,scheme INTEGER NOT NULL,UNIQUE (origin_url, username_element, username_value, password_element, submit_element, signon_realm)); -CREATE TABLE web_app_icons (url LONGVARCHAR,width int,height int,image BLOB, UNIQUE (url, width, height)); -CREATE TABLE web_apps (url LONGVARCHAR UNIQUE,has_all_images INTEGER NOT NULL); -CREATE TABLE autofill (name VARCHAR, value VARCHAR, value_lower VARCHAR, pair_id INTEGER PRIMARY KEY, count INTEGER DEFAULT 1); -CREATE TABLE autofill_dates ( pair_id INTEGER DEFAULT 0, date_created INTEGER DEFAULT 0); -CREATE TABLE autofill_profiles ( guid VARCHAR PRIMARY KEY, company_name VARCHAR, address_line_1 VARCHAR, address_line_2 VARCHAR, city VARCHAR, state VARCHAR, zipcode VARCHAR, country VARCHAR, country_code VARCHAR, date_modified INTEGER NOT NULL DEFAULT 0); -CREATE TABLE autofill_profile_names ( guid VARCHAR, first_name VARCHAR, middle_name VARCHAR, last_name VARCHAR); -CREATE TABLE autofill_profile_emails ( guid VARCHAR, email VARCHAR); -CREATE TABLE autofill_profile_phones ( guid VARCHAR, type INTEGER DEFAULT 0, number VARCHAR); - -/* A "John Doe" profile with all-valid fields. */ -INSERT INTO "autofill_profiles" VALUES('00000000-0000-0000-0000-000000000001','Acme Inc.','1 Main Street','Apt 2','San Francisco','CA','94102','United States','US',1300131704); -INSERT INTO "autofill_profile_names" VALUES('00000000-0000-0000-0000-000000000001','John','','Doe'); -INSERT INTO "autofill_profile_emails" VALUES('00000000-0000-0000-0000-000000000001','john@doe.com'); -INSERT INTO "autofill_profile_phones" VALUES('00000000-0000-0000-0000-000000000001',0,'4151112222'); -INSERT INTO "autofill_profile_phones" VALUES('00000000-0000-0000-0000-000000000001',1,'4151110000'); - -/* A subset of "John Doe". Should get discarded. */ -INSERT INTO "autofill_profiles" VALUES('00000000-0000-0000-0000-000000000002','','1 Main Street','Apt 2','San Francisco','CA','94102','United States','US',1300131704); -INSERT INTO "autofill_profile_names" VALUES('00000000-0000-0000-0000-000000000002','John','','Doe'); -INSERT INTO "autofill_profile_emails" VALUES('00000000-0000-0000-0000-000000000002','john@doe.com'); -INSERT INTO "autofill_profile_phones" VALUES('00000000-0000-0000-0000-000000000002',0,'4151112222'); -INSERT INTO "autofill_profile_phones" VALUES('00000000-0000-0000-0000-000000000002',1,'4151110000'); - -/* A profile with incomplete address. Should get discarded. */ -INSERT INTO "autofill_profiles" VALUES('00000000-0000-0000-0000-000000000003','','','Apt 3','San Francisco','CA','94102','United States','US',1300131704); -INSERT INTO "autofill_profile_names" VALUES('00000000-0000-0000-0000-000000000003','Jim','','Smith'); - -/* A profile with bad email. Should get discarded. */ -INSERT INTO "autofill_profiles" VALUES('00000000-0000-0000-0000-000000000004','Acme Inc.','4 Main Street','Apt 2','San Francisco','CA','94102','United States','US',1300131704); -INSERT INTO "autofill_profile_emails" VALUES('00000000-0000-0000-0000-000000000004','bademail'); - -/* A profile with bad State (country == US). Should get discarded. */ -INSERT INTO "autofill_profiles" VALUES('00000000-0000-0000-0000-000000000005','Acme Inc.','6 Main Street','Apt 2','San Francisco','BS','94102','United States','US',1300131704); -INSERT INTO "autofill_profile_names" VALUES('00000000-0000-0000-0000-000000000006','John','','Doe'); - -/* A profile with bad zip (country == US). Should get discarded. */ -INSERT INTO "autofill_profiles" VALUES('00000000-0000-0000-0000-000000000006','Acme Inc.','7 Main Street','Apt 2','San Francisco','CA','bogus','United States','US',1300131704); -INSERT INTO "autofill_profile_names" VALUES('00000000-0000-0000-0000-000000000007','John','','Doe'); - -CREATE TABLE credit_cards ( guid VARCHAR PRIMARY KEY, name_on_card VARCHAR, expiration_month INTEGER, expiration_year INTEGER, card_number_encrypted BLOB, date_modified INTEGER NOT NULL DEFAULT 0); -CREATE TABLE token_service (service VARCHAR PRIMARY KEY NOT NULL,encrypted_token BLOB); -CREATE INDEX logins_signon ON logins (signon_realm); -CREATE INDEX web_apps_url_index ON web_apps (url); -CREATE INDEX autofill_name ON autofill (name); -CREATE INDEX autofill_name_value_lower ON autofill (name, value_lower); -CREATE INDEX autofill_dates_pair_id ON autofill_dates (pair_id); -COMMIT;
diff --git a/components/test/data/web_database/version_37.sql b/components/test/data/web_database/version_37.sql deleted file mode 100644 index 045450c..0000000 --- a/components/test/data/web_database/version_37.sql +++ /dev/null
@@ -1,26 +0,0 @@ -PRAGMA foreign_keys=OFF; -BEGIN TRANSACTION; -CREATE TABLE meta(key LONGVARCHAR NOT NULL UNIQUE PRIMARY KEY,value LONGVARCHAR); -INSERT INTO "meta" VALUES('version','37'); -INSERT INTO "meta" VALUES('last_compatible_version','37'); -INSERT INTO "meta" VALUES('Default Search Provider ID','2'); -INSERT INTO "meta" VALUES('Builtin Keyword Version','33'); -CREATE TABLE keywords (id INTEGER PRIMARY KEY,short_name VARCHAR NOT NULL,keyword VARCHAR NOT NULL,favicon_url VARCHAR NOT NULL,url VARCHAR NOT NULL,show_in_default_list INTEGER,safe_for_autoreplace INTEGER,originating_url VARCHAR,date_created INTEGER DEFAULT 0,usage_count INTEGER DEFAULT 0,input_encodings VARCHAR,suggest_url VARCHAR,prepopulate_id INTEGER DEFAULT 0,autogenerate_keyword INTEGER DEFAULT 0,logo_id INTEGER DEFAULT 0,created_by_policy INTEGER DEFAULT 0,instant_url VARCHAR); -INSERT INTO "keywords" VALUES(2,'Google','google.com','http://www.google.com/favicon.ico','{google:baseURL}search?{google:RLZ}{google:acceptedSuggestion}{google:originalQueryForSuggestion}sourceid=chrome&ie={inputEncoding}&q={searchTerms}',1,1,'',0,0,'UTF-8','{google:baseSuggestURL}search?client=chrome&hl={language}&q={searchTerms}',1,1,6262,0,'{google:baseURL}webhp?{google:RLZ}sourceid=chrome-instant&ie={inputEncoding}&ion=1{searchTerms}&nord=1'); -CREATE TABLE logins (origin_url VARCHAR NOT NULL, action_url VARCHAR, username_element VARCHAR, username_value VARCHAR, password_element VARCHAR, password_value BLOB, submit_element VARCHAR, signon_realm VARCHAR NOT NULL,ssl_valid INTEGER NOT NULL,preferred INTEGER NOT NULL,date_created INTEGER NOT NULL,blacklisted_by_user INTEGER NOT NULL,scheme INTEGER NOT NULL,UNIQUE (origin_url, username_element, username_value, password_element, submit_element, signon_realm)); -CREATE TABLE web_app_icons (url LONGVARCHAR,width int,height int,image BLOB, UNIQUE (url, width, height)); -CREATE TABLE web_apps (url LONGVARCHAR UNIQUE,has_all_images INTEGER NOT NULL); -CREATE TABLE autofill (name VARCHAR, value VARCHAR, value_lower VARCHAR, pair_id INTEGER PRIMARY KEY, count INTEGER DEFAULT 1); -CREATE TABLE autofill_dates ( pair_id INTEGER DEFAULT 0, date_created INTEGER DEFAULT 0); -CREATE TABLE autofill_profiles ( guid VARCHAR PRIMARY KEY, company_name VARCHAR, address_line_1 VARCHAR, address_line_2 VARCHAR, city VARCHAR, state VARCHAR, zipcode VARCHAR, country VARCHAR, country_code VARCHAR, date_modified INTEGER NOT NULL DEFAULT 0); -CREATE TABLE autofill_profile_names ( guid VARCHAR, first_name VARCHAR, middle_name VARCHAR, last_name VARCHAR); -CREATE TABLE autofill_profile_emails ( guid VARCHAR, email VARCHAR); -CREATE TABLE autofill_profile_phones ( guid VARCHAR, type INTEGER DEFAULT 0, number VARCHAR); -CREATE TABLE credit_cards ( guid VARCHAR PRIMARY KEY, name_on_card VARCHAR, expiration_month INTEGER, expiration_year INTEGER, card_number_encrypted BLOB, date_modified INTEGER NOT NULL DEFAULT 0); -CREATE TABLE token_service (service VARCHAR PRIMARY KEY NOT NULL,encrypted_token BLOB); -CREATE INDEX logins_signon ON logins (signon_realm); -CREATE INDEX web_apps_url_index ON web_apps (url); -CREATE INDEX autofill_name ON autofill (name); -CREATE INDEX autofill_name_value_lower ON autofill (name, value_lower); -CREATE INDEX autofill_dates_pair_id ON autofill_dates (pair_id); -COMMIT;
diff --git a/components/test/data/web_database/version_38.sql b/components/test/data/web_database/version_38.sql deleted file mode 100644 index 679ad987..0000000 --- a/components/test/data/web_database/version_38.sql +++ /dev/null
@@ -1,26 +0,0 @@ -PRAGMA foreign_keys=OFF; -BEGIN TRANSACTION; -CREATE TABLE meta(key LONGVARCHAR NOT NULL UNIQUE PRIMARY KEY,value LONGVARCHAR); -INSERT INTO "meta" VALUES('version','38'); -INSERT INTO "meta" VALUES('last_compatible_version','38'); -INSERT INTO "meta" VALUES('Default Search Provider ID','2'); -INSERT INTO "meta" VALUES('Builtin Keyword Version','33'); -CREATE TABLE keywords (id INTEGER PRIMARY KEY,short_name VARCHAR NOT NULL,keyword VARCHAR NOT NULL,favicon_url VARCHAR NOT NULL,url VARCHAR NOT NULL,show_in_default_list INTEGER,safe_for_autoreplace INTEGER,originating_url VARCHAR,date_created INTEGER DEFAULT 0,usage_count INTEGER DEFAULT 0,input_encodings VARCHAR,suggest_url VARCHAR,prepopulate_id INTEGER DEFAULT 0,autogenerate_keyword INTEGER DEFAULT 0,logo_id INTEGER DEFAULT 0,created_by_policy INTEGER DEFAULT 0,instant_url VARCHAR,last_modified INTEGER DEFAULT 0); -INSERT INTO "keywords" VALUES(2,'Google','google.com','http://www.google.com/favicon.ico','{google:baseURL}search?{google:RLZ}{google:acceptedSuggestion}{google:originalQueryForSuggestion}sourceid=chrome&ie={inputEncoding}&q={searchTerms}',1,1,'',0,0,'UTF-8','{google:baseSuggestURL}search?client=chrome&hl={language}&q={searchTerms}',1,1,6262,0,'{google:baseURL}webhp?{google:RLZ}sourceid=chrome-instant&ie={inputEncoding}&ion=1{searchTerms}&nord=1',0); -CREATE TABLE logins (origin_url VARCHAR NOT NULL, action_url VARCHAR, username_element VARCHAR, username_value VARCHAR, password_element VARCHAR, password_value BLOB, submit_element VARCHAR, signon_realm VARCHAR NOT NULL,ssl_valid INTEGER NOT NULL,preferred INTEGER NOT NULL,date_created INTEGER NOT NULL,blacklisted_by_user INTEGER NOT NULL,scheme INTEGER NOT NULL,UNIQUE (origin_url, username_element, username_value, password_element, submit_element, signon_realm)); -CREATE TABLE web_app_icons (url LONGVARCHAR,width int,height int,image BLOB, UNIQUE (url, width, height)); -CREATE TABLE web_apps (url LONGVARCHAR UNIQUE,has_all_images INTEGER NOT NULL); -CREATE TABLE autofill (name VARCHAR, value VARCHAR, value_lower VARCHAR, pair_id INTEGER PRIMARY KEY, count INTEGER DEFAULT 1); -CREATE TABLE autofill_dates ( pair_id INTEGER DEFAULT 0, date_created INTEGER DEFAULT 0); -CREATE TABLE autofill_profiles ( guid VARCHAR PRIMARY KEY, company_name VARCHAR, address_line_1 VARCHAR, address_line_2 VARCHAR, city VARCHAR, state VARCHAR, zipcode VARCHAR, country VARCHAR, country_code VARCHAR, date_modified INTEGER NOT NULL DEFAULT 0); -CREATE TABLE autofill_profile_names ( guid VARCHAR, first_name VARCHAR, middle_name VARCHAR, last_name VARCHAR); -CREATE TABLE autofill_profile_emails ( guid VARCHAR, email VARCHAR); -CREATE TABLE autofill_profile_phones ( guid VARCHAR, type INTEGER DEFAULT 0, number VARCHAR); -CREATE TABLE credit_cards ( guid VARCHAR PRIMARY KEY, name_on_card VARCHAR, expiration_month INTEGER, expiration_year INTEGER, card_number_encrypted BLOB, date_modified INTEGER NOT NULL DEFAULT 0); -CREATE TABLE token_service (service VARCHAR PRIMARY KEY NOT NULL,encrypted_token BLOB); -CREATE INDEX logins_signon ON logins (signon_realm); -CREATE INDEX web_apps_url_index ON web_apps (url); -CREATE INDEX autofill_name ON autofill (name); -CREATE INDEX autofill_name_value_lower ON autofill (name, value_lower); -CREATE INDEX autofill_dates_pair_id ON autofill_dates (pair_id); -COMMIT;
diff --git a/components/test/data/web_database/version_39.sql b/components/test/data/web_database/version_39.sql deleted file mode 100644 index d8f4c9f1..0000000 --- a/components/test/data/web_database/version_39.sql +++ /dev/null
@@ -1,26 +0,0 @@ -PRAGMA foreign_keys=OFF; -BEGIN TRANSACTION; -CREATE TABLE meta(key LONGVARCHAR NOT NULL UNIQUE PRIMARY KEY,value LONGVARCHAR); -INSERT INTO "meta" VALUES('version','39'); -INSERT INTO "meta" VALUES('last_compatible_version','39'); -INSERT INTO "meta" VALUES('Default Search Provider ID','2'); -INSERT INTO "meta" VALUES('Builtin Keyword Version','33'); -CREATE TABLE keywords (id INTEGER PRIMARY KEY,short_name VARCHAR NOT NULL,keyword VARCHAR NOT NULL,favicon_url VARCHAR NOT NULL,url VARCHAR NOT NULL,show_in_default_list INTEGER,safe_for_autoreplace INTEGER,originating_url VARCHAR,date_created INTEGER DEFAULT 0,usage_count INTEGER DEFAULT 0,input_encodings VARCHAR,suggest_url VARCHAR,prepopulate_id INTEGER DEFAULT 0,autogenerate_keyword INTEGER DEFAULT 0,logo_id INTEGER DEFAULT 0,created_by_policy INTEGER DEFAULT 0,instant_url VARCHAR,last_modified INTEGER DEFAULT 0, sync_guid VARCHAR); -INSERT INTO "keywords" VALUES(2,'Google','google.com','http://www.google.com/favicon.ico','{google:baseURL}search?{google:RLZ}{google:acceptedSuggestion}{google:originalQueryForSuggestion}sourceid=chrome&ie={inputEncoding}&q={searchTerms}',1,1,'',0,0,'UTF-8','{google:baseSuggestURL}search?client=chrome&hl={language}&q={searchTerms}',1,1,6262,0,'{google:baseURL}webhp?{google:RLZ}sourceid=chrome-instant&ie={inputEncoding}&ion=1{searchTerms}&nord=1',0,'{1234-5678-90AB-CDEF}'); -CREATE TABLE logins (origin_url VARCHAR NOT NULL, action_url VARCHAR, username_element VARCHAR, username_value VARCHAR, password_element VARCHAR, password_value BLOB, submit_element VARCHAR, signon_realm VARCHAR NOT NULL,ssl_valid INTEGER NOT NULL,preferred INTEGER NOT NULL,date_created INTEGER NOT NULL,blacklisted_by_user INTEGER NOT NULL,scheme INTEGER NOT NULL,UNIQUE (origin_url, username_element, username_value, password_element, submit_element, signon_realm)); -CREATE TABLE web_app_icons (url LONGVARCHAR,width int,height int,image BLOB, UNIQUE (url, width, height)); -CREATE TABLE web_apps (url LONGVARCHAR UNIQUE,has_all_images INTEGER NOT NULL); -CREATE TABLE autofill (name VARCHAR, value VARCHAR, value_lower VARCHAR, pair_id INTEGER PRIMARY KEY, count INTEGER DEFAULT 1); -CREATE TABLE autofill_dates ( pair_id INTEGER DEFAULT 0, date_created INTEGER DEFAULT 0); -CREATE TABLE autofill_profiles ( guid VARCHAR PRIMARY KEY, company_name VARCHAR, address_line_1 VARCHAR, address_line_2 VARCHAR, city VARCHAR, state VARCHAR, zipcode VARCHAR, country VARCHAR, country_code VARCHAR, date_modified INTEGER NOT NULL DEFAULT 0); -CREATE TABLE autofill_profile_names ( guid VARCHAR, first_name VARCHAR, middle_name VARCHAR, last_name VARCHAR); -CREATE TABLE autofill_profile_emails ( guid VARCHAR, email VARCHAR); -CREATE TABLE autofill_profile_phones ( guid VARCHAR, type INTEGER DEFAULT 0, number VARCHAR); -CREATE TABLE credit_cards ( guid VARCHAR PRIMARY KEY, name_on_card VARCHAR, expiration_month INTEGER, expiration_year INTEGER, card_number_encrypted BLOB, date_modified INTEGER NOT NULL DEFAULT 0); -CREATE TABLE token_service (service VARCHAR PRIMARY KEY NOT NULL,encrypted_token BLOB); -CREATE INDEX logins_signon ON logins (signon_realm); -CREATE INDEX web_apps_url_index ON web_apps (url); -CREATE INDEX autofill_name ON autofill (name); -CREATE INDEX autofill_name_value_lower ON autofill (name, value_lower); -CREATE INDEX autofill_dates_pair_id ON autofill_dates (pair_id); -COMMIT;
diff --git a/components/test/data/web_database/version_40.sql b/components/test/data/web_database/version_40.sql deleted file mode 100644 index 5eee626..0000000 --- a/components/test/data/web_database/version_40.sql +++ /dev/null
@@ -1,29 +0,0 @@ -PRAGMA foreign_keys=OFF; -BEGIN TRANSACTION; -CREATE TABLE meta(key LONGVARCHAR NOT NULL UNIQUE PRIMARY KEY,value LONGVARCHAR); -INSERT INTO "meta" VALUES('version','40'); -INSERT INTO "meta" VALUES('last_compatible_version','40'); -INSERT INTO "meta" VALUES('Default Search Provider ID','2'); -INSERT INTO "meta" VALUES('Default Search Provider ID Backup','2'); -INSERT INTO "meta" VALUES('Default Search Provider ID Backup Signature',''); -INSERT INTO "meta" VALUES('Builtin Keyword Version','33'); -CREATE TABLE keywords (id INTEGER PRIMARY KEY,short_name VARCHAR NOT NULL,keyword VARCHAR NOT NULL,favicon_url VARCHAR NOT NULL,url VARCHAR NOT NULL,show_in_default_list INTEGER,safe_for_autoreplace INTEGER,originating_url VARCHAR,date_created INTEGER DEFAULT 0,usage_count INTEGER DEFAULT 0,input_encodings VARCHAR,suggest_url VARCHAR,prepopulate_id INTEGER DEFAULT 0,autogenerate_keyword INTEGER DEFAULT 0,logo_id INTEGER DEFAULT 0,created_by_policy INTEGER DEFAULT 0,instant_url VARCHAR,last_modified INTEGER DEFAULT 0, sync_guid VARCHAR); -INSERT INTO "keywords" VALUES(2,'Google','google.com','http://www.google.com/favicon.ico','{google:baseURL}search?{google:RLZ}{google:acceptedSuggestion}{google:originalQueryForSuggestion}sourceid=chrome&ie={inputEncoding}&q={searchTerms}',1,1,'',0,0,'UTF-8','{google:baseSuggestURL}search?client=chrome&hl={language}&q={searchTerms}',1,1,6262,0,'{google:baseURL}webhp?{google:RLZ}sourceid=chrome-instant&ie={inputEncoding}&ion=1{searchTerms}&nord=1',0,'{1234-5678-90AB-CDEF}'); -CREATE TABLE logins (origin_url VARCHAR NOT NULL, action_url VARCHAR, username_element VARCHAR, username_value VARCHAR, password_element VARCHAR, password_value BLOB, submit_element VARCHAR, signon_realm VARCHAR NOT NULL,ssl_valid INTEGER NOT NULL,preferred INTEGER NOT NULL,date_created INTEGER NOT NULL,blacklisted_by_user INTEGER NOT NULL,scheme INTEGER NOT NULL,UNIQUE (origin_url, username_element, username_value, password_element, submit_element, signon_realm)); -CREATE TABLE web_app_icons (url LONGVARCHAR,width int,height int,image BLOB, UNIQUE (url, width, height)); -CREATE TABLE web_apps (url LONGVARCHAR UNIQUE,has_all_images INTEGER NOT NULL); -CREATE TABLE autofill (name VARCHAR, value VARCHAR, value_lower VARCHAR, pair_id INTEGER PRIMARY KEY, count INTEGER DEFAULT 1); -CREATE TABLE autofill_dates ( pair_id INTEGER DEFAULT 0, date_created INTEGER DEFAULT 0); -CREATE TABLE autofill_profiles ( guid VARCHAR PRIMARY KEY, company_name VARCHAR, address_line_1 VARCHAR, address_line_2 VARCHAR, city VARCHAR, state VARCHAR, zipcode VARCHAR, country VARCHAR, country_code VARCHAR, date_modified INTEGER NOT NULL DEFAULT 0); -CREATE TABLE autofill_profile_names ( guid VARCHAR, first_name VARCHAR, middle_name VARCHAR, last_name VARCHAR); -CREATE TABLE autofill_profile_emails ( guid VARCHAR, email VARCHAR); -CREATE TABLE autofill_profile_phones ( guid VARCHAR, type INTEGER DEFAULT 0, number VARCHAR); -CREATE TABLE credit_cards ( guid VARCHAR PRIMARY KEY, name_on_card VARCHAR, expiration_month INTEGER, expiration_year INTEGER, card_number_encrypted BLOB, date_modified INTEGER NOT NULL DEFAULT 0); -CREATE TABLE token_service (service VARCHAR PRIMARY KEY NOT NULL,encrypted_token BLOB); -CREATE INDEX logins_signon ON logins (signon_realm); -CREATE INDEX web_apps_url_index ON web_apps (url); -CREATE INDEX autofill_name ON autofill (name); -CREATE INDEX autofill_name_value_lower ON autofill (name, value_lower); -CREATE INDEX autofill_dates_pair_id ON autofill_dates (pair_id); -COMMIT; -
diff --git a/components/test/data/web_database/version_41.sql b/components/test/data/web_database/version_41.sql deleted file mode 100644 index 4804d167..0000000 --- a/components/test/data/web_database/version_41.sql +++ /dev/null
@@ -1,30 +0,0 @@ -PRAGMA foreign_keys=OFF; -BEGIN TRANSACTION; -CREATE TABLE meta(key LONGVARCHAR NOT NULL UNIQUE PRIMARY KEY,value LONGVARCHAR); -INSERT INTO "meta" VALUES('version','41'); -INSERT INTO "meta" VALUES('last_compatible_version','41'); -INSERT INTO "meta" VALUES('Default Search Provider ID','2'); -INSERT INTO "meta" VALUES('Default Search Provider ID Backup','2'); -INSERT INTO "meta" VALUES('Default Search Provider ID Backup Signature',''); -INSERT INTO "meta" VALUES('Builtin Keyword Version','33'); -CREATE TABLE keywords (id INTEGER PRIMARY KEY,short_name VARCHAR NOT NULL,keyword VARCHAR NOT NULL,favicon_url VARCHAR NOT NULL,url VARCHAR NOT NULL,show_in_default_list INTEGER,safe_for_autoreplace INTEGER,originating_url VARCHAR,date_created INTEGER DEFAULT 0,usage_count INTEGER DEFAULT 0,input_encodings VARCHAR,suggest_url VARCHAR,prepopulate_id INTEGER DEFAULT 0,autogenerate_keyword INTEGER DEFAULT 0,logo_id INTEGER DEFAULT 0,created_by_policy INTEGER DEFAULT 0,instant_url VARCHAR,last_modified INTEGER DEFAULT 0, sync_guid VARCHAR); -INSERT INTO "keywords" VALUES(2,'Google','google.com','http://www.google.com/favicon.ico','{google:baseURL}search?{google:RLZ}{google:acceptedSuggestion}{google:originalQueryForSuggestion}sourceid=chrome&ie={inputEncoding}&q={searchTerms}',1,1,'',0,0,'UTF-8','{google:baseSuggestURL}search?client=chrome&hl={language}&q={searchTerms}',1,1,6262,0,'{google:baseURL}webhp?{google:RLZ}sourceid=chrome-instant&ie={inputEncoding}&ion=1{searchTerms}&nord=1',0,'{1234-5678-90AB-CDEF}'); -CREATE TABLE logins (origin_url VARCHAR NOT NULL, action_url VARCHAR, username_element VARCHAR, username_value VARCHAR, password_element VARCHAR, password_value BLOB, submit_element VARCHAR, signon_realm VARCHAR NOT NULL,ssl_valid INTEGER NOT NULL,preferred INTEGER NOT NULL,date_created INTEGER NOT NULL,blacklisted_by_user INTEGER NOT NULL,scheme INTEGER NOT NULL,UNIQUE (origin_url, username_element, username_value, password_element, submit_element, signon_realm)); -CREATE TABLE web_app_icons (url LONGVARCHAR,width int,height int,image BLOB, UNIQUE (url, width, height)); -CREATE TABLE web_apps (url LONGVARCHAR UNIQUE,has_all_images INTEGER NOT NULL); -CREATE TABLE autofill (name VARCHAR, value VARCHAR, value_lower VARCHAR, pair_id INTEGER PRIMARY KEY, count INTEGER DEFAULT 1); -CREATE TABLE autofill_dates ( pair_id INTEGER DEFAULT 0, date_created INTEGER DEFAULT 0); -CREATE TABLE autofill_profiles ( guid VARCHAR PRIMARY KEY, company_name VARCHAR, address_line_1 VARCHAR, address_line_2 VARCHAR, city VARCHAR, state VARCHAR, zipcode VARCHAR, country VARCHAR, country_code VARCHAR, date_modified INTEGER NOT NULL DEFAULT 0); -CREATE TABLE autofill_profile_names ( guid VARCHAR, first_name VARCHAR, middle_name VARCHAR, last_name VARCHAR); -CREATE TABLE autofill_profile_emails ( guid VARCHAR, email VARCHAR); -CREATE TABLE autofill_profile_phones ( guid VARCHAR, type INTEGER DEFAULT 0, number VARCHAR); -CREATE TABLE credit_cards ( guid VARCHAR PRIMARY KEY, name_on_card VARCHAR, expiration_month INTEGER, expiration_year INTEGER, card_number_encrypted BLOB, date_modified INTEGER NOT NULL DEFAULT 0); -CREATE TABLE token_service (service VARCHAR PRIMARY KEY NOT NULL,encrypted_token BLOB); -CREATE INDEX logins_signon ON logins (signon_realm); -CREATE INDEX web_apps_url_index ON web_apps (url); -CREATE INDEX autofill_name ON autofill (name); -CREATE INDEX autofill_name_value_lower ON autofill (name, value_lower); -CREATE INDEX autofill_dates_pair_id ON autofill_dates (pair_id); -COMMIT; - -
diff --git a/components/test/data/web_database/version_42.sql b/components/test/data/web_database/version_42.sql deleted file mode 100644 index 01b99253..0000000 --- a/components/test/data/web_database/version_42.sql +++ /dev/null
@@ -1,30 +0,0 @@ -PRAGMA foreign_keys=OFF; -BEGIN TRANSACTION; -CREATE TABLE meta(key LONGVARCHAR NOT NULL UNIQUE PRIMARY KEY,value LONGVARCHAR); -INSERT INTO "meta" VALUES('version','42'); -INSERT INTO "meta" VALUES('last_compatible_version','42'); -INSERT INTO "meta" VALUES('Default Search Provider ID','2'); -INSERT INTO "meta" VALUES('Default Search Provider ID Backup','2'); -INSERT INTO "meta" VALUES('Default Search Provider ID Backup Signature',''); -INSERT INTO "meta" VALUES('Default Search Provider Backup','2Googlegoogle.comhttp://www.google.com/favicon.ico{google:baseURL}search?{google:RLZ}{google:acceptedSuggestion}{google:originalQueryForSuggestion}sourceid=chrome&ie={inputEncoding}&q={searchTerms}100UTF-81{google:baseSuggestURL}search?client=chrome&hl={language}&q={searchTerms}1162620{google:baseURL}webhp?{google:RLZ}sourceid=chrome-instant&ie={inputEncoding}&ion=1{searchTerms}&nord=10{1234-5678-90AB-CDEF}'); -INSERT INTO "meta" VALUES('Builtin Keyword Version','33'); -CREATE TABLE keywords (id INTEGER PRIMARY KEY,short_name VARCHAR NOT NULL,keyword VARCHAR NOT NULL,favicon_url VARCHAR NOT NULL,url VARCHAR NOT NULL,show_in_default_list INTEGER,safe_for_autoreplace INTEGER,originating_url VARCHAR,date_created INTEGER DEFAULT 0,usage_count INTEGER DEFAULT 0,input_encodings VARCHAR,suggest_url VARCHAR,prepopulate_id INTEGER DEFAULT 0,autogenerate_keyword INTEGER DEFAULT 0,logo_id INTEGER DEFAULT 0,created_by_policy INTEGER DEFAULT 0,instant_url VARCHAR,last_modified INTEGER DEFAULT 0, sync_guid VARCHAR); -INSERT INTO "keywords" VALUES(2,'Google','google.com','http://www.google.com/favicon.ico','{google:baseURL}search?{google:RLZ}{google:acceptedSuggestion}{google:originalQueryForSuggestion}sourceid=chrome&ie={inputEncoding}&q={searchTerms}',1,1,'',0,0,'UTF-8','{google:baseSuggestURL}search?client=chrome&hl={language}&q={searchTerms}',1,1,6262,0,'{google:baseURL}webhp?{google:RLZ}sourceid=chrome-instant&ie={inputEncoding}&ion=1{searchTerms}&nord=1',0,'{1234-5678-90AB-CDEF}'); -CREATE TABLE logins (origin_url VARCHAR NOT NULL, action_url VARCHAR, username_element VARCHAR, username_value VARCHAR, password_element VARCHAR, password_value BLOB, submit_element VARCHAR, signon_realm VARCHAR NOT NULL,ssl_valid INTEGER NOT NULL,preferred INTEGER NOT NULL,date_created INTEGER NOT NULL,blacklisted_by_user INTEGER NOT NULL,scheme INTEGER NOT NULL,UNIQUE (origin_url, username_element, username_value, password_element, submit_element, signon_realm)); -CREATE TABLE web_app_icons (url LONGVARCHAR,width int,height int,image BLOB, UNIQUE (url, width, height)); -CREATE TABLE web_apps (url LONGVARCHAR UNIQUE,has_all_images INTEGER NOT NULL); -CREATE TABLE autofill (name VARCHAR, value VARCHAR, value_lower VARCHAR, pair_id INTEGER PRIMARY KEY, count INTEGER DEFAULT 1); -CREATE TABLE autofill_dates ( pair_id INTEGER DEFAULT 0, date_created INTEGER DEFAULT 0); -CREATE TABLE autofill_profiles ( guid VARCHAR PRIMARY KEY, company_name VARCHAR, address_line_1 VARCHAR, address_line_2 VARCHAR, city VARCHAR, state VARCHAR, zipcode VARCHAR, country VARCHAR, country_code VARCHAR, date_modified INTEGER NOT NULL DEFAULT 0); -CREATE TABLE autofill_profile_names ( guid VARCHAR, first_name VARCHAR, middle_name VARCHAR, last_name VARCHAR); -CREATE TABLE autofill_profile_emails ( guid VARCHAR, email VARCHAR); -CREATE TABLE autofill_profile_phones ( guid VARCHAR, type INTEGER DEFAULT 0, number VARCHAR); -CREATE TABLE credit_cards ( guid VARCHAR PRIMARY KEY, name_on_card VARCHAR, expiration_month INTEGER, expiration_year INTEGER, card_number_encrypted BLOB, date_modified INTEGER NOT NULL DEFAULT 0); -CREATE TABLE token_service (service VARCHAR PRIMARY KEY NOT NULL,encrypted_token BLOB); -CREATE INDEX logins_signon ON logins (signon_realm); -CREATE INDEX web_apps_url_index ON web_apps (url); -CREATE INDEX autofill_name ON autofill (name); -CREATE INDEX autofill_name_value_lower ON autofill (name, value_lower); -CREATE INDEX autofill_dates_pair_id ON autofill_dates (pair_id); -COMMIT; -
diff --git a/components/test/data/web_database/version_43.sql b/components/test/data/web_database/version_43.sql deleted file mode 100644 index e0bcd549..0000000 --- a/components/test/data/web_database/version_43.sql +++ /dev/null
@@ -1,31 +0,0 @@ -PRAGMA foreign_keys=OFF; -BEGIN TRANSACTION; -CREATE TABLE meta(key LONGVARCHAR NOT NULL UNIQUE PRIMARY KEY,value LONGVARCHAR); -INSERT INTO "meta" VALUES('version','43'); -INSERT INTO "meta" VALUES('last_compatible_version','43'); -INSERT INTO "meta" VALUES('Default Search Provider ID','2'); -INSERT INTO "meta" VALUES('Default Search Provider ID Backup','3'); -INSERT INTO "meta" VALUES('Default Search Provider ID Backup Signature',''); -INSERT INTO "meta" VALUES('Builtin Keyword Version','37'); -CREATE TABLE keywords (id INTEGER PRIMARY KEY,short_name VARCHAR NOT NULL,keyword VARCHAR NOT NULL,favicon_url VARCHAR NOT NULL,url VARCHAR NOT NULL,show_in_default_list INTEGER,safe_for_autoreplace INTEGER,originating_url VARCHAR,date_created INTEGER DEFAULT 0,usage_count INTEGER DEFAULT 0,input_encodings VARCHAR,suggest_url VARCHAR,prepopulate_id INTEGER DEFAULT 0,autogenerate_keyword INTEGER DEFAULT 0,logo_id INTEGER DEFAULT 0,created_by_policy INTEGER DEFAULT 0,instant_url VARCHAR,last_modified INTEGER DEFAULT 0, sync_guid VARCHAR); -INSERT INTO "keywords" VALUES(2,'Google','google.com','http://www.google.com/favicon.ico','{google:baseURL}search?{google:RLZ}{google:acceptedSuggestion}{google:originalQueryForSuggestion}sourceid=chrome&ie={inputEncoding}&q={searchTerms}',1,1,'',0,0,'UTF-8','{google:baseSuggestURL}search?client=chrome&hl={language}&q={searchTerms}',1,1,1234,0,'{google:baseURL}webhp?{google:RLZ}sourceid=chrome-instant&ie={inputEncoding}&ion=1{searchTerms}&nord=1',0,'{1234-5678-90AB-CDEF}'); -CREATE TABLE keywords_backup (id INTEGER PRIMARY KEY,short_name VARCHAR NOT NULL,keyword VARCHAR NOT NULL,favicon_url VARCHAR NOT NULL,url VARCHAR NOT NULL,show_in_default_list INTEGER,safe_for_autoreplace INTEGER,originating_url VARCHAR,date_created INTEGER DEFAULT 0,usage_count INTEGER DEFAULT 0,input_encodings VARCHAR,suggest_url VARCHAR,prepopulate_id INTEGER DEFAULT 0,autogenerate_keyword INTEGER DEFAULT 0,logo_id INTEGER DEFAULT 0,created_by_policy INTEGER DEFAULT 0,instant_url VARCHAR,last_modified INTEGER DEFAULT 0, sync_guid VARCHAR); -INSERT INTO "keywords_backup" VALUES(2,'Google','google.com','http://www.google.com/favicon.ico','{google:baseURL}search?{google:RLZ}{google:acceptedSuggestion}{google:originalQueryForSuggestion}sourceid=chrome&ie={inputEncoding}&q={searchTerms}',1,1,'',0,0,'UTF-8','{google:baseSuggestURL}search?client=chrome&hl={language}&q={searchTerms}',1,1,1234,0,'{google:baseURL}webhp?{google:RLZ}sourceid=chrome-instant&ie={inputEncoding}&ion=1{searchTerms}&nord=1',0,'{1234-5678-90AB-CDEF}'); -CREATE TABLE logins (origin_url VARCHAR NOT NULL, action_url VARCHAR, username_element VARCHAR, username_value VARCHAR, password_element VARCHAR, password_value BLOB, submit_element VARCHAR, signon_realm VARCHAR NOT NULL,ssl_valid INTEGER NOT NULL,preferred INTEGER NOT NULL,date_created INTEGER NOT NULL,blacklisted_by_user INTEGER NOT NULL,scheme INTEGER NOT NULL,UNIQUE (origin_url, username_element, username_value, password_element, submit_element, signon_realm)); -CREATE TABLE web_app_icons (url LONGVARCHAR,width int,height int,image BLOB, UNIQUE (url, width, height)); -CREATE TABLE web_apps (url LONGVARCHAR UNIQUE,has_all_images INTEGER NOT NULL); -CREATE TABLE autofill (name VARCHAR, value VARCHAR, value_lower VARCHAR, pair_id INTEGER PRIMARY KEY, count INTEGER DEFAULT 1); -CREATE TABLE autofill_dates ( pair_id INTEGER DEFAULT 0, date_created INTEGER DEFAULT 0); -CREATE TABLE autofill_profiles ( guid VARCHAR PRIMARY KEY, company_name VARCHAR, address_line_1 VARCHAR, address_line_2 VARCHAR, city VARCHAR, state VARCHAR, zipcode VARCHAR, country VARCHAR, country_code VARCHAR, date_modified INTEGER NOT NULL DEFAULT 0); -CREATE TABLE autofill_profile_names ( guid VARCHAR, first_name VARCHAR, middle_name VARCHAR, last_name VARCHAR); -CREATE TABLE autofill_profile_emails ( guid VARCHAR, email VARCHAR); -CREATE TABLE autofill_profile_phones ( guid VARCHAR, type INTEGER DEFAULT 0, number VARCHAR); -CREATE TABLE credit_cards ( guid VARCHAR PRIMARY KEY, name_on_card VARCHAR, expiration_month INTEGER, expiration_year INTEGER, card_number_encrypted BLOB, date_modified INTEGER NOT NULL DEFAULT 0); -CREATE TABLE token_service (service VARCHAR PRIMARY KEY NOT NULL,encrypted_token BLOB); -CREATE INDEX logins_signon ON logins (signon_realm); -CREATE INDEX web_apps_url_index ON web_apps (url); -CREATE INDEX autofill_name ON autofill (name); -CREATE INDEX autofill_name_value_lower ON autofill (name, value_lower); -CREATE INDEX autofill_dates_pair_id ON autofill_dates (pair_id); -COMMIT; -
diff --git a/components/test/data/web_database/version_44.sql b/components/test/data/web_database/version_44.sql deleted file mode 100644 index e36ffea8..0000000 --- a/components/test/data/web_database/version_44.sql +++ /dev/null
@@ -1,53 +0,0 @@ -PRAGMA foreign_keys=OFF; -BEGIN TRANSACTION; -CREATE TABLE meta(key LONGVARCHAR NOT NULL UNIQUE PRIMARY KEY,value LONGVARCHAR); -INSERT INTO "meta" VALUES('version','44'); -INSERT INTO "meta" VALUES('last_compatible_version','44'); -INSERT INTO "meta" VALUES('Default Search Provider ID Backup','0'); -INSERT INTO "meta" VALUES('Default Search Provider ID Backup Signature',''); -CREATE TABLE keywords (id INTEGER PRIMARY KEY,short_name VARCHAR NOT NULL,keyword VARCHAR NOT NULL,favicon_url VARCHAR NOT NULL,url VARCHAR NOT NULL,show_in_default_list INTEGER,safe_for_autoreplace INTEGER,originating_url VARCHAR,date_created INTEGER DEFAULT 0,usage_count INTEGER DEFAULT 0,input_encodings VARCHAR,suggest_url VARCHAR,prepopulate_id INTEGER DEFAULT 0,autogenerate_keyword INTEGER DEFAULT 0,logo_id INTEGER DEFAULT 0,created_by_policy INTEGER DEFAULT 0,instant_url VARCHAR,last_modified INTEGER DEFAULT 0,sync_guid VARCHAR); -CREATE TABLE keywords_backup( - id INT, - short_name TEXT, - keyword TEXT, - favicon_url TEXT, - url TEXT, - safe_for_autoreplace INT, - originating_url TEXT, - date_created INT, - usage_count INT, - input_encodings TEXT, - show_in_default_list INT, - suggest_url TEXT, - prepopulate_id INT, - autogenerate_keyword INT, - logo_id INT, - created_by_policy INT, - instant_url TEXT, - last_modified INT, - sync_guid TEXT -); -CREATE TABLE autofill (name VARCHAR, value VARCHAR, value_lower VARCHAR, pair_id INTEGER PRIMARY KEY, count INTEGER DEFAULT 1); -CREATE TABLE credit_cards ( guid VARCHAR PRIMARY KEY, name_on_card VARCHAR, expiration_month INTEGER, expiration_year INTEGER, card_number_encrypted BLOB, date_modified INTEGER NOT NULL DEFAULT 0); -CREATE TABLE autofill_dates ( pair_id INTEGER DEFAULT 0, date_created INTEGER DEFAULT 0); -CREATE TABLE autofill_profiles ( guid VARCHAR PRIMARY KEY, company_name VARCHAR, address_line_1 VARCHAR, address_line_2 VARCHAR, city VARCHAR, state VARCHAR, zipcode VARCHAR, country VARCHAR, country_code VARCHAR, date_modified INTEGER NOT NULL DEFAULT 0); -CREATE TABLE autofill_profile_names ( guid VARCHAR, first_name VARCHAR, middle_name VARCHAR, last_name VARCHAR); -CREATE TABLE autofill_profile_emails ( guid VARCHAR, email VARCHAR); -CREATE TABLE autofill_profile_phones ( guid VARCHAR, type INTEGER DEFAULT 0, number VARCHAR); -CREATE TABLE autofill_profiles_trash ( guid VARCHAR); -CREATE TABLE logins (origin_url VARCHAR NOT NULL, action_url VARCHAR, username_element VARCHAR, username_value VARCHAR, password_element VARCHAR, password_value BLOB, submit_element VARCHAR, signon_realm VARCHAR NOT NULL,ssl_valid INTEGER NOT NULL,preferred INTEGER NOT NULL,date_created INTEGER NOT NULL,blacklisted_by_user INTEGER NOT NULL,scheme INTEGER NOT NULL,UNIQUE (origin_url, username_element, username_value, password_element, submit_element, signon_realm)); -CREATE TABLE ie7_logins (url_hash VARCHAR NOT NULL, password_value BLOB, date_created INTEGER NOT NULL,UNIQUE (url_hash)); -CREATE TABLE web_app_icons (url LONGVARCHAR,width int,height int,image BLOB, UNIQUE (url, width, height)); -CREATE TABLE web_apps (url LONGVARCHAR UNIQUE,has_all_images INTEGER NOT NULL); -CREATE TABLE token_service (service VARCHAR PRIMARY KEY NOT NULL,encrypted_token BLOB); -CREATE TABLE web_intents (service_url LONGVARCHAR,action VARCHAR,type VARCHAR,title LONGVARCHAR,disposition VARCHAR,UNIQUE (service_url, action, type)); -CREATE TABLE web_intents_defaults (action VARCHAR,type VARCHAR,url_pattern LONGVARCHAR,user_date INTEGER,suppression INTEGER,service_url LONGVARCHAR,UNIQUE (action, type, url_pattern)); -CREATE INDEX autofill_name ON autofill (name); -CREATE INDEX autofill_name_value_lower ON autofill (name, value_lower); -CREATE INDEX autofill_dates_pair_id ON autofill_dates (pair_id); -CREATE INDEX logins_signon ON logins (signon_realm); -CREATE INDEX ie7_logins_hash ON ie7_logins (url_hash); -CREATE INDEX web_apps_url_index ON web_apps (url); -CREATE INDEX web_intents_index ON web_intents (action); -CREATE INDEX web_intents_default_index ON web_intents_defaults (action); -COMMIT;
diff --git a/components/test/data/web_database/version_45.sql b/components/test/data/web_database/version_45.sql deleted file mode 100644 index 4b1e70a..0000000 --- a/components/test/data/web_database/version_45.sql +++ /dev/null
@@ -1,53 +0,0 @@ -PRAGMA foreign_keys=OFF; -BEGIN TRANSACTION; -CREATE TABLE meta(key LONGVARCHAR NOT NULL UNIQUE PRIMARY KEY, value LONGVARCHAR); -INSERT INTO "meta" VALUES('Default Search Provider ID','2'); -INSERT INTO "meta" VALUES('version','45'); -INSERT INTO "meta" VALUES('last_compatible_version','45'); -INSERT INTO "meta" VALUES('Default Search Provider ID Backup','2'); -INSERT INTO "meta" VALUES('Default Search Provider ID Backup Signature',''); -INSERT INTO "meta" VALUES('Builtin Keyword Version','39'); -CREATE TABLE autofill (name VARCHAR, value VARCHAR, value_lower VARCHAR, pair_id INTEGER PRIMARY KEY, count INTEGER DEFAULT 1); -CREATE TABLE credit_cards ( guid VARCHAR PRIMARY KEY, name_on_card VARCHAR, expiration_month INTEGER, expiration_year INTEGER, card_number_encrypted BLOB, date_modified INTEGER NOT NULL DEFAULT 0); -CREATE TABLE autofill_dates ( pair_id INTEGER DEFAULT 0, date_created INTEGER DEFAULT 0); -CREATE TABLE autofill_profiles ( guid VARCHAR PRIMARY KEY, company_name VARCHAR, address_line_1 VARCHAR, address_line_2 VARCHAR, city VARCHAR, state VARCHAR, zipcode VARCHAR, country VARCHAR, country_code VARCHAR, date_modified INTEGER NOT NULL DEFAULT 0); -CREATE TABLE autofill_profile_names ( guid VARCHAR, first_name VARCHAR, middle_name VARCHAR, last_name VARCHAR); -CREATE TABLE autofill_profile_emails ( guid VARCHAR, email VARCHAR); -CREATE TABLE autofill_profile_phones ( guid VARCHAR, type INTEGER DEFAULT 0, number VARCHAR); -CREATE TABLE autofill_profiles_trash ( guid VARCHAR); -CREATE TABLE web_app_icons (url LONGVARCHAR,width int,height int,image BLOB, UNIQUE (url, width, height)); -CREATE TABLE web_apps (url LONGVARCHAR UNIQUE,has_all_images INTEGER NOT NULL); -CREATE TABLE token_service (service VARCHAR PRIMARY KEY NOT NULL,encrypted_token BLOB); -CREATE TABLE web_intents (service_url LONGVARCHAR,action VARCHAR,type VARCHAR,title LONGVARCHAR,disposition VARCHAR,UNIQUE (service_url, action, type)); -CREATE TABLE web_intents_defaults (action VARCHAR,type VARCHAR,url_pattern LONGVARCHAR,user_date INTEGER,suppression INTEGER,service_url LONGVARCHAR,UNIQUE (action, type, url_pattern)); -CREATE TABLE "keywords" (id INTEGER PRIMARY KEY,short_name VARCHAR NOT NULL,keyword VARCHAR NOT NULL,favicon_url VARCHAR NOT NULL,url VARCHAR NOT NULL,safe_for_autoreplace INTEGER,originating_url VARCHAR,date_created INTEGER DEFAULT 0,usage_count INTEGER DEFAULT 0,input_encodings VARCHAR,show_in_default_list INTEGER,suggest_url VARCHAR,prepopulate_id INTEGER DEFAULT 0,created_by_policy INTEGER DEFAULT 0,instant_url VARCHAR,last_modified INTEGER DEFAULT 0,sync_guid VARCHAR); -CREATE TABLE keywords_backup( - id INT, - short_name TEXT, - keyword TEXT, - favicon_url TEXT, - url TEXT, - safe_for_autoreplace INT, - originating_url TEXT, - date_created INT, - usage_count INT, - input_encodings TEXT, - show_in_default_list INT, - suggest_url TEXT, - prepopulate_id INT, - created_by_policy INT, - instant_url TEXT, - last_modified INT, - sync_guid TEXT -); -CREATE INDEX autofill_name ON autofill (name); -CREATE INDEX autofill_name_value_lower ON autofill (name, value_lower); -CREATE INDEX autofill_dates_pair_id ON autofill_dates (pair_id); -CREATE INDEX web_apps_url_index ON web_apps (url); -CREATE INDEX web_intents_index ON web_intents (action); -CREATE INDEX web_intents_default_index ON web_intents_defaults (action); --- following statements are required for testing migration to version 46 -INSERT INTO web_intents VALUES ('http://poodles.com/fuzzer', 'fuzz', 'poodle/*', 'Poodle Fuzzer', 'window'); -INSERT INTO web_intents_defaults VALUES ('fuzz', 'poodle/*', '', 0, 0, 'http://poodles.com/fuzzer'); -COMMIT; -
diff --git a/components/test/data/web_database/version_45_compatible.sql b/components/test/data/web_database/version_45_compatible.sql deleted file mode 100644 index 158c40df..0000000 --- a/components/test/data/web_database/version_45_compatible.sql +++ /dev/null
@@ -1,50 +0,0 @@ -PRAGMA foreign_keys=OFF; -BEGIN TRANSACTION; -CREATE TABLE meta(key LONGVARCHAR NOT NULL UNIQUE PRIMARY KEY, value LONGVARCHAR); -INSERT INTO "meta" VALUES('Default Search Provider ID','2'); -INSERT INTO "meta" VALUES('version','40'); -INSERT INTO "meta" VALUES('last_compatible_version','45'); -INSERT INTO "meta" VALUES('Default Search Provider ID Backup','2'); -INSERT INTO "meta" VALUES('Default Search Provider ID Backup Signature',''); -INSERT INTO "meta" VALUES('Builtin Keyword Version','39'); -CREATE TABLE autofill (name VARCHAR, value VARCHAR, value_lower VARCHAR, pair_id INTEGER PRIMARY KEY, count INTEGER DEFAULT 1); -CREATE TABLE credit_cards ( guid VARCHAR PRIMARY KEY, name_on_card VARCHAR, expiration_month INTEGER, expiration_year INTEGER, card_number_encrypted BLOB, date_modified INTEGER NOT NULL DEFAULT 0); -CREATE TABLE autofill_dates ( pair_id INTEGER DEFAULT 0, date_created INTEGER DEFAULT 0); -CREATE TABLE autofill_profiles ( guid VARCHAR PRIMARY KEY, company_name VARCHAR, address_line_1 VARCHAR, address_line_2 VARCHAR, city VARCHAR, state VARCHAR, zipcode VARCHAR, country VARCHAR, country_code VARCHAR, date_modified INTEGER NOT NULL DEFAULT 0); -CREATE TABLE autofill_profile_names ( guid VARCHAR, first_name VARCHAR, middle_name VARCHAR, last_name VARCHAR); -CREATE TABLE autofill_profile_emails ( guid VARCHAR, email VARCHAR); -CREATE TABLE autofill_profile_phones ( guid VARCHAR, type INTEGER DEFAULT 0, number VARCHAR); -CREATE TABLE autofill_profiles_trash ( guid VARCHAR); -CREATE TABLE web_app_icons (url LONGVARCHAR,width int,height int,image BLOB, UNIQUE (url, width, height)); -CREATE TABLE web_apps (url LONGVARCHAR UNIQUE,has_all_images INTEGER NOT NULL); -CREATE TABLE token_service (service VARCHAR PRIMARY KEY NOT NULL,encrypted_token BLOB); -CREATE TABLE web_intents (service_url LONGVARCHAR,action VARCHAR,type VARCHAR,title LONGVARCHAR,disposition VARCHAR,UNIQUE (service_url, action, type)); -CREATE TABLE web_intents_defaults (action VARCHAR,type VARCHAR,url_pattern LONGVARCHAR,user_date INTEGER,suppression INTEGER,service_url LONGVARCHAR,UNIQUE (action, type, url_pattern)); -CREATE TABLE "keywords" (id INTEGER PRIMARY KEY,short_name VARCHAR NOT NULL,keyword VARCHAR NOT NULL,favicon_url VARCHAR NOT NULL,url VARCHAR NOT NULL,safe_for_autoreplace INTEGER,originating_url VARCHAR,date_created INTEGER DEFAULT 0,usage_count INTEGER DEFAULT 0,input_encodings VARCHAR,show_in_default_list INTEGER,suggest_url VARCHAR,prepopulate_id INTEGER DEFAULT 0,created_by_policy INTEGER DEFAULT 0,instant_url VARCHAR,last_modified INTEGER DEFAULT 0,sync_guid VARCHAR); -CREATE TABLE keywords_backup( - id INT, - short_name TEXT, - keyword TEXT, - favicon_url TEXT, - url TEXT, - safe_for_autoreplace INT, - originating_url TEXT, - date_created INT, - usage_count INT, - input_encodings TEXT, - show_in_default_list INT, - suggest_url TEXT, - prepopulate_id INT, - created_by_policy INT, - instant_url TEXT, - last_modified INT, - sync_guid TEXT -); -CREATE INDEX autofill_name ON autofill (name); -CREATE INDEX autofill_name_value_lower ON autofill (name, value_lower); -CREATE INDEX autofill_dates_pair_id ON autofill_dates (pair_id); -CREATE INDEX web_apps_url_index ON web_apps (url); -CREATE INDEX web_intents_index ON web_intents (action); -CREATE INDEX web_intents_default_index ON web_intents_defaults (action); -COMMIT; -
diff --git a/components/test/data/web_database/version_45_invalid.sql b/components/test/data/web_database/version_45_invalid.sql deleted file mode 100644 index ff2b94b..0000000 --- a/components/test/data/web_database/version_45_invalid.sql +++ /dev/null
@@ -1,50 +0,0 @@ -PRAGMA foreign_keys=OFF; -BEGIN TRANSACTION; -CREATE TABLE meta(key LONGVARCHAR NOT NULL UNIQUE PRIMARY KEY, value LONGVARCHAR); -INSERT INTO "meta" VALUES('Default Search Provider ID','2'); -INSERT INTO "meta" VALUES('version','45'); -INSERT INTO "meta" VALUES('last_compatible_version','45'); -INSERT INTO "meta" VALUES('Default Search Provider ID Backup','2'); -INSERT INTO "meta" VALUES('Default Search Provider ID Backup Signature',''); -INSERT INTO "meta" VALUES('Builtin Keyword Version','39'); -CREATE TABLE autofill (name VARCHAR, value VARCHAR, value_lower VARCHAR, pair_id INTEGER PRIMARY KEY, count INTEGER DEFAULT 1); -CREATE TABLE credit_cards ( guid VARCHAR PRIMARY KEY, name_on_card VARCHAR, expiration_month INTEGER, expiration_year INTEGER, card_number_encrypted BLOB, date_modified INTEGER NOT NULL DEFAULT 0); -CREATE TABLE autofill_dates ( pair_id INTEGER DEFAULT 0, date_created INTEGER DEFAULT 0); -CREATE TABLE autofill_profiles ( guid VARCHAR PRIMARY KEY, company_name VARCHAR, address_line_1 VARCHAR, address_line_2 VARCHAR, city VARCHAR, state VARCHAR, zipcode VARCHAR, country VARCHAR, country_code VARCHAR, date_modified INTEGER NOT NULL DEFAULT 0); -CREATE TABLE autofill_profile_names ( guid VARCHAR, first_name VARCHAR, middle_name VARCHAR, last_name VARCHAR); -CREATE TABLE autofill_profile_emails ( guid VARCHAR, email VARCHAR); -CREATE TABLE autofill_profile_phones ( guid VARCHAR, type INTEGER DEFAULT 0, number VARCHAR); -CREATE TABLE autofill_profiles_trash ( guid VARCHAR); -CREATE TABLE web_app_icons (url LONGVARCHAR,width int,height int,image BLOB, UNIQUE (url, width, height)); -CREATE TABLE web_apps (url LONGVARCHAR UNIQUE,has_all_images INTEGER NOT NULL); -CREATE TABLE token_service (service VARCHAR PRIMARY KEY NOT NULL,encrypted_token BLOB); -CREATE TABLE web_intents (INTEGER blabbity); -CREATE TABLE web_intents_defaults (VARCHAR hammy); -CREATE TABLE "keywords" (id INTEGER PRIMARY KEY,short_name VARCHAR NOT NULL,keyword VARCHAR NOT NULL,favicon_url VARCHAR NOT NULL,url VARCHAR NOT NULL,safe_for_autoreplace INTEGER,originating_url VARCHAR,date_created INTEGER DEFAULT 0,usage_count INTEGER DEFAULT 0,input_encodings VARCHAR,show_in_default_list INTEGER,suggest_url VARCHAR,prepopulate_id INTEGER DEFAULT 0,created_by_policy INTEGER DEFAULT 0,instant_url VARCHAR,last_modified INTEGER DEFAULT 0,sync_guid VARCHAR); -CREATE TABLE keywords_backup( - id INT, - short_name TEXT, - keyword TEXT, - favicon_url TEXT, - url TEXT, - safe_for_autoreplace INT, - originating_url TEXT, - date_created INT, - usage_count INT, - input_encodings TEXT, - show_in_default_list INT, - suggest_url TEXT, - prepopulate_id INT, - created_by_policy INT, - instant_url TEXT, - last_modified INT, - sync_guid TEXT -); -CREATE INDEX autofill_name ON autofill (name); -CREATE INDEX autofill_name_value_lower ON autofill (name, value_lower); -CREATE INDEX autofill_dates_pair_id ON autofill_dates (pair_id); -CREATE INDEX web_apps_url_index ON web_apps (url); --- following statements are required for testing migration to version 46 -INSERT INTO web_intents VALUES (11); -INSERT INTO web_intents_defaults VALUES ('fuzz'); -COMMIT;
diff --git a/components/test/data/web_database/version_46.sql b/components/test/data/web_database/version_46.sql deleted file mode 100644 index 8dcf7cb..0000000 --- a/components/test/data/web_database/version_46.sql +++ /dev/null
@@ -1,31 +0,0 @@ -PRAGMA foreign_keys=OFF; -BEGIN TRANSACTION; -CREATE TABLE meta(key LONGVARCHAR NOT NULL UNIQUE PRIMARY KEY, value LONGVARCHAR); -INSERT INTO "meta" VALUES('Default Search Provider ID','0'); -INSERT INTO "meta" VALUES('version','46'); -INSERT INTO "meta" VALUES('last_compatible_version','46'); -INSERT INTO "meta" VALUES('Default Search Provider ID Backup','0'); -INSERT INTO "meta" VALUES('Default Search Provider ID Backup Signature',''); -INSERT INTO "meta" VALUES('Builtin Keyword Version','39'); -CREATE TABLE autofill (name VARCHAR, value VARCHAR, value_lower VARCHAR, pair_id INTEGER PRIMARY KEY, count INTEGER DEFAULT 1); -CREATE TABLE credit_cards ( guid VARCHAR PRIMARY KEY, name_on_card VARCHAR, expiration_month INTEGER, expiration_year INTEGER, card_number_encrypted BLOB, date_modified INTEGER NOT NULL DEFAULT 0); -CREATE TABLE autofill_dates ( pair_id INTEGER DEFAULT 0, date_created INTEGER DEFAULT 0); -CREATE TABLE autofill_profiles ( guid VARCHAR PRIMARY KEY, company_name VARCHAR, address_line_1 VARCHAR, address_line_2 VARCHAR, city VARCHAR, state VARCHAR, zipcode VARCHAR, country VARCHAR, country_code VARCHAR, date_modified INTEGER NOT NULL DEFAULT 0); -CREATE TABLE autofill_profile_names ( guid VARCHAR, first_name VARCHAR, middle_name VARCHAR, last_name VARCHAR); -CREATE TABLE autofill_profile_emails ( guid VARCHAR, email VARCHAR); -CREATE TABLE autofill_profile_phones ( guid VARCHAR, type INTEGER DEFAULT 0, number VARCHAR); -CREATE TABLE autofill_profiles_trash ( guid VARCHAR); -CREATE TABLE web_app_icons (url LONGVARCHAR,width int,height int,image BLOB, UNIQUE (url, width, height)); -CREATE TABLE web_apps (url LONGVARCHAR UNIQUE,has_all_images INTEGER NOT NULL); -CREATE TABLE token_service (service VARCHAR PRIMARY KEY NOT NULL,encrypted_token BLOB); -CREATE TABLE web_intents (service_url LONGVARCHAR,action VARCHAR,type VARCHAR,title LONGVARCHAR,disposition VARCHAR,scheme VARCHAR,UNIQUE (service_url, action, type)); -CREATE TABLE web_intents_defaults (action VARCHAR,type VARCHAR,url_pattern LONGVARCHAR,user_date INTEGER,suppression INTEGER,service_url LONGVARCHAR,scheme VARCHAR,UNIQUE (action, type, url_pattern)); -CREATE TABLE keywords (id INTEGER PRIMARY KEY,short_name VARCHAR NOT NULL,keyword VARCHAR NOT NULL,favicon_url VARCHAR NOT NULL,url VARCHAR NOT NULL,safe_for_autoreplace INTEGER,originating_url VARCHAR,date_created INTEGER DEFAULT 0,usage_count INTEGER DEFAULT 0,input_encodings VARCHAR,show_in_default_list INTEGER,suggest_url VARCHAR,prepopulate_id INTEGER DEFAULT 0,created_by_policy INTEGER DEFAULT 0,instant_url VARCHAR,last_modified INTEGER DEFAULT 0,sync_guid VARCHAR); -CREATE TABLE keywords_backup(id INT,short_name TEXT,keyword TEXT,favicon_url TEXT,url TEXT,safe_for_autoreplace INT,originating_url TEXT,date_created INT,usage_count INT,input_encodings TEXT,show_in_default_list INT,suggest_url TEXT,prepopulate_id INT,created_by_policy INT,instant_url TEXT,last_modified INT,sync_guid TEXT); -CREATE INDEX autofill_name ON autofill (name); -CREATE INDEX autofill_name_value_lower ON autofill (name, value_lower); -CREATE INDEX autofill_dates_pair_id ON autofill_dates (pair_id); -CREATE INDEX web_apps_url_index ON web_apps (url); -CREATE INDEX web_intents_index ON web_intents (action); -CREATE INDEX web_intents_default_index ON web_intents_defaults (action); -COMMIT;
diff --git a/components/test/data/web_database/version_47.sql b/components/test/data/web_database/version_47.sql deleted file mode 100644 index aae06e8..0000000 --- a/components/test/data/web_database/version_47.sql +++ /dev/null
@@ -1,50 +0,0 @@ -PRAGMA foreign_keys=OFF; -BEGIN TRANSACTION; -CREATE TABLE meta(key LONGVARCHAR NOT NULL UNIQUE PRIMARY KEY, value LONGVARCHAR); -INSERT INTO "meta" VALUES('version','47'); -INSERT INTO "meta" VALUES('last_compatible_version','47'); -INSERT INTO "meta" VALUES('Builtin Keyword Version','46'); -INSERT INTO "meta" VALUES('Default Search Provider ID','2'); -INSERT INTO "meta" VALUES('Default Search Provider ID Backup','2'); -INSERT INTO "meta" VALUES('Default Search Provider ID Backup Signature',''); -CREATE TABLE keywords (id INTEGER PRIMARY KEY,short_name VARCHAR NOT NULL,keyword VARCHAR NOT NULL,favicon_url VARCHAR NOT NULL,url VARCHAR NOT NULL,safe_for_autoreplace INTEGER,originating_url VARCHAR,date_created INTEGER DEFAULT 0,usage_count INTEGER DEFAULT 0,input_encodings VARCHAR,show_in_default_list INTEGER,suggest_url VARCHAR,prepopulate_id INTEGER DEFAULT 0,created_by_policy INTEGER DEFAULT 0,instant_url VARCHAR,last_modified INTEGER DEFAULT 0,sync_guid VARCHAR,alternate_urls VARCHAR); -CREATE TABLE keywords_backup( - id INT, - short_name TEXT, - keyword TEXT, - favicon_url TEXT, - url TEXT, - safe_for_autoreplace INT, - originating_url TEXT, - date_created INT, - usage_count INT, - input_encodings TEXT, - show_in_default_list INT, - suggest_url TEXT, - prepopulate_id INT, - created_by_policy INT, - instant_url TEXT, - last_modified INT, - sync_guid TEXT, - alternate_urls TEXT -); -CREATE TABLE autofill (name VARCHAR, value VARCHAR, value_lower VARCHAR, pair_id INTEGER PRIMARY KEY, count INTEGER DEFAULT 1); -CREATE TABLE credit_cards ( guid VARCHAR PRIMARY KEY, name_on_card VARCHAR, expiration_month INTEGER, expiration_year INTEGER, card_number_encrypted BLOB, date_modified INTEGER NOT NULL DEFAULT 0); -CREATE TABLE autofill_dates ( pair_id INTEGER DEFAULT 0, date_created INTEGER DEFAULT 0); -CREATE TABLE autofill_profiles ( guid VARCHAR PRIMARY KEY, company_name VARCHAR, address_line_1 VARCHAR, address_line_2 VARCHAR, city VARCHAR, state VARCHAR, zipcode VARCHAR, country VARCHAR, country_code VARCHAR, date_modified INTEGER NOT NULL DEFAULT 0); -CREATE TABLE autofill_profile_names ( guid VARCHAR, first_name VARCHAR, middle_name VARCHAR, last_name VARCHAR); -CREATE TABLE autofill_profile_emails ( guid VARCHAR, email VARCHAR); -CREATE TABLE autofill_profile_phones ( guid VARCHAR, type INTEGER DEFAULT 0, number VARCHAR); -CREATE TABLE autofill_profiles_trash ( guid VARCHAR); -CREATE TABLE web_app_icons (url LONGVARCHAR,width int,height int,image BLOB, UNIQUE (url, width, height)); -CREATE TABLE web_apps (url LONGVARCHAR UNIQUE,has_all_images INTEGER NOT NULL); -CREATE TABLE token_service (service VARCHAR PRIMARY KEY NOT NULL,encrypted_token BLOB); -CREATE TABLE web_intents ( service_url LONGVARCHAR, action VARCHAR, type VARCHAR, title LONGVARCHAR, disposition VARCHAR, scheme VARCHAR, UNIQUE (service_url, action, scheme, type)); -CREATE TABLE web_intents_defaults ( action VARCHAR, type VARCHAR, url_pattern LONGVARCHAR, user_date INTEGER, suppression INTEGER, service_url LONGVARCHAR, scheme VARCHAR, UNIQUE (action, scheme, type, url_pattern)); -CREATE INDEX autofill_name ON autofill (name); -CREATE INDEX autofill_name_value_lower ON autofill (name, value_lower); -CREATE INDEX autofill_dates_pair_id ON autofill_dates (pair_id); -CREATE INDEX web_apps_url_index ON web_apps (url); -CREATE INDEX web_intents_index ON web_intents (action); -CREATE INDEX web_intents_default_index ON web_intents_defaults (action); -COMMIT;
diff --git a/components/test/data/web_database/version_48.sql b/components/test/data/web_database/version_48.sql deleted file mode 100644 index 53a9ed7..0000000 --- a/components/test/data/web_database/version_48.sql +++ /dev/null
@@ -1,28 +0,0 @@ -PRAGMA foreign_keys=OFF; -BEGIN TRANSACTION; -CREATE TABLE meta(key LONGVARCHAR NOT NULL UNIQUE PRIMARY KEY, value LONGVARCHAR); -INSERT INTO "meta" VALUES('version','48'); -INSERT INTO "meta" VALUES('last_compatible_version','48'); -INSERT INTO "meta" VALUES('Builtin Keyword Version','48'); -INSERT INTO "meta" VALUES('Default Search Provider ID','2'); -CREATE TABLE keywords (id INTEGER PRIMARY KEY,short_name VARCHAR NOT NULL,keyword VARCHAR NOT NULL,favicon_url VARCHAR NOT NULL,url VARCHAR NOT NULL,safe_for_autoreplace INTEGER,originating_url VARCHAR,date_created INTEGER DEFAULT 0,usage_count INTEGER DEFAULT 0,input_encodings VARCHAR,show_in_default_list INTEGER,suggest_url VARCHAR,prepopulate_id INTEGER DEFAULT 0,created_by_policy INTEGER DEFAULT 0,instant_url VARCHAR,last_modified INTEGER DEFAULT 0,sync_guid VARCHAR,alternate_urls VARCHAR); -CREATE TABLE autofill (name VARCHAR, value VARCHAR, value_lower VARCHAR, pair_id INTEGER PRIMARY KEY, count INTEGER DEFAULT 1); -CREATE TABLE credit_cards ( guid VARCHAR PRIMARY KEY, name_on_card VARCHAR, expiration_month INTEGER, expiration_year INTEGER, card_number_encrypted BLOB, date_modified INTEGER NOT NULL DEFAULT 0); -CREATE TABLE autofill_dates ( pair_id INTEGER DEFAULT 0, date_created INTEGER DEFAULT 0); -CREATE TABLE autofill_profiles ( guid VARCHAR PRIMARY KEY, company_name VARCHAR, address_line_1 VARCHAR, address_line_2 VARCHAR, city VARCHAR, state VARCHAR, zipcode VARCHAR, country VARCHAR, country_code VARCHAR, date_modified INTEGER NOT NULL DEFAULT 0); -CREATE TABLE autofill_profile_names ( guid VARCHAR, first_name VARCHAR, middle_name VARCHAR, last_name VARCHAR); -CREATE TABLE autofill_profile_emails ( guid VARCHAR, email VARCHAR); -CREATE TABLE autofill_profile_phones ( guid VARCHAR, type INTEGER DEFAULT 0, number VARCHAR); -CREATE TABLE autofill_profiles_trash ( guid VARCHAR); -CREATE TABLE web_app_icons (url LONGVARCHAR,width int,height int,image BLOB, UNIQUE (url, width, height)); -CREATE TABLE web_apps (url LONGVARCHAR UNIQUE,has_all_images INTEGER NOT NULL); -CREATE TABLE token_service (service VARCHAR PRIMARY KEY NOT NULL,encrypted_token BLOB); -CREATE TABLE web_intents ( service_url LONGVARCHAR, action VARCHAR, type VARCHAR, title LONGVARCHAR, disposition VARCHAR, scheme VARCHAR, UNIQUE (service_url, action, scheme, type)); -CREATE TABLE web_intents_defaults ( action VARCHAR, type VARCHAR, url_pattern LONGVARCHAR, user_date INTEGER, suppression INTEGER, service_url LONGVARCHAR, scheme VARCHAR, UNIQUE (action, scheme, type, url_pattern)); -CREATE INDEX autofill_name ON autofill (name); -CREATE INDEX autofill_name_value_lower ON autofill (name, value_lower); -CREATE INDEX autofill_dates_pair_id ON autofill_dates (pair_id); -CREATE INDEX web_apps_url_index ON web_apps (url); -CREATE INDEX web_intents_index ON web_intents (action); -CREATE INDEX web_intents_default_index ON web_intents_defaults (action); -COMMIT;
diff --git a/components/test/data/web_database/version_49.sql b/components/test/data/web_database/version_49.sql deleted file mode 100644 index 02a4fd9..0000000 --- a/components/test/data/web_database/version_49.sql +++ /dev/null
@@ -1,31 +0,0 @@ -PRAGMA foreign_keys=OFF; -BEGIN TRANSACTION; -CREATE TABLE meta(key LONGVARCHAR NOT NULL UNIQUE PRIMARY KEY, value LONGVARCHAR); -INSERT INTO "meta" VALUES('version','49'); -INSERT INTO "meta" VALUES('last_compatible_version','48'); -INSERT INTO "meta" VALUES('Builtin Keyword Version','54'); -INSERT INTO "meta" VALUES('Default Search Provider ID','2'); -CREATE TABLE autofill (name VARCHAR, value VARCHAR, value_lower VARCHAR, pair_id INTEGER PRIMARY KEY, count INTEGER DEFAULT 1); -CREATE TABLE credit_cards ( guid VARCHAR PRIMARY KEY, name_on_card VARCHAR, expiration_month INTEGER, expiration_year INTEGER, card_number_encrypted BLOB, date_modified INTEGER NOT NULL DEFAULT 0); -CREATE TABLE autofill_dates ( pair_id INTEGER DEFAULT 0, date_created INTEGER DEFAULT 0); -CREATE TABLE autofill_profiles ( guid VARCHAR PRIMARY KEY, company_name VARCHAR, address_line_1 VARCHAR, address_line_2 VARCHAR, city VARCHAR, state VARCHAR, zipcode VARCHAR, country VARCHAR, country_code VARCHAR, date_modified INTEGER NOT NULL DEFAULT 0); -CREATE TABLE autofill_profile_names ( guid VARCHAR, first_name VARCHAR, middle_name VARCHAR, last_name VARCHAR); -CREATE TABLE autofill_profile_emails ( guid VARCHAR, email VARCHAR); -CREATE TABLE autofill_profile_phones ( guid VARCHAR, type INTEGER DEFAULT 0, number VARCHAR); -CREATE TABLE autofill_profiles_trash ( guid VARCHAR); -CREATE TABLE keywords (id INTEGER PRIMARY KEY,short_name VARCHAR NOT NULL,keyword VARCHAR NOT NULL,favicon_url VARCHAR NOT NULL,url VARCHAR NOT NULL,safe_for_autoreplace INTEGER,originating_url VARCHAR,date_created INTEGER DEFAULT 0,usage_count INTEGER DEFAULT 0,input_encodings VARCHAR,show_in_default_list INTEGER,suggest_url VARCHAR,prepopulate_id INTEGER DEFAULT 0,created_by_policy INTEGER DEFAULT 0,instant_url VARCHAR,last_modified INTEGER DEFAULT 0,sync_guid VARCHAR,alternate_urls VARCHAR,search_terms_replacement_key VARCHAR); -INSERT INTO "keywords" VALUES(2,'Google','google.com','http://www.google.com/favicon.ico','{google:baseURL}search?q={searchTerms}&{google:RLZ}{google:originalQueryForSuggestion}{google:assistedQueryStats}{google:searchFieldtrialParameter}{google:searchClient}{google:sourceId}{google:instantExtendedEnabledParameter}ie={inputEncoding}',1,'',0,0,'UTF-8',1,'{google:baseSuggestURL}search?{google:searchFieldtrialParameter}client=chrome&q={searchTerms}&{google:cursorPosition}sugkey={google:suggestAPIKeyParameter}',1,0,'{google:baseURL}webhp?sourceid=chrome-instant&{google:RLZ}{google:instantEnabledParameter}{google:instantExtendedEnabledParameter}{google:ntpIsThemedParameter}{google:omniboxStartMarginParameter}ie={inputEncoding}',0,'711AEC98-A563-FD8B-87D5-427C60828A43','["{google:baseURL}#q={searchTerms}","{google:baseURL}search#q={searchTerms}","{google:baseURL}webhp#q={searchTerms}"]','espv'); -INSERT INTO "keywords" VALUES(3,'Yahoo!','yahoo.com','http://search.yahoo.com/favicon.ico','http://search.yahoo.com/search?ei={inputEncoding}&fr=crmas&p={searchTerms}',1,'',0,0,'UTF-8',1,'http://ff.search.yahoo.com/gossip?output=fxjson&command={searchTerms}',2,0,'',0,'7A35F8C9-ADD7-2C08-475E-B51151C79514','[]',''); -INSERT INTO "keywords" VALUES(4,'Bing','bing.com','http://www.bing.com/s/wlflag.ico','http://www.bing.com/search?setmkt=en-US&q={searchTerms}',1,'',0,0,'UTF-8',1,'http://api.bing.com/osjson.aspx?query={searchTerms}&language={language}',3,0,'',0,'94DA8067-BC2D-9033-0EDD-2F667874C223','[]',''); -CREATE TABLE token_service (service VARCHAR PRIMARY KEY NOT NULL,encrypted_token BLOB); -CREATE TABLE web_app_icons (url LONGVARCHAR,width int,height int,image BLOB, UNIQUE (url, width, height)); -CREATE TABLE web_apps (url LONGVARCHAR UNIQUE,has_all_images INTEGER NOT NULL); -CREATE TABLE web_intents ( service_url LONGVARCHAR, action VARCHAR, type VARCHAR, title LONGVARCHAR, disposition VARCHAR, scheme VARCHAR, UNIQUE (service_url, action, scheme, type)); -CREATE TABLE web_intents_defaults ( action VARCHAR, type VARCHAR, url_pattern LONGVARCHAR, user_date INTEGER, suppression INTEGER, service_url LONGVARCHAR, scheme VARCHAR, UNIQUE (action, scheme, type, url_pattern)); -CREATE INDEX autofill_name ON autofill (name); -CREATE INDEX autofill_name_value_lower ON autofill (name, value_lower); -CREATE INDEX autofill_dates_pair_id ON autofill_dates (pair_id); -CREATE INDEX web_apps_url_index ON web_apps (url); -CREATE INDEX web_intents_index ON web_intents (action); -CREATE INDEX web_intents_default_index ON web_intents_defaults (action); -COMMIT;
diff --git a/components/test/data/web_database/version_62.sql b/components/test/data/web_database/version_62.sql new file mode 100644 index 0000000..e23ab8b --- /dev/null +++ b/components/test/data/web_database/version_62.sql
@@ -0,0 +1,26 @@ +PRAGMA foreign_keys=OFF; +BEGIN TRANSACTION; +CREATE TABLE meta(key LONGVARCHAR NOT NULL UNIQUE PRIMARY KEY, value LONGVARCHAR); +INSERT INTO "meta" VALUES('version','60'); +INSERT INTO "meta" VALUES('last_compatible_version','59'); +INSERT INTO "meta" VALUES('Builtin Keyword Version','79'); +CREATE TABLE token_service (service VARCHAR PRIMARY KEY NOT NULL,encrypted_token BLOB); +CREATE TABLE autofill (name VARCHAR, value VARCHAR, value_lower VARCHAR, date_created INTEGER DEFAULT 0, date_last_used INTEGER DEFAULT 0, count INTEGER DEFAULT 1, PRIMARY KEY (name, value)); +CREATE TABLE credit_cards ( guid VARCHAR PRIMARY KEY, name_on_card VARCHAR, expiration_month INTEGER, expiration_year INTEGER, card_number_encrypted BLOB, date_modified INTEGER NOT NULL DEFAULT 0, origin VARCHAR DEFAULT ''); +CREATE TABLE autofill_profiles ( guid VARCHAR PRIMARY KEY, company_name VARCHAR, street_address VARCHAR, dependent_locality VARCHAR, city VARCHAR, state VARCHAR, zipcode VARCHAR, sorting_code VARCHAR, country_code VARCHAR, date_modified INTEGER NOT NULL DEFAULT 0, origin VARCHAR DEFAULT '', language_code VARCHAR); +CREATE TABLE autofill_profile_names ( guid VARCHAR, first_name VARCHAR, middle_name VARCHAR, last_name VARCHAR, full_name VARCHAR); +CREATE TABLE autofill_profile_emails ( guid VARCHAR, email VARCHAR); +CREATE TABLE autofill_profile_phones ( guid VARCHAR, number VARCHAR); +CREATE TABLE autofill_profiles_trash ( guid VARCHAR); +CREATE TABLE masked_credit_cards (id VARCHAR,status VARCHAR,name_on_card VARCHAR,type VARCHAR,last_four VARCHAR,exp_month INTEGER DEFAULT 0,exp_year INTEGER DEFAULT 0); +CREATE TABLE unmasked_credit_cards (id VARCHAR,card_number_encrypted VARCHAR); +CREATE TABLE server_addresses (id VARCHAR,company_name VARCHAR,street_address VARCHAR,address_1 VARCHAR,address_2 VARCHAR,address_3 VARCHAR,address_4 VARCHAR,postal_code VARCHAR,sorting_code VARCHAR,country_code VARCHAR,language_code VARCHAR); +CREATE TABLE keywords (id INTEGER PRIMARY KEY,short_name VARCHAR NOT NULL,keyword VARCHAR NOT NULL,favicon_url VARCHAR NOT NULL,url VARCHAR NOT NULL,safe_for_autoreplace INTEGER,originating_url VARCHAR,date_created INTEGER DEFAULT 0,usage_count INTEGER DEFAULT 0,input_encodings VARCHAR,show_in_default_list INTEGER,suggest_url VARCHAR,prepopulate_id INTEGER DEFAULT 0,created_by_policy INTEGER DEFAULT 0,instant_url VARCHAR,last_modified INTEGER DEFAULT 0,sync_guid VARCHAR,alternate_urls VARCHAR,search_terms_replacement_key VARCHAR,image_url VARCHAR,search_url_post_params VARCHAR,suggest_url_post_params VARCHAR,instant_url_post_params VARCHAR,image_url_post_params VARCHAR,new_tab_url VARCHAR); +INSERT INTO "keywords" VALUES(2,'Google','google.com','http://www.google.com/favicon.ico','{google:baseURL}search?q={searchTerms}&{google:RLZ}{google:originalQueryForSuggestion}{google:assistedQueryStats}{google:searchFieldtrialParameter}{google:bookmarkBarPinned}{google:searchClient}{google:sourceId}{google:instantExtendedEnabledParameter}{google:omniboxStartMarginParameter}{google:contextualSearchVersion}ie={inputEncoding}',1,'',0,0,'UTF-8',1,'{google:baseSuggestURL}search?{google:searchFieldtrialParameter}client={google:suggestClient}&gs_ri={google:suggestRid}&xssi=t&q={searchTerms}&{google:inputType}{google:cursorPosition}{google:currentPageUrl}{google:pageClassification}{google:searchVersion}{google:sessionToken}{google:prefetchQuery}sugkey={google:suggestAPIKeyParameter}',1,0,'{google:baseURL}webhp?sourceid=chrome-instant&{google:RLZ}{google:forceInstantResults}{google:instantExtendedEnabledParameter}{google:ntpIsThemedParameter}{google:omniboxStartMarginParameter}ie={inputEncoding}',0,'EAB7604D-85AD-455A-AA7F-3A1B68CDDA0C','["{google:baseURL}#q={searchTerms}","{google:baseURL}search#q={searchTerms}","{google:baseURL}webhp#q={searchTerms}","{google:baseURL}s?q={searchTerms}"]','espv','{google:baseURL}searchbyimage/upload','','','','encoded_image={google:imageThumbnail},image_url={google:imageURL},sbisrc={google:imageSearchSource},original_width={google:imageOriginalWidth},original_height={google:imageOriginalHeight}','{google:baseURL}_/chrome/newtab?{google:RLZ}{google:instantExtendedEnabledParameter}{google:ntpIsThemedParameter}ie={inputEncoding}'); +INSERT INTO "keywords" VALUES(3,'Bing','bing.com','https://www.bing.com/s/a/bing_p.ico','https://www.bing.com/search?setmkt=en-US&q={searchTerms}',1,'',0,0,'UTF-8',1,'http://api.bing.com/osjson.aspx?query={searchTerms}&language={language}',3,0,'',0,'865547E0-515C-482B-A202-F79CA3743BF8','[]','','','','','','','https://www.bing.com/chrome/newtab?setmkt=en-US'); +INSERT INTO "keywords" VALUES(4,'Yahoo!','yahoo.com','https://search.yahoo.com/favicon.ico','https://search.yahoo.com/search?ei={inputEncoding}&fr=crmas&p={searchTerms}',1,'',0,0,'UTF-8',1,'https://search.yahoo.com/sugg/chrome?output=fxjson&appid=crmas&command={searchTerms}',2,0,'',0,'9C8E4670-5993-46EF-8BEF-8012124C299D','[]','','','','','','',''); +INSERT INTO "keywords" VALUES(5,'AOL','aol.com','http://search.aol.com/favicon.ico','http://search.aol.com/aol/search?q={searchTerms}',1,'',0,0,'UTF-8',1,'http://autocomplete.search.aol.com/autocomplete/get?output=json&it=&q={searchTerms}',35,0,'',0,'946DE8D0-0602-4C1A-BE0C-E44EDE8DCCA3','[]','','','','','','',''); +INSERT INTO "keywords" VALUES(6,'Ask','ask.com','http://sp.ask.com/sh/i/a16/favicon/favicon.ico','http://www.ask.com/web?q={searchTerms}',1,'',0,0,'UTF-8',1,'http://ss.ask.com/query?q={searchTerms}&li=ff',4,0,'',0,'F5C5564A-42A4-432B-A59E-2306689DF48B','[]','','','','','','',''); +CREATE INDEX autofill_name ON autofill (name); +CREATE INDEX autofill_name_value_lower ON autofill (name, value_lower); +COMMIT;
diff --git a/components/web_modal/native_web_contents_modal_dialog.h b/components/web_modal/native_web_contents_modal_dialog.h index 4bb956a..ef459b1e 100644 --- a/components/web_modal/native_web_contents_modal_dialog.h +++ b/components/web_modal/native_web_contents_modal_dialog.h
@@ -11,21 +11,8 @@ // TODO(gbillock): rename this file -#if defined(OS_MACOSX) -// Use a void* since none of the gfx::Native* types are suitable for -// representing the web contents modal dialog under Cocoa. -typedef void* NativeWebContentsModalDialog; -#else -typedef gfx::NativeView NativeWebContentsModalDialog; -#endif - -#if defined(OS_MACOSX) -// Use a void* since none of the gfx::Native* types are suitable for -// representing a popup window under Cocoa. -typedef void* NativePopup; -#else -typedef gfx::NativeView NativePopup; -#endif +using NativeWebContentsModalDialog = gfx::NativeWindow; +using NativePopup = gfx::NativeWindow; } // namespace web_modal
diff --git a/components/webdata/common/web_database.cc b/components/webdata/common/web_database.cc index 018663da..675f7c5 100644 --- a/components/webdata/common/web_database.cc +++ b/components/webdata/common/web_database.cc
@@ -14,7 +14,9 @@ // corresponding changes must happen in the unit tests, and new migration test // added. See |WebDatabaseMigrationTest::kCurrentTestedVersionNumber|. // static -const int WebDatabase::kCurrentVersionNumber = 62; +const int WebDatabase::kCurrentVersionNumber = 63; + +const int WebDatabase::kDeprecatedVersionNumber = 51; namespace { @@ -87,7 +89,13 @@ if (!db_.Open(db_name)) return sql::INIT_FAILURE; - // Initialize various tables + // Clobber really old databases. + static_assert(kDeprecatedVersionNumber < kCurrentVersionNumber, + "Deprecation version must be less than current"); + sql::MetaTable::RazeIfDeprecated(&db_, kDeprecatedVersionNumber); + + // Scope initialization in a transaction so we can't be partially + // initialized. sql::Transaction transaction(&db_); if (!transaction.Begin()) return sql::INIT_FAILURE; @@ -135,22 +143,7 @@ if (current_version > meta_table_.GetVersionNumber()) ChangeVersion(&meta_table_, current_version, false); - if (current_version < 20) { - // Versions 1 - 19 are unhandled. Version numbers greater than - // kCurrentVersionNumber should have already been weeded out by the caller. - // - // When the version is too old, we return failure error code. The schema - // is too out of date to migrate. - // - // There should not be a released product that makes a database too old to - // migrate. If we do encounter such a legacy database, we will need a - // better solution to handle it (i.e., pop up a dialog to tell the user, - // erase all their prefs and start over, etc.). - LOG(WARNING) << "Web database version " << current_version - << " is too old to handle."; - NOTREACHED(); - return sql::INIT_FAILURE; - } + DCHECK_GT(current_version, kDeprecatedVersionNumber); for (int next_version = current_version + 1; next_version <= kCurrentVersionNumber;
diff --git a/components/webdata/common/web_database.h b/components/webdata/common/web_database.h index 22730fe..c6d0c1d5 100644 --- a/components/webdata/common/web_database.h +++ b/components/webdata/common/web_database.h
@@ -27,6 +27,8 @@ }; // Exposed publicly so the keyword table can access it. static const int kCurrentVersionNumber; + // The newest version of the database Chrome will NOT try to migrate. + static const int kDeprecatedVersionNumber; WebDatabase(); virtual ~WebDatabase();
diff --git a/components/webdata/common/web_database_migration_unittest.cc b/components/webdata/common/web_database_migration_unittest.cc index fbba5cd..765883b 100644 --- a/components/webdata/common/web_database_migration_unittest.cc +++ b/components/webdata/common/web_database_migration_unittest.cc
@@ -38,122 +38,6 @@ namespace { -void AutofillProfile31FromStatement(const sql::Statement& s, - AutofillProfile* profile, - base::string16* label, - int* unique_id, - int64* date_modified) { - DCHECK(profile); - DCHECK(label); - DCHECK(unique_id); - DCHECK(date_modified); - *label = s.ColumnString16(0); - *unique_id = s.ColumnInt(1); - profile->SetRawInfo(autofill::NAME_FIRST, s.ColumnString16(2)); - profile->SetRawInfo(autofill::NAME_MIDDLE, s.ColumnString16(3)); - profile->SetRawInfo(autofill::NAME_LAST, s.ColumnString16(4)); - profile->SetRawInfo(autofill::EMAIL_ADDRESS, s.ColumnString16(5)); - profile->SetRawInfo(autofill::COMPANY_NAME, s.ColumnString16(6)); - profile->SetRawInfo(autofill::ADDRESS_HOME_LINE1, s.ColumnString16(7)); - profile->SetRawInfo(autofill::ADDRESS_HOME_LINE2, s.ColumnString16(8)); - profile->SetRawInfo(autofill::ADDRESS_HOME_CITY, s.ColumnString16(9)); - profile->SetRawInfo(autofill::ADDRESS_HOME_STATE, s.ColumnString16(10)); - profile->SetRawInfo(autofill::ADDRESS_HOME_ZIP, s.ColumnString16(11)); - profile->SetInfo( - autofill::AutofillType(autofill::ADDRESS_HOME_COUNTRY), - s.ColumnString16(12), "en-US"); - profile->SetRawInfo(autofill::PHONE_HOME_WHOLE_NUMBER, s.ColumnString16(13)); - *date_modified = s.ColumnInt64(15); - profile->set_guid(s.ColumnString(16)); - EXPECT_TRUE(base::IsValidGUID(profile->guid())); -} - -void AutofillProfile33FromStatement(const sql::Statement& s, - AutofillProfile* profile, - int64* date_modified) { - DCHECK(profile); - DCHECK(date_modified); - profile->set_guid(s.ColumnString(0)); - EXPECT_TRUE(base::IsValidGUID(profile->guid())); - profile->SetRawInfo(autofill::COMPANY_NAME, s.ColumnString16(1)); - profile->SetRawInfo(autofill::ADDRESS_HOME_STREET_ADDRESS, - s.ColumnString16(2)); - profile->SetRawInfo(autofill::ADDRESS_HOME_CITY, s.ColumnString16(3)); - profile->SetRawInfo(autofill::ADDRESS_HOME_STATE, s.ColumnString16(4)); - profile->SetRawInfo(autofill::ADDRESS_HOME_ZIP, s.ColumnString16(5)); - profile->SetInfo( - autofill::AutofillType(autofill::ADDRESS_HOME_COUNTRY), - s.ColumnString16(6), "en-US"); - *date_modified = s.ColumnInt64(7); -} - -void CreditCard31FromStatement(const sql::Statement& s, - CreditCard* credit_card, - base::string16* label, - int* unique_id, - std::string* encrypted_number, - int64* date_modified) { - DCHECK(credit_card); - DCHECK(label); - DCHECK(unique_id); - DCHECK(encrypted_number); - DCHECK(date_modified); - *label = s.ColumnString16(0); - *unique_id = s.ColumnInt(1); - credit_card->SetRawInfo(autofill::CREDIT_CARD_NAME, s.ColumnString16(2)); - credit_card->SetRawInfo(autofill::CREDIT_CARD_TYPE, s.ColumnString16(3)); - credit_card->SetRawInfo(autofill::CREDIT_CARD_EXP_MONTH, s.ColumnString16(5)); - credit_card->SetRawInfo( - autofill::CREDIT_CARD_EXP_4_DIGIT_YEAR, s.ColumnString16(6)); - int encrypted_number_len = s.ColumnByteLength(10); - if (encrypted_number_len) { - encrypted_number->resize(encrypted_number_len); - memcpy(&(*encrypted_number)[0], s.ColumnBlob(10), encrypted_number_len); - } - *date_modified = s.ColumnInt64(12); - credit_card->set_guid(s.ColumnString(13)); - EXPECT_TRUE(base::IsValidGUID(credit_card->guid())); -} - -void CreditCard32FromStatement(const sql::Statement& s, - CreditCard* credit_card, - std::string* encrypted_number, - int64* date_modified) { - DCHECK(credit_card); - DCHECK(encrypted_number); - DCHECK(date_modified); - credit_card->set_guid(s.ColumnString(0)); - EXPECT_TRUE(base::IsValidGUID(credit_card->guid())); - credit_card->SetRawInfo(autofill::CREDIT_CARD_NAME, s.ColumnString16(1)); - credit_card->SetRawInfo(autofill::CREDIT_CARD_EXP_MONTH, s.ColumnString16(2)); - credit_card->SetRawInfo( - autofill::CREDIT_CARD_EXP_4_DIGIT_YEAR, s.ColumnString16(3)); - int encrypted_number_len = s.ColumnByteLength(4); - if (encrypted_number_len) { - encrypted_number->resize(encrypted_number_len); - memcpy(&(*encrypted_number)[0], s.ColumnBlob(4), encrypted_number_len); - } - *date_modified = s.ColumnInt64(5); -} - -void CheckHasBackupData(sql::MetaTable* meta_table) { - std::string value; - EXPECT_TRUE(meta_table->GetValue( - "Default Search Provider ID Backup", &value)); - EXPECT_TRUE(meta_table->GetValue( - "Default Search Provider ID Backup Signature", &value)); -} - -void CheckNoBackupData(const sql::Connection& connection, - sql::MetaTable* meta_table) { - std::string value; - EXPECT_FALSE(meta_table->GetValue( - "Default Search Provider ID Backup", &value)); - EXPECT_FALSE(meta_table->GetValue( - "Default Search Provider ID Backup Signature", &value)); - EXPECT_FALSE(connection.DoesTableExist("keywords_backup")); -} - std::string RemoveQuotes(const std::string& has_quotes) { std::string no_quotes; // SQLite quotes: http://www.sqlite.org/lang_keywords.html @@ -248,7 +132,7 @@ DISALLOW_COPY_AND_ASSIGN(WebDatabaseMigrationTest); }; -const int WebDatabaseMigrationTest::kCurrentTestedVersionNumber = 62; +const int WebDatabaseMigrationTest::kCurrentTestedVersionNumber = 63; void WebDatabaseMigrationTest::LoadDatabase( const base::FilePath::StringType& file) { @@ -267,15 +151,23 @@ sql::Connection connection; ASSERT_TRUE(connection.Open(GetDatabasePath())); const std::string& expected_schema = RemoveQuotes(connection.GetSchema()); - static const int kFirstVersion = 53; - for (int i = kFirstVersion; i < kCurrentTestedVersionNumber; ++i) { + for (int i = WebDatabase::kDeprecatedVersionNumber + 1; + i < kCurrentTestedVersionNumber; ++i) { + // We don't test version 52 because there's a slight discrepancy in the + // initialization code and the migration code (relating to schema + // formatting). Fixing the bug is possible, but would require updating every + // version_nn.sql file. + if (i == 52) + continue; + connection.Raze(); const base::FilePath& file_name = base::FilePath::FromUTF8Unsafe( "version_" + base::IntToString(i) + ".sql"); ASSERT_NO_FATAL_FAILURE(LoadDatabase(file_name.value())) << "Failed to load " << file_name.MaybeAsASCII(); DoMigration(); - EXPECT_EQ(expected_schema, RemoveQuotes(connection.GetSchema())); + EXPECT_EQ(expected_schema, RemoveQuotes(connection.GetSchema())) + << "For version " << i; } } @@ -314,1851 +206,8 @@ } } -// Tests that absent Autofill tables do not create any problems when migrating -// from a DB written by the earliest publicly released version of Chrome. -TEST_F(WebDatabaseMigrationTest, MigrateVersion20ToCurrent) { - ASSERT_NO_FATAL_FAILURE(LoadDatabase(FILE_PATH_LITERAL("version_20.sql"))); - - // Verify pre-conditions. - { - sql::Connection connection; - ASSERT_TRUE(connection.Open(GetDatabasePath())); - - EXPECT_FALSE(connection.DoesTableExist("autofill")); - EXPECT_FALSE(connection.DoesTableExist("autofill_profiles")); - EXPECT_FALSE(connection.DoesTableExist("credit_cards")); - } - - DoMigration(); - - // Verify post-conditions. These are expectations for current version of the - // database. - { - sql::Connection connection; - ASSERT_TRUE(connection.Open(GetDatabasePath())); - - // Check version. - EXPECT_EQ(kCurrentTestedVersionNumber, VersionFromConnection(&connection)); - - // Mostly this test just verifies that no SQL errors occur during migration; - // but might as well verify that the tables were created as well. - EXPECT_TRUE(connection.DoesTableExist("autofill")); - EXPECT_TRUE(connection.DoesTableExist("autofill_profiles")); - EXPECT_TRUE(connection.DoesTableExist("credit_cards")); - } -} - -// Tests that rows with empty values get removed from the autofill tables. -TEST_F(WebDatabaseMigrationTest, MigrateVersion21ToCurrent) { - ASSERT_NO_FATAL_FAILURE(LoadDatabase(FILE_PATH_LITERAL("version_21.sql"))); - - // Verify pre-conditions. - { - sql::Connection connection; - ASSERT_TRUE(connection.Open(GetDatabasePath())); - - // Both empty and non-empty values are allowed in a version 21 database. - sql::Statement s_autofill(connection.GetUniqueStatement( - "SELECT name, value, value_lower, pair_id, count FROM autofill")); - sql::Statement s_dates(connection.GetUniqueStatement( - "SELECT pair_id, date_created FROM autofill_dates")); - - // An entry with a non-empty value. - ASSERT_TRUE(s_autofill.Step()); - EXPECT_EQ(ASCIIToUTF16("Name"), s_autofill.ColumnString16(0)); - EXPECT_EQ(ASCIIToUTF16("John Doe"), s_autofill.ColumnString16(1)); - EXPECT_EQ(ASCIIToUTF16("john doe"), s_autofill.ColumnString16(2)); - EXPECT_EQ(10, s_autofill.ColumnInt(3)); - EXPECT_EQ(1, s_autofill.ColumnInt(4)); - ASSERT_TRUE(s_dates.Step()); - EXPECT_EQ(10, s_dates.ColumnInt(0)); - EXPECT_EQ(1384299100, s_dates.ColumnInt64(1)); - - // An entry with an empty value. - ASSERT_TRUE(s_autofill.Step()); - EXPECT_EQ(ASCIIToUTF16("Name"), s_autofill.ColumnString16(0)); - EXPECT_EQ(base::string16(), s_autofill.ColumnString16(1)); - EXPECT_EQ(base::string16(), s_autofill.ColumnString16(2)); - EXPECT_EQ(11, s_autofill.ColumnInt(3)); - EXPECT_EQ(1, s_autofill.ColumnInt(4)); - ASSERT_TRUE(s_dates.Step()); - EXPECT_EQ(11, s_dates.ColumnInt(0)); - EXPECT_EQ(1384299200, s_dates.ColumnInt64(1)); - - // Another entry with a non-empty value. - ASSERT_TRUE(s_autofill.Step()); - EXPECT_EQ(ASCIIToUTF16("Email"), s_autofill.ColumnString16(0)); - EXPECT_EQ(ASCIIToUTF16("jane@example.com"), s_autofill.ColumnString16(1)); - EXPECT_EQ(ASCIIToUTF16("jane@example.com"), s_autofill.ColumnString16(2)); - EXPECT_EQ(20, s_autofill.ColumnInt(3)); - EXPECT_EQ(3, s_autofill.ColumnInt(4)); - ASSERT_TRUE(s_dates.Step()); - EXPECT_EQ(20, s_dates.ColumnInt(0)); - EXPECT_EQ(1384299300, s_dates.ColumnInt64(1)); - ASSERT_TRUE(s_dates.Step()); - EXPECT_EQ(20, s_dates.ColumnInt(0)); - EXPECT_EQ(1384299301, s_dates.ColumnInt64(1)); - - // Another entry with an empty value. - ASSERT_TRUE(s_autofill.Step()); - EXPECT_EQ(ASCIIToUTF16("Email"), s_autofill.ColumnString16(0)); - EXPECT_EQ(base::string16(), s_autofill.ColumnString16(1)); - EXPECT_EQ(base::string16(), s_autofill.ColumnString16(2)); - EXPECT_EQ(21, s_autofill.ColumnInt(3)); - EXPECT_EQ(4, s_autofill.ColumnInt(4)); - ASSERT_TRUE(s_dates.Step()); - EXPECT_EQ(21, s_dates.ColumnInt(0)); - EXPECT_EQ(1384299401, s_dates.ColumnInt64(1)); - ASSERT_TRUE(s_dates.Step()); - EXPECT_EQ(21, s_dates.ColumnInt(0)); - EXPECT_EQ(1384299400, s_dates.ColumnInt64(1)); - ASSERT_TRUE(s_dates.Step()); - EXPECT_EQ(21, s_dates.ColumnInt(0)); - EXPECT_EQ(1384299403, s_dates.ColumnInt64(1)); - ASSERT_TRUE(s_dates.Step()); - EXPECT_EQ(21, s_dates.ColumnInt(0)); - EXPECT_EQ(1384299402, s_dates.ColumnInt64(1)); - - // No more entries expected. - ASSERT_FALSE(s_autofill.Step()); - ASSERT_FALSE(s_dates.Step()); - } - - DoMigration(); - - // Verify post-conditions. These are expectations for current version of the - // database. - { - sql::Connection connection; - ASSERT_TRUE(connection.Open(GetDatabasePath())); - - // Check version. - EXPECT_EQ(kCurrentTestedVersionNumber, VersionFromConnection(&connection)); - - // Entries with empty values should have been dropped. The remaining - // entries should have been preserved. - sql::Statement s( - connection.GetUniqueStatement( - "SELECT name, value, value_lower, date_created, date_last_used," - " count " - "FROM autofill " - "ORDER BY name, value ASC")); - - // "jane@example.com" - ASSERT_TRUE(s.Step()); - EXPECT_EQ(ASCIIToUTF16("Email"), s.ColumnString16(0)); - EXPECT_EQ(ASCIIToUTF16("jane@example.com"), s.ColumnString16(1)); - EXPECT_EQ(ASCIIToUTF16("jane@example.com"), s.ColumnString16(2)); - EXPECT_EQ(1384299300, s.ColumnInt64(3)); - EXPECT_EQ(1384299301, s.ColumnInt64(4)); - EXPECT_EQ(3, s.ColumnInt(5)); - - // "John Doe" - ASSERT_TRUE(s.Step()); - EXPECT_EQ(ASCIIToUTF16("Name"), s.ColumnString16(0)); - EXPECT_EQ(ASCIIToUTF16("John Doe"), s.ColumnString16(1)); - EXPECT_EQ(ASCIIToUTF16("john doe"), s.ColumnString16(2)); - EXPECT_EQ(1384299100, s.ColumnInt64(3)); - EXPECT_EQ(1384299100, s.ColumnInt64(4)); - EXPECT_EQ(1, s.ColumnInt(5)); - - // No more entries expected. - ASSERT_FALSE(s.Step()); - } -} - -// Tests that the |credit_card| table gets added to the schema for a version 22 -// database. -TEST_F(WebDatabaseMigrationTest, MigrateVersion22ToCurrent) { - // This schema is taken from a build prior to the addition of the - // |credit_card| table. Version 22 of the schema. Contrast this with the - // corrupt version below. - ASSERT_NO_FATAL_FAILURE(LoadDatabase(FILE_PATH_LITERAL("version_22.sql"))); - - // Verify pre-conditions. - { - sql::Connection connection; - ASSERT_TRUE(connection.Open(GetDatabasePath())); - - // No |credit_card| table prior to version 23. - ASSERT_FALSE(connection.DoesColumnExist("credit_cards", "guid")); - ASSERT_FALSE( - connection.DoesColumnExist("credit_cards", "card_number_encrypted")); - } - - DoMigration(); - - // Verify post-conditions. These are expectations for current version of the - // database. - { - sql::Connection connection; - ASSERT_TRUE(connection.Open(GetDatabasePath())); - - // Check version. - EXPECT_EQ(kCurrentTestedVersionNumber, VersionFromConnection(&connection)); - - // |credit_card| table now exists. - EXPECT_TRUE(connection.DoesColumnExist("credit_cards", "guid")); - EXPECT_TRUE( - connection.DoesColumnExist("credit_cards", "card_number_encrypted")); - } -} - -// Tests that the |credit_card| table gets added to the schema for a corrupt -// version 22 database. The corruption is that the |credit_cards| table exists -// but the schema version number was not set correctly to 23 or later. This -// test exercises code introduced to fix bug http://crbug.com/50699 that -// resulted from the corruption. -TEST_F(WebDatabaseMigrationTest, MigrateVersion22CorruptedToCurrent) { - // This schema is taken from a build after the addition of the |credit_card| - // table. Due to a bug in the migration logic the version is set incorrectly - // to 22 (it should have been updated to 23 at least). - ASSERT_NO_FATAL_FAILURE( - LoadDatabase(FILE_PATH_LITERAL("version_22_corrupt.sql"))); - - // Verify pre-conditions. These are expectations for corrupt version 22 of - // the database. - { - sql::Connection connection; - ASSERT_TRUE(connection.Open(GetDatabasePath())); - - // Columns existing and not existing before current version. - ASSERT_TRUE(connection.DoesColumnExist("credit_cards", "unique_id")); - ASSERT_TRUE( - connection.DoesColumnExist("credit_cards", "card_number_encrypted")); - ASSERT_TRUE(connection.DoesColumnExist("keywords", "id")); - } - - DoMigration(); - - // Verify post-conditions. These are expectations for current version of the - // database. - { - sql::Connection connection; - ASSERT_TRUE(connection.Open(GetDatabasePath())); - - // Check version. - EXPECT_EQ(kCurrentTestedVersionNumber, VersionFromConnection(&connection)); - - - // Columns existing and not existing before version 25. - EXPECT_FALSE(connection.DoesColumnExist("credit_cards", "unique_id")); - EXPECT_TRUE(connection.DoesColumnExist("credit_cards", "guid")); - EXPECT_TRUE( - connection.DoesColumnExist("credit_cards", "card_number_encrypted")); - EXPECT_TRUE(connection.DoesColumnExist("keywords", "id")); - } -} - -// Tests that the |keywords| |created_by_policy| column gets added to the schema -// for a version 25 database. -TEST_F(WebDatabaseMigrationTest, MigrateVersion25ToCurrent) { - // This schema is taken from a build prior to the addition of the |keywords| - // |created_by_policy| column. - ASSERT_NO_FATAL_FAILURE(LoadDatabase(FILE_PATH_LITERAL("version_25.sql"))); - - // Verify pre-conditions. These are expectations for version 25 of the - // database. - { - sql::Connection connection; - ASSERT_TRUE(connection.Open(GetDatabasePath())); - } - - DoMigration(); - - // Verify post-conditions. These are expectations for current version of the - // database. - { - sql::Connection connection; - ASSERT_TRUE(connection.Open(GetDatabasePath())); - - // Check version. - EXPECT_EQ(kCurrentTestedVersionNumber, VersionFromConnection(&connection)); - - // |keywords| |created_by_policy| column should have been added. - EXPECT_TRUE(connection.DoesColumnExist("keywords", "id")); - EXPECT_TRUE(connection.DoesColumnExist("keywords", "created_by_policy")); - } -} - -// Tests that the credit_cards.billing_address column is changed from a string -// to an int whilst preserving the associated billing address. This version of -// the test makes sure a stored label is converted to an ID. -TEST_F(WebDatabaseMigrationTest, MigrateVersion26ToCurrentStringLabels) { - // This schema is taken from a build prior to the change of column type for - // credit_cards.billing_address from string to int. - ASSERT_NO_FATAL_FAILURE(LoadDatabase(FILE_PATH_LITERAL("version_26.sql"))); - - // Verify pre-conditions. These are expectations for version 26 of the - // database. - { - sql::Connection connection; - ASSERT_TRUE(connection.Open(GetDatabasePath())); - - // Columns existing and not existing before current version. - EXPECT_TRUE(connection.DoesColumnExist("credit_cards", "billing_address")); - - std::string stmt = "INSERT INTO autofill_profiles" - "(label, unique_id, first_name, middle_name, last_name, email," - " company_name, address_line_1, address_line_2, city, state, zipcode," - " country, phone, fax)" - "VALUES ('Home',1,'','','','','','','','','','','','','')"; - sql::Statement s(connection.GetUniqueStatement(stmt.c_str())); - ASSERT_TRUE(s.Run()); - - // Insert a CC linked to an existing address. - std::string stmt2 = "INSERT INTO credit_cards" - "(label, unique_id, name_on_card, type, card_number," - " expiration_month, expiration_year, verification_code, billing_address," - " shipping_address, card_number_encrypted, verification_code_encrypted)" - "VALUES ('label',2,'Jack','Visa','1234',2,2012,'','Home','','','')"; - sql::Statement s2(connection.GetUniqueStatement(stmt2.c_str())); - ASSERT_TRUE(s2.Run()); - - // |billing_address| is a string. - std::string stmt3 = "SELECT billing_address FROM credit_cards"; - sql::Statement s3(connection.GetUniqueStatement(stmt3.c_str())); - ASSERT_TRUE(s3.Step()); - EXPECT_EQ(s3.ColumnType(0), sql::COLUMN_TYPE_TEXT); - } - - DoMigration(); - - // Verify post-conditions. These are expectations for current version of the - // database. - { - sql::Connection connection; - ASSERT_TRUE(connection.Open(GetDatabasePath())); - - // Check version. - EXPECT_EQ(kCurrentTestedVersionNumber, VersionFromConnection(&connection)); - EXPECT_FALSE(connection.DoesColumnExist("credit_cards", "billing_address")); - - // Verify the credit card data is converted. - sql::Statement s(connection.GetUniqueStatement( - "SELECT guid, name_on_card, expiration_month, expiration_year, " - "card_number_encrypted, date_modified " - "FROM credit_cards")); - ASSERT_TRUE(s.Step()); - EXPECT_EQ("Jack", s.ColumnString(1)); - EXPECT_EQ(2, s.ColumnInt(2)); - EXPECT_EQ(2012, s.ColumnInt(3)); - // Column 5 is encrypted number blob. - // Column 6 is date_modified. - } -} - -// Tests that the credit_cards.billing_address column is changed from a string -// to an int whilst preserving the associated billing address. This version of -// the test makes sure a stored string ID is converted to an integer ID. -TEST_F(WebDatabaseMigrationTest, MigrateVersion26ToCurrentStringIDs) { - // This schema is taken from a build prior to the change of column type for - // credit_cards.billing_address from string to int. - ASSERT_NO_FATAL_FAILURE(LoadDatabase(FILE_PATH_LITERAL("version_26.sql"))); - - // Verify pre-conditions. These are expectations for version 26 of the - // database. - { - sql::Connection connection; - ASSERT_TRUE(connection.Open(GetDatabasePath())); - EXPECT_TRUE(connection.DoesColumnExist("credit_cards", "billing_address")); - - std::string stmt = "INSERT INTO autofill_profiles" - "(label, unique_id, first_name, middle_name, last_name, email," - " company_name, address_line_1, address_line_2, city, state, zipcode," - " country, phone, fax)" - "VALUES ('Home',1,'','','','','','','','','','','','','')"; - sql::Statement s(connection.GetUniqueStatement(stmt.c_str())); - ASSERT_TRUE(s.Run()); - - // Insert a CC linked to an existing address. - std::string stmt2 = "INSERT INTO credit_cards" - "(label, unique_id, name_on_card, type, card_number," - " expiration_month, expiration_year, verification_code, billing_address," - " shipping_address, card_number_encrypted, verification_code_encrypted)" - "VALUES ('label',2,'Jack','Visa','1234',2,2012,'','1','','','')"; - sql::Statement s2(connection.GetUniqueStatement(stmt2.c_str())); - ASSERT_TRUE(s2.Run()); - - // |billing_address| is a string. - std::string stmt3 = "SELECT billing_address FROM credit_cards"; - sql::Statement s3(connection.GetUniqueStatement(stmt3.c_str())); - ASSERT_TRUE(s3.Step()); - EXPECT_EQ(s3.ColumnType(0), sql::COLUMN_TYPE_TEXT); - } - - DoMigration(); - - // Verify post-conditions. These are expectations for current version of the - // database. - { - sql::Connection connection; - ASSERT_TRUE(connection.Open(GetDatabasePath())); - - // Check version. - EXPECT_EQ(kCurrentTestedVersionNumber, VersionFromConnection(&connection)); - - // |keywords| |created_by_policy| column should have been added. - EXPECT_TRUE(connection.DoesColumnExist("keywords", "id")); - EXPECT_TRUE(connection.DoesColumnExist("keywords", "created_by_policy")); - EXPECT_FALSE(connection.DoesColumnExist("credit_cards", "billing_address")); - - // Verify the credit card data is converted. - sql::Statement s(connection.GetUniqueStatement( - "SELECT guid, name_on_card, expiration_month, expiration_year, " - "card_number_encrypted, date_modified " - "FROM credit_cards")); - ASSERT_TRUE(s.Step()); - EXPECT_EQ("Jack", s.ColumnString(1)); - EXPECT_EQ(2, s.ColumnInt(2)); - EXPECT_EQ(2012, s.ColumnInt(3)); - // Column 5 is encrypted credit card number blo b. - // Column 6 is date_modified. - } -} - -// Makes sure instant_url is added correctly to keywords. -TEST_F(WebDatabaseMigrationTest, MigrateVersion27ToCurrent) { - // Initialize the database. - ASSERT_NO_FATAL_FAILURE(LoadDatabase(FILE_PATH_LITERAL("version_27.sql"))); - - // Verify pre-conditions. These are expectations for version 27 of the - // database. - { - sql::Connection connection; - ASSERT_TRUE(connection.Open(GetDatabasePath())); - - ASSERT_FALSE(connection.DoesColumnExist("keywords", "instant_url")); - } - - DoMigration(); - - // Verify post-conditions. These are expectations for current version of the - // database. - { - sql::Connection connection; - ASSERT_TRUE(connection.Open(GetDatabasePath())); - - // Check version. - EXPECT_EQ(kCurrentTestedVersionNumber, VersionFromConnection(&connection)); - - // Make sure supports_instant (added in Version 28) was ultimately dropped - // again and instant_url was added. - EXPECT_FALSE(connection.DoesColumnExist("keywords", "supports_instant")); - EXPECT_TRUE(connection.DoesColumnExist("keywords", "instant_url")); - - // Check that instant_url is empty. - std::string stmt = "SELECT instant_url FROM keywords"; - sql::Statement s(connection.GetUniqueStatement(stmt.c_str())); - ASSERT_TRUE(s.Step()); - EXPECT_EQ(std::string(), s.ColumnString(0)); - - // Verify the data made it over. - stmt = "SELECT " + KeywordTable::GetKeywordColumns() + " FROM keywords"; - sql::Statement s2(connection.GetUniqueStatement(stmt.c_str())); - ASSERT_TRUE(s2.Step()); - EXPECT_EQ(2, s2.ColumnInt(0)); - EXPECT_EQ("Google", s2.ColumnString(1)); - EXPECT_EQ("google.com", s2.ColumnString(2)); - EXPECT_EQ("http://www.google.com/favicon.ico", s2.ColumnString(3)); - EXPECT_EQ("{google:baseURL}search?{google:RLZ}{google:acceptedSuggestion}"\ - "{google:originalQueryForSuggestion}sourceid=chrome&ie={inputEncoding}"\ - "&q={searchTerms}", - s2.ColumnString(4)); - EXPECT_TRUE(s2.ColumnBool(5)); - EXPECT_EQ(std::string(), s2.ColumnString(6)); - EXPECT_EQ(0, s2.ColumnInt(7)); - EXPECT_EQ(0, s2.ColumnInt(8)); - EXPECT_EQ(std::string("UTF-8"), s2.ColumnString(9)); - EXPECT_TRUE(s2.ColumnBool(10)); - EXPECT_EQ(std::string("{google:baseSuggestURL}search?client=chrome&hl=" - "{language}&q={searchTerms}"), s2.ColumnString(11)); - EXPECT_EQ(1, s2.ColumnInt(12)); - EXPECT_FALSE(s2.ColumnBool(13)); - EXPECT_EQ(std::string(), s2.ColumnString(14)); - EXPECT_EQ(0, s2.ColumnInt(15)); - EXPECT_EQ(std::string(), s2.ColumnString(16)); - } -} - -// Makes sure date_modified is added correctly to autofill_profiles and -// credit_cards. -TEST_F(WebDatabaseMigrationTest, MigrateVersion29ToCurrent) { - // Initialize the database. - ASSERT_NO_FATAL_FAILURE(LoadDatabase(FILE_PATH_LITERAL("version_29.sql"))); - - // Verify pre-conditions. These are expectations for version 29 of the - // database. - { - sql::Connection connection; - ASSERT_TRUE(connection.Open(GetDatabasePath())); - - EXPECT_FALSE(connection.DoesColumnExist("autofill_profiles", - "date_modified")); - EXPECT_FALSE(connection.DoesColumnExist("credit_cards", - "date_modified")); - } - - Time pre_creation_time = Time::Now(); - DoMigration(); - Time post_creation_time = Time::Now(); - - // Verify post-conditions. These are expectations for current version of the - // database. - { - sql::Connection connection; - ASSERT_TRUE(connection.Open(GetDatabasePath())); - - // Check version. - EXPECT_EQ(kCurrentTestedVersionNumber, VersionFromConnection(&connection)); - - // Check that the columns were created. - EXPECT_TRUE(connection.DoesColumnExist("autofill_profiles", - "date_modified")); - EXPECT_TRUE(connection.DoesColumnExist("credit_cards", - "date_modified")); - - sql::Statement s_profiles(connection.GetUniqueStatement( - "SELECT date_modified FROM autofill_profiles ")); - ASSERT_TRUE(s_profiles.is_valid()); - while (s_profiles.Step()) { - EXPECT_GE(s_profiles.ColumnInt64(0), - pre_creation_time.ToTimeT()); - EXPECT_LE(s_profiles.ColumnInt64(0), - post_creation_time.ToTimeT()); - } - EXPECT_TRUE(s_profiles.Succeeded()); - - sql::Statement s_credit_cards(connection.GetUniqueStatement( - "SELECT date_modified FROM credit_cards ")); - ASSERT_TRUE(s_credit_cards.is_valid()); - while (s_credit_cards.Step()) { - EXPECT_GE(s_credit_cards.ColumnInt64(0), - pre_creation_time.ToTimeT()); - EXPECT_LE(s_credit_cards.ColumnInt64(0), - post_creation_time.ToTimeT()); - } - EXPECT_TRUE(s_credit_cards.Succeeded()); - } -} - -// Makes sure guids are added to autofill_profiles and credit_cards tables. -TEST_F(WebDatabaseMigrationTest, MigrateVersion30ToCurrent) { - // Initialize the database. - ASSERT_NO_FATAL_FAILURE(LoadDatabase(FILE_PATH_LITERAL("version_30.sql"))); - - // Verify pre-conditions. These are expectations for version 29 of the - // database. - { - sql::Connection connection; - ASSERT_TRUE(connection.Open(GetDatabasePath())); - - EXPECT_FALSE(connection.DoesColumnExist("autofill_profiles", "guid")); - EXPECT_FALSE(connection.DoesColumnExist("credit_cards", "guid")); - } - - DoMigration(); - - // Verify post-conditions. These are expectations for current version of the - // database. - { - sql::Connection connection; - ASSERT_TRUE(connection.Open(GetDatabasePath())); - - // Check version. - EXPECT_EQ(kCurrentTestedVersionNumber, VersionFromConnection(&connection)); - - ASSERT_TRUE(connection.DoesColumnExist("autofill_profiles", "guid")); - ASSERT_TRUE(connection.DoesColumnExist("credit_cards", "guid")); - - // Check that guids are non-null, non-empty, conforms to guid format, and - // are different. - sql::Statement s( - connection.GetUniqueStatement("SELECT guid FROM autofill_profiles")); - - ASSERT_TRUE(s.Step()); - std::string guid1 = s.ColumnString(0); - EXPECT_TRUE(base::IsValidGUID(guid1)); - - ASSERT_TRUE(s.Step()); - std::string guid2 = s.ColumnString(0); - EXPECT_TRUE(base::IsValidGUID(guid2)); - - EXPECT_NE(guid1, guid2); - } -} - -// Removes unique IDs and make GUIDs the primary key. Also removes unused -// columns. -TEST_F(WebDatabaseMigrationTest, MigrateVersion31ToCurrent) { - // Initialize the database. - ASSERT_NO_FATAL_FAILURE(LoadDatabase(FILE_PATH_LITERAL("version_31.sql"))); - - // Verify pre-conditions. These are expectations for version 30 of the - // database. - AutofillProfile profile; - base::string16 profile_label; - int profile_unique_id = 0; - int64 profile_date_modified = 0; - CreditCard credit_card; - base::string16 cc_label; - int cc_unique_id = 0; - std::string cc_number_encrypted; - int64 cc_date_modified = 0; - { - sql::Connection connection; - ASSERT_TRUE(connection.Open(GetDatabasePath())); - - // Verify existence of columns we'll be changing. - EXPECT_TRUE(connection.DoesColumnExist("autofill_profiles", "guid")); - EXPECT_TRUE(connection.DoesColumnExist("autofill_profiles", "unique_id")); - EXPECT_TRUE(connection.DoesColumnExist("credit_cards", "guid")); - EXPECT_TRUE(connection.DoesColumnExist("credit_cards", "unique_id")); - EXPECT_TRUE(connection.DoesColumnExist("credit_cards", "type")); - EXPECT_TRUE(connection.DoesColumnExist("credit_cards", "card_number")); - EXPECT_TRUE(connection.DoesColumnExist("credit_cards", - "verification_code")); - EXPECT_TRUE(connection.DoesColumnExist("credit_cards", "billing_address")); - EXPECT_TRUE(connection.DoesColumnExist("credit_cards", "shipping_address")); - EXPECT_TRUE(connection.DoesColumnExist("credit_cards", - "verification_code_encrypted")); - - // Fetch data in the database prior to migration. - sql::Statement s1( - connection.GetUniqueStatement( - "SELECT label, unique_id, first_name, middle_name, last_name, " - "email, company_name, address_line_1, address_line_2, city, state, " - "zipcode, country, phone, fax, date_modified, guid " - "FROM autofill_profiles")); - ASSERT_TRUE(s1.Step()); - EXPECT_NO_FATAL_FAILURE(AutofillProfile31FromStatement( - s1, &profile, &profile_label, &profile_unique_id, - &profile_date_modified)); - - sql::Statement s2( - connection.GetUniqueStatement( - "SELECT label, unique_id, name_on_card, type, card_number, " - "expiration_month, expiration_year, verification_code, " - "billing_address, shipping_address, card_number_encrypted, " - "verification_code_encrypted, date_modified, guid " - "FROM credit_cards")); - ASSERT_TRUE(s2.Step()); - EXPECT_NO_FATAL_FAILURE(CreditCard31FromStatement(s2, - &credit_card, - &cc_label, - &cc_unique_id, - &cc_number_encrypted, - &cc_date_modified)); - - EXPECT_NE(profile_unique_id, cc_unique_id); - EXPECT_NE(profile.guid(), credit_card.guid()); - } - - DoMigration(); - - // Verify post-conditions. These are expectations for current version of the - // database. - { - sql::Connection connection; - ASSERT_TRUE(connection.Open(GetDatabasePath())); - - // Check version. - EXPECT_EQ(kCurrentTestedVersionNumber, VersionFromConnection(&connection)); - - // Verify existence of columns we'll be changing. - EXPECT_TRUE(connection.DoesColumnExist("autofill_profiles", "guid")); - EXPECT_FALSE(connection.DoesColumnExist("autofill_profiles", "unique_id")); - EXPECT_TRUE(connection.DoesColumnExist("credit_cards", "guid")); - EXPECT_FALSE(connection.DoesColumnExist("credit_cards", "unique_id")); - EXPECT_FALSE(connection.DoesColumnExist("credit_cards", "type")); - EXPECT_FALSE(connection.DoesColumnExist("credit_cards", "card_number")); - EXPECT_FALSE(connection.DoesColumnExist("credit_cards", - "verification_code")); - EXPECT_FALSE(connection.DoesColumnExist("credit_cards", "billing_address")); - EXPECT_FALSE(connection.DoesColumnExist("credit_cards", - "shipping_address")); - EXPECT_FALSE(connection.DoesColumnExist("credit_cards", - "verification_code_encrypted")); - - // Verify data in the database after the migration. - sql::Statement s1( - connection.GetUniqueStatement( - "SELECT guid, company_name, street_address, city, state, zipcode," - " country_code, date_modified " - "FROM autofill_profiles")); - ASSERT_TRUE(s1.Step()); - - AutofillProfile profile_a; - int64 profile_date_modified_a = 0; - EXPECT_NO_FATAL_FAILURE(AutofillProfile33FromStatement( - s1, &profile_a, &profile_date_modified_a)); - EXPECT_EQ(profile.guid(), profile_a.guid()); - EXPECT_EQ(profile.GetRawInfo(autofill::COMPANY_NAME), - profile_a.GetRawInfo(autofill::COMPANY_NAME)); - EXPECT_EQ(profile.GetRawInfo(autofill::ADDRESS_HOME_LINE1), - profile_a.GetRawInfo(autofill::ADDRESS_HOME_LINE1)); - EXPECT_EQ(profile.GetRawInfo(autofill::ADDRESS_HOME_LINE2), - profile_a.GetRawInfo(autofill::ADDRESS_HOME_LINE2)); - EXPECT_EQ(profile.GetRawInfo(autofill::ADDRESS_HOME_CITY), - profile_a.GetRawInfo(autofill::ADDRESS_HOME_CITY)); - EXPECT_EQ(profile.GetRawInfo(autofill::ADDRESS_HOME_STATE), - profile_a.GetRawInfo(autofill::ADDRESS_HOME_STATE)); - EXPECT_EQ(profile.GetRawInfo(autofill::ADDRESS_HOME_ZIP), - profile_a.GetRawInfo(autofill::ADDRESS_HOME_ZIP)); - EXPECT_EQ(profile.GetRawInfo(autofill::ADDRESS_HOME_COUNTRY), - profile_a.GetRawInfo(autofill::ADDRESS_HOME_COUNTRY)); - EXPECT_EQ(profile_date_modified, profile_date_modified_a); - - sql::Statement s2( - connection.GetUniqueStatement( - "SELECT guid, name_on_card, expiration_month, " - "expiration_year, card_number_encrypted, date_modified " - "FROM credit_cards")); - ASSERT_TRUE(s2.Step()); - - CreditCard credit_card_a; - base::string16 cc_label_a; - std::string cc_number_encrypted_a; - int64 cc_date_modified_a = 0; - EXPECT_NO_FATAL_FAILURE(CreditCard32FromStatement(s2, - &credit_card_a, - &cc_number_encrypted_a, - &cc_date_modified_a)); - EXPECT_EQ(credit_card, credit_card_a); - EXPECT_EQ(cc_label, cc_label_a); - EXPECT_EQ(cc_number_encrypted, cc_number_encrypted_a); - EXPECT_EQ(cc_date_modified, cc_date_modified_a); - } -} - -// Factor |autofill_profiles| address information separately from name, email, -// and phone. -TEST_F(WebDatabaseMigrationTest, MigrateVersion32ToCurrent) { - // Initialize the database. - ASSERT_NO_FATAL_FAILURE(LoadDatabase(FILE_PATH_LITERAL("version_32.sql"))); - - // Verify pre-conditions. These are expectations for version 32 of the - // database. - { - sql::Connection connection; - ASSERT_TRUE(connection.Open(GetDatabasePath())); - - // Verify existence of columns we'll be changing. - EXPECT_TRUE(connection.DoesColumnExist("autofill_profiles", "guid")); - EXPECT_TRUE(connection.DoesColumnExist("autofill_profiles", "label")); - EXPECT_TRUE(connection.DoesColumnExist("autofill_profiles", "first_name")); - EXPECT_TRUE(connection.DoesColumnExist("autofill_profiles", "middle_name")); - EXPECT_TRUE(connection.DoesColumnExist("autofill_profiles", "last_name")); - EXPECT_TRUE(connection.DoesColumnExist("autofill_profiles", "email")); - EXPECT_TRUE(connection.DoesColumnExist("autofill_profiles", - "company_name")); - EXPECT_TRUE(connection.DoesColumnExist("autofill_profiles", - "address_line_1")); - EXPECT_TRUE(connection.DoesColumnExist("autofill_profiles", - "address_line_2")); - EXPECT_TRUE(connection.DoesColumnExist("autofill_profiles", "city")); - EXPECT_TRUE(connection.DoesColumnExist("autofill_profiles", "state")); - EXPECT_TRUE(connection.DoesColumnExist("autofill_profiles", "zipcode")); - EXPECT_TRUE(connection.DoesColumnExist("autofill_profiles", "country")); - EXPECT_TRUE(connection.DoesColumnExist("autofill_profiles", "phone")); - EXPECT_TRUE(connection.DoesColumnExist("autofill_profiles", "fax")); - EXPECT_TRUE(connection.DoesColumnExist("autofill_profiles", - "date_modified")); - - EXPECT_FALSE(connection.DoesTableExist("autofill_profile_names")); - EXPECT_FALSE(connection.DoesTableExist("autofill_profile_emails")); - EXPECT_FALSE(connection.DoesTableExist("autofill_profile_phones")); - - EXPECT_TRUE(connection.DoesColumnExist("credit_cards", "label")); - } - - DoMigration(); - - // Verify post-conditions. These are expectations for current version of the - // database. - { - sql::Connection connection; - ASSERT_TRUE(connection.Open(GetDatabasePath())); - - // Check version. - EXPECT_EQ(kCurrentTestedVersionNumber, VersionFromConnection(&connection)); - - // Verify changes to columns. - EXPECT_TRUE(connection.DoesColumnExist("autofill_profiles", "guid")); - EXPECT_FALSE(connection.DoesColumnExist("autofill_profiles", "label")); - EXPECT_FALSE(connection.DoesColumnExist("autofill_profiles", "first_name")); - EXPECT_FALSE(connection.DoesColumnExist("autofill_profiles", - "middle_name")); - EXPECT_FALSE(connection.DoesColumnExist("autofill_profiles", "last_name")); - EXPECT_FALSE(connection.DoesColumnExist("autofill_profiles", "email")); - EXPECT_TRUE(connection.DoesColumnExist("autofill_profiles", - "company_name")); - EXPECT_TRUE(connection.DoesColumnExist("autofill_profiles", - "street_address")); - EXPECT_TRUE(connection.DoesColumnExist("autofill_profiles", "city")); - EXPECT_TRUE(connection.DoesColumnExist("autofill_profiles", "state")); - EXPECT_TRUE(connection.DoesColumnExist("autofill_profiles", "zipcode")); - EXPECT_TRUE(connection.DoesColumnExist("autofill_profiles", - "country_code")); - EXPECT_FALSE(connection.DoesColumnExist("autofill_profiles", "phone")); - EXPECT_FALSE(connection.DoesColumnExist("autofill_profiles", "fax")); - EXPECT_TRUE(connection.DoesColumnExist("autofill_profiles", - "date_modified")); - - // New "names" table. - EXPECT_TRUE(connection.DoesColumnExist("autofill_profile_names", "guid")); - EXPECT_TRUE(connection.DoesColumnExist("autofill_profile_names", - "first_name")); - EXPECT_TRUE(connection.DoesColumnExist("autofill_profile_names", - "middle_name")); - EXPECT_TRUE(connection.DoesColumnExist("autofill_profile_names", - "last_name")); - - // New "emails" table. - EXPECT_TRUE(connection.DoesColumnExist("autofill_profile_emails", "guid")); - EXPECT_TRUE(connection.DoesColumnExist("autofill_profile_emails", "email")); - - // New "phones" table. - EXPECT_TRUE(connection.DoesColumnExist("autofill_profile_phones", "guid")); - EXPECT_TRUE(connection.DoesColumnExist("autofill_profile_phones", - "number")); - - EXPECT_FALSE(connection.DoesColumnExist("credit_cards", "label")); - - // Verify data in the database after the migration. - sql::Statement s1( - connection.GetUniqueStatement( - "SELECT guid, company_name, street_address, city, state, zipcode, " - " country_code, date_modified " - "FROM autofill_profiles")); - - // John Doe. - ASSERT_TRUE(s1.Step()); - EXPECT_EQ("00580526-FF81-EE2A-0546-1AC593A32E2F", s1.ColumnString(0)); - EXPECT_EQ(ASCIIToUTF16("Doe Enterprises"), s1.ColumnString16(1)); - EXPECT_EQ(ASCIIToUTF16("1 Main St\n" - "Apt 1"), - s1.ColumnString16(2)); - EXPECT_EQ(ASCIIToUTF16("Los Altos"), s1.ColumnString16(3)); - EXPECT_EQ(ASCIIToUTF16("CA"), s1.ColumnString16(4)); - EXPECT_EQ(ASCIIToUTF16("94022"), s1.ColumnString16(5)); - EXPECT_EQ(ASCIIToUTF16("US"), s1.ColumnString16(6)); - EXPECT_EQ(1297882100L, s1.ColumnInt64(7)); - - // John P. Doe. - // Gets merged during migration from 35 to 37 due to multi-valued fields. - - // Dave Smith. - ASSERT_TRUE(s1.Step()); - EXPECT_EQ("4C74A9D8-7EEE-423E-F9C2-E7FA70ED1396", s1.ColumnString(0)); - EXPECT_EQ(base::string16(), s1.ColumnString16(1)); - EXPECT_EQ(ASCIIToUTF16("2 Main Street"), s1.ColumnString16(2)); - EXPECT_EQ(ASCIIToUTF16("Los Altos"), s1.ColumnString16(3)); - EXPECT_EQ(ASCIIToUTF16("CA"), s1.ColumnString16(4)); - EXPECT_EQ(ASCIIToUTF16("94022"), s1.ColumnString16(5)); - EXPECT_EQ(ASCIIToUTF16("US"), s1.ColumnString16(6)); - EXPECT_EQ(1297882100L, s1.ColumnInt64(7)); - - // Dave Smith (Part 2). - ASSERT_TRUE(s1.Step()); - EXPECT_EQ("722DF5C4-F74A-294A-46F0-31FFDED0D635", s1.ColumnString(0)); - EXPECT_EQ(base::string16(), s1.ColumnString16(1)); - EXPECT_EQ(ASCIIToUTF16("2 Main St"), s1.ColumnString16(2)); - EXPECT_EQ(ASCIIToUTF16("Los Altos"), s1.ColumnString16(3)); - EXPECT_EQ(ASCIIToUTF16("CA"), s1.ColumnString16(4)); - EXPECT_EQ(ASCIIToUTF16("94022"), s1.ColumnString16(5)); - EXPECT_EQ(ASCIIToUTF16("US"), s1.ColumnString16(6)); - EXPECT_EQ(1297882100L, s1.ColumnInt64(7)); - - // Alfred E Newman. - // Gets culled during migration from 35 to 36 due to incomplete address. - - // 3 Main St. - ASSERT_TRUE(s1.Step()); - EXPECT_EQ("9E5FE298-62C7-83DF-6293-381BC589183F", s1.ColumnString(0)); - EXPECT_EQ(base::string16(), s1.ColumnString16(1)); - EXPECT_EQ(ASCIIToUTF16("3 Main St"), s1.ColumnString16(2)); - EXPECT_EQ(ASCIIToUTF16("Los Altos"), s1.ColumnString16(3)); - EXPECT_EQ(ASCIIToUTF16("CA"), s1.ColumnString16(4)); - EXPECT_EQ(ASCIIToUTF16("94022"), s1.ColumnString16(5)); - EXPECT_EQ(ASCIIToUTF16("US"), s1.ColumnString16(6)); - EXPECT_EQ(1297882100L, s1.ColumnInt64(7)); - - // That should be all. - EXPECT_FALSE(s1.Step()); - - sql::Statement s2( - connection.GetUniqueStatement( - "SELECT guid, first_name, middle_name, last_name " - "FROM autofill_profile_names")); - - // John Doe. - ASSERT_TRUE(s2.Step()); - EXPECT_EQ("00580526-FF81-EE2A-0546-1AC593A32E2F", s2.ColumnString(0)); - EXPECT_EQ(ASCIIToUTF16("John"), s2.ColumnString16(1)); - EXPECT_EQ(base::string16(), s2.ColumnString16(2)); - EXPECT_EQ(ASCIIToUTF16("Doe"), s2.ColumnString16(3)); - - // John P. Doe. Note same guid as above due to merging of multi-valued - // fields. - ASSERT_TRUE(s2.Step()); - EXPECT_EQ("00580526-FF81-EE2A-0546-1AC593A32E2F", s2.ColumnString(0)); - EXPECT_EQ(ASCIIToUTF16("John"), s2.ColumnString16(1)); - EXPECT_EQ(ASCIIToUTF16("P."), s2.ColumnString16(2)); - EXPECT_EQ(ASCIIToUTF16("Doe"), s2.ColumnString16(3)); - - // Dave Smith. - ASSERT_TRUE(s2.Step()); - EXPECT_EQ("4C74A9D8-7EEE-423E-F9C2-E7FA70ED1396", s2.ColumnString(0)); - EXPECT_EQ(ASCIIToUTF16("Dave"), s2.ColumnString16(1)); - EXPECT_EQ(base::string16(), s2.ColumnString16(2)); - EXPECT_EQ(ASCIIToUTF16("Smith"), s2.ColumnString16(3)); - - // Dave Smith (Part 2). - ASSERT_TRUE(s2.Step()); - EXPECT_EQ("722DF5C4-F74A-294A-46F0-31FFDED0D635", s2.ColumnString(0)); - EXPECT_EQ(ASCIIToUTF16("Dave"), s2.ColumnString16(1)); - EXPECT_EQ(base::string16(), s2.ColumnString16(2)); - EXPECT_EQ(ASCIIToUTF16("Smith"), s2.ColumnString16(3)); - - // Alfred E Newman. - // Gets culled during migration from 35 to 36 due to incomplete address. - - // 3 Main St. - ASSERT_TRUE(s2.Step()); - EXPECT_EQ("9E5FE298-62C7-83DF-6293-381BC589183F", s2.ColumnString(0)); - EXPECT_EQ(base::string16(), s2.ColumnString16(1)); - EXPECT_EQ(base::string16(), s2.ColumnString16(2)); - EXPECT_EQ(base::string16(), s2.ColumnString16(3)); - - // Should be all. - EXPECT_FALSE(s2.Step()); - - sql::Statement s3( - connection.GetUniqueStatement( - "SELECT guid, email " - "FROM autofill_profile_emails")); - - // John Doe. - ASSERT_TRUE(s3.Step()); - EXPECT_EQ("00580526-FF81-EE2A-0546-1AC593A32E2F", s3.ColumnString(0)); - EXPECT_EQ(ASCIIToUTF16("john@doe.com"), s3.ColumnString16(1)); - - // John P. Doe. - // Gets culled during migration from 35 to 37 due to merging of John Doe and - // John P. Doe addresses. - - // 2 Main Street. - ASSERT_TRUE(s3.Step()); - EXPECT_EQ("4C74A9D8-7EEE-423E-F9C2-E7FA70ED1396", s3.ColumnString(0)); - EXPECT_EQ(base::string16(), s3.ColumnString16(1)); - - // 2 Main St. - ASSERT_TRUE(s3.Step()); - EXPECT_EQ("722DF5C4-F74A-294A-46F0-31FFDED0D635", s3.ColumnString(0)); - EXPECT_EQ(base::string16(), s3.ColumnString16(1)); - - // Alfred E Newman. - // Gets culled during migration from 35 to 36 due to incomplete address. - - // 3 Main St. - ASSERT_TRUE(s3.Step()); - EXPECT_EQ("9E5FE298-62C7-83DF-6293-381BC589183F", s3.ColumnString(0)); - EXPECT_EQ(base::string16(), s3.ColumnString16(1)); - - // Should be all. - EXPECT_FALSE(s3.Step()); - - sql::Statement s4( - connection.GetUniqueStatement( - "SELECT guid, number " - "FROM autofill_profile_phones")); - - // John Doe phone. - ASSERT_TRUE(s4.Step()); - EXPECT_EQ("00580526-FF81-EE2A-0546-1AC593A32E2F", s4.ColumnString(0)); - EXPECT_EQ(ASCIIToUTF16("4151112222"), s4.ColumnString16(1)); - - // John Doe fax. - // Gets culled after fax type removed. - - // John P. Doe phone. - // Gets culled during migration from 35 to 37 due to merging of John Doe and - // John P. Doe addresses. - - // John P. Doe fax. - // Gets culled during migration from 35 to 37 due to merging of John Doe and - // John P. Doe addresses. - - // 2 Main Street phone. - ASSERT_TRUE(s4.Step()); - EXPECT_EQ("4C74A9D8-7EEE-423E-F9C2-E7FA70ED1396", s4.ColumnString(0)); - EXPECT_EQ(base::string16(), s4.ColumnString16(1)); - - // 2 Main Street fax. - // Gets culled after fax type removed. - - // 2 Main St phone. - ASSERT_TRUE(s4.Step()); - EXPECT_EQ("722DF5C4-F74A-294A-46F0-31FFDED0D635", s4.ColumnString(0)); - EXPECT_EQ(0, s4.ColumnInt(1)); // 0 means phone. - EXPECT_EQ(base::string16(), s4.ColumnString16(2)); - - // 2 Main St fax. - // Gets culled after fax type removed. - - // Note no phone or fax for Alfred E Newman. - - // 3 Main St phone. - ASSERT_TRUE(s4.Step()); - EXPECT_EQ("9E5FE298-62C7-83DF-6293-381BC589183F", s4.ColumnString(0)); - EXPECT_EQ(base::string16(), s4.ColumnString16(1)); - - // 2 Main St fax. - // Gets culled after fax type removed. - - // Should be all. - EXPECT_FALSE(s4.Step()); - } -} - -// Adds a column for the autofill profile's country code. -TEST_F(WebDatabaseMigrationTest, MigrateVersion33ToCurrent) { - // Initialize the database. - ASSERT_NO_FATAL_FAILURE(LoadDatabase(FILE_PATH_LITERAL("version_33.sql"))); - - // Verify pre-conditions. These are expectations for version 33 of the - // database. - { - sql::Connection connection; - ASSERT_TRUE(connection.Open(GetDatabasePath())); - - EXPECT_FALSE(connection.DoesColumnExist("autofill_profiles", - "country_code")); - - // Check that the country value is the one we expect. - sql::Statement s( - connection.GetUniqueStatement("SELECT country FROM autofill_profiles")); - - ASSERT_TRUE(s.Step()); - std::string country = s.ColumnString(0); - EXPECT_EQ("United States", country); - } - - DoMigration(); - - // Verify post-conditions. These are expectations for current version of the - // database. - { - sql::Connection connection; - ASSERT_TRUE(connection.Open(GetDatabasePath())); - - // Check version. - EXPECT_EQ(kCurrentTestedVersionNumber, VersionFromConnection(&connection)); - - ASSERT_TRUE(connection.DoesColumnExist("autofill_profiles", - "country_code")); - - // Check that the country code is properly converted. - sql::Statement s(connection.GetUniqueStatement( - "SELECT country_code FROM autofill_profiles")); - - ASSERT_TRUE(s.Step()); - std::string country_code = s.ColumnString(0); - EXPECT_EQ("US", country_code); - } -} - -// Cleans up bad country code "UK" in favor of good country code "GB". -TEST_F(WebDatabaseMigrationTest, MigrateVersion34ToCurrent) { - // Initialize the database. - ASSERT_NO_FATAL_FAILURE(LoadDatabase(FILE_PATH_LITERAL("version_34.sql"))); - - // Verify pre-conditions. These are expectations for version 34 of the - // database. - { - sql::Connection connection; - ASSERT_TRUE(connection.Open(GetDatabasePath())); - - EXPECT_TRUE(connection.DoesColumnExist("autofill_profiles", - "country_code")); - - // Check that the country_code value is the one we expect. - sql::Statement s( - connection.GetUniqueStatement("SELECT country_code " - "FROM autofill_profiles")); - - ASSERT_TRUE(s.Step()); - std::string country_code = s.ColumnString(0); - EXPECT_EQ("UK", country_code); - - // Should have only one. - ASSERT_FALSE(s.Step()); - } - - DoMigration(); - - // Verify post-conditions. These are expectations for current version of the - // database. - { - sql::Connection connection; - ASSERT_TRUE(connection.Open(GetDatabasePath())); - - // Check version. - EXPECT_EQ(kCurrentTestedVersionNumber, VersionFromConnection(&connection)); - - ASSERT_TRUE(connection.DoesColumnExist("autofill_profiles", - "country_code")); - - // Check that the country_code code is properly converted. - sql::Statement s(connection.GetUniqueStatement( - "SELECT country_code FROM autofill_profiles")); - - ASSERT_TRUE(s.Step()); - std::string country_code = s.ColumnString(0); - EXPECT_EQ("GB", country_code); - - // Should have only one. - ASSERT_FALSE(s.Step()); - } -} - -// Cleans up invalid profiles based on more agressive merging. Filters out -// profiles that are subsets of other profiles, and profiles with invalid email, -// state, and incomplete address. -TEST_F(WebDatabaseMigrationTest, MigrateVersion35ToCurrent) { - // Initialize the database. - ASSERT_NO_FATAL_FAILURE(LoadDatabase(FILE_PATH_LITERAL("version_35.sql"))); - - // Verify pre-conditions. These are expectations for version 34 of the - // database. - { - sql::Connection connection; - ASSERT_TRUE(connection.Open(GetDatabasePath())); - - EXPECT_FALSE(connection.DoesTableExist("autofill_profiles_trash")); - ASSERT_TRUE(connection.DoesColumnExist("autofill_profiles", "guid")); - - // Check that there are 6 profiles prior to merge. - sql::Statement s( - connection.GetUniqueStatement("SELECT guid FROM autofill_profiles")); - int i = 0; - while (s.Step()) - ++i; - EXPECT_EQ(6, i); - } - - DoMigration(); - - // Verify post-conditions. These are expectations for current version of the - // database. - { - sql::Connection connection; - ASSERT_TRUE(connection.Open(GetDatabasePath())); - - // Check version. - EXPECT_EQ(kCurrentTestedVersionNumber, VersionFromConnection(&connection)); - - ASSERT_TRUE(connection.DoesTableExist("autofill_profiles_trash")); - ASSERT_TRUE(connection.DoesColumnExist("autofill_profiles_trash", "guid")); - ASSERT_TRUE(connection.DoesColumnExist("autofill_profiles", "guid")); - - // Verify data in the database after the migration. - sql::Statement s1( - connection.GetUniqueStatement( - "SELECT guid, company_name, street_address, city, state, zipcode," - " country_code, date_modified " - "FROM autofill_profiles")); - - // John Doe. - ASSERT_TRUE(s1.Step()); - EXPECT_EQ("00000000-0000-0000-0000-000000000001", s1.ColumnString(0)); - EXPECT_EQ(ASCIIToUTF16("Acme Inc."), s1.ColumnString16(1)); - EXPECT_EQ(ASCIIToUTF16("1 Main Street\n" - "Apt 2"), - s1.ColumnString16(2)); - EXPECT_EQ(ASCIIToUTF16("San Francisco"), s1.ColumnString16(3)); - EXPECT_EQ(ASCIIToUTF16("CA"), s1.ColumnString16(4)); - EXPECT_EQ(ASCIIToUTF16("94102"), s1.ColumnString16(5)); - EXPECT_EQ(ASCIIToUTF16("US"), s1.ColumnString16(6)); - EXPECT_EQ(1300131704, s1.ColumnInt64(7)); - - // That should be it. - ASSERT_FALSE(s1.Step()); - - // Check that there 5 trashed profile after the merge. - sql::Statement s2( - connection.GetUniqueStatement("SELECT guid " - "FROM autofill_profiles_trash")); - ASSERT_TRUE(s2.Step()); - EXPECT_EQ("00000000-0000-0000-0000-000000000002", s2.ColumnString(0)); - - ASSERT_TRUE(s2.Step()); - EXPECT_EQ("00000000-0000-0000-0000-000000000003", s2.ColumnString(0)); - - ASSERT_TRUE(s2.Step()); - EXPECT_EQ("00000000-0000-0000-0000-000000000004", s2.ColumnString(0)); - - ASSERT_TRUE(s2.Step()); - EXPECT_EQ("00000000-0000-0000-0000-000000000005", s2.ColumnString(0)); - - ASSERT_TRUE(s2.Step()); - EXPECT_EQ("00000000-0000-0000-0000-000000000006", s2.ColumnString(0)); - - // That should be it. - ASSERT_FALSE(s2.Step()); - } -} - -// Tests that the |keywords| |last_modified| column gets added to the schema for -// a version 37 database. -TEST_F(WebDatabaseMigrationTest, MigrateVersion37ToCurrent) { - // This schema is taken from a build prior to the addition of the |keywords| - // |last_modified| column. - ASSERT_NO_FATAL_FAILURE(LoadDatabase(FILE_PATH_LITERAL("version_37.sql"))); - - // Verify pre-conditions. These are expectations for version 37 of the - // database. - { - sql::Connection connection; - ASSERT_TRUE(connection.Open(GetDatabasePath())); - - // Columns existing and not existing before current version. - ASSERT_TRUE(connection.DoesColumnExist("keywords", "id")); - ASSERT_FALSE(connection.DoesColumnExist("keywords", "last_modified")); - } - - DoMigration(); - - // Verify post-conditions. These are expectations for current version of the - // database. - { - sql::Connection connection; - ASSERT_TRUE(connection.Open(GetDatabasePath())); - - // Check version. - EXPECT_EQ(kCurrentTestedVersionNumber, VersionFromConnection(&connection)); - - // |keywords| |last_modified| column should have been added. - EXPECT_TRUE(connection.DoesColumnExist("keywords", "id")); - EXPECT_TRUE(connection.DoesColumnExist("keywords", "last_modified")); - } -} - -// Tests that the |keywords| |sync_guid| column gets added to the schema for -// a version 38 database. -TEST_F(WebDatabaseMigrationTest, MigrateVersion38ToCurrent) { - // This schema is taken from a build prior to the addition of the |keywords| - // |sync_guid| column. - ASSERT_NO_FATAL_FAILURE(LoadDatabase(FILE_PATH_LITERAL("version_38.sql"))); - - // Verify pre-conditions. These are expectations for version 38 of the - // database. - { - sql::Connection connection; - ASSERT_TRUE(connection.Open(GetDatabasePath())); - - // Columns existing and not existing before current version. - ASSERT_TRUE(connection.DoesColumnExist("keywords", "id")); - ASSERT_FALSE(connection.DoesColumnExist("keywords", "sync_guid")); - } - - DoMigration(); - - // Verify post-conditions. These are expectations for current version of the - // database. - { - sql::Connection connection; - ASSERT_TRUE(connection.Open(GetDatabasePath())); - - // Check version. - EXPECT_EQ(kCurrentTestedVersionNumber, VersionFromConnection(&connection)); - - // |keywords| |sync_guid| column should have been added. - EXPECT_TRUE(connection.DoesColumnExist("keywords", "id")); - EXPECT_TRUE(connection.DoesColumnExist("keywords", "sync_guid")); - } -} - -// Tests that no backup data is added to a version 39 database. -TEST_F(WebDatabaseMigrationTest, MigrateVersion39ToCurrent) { - // This schema is taken from a build prior to the addition of the default - // search provider backup field to the meta table. - ASSERT_NO_FATAL_FAILURE(LoadDatabase(FILE_PATH_LITERAL("version_39.sql"))); - - // Verify pre-conditions. These are expectations for version 39 of the - // database. - { - sql::Connection connection; - ASSERT_TRUE(connection.Open(GetDatabasePath())); - ASSERT_TRUE(sql::MetaTable::DoesTableExist(&connection)); - - sql::MetaTable meta_table; - ASSERT_TRUE(meta_table.Init(&connection, 39, 39)); - - int64 default_search_provider_id = 0; - EXPECT_TRUE(meta_table.GetValue(KeywordTable::kDefaultSearchProviderKey, - &default_search_provider_id)); - - EXPECT_NO_FATAL_FAILURE(CheckNoBackupData(connection, &meta_table)); - } - - DoMigration(); - - // Verify post-conditions. These are expectations for current version of the - // database. - { - sql::Connection connection; - ASSERT_TRUE(connection.Open(GetDatabasePath())); - ASSERT_TRUE(sql::MetaTable::DoesTableExist(&connection)); - - // Check version. - EXPECT_EQ(kCurrentTestedVersionNumber, VersionFromConnection(&connection)); - - sql::MetaTable meta_table; - ASSERT_TRUE(meta_table.Init(&connection, kCurrentTestedVersionNumber, - kCurrentTestedVersionNumber)); - - int64 default_search_provider_id = 0; - EXPECT_TRUE(meta_table.GetValue(KeywordTable::kDefaultSearchProviderKey, - &default_search_provider_id)); - EXPECT_NE(0, default_search_provider_id); - - EXPECT_NO_FATAL_FAILURE(CheckNoBackupData(connection, &meta_table)); - } -} - -// Tests that the backup data is removed from the database. -TEST_F(WebDatabaseMigrationTest, MigrateVersion40ToCurrent) { - ASSERT_NO_FATAL_FAILURE(LoadDatabase(FILE_PATH_LITERAL("version_40.sql"))); - - // Verify pre-conditions. These are expectations for version 40 of the - // database. - { - sql::Connection connection; - ASSERT_TRUE(connection.Open(GetDatabasePath())); - ASSERT_TRUE(sql::MetaTable::DoesTableExist(&connection)); - - sql::MetaTable meta_table; - ASSERT_TRUE(meta_table.Init(&connection, 40, 40)); - - int64 default_search_provider_id = 0; - EXPECT_TRUE(meta_table.GetValue(KeywordTable::kDefaultSearchProviderKey, - &default_search_provider_id)); - - EXPECT_NO_FATAL_FAILURE(CheckHasBackupData(&meta_table)); - } - - DoMigration(); - - // Verify post-conditions. These are expectations for current version of the - // database. - { - sql::Connection connection; - ASSERT_TRUE(connection.Open(GetDatabasePath())); - ASSERT_TRUE(sql::MetaTable::DoesTableExist(&connection)); - - // Check version. - EXPECT_EQ(kCurrentTestedVersionNumber, VersionFromConnection(&connection)); - - sql::MetaTable meta_table; - ASSERT_TRUE(meta_table.Init(&connection, kCurrentTestedVersionNumber, - kCurrentTestedVersionNumber)); - - int64 default_search_provider_id = 0; - EXPECT_TRUE(meta_table.GetValue(KeywordTable::kDefaultSearchProviderKey, - &default_search_provider_id)); - EXPECT_NE(0, default_search_provider_id); - - EXPECT_NO_FATAL_FAILURE(CheckNoBackupData(connection, &meta_table)); - } -} - -// Tests that the backup data is removed from the database. -TEST_F(WebDatabaseMigrationTest, MigrateVersion41ToCurrent) { - ASSERT_NO_FATAL_FAILURE(LoadDatabase(FILE_PATH_LITERAL("version_41.sql"))); - - // Verify pre-conditions. These are expectations for version 41 of the - // database. - { - sql::Connection connection; - ASSERT_TRUE(connection.Open(GetDatabasePath())); - ASSERT_TRUE(sql::MetaTable::DoesTableExist(&connection)); - - sql::MetaTable meta_table; - ASSERT_TRUE(meta_table.Init(&connection, 41, 41)); - - int64 default_search_provider_id = 0; - EXPECT_TRUE(meta_table.GetValue(KeywordTable::kDefaultSearchProviderKey, - &default_search_provider_id)); - - EXPECT_NO_FATAL_FAILURE(CheckHasBackupData(&meta_table)); - } - - DoMigration(); - - // Verify post-conditions. These are expectations for current version of the - // database. - { - sql::Connection connection; - ASSERT_TRUE(connection.Open(GetDatabasePath())); - ASSERT_TRUE(sql::MetaTable::DoesTableExist(&connection)); - - // Check version. - EXPECT_EQ(kCurrentTestedVersionNumber, VersionFromConnection(&connection)); - - sql::MetaTable meta_table; - ASSERT_TRUE(meta_table.Init(&connection, kCurrentTestedVersionNumber, - kCurrentTestedVersionNumber)); - - int64 default_search_provider_id = 0; - EXPECT_TRUE(meta_table.GetValue(KeywordTable::kDefaultSearchProviderKey, - &default_search_provider_id)); - EXPECT_NE(0, default_search_provider_id); - - EXPECT_NO_FATAL_FAILURE(CheckNoBackupData(connection, &meta_table)); - } -} - -// Tests that the backup data is removed from the database. -TEST_F(WebDatabaseMigrationTest, MigrateVersion42ToCurrent) { - ASSERT_NO_FATAL_FAILURE(LoadDatabase(FILE_PATH_LITERAL("version_42.sql"))); - - // Verify pre-conditions. These are expectations for version 42 of the - // database. - { - sql::Connection connection; - ASSERT_TRUE(connection.Open(GetDatabasePath())); - ASSERT_TRUE(sql::MetaTable::DoesTableExist(&connection)); - - sql::MetaTable meta_table; - ASSERT_TRUE(meta_table.Init(&connection, 42, 42)); - - int64 default_search_provider_id = 0; - EXPECT_TRUE(meta_table.GetValue(KeywordTable::kDefaultSearchProviderKey, - &default_search_provider_id)); - - EXPECT_NO_FATAL_FAILURE(CheckHasBackupData(&meta_table)); - - EXPECT_FALSE(connection.DoesTableExist("keywords_backup")); - } - - DoMigration(); - - // Verify post-conditions. These are expectations for current version of the - // database. - { - sql::Connection connection; - ASSERT_TRUE(connection.Open(GetDatabasePath())); - ASSERT_TRUE(sql::MetaTable::DoesTableExist(&connection)); - - // Check version. - EXPECT_EQ(kCurrentTestedVersionNumber, VersionFromConnection(&connection)); - - sql::MetaTable meta_table; - ASSERT_TRUE(meta_table.Init(&connection, kCurrentTestedVersionNumber, - kCurrentTestedVersionNumber)); - - int64 default_search_provider_id = 0; - EXPECT_TRUE(meta_table.GetValue(KeywordTable::kDefaultSearchProviderKey, - &default_search_provider_id)); - EXPECT_NE(0, default_search_provider_id); - - EXPECT_NO_FATAL_FAILURE(CheckNoBackupData(connection, &meta_table)); - } -} - -// Tests that the backup data is removed from the database. -TEST_F(WebDatabaseMigrationTest, MigrateVersion43ToCurrent) { - ASSERT_NO_FATAL_FAILURE(LoadDatabase(FILE_PATH_LITERAL("version_43.sql"))); - - int64 previous_default_search_provider_id; - - // Verify pre-conditions. These are expectations for version 43 of the - // database. - { - sql::Connection connection; - ASSERT_TRUE(connection.Open(GetDatabasePath())); - ASSERT_TRUE(sql::MetaTable::DoesTableExist(&connection)); - - sql::MetaTable meta_table; - ASSERT_TRUE(meta_table.Init(&connection, 43, 43)); - - int64 default_search_provider_id = 0; - EXPECT_TRUE(meta_table.GetValue(KeywordTable::kDefaultSearchProviderKey, - &default_search_provider_id)); - EXPECT_NE(default_search_provider_id, 0); - previous_default_search_provider_id = default_search_provider_id; - - EXPECT_NO_FATAL_FAILURE(CheckHasBackupData(&meta_table)); - EXPECT_TRUE(connection.DoesTableExist("keywords_backup")); - } - - DoMigration(); - - // Verify post-conditions. These are expectations for current version of the - // database. - { - sql::Connection connection; - ASSERT_TRUE(connection.Open(GetDatabasePath())); - ASSERT_TRUE(sql::MetaTable::DoesTableExist(&connection)); - - // Check version. - EXPECT_EQ(kCurrentTestedVersionNumber, VersionFromConnection(&connection)); - - sql::MetaTable meta_table; - ASSERT_TRUE(meta_table.Init( - &connection, - kCurrentTestedVersionNumber, - kCurrentTestedVersionNumber)); - - int64 default_search_provider_id = 0; - EXPECT_TRUE(meta_table.GetValue(KeywordTable::kDefaultSearchProviderKey, - &default_search_provider_id)); - // Default search provider ID should not change. - EXPECT_EQ(previous_default_search_provider_id, default_search_provider_id); - - EXPECT_NO_FATAL_FAILURE(CheckNoBackupData(connection, &meta_table)); - } -} - -// Tests that the |autogenerate_keyword| and |logo_id| columns get removed from -// the keyword table schema for a version 45 database. -TEST_F(WebDatabaseMigrationTest, MigrateVersion44ToCurrent) { - ASSERT_NO_FATAL_FAILURE(LoadDatabase(FILE_PATH_LITERAL("version_44.sql"))); - - // Verify pre-conditions. These are expectations for version 44 of the - // database. - { - sql::Connection connection; - ASSERT_TRUE(connection.Open(GetDatabasePath())); - ASSERT_TRUE(sql::MetaTable::DoesTableExist(&connection)); - - sql::MetaTable meta_table; - ASSERT_TRUE(meta_table.Init(&connection, 44, 44)); - - ASSERT_TRUE(connection.DoesColumnExist("keywords", "autogenerate_keyword")); - ASSERT_TRUE(connection.DoesColumnExist("keywords", "logo_id")); - } - - DoMigration(); - - // Verify post-conditions. These are expectations for current version of the - // database. - { - sql::Connection connection; - ASSERT_TRUE(connection.Open(GetDatabasePath())); - ASSERT_TRUE(sql::MetaTable::DoesTableExist(&connection)); - - // Check version. - EXPECT_EQ(kCurrentTestedVersionNumber, VersionFromConnection(&connection)); - - sql::MetaTable meta_table; - ASSERT_TRUE(meta_table.Init(&connection, kCurrentTestedVersionNumber, - kCurrentTestedVersionNumber)); - - // We should have removed this obsolete key. - std::string default_search_provider_backup; - EXPECT_FALSE(meta_table.GetValue("Default Search Provider Backup", - &default_search_provider_backup)); - - // Two columns should have been removed. - EXPECT_FALSE(connection.DoesColumnExist("keywords", - "autogenerate_keyword")); - EXPECT_FALSE(connection.DoesColumnExist("keywords", "logo_id")); - - // Backup data should have been removed. - EXPECT_NO_FATAL_FAILURE(CheckNoBackupData(connection, &meta_table)); - } -} - -// Previously, this tested that the web_intents and web_intents_defaults tables -// were modified to include "scheme" columns. Since the web_intents and -// web_intents_defaults tables are now obsolete, this test checks to ensure that -// they are properly removed. -TEST_F(WebDatabaseMigrationTest, MigrateVersion45ToCurrent) { - ASSERT_NO_FATAL_FAILURE(LoadDatabase(FILE_PATH_LITERAL("version_45.sql"))); - - // Verify pre-conditions. These are expectations for version 45 of the - // database. - { - sql::Connection connection; - ASSERT_TRUE(connection.Open(GetDatabasePath())); - ASSERT_TRUE(sql::MetaTable::DoesTableExist(&connection)); - - sql::MetaTable meta_table; - ASSERT_TRUE(meta_table.Init(&connection, 45, 45)); - - ASSERT_FALSE(connection.DoesColumnExist("scheme", "web_intents")); - ASSERT_FALSE(connection.DoesColumnExist( - "scheme", "web_intents_defaults")); - } - - DoMigration(); - - // Verify post-conditions. These are expectations for current version of the - // database. - { - sql::Connection connection; - ASSERT_TRUE(connection.Open(GetDatabasePath())); - ASSERT_TRUE(sql::MetaTable::DoesTableExist(&connection)); - - // Check version. - EXPECT_EQ(kCurrentTestedVersionNumber, VersionFromConnection(&connection)); - - sql::MetaTable meta_table; - ASSERT_TRUE(meta_table.Init( - &connection, - kCurrentTestedVersionNumber, - kCurrentTestedVersionNumber)); - - // finally ensure the migration code cleaned up after itself - EXPECT_FALSE(connection.DoesTableExist("web_intents")); - EXPECT_FALSE(connection.DoesTableExist("web_intents_defaults")); - } -} - -// Previously, this tested that the web_intents and web_intents_defaults tables -// were modified to include "scheme" columns. Since the web_intents and -// web_intents_defaults tables are now obsolete, this test checks to ensure that -// they are properly removed. -TEST_F(WebDatabaseMigrationTest, MigrateVersion45InvalidToCurrent) { - ASSERT_NO_FATAL_FAILURE( - LoadDatabase(FILE_PATH_LITERAL("version_45_invalid.sql"))); - - // Verify pre-conditions. These are expectations for version 45 of the - // database. - { - sql::Connection connection; - ASSERT_TRUE(connection.Open(GetDatabasePath())); - ASSERT_TRUE(sql::MetaTable::DoesTableExist(&connection)); - - sql::MetaTable meta_table; - ASSERT_TRUE(meta_table.Init(&connection, 45, 45)); - - ASSERT_FALSE(connection.DoesColumnExist("scheme", "web_intents")); - ASSERT_FALSE(connection.DoesColumnExist( - "scheme", "web_intents_defaults")); - } - - DoMigration(); - - // Verify post-conditions. These are expectations for current version of the - // database. - { - sql::Connection connection; - ASSERT_TRUE(connection.Open(GetDatabasePath())); - ASSERT_TRUE(sql::MetaTable::DoesTableExist(&connection)); - - // Check version. - EXPECT_EQ(kCurrentTestedVersionNumber, VersionFromConnection(&connection)); - - sql::MetaTable meta_table; - ASSERT_TRUE(meta_table.Init( - &connection, - kCurrentTestedVersionNumber, - kCurrentTestedVersionNumber)); - - EXPECT_FALSE(connection.DoesTableExist("web_intents")); - EXPECT_FALSE(connection.DoesTableExist("web_intents_defaults")); - } -} - -// Check that current version is forced to compatible version before migration, -// if the former is smaller. -TEST_F(WebDatabaseMigrationTest, MigrateVersion45CompatibleToCurrent) { - ASSERT_NO_FATAL_FAILURE( - LoadDatabase(FILE_PATH_LITERAL("version_45_compatible.sql"))); - - // Verify pre-conditions. These are expectations for version 45 of the - // database. - { - sql::Connection connection; - ASSERT_TRUE(connection.Open(GetDatabasePath())); - ASSERT_TRUE(sql::MetaTable::DoesTableExist(&connection)); - - sql::MetaTable meta_table; - // Database is actually version 45 but the version field states 40. - ASSERT_TRUE(meta_table.Init(&connection, 40, 45)); - } - - DoMigration(); - - // Verify post-conditions. These are expectations for current version of the - // database. - { - sql::Connection connection; - ASSERT_TRUE(connection.Open(GetDatabasePath())); - ASSERT_TRUE(sql::MetaTable::DoesTableExist(&connection)); - - // Check version. - EXPECT_EQ(kCurrentTestedVersionNumber, VersionFromConnection(&connection)); - EXPECT_LE(45, VersionFromConnection(&connection)); - } -} - -// Tests that the |alternate_urls| column is added to the keyword table schema -// for a version 47 database. -TEST_F(WebDatabaseMigrationTest, MigrateVersion46ToCurrent) { - ASSERT_NO_FATAL_FAILURE( - LoadDatabase(FILE_PATH_LITERAL("version_46.sql"))); - - // Verify pre-conditions. These are expectations for version 46 of the - // database. - { - sql::Connection connection; - ASSERT_TRUE(connection.Open(GetDatabasePath())); - ASSERT_TRUE(sql::MetaTable::DoesTableExist(&connection)); - - sql::MetaTable meta_table; - ASSERT_TRUE(meta_table.Init(&connection, 46, 46)); - - ASSERT_FALSE(connection.DoesColumnExist("keywords", "alternate_urls")); - ASSERT_FALSE(connection.DoesColumnExist("keywords_backup", - "alternate_urls")); - } - - DoMigration(); - - // Verify post-conditions. These are expectations for current version of the - // database. - { - sql::Connection connection; - ASSERT_TRUE(connection.Open(GetDatabasePath())); - ASSERT_TRUE(sql::MetaTable::DoesTableExist(&connection)); - - // Check version. - EXPECT_EQ(kCurrentTestedVersionNumber, VersionFromConnection(&connection)); - - // A new column should have been created. - EXPECT_TRUE(connection.DoesColumnExist("keywords", "alternate_urls")); - } -} - -// Tests that the backup data is removed from the database. -TEST_F(WebDatabaseMigrationTest, MigrateVersion47ToCurrent) { - ASSERT_NO_FATAL_FAILURE(LoadDatabase(FILE_PATH_LITERAL("version_47.sql"))); - - // Verify pre-conditions. These are expectations for version 47 of the - // database. - { - sql::Connection connection; - ASSERT_TRUE(connection.Open(GetDatabasePath())); - ASSERT_TRUE(sql::MetaTable::DoesTableExist(&connection)); - - sql::MetaTable meta_table; - ASSERT_TRUE(meta_table.Init(&connection, 47, 47)); - - int64 default_search_provider_id = 0; - EXPECT_TRUE(meta_table.GetValue(KeywordTable::kDefaultSearchProviderKey, - &default_search_provider_id)); - EXPECT_NE(0, default_search_provider_id); - - EXPECT_NO_FATAL_FAILURE(CheckHasBackupData(&meta_table)); - EXPECT_TRUE(connection.DoesTableExist("keywords_backup")); - } - - DoMigration(); - - // Verify post-conditions. These are expectations for current version of the - // database. - { - sql::Connection connection; - ASSERT_TRUE(connection.Open(GetDatabasePath())); - ASSERT_TRUE(sql::MetaTable::DoesTableExist(&connection)); - - // Check version. - EXPECT_EQ(kCurrentTestedVersionNumber, VersionFromConnection(&connection)); - - sql::MetaTable meta_table; - ASSERT_TRUE(meta_table.Init(&connection, kCurrentTestedVersionNumber, - kCurrentTestedVersionNumber)); - - int64 default_search_provider_id = 0; - EXPECT_TRUE(meta_table.GetValue(KeywordTable::kDefaultSearchProviderKey, - &default_search_provider_id)); - EXPECT_NE(0, default_search_provider_id); - - EXPECT_NO_FATAL_FAILURE(CheckNoBackupData(connection, &meta_table)); - } -} - -// Tests that the |search_terms_replacement_key| column is added to the keyword -// table schema for a version 49 database. -TEST_F(WebDatabaseMigrationTest, MigrateVersion48ToCurrent) { - ASSERT_NO_FATAL_FAILURE( - LoadDatabase(FILE_PATH_LITERAL("version_48.sql"))); - - // Verify pre-conditions. These are expectations for version 48 of the - // database. - { - sql::Connection connection; - ASSERT_TRUE(connection.Open(GetDatabasePath())); - ASSERT_TRUE(sql::MetaTable::DoesTableExist(&connection)); - - sql::MetaTable meta_table; - ASSERT_TRUE(meta_table.Init(&connection, 48, 48)); - - ASSERT_FALSE(connection.DoesColumnExist("keywords", - "search_terms_replacement_key")); - } - - DoMigration(); - - // Verify post-conditions. These are expectations for current version of the - // database. - { - sql::Connection connection; - ASSERT_TRUE(connection.Open(GetDatabasePath())); - ASSERT_TRUE(sql::MetaTable::DoesTableExist(&connection)); - - // Check version. - EXPECT_EQ(kCurrentTestedVersionNumber, VersionFromConnection(&connection)); - - // A new column should have been created. - EXPECT_TRUE(connection.DoesColumnExist("keywords", - "search_terms_replacement_key")); - } -} - -// Tests that the |origin| column is added to the autofill_profiles and -// credit_cards table schemas for a version 50 database. -TEST_F(WebDatabaseMigrationTest, MigrateVersion49ToCurrent) { - ASSERT_NO_FATAL_FAILURE(LoadDatabase(FILE_PATH_LITERAL("version_49.sql"))); - - // Verify pre-conditions. These are expectations for version 49 of the - // database. - { - sql::Connection connection; - ASSERT_TRUE(connection.Open(GetDatabasePath())); - - ASSERT_FALSE(connection.DoesColumnExist("autofill_profiles", "origin")); - ASSERT_FALSE(connection.DoesColumnExist("credit_cards", "origin")); - } - - DoMigration(); - - // Verify post-conditions. These are expectations for current version of the - // database. - { - sql::Connection connection; - ASSERT_TRUE(connection.Open(GetDatabasePath())); - ASSERT_TRUE(sql::MetaTable::DoesTableExist(&connection)); - - // Check version. - EXPECT_EQ(kCurrentTestedVersionNumber, VersionFromConnection(&connection)); - - // A new column should have been created in both tables. - EXPECT_TRUE(connection.DoesColumnExist("autofill_profiles", "origin")); - EXPECT_TRUE(connection.DoesColumnExist("credit_cards", "origin")); - } -} - -// Tests that the columns |image_url|, |search_url_post_params|, -// |suggest_url_post_params|, |instant_url_post_params|, and -// |image_url_post_params| are added to the keyword table schema for a version -// 50 database. -TEST_F(WebDatabaseMigrationTest, MigrateVersion50ToCurrent) { +// Versions below 52 are deprecated. This verifies that old databases are razed. +TEST_F(WebDatabaseMigrationTest, RazeDeprecatedVersionAndReinit) { ASSERT_NO_FATAL_FAILURE( LoadDatabase(FILE_PATH_LITERAL("version_50.sql")));
diff --git a/content/browser/android/media_players_observer.cc b/content/browser/android/media_players_observer.cc new file mode 100644 index 0000000..c4fd472 --- /dev/null +++ b/content/browser/android/media_players_observer.cc
@@ -0,0 +1,60 @@ +// 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/browser/android/media_players_observer.h" + +#include <climits> + +#include "base/logging.h" +#include "content/public/browser/web_contents.h" + +namespace content { + +MediaPlayersObserver::MediaPlayersObserver(WebContents* web_contents) + : AudioStateProvider(web_contents) { +} + +MediaPlayersObserver::~MediaPlayersObserver() {} + +bool MediaPlayersObserver::IsAudioStateAvailable() const { + return true; +} + +// This audio state provider does not have a monitor +AudioStreamMonitor* MediaPlayersObserver::audio_stream_monitor() { + return nullptr; +} + +void MediaPlayersObserver::OnAudibleStateChanged(RenderFrameHost* rfh, + int player_id, + bool is_audible) { + audio_status_map_[Key(rfh, player_id)] = is_audible; + UpdateStatusAndNotify(); +} + +void MediaPlayersObserver::RemovePlayer(RenderFrameHost* rfh, int player_id) { + size_t num_erased_entries = audio_status_map_.erase(Key(rfh, player_id)); + DCHECK_EQ(1u, num_erased_entries); + UpdateStatusAndNotify(); +} + +void MediaPlayersObserver::RenderFrameDeleted(RenderFrameHost* rfh) { + StatusMap::iterator begin = audio_status_map_.lower_bound(Key(rfh, 0)); + StatusMap::iterator end = audio_status_map_.upper_bound(Key(rfh, INT_MAX)); + audio_status_map_.erase(begin, end); + UpdateStatusAndNotify(); +} + +void MediaPlayersObserver::UpdateStatusAndNotify() { + for (const auto& player_status : audio_status_map_) { + if (player_status.second) { + Notify(true); // at least one player is making noise + return; + } + } + + Notify(false); +} + +} // namespace content
diff --git a/content/browser/android/media_players_observer.h b/content/browser/android/media_players_observer.h new file mode 100644 index 0000000..b01a3bf --- /dev/null +++ b/content/browser/android/media_players_observer.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 CONTENT_BROWSER_ANDROID_MEDIA_PLAYERS_OBSERVER_H_ +#define CONTENT_BROWSER_ANDROID_MEDIA_PLAYERS_OBSERVER_H_ + +#include <map> + +#include "base/macros.h" +#include "content/browser/media/audio_state_provider.h" + +namespace content { + +class RenderFrameHost; + +// On Android the MediaPlayerAndroid objects report +// the audible state to us. +class MediaPlayersObserver : public AudioStateProvider { + public: + explicit MediaPlayersObserver(WebContents* web_contents); + ~MediaPlayersObserver() override; + + bool IsAudioStateAvailable() const override; + + // This audio state provider does not have a monitor, + // the method returns nullptr. + AudioStreamMonitor* audio_stream_monitor() override; + + // These methods constitute the observer pattern, should + // be called when corresponding event happens. They will notify + // WebContents whenever its audible state as a whole changes. + void OnAudibleStateChanged(RenderFrameHost* rfh, int player_id, + bool is_audible); + void RemovePlayer(RenderFrameHost* rfh, int player_id); + void RenderFrameDeleted(RenderFrameHost* rfh); + + private: + void UpdateStatusAndNotify(); + + // Audible status per player ID and frame + typedef std::pair<RenderFrameHost*, int> Key; + typedef std::map<Key, bool> StatusMap; + StatusMap audio_status_map_; + + DISALLOW_COPY_AND_ASSIGN(MediaPlayersObserver); +}; + +} // namespace content + +#endif // CONTENT_BROWSER_ANDROID_MEDIA_PLAYERS_OBSERVER_H_
diff --git a/content/browser/compositor/software_browser_compositor_output_surface.cc b/content/browser/compositor/software_browser_compositor_output_surface.cc index 647a062..2d422c9 100644 --- a/content/browser/compositor/software_browser_compositor_output_surface.cc +++ b/content/browser/compositor/software_browser_compositor_output_surface.cc
@@ -30,9 +30,13 @@ void SoftwareBrowserCompositorOutputSurface::SwapBuffers( cc::CompositorFrame* frame) { - for (size_t i = 0; i < frame->metadata.latency_info.size(); i++) { - frame->metadata.latency_info[i].AddLatencyNumber( - ui::INPUT_EVENT_LATENCY_TERMINATED_FRAME_SWAP_COMPONENT, 0, 0); + base::TimeTicks swap_time = base::TimeTicks::Now(); + for (auto& latency : frame->metadata.latency_info) { + latency.AddLatencyNumberWithTimestamp( + ui::INPUT_EVENT_GPU_SWAP_BUFFER_COMPONENT, 0, 0, swap_time, 1); + latency.AddLatencyNumberWithTimestamp( + ui::INPUT_EVENT_LATENCY_TERMINATED_FRAME_SWAP_COMPONENT, 0, 0, + swap_time, 1); } base::MessageLoop::current()->PostTask( FROM_HERE,
diff --git a/content/browser/dom_storage/session_storage_database.cc b/content/browser/dom_storage/session_storage_database.cc index 6e47a1f..3afc669 100644 --- a/content/browser/dom_storage/session_storage_database.cc +++ b/content/browser/dom_storage/session_storage_database.cc
@@ -236,9 +236,14 @@ } bool SessionStorageDatabase::DeleteNamespace(const std::string& namespace_id) { - if (!LazyOpen(false)) { - // No need to create the database if it doesn't exist. - return true; + { + // The caller should have called other methods to open the DB before this + // function. Otherwise, DB stores nothing interesting related to the + // specified namespace. + // Do nothing if the DB is not open (or we know it has failed already), + base::AutoLock auto_lock(db_lock_); + if (!IsOpen() || db_error_ || is_inconsistent_) + return false; } DBOperation operation(this); // Itereate through the areas in the namespace.
diff --git a/content/browser/fileapi/blob_storage_context_unittest.cc b/content/browser/fileapi/blob_storage_context_unittest.cc index 9602b3a..29270b7 100644 --- a/content/browser/fileapi/blob_storage_context_unittest.cc +++ b/content/browser/fileapi/blob_storage_context_unittest.cc
@@ -2,6 +2,11 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. +#include "storage/browser/blob/blob_storage_context.h" + +#include <limits> +#include <string> + #include "base/files/file_path.h" #include "base/memory/ref_counted.h" #include "base/memory/scoped_ptr.h" @@ -11,24 +16,19 @@ #include "content/browser/fileapi/blob_storage_host.h" #include "storage/browser/blob/blob_data_builder.h" #include "storage/browser/blob/blob_data_handle.h" +#include "storage/browser/blob/blob_data_item.h" #include "storage/browser/blob/blob_data_snapshot.h" -#include "storage/browser/blob/blob_storage_context.h" #include "testing/gtest/include/gtest/gtest.h" using storage::BlobDataBuilder; using storage::BlobDataHandle; +using storage::BlobDataItem; using storage::BlobDataSnapshot; using storage::BlobStorageContext; using storage::DataElement; namespace content { - namespace { -// This is necessary to clean up the blobs after the handles are released. -void RunEventLoopTillIdle() { - base::RunLoop run_loop; - run_loop.RunUntilIdle(); -} void SetupBasicBlob(BlobStorageHost* host, const std::string& id) { EXPECT_TRUE(host->StartBuildingBlob(id)); @@ -38,6 +38,7 @@ EXPECT_TRUE(host->FinishBuildingBlob(id, "text/plain")); EXPECT_FALSE(host->StartBuildingBlob(id)); } + } // namespace TEST(BlobStorageContextTest, IncrementDecrementRef) { @@ -54,7 +55,7 @@ blob_data_handle = context.GetBlobDataFromUUID(kId); EXPECT_TRUE(blob_data_handle); blob_data_handle.reset(); - RunEventLoopTillIdle(); + base::RunLoop().RunUntilIdle(); // Make sure its still there after inc/dec. EXPECT_TRUE(host.IncrementBlobRefCount(kId)); @@ -62,7 +63,7 @@ blob_data_handle = context.GetBlobDataFromUUID(kId); EXPECT_TRUE(blob_data_handle); blob_data_handle.reset(); - RunEventLoopTillIdle(); + base::RunLoop().RunUntilIdle(); // Make sure it goes away in the end. EXPECT_TRUE(host.DecrementBlobRefCount(kId)); @@ -113,7 +114,7 @@ // Should disappear after dropping both handles. blob_data_handle.reset(); another_handle.reset(); - RunEventLoopTillIdle(); + base::RunLoop().RunUntilIdle(); blob_data_handle = context.GetBlobDataFromUUID(kId); EXPECT_FALSE(blob_data_handle); @@ -147,11 +148,11 @@ EXPECT_EQ(10lu, context.memory_usage()); blob_data_handle.reset(); - RunEventLoopTillIdle(); + base::RunLoop().RunUntilIdle(); EXPECT_EQ(10lu, context.memory_usage()); blob_data_handle2.reset(); - RunEventLoopTillIdle(); + base::RunLoop().RunUntilIdle(); EXPECT_EQ(0lu, context.memory_usage()); } @@ -190,7 +191,7 @@ blob_data_handle.reset(); data2.reset(); - RunEventLoopTillIdle(); + base::RunLoop().RunUntilIdle(); blob_data_handle = context.GetBlobDataFromUUID(kId1); EXPECT_FALSE(blob_data_handle); @@ -205,7 +206,7 @@ scoped_ptr<BlobDataHandle> blob_data_handle3 = context.AddFinishedBlob(&builder3); blob_data_handle2.reset(); - RunEventLoopTillIdle(); + base::RunLoop().RunUntilIdle(); blob_data_handle2 = context.GetBlobDataFromUUID(kId2); EXPECT_FALSE(blob_data_handle2); @@ -222,7 +223,43 @@ blob_data_handle.reset(); blob_data_handle2.reset(); blob_data_handle3.reset(); - RunEventLoopTillIdle(); + base::RunLoop().RunUntilIdle(); +} + +TEST(BlobStorageContextTest, AddFinishedBlob_LargeOffset) { + // A value which does not fit in a 4-byte data type. Used to confirm that + // large values are supported on 32-bit Chromium builds. Regression test for: + // crbug.com/458122. + const uint64_t kLargeSize = std::numeric_limits<uint64_t>::max(); + + const uint64_t kBlobLength = 5; + const std::string kId1("id1"); + const std::string kId2("id2"); + base::MessageLoop fake_io_message_loop; + + BlobDataBuilder builder1(kId1); + builder1.AppendFileSystemFile(GURL(), 0, kLargeSize, base::Time::Now()); + + BlobDataBuilder builder2(kId2); + builder2.AppendBlob(kId1, kLargeSize - kBlobLength, kBlobLength); + + BlobStorageContext context; + scoped_ptr<BlobDataHandle> blob_data_handle1 = + context.AddFinishedBlob(&builder1); + scoped_ptr<BlobDataHandle> blob_data_handle2 = + context.AddFinishedBlob(&builder2); + + ASSERT_TRUE(blob_data_handle1); + ASSERT_TRUE(blob_data_handle2); + scoped_ptr<BlobDataSnapshot> data = blob_data_handle2->CreateSnapshot(); + ASSERT_EQ(1u, data->items().size()); + const scoped_refptr<BlobDataItem> item = data->items()[0]; + EXPECT_EQ(kLargeSize - kBlobLength, item->offset()); + EXPECT_EQ(kBlobLength, item->length()); + + blob_data_handle1.reset(); + blob_data_handle2.reset(); + base::RunLoop().RunUntilIdle(); } TEST(BlobStorageContextTest, CompoundBlobs) { @@ -276,7 +313,7 @@ EXPECT_EQ(*data, canonicalized_blob_data2); blob_data_handle.reset(); - RunEventLoopTillIdle(); + base::RunLoop().RunUntilIdle(); } TEST(BlobStorageContextTest, PublicBlobUrls) { @@ -297,7 +334,7 @@ EXPECT_EQ(kId, blob_data_handle->uuid()); scoped_ptr<BlobDataSnapshot> data = blob_data_handle->CreateSnapshot(); blob_data_handle.reset(); - RunEventLoopTillIdle(); + base::RunLoop().RunUntilIdle(); // The url registration should keep the blob alive even after // explicit references are dropped. @@ -305,7 +342,7 @@ blob_data_handle = context.GetBlobDataFromPublicURL(kUrl); EXPECT_TRUE(blob_data_handle); blob_data_handle.reset(); - RunEventLoopTillIdle(); + base::RunLoop().RunUntilIdle(); // Finally get rid of the url registration and the blob. EXPECT_TRUE(host.RevokePublicBlobURL(kUrl));
diff --git a/content/browser/frame_host/frame_tree_unittest.cc b/content/browser/frame_host/frame_tree_unittest.cc index ad4fd75..27285fbc 100644 --- a/content/browser/frame_host/frame_tree_unittest.cc +++ b/content/browser/frame_host/frame_tree_unittest.cc
@@ -69,13 +69,9 @@ void RenderFrameHostChanged(RenderFrameHost* old_host, RenderFrameHost* new_host) override { - // TODO(nasko): Re-enable this logging once RenderFrameHostChanged observer - // methods are fixed. See https://crbug.com/450799. - /* if (old_host) - LogWhatHappened("RenderFrameChanged(old)", old_host); - LogWhatHappened("RenderFrameChanged(new)", new_host); - */ + LogWhatHappened("RenderFrameHostChanged(old)", old_host); + LogWhatHappened("RenderFrameHostChanged(new)", new_host); } void RenderFrameDeleted(RenderFrameHost* render_frame_host) override { @@ -213,9 +209,15 @@ // Simulate attaching a series of frames to build the frame tree. main_test_rfh()->OnCreateChildFrame(14, std::string(), SandboxFlags::NONE); - EXPECT_EQ("RenderFrameCreated(14) -> 1: [14: []]", activity.GetLog()); + EXPECT_EQ( + "RenderFrameHostChanged(new)(14) -> 1: []\n" + "RenderFrameCreated(14) -> 1: [14: []]", + activity.GetLog()); main_test_rfh()->OnCreateChildFrame(18, std::string(), SandboxFlags::NONE); - EXPECT_EQ("RenderFrameCreated(18) -> 1: [14: [], 18: []]", activity.GetLog()); + EXPECT_EQ( + "RenderFrameHostChanged(new)(18) -> 1: [14: []]\n" + "RenderFrameCreated(18) -> 1: [14: [], 18: []]", + activity.GetLog()); frame_tree->RemoveFrame(root->child_at(0)); EXPECT_EQ("RenderFrameDeleted(14) -> 1: [18: []]", activity.GetLog()); frame_tree->RemoveFrame(root->child_at(0)); @@ -228,9 +230,15 @@ TreeWalkingWebContentsLogger activity(contents()); main_test_rfh()->OnCreateChildFrame(22, std::string(), SandboxFlags::NONE); - EXPECT_EQ("RenderFrameCreated(22) -> 1: [22: []]", activity.GetLog()); + EXPECT_EQ( + "RenderFrameHostChanged(new)(22) -> 1: []\n" + "RenderFrameCreated(22) -> 1: [22: []]", + activity.GetLog()); main_test_rfh()->OnCreateChildFrame(23, std::string(), SandboxFlags::NONE); - EXPECT_EQ("RenderFrameCreated(23) -> 1: [22: [], 23: []]", activity.GetLog()); + EXPECT_EQ( + "RenderFrameHostChanged(new)(23) -> 1: [22: []]\n" + "RenderFrameCreated(23) -> 1: [22: [], 23: []]", + activity.GetLog()); // Crash the renderer main_test_rfh()->OnMessageReceived(FrameHostMsg_RenderProcessGone(
diff --git a/content/browser/frame_host/navigation_entry_impl.cc b/content/browser/frame_host/navigation_entry_impl.cc index 7e39192..864c7c3 100644 --- a/content/browser/frame_host/navigation_entry_impl.cc +++ b/content/browser/frame_host/navigation_entry_impl.cc
@@ -351,4 +351,8 @@ UMA_HISTOGRAM_MEMORY_KB("Overscroll.ScreenshotSize", screenshot_->size()); } +GURL NavigationEntryImpl::GetHistoryURLForDataURL() const { + return GetBaseURLForDataURL().is_empty() ? GURL() : GetVirtualURL(); +} + } // namespace content
diff --git a/content/browser/frame_host/navigation_entry_impl.h b/content/browser/frame_host/navigation_entry_impl.h index 8fadcb3..c69c978e 100644 --- a/content/browser/frame_host/navigation_entry_impl.h +++ b/content/browser/frame_host/navigation_entry_impl.h
@@ -225,6 +225,9 @@ frame_tree_node_id_ = frame_tree_node_id; } + // Returns the history URL for a data URL to use in Blink. + GURL GetHistoryURLForDataURL() const; + #if defined(OS_ANDROID) base::TimeTicks intent_received_timestamp() const { return intent_received_timestamp_;
diff --git a/content/browser/frame_host/navigation_request.cc b/content/browser/frame_host/navigation_request.cc index 8a599b1..75e61001 100644 --- a/content/browser/frame_host/navigation_request.cc +++ b/content/browser/frame_host/navigation_request.cc
@@ -50,6 +50,13 @@ } // namespace // static +bool NavigationRequest::ShouldMakeNetworkRequest(const GURL& url) { + // Data urls should not make network requests. + // TODO(clamy): same document navigations should not make network requests. + return !url.SchemeIs(url::kDataScheme); +} + +// static scoped_ptr<NavigationRequest> NavigationRequest::CreateBrowserInitiated( FrameTreeNode* frame_tree_node, const NavigationEntryImpl& entry, @@ -90,7 +97,8 @@ CommonNavigationParams(entry.GetURL(), entry.GetReferrer(), entry.GetTransitionType(), navigation_type, !entry.IsViewSourceMode(),ui_timestamp, - report_type), + report_type, entry.GetBaseURLForDataURL(), + entry.GetHistoryURLForDataURL()), BeginNavigationParams(method, headers.ToString(), LoadFlagFromNavigationType(navigation_type), false), @@ -158,13 +166,24 @@ NavigationRequest::~NavigationRequest() { } -void NavigationRequest::BeginNavigation() { +bool NavigationRequest::BeginNavigation() { DCHECK(!loader_); DCHECK(state_ == NOT_STARTED || state_ == WAITING_FOR_RENDERER_RESPONSE); state_ = STARTED; - loader_ = NavigationURLLoader::Create( - frame_tree_node_->navigator()->GetController()->GetBrowserContext(), - frame_tree_node_->frame_tree_node_id(), info_.Pass(), this); + + if (ShouldMakeNetworkRequest(common_params_.url)) { + loader_ = NavigationURLLoader::Create( + frame_tree_node_->navigator()->GetController()->GetBrowserContext(), + frame_tree_node_->frame_tree_node_id(), info_.Pass(), this); + return true; + } + + // There is no need to make a network request for this navigation, so commit + // it immediately. + state_ = RESPONSE_STARTED; + frame_tree_node_->navigator()->CommitNavigation( + frame_tree_node_, nullptr, scoped_ptr<StreamHandle>()); + return false; // TODO(davidben): Fire (and add as necessary) observer methods such as // DidStartProvisionalLoadForFrame for the navigation.
diff --git a/content/browser/frame_host/navigation_request.h b/content/browser/frame_host/navigation_request.h index 948dbd1..56e993d 100644 --- a/content/browser/frame_host/navigation_request.h +++ b/content/browser/frame_host/navigation_request.h
@@ -52,6 +52,10 @@ FAILED, }; + // Helper function to determine if the navigation request to |url| should be + // sent to the network stack. + static bool ShouldMakeNetworkRequest(const GURL& url); + // Creates a request for a browser-intiated navigation. static scoped_ptr<NavigationRequest> CreateBrowserInitiated( FrameTreeNode* frame_tree_node, @@ -70,11 +74,11 @@ ~NavigationRequest() override; - // Called on the UI thread by the Navigator to start the navigation on the IO - // thread. + // Called on the UI thread by the Navigator to start the navigation. Returns + // whether a request was made on the IO thread. // TODO(clamy): see if ResourceRequestBody could be un-refcounted to avoid // threading subtleties. - void BeginNavigation(); + bool BeginNavigation(); const CommonNavigationParams& common_params() const { return common_params_; }
diff --git a/content/browser/frame_host/navigator_impl.cc b/content/browser/frame_host/navigator_impl.cc index 3e78f54..72f9f87 100644 --- a/content/browser/frame_host/navigator_impl.cc +++ b/content/browser/frame_host/navigator_impl.cc
@@ -94,7 +94,8 @@ params->common_params = CommonNavigationParams( entry.GetURL(), entry.GetReferrer(), entry.GetTransitionType(), GetNavigationType(controller->GetBrowserContext(), entry, reload_type), - !entry.IsViewSourceMode(), ui_timestamp, report_type); + !entry.IsViewSourceMode(), ui_timestamp, report_type, + entry.GetBaseURLForDataURL(), entry.GetHistoryURLForDataURL()); params->commit_params = CommitNavigationParams( entry.GetPageState(), entry.GetIsOverridingUserAgent(), navigation_start); params->is_post = entry.GetHasPostData(); @@ -106,10 +107,6 @@ entry.GetBrowserInitiatedPostData()->size()); } - if (!entry.GetBaseURLForDataURL().is_empty()) { - params->base_url_for_data_url = entry.GetBaseURLForDataURL(); - params->history_url_for_data_url = entry.GetVirtualURL(); - } params->should_replace_current_entry = entry.should_replace_entry(); // This is used by the old performance infrastructure to set up DocumentState // associated with the RenderView. @@ -733,19 +730,22 @@ CHECK(base::CommandLine::ForCurrentProcess()->HasSwitch( switches::kEnableBrowserSideNavigation)); + NavigationRequest* navigation_request = + navigation_request_map_.get(frame_tree_node->frame_tree_node_id()); + DCHECK(navigation_request); + DCHECK(response || + !NavigationRequest::ShouldMakeNetworkRequest( + navigation_request->common_params().url)); + // HTTP 204 (No Content) and HTTP 205 (Reset Content) responses should not // commit; they leave the frame showing the previous page. - if (response->head.headers.get() && + if (response && response->head.headers.get() && (response->head.headers->response_code() == 204 || response->head.headers->response_code() == 205)) { CancelNavigation(frame_tree_node); return; } - NavigationRequest* navigation_request = - navigation_request_map_.get(frame_tree_node->frame_tree_node_id()); - DCHECK(navigation_request); - // Select an appropriate renderer to commit the navigation. RenderFrameHostImpl* render_frame_host = frame_tree_node->render_manager()->GetFrameHostForNavigation( @@ -864,12 +864,13 @@ if (!navigation_request) return; - // First start the request on the IO thread. - navigation_request->BeginNavigation(); - - // Then notify the RenderFrameHostManager so it can speculatively create a - // RenderFrameHost (and potentially a new renderer process) in parallel. - frame_tree_node->render_manager()->BeginNavigation(*navigation_request); + // Start the request. + if (navigation_request->BeginNavigation()) { + // If the request was sent to the IO thread, notify the + // RenderFrameHostManager so it can speculatively create a RenderFrameHost + // (and potentially a new renderer process) in parallel. + frame_tree_node->render_manager()->BeginNavigation(*navigation_request); + } } void NavigatorImpl::RecordNavigationMetrics(
diff --git a/content/browser/frame_host/navigator_impl_unittest.cc b/content/browser/frame_host/navigator_impl_unittest.cc index 82a49874..7eb3be69 100644 --- a/content/browser/frame_host/navigator_impl_unittest.cc +++ b/content/browser/frame_host/navigator_impl_unittest.cc
@@ -941,4 +941,50 @@ EXPECT_FALSE(rfhm->IsOnSwappedOutList(rfh1)); } +// PlzNavigate: Verify that data urls are properly handled. +TEST_F(NavigatorTestWithBrowserSideNavigation, DataUrls) { + const GURL kUrl1("http://wikipedia.org/"); + const GURL kUrl2("data:text/html,test"); + + // Navigate to an initial site. + contents()->NavigateAndCommit(kUrl1); + FrameTreeNode* node = main_test_rfh()->frame_tree_node(); + + // Navigate to a data url. + RequestNavigation(node, kUrl2); + NavigationRequest* navigation_request = + GetNavigationRequestForFrameTreeNode(node); + ASSERT_TRUE(navigation_request); + EXPECT_EQ(NavigationRequest::WAITING_FOR_RENDERER_RESPONSE, + navigation_request->state()); + main_test_rfh()->SendBeforeUnloadACK(true); + + // The request should not have been sent to the IO thread but committed + // immediately. + EXPECT_EQ(NavigationRequest::RESPONSE_STARTED, + navigation_request->state()); + EXPECT_FALSE(navigation_request->loader_for_testing()); + TestRenderFrameHost* speculative_rfh = GetSpeculativeRenderFrameHost(node); + ASSERT_TRUE(speculative_rfh); + speculative_rfh->SendNavigate(0, kUrl2); + EXPECT_EQ(main_test_rfh(), speculative_rfh); + + // Go back to the initial site. + contents()->NavigateAndCommit(kUrl1); + + // Do a renderer-initiated navigation to a data url. The request should not be + // sent to the IO thread, nor committed. + TestRenderFrameHost* main_rfh = main_test_rfh(); + main_rfh->SendBeginNavigationWithURL(kUrl2, true); + navigation_request = GetNavigationRequestForFrameTreeNode(node); + ASSERT_TRUE(navigation_request); + EXPECT_EQ(NavigationRequest::RESPONSE_STARTED, + navigation_request->state()); + EXPECT_FALSE(navigation_request->loader_for_testing()); + speculative_rfh = GetSpeculativeRenderFrameHost(node); + ASSERT_TRUE(speculative_rfh); + speculative_rfh->SendNavigate(0, kUrl2); + EXPECT_EQ(main_test_rfh(), speculative_rfh); +} + } // namespace content
diff --git a/content/browser/frame_host/render_frame_host_impl.cc b/content/browser/frame_host/render_frame_host_impl.cc index 38f4192..272aeb2 100644 --- a/content/browser/frame_host/render_frame_host_impl.cc +++ b/content/browser/frame_host/render_frame_host_impl.cc
@@ -21,6 +21,7 @@ #include "content/browser/frame_host/frame_accessibility.h" #include "content/browser/frame_host/frame_tree.h" #include "content/browser/frame_host/frame_tree_node.h" +#include "content/browser/frame_host/navigation_request.h" #include "content/browser/frame_host/navigator.h" #include "content/browser/frame_host/navigator_impl.h" #include "content/browser/frame_host/render_frame_host_delegate.h" @@ -1495,11 +1496,11 @@ ChildProcessSecurityPolicyImpl::GetInstance()->GrantRequestURL( GetProcess()->GetID(), params.common_params.url); if (params.common_params.url.SchemeIs(url::kDataScheme) && - params.base_url_for_data_url.SchemeIs(url::kFileScheme)) { + params.common_params.base_url_for_data_url.SchemeIs(url::kFileScheme)) { // If 'data:' is used, and we have a 'file:' base url, grant access to // local files. ChildProcessSecurityPolicyImpl::GetInstance()->GrantRequestURL( - GetProcess()->GetID(), params.base_url_for_data_url); + GetProcess()->GetID(), params.common_params.base_url_for_data_url); } } @@ -1666,6 +1667,8 @@ scoped_ptr<StreamHandle> body, const CommonNavigationParams& common_params, const CommitNavigationParams& commit_params) { + DCHECK((response && body.get()) || + !NavigationRequest::ShouldMakeNetworkRequest(common_params.url)); // TODO(clamy): Check if we have to add security checks for the browser plugin // guests. @@ -1673,9 +1676,11 @@ // completing a RFH swap or unload handler. SetState(RenderFrameHostImpl::STATE_DEFAULT); + const GURL body_url = body.get() ? body->GetURL() : GURL(); + const ResourceResponseHead head = response ? + response->head : ResourceResponseHead(); Send(new FrameMsg_CommitNavigation( - routing_id_, response->head, body->GetURL(), - common_params, commit_params)); + routing_id_, head, body_url, common_params, commit_params)); // TODO(clamy): Check if we should start the throbber for non javascript urls // here.
diff --git a/content/browser/frame_host/render_frame_host_manager.cc b/content/browser/frame_host/render_frame_host_manager.cc index f9e2bf9..b9328a4 100644 --- a/content/browser/frame_host/render_frame_host_manager.cc +++ b/content/browser/frame_host/render_frame_host_manager.cc
@@ -109,6 +109,14 @@ SetRenderFrameHost(CreateRenderFrameHost(site_instance, view_routing_id, frame_routing_id, flags)); + // Notify the delegate of the creation of the current RenderFrameHost. + // Do this only for subframes, as the main frame case is taken care of by + // WebContentsImpl::Init. + if (!frame_tree_node_->IsMainFrame()) { + delegate_->NotifySwappedFromRenderManager( + nullptr, render_frame_host_.get(), false); + } + // Keep track of renderer processes as they start to shut down or are // crashed/killed. registrar_.Add(this, NOTIFICATION_RENDERER_PROCESS_CLOSED, @@ -224,14 +232,18 @@ // Now that we've created a new renderer, be sure to hide it if it isn't // our primary one. Otherwise, we might crash if we try to call Show() // on it later. - if (dest_render_frame_host != render_frame_host_ && - dest_render_frame_host->GetView()) { - dest_render_frame_host->GetView()->Hide(); + if (dest_render_frame_host != render_frame_host_) { + if (dest_render_frame_host->GetView()) + dest_render_frame_host->GetView()->Hide(); } else { - // Notify here as we won't be calling CommitPending (which does the - // notify). - delegate_->NotifySwappedFromRenderManager( - NULL, render_frame_host_.get(), frame_tree_node_->IsMainFrame()); + // TODO(nasko): This is a very ugly hack. The Chrome extensions process + // manager still uses NotificationService and expects to see a + // RenderViewHost changed notification after WebContents and + // RenderFrameHostManager are completely initialized. This should be + // removed once the process manager moves away from NotificationService. + // See https://crbug.com/462682. + delegate_->NotifyMainFrameSwappedFromRenderManager( + nullptr, render_frame_host_->render_view_host()); } }
diff --git a/content/browser/frame_host/render_frame_host_manager.h b/content/browser/frame_host/render_frame_host_manager.h index 15338be..073908a 100644 --- a/content/browser/frame_host/render_frame_host_manager.h +++ b/content/browser/frame_host/render_frame_host_manager.h
@@ -137,6 +137,11 @@ virtual void NotifySwappedFromRenderManager(RenderFrameHost* old_host, RenderFrameHost* new_host, bool is_main_frame) = 0; + // TODO(nasko): This should be removed once extensions no longer use + // NotificationService. See https://crbug.com/462682. + virtual void NotifyMainFrameSwappedFromRenderManager( + RenderViewHost* old_host, + RenderViewHost* new_host) = 0; virtual NavigationControllerImpl& GetControllerForRenderManager() = 0;
diff --git a/content/browser/gpu/compositor_util.cc b/content/browser/gpu/compositor_util.cc index b949142..18eefc7 100644 --- a/content/browser/gpu/compositor_util.cc +++ b/content/browser/gpu/compositor_util.cc
@@ -316,12 +316,19 @@ bool UseSurfacesEnabled() { #if defined(OS_ANDROID) return false; -#else +#endif + bool enabled = false; +#if (defined(USE_AURA) && !defined(OS_CHROMEOS)) || defined(OS_MACOSX) + enabled = true; +#endif + const base::CommandLine& command_line = *base::CommandLine::ForCurrentProcess(); - return command_line.HasSwitch(switches::kUseSurfaces); -#endif + // Flags override. + enabled |= command_line.HasSwitch(switches::kUseSurfaces); + enabled &= !command_line.HasSwitch(switches::kDisableSurfaces); + return enabled; } int GpuRasterizationMSAASampleCount() {
diff --git a/content/browser/loader/cross_site_resource_handler.cc b/content/browser/loader/cross_site_resource_handler.cc index 44d24ce..ccdd321 100644 --- a/content/browser/loader/cross_site_resource_handler.cc +++ b/content/browser/loader/cross_site_resource_handler.cc
@@ -68,6 +68,13 @@ RenderFrameHostImpl::FromID(params.global_request_id.child_id, params.render_frame_id); if (rfh) { + if (rfh->GetParent()) { + // We should only swap processes for subframes in --site-per-process mode. + // CrossSiteResourceHandler is not installed on subframe requests in + // default Chrome. + CHECK(base::CommandLine::ForCurrentProcess()->HasSwitch( + switches::kSitePerProcess)); + } rfh->OnCrossSiteResponse( params.global_request_id, cross_site_transferring_request.Pass(), params.transfer_url_chain, params.referrer,
diff --git a/content/browser/loader/resource_dispatcher_host_impl.cc b/content/browser/loader/resource_dispatcher_host_impl.cc index 19eb7560..e539eaa 100644 --- a/content/browser/loader/resource_dispatcher_host_impl.cc +++ b/content/browser/loader/resource_dispatcher_host_impl.cc
@@ -2149,6 +2149,10 @@ // thread where they can be passed along to the respective RVHs. scoped_ptr<LoadInfoMap> info_map(new LoadInfoMap()); + tracked_objects::ScopedTracker tracking_profile0( + FROM_HERE_WITH_EXPLICIT_FUNCTION( + "455952 ResourceDispatcherHostImpl::GetLoadInfoForAllRoutes0")); + for (const auto& loader : pending_loaders_) { // Also poll for upload progress on this timer and send upload progress ipc // messages to the plugin process. @@ -2220,6 +2224,10 @@ if (info_map->empty()) return; + tracked_objects::ScopedTracker tracking_profile2( + FROM_HERE_WITH_EXPLICIT_FUNCTION( + "455952 ResourceDispatcherHostImpl::UpdateLoadInfo2")); + BrowserThread::PostTask( BrowserThread::UI, FROM_HERE, base::Bind(&ResourceDispatcherHostImpl::UpdateLoadInfoOnUIThread,
diff --git a/content/browser/media/android/browser_media_player_manager.cc b/content/browser/media/android/browser_media_player_manager.cc index 5fecd39..8600a75 100644 --- a/content/browser/media/android/browser_media_player_manager.cc +++ b/content/browser/media/android/browser_media_player_manager.cc
@@ -7,6 +7,7 @@ #include "base/android/scoped_java_ref.h" #include "base/command_line.h" #include "content/browser/android/content_view_core_impl.h" +#include "content/browser/android/media_players_observer.h" #include "content/browser/media/android/browser_demuxer_android.h" #include "content/browser/media/android/media_resource_getter_impl.h" #include "content/browser/renderer_host/render_view_host_impl.h" @@ -57,10 +58,11 @@ // static BrowserMediaPlayerManager* BrowserMediaPlayerManager::Create( - RenderFrameHost* rfh) { + RenderFrameHost* rfh, + MediaPlayersObserver* audio_monitor) { if (g_factory) - return g_factory(rfh); - return new BrowserMediaPlayerManager(rfh); + return g_factory(rfh, audio_monitor); + return new BrowserMediaPlayerManager(rfh, audio_monitor); } ContentViewCoreImpl* BrowserMediaPlayerManager::GetContentViewCore() const { @@ -121,8 +123,10 @@ } BrowserMediaPlayerManager::BrowserMediaPlayerManager( - RenderFrameHost* render_frame_host) + RenderFrameHost* render_frame_host, + MediaPlayersObserver* audio_monitor) : render_frame_host_(render_frame_host), + audio_monitor_(audio_monitor), fullscreen_player_id_(kInvalidMediaPlayerId), fullscreen_player_is_released_(false), web_contents_(WebContents::FromRenderFrameHost(render_frame_host)), @@ -254,6 +258,12 @@ video_view_->OnVideoSizeChanged(width, height); } +void BrowserMediaPlayerManager::OnAudibleStateChanged( + int player_id, bool is_audible) { + audio_monitor_->OnAudibleStateChanged( + render_frame_host_, player_id, is_audible); +} + media::MediaResourceGetter* BrowserMediaPlayerManager::GetMediaResourceGetter() { if (!media_resource_getter_.get()) { @@ -518,6 +528,7 @@ if ((*it)->player_id() == player_id) { ReleaseMediaResources(player_id); players_.erase(it); + audio_monitor_->RemovePlayer(render_frame_host_, player_id); break; } }
diff --git a/content/browser/media/android/browser_media_player_manager.h b/content/browser/media/android/browser_media_player_manager.h index e0a40132..bec4695 100644 --- a/content/browser/media/android/browser_media_player_manager.h +++ b/content/browser/media/android/browser_media_player_manager.h
@@ -30,6 +30,7 @@ class BrowserDemuxerAndroid; class ContentViewCoreImpl; class ExternalVideoSurfaceContainer; +class MediaPlayersObserver; class RenderFrameHost; class WebContents; @@ -42,7 +43,8 @@ : public media::MediaPlayerManager { public: // Permits embedders to provide an extended version of the class. - typedef BrowserMediaPlayerManager* (*Factory)(RenderFrameHost*); + typedef BrowserMediaPlayerManager* (*Factory)(RenderFrameHost*, + MediaPlayersObserver*); static void RegisterFactory(Factory factory); // Permits embedders to handle custom urls. @@ -50,7 +52,9 @@ media::MediaUrlInterceptor* media_url_interceptor); // Returns a new instance using the registered factory if available. - static BrowserMediaPlayerManager* Create(RenderFrameHost* rfh); + static BrowserMediaPlayerManager* Create( + RenderFrameHost* rfh, + MediaPlayersObserver* audio_monitor); ContentViewCoreImpl* GetContentViewCore() const; @@ -83,6 +87,9 @@ const base::TimeDelta& current_time) override; void OnError(int player_id, int error) override; void OnVideoSizeChanged(int player_id, int width, int height) override; + void OnAudibleStateChanged( + int player_id, bool is_audible_now) override; + media::MediaResourceGetter* GetMediaResourceGetter() override; media::MediaUrlInterceptor* GetMediaUrlInterceptor() override; media::MediaPlayerAndroid* GetFullscreenPlayer() override; @@ -118,7 +125,8 @@ protected: // Clients must use Create() or subclass constructor. - explicit BrowserMediaPlayerManager(RenderFrameHost* render_frame_host); + BrowserMediaPlayerManager(RenderFrameHost* render_frame_host, + MediaPlayersObserver* audio_monitor); WebContents* web_contents() const { return web_contents_; } @@ -168,6 +176,8 @@ RenderFrameHost* const render_frame_host_; + MediaPlayersObserver* audio_monitor_; + // An array of managed players. ScopedVector<media::MediaPlayerAndroid> players_;
diff --git a/content/browser/media/audio_state_provider.cc b/content/browser/media/audio_state_provider.cc new file mode 100644 index 0000000..e09356a --- /dev/null +++ b/content/browser/media/audio_state_provider.cc
@@ -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 "content/browser/media/audio_state_provider.h" + +#include "base/logging.h" +#include "content/browser/media/audio_stream_monitor.h" +#include "content/public/browser/web_contents.h" + +namespace content { + +AudioStateProvider::AudioStateProvider(WebContents* contents) + : web_contents_(contents), + was_recently_audible_(false) { + DCHECK(web_contents_); +} + +bool AudioStateProvider::WasRecentlyAudible() const { + return was_recently_audible_; +} + +void AudioStateProvider::Notify(bool new_state) { + if (was_recently_audible_ != new_state) { + was_recently_audible_ = new_state; + web_contents_->NotifyNavigationStateChanged(INVALIDATE_TYPE_TAB); + } +} + +} // namespace content
diff --git a/content/browser/media/audio_state_provider.h b/content/browser/media/audio_state_provider.h new file mode 100644 index 0000000..5bd1b718 --- /dev/null +++ b/content/browser/media/audio_state_provider.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 CONTENT_BROWSER_MEDIA_AUDIO_STATE_PROVIDER_H_ +#define CONTENT_BROWSER_MEDIA_AUDIO_STATE_PROVIDER_H_ + +#include "content/common/content_export.h" + +namespace content { +class WebContents; +class AudioStreamMonitor; + +// This class is associated with a WebContents, and maintains the audible +// state regarding all the players in it. +// The audible state is true if at least one player is playing a sound. +// Whenever the audible state of the WebContents as a whole changes, this +// class sends a notification to it. +// +// Each WebContentsImpl owns an AudioStateProvider +class CONTENT_EXPORT AudioStateProvider { + public: + explicit AudioStateProvider(WebContents* web_contents); + virtual ~AudioStateProvider() {} + + // Indicates whether this service is available on the system. + virtual bool IsAudioStateAvailable() const = 0; + + // If this provider uses monitoring (i.e. measure the signal), + // return its monitor. + virtual AudioStreamMonitor* audio_stream_monitor() = 0; + + // Returns true if the WebContents is playing or has recently been + // playing the sound. + virtual bool WasRecentlyAudible() const; + + void set_was_recently_audible_for_testing(bool value) { + was_recently_audible_ = value; + } + + protected: + // Notify WebContents that the audio state has changed. + void Notify(bool new_state); + + // The WebContents instance instance to receive indicator toggle + // notifications. This pointer should be valid for the lifetime of + // AudioStreamMonitor. + WebContents* const web_contents_; + + // The audio state that is being maintained + bool was_recently_audible_; + +}; + +} // namespace content + +#endif // CONTENT_BROWSER_MEDIA_AUDIO_STATE_PROVIDER_H_
diff --git a/content/browser/media/audio_stream_monitor.cc b/content/browser/media/audio_stream_monitor.cc index 1d2f76f7..4c0bc0a 100644 --- a/content/browser/media/audio_stream_monitor.cc +++ b/content/browser/media/audio_stream_monitor.cc
@@ -21,23 +21,36 @@ WebContentsImpl* const web_contents = static_cast<WebContentsImpl*>(WebContents::FromRenderFrameHost( RenderFrameHost::FromID(render_process_id, render_frame_id))); - return web_contents ? web_contents->audio_stream_monitor() : NULL; + + if (!web_contents) + return nullptr; + + AudioStateProvider* audio_provider = web_contents->audio_state_provider(); + return audio_provider ? audio_provider->audio_stream_monitor() : nullptr; } } // namespace AudioStreamMonitor::AudioStreamMonitor(WebContents* contents) - : web_contents_(contents), - clock_(&default_tick_clock_), - was_recently_audible_(false) { - DCHECK(web_contents_); + : AudioStateProvider(contents), + clock_(&default_tick_clock_) +{ } AudioStreamMonitor::~AudioStreamMonitor() {} +bool AudioStreamMonitor::IsAudioStateAvailable() const { + return media::AudioOutputController::will_monitor_audio_levels(); +} + +// This provider is the monitor. +AudioStreamMonitor* AudioStreamMonitor::audio_stream_monitor() { + return this; +} + bool AudioStreamMonitor::WasRecentlyAudible() const { DCHECK(thread_checker_.CalledOnValidThread()); - return was_recently_audible_; + return AudioStateProvider::WasRecentlyAudible(); } // static @@ -46,7 +59,7 @@ int render_frame_id, int stream_id, const ReadPowerAndClipCallback& read_power_callback) { - if (!monitoring_available()) + if (!media::AudioOutputController::will_monitor_audio_levels()) return; BrowserThread::PostTask(BrowserThread::UI, FROM_HERE, @@ -61,7 +74,7 @@ void AudioStreamMonitor::StopMonitoringStream(int render_process_id, int render_frame_id, int stream_id) { - if (!monitoring_available()) + if (!media::AudioOutputController::will_monitor_audio_levels()) return; BrowserThread::PostTask(BrowserThread::UI, FROM_HERE, @@ -138,16 +151,12 @@ } void AudioStreamMonitor::MaybeToggle() { - const bool indicator_was_on = was_recently_audible_; const base::TimeTicks off_time = last_blurt_time_ + base::TimeDelta::FromMilliseconds(kHoldOnMilliseconds); const base::TimeTicks now = clock_->NowTicks(); const bool should_indicator_be_on = now < off_time; - if (should_indicator_be_on != indicator_was_on) { - was_recently_audible_ = should_indicator_be_on; - web_contents_->NotifyNavigationStateChanged(INVALIDATE_TYPE_TAB); - } + Notify(should_indicator_be_on); if (!should_indicator_be_on) { off_timer_.Stop();
diff --git a/content/browser/media/audio_stream_monitor.h b/content/browser/media/audio_stream_monitor.h index d1a32d5..b3cbf16 100644 --- a/content/browser/media/audio_stream_monitor.h +++ b/content/browser/media/audio_stream_monitor.h
@@ -14,6 +14,7 @@ #include "base/time/time.h" #include "base/timer/timer.h" #include "build/build_config.h" +#include "content/browser/media/audio_state_provider.h" #include "content/common/content_export.h" #include "media/audio/audio_output_controller.h" @@ -22,7 +23,6 @@ } namespace content { -class WebContents; // Repeatedly polls audio streams for their power levels, and "debounces" the // information into a simple, binary "was recently audible" result for the audio @@ -32,23 +32,23 @@ // to turn on/off repeatedly and annoy the user. AudioStreamMonitor sends UI // update notifications only when needed, but may be queried at any time. // -// Each WebContentsImpl owns an AudioStreamMonitor. -class CONTENT_EXPORT AudioStreamMonitor { +class CONTENT_EXPORT AudioStreamMonitor : public AudioStateProvider { public: explicit AudioStreamMonitor(WebContents* contents); - ~AudioStreamMonitor(); + ~AudioStreamMonitor() override; // Indicates if audio stream monitoring is available. It's only available if // AudioOutputController can and will monitor output power levels. - static bool monitoring_available() { - return media::AudioOutputController::will_monitor_audio_levels(); - } + bool IsAudioStateAvailable() const override; + + // This provider is a monitor, the method returns |this|. + AudioStreamMonitor* audio_stream_monitor() override; // Returns true if audio has recently been audible from the tab. This is // usually called whenever the tab data model is refreshed; but there are // other use cases as well (e.g., the OOM killer uses this to de-prioritize // the killing of tabs making sounds). - bool WasRecentlyAudible() const; + bool WasRecentlyAudible() const override; // Starts or stops audio level monitoring respectively for the stream owned by // the specified renderer. Safe to call from any thread. @@ -66,10 +66,6 @@ int render_frame_id, int stream_id); - void set_was_recently_audible_for_testing(bool value) { - was_recently_audible_ = value; - } - private: friend class AudioStreamMonitorTest; @@ -112,11 +108,6 @@ // on, |off_timer_| is started to re-invoke this method in the future. void MaybeToggle(); - // The WebContents instance instance to receive indicator toggle - // notifications. This pointer should be valid for the lifetime of - // AudioStreamMonitor. - WebContents* const web_contents_; - // Note: |clock_| is always |&default_tick_clock_|, except during unit // testing. base::DefaultTickClock default_tick_clock_; @@ -134,10 +125,6 @@ // Records the last time at which sound was audible from any stream. base::TimeTicks last_blurt_time_; - // Set to true if the last call to MaybeToggle() determined the indicator - // should be turned on. - bool was_recently_audible_; - // Calls Poll() at regular intervals while |poll_callbacks_| is non-empty. base::RepeatingTimer<AudioStreamMonitor> poll_timer_;
diff --git a/content/browser/media/audio_stream_monitor_unittest.cc b/content/browser/media/audio_stream_monitor_unittest.cc index 0d206216..0607b75 100644 --- a/content/browser/media/audio_stream_monitor_unittest.cc +++ b/content/browser/media/audio_stream_monitor_unittest.cc
@@ -52,7 +52,13 @@ WebContentsImpl* web_contents = reinterpret_cast<WebContentsImpl*>( RenderViewHostTestHarness::web_contents()); web_contents->SetDelegate(&mock_web_contents_delegate_); - monitor_ = web_contents->audio_stream_monitor(); + + AudioStateProvider* provider = web_contents->audio_state_provider(); + ASSERT_TRUE(provider); + + monitor_ = provider->audio_stream_monitor(); + ASSERT_TRUE(monitor_); + const_cast<base::TickClock*&>(monitor_->clock_) = &clock_; }
diff --git a/content/browser/media/media_web_contents_observer.cc b/content/browser/media/media_web_contents_observer.cc index cc90b55e..f87cfb1 100644 --- a/content/browser/media/media_web_contents_observer.cc +++ b/content/browser/media/media_web_contents_observer.cc
@@ -8,11 +8,13 @@ #include "base/stl_util.h" #include "content/browser/media/cdm/browser_cdm_manager.h" #include "content/browser/renderer_host/render_process_host_impl.h" +#include "content/browser/web_contents/web_contents_impl.h" #include "content/public/browser/render_frame_host.h" #include "content/public/browser/web_contents.h" #include "ipc/ipc_message_macros.h" #if defined(OS_ANDROID) +#include "content/browser/android/media_players_observer.h" #include "content/browser/media/android/browser_media_player_manager.h" #include "content/common/media/media_player_messages_android.h" #include "media/base/android/media_player_android.h" @@ -22,7 +24,8 @@ MediaWebContentsObserver::MediaWebContentsObserver( WebContents* web_contents) - : WebContentsObserver(web_contents) { + : WebContentsObserver(web_contents) +{ } MediaWebContentsObserver::~MediaWebContentsObserver() { @@ -35,6 +38,10 @@ // Always destroy the media players before CDMs because we do not support // detaching CDMs from media players yet. See http://crbug.com/330324 media_player_managers_.erase(key); + + MediaPlayersObserver* audio_observer = GetMediaPlayersObserver(); + if (audio_observer) + audio_observer->RenderFrameDeleted(render_frame_host); #endif // TODO(xhwang): Currently MediaWebContentsObserver, BrowserMediaPlayerManager // and BrowserCdmManager all run on browser UI thread. So this call is okay. @@ -161,11 +168,24 @@ if (!media_player_managers_.contains(key)) { media_player_managers_.set( key, - make_scoped_ptr(BrowserMediaPlayerManager::Create(render_frame_host))); + make_scoped_ptr(BrowserMediaPlayerManager::Create( + render_frame_host, GetMediaPlayersObserver()))); } return media_player_managers_.get(key); } +MediaPlayersObserver* +MediaWebContentsObserver::GetMediaPlayersObserver() const { + AudioStateProvider* provider = + static_cast<WebContentsImpl*>(web_contents())->audio_state_provider(); + + MediaPlayersObserver* audio_observer = + static_cast<MediaPlayersObserver*>(provider); + + DCHECK(audio_observer); + return audio_observer; +} + #if defined(VIDEO_HOLE) void MediaWebContentsObserver::OnFrameInfoUpdated() { for (MediaPlayerManagerMap::iterator iter = media_player_managers_.begin();
diff --git a/content/browser/media/media_web_contents_observer.h b/content/browser/media/media_web_contents_observer.h index 3b451a8..2eb08c1 100644 --- a/content/browser/media/media_web_contents_observer.h +++ b/content/browser/media/media_web_contents_observer.h
@@ -7,11 +7,16 @@ #include "base/compiler_specific.h" #include "base/containers/scoped_ptr_hash_map.h" +#include "base/memory/scoped_ptr.h" #include "content/common/content_export.h" #include "content/public/browser/web_contents_observer.h" namespace content { +#if defined(OS_ANDROID) +class MediaPlayersObserver; +#endif // defined(OS_ANDROID) + class BrowserCdmManager; class BrowserMediaPlayerManager; @@ -45,6 +50,8 @@ void OnSetCdm(RenderFrameHost* render_frame_host, int player_id, int cdm_id); + MediaPlayersObserver* GetMediaPlayersObserver() const; + #if defined(VIDEO_HOLE) void OnFrameInfoUpdated(); #endif // defined(VIDEO_HOLE)
diff --git a/content/browser/media/webrtc_browsertest.cc b/content/browser/media/webrtc_browsertest.cc index fc613c84..cdd5cb9 100644 --- a/content/browser/media/webrtc_browsertest.cc +++ b/content/browser/media/webrtc_browsertest.cc
@@ -371,9 +371,7 @@ // MediaStream that has been created based on a MediaStream created with // getUserMedia. When video is flowing, the VideoTrack is removed and an // AudioTrack is added instead. -// TODO(phoglund): This test is manual since not all buildbots has an audio -// input. -IN_PROC_BROWSER_TEST_F(MAYBE_WebRtcBrowserTest, MANUAL_CallAndModifyStream) { +IN_PROC_BROWSER_TEST_F(MAYBE_WebRtcBrowserTest, CallAndModifyStream) { MakeTypicalPeerConnectionCall( "callWithNewVideoMediaStreamLaterSwitchToAudio();"); }
diff --git a/content/browser/renderer_host/render_widget_host_latency_tracker.cc b/content/browser/renderer_host/render_widget_host_latency_tracker.cc index 9cbd986..8de5512 100644 --- a/content/browser/renderer_host/render_widget_host_latency_tracker.cc +++ b/content/browser/renderer_host/render_widget_host_latency_tracker.cc
@@ -150,10 +150,10 @@ 1, 50000, 50) void ComputeScrollLatencyHistograms( - const LatencyInfo::LatencyComponent& swap_component, + const LatencyInfo::LatencyComponent& gpu_swap_component, int64 latency_component_id, - const ui::LatencyInfo& latency) { - DCHECK(!swap_component.event_time.is_null()); + const LatencyInfo& latency) { + DCHECK(!gpu_swap_component.event_time.is_null()); LatencyInfo::LatencyComponent first_original_component, original_component; if (latency.FindLatency( ui::INPUT_EVENT_LATENCY_FIRST_SCROLL_UPDATE_ORIGINAL_COMPONENT, @@ -164,7 +164,7 @@ for (size_t i = 0; i < first_original_component.event_count; i++) { UMA_HISTOGRAM_CUSTOM_COUNTS( "Event.Latency.TouchToFirstScrollUpdateSwap", - (swap_component.event_time - first_original_component.event_time) + (gpu_swap_component.event_time - first_original_component.event_time) .InMicroseconds(), 1, 1000000, 100); } @@ -181,7 +181,7 @@ for (size_t i = 0; i < original_component.event_count; i++) { UMA_HISTOGRAM_CUSTOM_COUNTS( "Event.Latency.TouchToScrollUpdateSwap", - (swap_component.event_time - original_component.event_time) + (gpu_swap_component.event_time - original_component.event_time) .InMicroseconds(), 1, 1000000, 100); } @@ -235,17 +235,19 @@ "Event.Latency.ScrollUpdate.RendererSwapToBrowserNotified", renderer_swap_component, browser_received_swap_component); - LatencyInfo::LatencyComponent gpu_swap_component; - if (!latency.FindLatency(ui::INPUT_EVENT_GPU_SWAP_BUFFER_COMPONENT, - 0, &gpu_swap_component)) - return; - UMA_HISTOGRAM_SCROLL_LATENCY_LONG( "Event.Latency.ScrollUpdate.BrowserNotifiedToBeforeGpuSwap", browser_received_swap_component, gpu_swap_component); + LatencyInfo::LatencyComponent gpu_swap_ack_component; + if (!latency.FindLatency( + ui::INPUT_EVENT_LATENCY_TERMINATED_FRAME_SWAP_COMPONENT, 0, + &gpu_swap_ack_component)) + return; + UMA_HISTOGRAM_SCROLL_LATENCY_SHORT("Event.Latency.ScrollUpdate.GpuSwap", - gpu_swap_component, swap_component); + gpu_swap_component, + gpu_swap_ack_component); } // LatencyComponents generated in the renderer must have component IDs @@ -389,11 +391,10 @@ } void RenderWidgetHostLatencyTracker::OnFrameSwapped( - const ui::LatencyInfo& latency) { - LatencyInfo::LatencyComponent swap_component; - if (!latency.FindLatency( - ui::INPUT_EVENT_LATENCY_TERMINATED_FRAME_SWAP_COMPONENT, 0, - &swap_component)) { + const LatencyInfo& latency) { + LatencyInfo::LatencyComponent gpu_swap_component; + if (!latency.FindLatency(ui::INPUT_EVENT_GPU_SWAP_BUFFER_COMPONENT, 0, + &gpu_swap_component)) { return; } @@ -401,28 +402,21 @@ if (latency.FindLatency(ui::TAB_SHOW_COMPONENT, latency_component_id_, &tab_switch_component)) { base::TimeDelta delta = - swap_component.event_time - tab_switch_component.event_time; + gpu_swap_component.event_time - tab_switch_component.event_time; for (size_t i = 0; i < tab_switch_component.event_count; i++) { UMA_HISTOGRAM_TIMES("MPArch.RWH_TabSwitchPaintDuration", delta); } } - LatencyInfo::LatencyComponent rwh_component; if (!latency.FindLatency(ui::INPUT_EVENT_LATENCY_BEGIN_RWH_COMPONENT, - latency_component_id_, &rwh_component)) { + latency_component_id_, nullptr)) { return; } - ComputeScrollLatencyHistograms(swap_component, latency_component_id_, + ComputeScrollLatencyHistograms(gpu_swap_component, latency_component_id_, latency); - ui::LatencyInfo::LatencyComponent gpu_swap_component; - if (!latency.FindLatency(ui::INPUT_EVENT_GPU_SWAP_BUFFER_COMPONENT, 0, - &gpu_swap_component)) { - return; - } - - ui::LatencyInfo::LatencyComponent browser_swap_component; + LatencyInfo::LatencyComponent browser_swap_component; if (latency.FindLatency( ui::INPUT_EVENT_BROWSER_RECEIVED_RENDERER_SWAP_COMPONENT, 0, &browser_swap_component)) {
diff --git a/content/browser/service_worker/service_worker_version.cc b/content/browser/service_worker/service_worker_version.cc index 747319e..d6468fd 100644 --- a/content/browser/service_worker/service_worker_version.cc +++ b/content/browser/service_worker/service_worker_version.cc
@@ -426,22 +426,6 @@ context_->UpdateServiceWorker(registration); } -void ServiceWorkerVersion::SendMessage( - const IPC::Message& message, const StatusCallback& callback) { - if (running_status() != RUNNING) { - // Schedule calling this method after starting the worker. - StartWorker(base::Bind(&RunTaskAfterStartWorker, - weak_factory_.GetWeakPtr(), callback, - base::Bind(&self::SendMessage, - weak_factory_.GetWeakPtr(), - message, callback))); - return; - } - - ServiceWorkerStatusCode status = embedded_worker_->SendMessage(message); - RunSoon(base::Bind(callback, status)); -} - void ServiceWorkerVersion::DispatchMessageEvent( const base::string16& message, const std::vector<TransferredMessagePort>& sent_message_ports,
diff --git a/content/browser/service_worker/service_worker_version.h b/content/browser/service_worker/service_worker_version.h index 2aeaabb..220c67a 100644 --- a/content/browser/service_worker/service_worker_version.h +++ b/content/browser/service_worker/service_worker_version.h
@@ -166,13 +166,6 @@ // Starts an update now. void StartUpdate(); - // Sends an IPC message to the worker. - // If the worker is not running this first tries to start it by - // calling StartWorker internally. - // |callback| can be null if the sender does not need to know if the - // message is successfully sent or not. - void SendMessage(const IPC::Message& message, const StatusCallback& callback); - // Sends a message event to the associated embedded worker. void DispatchMessageEvent( const base::string16& message,
diff --git a/content/browser/service_worker/service_worker_version_unittest.cc b/content/browser/service_worker/service_worker_version_unittest.cc index 7cf16e2d..bdcea477 100644 --- a/content/browser/service_worker/service_worker_version_unittest.cc +++ b/content/browser/service_worker/service_worker_version_unittest.cc
@@ -250,31 +250,31 @@ EXPECT_EQ(SERVICE_WORKER_OK, status3); } -TEST_F(ServiceWorkerVersionTest, SendMessage) { +TEST_F(ServiceWorkerVersionTest, DispatchEventToStoppedWorker) { EXPECT_EQ(ServiceWorkerVersion::STOPPED, version_->running_status()); - // Send a message without starting the worker. + // Dispatch an event without starting the worker. ServiceWorkerStatusCode status = SERVICE_WORKER_ERROR_FAILED; - version_->SendMessage(TestMsg_Message(), - CreateReceiverOnCurrentThread(&status)); + version_->SetStatus(ServiceWorkerVersion::INSTALLING); + version_->DispatchInstallEvent(-1, CreateReceiverOnCurrentThread(&status)); base::RunLoop().RunUntilIdle(); EXPECT_EQ(SERVICE_WORKER_OK, status); // The worker should be now started. EXPECT_EQ(ServiceWorkerVersion::RUNNING, version_->running_status()); - // Stop the worker, and then send the message immediately. - ServiceWorkerStatusCode msg_status = SERVICE_WORKER_ERROR_FAILED; + // Stop the worker, and then dispatch an event immediately after that. + status = SERVICE_WORKER_ERROR_FAILED; ServiceWorkerStatusCode stop_status = SERVICE_WORKER_ERROR_FAILED; version_->StopWorker(CreateReceiverOnCurrentThread(&stop_status)); - version_->SendMessage(TestMsg_Message(), - CreateReceiverOnCurrentThread(&msg_status)); + version_->DispatchInstallEvent( + -1, CreateReceiverOnCurrentThread(&status)); base::RunLoop().RunUntilIdle(); EXPECT_EQ(SERVICE_WORKER_OK, stop_status); - // SendMessage should return SERVICE_WORKER_OK since the worker should have - // been restarted to deliver the message. - EXPECT_EQ(SERVICE_WORKER_OK, msg_status); + // Dispatch an event should return SERVICE_WORKER_OK since the worker + // should have been restarted to dispatch the event. + EXPECT_EQ(SERVICE_WORKER_OK, status); // The worker should be now started again. EXPECT_EQ(ServiceWorkerVersion::RUNNING, version_->running_status());
diff --git a/content/browser/speech/speech_recognition_browsertest.cc b/content/browser/speech/speech_recognition_browsertest.cc index 62b22ad23..8bc0749f 100644 --- a/content/browser/speech/speech_recognition_browsertest.cc +++ b/content/browser/speech/speech_recognition_browsertest.cc
@@ -94,7 +94,7 @@ } std::string GetPageFragment() { - return shell()->web_contents()->GetURL().ref(); + return shell()->web_contents()->GetLastCommittedURL().ref(); } const StreamingServerState &streaming_server_state() {
diff --git a/content/browser/web_contents/web_contents_impl.cc b/content/browser/web_contents/web_contents_impl.cc index ede1642..5d51ed1 100644 --- a/content/browser/web_contents/web_contents_impl.cc +++ b/content/browser/web_contents/web_contents_impl.cc
@@ -108,6 +108,7 @@ #if defined(OS_ANDROID) #include "content/browser/android/content_video_view.h" #include "content/browser/android/date_time_chooser_android.h" +#include "content/browser/android/media_players_observer.h" #include "content/browser/media/android/browser_media_player_manager.h" #include "content/browser/web_contents/web_contents_android.h" #endif @@ -358,7 +359,6 @@ geolocation_service_context_(new GeolocationServiceContext()), accessibility_mode_( BrowserAccessibilityStateImpl::GetInstance()->accessibility_mode()), - audio_stream_monitor_(this), virtual_keyboard_requested_(false), loading_weak_factory_(this) { frame_tree_.SetFrameRemoveListener( @@ -367,6 +367,12 @@ #if defined(ENABLE_BROWSER_CDMS) media_web_contents_observer_.reset(new MediaWebContentsObserver(this)); #endif + +#if defined(OS_ANDROID) + audio_state_provider_.reset(new MediaPlayersObserver(this)); +#else + audio_state_provider_.reset(new AudioStreamMonitor(this)); +#endif } WebContentsImpl::~WebContentsImpl() { @@ -1041,7 +1047,7 @@ // Create and release the audio power save blocker depending on whether the // tab is actively producing audio or not. if ((changed_flags & INVALIDATE_TYPE_TAB) && - AudioStreamMonitor::monitoring_available()) { + audio_state_provider_->IsAudioStateAvailable()) { if (WasRecentlyAudible()) { if (!audio_power_save_blocker_) CreateAudioPowerSaveBlocker(); @@ -1272,6 +1278,13 @@ RenderViewCreated(GetRenderViewHost()); GetRenderManager()->current_frame_host()->SetRenderFrameCreated(true); } + + // Ensure that observers are notified of the creation of this WebContents's + // main RenderFrameHost. It must be done here for main frames, since the + // NotifySwappedFromRenderManager expects view_ to already be created and that + // happens after RenderFrameHostManager::Init. + NotifySwappedFromRenderManager( + nullptr, GetRenderManager()->current_frame_host(), true); } void WebContentsImpl::OnWebContentsDestroyed(WebContentsImpl* web_contents) { @@ -2516,7 +2529,7 @@ } bool WebContentsImpl::WasRecentlyAudible() { - return audio_stream_monitor_.WasRecentlyAudible(); + return audio_state_provider_->WasRecentlyAudible(); } void WebContentsImpl::GetManifest(const GetManifestCallback& callback) { @@ -3203,7 +3216,7 @@ // monitoring, release the audio power save blocker here instead of during // NotifyNavigationStateChanged(). if (active_audio_players_.empty() && - !AudioStreamMonitor::monitoring_available()) { + !audio_state_provider_->IsAudioStateAvailable()) { audio_power_save_blocker_.reset(); } @@ -3226,7 +3239,7 @@ // If we don't have audio stream monitoring, allocate the audio power save // blocker here instead of during NotifyNavigationStateChanged(). if (!audio_power_save_blocker_ && - !AudioStreamMonitor::monitoring_available()) { + !audio_state_provider_->IsAudioStateAvailable()) { CreateAudioPowerSaveBlocker(); } } @@ -4184,7 +4197,7 @@ RenderFrameHost* new_host, bool is_main_frame) { if (is_main_frame) { - NotifyViewSwapped(old_host ? old_host->GetRenderViewHost() : NULL, + NotifyViewSwapped(old_host ? old_host->GetRenderViewHost() : nullptr, new_host->GetRenderViewHost()); // Make sure the visible RVH reflects the new delegate's preferences. @@ -4197,6 +4210,12 @@ NotifyFrameSwapped(old_host, new_host); } +void WebContentsImpl::NotifyMainFrameSwappedFromRenderManager( + RenderViewHost* old_host, + RenderViewHost* new_host) { + NotifyViewSwapped(old_host, new_host); +} + int WebContentsImpl::CreateOpenerRenderViewsForRenderManager( SiteInstance* instance) { if (!opener_)
diff --git a/content/browser/web_contents/web_contents_impl.h b/content/browser/web_contents/web_contents_impl.h index ae57bea4..2e0e9661 100644 --- a/content/browser/web_contents/web_contents_impl.h +++ b/content/browser/web_contents/web_contents_impl.h
@@ -22,7 +22,7 @@ #include "content/browser/frame_host/navigator_delegate.h" #include "content/browser/frame_host/render_frame_host_delegate.h" #include "content/browser/frame_host/render_frame_host_manager.h" -#include "content/browser/media/audio_stream_monitor.h" +#include "content/browser/media/audio_state_provider.h" #include "content/browser/renderer_host/render_view_host_delegate.h" #include "content/browser/renderer_host/render_widget_host_delegate.h" #include "content/common/accessibility_mode_enums.h" @@ -568,6 +568,9 @@ void NotifySwappedFromRenderManager(RenderFrameHost* old_host, RenderFrameHost* new_host, bool is_main_frame) override; + void NotifyMainFrameSwappedFromRenderManager( + RenderViewHost* old_host, + RenderViewHost* new_host) override; int CreateOpenerRenderViewsForRenderManager(SiteInstance* instance) override; NavigationControllerImpl& GetControllerForRenderManager() override; scoped_ptr<WebUIImpl> CreateWebUIForRenderManager(const GURL& url) override; @@ -666,8 +669,8 @@ // Forces overscroll to be disabled (used by touch emulation). void SetForceDisableOverscrollContent(bool force_disable); - AudioStreamMonitor* audio_stream_monitor() { - return &audio_stream_monitor_; + AudioStateProvider* audio_state_provider() { + return audio_state_provider_.get(); } bool has_audio_power_save_blocker_for_testing() const { @@ -1022,6 +1025,11 @@ scoped_ptr<PowerSaveBlocker> audio_power_save_blocker_; scoped_ptr<PowerSaveBlocker> video_power_save_blocker_; + // Tells whether this WebContents is actively producing sound. + // Order is important: the |frame_tree_| destruction uses + // |audio_state_provider_|. + scoped_ptr<AudioStateProvider> audio_state_provider_; + // Manages the frame tree of the page and process swaps in each node. FrameTree frame_tree_; @@ -1236,9 +1244,6 @@ // is created, and broadcast to all frames when it changes. AccessibilityMode accessibility_mode_; - // Monitors power levels for audio streams associated with this WebContents. - AudioStreamMonitor audio_stream_monitor_; - // Created on-demand to mute all audio output from this WebContents. scoped_ptr<WebContentsAudioMuter> audio_muter_;
diff --git a/content/browser/web_contents/web_contents_impl_unittest.cc b/content/browser/web_contents/web_contents_impl_unittest.cc index da3c82e..187f3c4 100644 --- a/content/browser/web_contents/web_contents_impl_unittest.cc +++ b/content/browser/web_contents/web_contents_impl_unittest.cc
@@ -9,7 +9,7 @@ #include "content/browser/frame_host/interstitial_page_impl.h" #include "content/browser/frame_host/navigation_entry_impl.h" #include "content/browser/frame_host/render_frame_host_impl.h" -#include "content/browser/media/audio_stream_monitor.h" +#include "content/browser/media/audio_state_provider.h" #include "content/browser/renderer_host/render_view_host_impl.h" #include "content/browser/site_instance_impl.h" #include "content/browser/webui/web_ui_controller_factory_registry.h" @@ -2891,20 +2891,20 @@ EXPECT_FALSE(contents()->has_video_power_save_blocker_for_testing()); TestRenderFrameHost* rfh = contents()->GetMainFrame(); - AudioStreamMonitor* monitor = contents()->audio_stream_monitor(); + AudioStateProvider* audio_state = contents()->audio_state_provider(); // The audio power save blocker should not be based on having a media player // when audio stream monitoring is available. - if (AudioStreamMonitor::monitoring_available()) { + if (audio_state->IsAudioStateAvailable()) { // Send a fake audio stream monitor notification. The audio power save // blocker should be created. - monitor->set_was_recently_audible_for_testing(true); + audio_state->set_was_recently_audible_for_testing(true); contents()->NotifyNavigationStateChanged(INVALIDATE_TYPE_TAB); EXPECT_TRUE(contents()->has_audio_power_save_blocker_for_testing()); // Send another fake notification, this time when WasRecentlyAudible() will // be false. The power save blocker should be released. - monitor->set_was_recently_audible_for_testing(false); + audio_state->set_was_recently_audible_for_testing(false); contents()->NotifyNavigationStateChanged(INVALIDATE_TYPE_TAB); EXPECT_FALSE(contents()->has_audio_power_save_blocker_for_testing()); } @@ -2916,7 +2916,7 @@ 0, kPlayerAudioVideoId, true, true, false)); EXPECT_TRUE(contents()->has_video_power_save_blocker_for_testing()); EXPECT_EQ(contents()->has_audio_power_save_blocker_for_testing(), - !AudioStreamMonitor::monitoring_available()); + !audio_state->IsAudioStateAvailable()); // Upon hiding the video power save blocker should be released. contents()->WasHidden(); @@ -2929,7 +2929,7 @@ 0, kPlayerVideoOnlyId, true, false, false)); EXPECT_FALSE(contents()->has_video_power_save_blocker_for_testing()); EXPECT_EQ(contents()->has_audio_power_save_blocker_for_testing(), - !AudioStreamMonitor::monitoring_available()); + !audio_state->IsAudioStateAvailable()); // Showing the WebContents should result in the creation of the blocker. contents()->WasShown(); @@ -2941,7 +2941,7 @@ 0, kPlayerAudioOnlyId, false, true, false)); EXPECT_TRUE(contents()->has_video_power_save_blocker_for_testing()); EXPECT_EQ(contents()->has_audio_power_save_blocker_for_testing(), - !AudioStreamMonitor::monitoring_available()); + !audio_state->IsAudioStateAvailable()); // Start a remote player. There should be no change in the power save // blockers. @@ -2949,7 +2949,7 @@ 0, kPlayerRemoteId, true, true, true)); EXPECT_TRUE(contents()->has_video_power_save_blocker_for_testing()); EXPECT_EQ(contents()->has_audio_power_save_blocker_for_testing(), - !AudioStreamMonitor::monitoring_available()); + !audio_state->IsAudioStateAvailable()); // Destroy the original audio video player. Both power save blockers should // remain. @@ -2957,7 +2957,7 @@ FrameHostMsg_MediaPausedNotification(0, kPlayerAudioVideoId)); EXPECT_TRUE(contents()->has_video_power_save_blocker_for_testing()); EXPECT_EQ(contents()->has_audio_power_save_blocker_for_testing(), - !AudioStreamMonitor::monitoring_available()); + !audio_state->IsAudioStateAvailable()); // Destroy the audio only player. The video power save blocker should remain. rfh->OnMessageReceived( @@ -2984,7 +2984,7 @@ 0, kPlayerAudioVideoId, true, true, false)); EXPECT_TRUE(contents()->has_video_power_save_blocker_for_testing()); EXPECT_EQ(contents()->has_audio_power_save_blocker_for_testing(), - !AudioStreamMonitor::monitoring_available()); + !audio_state->IsAudioStateAvailable()); // Crash the renderer. contents()->GetMainFrame()->OnMessageReceived(
diff --git a/content/common/frame_messages.h b/content/common/frame_messages.h index a9ca4b86..c3b5b62 100644 --- a/content/common/frame_messages.h +++ b/content/common/frame_messages.h
@@ -212,6 +212,8 @@ IPC_STRUCT_TRAITS_MEMBER(allow_download) IPC_STRUCT_TRAITS_MEMBER(ui_timestamp) IPC_STRUCT_TRAITS_MEMBER(report_type) + IPC_STRUCT_TRAITS_MEMBER(base_url_for_data_url) + IPC_STRUCT_TRAITS_MEMBER(history_url_for_data_url) IPC_STRUCT_TRAITS_END() IPC_STRUCT_TRAITS_BEGIN(content::BeginNavigationParams) @@ -284,14 +286,6 @@ // succesful when the navigation commits. IPC_STRUCT_MEMBER(bool, should_clear_history_list) - // Base URL for use in WebKit's SubstituteData. - // Is only used with data: URLs. - IPC_STRUCT_MEMBER(GURL, base_url_for_data_url) - - // History URL for use in WebKit's SubstituteData. - // Is only used with data: URLs. - IPC_STRUCT_MEMBER(GURL, history_url_for_data_url) - // Any redirect URLs that occurred before |url|. Useful for cross-process // navigations; defaults to empty. IPC_STRUCT_MEMBER(std::vector<GURL>, redirects)
diff --git a/content/common/gpu/image_transport_surface.cc b/content/common/gpu/image_transport_surface.cc index 02fbdfa4..b6367dd4 100644 --- a/content/common/gpu/image_transport_surface.cc +++ b/content/common/gpu/image_transport_surface.cc
@@ -191,8 +191,12 @@ // GetVsyncValues before SwapBuffers to work around Mali driver bug: // crbug.com/223558. SendVSyncUpdateIfAvailable(); - for (auto& latency : latency_info_) - latency.AddLatencyNumber(ui::INPUT_EVENT_GPU_SWAP_BUFFER_COMPONENT, 0, 0); + + base::TimeTicks swap_time = base::TimeTicks::Now(); + for (auto& latency : latency_info_) { + latency.AddLatencyNumberWithTimestamp( + ui::INPUT_EVENT_GPU_SWAP_BUFFER_COMPONENT, 0, 0, swap_time, 1); + } // We use WeakPtr here to avoid manual management of life time of an instance // of this class. Callback will not be called once the instance of this class @@ -206,6 +210,13 @@ bool PassThroughImageTransportSurface::PostSubBuffer( int x, int y, int width, int height) { SendVSyncUpdateIfAvailable(); + + base::TimeTicks swap_time = base::TimeTicks::Now(); + for (auto& latency : latency_info_) { + latency.AddLatencyNumberWithTimestamp( + ui::INPUT_EVENT_GPU_SWAP_BUFFER_COMPONENT, 0, 0, swap_time, 1); + } + // We use WeakPtr here to avoid manual management of life time of an instance // of this class. Callback will not be called once the instance of this class // is destroyed. However, this also means that the callback can be run on @@ -216,9 +227,11 @@ } void PassThroughImageTransportSurface::SwapBuffersCallBack() { - for (size_t i = 0; i < latency_info_.size(); i++) { - latency_info_[i].AddLatencyNumber( - ui::INPUT_EVENT_LATENCY_TERMINATED_FRAME_SWAP_COMPONENT, 0, 0); + base::TimeTicks swap_ack_time = base::TimeTicks::Now(); + for (auto& latency : latency_info_) { + latency.AddLatencyNumberWithTimestamp( + ui::INPUT_EVENT_LATENCY_TERMINATED_FRAME_SWAP_COMPONENT, 0, 0, + swap_ack_time, 1); } helper_->stub()->SendSwapBuffersCompleted(latency_info_);
diff --git a/content/common/gpu/image_transport_surface_linux.cc b/content/common/gpu/image_transport_surface_linux.cc index b648b19..db36efe 100644 --- a/content/common/gpu/image_transport_surface_linux.cc +++ b/content/common/gpu/image_transport_surface_linux.cc
@@ -13,9 +13,13 @@ const gfx::GLSurfaceHandle& handle) { DCHECK(handle.handle); DCHECK(handle.transport_type == gfx::NATIVE_DIRECT); - scoped_refptr<gfx::GLSurface> surface = - gfx::GLSurface::CreateViewGLSurface(handle.handle); - if (!surface.get()) + scoped_refptr<gfx::GLSurface> surface; +#if defined(USE_OZONE) + surface = gfx::GLSurface::CreateSurfacelessViewGLSurface(handle.handle); +#endif + if (!surface) + surface = gfx::GLSurface::CreateViewGLSurface(handle.handle); + if (!surface) return surface; return scoped_refptr<gfx::GLSurface>(new PassThroughImageTransportSurface( manager, stub, surface.get()));
diff --git a/content/common/gpu/media/rendering_helper.cc b/content/common/gpu/media/rendering_helper.cc index cf83611..3ceea1f 100644 --- a/content/common/gpu/media/rendering_helper.cc +++ b/content/common/gpu/media/rendering_helper.cc
@@ -314,6 +314,9 @@ message_loop_ = base::MessageLoop::current(); gl_surface_ = gfx::GLSurface::CreateViewGLSurface(window_); +#if defined(USE_OZONE) + gl_surface_->Resize(platform_window_delegate_->GetSize()); +#endif // defined(USE_OZONE) screen_size_ = gl_surface_->GetSize(); gl_context_ = gfx::GLContext::CreateGLContext( @@ -364,7 +367,8 @@ CHECK(fb_status == GL_FRAMEBUFFER_COMPLETE) << fb_status; glClearColor(0.0f, 0.0f, 0.0f, 1.0f); glClear(GL_COLOR_BUFFER_BIT); - glBindFramebufferEXT(GL_FRAMEBUFFER, 0); + glBindFramebufferEXT(GL_FRAMEBUFFER, + gl_surface_->GetBackingFrameBufferObject()); } // These vertices and texture coords. map (0,0) in the texture to the @@ -504,6 +508,7 @@ glDeleteFramebuffersEXT(1, &thumbnails_fbo_id_); } + gl_surface_->Destroy(); gl_context_->ReleaseCurrent(gl_surface_.get()); gl_context_ = NULL; gl_surface_ = NULL; @@ -570,7 +575,8 @@ glBindFramebufferEXT(GL_FRAMEBUFFER, thumbnails_fbo_id_); GLSetViewPort(area); RenderTexture(texture_target, texture_id); - glBindFramebufferEXT(GL_FRAMEBUFFER, 0); + glBindFramebufferEXT(GL_FRAMEBUFFER, + gl_surface_->GetBackingFrameBufferObject()); // Need to flush the GL commands before we return the tnumbnail texture to // the decoder. @@ -661,7 +667,8 @@ GL_RGBA, GL_UNSIGNED_BYTE, &rgba[0]); - glBindFramebufferEXT(GL_FRAMEBUFFER, 0); + glBindFramebufferEXT(GL_FRAMEBUFFER, + gl_surface_->GetBackingFrameBufferObject()); rgb->resize(num_pixels * 3); // Drop the alpha channel, but check as we go that it is all 0xff. bool solid = true; @@ -698,7 +705,13 @@ static_cast<base::WaitableEvent*>(NULL))); } - glUniform1i(glGetUniformLocation(program_, "tex_flip"), 1); + int tex_flip = 1; +#if defined(USE_OZONE) + // Ozone surfaceless renders flipped from normal GL, so there's no need to + // do an extra flip. + tex_flip = 0; +#endif // defined(USE_OZONE) + glUniform1i(glGetUniformLocation(program_, "tex_flip"), tex_flip); // Frames that will be returned to the client (via the no_longer_needed_cb) // after this vector falls out of scope at the end of this method. We need
diff --git a/content/common/input/input_param_traits.cc b/content/common/input/input_param_traits.cc index 33769fe0..1f4b7e4 100644 --- a/content/common/input/input_param_traits.cc +++ b/content/common/input/input_param_traits.cc
@@ -6,6 +6,7 @@ #include "content/common/content_param_traits.h" #include "content/common/input/synthetic_pinch_gesture_params.h" +#include "content/common/input/synthetic_smooth_drag_gesture_params.h" #include "content/common/input/synthetic_smooth_scroll_gesture_params.h" #include "content/common/input/web_input_event_traits.h" #include "content/common/input_messages.h" @@ -62,6 +63,10 @@ WriteParam(m, *content::SyntheticSmoothScrollGestureParams::Cast( p.gesture_params())); break; + case content::SyntheticGestureParams::SMOOTH_DRAG_GESTURE: + WriteParam(m, *content::SyntheticSmoothDragGestureParams::Cast( + p.gesture_params())); + break; case content::SyntheticGestureParams::PINCH_GESTURE: WriteParam(m, *content::SyntheticPinchGestureParams::Cast( p.gesture_params())); @@ -70,10 +75,6 @@ WriteParam(m, *content::SyntheticTapGestureParams::Cast( p.gesture_params())); break; - // TODO(ssid): When API and IPC messages are set up, implement this. - case content::SyntheticGestureParams::SMOOTH_DRAG_GESTURE: - NOTIMPLEMENTED(); - break; } } @@ -90,6 +91,10 @@ ReadGestureParams<content::SyntheticSmoothScrollGestureParams>(m, iter); break; + case content::SyntheticGestureParams::SMOOTH_DRAG_GESTURE: + gesture_params = + ReadGestureParams<content::SyntheticSmoothDragGestureParams>(m, iter); + break; case content::SyntheticGestureParams::PINCH_GESTURE: gesture_params = ReadGestureParams<content::SyntheticPinchGestureParams>(m, iter); @@ -116,6 +121,11 @@ p.gesture_params()), l); break; + case content::SyntheticGestureParams::SMOOTH_DRAG_GESTURE: + LogParam( + *content::SyntheticSmoothDragGestureParams::Cast(p.gesture_params()), + l); + break; case content::SyntheticGestureParams::PINCH_GESTURE: LogParam( *content::SyntheticPinchGestureParams::Cast(p.gesture_params()), @@ -126,10 +136,6 @@ *content::SyntheticTapGestureParams::Cast(p.gesture_params()), l); break; - // TODO(ssid): When API and IPC messages are set up, implement this. - case content::SyntheticGestureParams::SMOOTH_DRAG_GESTURE: - NOTIMPLEMENTED(); - break; } }
diff --git a/content/common/input_messages.h b/content/common/input_messages.h index 14967b48..5bdda8f 100644 --- a/content/common/input_messages.h +++ b/content/common/input_messages.h
@@ -17,6 +17,7 @@ #include "content/common/input/synthetic_gesture_packet.h" #include "content/common/input/synthetic_gesture_params.h" #include "content/common/input/synthetic_pinch_gesture_params.h" +#include "content/common/input/synthetic_smooth_drag_gesture_params.h" #include "content/common/input/synthetic_smooth_scroll_gesture_params.h" #include "content/common/input/synthetic_tap_gesture_params.h" #include "content/common/input/touch_action.h" @@ -77,6 +78,13 @@ IPC_STRUCT_TRAITS_MEMBER(gesture_source_type) IPC_STRUCT_TRAITS_END() +IPC_STRUCT_TRAITS_BEGIN(content::SyntheticSmoothDragGestureParams) + IPC_STRUCT_TRAITS_PARENT(content::SyntheticGestureParams) + IPC_STRUCT_TRAITS_MEMBER(start_point) + IPC_STRUCT_TRAITS_MEMBER(distances) + IPC_STRUCT_TRAITS_MEMBER(speed_in_pixels_s) +IPC_STRUCT_TRAITS_END() + IPC_STRUCT_TRAITS_BEGIN(content::SyntheticSmoothScrollGestureParams) IPC_STRUCT_TRAITS_PARENT(content::SyntheticGestureParams) IPC_STRUCT_TRAITS_MEMBER(anchor)
diff --git a/content/common/navigation_params.cc b/content/common/navigation_params.cc index 4171937..3213337f 100644 --- a/content/common/navigation_params.cc +++ b/content/common/navigation_params.cc
@@ -7,6 +7,7 @@ #include "base/memory/ref_counted_memory.h" namespace content { + CommonNavigationParams::CommonNavigationParams() : transition(ui::PAGE_TRANSITION_LINK), navigation_type(FrameMsg_Navigate_Type::NORMAL), @@ -21,14 +22,18 @@ FrameMsg_Navigate_Type::Value navigation_type, bool allow_download, base::TimeTicks ui_timestamp, - FrameMsg_UILoadMetricsReportType::Value report_type) + FrameMsg_UILoadMetricsReportType::Value report_type, + const GURL& base_url_for_data_url, + const GURL& history_url_for_data_url) : url(url), referrer(referrer), transition(transition), navigation_type(navigation_type), allow_download(allow_download), ui_timestamp(ui_timestamp), - report_type(report_type) { + report_type(report_type), + base_url_for_data_url(base_url_for_data_url), + history_url_for_data_url(history_url_for_data_url) { } CommonNavigationParams::~CommonNavigationParams() {
diff --git a/content/common/navigation_params.h b/content/common/navigation_params.h index 757d1a7..58e2ca5 100644 --- a/content/common/navigation_params.h +++ b/content/common/navigation_params.h
@@ -38,7 +38,9 @@ FrameMsg_Navigate_Type::Value navigation_type, bool allow_download, base::TimeTicks ui_timestamp, - FrameMsg_UILoadMetricsReportType::Value report_type); + FrameMsg_UILoadMetricsReportType::Value report_type, + const GURL& base_url_for_data_url, + const GURL& history_url_for_data_url); ~CommonNavigationParams(); // The URL to navigate to. @@ -66,6 +68,14 @@ // The report type to be used when recording the metric using |ui_timestamp|. FrameMsg_UILoadMetricsReportType::Value report_type; + + // Base URL for use in Blink's SubstituteData. + // Is only used with data: URLs. + GURL base_url_for_data_url; + + // History URL for use in Blink's SubstituteData. + // Is only used with data: URLs. + GURL history_url_for_data_url; }; // PlzNavigate: parameters needed to start a navigation on the IO thread.
diff --git a/content/content_browser.gypi b/content/content_browser.gypi index e0afa125..7715d1b 100644 --- a/content/content_browser.gypi +++ b/content/content_browser.gypi
@@ -355,6 +355,8 @@ 'browser/android/interstitial_page_delegate_android.h', 'browser/android/load_url_params.cc', 'browser/android/load_url_params.h', + 'browser/android/media_players_observer.cc', + 'browser/android/media_players_observer.h', 'browser/android/overscroll_controller_android.cc', 'browser/android/overscroll_controller_android.h', 'browser/android/overscroll_glow.cc', @@ -928,6 +930,8 @@ 'browser/media/android/media_drm_credential_manager.h', 'browser/media/android/media_resource_getter_impl.cc', 'browser/media/android/media_resource_getter_impl.h', + 'browser/media/audio_state_provider.cc', + 'browser/media/audio_state_provider.h', 'browser/media/audio_stream_monitor.cc', 'browser/media/audio_stream_monitor.h', 'browser/media/capture/audio_mirroring_manager.cc',
diff --git a/content/content_tests.gypi b/content/content_tests.gypi index 602f098a..9d5a2dc 100644 --- a/content/content_tests.gypi +++ b/content/content_tests.gypi
@@ -99,6 +99,7 @@ 'public/test/test_synchronous_compositor_android.h', 'public/test/test_utils.cc', 'public/test/test_utils.h', + 'public/test/test_web_contents_factory.h', 'public/test/unittest_test_suite.cc', 'public/test/unittest_test_suite.h', 'public/test/web_contents_observer_sanity_checker.cc', @@ -164,6 +165,7 @@ 'test/test_render_view_host_factory.h', 'test/test_web_contents.cc', 'test/test_web_contents.h', + 'test/test_web_contents_factory.cc', 'test/web_gesture_curve_mock.cc', 'test/web_gesture_curve_mock.h', 'test/web_layer_tree_view_impl_for_testing.cc', @@ -1118,6 +1120,7 @@ 'sources!': [ 'browser/geolocation/network_location_provider_unittest.cc', 'browser/geolocation/wifi_data_provider_common_unittest.cc', + 'browser/media/audio_stream_monitor_unittest.cc', 'browser/webui/url_data_manager_backend_unittest.cc', ], 'dependencies': [
diff --git a/content/gpu/gpu_main.cc b/content/gpu/gpu_main.cc index f73bb0d1..b34d42f 100644 --- a/content/gpu/gpu_main.cc +++ b/content/gpu/gpu_main.cc
@@ -61,6 +61,7 @@ #if defined(SANITIZER_COVERAGE) #include <sanitizer/common_interface_defs.h> +#include <sanitizer/coverage_interface.h> #endif const int kGpuTimeout = 10000;
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 226e4ea..00ea68a 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
@@ -5,6 +5,7 @@ package org.chromium.content.browser; import android.annotation.SuppressLint; +import android.annotation.TargetApi; import android.app.Activity; import android.app.SearchManager; import android.content.ClipboardManager; @@ -2806,6 +2807,7 @@ /** * @see View#onInitializeAccessibilityEvent(AccessibilityEvent) */ + @TargetApi(Build.VERSION_CODES.ICE_CREAM_SANDWICH_MR1) public void onInitializeAccessibilityEvent(AccessibilityEvent event) { // Note: this is only used by the script-injecting accessibility code. event.setClassName(this.getClass().getName()); @@ -2820,9 +2822,7 @@ int maxScrollYPix = Math.max(0, mRenderCoordinates.getMaxVerticalScrollPixInt()); event.setScrollable(maxScrollXPix > 0 || maxScrollYPix > 0); - // Setting the maximum scroll values requires API level 15 or higher. - final int sdkVersionRequiredToSetScroll = 15; - if (Build.VERSION.SDK_INT >= sdkVersionRequiredToSetScroll) { + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.ICE_CREAM_SANDWICH_MR1) { event.setMaxScrollX(maxScrollXPix); event.setMaxScrollY(maxScrollYPix); }
diff --git a/content/public/android/java/src/org/chromium/content/browser/accessibility/BrowserAccessibilityManager.java b/content/public/android/java/src/org/chromium/content/browser/accessibility/BrowserAccessibilityManager.java index b77c88ce..b0ebf0c7 100644 --- a/content/public/android/java/src/org/chromium/content/browser/accessibility/BrowserAccessibilityManager.java +++ b/content/public/android/java/src/org/chromium/content/browser/accessibility/BrowserAccessibilityManager.java
@@ -4,6 +4,7 @@ package org.chromium.content.browser.accessibility; +import android.annotation.TargetApi; import android.content.Context; import android.graphics.Rect; import android.os.Build; @@ -38,6 +39,7 @@ * accessibility. */ @JNINamespace("content") +@TargetApi(Build.VERSION_CODES.JELLY_BEAN) public class BrowserAccessibilityManager { private static final String TAG = "BrowserAccessibilityManager";
diff --git a/content/public/android/java/src/org/chromium/content/browser/accessibility/JellyBeanAccessibilityInjector.java b/content/public/android/java/src/org/chromium/content/browser/accessibility/JellyBeanAccessibilityInjector.java index abdeae7..67b4dca 100644 --- a/content/public/android/java/src/org/chromium/content/browser/accessibility/JellyBeanAccessibilityInjector.java +++ b/content/public/android/java/src/org/chromium/content/browser/accessibility/JellyBeanAccessibilityInjector.java
@@ -4,7 +4,9 @@ package org.chromium.content.browser.accessibility; +import android.annotation.TargetApi; import android.content.Context; +import android.os.Build; import android.os.Bundle; import android.os.SystemClock; import android.view.accessibility.AccessibilityNodeInfo; @@ -22,6 +24,7 @@ * Handles injecting accessibility Javascript and related Javascript -> Java APIs for JB and newer * devices. */ +@TargetApi(Build.VERSION_CODES.JELLY_BEAN) class JellyBeanAccessibilityInjector extends AccessibilityInjector { private CallbackHandler mCallback; private JSONObject mAccessibilityJSONObject;
diff --git a/content/public/android/java/src/org/chromium/content/browser/accessibility/JellyBeanBrowserAccessibilityManager.java b/content/public/android/java/src/org/chromium/content/browser/accessibility/JellyBeanBrowserAccessibilityManager.java index 62185c2..98f8863 100644 --- a/content/public/android/java/src/org/chromium/content/browser/accessibility/JellyBeanBrowserAccessibilityManager.java +++ b/content/public/android/java/src/org/chromium/content/browser/accessibility/JellyBeanBrowserAccessibilityManager.java
@@ -4,6 +4,8 @@ package org.chromium.content.browser.accessibility; +import android.annotation.TargetApi; +import android.os.Build; import android.os.Bundle; import android.view.accessibility.AccessibilityNodeInfo; import android.view.accessibility.AccessibilityNodeProvider; @@ -18,6 +20,7 @@ * AccessibilityNodeProvider and delegates its implementation to this object. */ @JNINamespace("content") +@TargetApi(Build.VERSION_CODES.JELLY_BEAN) public class JellyBeanBrowserAccessibilityManager extends BrowserAccessibilityManager { private AccessibilityNodeProvider mAccessibilityNodeProvider;
diff --git a/content/public/android/java/src/org/chromium/content/browser/accessibility/LollipopAccessibilityInjector.java b/content/public/android/java/src/org/chromium/content/browser/accessibility/LollipopAccessibilityInjector.java index d61484fc..d7737eb5 100644 --- a/content/public/android/java/src/org/chromium/content/browser/accessibility/LollipopAccessibilityInjector.java +++ b/content/public/android/java/src/org/chromium/content/browser/accessibility/LollipopAccessibilityInjector.java
@@ -4,7 +4,9 @@ package org.chromium.content.browser.accessibility; +import android.annotation.TargetApi; import android.content.Context; +import android.os.Build; import android.os.Bundle; import android.view.View; import android.view.accessibility.AccessibilityNodeInfo; @@ -20,6 +22,7 @@ * Handles injecting accessibility Javascript and related Javascript -> Java APIs for Lollipop and * newer devices. */ +@TargetApi(Build.VERSION_CODES.LOLLIPOP) class LollipopAccessibilityInjector extends JellyBeanAccessibilityInjector { /** * Constructs an instance of the LollipopAccessibilityInjector.
diff --git a/content/public/android/java/src/org/chromium/content/browser/accessibility/LollipopBrowserAccessibilityManager.java b/content/public/android/java/src/org/chromium/content/browser/accessibility/LollipopBrowserAccessibilityManager.java index a966ed6..f5c3af1 100644 --- a/content/public/android/java/src/org/chromium/content/browser/accessibility/LollipopBrowserAccessibilityManager.java +++ b/content/public/android/java/src/org/chromium/content/browser/accessibility/LollipopBrowserAccessibilityManager.java
@@ -4,6 +4,8 @@ package org.chromium.content.browser.accessibility; +import android.annotation.TargetApi; +import android.os.Build; import android.view.accessibility.AccessibilityEvent; import android.view.accessibility.AccessibilityNodeInfo; import android.view.accessibility.AccessibilityNodeInfo.AccessibilityAction; @@ -17,6 +19,7 @@ * AccessibilityNodeProvider and delegates its implementation to this object. */ @JNINamespace("content") +@TargetApi(Build.VERSION_CODES.LOLLIPOP) public class LollipopBrowserAccessibilityManager extends JellyBeanBrowserAccessibilityManager { LollipopBrowserAccessibilityManager(long nativeBrowserAccessibilityManagerAndroid, ContentViewCore contentViewCore) {
diff --git a/content/public/common/content_switches.cc b/content/public/common/content_switches.cc index 3b7d13b58..8d9bd67 100644 --- a/content/public/common/content_switches.cc +++ b/content/public/common/content_switches.cc
@@ -844,6 +844,9 @@ // Use the new surfaces system to handle compositor delegation. const char kUseSurfaces[] = "use-surfaces"; +// Disable the use of the new surfaces system to handle compositor delegation. +const char kDisableSurfaces[] = "disable-surfaces"; + // The contents of this flag are prepended to the utility process command line. // Useful values might be "valgrind" or "xterm -e gdb --args". const char kUtilityCmdPrefix[] = "utility-cmd-prefix";
diff --git a/content/public/common/content_switches.h b/content/public/common/content_switches.h index f792770d..a248681 100644 --- a/content/public/common/content_switches.h +++ b/content/public/common/content_switches.h
@@ -231,6 +231,7 @@ CONTENT_EXPORT extern const char kUseMobileUserAgent[]; CONTENT_EXPORT extern const char kUseNormalPriorityForTileTaskWorkerThreads[]; extern const char kUseSurfaces[]; +CONTENT_EXPORT extern const char kDisableSurfaces[]; extern const char kUtilityCmdPrefix[]; CONTENT_EXPORT extern const char kUtilityProcess[]; extern const char kUtilityProcessAllowedDir[];
diff --git a/content/public/test/test_web_contents_factory.h b/content/public/test/test_web_contents_factory.h new file mode 100644 index 0000000..8b48f9ef --- /dev/null +++ b/content/public/test/test_web_contents_factory.h
@@ -0,0 +1,52 @@ +// 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_WEB_CONTENTS_FACTORY_H_ +#define CONTENT_PUBLIC_TEST_TEST_WEB_CONTENTS_FACTORY_H_ + +#include "base/macros.h" +#include "base/memory/scoped_vector.h" + +namespace content { +class BrowserContext; +class RenderViewHostTestEnabler; +class WebContents; + +// A helper class to create test web contents (tabs) for unit tests, without +// inheriting from RenderViewTestHarness. Can create web contents, and will +// clean up after itself upon destruction. Owns all created web contents. +// A few notes: +// - Works well allocated on the stack, because it should be destroyed before +// associated browser context. +// - Doesn't play nice with web contents created any other way (because of +// the implementation of RenderViewHostTestEnabler). But if you are creating +// web contents already, what do you need this for? ;) +// TODO(devlin): The API is currently a bit sparse; there may need to be methods +// to, e.g., delete/close a web contents, access existing web contents, etc. +// These can be added as-needed. +class TestWebContentsFactory { + public: + TestWebContentsFactory(); + ~TestWebContentsFactory(); + + // Creates a new WebContents with the given |context|, and returns it. + // Ownership remains with the TestWebContentsFactory. + WebContents* CreateWebContents(BrowserContext* context); + + private: + // The test factory (and friends) for creating test web contents. + scoped_ptr<RenderViewHostTestEnabler> rvh_enabler_; + + // The vector of web contents that this class created. + ScopedVector<WebContents> web_contents_; + + // True if the factory initialized aura (and should thus tear it down). + bool tear_down_aura_; + + DISALLOW_COPY_AND_ASSIGN(TestWebContentsFactory); +}; + +} // namespace content + +#endif // CONTENT_PUBLIC_TEST_TEST_WEB_CONTENTS_FACTORY_H_
diff --git a/content/public/test/web_contents_observer_sanity_checker.cc b/content/public/test/web_contents_observer_sanity_checker.cc index e59998b..9b0fdcc 100644 --- a/content/public/test/web_contents_observer_sanity_checker.cc +++ b/content/public/test/web_contents_observer_sanity_checker.cc
@@ -4,7 +4,6 @@ #include "content/public/test/web_contents_observer_sanity_checker.h" -#include "base/debug/stack_trace.h" #include "base/strings/stringprintf.h" #include "content/common/frame_messages.h" #include "content/public/browser/render_frame_host.h" @@ -80,8 +79,27 @@ CHECK(new_host); CHECK_NE(new_host, old_host); - // TODO(nasko): Implement consistency checking for RenderFrameHostChanged - // in follow up CL. + if (old_host) { + std::pair<int, int> routing_pair = + std::make_pair(old_host->GetProcess()->GetID(), + old_host->GetRoutingID()); + bool old_did_exist = !!current_hosts_.erase(routing_pair); + if (!old_did_exist) { + CHECK(false) + << "RenderFrameHostChanged called with old host that did not exist:" + << Format(old_host); + } + } + + std::pair<int, int> routing_pair = + std::make_pair(new_host->GetProcess()->GetID(), + new_host->GetRoutingID()); + bool host_exists = !current_hosts_.insert(routing_pair).second; + if (host_exists) { + CHECK(false) + << "RenderFrameHostChanged called more than once for routing pair:" + << Format(new_host); + } } void WebContentsObserverSanityChecker::FrameDeleted(
diff --git a/content/public/test/web_contents_observer_sanity_checker.h b/content/public/test/web_contents_observer_sanity_checker.h index b8c3b61..2fab3ab 100644 --- a/content/public/test/web_contents_observer_sanity_checker.h +++ b/content/public/test/web_contents_observer_sanity_checker.h
@@ -87,6 +87,7 @@ void AssertRenderFrameExists(RenderFrameHost* render_frame_host); void AssertMainFrameExists(); + std::set<std::pair<int, int>> current_hosts_; std::set<std::pair<int, int>> live_routes_; std::set<std::pair<int, int>> deleted_routes_;
diff --git a/content/renderer/gpu/gpu_benchmarking_extension.cc b/content/renderer/gpu/gpu_benchmarking_extension.cc index 68221886..1f2369d 100644 --- a/content/renderer/gpu/gpu_benchmarking_extension.cc +++ b/content/renderer/gpu/gpu_benchmarking_extension.cc
@@ -14,6 +14,7 @@ #include "cc/layers/layer.h" #include "content/common/input/synthetic_gesture_params.h" #include "content/common/input/synthetic_pinch_gesture_params.h" +#include "content/common/input/synthetic_smooth_drag_gesture_params.h" #include "content/common/input/synthetic_smooth_scroll_gesture_params.h" #include "content/common/input/synthetic_tap_gesture_params.h" #include "content/public/child/v8_value_converter.h" @@ -381,6 +382,48 @@ return true; } +bool BeginSmoothDrag(v8::Isolate* isolate, + float start_x, + float start_y, + float end_x, + float end_y, + v8::Handle<v8::Function> callback, + int gesture_source_type, + int speed_in_pixels_s) { + GpuBenchmarkingContext context; + if (!context.Init(false)) + return false; + scoped_refptr<CallbackAndContext> callback_and_context = + new CallbackAndContext(isolate, callback, + context.web_frame()->mainWorldScriptContext()); + + scoped_ptr<SyntheticSmoothDragGestureParams> gesture_params( + new SyntheticSmoothDragGestureParams); + + // Convert coordinates from CSS pixels to density independent pixels (DIPs). + float page_scale_factor = context.web_view()->pageScaleFactor(); + + gesture_params->start_point.SetPoint(start_x * page_scale_factor, + start_y * page_scale_factor); + gfx::PointF end_point(end_x * page_scale_factor, + end_y * page_scale_factor); + gfx::Vector2dF distance = gesture_params->start_point - end_point; + gesture_params->distances.push_back(distance); + gesture_params->speed_in_pixels_s = speed_in_pixels_s * page_scale_factor; + gesture_params->gesture_source_type = + static_cast<SyntheticGestureParams::GestureSourceType>( + gesture_source_type); + + // TODO(nduca): If the render_view_impl is destroyed while the gesture is in + // progress, we will leak the callback and context. This needs to be fixed, + // somehow. + context.render_view_impl()->QueueSyntheticGesture( + gesture_params.Pass(), + base::Bind(&OnSyntheticGestureCompleted, callback_and_context)); + + return true; +} + } // namespace gin::WrapperInfo GpuBenchmarking::kWrapperInfo = {gin::kEmbedderNativeGin}; @@ -425,6 +468,7 @@ .SetMethod("gestureSourceTypeSupported", &GpuBenchmarking::GestureSourceTypeSupported) .SetMethod("smoothScrollBy", &GpuBenchmarking::SmoothScrollBy) + .SetMethod("smoothDrag", &GpuBenchmarking::SmoothDrag) .SetMethod("swipe", &GpuBenchmarking::Swipe) .SetMethod("scrollBounce", &GpuBenchmarking::ScrollBounce) // TODO(dominikg): Remove once JS interface changes have rolled into @@ -529,6 +573,39 @@ start_y); } +bool GpuBenchmarking::SmoothDrag(gin::Arguments* args) { + GpuBenchmarkingContext context; + if (!context.Init(true)) + return false; + + float start_x; + float start_y; + float end_x; + float end_y; + v8::Handle<v8::Function> callback; + int gesture_source_type = SyntheticGestureParams::DEFAULT_INPUT; + int speed_in_pixels_s = 800; + + if (!GetArg(args, &start_x) || + !GetArg(args, &start_y) || + !GetArg(args, &end_x) || + !GetArg(args, &end_y) || + !GetOptionalArg(args, &callback) || + !GetOptionalArg(args, &gesture_source_type) || + !GetOptionalArg(args, &speed_in_pixels_s)) { + return false; + } + + return BeginSmoothDrag(args->isolate(), + start_x, + start_y, + end_x, + end_y, + callback, + gesture_source_type, + speed_in_pixels_s); +} + bool GpuBenchmarking::Swipe(gin::Arguments* args) { GpuBenchmarkingContext context; if (!context.Init(true))
diff --git a/content/renderer/gpu/gpu_benchmarking_extension.h b/content/renderer/gpu/gpu_benchmarking_extension.h index 33e10ea..bbfb015b 100644 --- a/content/renderer/gpu/gpu_benchmarking_extension.h +++ b/content/renderer/gpu/gpu_benchmarking_extension.h
@@ -45,6 +45,7 @@ void PrintToSkPicture(v8::Isolate* isolate, const std::string& dirname); bool GestureSourceTypeSupported(int gesture_source_type); bool SmoothScrollBy(gin::Arguments* args); + bool SmoothDrag(gin::Arguments* args); bool Swipe(gin::Arguments* args); bool ScrollBounce(gin::Arguments* args); bool PinchBy(gin::Arguments* args);
diff --git a/content/renderer/media/android/media_source_delegate.cc b/content/renderer/media/android/media_source_delegate.cc index a5bf0b61..25813a179 100644 --- a/content/renderer/media/android/media_source_delegate.cc +++ b/content/renderer/media/android/media_source_delegate.cc
@@ -152,7 +152,8 @@ encrypted_media_init_data_cb, const media::SetDecryptorReadyCB& set_decryptor_ready_cb, const UpdateNetworkStateCB& update_network_state_cb, - const DurationChangeCB& duration_change_cb) { + const DurationChangeCB& duration_change_cb, + const base::Closure& waiting_for_decryption_key_cb) { DCHECK(main_task_runner_->BelongsToCurrentThread()); DCHECK(!media_source_opened_cb.is_null()); media_source_opened_cb_ = media_source_opened_cb; @@ -160,6 +161,7 @@ set_decryptor_ready_cb_ = media::BindToCurrentLoop(set_decryptor_ready_cb); update_network_state_cb_ = media::BindToCurrentLoop(update_network_state_cb); duration_change_cb_ = duration_change_cb; + waiting_for_decryption_key_cb_ = waiting_for_decryption_key_cb; access_unit_size_ = kAccessUnitSizeForMediaSource; chunk_demuxer_.reset(new media::ChunkDemuxer( @@ -521,7 +523,8 @@ DCHECK(!set_decryptor_ready_cb_.is_null()); audio_decrypting_demuxer_stream_.reset(new media::DecryptingDemuxerStream( - media_task_runner_, set_decryptor_ready_cb_)); + media_task_runner_, set_decryptor_ready_cb_, + waiting_for_decryption_key_cb_)); audio_decrypting_demuxer_stream_->Initialize( audio_stream_, base::Bind(&MediaSourceDelegate::OnAudioDecryptingDemuxerStreamInitDone, @@ -534,7 +537,8 @@ DCHECK(!set_decryptor_ready_cb_.is_null()); video_decrypting_demuxer_stream_.reset(new media::DecryptingDemuxerStream( - media_task_runner_, set_decryptor_ready_cb_)); + media_task_runner_, set_decryptor_ready_cb_, + waiting_for_decryption_key_cb_)); video_decrypting_demuxer_stream_->Initialize( video_stream_, base::Bind(&MediaSourceDelegate::OnVideoDecryptingDemuxerStreamInitDone,
diff --git a/content/renderer/media/android/media_source_delegate.h b/content/renderer/media/android/media_source_delegate.h index c8eaade..666b380 100644 --- a/content/renderer/media/android/media_source_delegate.h +++ b/content/renderer/media/android/media_source_delegate.h
@@ -62,7 +62,8 @@ encrypted_media_init_data_cb, const media::SetDecryptorReadyCB& set_decryptor_ready_cb, const UpdateNetworkStateCB& update_network_state_cb, - const DurationChangeCB& duration_change_cb); + const DurationChangeCB& duration_change_cb, + const base::Closure& waiting_for_decryption_key_cb); blink::WebTimeRanges Buffered() const; size_t DecodedFrameCount() const; @@ -198,6 +199,7 @@ MediaSourceOpenedCB media_source_opened_cb_; media::Demuxer::EncryptedMediaInitDataCB encrypted_media_init_data_cb_; + base::Closure waiting_for_decryption_key_cb_; // Temporary for EME v0.1. In the future the init data type should be passed // through GenerateKeyRequest() directly from WebKit.
diff --git a/content/renderer/media/android/webmediaplayer_android.cc b/content/renderer/media/android/webmediaplayer_android.cc index fe32f058..d3b0dcb 100644 --- a/content/renderer/media/android/webmediaplayer_android.cc +++ b/content/renderer/media/android/webmediaplayer_android.cc
@@ -313,6 +313,8 @@ base::Bind(&WebMediaPlayerAndroid::UpdateNetworkState, weak_factory_.GetWeakPtr()), base::Bind(&WebMediaPlayerAndroid::OnDurationChanged, + weak_factory_.GetWeakPtr()), + base::Bind(&WebMediaPlayerAndroid::OnWaitingForDecryptionKey, weak_factory_.GetWeakPtr())); InitializePlayer(url_, frame_->document().firstPartyForCookies(), true, demuxer_client_id); @@ -1759,6 +1761,15 @@ vector_as_array(&init_data), init_data.size()); } +void WebMediaPlayerAndroid::OnWaitingForDecryptionKey() { + client_->didBlockPlaybackWaitingForKey(); + + // TODO(jrummell): didResumePlaybackBlockedForKey() should only be called + // when a key has been successfully added (e.g. OnSessionKeysChange() with + // |has_additional_usable_key| = true). http://crbug.com/461903 + client_->didResumePlaybackBlockedForKey(); +} + void WebMediaPlayerAndroid::SetCdmInternal( const media::CdmAttachedCB& cdm_attached_cb) { DCHECK(cdm_context_ && is_player_initialized_);
diff --git a/content/renderer/media/android/webmediaplayer_android.h b/content/renderer/media/android/webmediaplayer_android.h index 314d7ee..8d18a26 100644 --- a/content/renderer/media/android/webmediaplayer_android.h +++ b/content/renderer/media/android/webmediaplayer_android.h
@@ -258,6 +258,10 @@ void OnEncryptedMediaInitData(const std::string& init_data_type, const std::vector<uint8>& init_data); + // Called when a decoder detects that the key needed to decrypt the stream + // is not available. + void OnWaitingForDecryptionKey(); + protected: // Helper method to update the playing state. void UpdatePlayingState(bool is_playing_);
diff --git a/content/renderer/media/peer_connection_tracker.cc b/content/renderer/media/peer_connection_tracker.cc index 2075cdd0..dd970ba 100644 --- a/content/renderer/media/peer_connection_tracker.cc +++ b/content/renderer/media/peer_connection_tracker.cc
@@ -217,7 +217,7 @@ for (const auto& v : report.values()) { values->AppendString(v->display_name()); - values->AppendString(v->value); + values->AppendString(v->ToString()); } return dict;
diff --git a/content/renderer/media/rtc_peer_connection_handler.cc b/content/renderer/media/rtc_peer_connection_handler.cc index da93384f..e758685 100644 --- a/content/renderer/media/rtc_peer_connection_handler.cc +++ b/content/renderer/media/rtc_peer_connection_handler.cc
@@ -409,7 +409,7 @@ for (const auto& value : report.values) { response->addStatistic(idx, blink::WebString::fromUTF8(value->display_name()), - blink::WebString::fromUTF8(value->value)); + blink::WebString::fromUTF8(value->ToString())); } }
diff --git a/content/renderer/render_frame_impl.cc b/content/renderer/render_frame_impl.cc index 47e05b5b..1e3667f 100644 --- a/content/renderer/render_frame_impl.cc +++ b/content/renderer/render_frame_impl.cc
@@ -1093,22 +1093,8 @@ CHECK(entry->root().urlString() != WebString::fromUTF8(kSwappedOutURL)); render_view_->history_controller()->GoToEntry(entry.Pass(), cache_policy); } - } else if (!params.base_url_for_data_url.is_empty()) { - // A loadData request with a specified base URL. - std::string mime_type, charset, data; - if (net::DataURL::Parse( - params.common_params.url, &mime_type, &charset, &data)) { - frame->loadData( - WebData(data.c_str(), data.length()), - WebString::fromUTF8(mime_type), - WebString::fromUTF8(charset), - params.base_url_for_data_url, - params.history_url_for_data_url, - false); - } else { - CHECK(false) << "Invalid URL passed: " - << params.common_params.url.possibly_invalid_spec(); - } + } else if (!params.common_params.base_url_for_data_url.is_empty()) { + LoadDataURL(params.common_params, frame); } else { // Navigate to the given URL. WebURLRequest request = @@ -3629,8 +3615,8 @@ // VisibilityState remain a page-level concept or move to frames? // The semantics of 'Show' might have to change here. if (render_widget_) { - render_view()->webview()->setVisibilityState( - blink::WebPageVisibilityStateVisible, false); + static_cast<blink::WebFrameWidget*>(render_widget_->webwidget())-> + setVisibilityState(blink::WebPageVisibilityStateVisible, false); } FOR_EACH_OBSERVER(RenderFrameObserver, observers_, WasShown()); } @@ -3884,6 +3870,12 @@ GetContentClient()->SetActiveURL(common_params.url); + if (!common_params.base_url_for_data_url.is_empty() || + common_params.url.SchemeIs(url::kDataScheme)) { + LoadDataURL(common_params, frame_); + return; + } + // Create a WebURLRequest that blink can use to get access to the body of the // response through a stream in the browser. Blink will then commit the // navigation. @@ -4379,6 +4371,26 @@ GetRequestBodyForWebURLRequest(*request))); } +void RenderFrameImpl::LoadDataURL(const CommonNavigationParams& params, + WebFrame* frame) { + // A loadData request with a specified base URL. + std::string mime_type, charset, data; + if (net::DataURL::Parse(params.url, &mime_type, &charset, &data)) { + const GURL base_url = params.base_url_for_data_url.is_empty() ? + params.url : params.base_url_for_data_url; + frame->loadData( + WebData(data.c_str(), data.length()), + WebString::fromUTF8(mime_type), + WebString::fromUTF8(charset), + base_url, + params.history_url_for_data_url, + false); + } else { + CHECK(false) << "Invalid URL passed: " + << params.url.possibly_invalid_spec(); + } +} + GURL RenderFrameImpl::GetLoadingUrl() const { WebDataSource* ds = frame_->dataSource(); if (ds->hasUnreachableURL())
diff --git a/content/renderer/render_frame_impl.h b/content/renderer/render_frame_impl.h index 9512149..327d850 100644 --- a/content/renderer/render_frame_impl.h +++ b/content/renderer/render_frame_impl.h
@@ -710,6 +710,10 @@ // of the WebURLRequest. void BeginNavigation(blink::WebURLRequest* request); + // Loads a data url. + void LoadDataURL(const CommonNavigationParams& params, + blink::WebFrame* frame); + // Returns the URL being loaded by the |frame_|'s request. GURL GetLoadingUrl() const;
diff --git a/content/renderer/scheduler/renderer_scheduler_impl_unittest.cc b/content/renderer/scheduler/renderer_scheduler_impl_unittest.cc index f2f6a569..4a97a045 100644 --- a/content/renderer/scheduler/renderer_scheduler_impl_unittest.cc +++ b/content/renderer/scheduler/renderer_scheduler_impl_unittest.cc
@@ -338,9 +338,9 @@ base::TimeTicks deadline_in_task; int run_count = 0; - default_task_runner_->PostTask(FROM_HERE, base::Bind(&NullTask)); idle_task_runner_->PostIdleTaskAfterWakeup( FROM_HERE, base::Bind(&IdleTestTask, &run_count, &deadline_in_task)); + default_task_runner_->PostTask(FROM_HERE, base::Bind(&NullTask)); RunUntilIdle(); EnableIdleTasks(); // Must start a new idle period before idle task runs.
diff --git a/content/renderer/scheduler/task_queue_manager.cc b/content/renderer/scheduler/task_queue_manager.cc index f4f8fc5f..0b88d5a 100644 --- a/content/renderer/scheduler/task_queue_manager.cc +++ b/content/renderer/scheduler/task_queue_manager.cc
@@ -43,7 +43,7 @@ void PumpQueue(); bool UpdateWorkQueue(base::TimeTicks* next_pending_delayed_task, - TaskQueueManager::WorkQueueUpdateEventType event_type); + const base::PendingTask* previous_task); base::PendingTask TakeTaskFromWorkQueue(); void WillDeleteTaskQueueManager(); @@ -73,8 +73,8 @@ void EnqueueTask(const base::PendingTask& pending_task); void PumpQueueLocked(); - bool ShouldAutoPumpQueueLocked( - TaskQueueManager::WorkQueueUpdateEventType event_type); + bool TaskIsOlderThanQueuedTasks(const base::PendingTask* task); + bool ShouldAutoPumpQueueLocked(const base::PendingTask* previous_task); void EnqueueTaskLocked(const base::PendingTask& pending_task); void TraceQueueSize(bool is_locked) const; @@ -153,13 +153,35 @@ } } +bool TaskQueue::TaskIsOlderThanQueuedTasks(const base::PendingTask* task) { + lock_.AssertAcquired(); + // A null task is passed when UpdateQueue is called before any task is run. + // In this case we don't want to pump an after_wakeup queue, so return true + // here. + if (!task) + return true; + + // Return false if there are no task in the incoming queue. + if (incoming_queue_.empty()) + return false; + + base::PendingTask oldest_queued_task = incoming_queue_.front(); + DCHECK(oldest_queued_task.delayed_run_time.is_null()); + DCHECK(task->delayed_run_time.is_null()); + + // Note: the comparison is correct due to the fact that the PendingTask + // operator inverts its comparison operation in order to work well in a heap + // based priority queue. + return oldest_queued_task < *task; +} + bool TaskQueue::ShouldAutoPumpQueueLocked( - TaskQueueManager::WorkQueueUpdateEventType event_type) { + const base::PendingTask* previous_task) { lock_.AssertAcquired(); if (pump_policy_ == TaskQueueManager::PumpPolicy::MANUAL) return false; if (pump_policy_ == TaskQueueManager::PumpPolicy::AFTER_WAKEUP && - event_type != TaskQueueManager::WorkQueueUpdateEventType::AFTER_WAKEUP) + TaskIsOlderThanQueuedTasks(previous_task)) return false; if (incoming_queue_.empty()) return false; @@ -168,7 +190,7 @@ bool TaskQueue::UpdateWorkQueue( base::TimeTicks* next_pending_delayed_task, - TaskQueueManager::WorkQueueUpdateEventType event_type) { + const base::PendingTask* previous_task) { if (!work_queue_.empty()) return true; @@ -178,7 +200,7 @@ *next_pending_delayed_task = std::min(*next_pending_delayed_task, delayed_task_run_times_.top()); } - if (!ShouldAutoPumpQueueLocked(event_type)) + if (!ShouldAutoPumpQueueLocked(previous_task)) return false; work_queue_.Swap(&incoming_queue_); TraceQueueSize(true); @@ -383,14 +405,15 @@ bool TaskQueueManager::UpdateWorkQueues( base::TimeTicks* next_pending_delayed_task, - WorkQueueUpdateEventType event_type) { + const base::PendingTask* previous_task) { // TODO(skyostil): This is not efficient when the number of queues grows very // large due to the number of locks taken. Consider optimizing when we get // there. DCHECK(main_thread_checker_.CalledOnValidThread()); bool has_work = false; for (auto& queue : queues_) { - has_work |= queue->UpdateWorkQueue(next_pending_delayed_task, event_type); + has_work |= queue->UpdateWorkQueue(next_pending_delayed_task, + previous_task); if (!queue->work_queue().empty()) { // Currently we should not be getting tasks with delayed run times in any // of the work queues. @@ -426,8 +449,9 @@ base::TimeTicks next_pending_delayed_task( base::TimeTicks::FromInternalValue(kMaxTimeTicks)); - if (!UpdateWorkQueues(&next_pending_delayed_task, - WorkQueueUpdateEventType::BEFORE_WAKEUP)) + // Pass nullptr to UpdateWorkQueues here to prevent waking up an + // pump-after-wakeup queue. + if (!UpdateWorkQueues(&next_pending_delayed_task, nullptr)) return; base::PendingTask previous_task((tracked_objects::Location()), @@ -446,8 +470,7 @@ MaybePostDoWorkOnMainRunner(); ProcessTaskFromWorkQueue(queue_index, i > 0, &previous_task); - if (!UpdateWorkQueues(&next_pending_delayed_task, - WorkQueueUpdateEventType::AFTER_WAKEUP)) + if (!UpdateWorkQueues(&next_pending_delayed_task, &previous_task)) return; } }
diff --git a/content/renderer/scheduler/task_queue_manager.h b/content/renderer/scheduler/task_queue_manager.h index 79df04d..8f32b93a 100644 --- a/content/renderer/scheduler/task_queue_manager.h +++ b/content/renderer/scheduler/task_queue_manager.h
@@ -116,8 +116,6 @@ private: friend class internal::TaskQueue; - enum class WorkQueueUpdateEventType { BEFORE_WAKEUP, AFTER_WAKEUP }; - // Called by the task queue to register a new pending task and allocate a // sequence number for it. void DidQueueTask(base::PendingTask* pending_task); @@ -131,12 +129,13 @@ void DoWork(bool posted_from_main_thread); // Reloads any empty work queues which have automatic pumping enabled and - // which are eligible to be auto pumped at the given |event_type|. - // Returns true if any work queue has tasks after doing this. + // which are eligible to be auto pumped based on the |previous_task| which was + // run. Call with an empty |previous_task| if no task was just run. Returns + // true if any work queue has tasks after doing this. // |next_pending_delayed_task| should be the time of the next known delayed // task. It is updated if any task is found which should run earlier. bool UpdateWorkQueues(base::TimeTicks* next_pending_delayed_task, - WorkQueueUpdateEventType event_type); + const base::PendingTask* previous_task); // Chooses the next work queue to service. Returns true if |out_queue_index| // indicates the queue from which the next task should be run, false to
diff --git a/content/renderer/scheduler/task_queue_manager_unittest.cc b/content/renderer/scheduler/task_queue_manager_unittest.cc index 5c4e4eb8..0a1a2a7 100644 --- a/content/renderer/scheduler/task_queue_manager_unittest.cc +++ b/content/renderer/scheduler/task_queue_manager_unittest.cc
@@ -58,6 +58,7 @@ selector_ = make_scoped_ptr(new SelectorForTest); manager_ = make_scoped_ptr( new TaskQueueManager(num_queues, test_task_runner_, selector_.get())); + EXPECT_EQ(num_queues, selector_->work_queues().size()); } void InitializeWithRealMessageLoop(size_t num_queues) { @@ -65,6 +66,7 @@ selector_ = make_scoped_ptr(new SelectorForTest); manager_ = make_scoped_ptr(new TaskQueueManager( num_queues, message_loop_->task_runner(), selector_.get())); + EXPECT_EQ(num_queues, selector_->work_queues().size()); } scoped_refptr<base::TestSimpleTaskRunner> test_task_runner_; @@ -93,7 +95,6 @@ TEST_F(TaskQueueManagerTest, SingleQueuePosting) { Initialize(1u); - EXPECT_EQ(1u, selector_->work_queues().size()); std::vector<int> run_order; scoped_refptr<base::SingleThreadTaskRunner> runner = @@ -113,7 +114,6 @@ TEST_F(TaskQueueManagerTest, MultiQueuePosting) { Initialize(3u); - EXPECT_EQ(3u, selector_->work_queues().size()); std::vector<int> run_order; scoped_refptr<base::SingleThreadTaskRunner> runners[3] = { @@ -141,7 +141,6 @@ TEST_F(TaskQueueManagerTest, NonNestableTaskPosting) { InitializeWithRealMessageLoop(1u); - EXPECT_EQ(1u, selector_->work_queues().size()); std::vector<int> run_order; scoped_refptr<base::SingleThreadTaskRunner> runner = @@ -157,7 +156,6 @@ TEST_F(TaskQueueManagerTest, NonNestableTaskExecutesInExpectedOrder) { InitializeWithRealMessageLoop(1u); - EXPECT_EQ(1u, selector_->work_queues().size()); std::vector<int> run_order; scoped_refptr<base::SingleThreadTaskRunner> runner = @@ -181,7 +179,6 @@ TEST_F(TaskQueueManagerTest, NonNestableTaskDoesntExecuteInNestedLoop) { InitializeWithRealMessageLoop(1u); - EXPECT_EQ(1u, selector_->work_queues().size()); std::vector<int> run_order; scoped_refptr<base::SingleThreadTaskRunner> runner = @@ -402,7 +399,6 @@ TEST_F(TaskQueueManagerTest, ReentrantPosting) { Initialize(1u); - EXPECT_EQ(1u, selector_->work_queues().size()); std::vector<int> run_order; scoped_refptr<base::SingleThreadTaskRunner> runner = @@ -457,18 +453,22 @@ EXPECT_THAT(run_order, ElementsAre(1)); } -void RePostingTestTask(scoped_refptr<base::SingleThreadTaskRunner> runner) { +void RePostingTestTask(scoped_refptr<base::SingleThreadTaskRunner> runner, + int* run_count) { + (*run_count)++; runner->PostTask( - FROM_HERE, Bind(&RePostingTestTask, base::Unretained(runner.get()))); + FROM_HERE, + Bind(&RePostingTestTask, base::Unretained(runner.get()), run_count)); } TEST_F(TaskQueueManagerTest, DoWorkCantPostItselfMultipleTimes) { Initialize(1u); - scoped_refptr<base::SingleThreadTaskRunner> runner = manager_->TaskRunnerForQueue(0); - runner->PostTask(FROM_HERE, base::Bind(&RePostingTestTask, runner)); + int run_count = 0; + runner->PostTask(FROM_HERE, + base::Bind(&RePostingTestTask, runner, &run_count)); selector_->AppendQueueToService(0); selector_->AppendQueueToService(0); @@ -478,6 +478,7 @@ // NOTE without the executing_task_ check in MaybePostDoWorkOnMainRunner there // will be two tasks here. EXPECT_EQ(1u, test_task_runner_->GetPendingTasks().size()); + EXPECT_EQ(1, run_count); } TEST_F(TaskQueueManagerTest, PostFromNestedRunloop) { @@ -583,9 +584,8 @@ EXPECT_THAT(run_order, ElementsAre(2, 3, 1)); } -TEST_F(TaskQueueManagerTest, AutoPumpOnWakeup) { +TEST_F(TaskQueueManagerTest, AutoPumpAfterWakeup) { Initialize(2u); - EXPECT_EQ(2u, selector_->work_queues().size()); manager_->SetPumpPolicy(0, TaskQueueManager::PumpPolicy::AFTER_WAKEUP); std::vector<int> run_order; @@ -610,9 +610,8 @@ EXPECT_THAT(run_order, ElementsAre(3, 1, 2)); } -TEST_F(TaskQueueManagerTest, AutoPumpOnWakeupWhenAlreadyAwake) { +TEST_F(TaskQueueManagerTest, AutoPumpAfterWakeupWhenAlreadyAwake) { Initialize(2u); - EXPECT_EQ(2u, selector_->work_queues().size()); manager_->SetPumpPolicy(0, TaskQueueManager::PumpPolicy::AFTER_WAKEUP); std::vector<int> run_order; @@ -622,15 +621,15 @@ selector_->AppendQueueToService(1); selector_->AppendQueueToService(0); - runners[1]->PostTask(FROM_HERE, base::Bind(&TestTask, 1, &run_order)); - runners[0]->PostTask(FROM_HERE, base::Bind(&TestTask, 2, &run_order)); + runners[0]->PostTask(FROM_HERE, base::Bind(&TestTask, 1, &run_order)); + runners[1]->PostTask(FROM_HERE, base::Bind(&TestTask, 2, &run_order)); test_task_runner_->RunUntilIdle(); - EXPECT_THAT(run_order, ElementsAre(1, 2)); // TQM was already awake. + EXPECT_THAT(run_order, ElementsAre(2, 1)); // TQM was already awake. } -TEST_F(TaskQueueManagerTest, AutoPumpOnWakeupTriggeredByManuallyPumpedQueue) { +TEST_F(TaskQueueManagerTest, + AutoPumpAfterWakeupTriggeredByManuallyPumpedQueue) { Initialize(2u); - EXPECT_EQ(2u, selector_->work_queues().size()); manager_->SetPumpPolicy(0, TaskQueueManager::PumpPolicy::AFTER_WAKEUP); manager_->SetPumpPolicy(1, TaskQueueManager::PumpPolicy::MANUAL); @@ -656,6 +655,104 @@ EXPECT_THAT(run_order, ElementsAre(2, 1)); } +void TestPostingTask(scoped_refptr<base::SingleThreadTaskRunner> task_runner, + base::Closure task) { + task_runner->PostTask(FROM_HERE, task); +} + +TEST_F(TaskQueueManagerTest, AutoPumpAfterWakeupFromTask) { + Initialize(2u); + manager_->SetPumpPolicy(0, TaskQueueManager::PumpPolicy::AFTER_WAKEUP); + + std::vector<int> run_order; + scoped_refptr<base::SingleThreadTaskRunner> runners[2] = { + manager_->TaskRunnerForQueue(0), manager_->TaskRunnerForQueue(1)}; + + selector_->AppendQueueToService(1); + selector_->AppendQueueToService(1); + selector_->AppendQueueToService(0); + + // Check that a task which posts a task to an auto pump after wakeup queue + // doesn't cause the queue to wake up. + base::Closure after_wakeup_task = base::Bind(&TestTask, 1, &run_order); + runners[1]->PostTask( + FROM_HERE, + base::Bind(&TestPostingTask, runners[0], after_wakeup_task)); + test_task_runner_->RunUntilIdle(); + EXPECT_TRUE(run_order.empty()); + + // Wake up the queue. + runners[1]->PostTask(FROM_HERE, base::Bind(&TestTask, 2, &run_order)); + test_task_runner_->RunUntilIdle(); + EXPECT_THAT(run_order, ElementsAre(2, 1)); +} + +TEST_F(TaskQueueManagerTest, AutoPumpAfterWakeupFromMultipleTasks) { + Initialize(2u); + manager_->SetPumpPolicy(0, TaskQueueManager::PumpPolicy::AFTER_WAKEUP); + + std::vector<int> run_order; + scoped_refptr<base::SingleThreadTaskRunner> runners[2] = { + manager_->TaskRunnerForQueue(0), manager_->TaskRunnerForQueue(1)}; + + selector_->AppendQueueToService(1); + selector_->AppendQueueToService(1); + selector_->AppendQueueToService(1); + selector_->AppendQueueToService(0); + selector_->AppendQueueToService(0); + + // Check that a task which posts a task to an auto pump after wakeup queue + // doesn't cause the queue to wake up. + base::Closure after_wakeup_task_1 = base::Bind(&TestTask, 1, &run_order); + base::Closure after_wakeup_task_2 = base::Bind(&TestTask, 2, &run_order); + runners[1]->PostTask( + FROM_HERE, + base::Bind(&TestPostingTask, runners[0], after_wakeup_task_1)); + runners[1]->PostTask( + FROM_HERE, + base::Bind(&TestPostingTask, runners[0], after_wakeup_task_2)); + test_task_runner_->RunUntilIdle(); + EXPECT_TRUE(run_order.empty()); + + // Wake up the queue. + runners[1]->PostTask(FROM_HERE, base::Bind(&TestTask, 3, &run_order)); + test_task_runner_->RunUntilIdle(); + EXPECT_THAT(run_order, ElementsAre(3, 1, 2)); +} + +void NullTestTask() { +} + +TEST_F(TaskQueueManagerTest, AutoPumpAfterWakeupBecomesQuiescent) { + Initialize(2u); + manager_->SetPumpPolicy(0, TaskQueueManager::PumpPolicy::AFTER_WAKEUP); + + int run_count = 0; + scoped_refptr<base::SingleThreadTaskRunner> runners[2] = { + manager_->TaskRunnerForQueue(0), manager_->TaskRunnerForQueue(1)}; + + selector_->AppendQueueToService(1); + selector_->AppendQueueToService(0); + selector_->AppendQueueToService(0); + // Append extra service queue '0' entries to the selector otherwise test will + // finish even if the RePostingTestTask woke each other up. + selector_->AppendQueueToService(0); + selector_->AppendQueueToService(0); + + // Check that if multiple tasks reposts themselves onto a pump-after-wakeup + // queue they don't wake each other and will eventually stop when no other + // tasks execute. + runners[0]->PostTask(FROM_HERE, + base::Bind(&RePostingTestTask, runners[0], &run_count)); + runners[0]->PostTask(FROM_HERE, + base::Bind(&RePostingTestTask, runners[0], &run_count)); + runners[1]->PostTask(FROM_HERE, base::Bind(&NullTestTask)); + test_task_runner_->RunUntilIdle(); + // The reposting tasks posted to the after wakeup queue shouldn't have woken + // each other up. + EXPECT_EQ(2, run_count); +} + class MockTaskObserver : public base::MessageLoop::TaskObserver { public: MOCK_METHOD1(DidProcessTask, void(const base::PendingTask& task));
diff --git a/content/shell/BUILD.gn b/content/shell/BUILD.gn index 2bbac9b..56723e8a 100644 --- a/content/shell/BUILD.gn +++ b/content/shell/BUILD.gn
@@ -482,7 +482,7 @@ # TODO(GYP): Figure out what this should be on android # and make linking this work on the Mac. -if (!is_android && !is_mac && (!is_win || link_chrome_on_windows)) { +if (!is_android && !is_mac) { executable("content_shell") { testonly = true
diff --git a/content/test/BUILD.gn b/content/test/BUILD.gn index ec6efd3..18048efa9 100644 --- a/content/test/BUILD.gn +++ b/content/test/BUILD.gn
@@ -247,7 +247,7 @@ } # !is_ios # TODO(GYP) enable content_browsertests on Mac when it links. -if (!is_mac && (!is_win || link_chrome_on_windows)) { +if (!is_mac) { test("content_browsertests") { sources = rebase_path(content_tests_gypi_values.content_browsertests_sources, @@ -439,7 +439,7 @@ } } -if (!is_mac && (!is_win || link_chrome_on_windows)) { # TODO(GYP) enable on Mac once it links. +if (!is_mac) { # TODO(GYP) enable on Mac once it links. test("content_unittests") { sources = rebase_path(content_tests_gypi_values.content_unittests_sources, ".", @@ -631,7 +631,7 @@ } } -if (!is_mac && (!is_win || link_chrome_on_windows)) { # TODO(GYP) enable on Mac once it links. +if (!is_mac) { # TODO(GYP) enable on Mac once it links. test("content_perftests") { sources = [ "../browser/net/sqlite_persistent_cookie_store_perftest.cc",
diff --git a/content/test/data/media/peerconnection-call.html b/content/test/data/media/peerconnection-call.html index 1e6ff4b8..345d0ea 100644 --- a/content/test/data/media/peerconnection-call.html +++ b/content/test/data/media/peerconnection-call.html
@@ -533,48 +533,48 @@ setAllEventsOccuredHandler(function() { // Add an audio track to the local stream and remove the video track and // then renegotiate. But first - setup the expectations. - local_stream = gFirstConnection.getLocalStreams()[0]; + var localStream = gFirstConnection.getLocalStreams()[0]; + var remoteStream1 = gFirstConnection.getRemoteStreams()[0]; - remote_stream_1 = gFirstConnection.getRemoteStreams()[0]; // Add an expected event that onaddtrack will be called on the remote // mediastream received on gFirstConnection when the audio track is // received. addExpectedEvent(); - remote_stream_1.onaddtrack = function(){ - assertEquals(remote_stream_1.getAudioTracks()[0].id, - local_stream.getAudioTracks()[0].id); + remoteStream1.onaddtrack = function(){ + assertEquals(remoteStream1.getAudioTracks()[0].id, + localStream.getAudioTracks()[0].id); eventOccured(); } // Add an expectation that the received video track is removed from // gFirstConnection. addExpectedEvent(); - remote_stream_1.onremovetrack = function() { + remoteStream1.onremovetrack = function() { eventOccured(); } // Add an expected event that onaddtrack will be called on the remote // mediastream received on gSecondConnection when the audio track is // received. - remote_stream_2 = gSecondConnection.getRemoteStreams()[0]; + remoteStream2 = gSecondConnection.getRemoteStreams()[0]; addExpectedEvent(); - remote_stream_2.onaddtrack = function() { - assertEquals(remote_stream_2.getAudioTracks()[0].id, - local_stream.getAudioTracks()[0].id); + remoteStream2.onaddtrack = function() { + assertEquals(remoteStream2.getAudioTracks()[0].id, + localStream.getAudioTracks()[0].id); eventOccured(); } // Add an expectation that the received video track is removed from // gSecondConnection. addExpectedEvent(); - remote_stream_2.onremovetrack = function() { + remoteStream2.onremovetrack = function() { eventOccured(); } // When all the above events have occurred- the test pass. setAllEventsOccuredHandler(reportTestSuccess); - local_stream.addTrack(gLocalStream.getAudioTracks()[0]); - local_stream.removeTrack(local_stream.getVideoTracks()[0]); + localStream.addTrack(gLocalStream.getAudioTracks()[0]); + localStream.removeTrack(localStream.getVideoTracks()[0]); negotiate(); }); } @@ -681,7 +681,7 @@ function addTwoMediaStreamsToOneConnection() { createConnections(null); navigator.webkitGetUserMedia({audio: true, video: true}, - CloneStreamAndAddTwoStreamstoOneConnection, printGetUserMediaError); + cloneStreamAndAddTwoStreamsToOneConnection, printGetUserMediaError); } function onToneChange(tone) { @@ -743,7 +743,7 @@ // Called if getUserMedia succeeds, then clone the stream, send two streams // from one peer connection. - function CloneStreamAndAddTwoStreamstoOneConnection(localStream) { + function cloneStreamAndAddTwoStreamsToOneConnection(localStream) { displayAndRemember(localStream); var clonedStream = null; @@ -780,15 +780,14 @@ negotiate(); } - // Called if getUserMedia succeeds when we want to send a modified - // MediaStream. A new MediaStream is created and the video track from - // |localStream| is added. + // A new MediaStream is created with video track from |localStream| and is + // added to both peer connections. function createNewVideoStreamAndAddToBothConnections(localStream) { displayAndRemember(localStream); - var new_stream = new webkitMediaStream(); - new_stream.addTrack(localStream.getVideoTracks()[0]); - gFirstConnection.addStream(new_stream); - gSecondConnection.addStream(new_stream); + var newStream = new webkitMediaStream(); + newStream.addTrack(localStream.getVideoTracks()[0]); + gFirstConnection.addStream(newStream); + gSecondConnection.addStream(newStream); negotiate(); }
diff --git a/content/test/test_web_contents_factory.cc b/content/test/test_web_contents_factory.cc new file mode 100644 index 0000000..0bf7a01 --- /dev/null +++ b/content/test/test_web_contents_factory.cc
@@ -0,0 +1,53 @@ +// 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_web_contents_factory.h" + +#include "base/run_loop.h" +#include "content/public/browser/web_contents.h" +#include "content/public/test/test_renderer_host.h" +#include "content/public/test/web_contents_tester.h" + +#if defined(USE_AURA) +#include "ui/aura/env.h" +#endif + +namespace content { + +TestWebContentsFactory::TestWebContentsFactory() + : rvh_enabler_(new content::RenderViewHostTestEnabler()), + tear_down_aura_(false) { +#if defined(USE_AURA) + if (aura::Env::GetInstanceDontCreate() == nullptr) { + aura::Env::CreateInstance(true); + tear_down_aura_ = true; + } +#endif +} + +TestWebContentsFactory::~TestWebContentsFactory() { + // We explicitly clear the vector to force destruction of any created web + // contents so that we can properly handle their cleanup (running posted + // tasks, etc). + web_contents_.clear(); + // Let any posted tasks for web contents deletion run. + base::RunLoop().RunUntilIdle(); + rvh_enabler_.reset(); + // Let any posted tasks for RenderProcess/ViewHost deletion run. + base::RunLoop().RunUntilIdle(); +#if defined(USE_AURA) + if (tear_down_aura_) + aura::Env::DeleteInstance(); +#endif +} + +WebContents* TestWebContentsFactory::CreateWebContents( + BrowserContext* context) { + web_contents_.push_back( + WebContentsTester::CreateTestWebContents(context, nullptr)); + DCHECK(web_contents_.back()); + return web_contents_.back(); +} + +} // namespace content
diff --git a/content/zygote/zygote_main_linux.cc b/content/zygote/zygote_main_linux.cc index efbfdb0..96fac21 100644 --- a/content/zygote/zygote_main_linux.cc +++ b/content/zygote/zygote_main_linux.cc
@@ -67,6 +67,7 @@ #if defined(SANITIZER_COVERAGE) #include <sanitizer/common_interface_defs.h> +#include <sanitizer/coverage_interface.h> #endif namespace content {
diff --git a/courgette/disassembler_elf_32.cc b/courgette/disassembler_elf_32.cc index ff2b9e03..02a31eb 100644 --- a/courgette/disassembler_elf_32.cc +++ b/courgette/disassembler_elf_32.cc
@@ -262,6 +262,9 @@ const Elf32_Shdr *section_header = SectionHeader(section_id); + if (section_header->sh_type == SHT_NOBITS) + continue; + if (!ParseSimpleRegion(file_offset, section_header->sh_offset, program)) @@ -282,8 +285,6 @@ return false; file_offset = section_header->sh_offset + section_header->sh_size; break; - case SHT_NOBITS: - // Fall through case SHT_INIT_ARRAY: // Fall through case SHT_FINI_ARRAY:
diff --git a/courgette/disassembler_elf_32_x86.cc b/courgette/disassembler_elf_32_x86.cc index 74496d3..d2c1c86b44 100644 --- a/courgette/disassembler_elf_32_x86.cc +++ b/courgette/disassembler_elf_32_x86.cc
@@ -91,6 +91,9 @@ uint32 section_relocs_count = section_header->sh_size / section_header->sh_entsize; + if (abs32_locations_.empty()) + match = false; + if (abs32_locations_.size() > section_relocs_count) match = false;
diff --git a/courgette/encode_decode_unittest.cc b/courgette/encode_decode_unittest.cc index 0e121d6..a3161ce 100644 --- a/courgette/encode_decode_unittest.cc +++ b/courgette/encode_decode_unittest.cc
@@ -82,3 +82,8 @@ std::string file = FileContents("elf-32-1"); TestAssembleToStreamDisassemble(file, 135988); } + +TEST_F(EncodeDecodeTest, Elf_HighBSS) { + std::string file = FileContents("elf-32-high-bss"); + TestAssembleToStreamDisassemble(file, 7308); +}
diff --git a/courgette/testdata/elf-32-high-bss b/courgette/testdata/elf-32-high-bss new file mode 100755 index 0000000..b9445c8 --- /dev/null +++ b/courgette/testdata/elf-32-high-bss Binary files differ
diff --git a/device/hid/BUILD.gn b/device/hid/BUILD.gn index b0375731..4a6a1b2 100644 --- a/device/hid/BUILD.gn +++ b/device/hid/BUILD.gn
@@ -6,6 +6,8 @@ sources = [ "device_monitor_linux.cc", "device_monitor_linux.h", + "fake_input_service_linux.cc", + "fake_input_service_linux.h", "hid_collection_info.cc", "hid_collection_info.h", "hid_connection.cc",
diff --git a/device/hid/fake_input_service_linux.cc b/device/hid/fake_input_service_linux.cc new file mode 100644 index 0000000..ae3f085 --- /dev/null +++ b/device/hid/fake_input_service_linux.cc
@@ -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 "device/hid/fake_input_service_linux.h" + +#include <string> +#include <vector> + +namespace device { + +FakeInputServiceLinux::FakeInputServiceLinux() { +} + +FakeInputServiceLinux::~FakeInputServiceLinux() { +} + +void FakeInputServiceLinux::AddDeviceForTesting(const InputDeviceInfo& info) { + AddDevice(info); +} + +void FakeInputServiceLinux::RemoveDeviceForTesting(const std::string& id) { + RemoveDevice(id); +} + +void FakeInputServiceLinux::ClearDeviceList() { + devices_.clear(); +} + +} // namespace device \ No newline at end of file
diff --git a/device/hid/fake_input_service_linux.h b/device/hid/fake_input_service_linux.h new file mode 100644 index 0000000..1b46d98 --- /dev/null +++ b/device/hid/fake_input_service_linux.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 DEVICE_HID_FAKE_INPUT_SERVICE_LINUX_H_ +#define DEVICE_HID_FAKE_INPUT_SERVICE_LINUX_H_ + +#include <string> + +#include "device/hid/input_service_linux.h" + +namespace device { + +class FakeInputServiceLinux : public InputServiceLinux { + + public: + FakeInputServiceLinux(); + ~FakeInputServiceLinux() override; + + void AddDeviceForTesting(const InputDeviceInfo& info); + void RemoveDeviceForTesting(const std::string& id); + void ClearDeviceList(); + + DISALLOW_COPY_AND_ASSIGN(FakeInputServiceLinux); +}; + +} // namespace device + +#endif // DEVICE_HID_FAKE_INPUT_SERVICE_LINUX_H_
diff --git a/device/hid/hid.gyp b/device/hid/hid.gyp index 42215d75..00b9a90 100644 --- a/device/hid/hid.gyp +++ b/device/hid/hid.gyp
@@ -21,6 +21,8 @@ 'sources': [ 'device_monitor_linux.cc', 'device_monitor_linux.h', + 'fake_input_service_linux.cc', + 'fake_input_service_linux.h', 'hid_collection_info.cc', 'hid_collection_info.h', 'hid_connection.cc', @@ -66,6 +68,8 @@ 'device_monitor_linux.h', 'hid_service_linux.cc', 'hid_service_linux.h', + 'fake_input_service_linux.cc', + 'fake_input_service_linux.h', 'input_service_linux.cc', 'input_service_linux.h', ],
diff --git a/device/hid/input_service_linux.cc b/device/hid/input_service_linux.cc index f6fd0dce..81cac1a 100644 --- a/device/hid/input_service_linux.cc +++ b/device/hid/input_service_linux.cc
@@ -90,6 +90,9 @@ }; InputServiceLinuxImpl::InputServiceLinuxImpl() { + base::ThreadRestrictions::AssertIOAllowed(); + base::MessageLoop::current()->AddDestructionObserver(this); + DeviceMonitorLinux::GetInstance()->AddObserver(this); DeviceMonitorLinux::GetInstance()->Enumerate(base::Bind( &InputServiceLinuxImpl::OnDeviceAdded, base::Unretained(this))); @@ -98,6 +101,7 @@ InputServiceLinuxImpl::~InputServiceLinuxImpl() { if (DeviceMonitorLinux::HasInstance()) DeviceMonitorLinux::GetInstance()->RemoveObserver(this); + base::MessageLoop::current()->RemoveDestructionObserver(this); } void InputServiceLinuxImpl::OnDeviceAdded(udev_device* device) { @@ -162,13 +166,10 @@ is_touchscreen(false) {} InputServiceLinux::InputServiceLinux() { - base::ThreadRestrictions::AssertIOAllowed(); - base::MessageLoop::current()->AddDestructionObserver(this); } InputServiceLinux::~InputServiceLinux() { DCHECK(CalledOnValidThread()); - base::MessageLoop::current()->RemoveDestructionObserver(this); } // static
diff --git a/device/hid/input_service_linux.h b/device/hid/input_service_linux.h index 55bf70c..7eda3bb81 100644 --- a/device/hid/input_service_linux.h +++ b/device/hid/input_service_linux.h
@@ -45,6 +45,9 @@ bool is_touchscreen : 1; }; + + using DeviceMap = base::hash_map<std::string, InputDeviceInfo>; + class Observer { public: virtual ~Observer() {} @@ -53,6 +56,7 @@ }; InputServiceLinux(); + ~InputServiceLinux() override; static InputServiceLinux* GetInstance(); static bool HasInstance(); @@ -73,21 +77,18 @@ void WillDestroyCurrentMessageLoop() override; protected: - ~InputServiceLinux() override; void AddDevice(const InputDeviceInfo& info); void RemoveDevice(const std::string& id); bool CalledOnValidThread() const; - private: - friend struct base::DefaultDeleter<InputServiceLinux>; - - typedef base::hash_map<std::string, InputDeviceInfo> DeviceMap; - DeviceMap devices_; ObserverList<Observer> observers_; + private: + friend struct base::DefaultDeleter<InputServiceLinux>; + base::ThreadChecker thread_checker_; DISALLOW_COPY_AND_ASSIGN(InputServiceLinux);
diff --git a/extensions/browser/api/power/power_api.cc b/extensions/browser/api/power/power_api.cc index d731b9f..13dbbab1 100644 --- a/extensions/browser/api/power/power_api.cc +++ b/extensions/browser/api/power/power_api.cc
@@ -4,24 +4,128 @@ #include "extensions/browser/api/power/power_api.h" -#include "extensions/browser/api/power/power_api_manager.h" +#include "base/bind.h" +#include "base/lazy_instance.h" +#include "extensions/browser/extension_registry.h" #include "extensions/common/api/power.h" +#include "extensions/common/extension.h" namespace extensions { +namespace { + +const char kPowerSaveBlockerDescription[] = "extension"; + +content::PowerSaveBlocker::PowerSaveBlockerType LevelToPowerSaveBlockerType( + core_api::power::Level level) { + switch (level) { + case core_api::power::LEVEL_SYSTEM: + return content::PowerSaveBlocker::kPowerSaveBlockPreventAppSuspension; + case core_api::power::LEVEL_DISPLAY: // fallthrough + case core_api::power::LEVEL_NONE: + return content::PowerSaveBlocker::kPowerSaveBlockPreventDisplaySleep; + } + NOTREACHED() << "Unhandled level " << level; + return content::PowerSaveBlocker::kPowerSaveBlockPreventDisplaySleep; +} + +base::LazyInstance<BrowserContextKeyedAPIFactory<PowerAPI>> g_factory = + LAZY_INSTANCE_INITIALIZER; + +} // namespace + bool PowerRequestKeepAwakeFunction::RunSync() { scoped_ptr<core_api::power::RequestKeepAwake::Params> params( core_api::power::RequestKeepAwake::Params::Create(*args_)); EXTENSION_FUNCTION_VALIDATE(params); EXTENSION_FUNCTION_VALIDATE(params->level != core_api::power::LEVEL_NONE); - PowerApiManager::Get(browser_context())->AddRequest( - extension_id(), params->level); + PowerAPI::Get(browser_context())->AddRequest(extension_id(), params->level); return true; } bool PowerReleaseKeepAwakeFunction::RunSync() { - PowerApiManager::Get(browser_context())->RemoveRequest(extension_id()); + PowerAPI::Get(browser_context())->RemoveRequest(extension_id()); return true; } +// static +PowerAPI* PowerAPI::Get(content::BrowserContext* context) { + return BrowserContextKeyedAPIFactory<PowerAPI>::Get(context); +} + +// static +BrowserContextKeyedAPIFactory<PowerAPI>* PowerAPI::GetFactoryInstance() { + return g_factory.Pointer(); +} + +void PowerAPI::AddRequest(const std::string& extension_id, + core_api::power::Level level) { + extension_levels_[extension_id] = level; + UpdatePowerSaveBlocker(); +} + +void PowerAPI::RemoveRequest(const std::string& extension_id) { + extension_levels_.erase(extension_id); + UpdatePowerSaveBlocker(); +} + +void PowerAPI::SetCreateBlockerFunctionForTesting( + CreateBlockerFunction function) { + create_blocker_function_ = + !function.is_null() ? function + : base::Bind(&content::PowerSaveBlocker::Create); +} + +void PowerAPI::OnExtensionUnloaded(content::BrowserContext* browser_context, + const Extension* extension, + UnloadedExtensionInfo::Reason reason) { + RemoveRequest(extension->id()); + UpdatePowerSaveBlocker(); +} + +PowerAPI::PowerAPI(content::BrowserContext* context) + : browser_context_(context), + create_blocker_function_(base::Bind(&content::PowerSaveBlocker::Create)), + current_level_(core_api::power::LEVEL_SYSTEM) { + ExtensionRegistry::Get(browser_context_)->AddObserver(this); +} + +PowerAPI::~PowerAPI() { +} + +void PowerAPI::UpdatePowerSaveBlocker() { + if (extension_levels_.empty()) { + power_save_blocker_.reset(); + return; + } + + core_api::power::Level new_level = core_api::power::LEVEL_SYSTEM; + for (ExtensionLevelMap::const_iterator it = extension_levels_.begin(); + it != extension_levels_.end(); ++it) { + if (it->second == core_api::power::LEVEL_DISPLAY) + new_level = it->second; + } + + // If the level changed and we need to create a new blocker, do a swap + // to ensure that there isn't a brief period where power management is + // unblocked. + if (!power_save_blocker_ || new_level != current_level_) { + content::PowerSaveBlocker::PowerSaveBlockerType type = + LevelToPowerSaveBlockerType(new_level); + scoped_ptr<content::PowerSaveBlocker> new_blocker( + create_blocker_function_.Run(type, + content::PowerSaveBlocker::kReasonOther, + kPowerSaveBlockerDescription)); + power_save_blocker_.swap(new_blocker); + current_level_ = new_level; + } +} + +void PowerAPI::Shutdown() { + // Unregister here rather than in the d'tor; otherwise this call will recreate + // the already-deleted ExtensionRegistry. + ExtensionRegistry::Get(browser_context_)->RemoveObserver(this); + power_save_blocker_.reset(); +} + } // namespace extensions
diff --git a/extensions/browser/api/power/power_api.h b/extensions/browser/api/power/power_api.h index 228e517b..7a4a752d 100644 --- a/extensions/browser/api/power/power_api.h +++ b/extensions/browser/api/power/power_api.h
@@ -5,7 +5,20 @@ #ifndef EXTENSIONS_BROWSER_API_POWER_POWER_API_H_ #define EXTENSIONS_BROWSER_API_POWER_POWER_API_H_ +#include <map> +#include <string> + +#include "base/callback.h" +#include "base/memory/scoped_ptr.h" +#include "content/public/browser/power_save_blocker.h" +#include "extensions/browser/browser_context_keyed_api_factory.h" #include "extensions/browser/extension_function.h" +#include "extensions/browser/extension_registry_observer.h" +#include "extensions/common/api/power.h" + +namespace content { +class BrowserContext; +} namespace extensions { @@ -33,6 +46,77 @@ bool RunSync() override; }; +// Handles calls made via the chrome.power API. There is a separate instance of +// this class for each profile, as requests are tracked by extension ID, but a +// regular and incognito profile will share the same instance. +class PowerAPI : public BrowserContextKeyedAPI, + public extensions::ExtensionRegistryObserver { + public: + typedef base::Callback<scoped_ptr<content::PowerSaveBlocker>( + content::PowerSaveBlocker::PowerSaveBlockerType, + content::PowerSaveBlocker::Reason, + const std::string&)> CreateBlockerFunction; + + static PowerAPI* Get(content::BrowserContext* context); + + // BrowserContextKeyedAPI implementation. + static BrowserContextKeyedAPIFactory<PowerAPI>* GetFactoryInstance(); + + // Adds an extension lock at |level| for |extension_id|, replacing the + // extension's existing lock, if any. + void AddRequest(const std::string& extension_id, + core_api::power::Level level); + + // Removes an extension lock for an extension. Calling this for an + // extension id without a lock will do nothing. + void RemoveRequest(const std::string& extension_id); + + // Replaces the function that will be called to create PowerSaveBlocker + // objects. Passing an empty callback will revert to the default. + void SetCreateBlockerFunctionForTesting(CreateBlockerFunction function); + + // Overridden from extensions::ExtensionRegistryObserver. + void OnExtensionUnloaded(content::BrowserContext* browser_context, + const Extension* extension, + UnloadedExtensionInfo::Reason reason) override; + + private: + friend class BrowserContextKeyedAPIFactory<PowerAPI>; + + explicit PowerAPI(content::BrowserContext* context); + ~PowerAPI() override; + + // Updates |power_save_blocker_| and |current_level_| after iterating + // over |extension_levels_|. + void UpdatePowerSaveBlocker(); + + // BrowserContextKeyedAPI implementation. + static const char* service_name() { return "PowerAPI"; } + static const bool kServiceRedirectedInIncognito = true; + static const bool kServiceIsCreatedWithBrowserContext = false; + void Shutdown() override; + + content::BrowserContext* browser_context_; + + // Function that should be called to create PowerSaveBlocker objects. + // Tests can change this to record what would've been done instead of + // actually changing the system power-saving settings. + CreateBlockerFunction create_blocker_function_; + + scoped_ptr<content::PowerSaveBlocker> power_save_blocker_; + + // Current level used by |power_save_blocker_|. Meaningless if + // |power_save_blocker_| is NULL. + core_api::power::Level current_level_; + + // Map from extension ID to the corresponding level for each extension + // that has an outstanding request. + typedef std::map<std::string, core_api::power::Level> ExtensionLevelMap; + ExtensionLevelMap extension_levels_; + + DISALLOW_COPY_AND_ASSIGN(PowerAPI); +}; + } // namespace extensions #endif // EXTENSIONS_BROWSER_API_POWER_POWER_API_H_
diff --git a/extensions/browser/api/power/power_api_manager.cc b/extensions/browser/api/power/power_api_manager.cc deleted file mode 100644 index 642e794..0000000 --- a/extensions/browser/api/power/power_api_manager.cc +++ /dev/null
@@ -1,116 +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 "extensions/browser/api/power/power_api_manager.h" - -#include "base/bind.h" -#include "base/lazy_instance.h" -#include "extensions/browser/extension_registry.h" -#include "extensions/common/extension.h" - -namespace extensions { - -namespace { - -const char kPowerSaveBlockerDescription[] = "extension"; - -content::PowerSaveBlocker::PowerSaveBlockerType -LevelToPowerSaveBlockerType(core_api::power::Level level) { - switch (level) { - case core_api::power::LEVEL_SYSTEM: - return content::PowerSaveBlocker::kPowerSaveBlockPreventAppSuspension; - case core_api::power::LEVEL_DISPLAY: // fallthrough - case core_api::power::LEVEL_NONE: - return content::PowerSaveBlocker::kPowerSaveBlockPreventDisplaySleep; - } - NOTREACHED() << "Unhandled level " << level; - return content::PowerSaveBlocker::kPowerSaveBlockPreventDisplaySleep; -} - -base::LazyInstance<BrowserContextKeyedAPIFactory<PowerApiManager> > g_factory = - LAZY_INSTANCE_INITIALIZER; - -} // namespace - -// static -PowerApiManager* PowerApiManager::Get(content::BrowserContext* context) { - return BrowserContextKeyedAPIFactory<PowerApiManager>::Get(context); -} - -// static -BrowserContextKeyedAPIFactory<PowerApiManager>* -PowerApiManager::GetFactoryInstance() { - return g_factory.Pointer(); -} - -void PowerApiManager::AddRequest(const std::string& extension_id, - core_api::power::Level level) { - extension_levels_[extension_id] = level; - UpdatePowerSaveBlocker(); -} - -void PowerApiManager::RemoveRequest(const std::string& extension_id) { - extension_levels_.erase(extension_id); - UpdatePowerSaveBlocker(); -} - -void PowerApiManager::SetCreateBlockerFunctionForTesting( - CreateBlockerFunction function) { - create_blocker_function_ = !function.is_null() ? function : - base::Bind(&content::PowerSaveBlocker::Create); -} - -void PowerApiManager::OnExtensionUnloaded( - content::BrowserContext* browser_context, - const Extension* extension, - UnloadedExtensionInfo::Reason reason) { - RemoveRequest(extension->id()); - UpdatePowerSaveBlocker(); -} - -PowerApiManager::PowerApiManager(content::BrowserContext* context) - : browser_context_(context), - create_blocker_function_(base::Bind(&content::PowerSaveBlocker::Create)), - current_level_(core_api::power::LEVEL_SYSTEM) { - ExtensionRegistry::Get(browser_context_)->AddObserver(this); -} - -PowerApiManager::~PowerApiManager() {} - -void PowerApiManager::UpdatePowerSaveBlocker() { - if (extension_levels_.empty()) { - power_save_blocker_.reset(); - return; - } - - core_api::power::Level new_level = core_api::power::LEVEL_SYSTEM; - for (ExtensionLevelMap::const_iterator it = extension_levels_.begin(); - it != extension_levels_.end(); ++it) { - if (it->second == core_api::power::LEVEL_DISPLAY) - new_level = it->second; - } - - // If the level changed and we need to create a new blocker, do a swap - // to ensure that there isn't a brief period where power management is - // unblocked. - if (!power_save_blocker_ || new_level != current_level_) { - content::PowerSaveBlocker::PowerSaveBlockerType type = - LevelToPowerSaveBlockerType(new_level); - scoped_ptr<content::PowerSaveBlocker> new_blocker( - create_blocker_function_.Run(type, - content::PowerSaveBlocker::kReasonOther, - kPowerSaveBlockerDescription)); - power_save_blocker_.swap(new_blocker); - current_level_ = new_level; - } -} - -void PowerApiManager::Shutdown() { - // Unregister here rather than in the d'tor; otherwise this call will recreate - // the already-deleted ExtensionRegistry. - ExtensionRegistry::Get(browser_context_)->RemoveObserver(this); - power_save_blocker_.reset(); -} - -} // namespace extensions
diff --git a/extensions/browser/api/power/power_api_manager.h b/extensions/browser/api/power/power_api_manager.h deleted file mode 100644 index 4037811..0000000 --- a/extensions/browser/api/power/power_api_manager.h +++ /dev/null
@@ -1,98 +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 EXTENSIONS_BROWSER_API_POWER_POWER_API_MANAGER_H_ -#define EXTENSIONS_BROWSER_API_POWER_POWER_API_MANAGER_H_ - -#include <map> -#include <string> - -#include "base/callback.h" -#include "base/memory/scoped_ptr.h" -#include "content/public/browser/power_save_blocker.h" -#include "extensions/browser/browser_context_keyed_api_factory.h" -#include "extensions/browser/extension_registry_observer.h" -#include "extensions/common/api/power.h" - -namespace content { -class BrowserContext; -} - -namespace extensions { - -// Handles calls made via the chrome.power API. There is a separate instance of -// this class for each profile, as requests are tracked by extension ID, but a -// regular and incognito profile will share the same instance. -// TODO(derat): Move this to power_api.h and rename it to PowerApi. -class PowerApiManager : public BrowserContextKeyedAPI, - public extensions::ExtensionRegistryObserver { - public: - typedef base::Callback<scoped_ptr<content::PowerSaveBlocker>( - content::PowerSaveBlocker::PowerSaveBlockerType, - content::PowerSaveBlocker::Reason, - const std::string&)> CreateBlockerFunction; - - static PowerApiManager* Get(content::BrowserContext* context); - - // BrowserContextKeyedAPI implementation. - static BrowserContextKeyedAPIFactory<PowerApiManager>* GetFactoryInstance(); - - // Adds an extension lock at |level| for |extension_id|, replacing the - // extension's existing lock, if any. - void AddRequest(const std::string& extension_id, - core_api::power::Level level); - - // Removes an extension lock for an extension. Calling this for an - // extension id without a lock will do nothing. - void RemoveRequest(const std::string& extension_id); - - // Replaces the function that will be called to create PowerSaveBlocker - // objects. Passing an empty callback will revert to the default. - void SetCreateBlockerFunctionForTesting(CreateBlockerFunction function); - - // Overridden from extensions::ExtensionRegistryObserver. - void OnExtensionUnloaded(content::BrowserContext* browser_context, - const Extension* extension, - UnloadedExtensionInfo::Reason reason) override; - - private: - friend class BrowserContextKeyedAPIFactory<PowerApiManager>; - - explicit PowerApiManager(content::BrowserContext* context); - ~PowerApiManager() override; - - // Updates |power_save_blocker_| and |current_level_| after iterating - // over |extension_levels_|. - void UpdatePowerSaveBlocker(); - - // BrowserContextKeyedAPI implementation. - static const char* service_name() { return "PowerApiManager"; } - static const bool kServiceRedirectedInIncognito = true; - static const bool kServiceIsCreatedWithBrowserContext = false; - void Shutdown() override; - - content::BrowserContext* browser_context_; - - // Function that should be called to create PowerSaveBlocker objects. - // Tests can change this to record what would've been done instead of - // actually changing the system power-saving settings. - CreateBlockerFunction create_blocker_function_; - - scoped_ptr<content::PowerSaveBlocker> power_save_blocker_; - - // Current level used by |power_save_blocker_|. Meaningless if - // |power_save_blocker_| is NULL. - core_api::power::Level current_level_; - - // Map from extension ID to the corresponding level for each extension - // that has an outstanding request. - typedef std::map<std::string, core_api::power::Level> ExtensionLevelMap; - ExtensionLevelMap extension_levels_; - - DISALLOW_COPY_AND_ASSIGN(PowerApiManager); -}; - -} // namespace extensions - -#endif // EXTENSIONS_BROWSER_API_POWER_POWER_API_MANAGER_H_
diff --git a/extensions/browser/api/power/power_api_unittest.cc b/extensions/browser/api/power/power_api_unittest.cc index e4e0a07..eb6c6a2 100644 --- a/extensions/browser/api/power/power_api_unittest.cc +++ b/extensions/browser/api/power/power_api_unittest.cc
@@ -12,7 +12,6 @@ #include "base/memory/scoped_ptr.h" #include "base/memory/weak_ptr.h" #include "content/public/browser/power_save_blocker.h" -#include "extensions/browser/api/power/power_api_manager.h" #include "extensions/browser/api_test_utils.h" #include "extensions/browser/api_unittest.h" #include "extensions/common/extension.h" @@ -56,7 +55,7 @@ }; // Manages PowerSaveBlockerStub objects. Tests can instantiate this class -// to make PowerApiManager's calls to create PowerSaveBlockers record the +// to make PowerAPI's calls to create PowerSaveBlockers record the // actions that would've been performed instead of actually blocking and // unblocking power management. class PowerSaveBlockerStubManager { @@ -66,14 +65,14 @@ weak_ptr_factory_(this) { // Use base::Unretained since callbacks with return values can't use // weak pointers. - PowerApiManager::Get(browser_context_)->SetCreateBlockerFunctionForTesting( - base::Bind(&PowerSaveBlockerStubManager::CreateStub, - base::Unretained(this))); + PowerAPI::Get(browser_context_) + ->SetCreateBlockerFunctionForTesting(base::Bind( + &PowerSaveBlockerStubManager::CreateStub, base::Unretained(this))); } ~PowerSaveBlockerStubManager() { - PowerApiManager::Get(browser_context_)->SetCreateBlockerFunctionForTesting( - PowerApiManager::CreateBlockerFunction()); + PowerAPI::Get(browser_context_) + ->SetCreateBlockerFunctionForTesting(PowerAPI::CreateBlockerFunction()); } // Removes and returns the first item from |requests_|. Returns NONE if @@ -127,7 +126,7 @@ } // namespace -class PowerApiTest : public ApiUnitTest { +class PowerAPITest : public ApiUnitTest { public: void SetUp() override { ApiUnitTest::SetUp(); @@ -162,17 +161,18 @@ return api_test_utils::RunFunction(function.get(), args, browser_context()); } - // Send a notification to PowerApiManager saying that |extension| has + // Send a notification to PowerAPI saying that |extension| has // been unloaded. void UnloadExtension(const extensions::Extension* extension) { - PowerApiManager::Get(browser_context())->OnExtensionUnloaded( - browser_context(), extension, UnloadedExtensionInfo::REASON_UNINSTALL); + PowerAPI::Get(browser_context()) + ->OnExtensionUnloaded(browser_context(), extension, + UnloadedExtensionInfo::REASON_UNINSTALL); } scoped_ptr<PowerSaveBlockerStubManager> manager_; }; -TEST_F(PowerApiTest, RequestAndRelease) { +TEST_F(PowerAPITest, RequestAndRelease) { // Simulate an extension making and releasing a "display" request and a // "system" request. ASSERT_TRUE(CallFunction(REQUEST, kDisplayArgs, extension())); @@ -190,7 +190,7 @@ EXPECT_EQ(NONE, manager_->PopFirstRequest()); } -TEST_F(PowerApiTest, RequestWithoutRelease) { +TEST_F(PowerAPITest, RequestWithoutRelease) { // Simulate an extension calling requestKeepAwake() without calling // releaseKeepAwake(). The override should be automatically removed when // the extension is unloaded. @@ -203,14 +203,14 @@ EXPECT_EQ(NONE, manager_->PopFirstRequest()); } -TEST_F(PowerApiTest, ReleaseWithoutRequest) { +TEST_F(PowerAPITest, ReleaseWithoutRequest) { // Simulate an extension calling releaseKeepAwake() without having // calling requestKeepAwake() earlier. The call should be ignored. ASSERT_TRUE(CallFunction(RELEASE, kEmptyArgs, extension())); EXPECT_EQ(NONE, manager_->PopFirstRequest()); } -TEST_F(PowerApiTest, UpgradeRequest) { +TEST_F(PowerAPITest, UpgradeRequest) { // Simulate an extension calling requestKeepAwake("system") and then // requestKeepAwake("display"). When the second call is made, a // display-sleep-blocking request should be made before the initial @@ -229,7 +229,7 @@ EXPECT_EQ(NONE, manager_->PopFirstRequest()); } -TEST_F(PowerApiTest, DowngradeRequest) { +TEST_F(PowerAPITest, DowngradeRequest) { // Simulate an extension calling requestKeepAwake("display") and then // requestKeepAwake("system"). When the second call is made, an // app-suspension-blocking request should be made before the initial @@ -248,7 +248,7 @@ EXPECT_EQ(NONE, manager_->PopFirstRequest()); } -TEST_F(PowerApiTest, MultipleExtensions) { +TEST_F(PowerAPITest, MultipleExtensions) { // Simulate an extension blocking the display from sleeping. ASSERT_TRUE(CallFunction(REQUEST, kDisplayArgs, extension())); EXPECT_EQ(BLOCK_DISPLAY_SLEEP, manager_->PopFirstRequest());
diff --git a/extensions/browser/app_window/app_window.cc b/extensions/browser/app_window/app_window.cc index a508074..7d0e7c3 100644 --- a/extensions/browser/app_window/app_window.cc +++ b/extensions/browser/app_window/app_window.cc
@@ -238,6 +238,7 @@ is_hidden_(false), cached_always_on_top_(false), requested_alpha_enabled_(false), + is_ime_window_(false), image_loader_ptr_factory_(this) { ExtensionsBrowserClient* client = ExtensionsBrowserClient::Get(); CHECK(!client->IsGuestSession(context) || context->IsOffTheRecord()) @@ -273,6 +274,8 @@ requested_alpha_enabled_ = new_params.alpha_enabled; + is_ime_window_ = params.is_ime_window; + AppWindowClient* app_window_client = AppWindowClient::Get(); native_app_window_.reset( app_window_client->CreateNativeAppWindow(this, &new_params));
diff --git a/extensions/browser/app_window/app_window.h b/extensions/browser/app_window/app_window.h index c7abf3d9..6c0e135 100644 --- a/extensions/browser/app_window/app_window.h +++ b/extensions/browser/app_window/app_window.h
@@ -351,6 +351,12 @@ // Whether the app window wants to be alpha enabled. bool requested_alpha_enabled() const { return requested_alpha_enabled_; } + // Whether the app window is created by IME extensions. + // TODO(bshe): rename to hide_app_window_in_launcher if it is not used + // anywhere other than app_window_launcher_controller after M45. Otherwise, + // remove this TODO. + bool is_ime_window() const { return is_ime_window_; } + void SetAppWindowContentsForTesting(scoped_ptr<AppWindowContents> contents) { app_window_contents_ = contents.Pass(); } @@ -559,6 +565,9 @@ // Whether |alpha_enabled| was set in the CreateParams. bool requested_alpha_enabled_; + // Whether |is_ime_window| was set in the CreateParams. + bool is_ime_window_; + base::WeakPtrFactory<AppWindow> image_loader_ptr_factory_; DISALLOW_COPY_AND_ASSIGN(AppWindow);
diff --git a/extensions/browser/extension_function.cc b/extensions/browser/extension_function.cc index b970fe3..6a136b2c 100644 --- a/extensions/browser/extension_function.cc +++ b/extensions/browser/extension_function.cc
@@ -404,7 +404,7 @@ if (!results_) results_.reset(new base::ListValue()); - response_callback_.Run(type, *results_, GetError()); + response_callback_.Run(type, *results_, GetError(), histogram_value()); } void ExtensionFunction::OnRespondingLater(ResponseValue value) {
diff --git a/extensions/browser/extension_function.h b/extensions/browser/extension_function.h index 9385719..f9a2a79d 100644 --- a/extensions/browser/extension_function.h +++ b/extensions/browser/extension_function.h
@@ -100,9 +100,11 @@ BAD_MESSAGE }; - typedef base::Callback<void(ResponseType type, - const base::ListValue& results, - const std::string& error)> ResponseCallback; + using ResponseCallback = base::Callback<void( + ResponseType type, + const base::ListValue& results, + const std::string& error, + extensions::functions::HistogramValue histogram_value)>; ExtensionFunction();
diff --git a/extensions/browser/extension_function_dispatcher.cc b/extensions/browser/extension_function_dispatcher.cc index cbc08cca..fcf4ab4 100644 --- a/extensions/browser/extension_function_dispatcher.cc +++ b/extensions/browser/extension_function_dispatcher.cc
@@ -9,6 +9,7 @@ #include "base/lazy_instance.h" #include "base/logging.h" #include "base/memory/ref_counted.h" +#include "base/metrics/histogram_macros.h" #include "base/metrics/sparse_histogram.h" #include "base/process/process.h" #include "base/profiler/scoped_profile.h" @@ -81,9 +82,14 @@ base::LazyInstance<Static> g_global_io_data = LAZY_INSTANCE_INITIALIZER; // Kills the specified process because it sends us a malformed message. -void KillBadMessageSender(base::ProcessHandle process) { +// Track the specific function's |histogram_value|, as this may indicate a bug +// in that API's implementation on the renderer. +void KillBadMessageSender(base::ProcessHandle process, + functions::HistogramValue histogram_value) { NOTREACHED(); content::RecordAction(base::UserMetricsAction("BadMessageTerminate_EFD")); + UMA_HISTOGRAM_ENUMERATION("Extensions.BadMessageFunctionName", + histogram_value, functions::ENUM_BOUNDARY); if (process) base::KillProcess(process, content::RESULT_CODE_KILLED_BAD_MESSAGE, false); } @@ -94,7 +100,8 @@ int request_id, ExtensionFunction::ResponseType type, const base::ListValue& results, - const std::string& error) { + const std::string& error, + functions::HistogramValue histogram_value) { DCHECK(ipc_sender); if (type == ExtensionFunction::BAD_MESSAGE) { @@ -108,9 +115,8 @@ // In single process mode it is better if we don't suicide but just crash. CHECK(false); } else { - KillBadMessageSender(peer_process); + KillBadMessageSender(peer_process, histogram_value); } - return; } @@ -125,17 +131,13 @@ int request_id, ExtensionFunction::ResponseType type, const base::ListValue& results, - const std::string& error) { + const std::string& error, + functions::HistogramValue histogram_value) { if (!ipc_sender.get()) return; - CommonResponseCallback(ipc_sender.get(), - routing_id, - ipc_sender->PeerHandle(), - request_id, - type, - results, - error); + CommonResponseCallback(ipc_sender.get(), routing_id, ipc_sender->PeerHandle(), + request_id, type, results, error, histogram_value); } } // namespace @@ -180,11 +182,11 @@ void OnExtensionFunctionCompleted(int request_id, ExtensionFunction::ResponseType type, const base::ListValue& results, - const std::string& error) { - CommonResponseCallback( - render_view_host_, render_view_host_->GetRoutingID(), - render_view_host_->GetProcess()->GetHandle(), request_id, type, - results, error); + const std::string& error, + functions::HistogramValue histogram_value) { + CommonResponseCallback(render_view_host_, render_view_host_->GetRoutingID(), + render_view_host_->GetProcess()->GetHandle(), + request_id, type, results, error, histogram_value); } base::WeakPtr<ExtensionFunctionDispatcher> dispatcher_; @@ -438,7 +440,7 @@ const ExtensionFunction::ResponseCallback& callback) { if (!function->HasPermission()) { LOG(ERROR) << "Permission denied for " << params.name; - SendAccessDenied(callback); + SendAccessDenied(callback, function->histogram_value()); return false; } return true; @@ -457,7 +459,7 @@ ExtensionFunctionRegistry::GetInstance()->NewFunction(params.name); if (!function) { LOG(ERROR) << "Unknown Extension API - " << params.name; - SendAccessDenied(callback); + SendAccessDenied(callback, function->histogram_value()); return NULL; } @@ -478,10 +480,11 @@ // static void ExtensionFunctionDispatcher::SendAccessDenied( - const ExtensionFunction::ResponseCallback& callback) { + const ExtensionFunction::ResponseCallback& callback, + functions::HistogramValue histogram_value) { base::ListValue empty_list; callback.Run(ExtensionFunction::FAILED, empty_list, - "Access to extension API denied."); + "Access to extension API denied.", histogram_value); } } // namespace extensions
diff --git a/extensions/browser/extension_function_dispatcher.h b/extensions/browser/extension_function_dispatcher.h index 0ae80dc..9224bbde 100644 --- a/extensions/browser/extension_function_dispatcher.h +++ b/extensions/browser/extension_function_dispatcher.h
@@ -146,7 +146,8 @@ // Helper to run the response callback with an access denied error. Can be // called on any thread. static void SendAccessDenied( - const ExtensionFunction::ResponseCallback& callback); + const ExtensionFunction::ResponseCallback& callback, + functions::HistogramValue histogram_value); void DispatchWithCallbackInternal( const ExtensionHostMsg_Request_Params& params,
diff --git a/extensions/browser/extension_host.cc b/extensions/browser/extension_host.cc index 973c1a49..61d0626d 100644 --- a/extensions/browser/extension_host.cc +++ b/extensions/browser/extension_host.cc
@@ -13,8 +13,6 @@ #include "content/public/browser/content_browser_client.h" #include "content/public/browser/native_web_keyboard_event.h" #include "content/public/browser/notification_service.h" -#include "content/public/browser/notification_source.h" -#include "content/public/browser/notification_types.h" #include "content/public/browser/render_process_host.h" #include "content/public/browser/render_view_host.h" #include "content/public/browser/render_widget_host_view.h" @@ -25,6 +23,7 @@ #include "extensions/browser/extension_host_delegate.h" #include "extensions/browser/extension_host_observer.h" #include "extensions/browser/extension_host_queue.h" +#include "extensions/browser/extension_registry.h" #include "extensions/browser/extension_system.h" #include "extensions/browser/extensions_browser_client.h" #include "extensions/browser/load_monitoring_extension_host_queue.h" @@ -77,15 +76,15 @@ // Listen for when an extension is unloaded from the same profile, as it may // be the same extension that this points to. - registrar_.Add(this, - extensions::NOTIFICATION_EXTENSION_UNLOADED_DEPRECATED, - content::Source<BrowserContext>(browser_context_)); + ExtensionRegistry::Get(browser_context_)->AddObserver(this); // Set up web contents observers and pref observers. delegate_->OnExtensionHostCreated(host_contents()); } ExtensionHost::~ExtensionHost() { + ExtensionRegistry::Get(browser_context_)->RemoveObserver(this); + if (extension_host_type_ == VIEW_TYPE_EXTENSION_BACKGROUND_PAGE && extension_ && BackgroundInfo::HasLazyBackgroundPage(extension_) && load_start_.get()) { @@ -210,23 +209,15 @@ return true; } -void ExtensionHost::Observe(int type, - const content::NotificationSource& source, - const content::NotificationDetails& details) { - switch (type) { - case extensions::NOTIFICATION_EXTENSION_UNLOADED_DEPRECATED: - // The extension object will be deleted after this notification has been - // sent. Null it out so that dirty pointer issues don't arise in cases - // when multiple ExtensionHost objects pointing to the same Extension are - // present. - if (extension_ == content::Details<UnloadedExtensionInfo>(details)-> - extension) { - extension_ = nullptr; - } - break; - default: - NOTREACHED() << "Unexpected notification sent."; - break; +void ExtensionHost::OnExtensionUnloaded( + content::BrowserContext* browser_context, + const Extension* extension, + UnloadedExtensionInfo::Reason reason) { + // The extension object will be deleted after this notification has been sent. + // Null it out so that dirty pointer issues don't arise in cases when multiple + // ExtensionHost objects pointing to the same Extension are present. + if (extension_ == extension) { + extension_ = nullptr; } }
diff --git a/extensions/browser/extension_host.h b/extensions/browser/extension_host.h index 953dc99..c308874 100644 --- a/extensions/browser/extension_host.h +++ b/extensions/browser/extension_host.h
@@ -7,18 +7,16 @@ #include <set> #include <string> -#include <vector> #include "base/logging.h" #include "base/memory/scoped_ptr.h" #include "base/observer_list.h" #include "base/timer/elapsed_timer.h" -#include "content/public/browser/notification_observer.h" -#include "content/public/browser/notification_registrar.h" #include "content/public/browser/web_contents_delegate.h" #include "content/public/browser/web_contents_observer.h" #include "extensions/browser/deferred_start_render_host.h" #include "extensions/browser/extension_function_dispatcher.h" +#include "extensions/browser/extension_registry_observer.h" #include "extensions/common/stack_frame.h" #include "extensions/common/view_type.h" @@ -49,7 +47,7 @@ public content::WebContentsDelegate, public content::WebContentsObserver, public ExtensionFunctionDispatcher::Delegate, - public content::NotificationObserver { + public ExtensionRegistryObserver { public: ExtensionHost(const Extension* extension, content::SiteInstance* site_instance, @@ -127,14 +125,12 @@ content::MediaStreamType type) override; bool IsNeverVisible(content::WebContents* web_contents) override; - // content::NotificationObserver: - void Observe(int type, - const content::NotificationSource& source, - const content::NotificationDetails& details) override; + // ExtensionRegistryObserver: + void OnExtensionUnloaded(content::BrowserContext* browser_context, + const Extension* extension, + UnloadedExtensionInfo::Reason reason) override; protected: - content::NotificationRegistrar* registrar() { return ®istrar_; } - // Called after the extension page finishes loading but before the // EXTENSION_HOST_DID_STOP_LOADING notification is sent. virtual void OnDidStopLoading(); @@ -191,8 +187,6 @@ // Messages sent out to the renderer that have not been acknowledged yet. std::set<int> unacked_messages_; - content::NotificationRegistrar registrar_; - ExtensionFunctionDispatcher extension_function_dispatcher_; // The type of view being hosted.
diff --git a/extensions/extensions.gypi b/extensions/extensions.gypi index bc780bab..4c2e6cd 100644 --- a/extensions/extensions.gypi +++ b/extensions/extensions.gypi
@@ -383,8 +383,6 @@ 'browser/api/networking_private/networking_private_event_router_factory.h', 'browser/api/power/power_api.cc', 'browser/api/power/power_api.h', - 'browser/api/power/power_api_manager.cc', - 'browser/api/power/power_api_manager.h', 'browser/api/printer_provider/printer_provider_api.cc', 'browser/api/printer_provider/printer_provider_api.h', 'browser/api/printer_provider/printer_provider_api_factory.cc',
diff --git a/extensions/renderer/resources/binding.js b/extensions/renderer/resources/binding.js index b1a3efca..22ccb7bd 100644 --- a/extensions/renderer/resources/binding.js +++ b/extensions/renderer/resources/binding.js
@@ -275,13 +275,35 @@ mod = mod[name]; } - // Add types to global schemaValidator, the types we depend on from other - // namespaces will be added as needed. if (schema.types) { $Array.forEach(schema.types, function(t) { if (!isSchemaNodeSupported(t, platform, manifestVersion)) return; + + // Add types to global schemaValidator; the types we depend on from + // other namespaces will be added as needed. schemaUtils.schemaValidator.addTypes(t); + + // Generate symbols for enums. + var enumValues = t['enum']; + if (enumValues) { + // Type IDs are qualified with the namespace during compilation, + // unfortunately, so remove it here. + logging.DCHECK( + t.id.substr(0, schema.namespace.length) == schema.namespace); + // Note: + 1 because it ends in a '.', e.g., 'fooApi.Type'. + var id = t.id.substr(schema.namespace.length + 1); + mod[id] = {}; + $Array.forEach(enumValues, function(enumValue) { + // Note: enums can be declared either as a list of strings + // ['foo', 'bar'] or as a list of objects + // [{'name': 'foo'}, {'name': 'bar'}]. + enumValue = + enumValue.hasOwnProperty('name') ? enumValue.name : enumValue; + if (enumValue) // Avoid setting any empty enums. + mod[id][enumValue] = enumValue; + }); + } }, this); }
diff --git a/extensions/shell/BUILD.gn b/extensions/shell/BUILD.gn index 70aef276..2e12978 100644 --- a/extensions/shell/BUILD.gn +++ b/extensions/shell/BUILD.gn
@@ -127,7 +127,7 @@ } } -if (!(is_chromeos && !use_ozone) && (!is_win || link_chrome_on_windows)) { +if (!(is_chromeos && !use_ozone)) { executable("app_shell") { # testonly because :app_shell_lib is testonly. See :app_shell_lib comment. testonly = true
diff --git a/google_apis/BUILD.gn b/google_apis/BUILD.gn index 1eae08f..b8ab4b6 100644 --- a/google_apis/BUILD.gn +++ b/google_apis/BUILD.gn
@@ -198,45 +198,43 @@ } } -if (!is_win || link_chrome_on_windows) { - test("google_apis_unittests") { - sources = [ - "gaia/gaia_auth_fetcher_unittest.cc", - "gaia/gaia_auth_util_unittest.cc", - "gaia/gaia_oauth_client_unittest.cc", - "gaia/google_service_auth_error_unittest.cc", - "gaia/merge_session_helper_unittest.cc", - "gaia/oauth2_access_token_fetcher_impl_unittest.cc", - "gaia/oauth2_api_call_flow_unittest.cc", - "gaia/oauth2_mint_token_flow_unittest.cc", - "gaia/oauth2_token_service_unittest.cc", - "gaia/oauth_request_signer_unittest.cc", - "gaia/ubertoken_fetcher_unittest.cc", - "google_api_keys_unittest.cc", +test("google_apis_unittests") { + sources = [ + "gaia/gaia_auth_fetcher_unittest.cc", + "gaia/gaia_auth_util_unittest.cc", + "gaia/gaia_oauth_client_unittest.cc", + "gaia/google_service_auth_error_unittest.cc", + "gaia/merge_session_helper_unittest.cc", + "gaia/oauth2_access_token_fetcher_impl_unittest.cc", + "gaia/oauth2_api_call_flow_unittest.cc", + "gaia/oauth2_mint_token_flow_unittest.cc", + "gaia/oauth2_token_service_unittest.cc", + "gaia/oauth_request_signer_unittest.cc", + "gaia/ubertoken_fetcher_unittest.cc", + "google_api_keys_unittest.cc", + ] + + configs += [ ":key_defines" ] + + deps = [ + ":google_apis", + ":test_support", + "//base", + "//base/test:run_all_unittests", + "//testing/gmock", + "//testing/gtest", + ] + + if (enable_extensions) { + sources += [ + "drive/base_requests_server_unittest.cc", + "drive/base_requests_unittest.cc", + "drive/drive_api_parser_unittest.cc", + "drive/drive_api_requests_unittest.cc", + "drive/drive_api_url_generator_unittest.cc", + "drive/request_sender_unittest.cc", + "drive/request_util_unittest.cc", + "drive/time_util_unittest.cc", ] - - configs += [ ":key_defines" ] - - deps = [ - ":google_apis", - ":test_support", - "//base", - "//base/test:run_all_unittests", - "//testing/gmock", - "//testing/gtest", - ] - - if (enable_extensions) { - sources += [ - "drive/base_requests_server_unittest.cc", - "drive/base_requests_unittest.cc", - "drive/drive_api_parser_unittest.cc", - "drive/drive_api_requests_unittest.cc", - "drive/drive_api_url_generator_unittest.cc", - "drive/request_sender_unittest.cc", - "drive/request_util_unittest.cc", - "drive/time_util_unittest.cc", - ] - } } }
diff --git a/gpu/BUILD.gn b/gpu/BUILD.gn index 86888bd..830464e9 100644 --- a/gpu/BUILD.gn +++ b/gpu/BUILD.gn
@@ -66,221 +66,219 @@ ] } -if (!is_win || link_chrome_on_windows) { - test("gl_tests") { - sources = [ - "command_buffer/tests/compressed_texture_test.cc", - "command_buffer/tests/gl_bind_uniform_location_unittest.cc", - "command_buffer/tests/gl_chromium_framebuffer_multisample_unittest.cc", - "command_buffer/tests/gl_chromium_path_rendering_unittest.cc", - "command_buffer/tests/gl_clear_framebuffer_unittest.cc", - "command_buffer/tests/gl_copy_texture_CHROMIUM_unittest.cc", - "command_buffer/tests/gl_depth_texture_unittest.cc", - "command_buffer/tests/gl_gpu_memory_buffer_unittest.cc", - "command_buffer/tests/gl_lose_context_chromium_unittest.cc", - "command_buffer/tests/gl_manager.cc", - "command_buffer/tests/gl_manager.h", - "command_buffer/tests/gl_pointcoord_unittest.cc", - "command_buffer/tests/gl_program_unittest.cc", - "command_buffer/tests/gl_query_unittest.cc", - "command_buffer/tests/gl_readback_unittest.cc", - "command_buffer/tests/gl_shared_resources_unittest.cc", - "command_buffer/tests/gl_stream_draw_unittest.cc", - "command_buffer/tests/gl_test_utils.cc", - "command_buffer/tests/gl_test_utils.h", - "command_buffer/tests/gl_tests_main.cc", - "command_buffer/tests/gl_texture_mailbox_unittest.cc", - "command_buffer/tests/gl_texture_storage_unittest.cc", - "command_buffer/tests/gl_unittest.cc", - "command_buffer/tests/gl_unittests_android.cc", - "command_buffer/tests/gl_virtual_contexts_unittest.cc", - "command_buffer/tests/occlusion_query_unittest.cc", - ] +test("gl_tests") { + sources = [ + "command_buffer/tests/compressed_texture_test.cc", + "command_buffer/tests/gl_bind_uniform_location_unittest.cc", + "command_buffer/tests/gl_chromium_framebuffer_multisample_unittest.cc", + "command_buffer/tests/gl_chromium_path_rendering_unittest.cc", + "command_buffer/tests/gl_clear_framebuffer_unittest.cc", + "command_buffer/tests/gl_copy_texture_CHROMIUM_unittest.cc", + "command_buffer/tests/gl_depth_texture_unittest.cc", + "command_buffer/tests/gl_gpu_memory_buffer_unittest.cc", + "command_buffer/tests/gl_lose_context_chromium_unittest.cc", + "command_buffer/tests/gl_manager.cc", + "command_buffer/tests/gl_manager.h", + "command_buffer/tests/gl_pointcoord_unittest.cc", + "command_buffer/tests/gl_program_unittest.cc", + "command_buffer/tests/gl_query_unittest.cc", + "command_buffer/tests/gl_readback_unittest.cc", + "command_buffer/tests/gl_shared_resources_unittest.cc", + "command_buffer/tests/gl_stream_draw_unittest.cc", + "command_buffer/tests/gl_test_utils.cc", + "command_buffer/tests/gl_test_utils.h", + "command_buffer/tests/gl_tests_main.cc", + "command_buffer/tests/gl_texture_mailbox_unittest.cc", + "command_buffer/tests/gl_texture_storage_unittest.cc", + "command_buffer/tests/gl_unittest.cc", + "command_buffer/tests/gl_unittests_android.cc", + "command_buffer/tests/gl_virtual_contexts_unittest.cc", + "command_buffer/tests/occlusion_query_unittest.cc", + ] - defines = [ "GL_GLEXT_PROTOTYPES" ] + defines = [ "GL_GLEXT_PROTOTYPES" ] - configs += [ "//build/config/compiler:no_size_t_to_int_warning" ] + configs += [ "//build/config/compiler:no_size_t_to_int_warning" ] - deps = [ - ":gpu", - ":test_support", - "//base", - "//base/test:test_support", - "//base/third_party/dynamic_annotations", - "//testing/gmock", - "//testing/gtest", - "//third_party/angle:translator", - "//ui/gfx", - "//ui/gfx:test_support", - "//ui/gfx/geometry", - "//ui/gl", - "//gpu/command_buffer/common:gles2_utils", - "//gpu/command_buffer/client:gles2_c_lib", - "//gpu/command_buffer/client:gles2_implementation", - ] + deps = [ + ":gpu", + ":test_support", + "//base", + "//base/test:test_support", + "//base/third_party/dynamic_annotations", + "//testing/gmock", + "//testing/gtest", + "//third_party/angle:translator", + "//ui/gfx", + "//ui/gfx:test_support", + "//ui/gfx/geometry", + "//ui/gl", + "//gpu/command_buffer/common:gles2_utils", + "//gpu/command_buffer/client:gles2_c_lib", + "//gpu/command_buffer/client:gles2_implementation", + ] - libs = [] + libs = [] - if (is_android) { - deps += [ "//testing/android:native_test_native_code" ] - libs += [ "android" ] - } - - # TODO(GYP) - # ['OS == "win"', { - # 'dependencies': [ - # '../third_party/angle/src/build_angle.gyp:libEGL', - # '../third_party/angle/src/build_angle.gyp:libGLESv2', - # ], - # }], + if (is_android) { + deps += [ "//testing/android:native_test_native_code" ] + libs += [ "android" ] } - test("gpu_unittests") { - sources = [ - "command_buffer/client/buffer_tracker_unittest.cc", - "command_buffer/client/client_test_helper.cc", - "command_buffer/client/client_test_helper.h", - "command_buffer/client/cmd_buffer_helper_test.cc", - "command_buffer/client/fenced_allocator_test.cc", - "command_buffer/client/gles2_implementation_unittest.cc", - "command_buffer/client/mapped_memory_unittest.cc", - "command_buffer/client/program_info_manager_unittest.cc", - "command_buffer/client/query_tracker_unittest.cc", - "command_buffer/client/ring_buffer_test.cc", - "command_buffer/client/transfer_buffer_unittest.cc", - "command_buffer/client/vertex_array_object_manager_unittest.cc", - "command_buffer/common/bitfield_helpers_test.cc", - "command_buffer/common/command_buffer_mock.cc", - "command_buffer/common/command_buffer_mock.h", - "command_buffer/common/command_buffer_shared_test.cc", - "command_buffer/common/debug_marker_manager_unittest.cc", - "command_buffer/common/gles2_cmd_format_test.cc", - "command_buffer/common/gles2_cmd_format_test_autogen.h", - "command_buffer/common/gles2_cmd_utils_unittest.cc", - "command_buffer/common/id_allocator_test.cc", - "command_buffer/common/trace_event.h", - "command_buffer/common/unittest_main.cc", - "command_buffer/service/async_pixel_transfer_delegate_mock.cc", - "command_buffer/service/async_pixel_transfer_delegate_mock.h", - "command_buffer/service/async_pixel_transfer_manager_mock.cc", - "command_buffer/service/async_pixel_transfer_manager_mock.h", - "command_buffer/service/buffer_manager_unittest.cc", - "command_buffer/service/cmd_parser_test.cc", - "command_buffer/service/command_buffer_service_unittest.cc", - "command_buffer/service/common_decoder_unittest.cc", - "command_buffer/service/context_group_unittest.cc", - "command_buffer/service/feature_info_unittest.cc", - "command_buffer/service/framebuffer_manager_unittest.cc", - "command_buffer/service/gl_surface_mock.cc", - "command_buffer/service/gl_surface_mock.h", - "command_buffer/service/gles2_cmd_decoder_unittest.cc", - "command_buffer/service/gles2_cmd_decoder_unittest.h", - "command_buffer/service/gles2_cmd_decoder_unittest_0_autogen.h", - "command_buffer/service/gles2_cmd_decoder_unittest_1.cc", - "command_buffer/service/gles2_cmd_decoder_unittest_1_autogen.h", - "command_buffer/service/gles2_cmd_decoder_unittest_2.cc", - "command_buffer/service/gles2_cmd_decoder_unittest_2_autogen.h", - "command_buffer/service/gles2_cmd_decoder_unittest_3.cc", - "command_buffer/service/gles2_cmd_decoder_unittest_3_autogen.h", - "command_buffer/service/gles2_cmd_decoder_unittest_async_pixel.cc", - "command_buffer/service/gles2_cmd_decoder_unittest_attribs.cc", - "command_buffer/service/gles2_cmd_decoder_unittest_base.cc", - "command_buffer/service/gles2_cmd_decoder_unittest_base.h", - "command_buffer/service/gles2_cmd_decoder_unittest_context_state.cc", - "command_buffer/service/gles2_cmd_decoder_unittest_drawing.cc", - "command_buffer/service/gles2_cmd_decoder_unittest_extensions.cc", - "command_buffer/service/gles2_cmd_decoder_unittest_framebuffers.cc", - "command_buffer/service/gles2_cmd_decoder_unittest_programs.cc", - "command_buffer/service/gles2_cmd_decoder_unittest_textures.cc", - "command_buffer/service/gles2_cmd_decoder_unittest_valuebuffer.cc", - "command_buffer/service/gpu_scheduler_unittest.cc", - "command_buffer/service/gpu_service_test.cc", - "command_buffer/service/gpu_service_test.h", - "command_buffer/service/gpu_tracer_unittest.cc", - "command_buffer/service/id_manager_unittest.cc", - "command_buffer/service/mailbox_manager_unittest.cc", - "command_buffer/service/memory_program_cache_unittest.cc", - "command_buffer/service/mocks.cc", - "command_buffer/service/mocks.h", - "command_buffer/service/program_cache_unittest.cc", - "command_buffer/service/program_manager_unittest.cc", - "command_buffer/service/query_manager_unittest.cc", - "command_buffer/service/renderbuffer_manager_unittest.cc", - "command_buffer/service/shader_manager_unittest.cc", - "command_buffer/service/shader_translator_cache_unittest.cc", - "command_buffer/service/shader_translator_unittest.cc", - "command_buffer/service/test_helper.cc", - "command_buffer/service/test_helper.h", - "command_buffer/service/texture_manager_unittest.cc", - "command_buffer/service/transfer_buffer_manager_unittest.cc", - "command_buffer/service/valuebuffer_manager_unittest.cc", - "command_buffer/service/vertex_array_manager_unittest.cc", - "command_buffer/service/vertex_attrib_manager_unittest.cc", - "config/gpu_blacklist_unittest.cc", - "config/gpu_control_list_entry_unittest.cc", - "config/gpu_control_list_number_info_unittest.cc", - "config/gpu_control_list_os_info_unittest.cc", - "config/gpu_control_list_unittest.cc", - "config/gpu_control_list_version_info_unittest.cc", - "config/gpu_driver_bug_list_unittest.cc", - "config/gpu_info_collector_unittest.cc", - "config/gpu_info_unittest.cc", - "config/gpu_test_config_unittest.cc", - "config/gpu_test_expectations_parser_unittest.cc", - "config/gpu_util_unittest.cc", - ] + # TODO(GYP) + # ['OS == "win"', { + # 'dependencies': [ + # '../third_party/angle/src/build_angle.gyp:libEGL', + # '../third_party/angle/src/build_angle.gyp:libGLESv2', + # ], + # }], +} - configs += [ "//build/config/compiler:no_size_t_to_int_warning" ] +test("gpu_unittests") { + sources = [ + "command_buffer/client/buffer_tracker_unittest.cc", + "command_buffer/client/client_test_helper.cc", + "command_buffer/client/client_test_helper.h", + "command_buffer/client/cmd_buffer_helper_test.cc", + "command_buffer/client/fenced_allocator_test.cc", + "command_buffer/client/gles2_implementation_unittest.cc", + "command_buffer/client/mapped_memory_unittest.cc", + "command_buffer/client/program_info_manager_unittest.cc", + "command_buffer/client/query_tracker_unittest.cc", + "command_buffer/client/ring_buffer_test.cc", + "command_buffer/client/transfer_buffer_unittest.cc", + "command_buffer/client/vertex_array_object_manager_unittest.cc", + "command_buffer/common/bitfield_helpers_test.cc", + "command_buffer/common/command_buffer_mock.cc", + "command_buffer/common/command_buffer_mock.h", + "command_buffer/common/command_buffer_shared_test.cc", + "command_buffer/common/debug_marker_manager_unittest.cc", + "command_buffer/common/gles2_cmd_format_test.cc", + "command_buffer/common/gles2_cmd_format_test_autogen.h", + "command_buffer/common/gles2_cmd_utils_unittest.cc", + "command_buffer/common/id_allocator_test.cc", + "command_buffer/common/trace_event.h", + "command_buffer/common/unittest_main.cc", + "command_buffer/service/async_pixel_transfer_delegate_mock.cc", + "command_buffer/service/async_pixel_transfer_delegate_mock.h", + "command_buffer/service/async_pixel_transfer_manager_mock.cc", + "command_buffer/service/async_pixel_transfer_manager_mock.h", + "command_buffer/service/buffer_manager_unittest.cc", + "command_buffer/service/cmd_parser_test.cc", + "command_buffer/service/command_buffer_service_unittest.cc", + "command_buffer/service/common_decoder_unittest.cc", + "command_buffer/service/context_group_unittest.cc", + "command_buffer/service/feature_info_unittest.cc", + "command_buffer/service/framebuffer_manager_unittest.cc", + "command_buffer/service/gl_surface_mock.cc", + "command_buffer/service/gl_surface_mock.h", + "command_buffer/service/gles2_cmd_decoder_unittest.cc", + "command_buffer/service/gles2_cmd_decoder_unittest.h", + "command_buffer/service/gles2_cmd_decoder_unittest_0_autogen.h", + "command_buffer/service/gles2_cmd_decoder_unittest_1.cc", + "command_buffer/service/gles2_cmd_decoder_unittest_1_autogen.h", + "command_buffer/service/gles2_cmd_decoder_unittest_2.cc", + "command_buffer/service/gles2_cmd_decoder_unittest_2_autogen.h", + "command_buffer/service/gles2_cmd_decoder_unittest_3.cc", + "command_buffer/service/gles2_cmd_decoder_unittest_3_autogen.h", + "command_buffer/service/gles2_cmd_decoder_unittest_async_pixel.cc", + "command_buffer/service/gles2_cmd_decoder_unittest_attribs.cc", + "command_buffer/service/gles2_cmd_decoder_unittest_base.cc", + "command_buffer/service/gles2_cmd_decoder_unittest_base.h", + "command_buffer/service/gles2_cmd_decoder_unittest_context_state.cc", + "command_buffer/service/gles2_cmd_decoder_unittest_drawing.cc", + "command_buffer/service/gles2_cmd_decoder_unittest_extensions.cc", + "command_buffer/service/gles2_cmd_decoder_unittest_framebuffers.cc", + "command_buffer/service/gles2_cmd_decoder_unittest_programs.cc", + "command_buffer/service/gles2_cmd_decoder_unittest_textures.cc", + "command_buffer/service/gles2_cmd_decoder_unittest_valuebuffer.cc", + "command_buffer/service/gpu_scheduler_unittest.cc", + "command_buffer/service/gpu_service_test.cc", + "command_buffer/service/gpu_service_test.h", + "command_buffer/service/gpu_tracer_unittest.cc", + "command_buffer/service/id_manager_unittest.cc", + "command_buffer/service/mailbox_manager_unittest.cc", + "command_buffer/service/memory_program_cache_unittest.cc", + "command_buffer/service/mocks.cc", + "command_buffer/service/mocks.h", + "command_buffer/service/program_cache_unittest.cc", + "command_buffer/service/program_manager_unittest.cc", + "command_buffer/service/query_manager_unittest.cc", + "command_buffer/service/renderbuffer_manager_unittest.cc", + "command_buffer/service/shader_manager_unittest.cc", + "command_buffer/service/shader_translator_cache_unittest.cc", + "command_buffer/service/shader_translator_unittest.cc", + "command_buffer/service/test_helper.cc", + "command_buffer/service/test_helper.h", + "command_buffer/service/texture_manager_unittest.cc", + "command_buffer/service/transfer_buffer_manager_unittest.cc", + "command_buffer/service/valuebuffer_manager_unittest.cc", + "command_buffer/service/vertex_array_manager_unittest.cc", + "command_buffer/service/vertex_attrib_manager_unittest.cc", + "config/gpu_blacklist_unittest.cc", + "config/gpu_control_list_entry_unittest.cc", + "config/gpu_control_list_number_info_unittest.cc", + "config/gpu_control_list_os_info_unittest.cc", + "config/gpu_control_list_unittest.cc", + "config/gpu_control_list_version_info_unittest.cc", + "config/gpu_driver_bug_list_unittest.cc", + "config/gpu_info_collector_unittest.cc", + "config/gpu_info_unittest.cc", + "config/gpu_test_config_unittest.cc", + "config/gpu_test_expectations_parser_unittest.cc", + "config/gpu_util_unittest.cc", + ] - deps = [ - ":gpu", - ":test_support", - "//base", - "//base/test:test_support", - "//base/third_party/dynamic_annotations", - "//testing/gmock", - "//testing/gtest", - "//third_party/angle:translator", - "//ui/gfx", - "//ui/gfx:test_support", - "//ui/gfx/geometry", - "//ui/gl", - "//gpu/command_buffer/common:gles2_utils", - "//gpu/command_buffer/client:gles2_c_lib", - "//gpu/command_buffer/client:gles2_implementation", - ] - } + configs += [ "//build/config/compiler:no_size_t_to_int_warning" ] - test("gpu_perftests") { - sources = [ - "perftests/measurements.cc", - "perftests/run_all_tests.cc", - "perftests/texture_upload_perftest.cc", - ] + deps = [ + ":gpu", + ":test_support", + "//base", + "//base/test:test_support", + "//base/third_party/dynamic_annotations", + "//testing/gmock", + "//testing/gtest", + "//third_party/angle:translator", + "//ui/gfx", + "//ui/gfx:test_support", + "//ui/gfx/geometry", + "//ui/gl", + "//gpu/command_buffer/common:gles2_utils", + "//gpu/command_buffer/client:gles2_c_lib", + "//gpu/command_buffer/client:gles2_implementation", + ] +} - deps = [ - "//base", - "//base/test:test_support", - "//gpu/command_buffer/service", - "//testing/gtest", - "//testing/perf", - "//ui/gfx/geometry", - "//ui/gl", - ] - } +test("gpu_perftests") { + sources = [ + "perftests/measurements.cc", + "perftests/run_all_tests.cc", + "perftests/texture_upload_perftest.cc", + ] - test("angle_unittests") { - sources = [ - "angle_unittest_main.cc", - ] + deps = [ + "//base", + "//base/test:test_support", + "//gpu/command_buffer/service", + "//testing/gtest", + "//testing/perf", + "//ui/gfx/geometry", + "//ui/gl", + ] +} - deps = [ - "//base", - "//base/test:test_support", - "//base/third_party/dynamic_annotations", - "//testing/gmock", - "//testing/gtest", - "//third_party/angle:translator_static", - ] - } +test("angle_unittests") { + sources = [ + "angle_unittest_main.cc", + ] + + deps = [ + "//base", + "//base/test:test_support", + "//base/third_party/dynamic_annotations", + "//testing/gmock", + "//testing/gtest", + "//third_party/angle:translator_static", + ] }
diff --git a/gpu/command_buffer/client/gles2_implementation_unittest.cc b/gpu/command_buffer/client/gles2_implementation_unittest.cc index 2acbc635..3af9413 100644 --- a/gpu/command_buffer/client/gles2_implementation_unittest.cc +++ b/gpu/command_buffer/client/gles2_implementation_unittest.cc
@@ -381,8 +381,7 @@ static const GLuint kMaxTransformFeedbackSeparateAttribs = 4; static const GLuint kMaxUniformBufferBindings = 36; static const GLuint kStartId = 1024; - static const GLuint kBuffersStartId = - GLES2Implementation::kClientSideArrayId + 2 * kNumTestContexts; + static const GLuint kBuffersStartId = 1; static const GLuint kFramebuffersStartId = 1; static const GLuint kProgramsAndShadersStartId = 1; static const GLuint kRenderbuffersStartId = 1;
diff --git a/gpu/command_buffer/common/id_allocator.cc b/gpu/command_buffer/common/id_allocator.cc index 507b14e..eccb468 100644 --- a/gpu/command_buffer/common/id_allocator.cc +++ b/gpu/command_buffer/common/id_allocator.cc
@@ -6,84 +6,200 @@ #include "gpu/command_buffer/common/id_allocator.h" +#include <limits> #include "base/logging.h" namespace gpu { -IdAllocator::IdAllocator() {} +IdAllocator::IdAllocator() { + COMPILE_ASSERT(kInvalidResource == 0u, invalid_resource_is_not_zero); + // Simplify the code by making sure that lower_bound(id) never + // returns the beginning of the map, if id is valid (eg != + // kInvalidResource). + used_ids_.insert(std::make_pair(0u, 0u)); +} IdAllocator::~IdAllocator() {} ResourceId IdAllocator::AllocateID() { - ResourceId id; - ResourceIdSet::iterator iter = free_ids_.begin(); - if (iter != free_ids_.end()) { - id = *iter; - } else { - id = LastUsedId() + 1; - if (!id) { - // We wrapped around to 0. - id = FindFirstUnusedId(); - } - } - MarkAsUsed(id); - return id; + return AllocateIDRange(1u); } ResourceId IdAllocator::AllocateIDAtOrAbove(ResourceId desired_id) { - ResourceId id; - ResourceIdSet::iterator iter = free_ids_.lower_bound(desired_id); - if (iter != free_ids_.end()) { - id = *iter; - } else if (LastUsedId() < desired_id) { - id = desired_id; - } else { - id = LastUsedId() + 1; - if (!id) { - // We wrapped around to 0. - id = FindFirstUnusedId(); - } + if (desired_id == 0u || desired_id == 1u) { + return AllocateIDRange(1u); } - MarkAsUsed(id); - return id; + + ResourceIdRangeMap::iterator current = used_ids_.lower_bound(desired_id); + ResourceIdRangeMap::iterator next = current; + if (current == used_ids_.end() || current->first > desired_id) { + current--; + } else { + next++; + } + + ResourceId first_id = current->first; + ResourceId last_id = current->second; + + DCHECK(desired_id >= first_id); + + if (desired_id - 1u <= last_id) { + // Append to current range. + last_id++; + if (last_id == 0) { + // The increment overflowed. + return AllocateIDRange(1u); + } + + current->second = last_id; + + if (next != used_ids_.end() && next->first - 1u == last_id) { + // Merge with next range. + current->second = next->second; + used_ids_.erase(next); + } + return last_id; + } else if (next != used_ids_.end() && next->first - 1u == desired_id) { + // Prepend to next range. + ResourceId last_existing_id = next->second; + used_ids_.erase(next); + used_ids_.insert(std::make_pair(desired_id, last_existing_id)); + return desired_id; + } + used_ids_.insert(std::make_pair(desired_id, desired_id)); + return desired_id; +} + +ResourceId IdAllocator::AllocateIDRange(uint32_t range) { + DCHECK(range > 0u); + + ResourceIdRangeMap::iterator current = used_ids_.begin(); + ResourceIdRangeMap::iterator next = current; + + while (++next != used_ids_.end()) { + if (next->first - current->second > range) { + break; + } + current = next; + } + + ResourceId first_id = current->second + 1u; + ResourceId last_id = first_id + range - 1u; + + if (first_id == 0u || last_id < first_id) { + return kInvalidResource; + } + + current->second = last_id; + + if (next != used_ids_.end() && next->first - 1u == last_id) { + // Merge with next range. + current->second = next->second; + used_ids_.erase(next); + } + + return first_id; } bool IdAllocator::MarkAsUsed(ResourceId id) { DCHECK(id); - free_ids_.erase(id); - std::pair<ResourceIdSet::iterator, bool> result = used_ids_.insert(id); - return result.second; + ResourceIdRangeMap::iterator current = used_ids_.lower_bound(id); + if (current != used_ids_.end() && current->first == id) { + return false; + } + + ResourceIdRangeMap::iterator next = current; + --current; + + if (current->second >= id) { + return false; + } + + DCHECK(current->first < id && current->second < id); + + if (current->second + 1u == id) { + // Append to current range. + current->second = id; + if (next != used_ids_.end() && next->first - 1u == id) { + // Merge with next range. + current->second = next->second; + used_ids_.erase(next); + } + return true; + } else if (next != used_ids_.end() && next->first - 1u == id) { + // Prepend to next range. + ResourceId last_existing_id = next->second; + used_ids_.erase(next); + used_ids_.insert(std::make_pair(id, last_existing_id)); + return true; + } + + used_ids_.insert(std::make_pair(id, id)); + return true; } void IdAllocator::FreeID(ResourceId id) { - if (id) { - used_ids_.erase(id); - free_ids_.insert(id); + FreeIDRange(id, 1u); +} + +void IdAllocator::FreeIDRange(ResourceId first_id, uint32 range) { + COMPILE_ASSERT(kInvalidResource == 0u, invalid_resource_is_not_zero); + + if (range == 0u || (first_id == 0u && range == 1u)) { + return; + } + + if (first_id == 0u) { + first_id++; + range--; + } + + ResourceId last_id = first_id + range - 1u; + if (last_id < first_id) { + last_id = std::numeric_limits<ResourceId>::max(); + } + + while (true) { + ResourceIdRangeMap::iterator current = used_ids_.lower_bound(last_id); + if (current == used_ids_.end() || current->first > last_id) { + --current; + } + + if (current->second < first_id) { + return; + } + + if (current->first >= first_id) { + ResourceId last_existing_id = current->second; + used_ids_.erase(current); + if (last_id < last_existing_id) { + used_ids_.insert(std::make_pair(last_id + 1u, last_existing_id)); + } + } else if (current->second <= last_id) { + current->second = first_id - 1u; + } else { + DCHECK(current->first < first_id && current->second > last_id); + ResourceId last_existing_id = current->second; + current->second = first_id - 1u; + used_ids_.insert(std::make_pair(last_id + 1u, last_existing_id)); + } } } bool IdAllocator::InUse(ResourceId id) const { - return id == kInvalidResource || used_ids_.find(id) != used_ids_.end(); -} - -ResourceId IdAllocator::LastUsedId() const { - if (used_ids_.empty()) { - return 0u; - } else { - return *used_ids_.rbegin(); + if (id == kInvalidResource) { + return false; } -} -ResourceId IdAllocator::FindFirstUnusedId() const { - ResourceId id = 1; - for (ResourceIdSet::const_iterator it = used_ids_.begin(); - it != used_ids_.end(); ++it) { - if ((*it) != id) { - return id; + ResourceIdRangeMap::const_iterator current = used_ids_.lower_bound(id); + if (current != used_ids_.end()) { + if (current->first == id) { + return true; } - ++id; } - return id; + + --current; + return current->second >= id; } } // namespace gpu
diff --git a/gpu/command_buffer/common/id_allocator.h b/gpu/command_buffer/common/id_allocator.h index b8770830..118424f 100644 --- a/gpu/command_buffer/common/id_allocator.h +++ b/gpu/command_buffer/common/id_allocator.h
@@ -9,7 +9,7 @@ #include <stdint.h> -#include <set> +#include <map> #include <utility> #include "base/compiler_specific.h" @@ -36,27 +36,28 @@ // Note: may wrap if it starts near limit. ResourceId AllocateIDAtOrAbove(ResourceId desired_id); + // Allocates |range| amount of contiguous ids. + // Returns the first id to |first_id| or |kInvalidResource| if + // allocation failed. + ResourceId AllocateIDRange(uint32_t range); + // Marks an id as used. Returns false if id was already used. bool MarkAsUsed(ResourceId id); // Frees a resource ID. void FreeID(ResourceId id); + // Frees a |range| amount of contiguous ids, starting from |first_id|. + void FreeIDRange(ResourceId first_id, uint32_t range); + // Checks whether or not a resource ID is in use. bool InUse(ResourceId id) const; private: - // TODO(gman): This would work much better with ranges or a hash table. - typedef std::set<ResourceId> ResourceIdSet; + // first_id -> last_id mapping. + typedef std::map<ResourceId, ResourceId> ResourceIdRangeMap; - // The highest ID on the used list. - ResourceId LastUsedId() const; - - // Lowest ID that isn't on the used list. This is slow, use as a last resort. - ResourceId FindFirstUnusedId() const; - - ResourceIdSet used_ids_; - ResourceIdSet free_ids_; + ResourceIdRangeMap used_ids_; DISALLOW_COPY_AND_ASSIGN(IdAllocator); };
diff --git a/gpu/command_buffer/common/id_allocator_test.cc b/gpu/command_buffer/common/id_allocator_test.cc index adeed5b0..7d93906 100644 --- a/gpu/command_buffer/common/id_allocator_test.cc +++ b/gpu/command_buffer/common/id_allocator_test.cc
@@ -125,4 +125,123 @@ EXPECT_NE(kInvalidResource, id3); } +TEST_F(IdAllocatorTest, AllocateIDRange) { + const ResourceId kMaxPossibleOffset = std::numeric_limits<ResourceId>::max(); + + IdAllocator* allocator = id_allocator(); + + ResourceId id1 = allocator->AllocateIDRange(1); + EXPECT_EQ(1u, id1); + ResourceId id2 = allocator->AllocateIDRange(2); + EXPECT_EQ(2u, id2); + ResourceId id3 = allocator->AllocateIDRange(3); + EXPECT_EQ(4u, id3); + ResourceId id4 = allocator->AllocateID(); + EXPECT_EQ(7u, id4); + allocator->FreeID(3); + ResourceId id5 = allocator->AllocateIDRange(1); + EXPECT_EQ(3u, id5); + allocator->FreeID(5); + allocator->FreeID(2); + allocator->FreeID(4); + ResourceId id6 = allocator->AllocateIDRange(2); + EXPECT_EQ(4u, id6); + ResourceId id7 = allocator->AllocateIDAtOrAbove(kMaxPossibleOffset); + EXPECT_EQ(kMaxPossibleOffset, id7); + ResourceId id8 = allocator->AllocateIDAtOrAbove(kMaxPossibleOffset); + EXPECT_EQ(2u, id8); + ResourceId id9 = allocator->AllocateIDRange(50); + EXPECT_EQ(8u, id9); + ResourceId id10 = allocator->AllocateIDRange(50); + EXPECT_EQ(58u, id10); + // Remove all the low-numbered ids. + allocator->FreeID(1); + allocator->FreeID(15); + allocator->FreeIDRange(2, 107); + ResourceId id11 = allocator->AllocateIDRange(100); + EXPECT_EQ(1u, id11); + allocator->FreeID(kMaxPossibleOffset); + ResourceId id12 = allocator->AllocateIDRange(100); + EXPECT_EQ(101u, id12); + + ResourceId id13 = allocator->AllocateIDAtOrAbove(kMaxPossibleOffset - 2u); + EXPECT_EQ(kMaxPossibleOffset - 2u, id13); + ResourceId id14 = allocator->AllocateIDRange(3); + EXPECT_EQ(201u, id14); +} + +TEST_F(IdAllocatorTest, AllocateIDRangeEndNoEffect) { + const ResourceId kMaxPossibleOffset = std::numeric_limits<ResourceId>::max(); + + IdAllocator* allocator = id_allocator(); + ResourceId id1 = allocator->AllocateIDAtOrAbove(kMaxPossibleOffset - 2u); + EXPECT_EQ(kMaxPossibleOffset - 2u, id1); + ResourceId id3 = allocator->AllocateIDRange(3); + EXPECT_EQ(1u, id3); + ResourceId id2 = allocator->AllocateIDRange(2); + EXPECT_EQ(4u, id2); +} + +TEST_F(IdAllocatorTest, AllocateFullIDRange) { + const uint32_t kMaxPossibleRange = std::numeric_limits<uint32_t>::max(); + const ResourceId kFreedId = 555u; + IdAllocator* allocator = id_allocator(); + + ResourceId id1 = allocator->AllocateIDRange(kMaxPossibleRange); + EXPECT_EQ(1u, id1); + ResourceId id2 = allocator->AllocateID(); + EXPECT_EQ(0u, id2); + allocator->FreeID(kFreedId); + ResourceId id3 = allocator->AllocateID(); + EXPECT_EQ(kFreedId, id3); + ResourceId id4 = allocator->AllocateID(); + EXPECT_EQ(0u, id4); + allocator->FreeID(kFreedId + 1u); + allocator->FreeID(kFreedId + 4u); + allocator->FreeID(kFreedId + 3u); + allocator->FreeID(kFreedId + 5u); + allocator->FreeID(kFreedId + 2u); + ResourceId id5 = allocator->AllocateIDRange(5); + EXPECT_EQ(kFreedId + 1u, id5); +} + +TEST_F(IdAllocatorTest, AllocateIDRangeNoWrapInRange) { + const uint32_t kMaxPossibleRange = std::numeric_limits<uint32_t>::max(); + const ResourceId kAllocId = 10u; + IdAllocator* allocator = id_allocator(); + + ResourceId id1 = allocator->AllocateIDAtOrAbove(kAllocId); + EXPECT_EQ(kAllocId, id1); + ResourceId id2 = allocator->AllocateIDRange(kMaxPossibleRange - 5u); + EXPECT_EQ(0u, id2); + ResourceId id3 = allocator->AllocateIDRange(kMaxPossibleRange - kAllocId); + EXPECT_EQ(kAllocId + 1u, id3); +} + +TEST_F(IdAllocatorTest, AllocateIdMax) { + const uint32_t kMaxPossibleRange = std::numeric_limits<uint32_t>::max(); + + IdAllocator* allocator = id_allocator(); + ResourceId id = allocator->AllocateIDRange(kMaxPossibleRange); + EXPECT_EQ(1u, id); + allocator->FreeIDRange(id, kMaxPossibleRange - 1u); + ResourceId id2 = allocator->AllocateIDRange(kMaxPossibleRange); + EXPECT_EQ(0u, id2); + allocator->FreeIDRange(id, kMaxPossibleRange); + ResourceId id3 = allocator->AllocateIDRange(kMaxPossibleRange); + EXPECT_EQ(1u, id3); +} + +TEST_F(IdAllocatorTest, ZeroIdCases) { + IdAllocator* allocator = id_allocator(); + EXPECT_FALSE(allocator->InUse(0)); + ResourceId id1 = allocator->AllocateIDAtOrAbove(0); + EXPECT_NE(0u, id1); + EXPECT_FALSE(allocator->InUse(0)); + allocator->FreeID(0); + EXPECT_FALSE(allocator->InUse(0)); + EXPECT_TRUE(allocator->InUse(id1)); + allocator->FreeID(id1); + EXPECT_FALSE(allocator->InUse(id1)); +} } // namespace gpu
diff --git a/ios/chrome/DEPS b/ios/chrome/DEPS index 32c8bbd..e568d4e2 100644 --- a/ios/chrome/DEPS +++ b/ios/chrome/DEPS
@@ -4,6 +4,8 @@ "-ios/chrome", "+ios/chrome/grit", + "+components/dom_distiller/core", + "+components/dom_distiller/ios", "+components/infobars/core", "+components/keyed_service/core", "+components/keyed_service/ios",
diff --git a/ios/chrome/browser/dom_distiller/OWNER b/ios/chrome/browser/dom_distiller/OWNER new file mode 100644 index 0000000..bf1620f --- /dev/null +++ b/ios/chrome/browser/dom_distiller/OWNER
@@ -0,0 +1 @@ +noyau@chromium.org
diff --git a/ios/chrome/browser/dom_distiller/distiller_viewer.cc b/ios/chrome/browser/dom_distiller/distiller_viewer.cc new file mode 100644 index 0000000..bf30950 --- /dev/null +++ b/ios/chrome/browser/dom_distiller/distiller_viewer.cc
@@ -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. + +#include "ios/chrome/browser/dom_distiller/distiller_viewer.h" + +#include <string> + +#include "components/dom_distiller/core/distilled_page_prefs.h" +#include "components/dom_distiller/core/dom_distiller_service.h" +#include "components/dom_distiller/core/proto/distilled_article.pb.h" +#include "components/dom_distiller/core/task_tracker.h" +#include "components/dom_distiller/core/viewer.h" +#include "ios/chrome/browser/dom_distiller/dom_distiller_service_factory.h" +#include "ios/public/provider/chrome/browser/browser_state/chrome_browser_state.h" +#include "ui/gfx/geometry/size.h" + +namespace dom_distiller { + +DistillerViewer::DistillerViewer(ios::ChromeBrowserState* browser_state, + const GURL& url, + const DistillationFinishedCallback& callback) + : url_(url), + callback_(callback), + distilled_page_prefs_(new DistilledPagePrefs(browser_state->GetPrefs())) { + DCHECK(browser_state); + DCHECK(url.is_valid()); + dom_distiller::DomDistillerService* distillerService = + dom_distiller::DomDistillerServiceFactory::GetForBrowserState( + browser_state); + + viewer_handle_ = distillerService->ViewUrl( + this, distillerService->CreateDefaultDistillerPage(gfx::Size()), url); +} + +DistillerViewer::~DistillerViewer() { +} + +void DistillerViewer::OnArticleReady( + const DistilledArticleProto* article_proto) { + const std::string html = viewer::GetUnsafeArticleHtml( + article_proto, distilled_page_prefs_->GetTheme(), + distilled_page_prefs_->GetFontFamily()); + + callback_.Run(url_, html); + + // No need to hold on to the ViewerHandle now that distillation is complete. + viewer_handle_.reset(); +} + +} // namespace dom_distiller
diff --git a/ios/chrome/browser/dom_distiller/distiller_viewer.h b/ios/chrome/browser/dom_distiller/distiller_viewer.h new file mode 100644 index 0000000..d822755 --- /dev/null +++ b/ios/chrome/browser/dom_distiller/distiller_viewer.h
@@ -0,0 +1,54 @@ +// 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_CHROME_BROWSER_DOM_DISTILLER_DISTILLER_VIEWER_H_ +#define IOS_CHROME_BROWSER_DOM_DISTILLER_DISTILLER_VIEWER_H_ + +#include "base/memory/scoped_ptr.h" +#include "components/dom_distiller/core/task_tracker.h" + +class GURL; + +namespace ios { +class ChromeBrowserState; +} + +namespace dom_distiller { + +class DistilledPagePrefs; + +// A very simple and naive implementation of the dom_distiller +// ViewRequestDelegate: From an URL it builds an HTML string and notifies when +// finished. +class DistillerViewer : public dom_distiller::ViewRequestDelegate { + public: + typedef base::Callback<void(const GURL&, const std::string&)> + DistillationFinishedCallback; + + DistillerViewer(ios::ChromeBrowserState* browser_state, + const GURL& url, + const DistillationFinishedCallback& callback); + ~DistillerViewer() override; + + // ViewRequestDelegate. + void OnArticleUpdated( + dom_distiller::ArticleDistillationUpdate article_update) override {} + void OnArticleReady(const DistilledArticleProto* article_proto) override; + + private: + // The url of the distilled page. + const GURL url_; + // Callback to invoke when the page is finished. + DistillationFinishedCallback callback_; + // Interface for accessing preferences for distilled pages. + scoped_ptr<DistilledPagePrefs> distilled_page_prefs_; + // Keeps the distiller going until the view is released. + scoped_ptr<dom_distiller::ViewerHandle> viewer_handle_; + + DISALLOW_COPY_AND_ASSIGN(DistillerViewer); +}; + +} // namespace dom_distiller + +#endif // IOS_CHROME_BROWSER_DOM_DISTILLER_DISTILLER_VIEWER_H_
diff --git a/ios/chrome/browser/dom_distiller/dom_distiller_service_factory.cc b/ios/chrome/browser/dom_distiller/dom_distiller_service_factory.cc new file mode 100644 index 0000000..0adbfa7 --- /dev/null +++ b/ios/chrome/browser/dom_distiller/dom_distiller_service_factory.cc
@@ -0,0 +1,113 @@ +// 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 "ios/chrome/browser/dom_distiller/dom_distiller_service_factory.h" + +#include "base/files/file_path.h" +#include "base/memory/scoped_ptr.h" +#include "base/memory/singleton.h" +#include "base/threading/sequenced_worker_pool.h" +#include "components/dom_distiller/core/article_entry.h" +#include "components/dom_distiller/core/distiller.h" +#include "components/dom_distiller/core/dom_distiller_service.h" +#include "components/dom_distiller/core/dom_distiller_store.h" +#include "components/dom_distiller/ios/distiller_page_factory_ios.h" +#include "components/keyed_service/core/keyed_service.h" +#include "components/keyed_service/ios/browser_state_dependency_manager.h" +#include "components/leveldb_proto/proto_database.h" +#include "components/leveldb_proto/proto_database_impl.h" +#include "ios/chrome/browser/browser_state/browser_state_otr_helper.h" +#include "ios/public/provider/chrome/browser/browser_state/chrome_browser_state.h" +#include "ios/web/public/browser_state.h" +#include "ios/web/public/web_thread.h" + +namespace { +// A simple wrapper for DomDistillerService to expose it as a +// KeyedService. +class DomDistillerKeyedService + : public KeyedService, + public dom_distiller::DomDistillerService { + public: + DomDistillerKeyedService( + scoped_ptr<dom_distiller::DomDistillerStoreInterface> store, + scoped_ptr<dom_distiller::DistillerFactory> distiller_factory, + scoped_ptr<dom_distiller::DistillerPageFactory> distiller_page_factory, + scoped_ptr<dom_distiller::DistilledPagePrefs> distilled_page_prefs) + : DomDistillerService(store.Pass(), + distiller_factory.Pass(), + distiller_page_factory.Pass(), + distilled_page_prefs.Pass()) {} + + ~DomDistillerKeyedService() override {} + + private: + DISALLOW_COPY_AND_ASSIGN(DomDistillerKeyedService); +}; +} // namespace + +namespace dom_distiller { + +// static +DomDistillerServiceFactory* DomDistillerServiceFactory::GetInstance() { + return Singleton<DomDistillerServiceFactory>::get(); +} + +// static +DomDistillerService* DomDistillerServiceFactory::GetForBrowserState( + web::BrowserState* browser_state) { + return static_cast<DomDistillerKeyedService*>( + GetInstance()->GetServiceForBrowserState(browser_state, true)); +} + +DomDistillerServiceFactory::DomDistillerServiceFactory() + : BrowserStateKeyedServiceFactory( + "DomDistillerService", + BrowserStateDependencyManager::GetInstance()) { +} + +DomDistillerServiceFactory::~DomDistillerServiceFactory() { +} + +KeyedService* DomDistillerServiceFactory::BuildServiceInstanceFor( + web::BrowserState* browser_state) const { + scoped_refptr<base::SequencedTaskRunner> background_task_runner = + web::WebThread::GetBlockingPool()->GetSequencedTaskRunner( + web::WebThread::GetBlockingPool()->GetSequenceToken()); + + scoped_ptr<leveldb_proto::ProtoDatabaseImpl<ArticleEntry>> db( + new leveldb_proto::ProtoDatabaseImpl<ArticleEntry>( + background_task_runner)); + + base::FilePath database_dir( + browser_state->GetStatePath().Append(FILE_PATH_LITERAL("Articles"))); + + scoped_ptr<DomDistillerStore> dom_distiller_store( + new DomDistillerStore(db.Pass(), database_dir)); + + scoped_ptr<DistillerPageFactory> distiller_page_factory( + new DistillerPageFactoryIOS(browser_state)); + scoped_ptr<DistillerURLFetcherFactory> distiller_url_fetcher_factory( + new DistillerURLFetcherFactory(browser_state->GetRequestContext())); + + dom_distiller::proto::DomDistillerOptions options; + scoped_ptr<DistillerFactory> distiller_factory( + new DistillerFactoryImpl(distiller_url_fetcher_factory.Pass(), options)); + scoped_ptr<DistilledPagePrefs> distilled_page_prefs(new DistilledPagePrefs( + ios::ChromeBrowserState::FromBrowserState(browser_state)->GetPrefs())); + + DomDistillerKeyedService* service = + new DomDistillerKeyedService( + dom_distiller_store.Pass(), distiller_factory.Pass(), + distiller_page_factory.Pass(), distilled_page_prefs.Pass()); + + return service; +} + +web::BrowserState* DomDistillerServiceFactory::GetBrowserStateToUse( + web::BrowserState* browser_state) const { + // Makes normal profile and off-the-record profile use same service instance. + return GetBrowserStateRedirectedInIncognito(browser_state); +} + +} // namespace dom_distiller
diff --git a/ios/chrome/browser/dom_distiller/dom_distiller_service_factory.h b/ios/chrome/browser/dom_distiller/dom_distiller_service_factory.h new file mode 100644 index 0000000..802e0fe --- /dev/null +++ b/ios/chrome/browser/dom_distiller/dom_distiller_service_factory.h
@@ -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. + +#ifndef IOS_CHROME_BROWSER_DOM_DISTILLER_DOM_DISTILLER_SERVICE_FACTORY_H_ +#define IOS_CHROME_BROWSER_DOM_DISTILLER_DOM_DISTILLER_SERVICE_FACTORY_H_ + +#include "components/dom_distiller/core/distilled_page_prefs.h" +#include "components/keyed_service/ios/browser_state_keyed_service_factory.h" + +template <typename T> struct DefaultSingletonTraits; + +class KeyedService; + +namespace dom_distiller { +class DomDistillerService; +} + +namespace web { +class BrowserState; +} + +namespace dom_distiller { + +class DomDistillerServiceFactory : public BrowserStateKeyedServiceFactory { + public: + static DomDistillerServiceFactory* GetInstance(); + static DomDistillerService* GetForBrowserState( + web::BrowserState* browser_state); + + private: + friend struct DefaultSingletonTraits<DomDistillerServiceFactory>; + + DomDistillerServiceFactory(); + ~DomDistillerServiceFactory() override; + + // BrowserStateKeyedServiceFactory implementation. + KeyedService* BuildServiceInstanceFor( + web::BrowserState* browser_state) const override; + web::BrowserState* GetBrowserStateToUse( + web::BrowserState* browser_state) const override; +}; + +} // namespace dom_distiller + +#endif // IOS_CHROME_BROWSER_DOM_DISTILLER_DOM_DISTILLER_SERVICE_FACTORY_H_
diff --git a/ios/chrome/browser/suggestions/suggestions_service_factory.mm b/ios/chrome/browser/suggestions/suggestions_service_factory.mm index efd35e5..400ff13 100644 --- a/ios/chrome/browser/suggestions/suggestions_service_factory.mm +++ b/ios/chrome/browser/suggestions/suggestions_service_factory.mm
@@ -59,7 +59,7 @@ ios::ChromeBrowserState* chrome_browser_state = ios::ChromeBrowserState::FromBrowserState(browser_state); base::FilePath database_dir( - chrome_browser_state->GetPath().Append(kThumbnailDirectory)); + chrome_browser_state->GetStatePath().Append(kThumbnailDirectory)); scoped_ptr<SuggestionsStore> suggestions_store( new SuggestionsStore(chrome_browser_state->GetPrefs())); scoped_ptr<BlacklistStore> blacklist_store(
diff --git a/ios/chrome/ios_chrome.gyp b/ios/chrome/ios_chrome.gyp index 5e68dea..4c2de56 100644 --- a/ios/chrome/ios_chrome.gyp +++ b/ios/chrome/ios_chrome.gyp
@@ -15,6 +15,8 @@ ], 'dependencies': [ '../../base/base.gyp:base', + '../../components/components.gyp:dom_distiller_core', + '../../components/components.gyp:dom_distiller_ios', '../../components/components.gyp:infobars_core', '../../components/components.gyp:keyed_service_core', '../../components/components.gyp:keyed_service_ios', @@ -54,6 +56,10 @@ 'browser/browser_state/browser_state_otr_helper.h', 'browser/chrome_url_constants.cc', 'browser/chrome_url_constants.h', + 'browser/dom_distiller/distiller_viewer.cc', + 'browser/dom_distiller/distiller_viewer.h', + 'browser/dom_distiller/dom_distiller_service_factory.cc', + 'browser/dom_distiller/dom_distiller_service_factory.h', 'browser/infobars/confirm_infobar_controller.h', 'browser/infobars/confirm_infobar_controller.mm', 'browser/infobars/infobar.h', @@ -101,12 +107,12 @@ 'browser/translate/translate_service_ios.h', 'browser/ui/animation_util.h', 'browser/ui/animation_util.mm', - 'browser/ui/commands/UIKit+ChromeExecuteCommand.h', - 'browser/ui/commands/UIKit+ChromeExecuteCommand.mm', 'browser/ui/commands/generic_chrome_command.h', 'browser/ui/commands/generic_chrome_command.mm', 'browser/ui/commands/open_url_command.h', 'browser/ui/commands/open_url_command.mm', + 'browser/ui/commands/UIKit+ChromeExecuteCommand.h', + 'browser/ui/commands/UIKit+ChromeExecuteCommand.mm', 'browser/ui/image_util.h', 'browser/ui/image_util.mm', 'browser/ui/reversed_animation.h',
diff --git a/ios/web/public/browser_state.h b/ios/web/public/browser_state.h index 0a3c131..b4f2ade 100644 --- a/ios/web/public/browser_state.h +++ b/ios/web/public/browser_state.h
@@ -28,7 +28,9 @@ virtual bool IsOffTheRecord() const = 0; // Returns the path where the BrowserState data is stored. - virtual base::FilePath GetPath() const = 0; + // Unlike Profile::GetPath(), incognito BrowserState do not share their path + // with their original BrowserState. + virtual base::FilePath GetStatePath() const = 0; // Returns the request context information associated with this // BrowserState.
diff --git a/ios/web/public/test/test_browser_state.cc b/ios/web/public/test/test_browser_state.cc index f9d428c..a5af592 100644 --- a/ios/web/public/test/test_browser_state.cc +++ b/ios/web/public/test/test_browser_state.cc
@@ -17,7 +17,7 @@ return false; } -base::FilePath TestBrowserState::GetPath() const { +base::FilePath TestBrowserState::GetStatePath() const { return base::FilePath(); }
diff --git a/ios/web/public/test/test_browser_state.h b/ios/web/public/test/test_browser_state.h index 320ba00..7544548 100644 --- a/ios/web/public/test/test_browser_state.h +++ b/ios/web/public/test/test_browser_state.h
@@ -15,7 +15,7 @@ // BrowserState: bool IsOffTheRecord() const override; - base::FilePath GetPath() const override; + base::FilePath GetStatePath() const override; net::URLRequestContextGetter* GetRequestContext() override; }; } // namespace web
diff --git a/media/base/android/media_player_android.cc b/media/base/android/media_player_android.cc index 954ba96c..eb52e3a5 100644 --- a/media/base/android/media_player_android.cc +++ b/media/base/android/media_player_android.cc
@@ -21,6 +21,7 @@ player_id_(player_id), manager_(manager), frame_url_(frame_url), + is_audible_(false), weak_factory_(this) { listener_.reset(new MediaPlayerListener(base::MessageLoopProxy::current(), weak_factory_.GetWeakPtr())); @@ -79,5 +80,11 @@ listener_->ReleaseMediaPlayerListenerResources(); } +void MediaPlayerAndroid::SetAudible(bool is_audible) { + if (is_audible_ != is_audible) { + is_audible_ = is_audible; + manager_->OnAudibleStateChanged(player_id(), is_audible_); + } +} } // namespace media
diff --git a/media/base/android/media_player_android.h b/media/base/android/media_player_android.h index cd5a92f1..d9091d4 100644 --- a/media/base/android/media_player_android.h +++ b/media/base/android/media_player_android.h
@@ -102,6 +102,7 @@ // events. Otherwise, it also listens to the events from |j_media_player|. void AttachListener(jobject j_media_player); void DetachListener(); + void SetAudible(bool is_audible); MediaPlayerManager* manager() { return manager_; } @@ -122,6 +123,9 @@ // Listener object that listens to all the media player events. scoped_ptr<MediaPlayerListener> listener_; + // Maintains the audible state of the player, true if it is playing sound. + bool is_audible_; + // Weak pointer passed to |listener_| for callbacks. // NOTE: Weak pointers must be invalidated before all other member variables. base::WeakPtrFactory<MediaPlayerAndroid> weak_factory_;
diff --git a/media/base/android/media_player_bridge.cc b/media/base/android/media_player_bridge.cc index a9bf7e4..ed8854f 100644 --- a/media/base/android/media_player_bridge.cc +++ b/media/base/android/media_player_bridge.cc
@@ -355,6 +355,8 @@ if (j_media_player_bridge_.is_null()) return; + SetAudible(false); + time_update_timer_.Stop(); if (prepared_) { pending_seek_ = GetCurrentTime(); @@ -371,15 +373,22 @@ } void MediaPlayerBridge::SetVolume(double volume) { - if (j_media_player_bridge_.is_null()) { - volume_ = volume; + volume_ = volume; + + if (j_media_player_bridge_.is_null()) return; - } JNIEnv* env = base::android::AttachCurrentThread(); CHECK(env); + + // Update the audible state if we are playing. + jboolean is_playing = Java_MediaPlayerBridge_isPlaying( + env, j_media_player_bridge_.obj()); + if (is_playing) + SetAudible(volume_ > 0); + Java_MediaPlayerBridge_setVolume( - env, j_media_player_bridge_.obj(), volume); + env, j_media_player_bridge_.obj(), volume_); } void MediaPlayerBridge::OnVideoSizeChanged(int width, int height) { @@ -389,11 +398,13 @@ } void MediaPlayerBridge::OnPlaybackComplete() { + SetAudible(false); time_update_timer_.Stop(); MediaPlayerAndroid::OnPlaybackComplete(); } void MediaPlayerBridge::OnMediaInterrupted() { + SetAudible(false); time_update_timer_.Stop(); MediaPlayerAndroid::OnMediaInterrupted(); } @@ -453,9 +464,13 @@ base::TimeDelta::FromMilliseconds(kTimeUpdateInterval), this, &MediaPlayerBridge::OnTimeUpdateTimerFired); } + + SetAudible(volume_ > 0); } void MediaPlayerBridge::PauseInternal() { + SetAudible(false); + JNIEnv* env = base::android::AttachCurrentThread(); Java_MediaPlayerBridge_pause(env, j_media_player_bridge_.obj()); time_update_timer_.Stop();
diff --git a/media/base/android/media_player_manager.h b/media/base/android/media_player_manager.h index 58a712f..de23d4f 100644 --- a/media/base/android/media_player_manager.h +++ b/media/base/android/media_player_manager.h
@@ -63,6 +63,9 @@ // Called when video size has changed. Args: player ID, width, height. virtual void OnVideoSizeChanged(int player_id, int width, int height) = 0; + // Called when the player thinks it stopped or started making sound. + virtual void OnAudibleStateChanged(int player_id, bool is_audible_now) = 0; + // Returns the player that's in the fullscreen mode currently. virtual MediaPlayerAndroid* GetFullscreenPlayer() = 0;
diff --git a/media/base/android/media_source_player_unittest.cc b/media/base/android/media_source_player_unittest.cc index 9ac934e..6750537 100644 --- a/media/base/android/media_source_player_unittest.cc +++ b/media/base/android/media_source_player_unittest.cc
@@ -75,6 +75,7 @@ const base::TimeDelta& current_time) override {} void OnError(int player_id, int error) override {} void OnVideoSizeChanged(int player_id, int width, int height) override {} + void OnAudibleStateChanged(int player_id, bool is_audible_now) override {} MediaPlayerAndroid* GetFullscreenPlayer() override { return NULL; } MediaPlayerAndroid* GetPlayer(int player_id) override { return NULL; } void RequestFullScreen(int player_id) override {}
diff --git a/media/base/audio_renderer.h b/media/base/audio_renderer.h index 7d0e3d76..586936a 100644 --- a/media/base/audio_renderer.h +++ b/media/base/audio_renderer.h
@@ -39,13 +39,18 @@ // |ended_cb| is executed when audio rendering has reached the end of stream. // // |error_cb| is executed if an error was encountered after initialization. - virtual void Initialize(DemuxerStream* stream, - const PipelineStatusCB& init_cb, - const SetDecryptorReadyCB& set_decryptor_ready_cb, - const StatisticsCB& statistics_cb, - const BufferingStateCB& buffering_state_cb, - const base::Closure& ended_cb, - const PipelineStatusCB& error_cb) = 0; + // + // |waiting_for_decryption_key_cb| is called whenever the key needed to + // decrypt the stream is not available. + virtual void Initialize( + DemuxerStream* stream, + const PipelineStatusCB& init_cb, + const SetDecryptorReadyCB& set_decryptor_ready_cb, + const StatisticsCB& statistics_cb, + const BufferingStateCB& buffering_state_cb, + const base::Closure& ended_cb, + const PipelineStatusCB& error_cb, + const base::Closure& waiting_for_decryption_key_cb) = 0; // Returns the TimeSource associated with audio rendering. virtual TimeSource* GetTimeSource() = 0;
diff --git a/media/base/mock_filters.h b/media/base/mock_filters.h index c8d1c822..9731fd0f 100644 --- a/media/base/mock_filters.h +++ b/media/base/mock_filters.h
@@ -121,16 +121,17 @@ virtual ~MockVideoRenderer(); // VideoRenderer implementation. - MOCK_METHOD9(Initialize, - void(DemuxerStream* stream, - const PipelineStatusCB& init_cb, - const SetDecryptorReadyCB& set_decryptor_ready_cb, - const StatisticsCB& statistics_cb, - const BufferingStateCB& buffering_state_cb, - const PaintCB& paint_cb, - const base::Closure& ended_cb, - const PipelineStatusCB& error_cb, - const TimeDeltaCB& get_time_cb)); + MOCK_METHOD10(Initialize, + void(DemuxerStream* stream, + const PipelineStatusCB& init_cb, + const SetDecryptorReadyCB& set_decryptor_ready_cb, + const StatisticsCB& statistics_cb, + const BufferingStateCB& buffering_state_cb, + const PaintCB& paint_cb, + const base::Closure& ended_cb, + const PipelineStatusCB& error_cb, + const TimeDeltaCB& get_time_cb, + const base::Closure& waiting_for_decryption_key_cb)); MOCK_METHOD1(Flush, void(const base::Closure& callback)); MOCK_METHOD1(StartPlayingFrom, void(base::TimeDelta)); @@ -144,14 +145,15 @@ virtual ~MockAudioRenderer(); // AudioRenderer implementation. - MOCK_METHOD7(Initialize, + MOCK_METHOD8(Initialize, void(DemuxerStream* stream, const PipelineStatusCB& init_cb, const SetDecryptorReadyCB& set_decryptor_ready_cb, const StatisticsCB& statistics_cb, const BufferingStateCB& buffering_state_cb, const base::Closure& ended_cb, - const PipelineStatusCB& error_cb)); + const PipelineStatusCB& error_cb, + const base::Closure& waiting_for_decryption_key_cb)); MOCK_METHOD0(GetTimeSource, TimeSource*()); MOCK_METHOD1(Flush, void(const base::Closure& callback)); MOCK_METHOD0(StartPlaying, void()); @@ -167,13 +169,15 @@ virtual ~MockRenderer(); // Renderer implementation. - MOCK_METHOD7(Initialize, void(DemuxerStreamProvider* demuxer_stream_provider, - const PipelineStatusCB& init_cb, - const StatisticsCB& statistics_cb, - const BufferingStateCB& buffering_state_cb, - const PaintCB& paint_cb, - const base::Closure& ended_cb, - const PipelineStatusCB& error_cb)); + MOCK_METHOD8(Initialize, + void(DemuxerStreamProvider* demuxer_stream_provider, + const PipelineStatusCB& init_cb, + const StatisticsCB& statistics_cb, + const BufferingStateCB& buffering_state_cb, + const PaintCB& paint_cb, + const base::Closure& ended_cb, + const PipelineStatusCB& error_cb, + const base::Closure& waiting_for_decryption_key_cb)); MOCK_METHOD1(Flush, void(const base::Closure& flush_cb)); MOCK_METHOD1(StartPlayingFrom, void(base::TimeDelta timestamp)); MOCK_METHOD1(SetPlaybackRate, void(float playback_rate));
diff --git a/media/base/pipeline.cc b/media/base/pipeline.cc index e9c52d66..d1fae01 100644 --- a/media/base/pipeline.cc +++ b/media/base/pipeline.cc
@@ -70,7 +70,8 @@ const BufferingStateCB& buffering_state_cb, const PaintCB& paint_cb, const base::Closure& duration_change_cb, - const AddTextTrackCB& add_text_track_cb) { + const AddTextTrackCB& add_text_track_cb, + const base::Closure& waiting_for_decryption_key_cb) { DCHECK(!ended_cb.is_null()); DCHECK(!error_cb.is_null()); DCHECK(!seek_cb.is_null()); @@ -92,6 +93,7 @@ paint_cb_ = paint_cb; duration_change_cb_ = duration_change_cb; add_text_track_cb_ = add_text_track_cb; + waiting_for_decryption_key_cb_ = waiting_for_decryption_key_cb; task_runner_->PostTask( FROM_HERE, base::Bind(&Pipeline::StartTask, weak_factory_.GetWeakPtr())); @@ -724,7 +726,8 @@ base::Bind(&Pipeline::BufferingStateChanged, weak_this), base::ResetAndReturn(&paint_cb_), base::Bind(&Pipeline::OnRendererEnded, weak_this), - base::Bind(&Pipeline::OnError, weak_this)); + base::Bind(&Pipeline::OnError, weak_this), + waiting_for_decryption_key_cb_); } void Pipeline::ReportMetadata() {
diff --git a/media/base/pipeline.h b/media/base/pipeline.h index 6bca477..30707b3 100644 --- a/media/base/pipeline.h +++ b/media/base/pipeline.h
@@ -105,6 +105,8 @@ // |duration_change_cb| optional callback that will be executed whenever the // presentation duration changes. // |add_text_track_cb| will be executed whenever a text track is added. + // |waiting_for_decryption_key_cb| will be executed whenever the key needed + // to decrypt the stream is not available. // It is an error to call this method after the pipeline has already started. void Start(Demuxer* demuxer, scoped_ptr<Renderer> renderer, @@ -115,7 +117,8 @@ const BufferingStateCB& buffering_state_cb, const PaintCB& paint_cb, const base::Closure& duration_change_cb, - const AddTextTrackCB& add_text_track_cb); + const AddTextTrackCB& add_text_track_cb, + const base::Closure& waiting_for_decryption_key_cb); // Asynchronously stops the pipeline, executing |stop_cb| when the pipeline // teardown has completed. @@ -360,6 +363,7 @@ PaintCB paint_cb_; base::Closure duration_change_cb_; AddTextTrackCB add_text_track_cb_; + base::Closure waiting_for_decryption_key_cb_; // Holds the initialized demuxer. Used for seeking. Owned by client. Demuxer* demuxer_;
diff --git a/media/base/pipeline_unittest.cc b/media/base/pipeline_unittest.cc index affb643..147e744 100644 --- a/media/base/pipeline_unittest.cc +++ b/media/base/pipeline_unittest.cc
@@ -170,7 +170,7 @@ // Sets up expectations to allow the video renderer to initialize. void SetRendererExpectations() { - EXPECT_CALL(*renderer_, Initialize(_, _, _, _, _, _, _)) + EXPECT_CALL(*renderer_, Initialize(_, _, _, _, _, _, _, _)) .WillOnce(DoAll(SaveArg<3>(&buffering_state_cb_), SaveArg<5>(&ended_cb_), PostCallback<1>(PIPELINE_OK))); @@ -187,6 +187,7 @@ } void StartPipeline() { + EXPECT_CALL(*this, OnWaitingForDecryptionKey()).Times(0); pipeline_->Start( demuxer_.get(), scoped_renderer_.Pass(), base::Bind(&CallbackHelper::OnEnded, base::Unretained(&callbacks_)), @@ -199,7 +200,9 @@ base::Unretained(&callbacks_)), base::Bind(&CallbackHelper::OnDurationChange, base::Unretained(&callbacks_)), - base::Bind(&PipelineTest::OnAddTextTrack, base::Unretained(this))); + base::Bind(&PipelineTest::OnAddTextTrack, base::Unretained(this)), + base::Bind(&PipelineTest::OnWaitingForDecryptionKey, + base::Unretained(this))); } // Sets up expectations on the callback and initializes the pipeline. Called @@ -296,6 +299,7 @@ MOCK_METHOD2(OnAddTextTrack, void(const TextTrackConfig&, const AddTextTrackDoneCB&)); + MOCK_METHOD0(OnWaitingForDecryptionKey, void(void)); void DoOnAddTextTrack(const TextTrackConfig& config, const AddTextTrackDoneCB& done_cb) { @@ -857,13 +861,13 @@ if (state == kInitRenderer) { if (stop_or_error == kStop) { - EXPECT_CALL(*renderer_, Initialize(_, _, _, _, _, _, _)) + EXPECT_CALL(*renderer_, Initialize(_, _, _, _, _, _, _, _)) .WillOnce(DoAll(Stop(pipeline_.get(), stop_cb), PostCallback<1>(PIPELINE_OK))); ExpectPipelineStopAndDestroyPipeline(); } else { status = PIPELINE_ERROR_INITIALIZATION_FAILED; - EXPECT_CALL(*renderer_, Initialize(_, _, _, _, _, _, _)) + EXPECT_CALL(*renderer_, Initialize(_, _, _, _, _, _, _, _)) .WillOnce(PostCallback<1>(status)); } @@ -872,7 +876,7 @@ return status; } - EXPECT_CALL(*renderer_, Initialize(_, _, _, _, _, _, _)) + EXPECT_CALL(*renderer_, Initialize(_, _, _, _, _, _, _, _)) .WillOnce(DoAll(SaveArg<3>(&buffering_state_cb_), PostCallback<1>(PIPELINE_OK)));
diff --git a/media/base/renderer.h b/media/base/renderer.h index 1c7afbd98..e3647f7 100644 --- a/media/base/renderer.h +++ b/media/base/renderer.h
@@ -43,13 +43,17 @@ // be called from any thread. // - |ended_cb|: Executed when rendering has reached the end of stream. // - |error_cb|: Executed if any error was encountered after initialization. - virtual void Initialize(DemuxerStreamProvider* demuxer_stream_provider, - const PipelineStatusCB& init_cb, - const StatisticsCB& statistics_cb, - const BufferingStateCB& buffering_state_cb, - const PaintCB& paint_cb, - const base::Closure& ended_cb, - const PipelineStatusCB& error_cb) = 0; + // - |waiting_for_decryption_key_cb|: Executed whenever the key needed to + // decrypt the stream is not available. + virtual void Initialize( + DemuxerStreamProvider* demuxer_stream_provider, + const PipelineStatusCB& init_cb, + const StatisticsCB& statistics_cb, + const BufferingStateCB& buffering_state_cb, + const PaintCB& paint_cb, + const base::Closure& ended_cb, + const PipelineStatusCB& error_cb, + const base::Closure& waiting_for_decryption_key_cb) = 0; // Associates the |cdm_context| with this Renderer for decryption (and // decoding) of media data, then fires |cdm_attached_cb| with the result.
diff --git a/media/base/video_renderer.h b/media/base/video_renderer.h index 1e44333..7a764b3 100644 --- a/media/base/video_renderer.h +++ b/media/base/video_renderer.h
@@ -53,15 +53,20 @@ // |error_cb| is executed if an error was encountered after initialization. // // |get_time_cb| is used to query the current media playback time. - virtual void Initialize(DemuxerStream* stream, - const PipelineStatusCB& init_cb, - const SetDecryptorReadyCB& set_decryptor_ready_cb, - const StatisticsCB& statistics_cb, - const BufferingStateCB& buffering_state_cb, - const PaintCB& paint_cb, - const base::Closure& ended_cb, - const PipelineStatusCB& error_cb, - const TimeDeltaCB& get_time_cb) = 0; + // + // |waiting_for_decryption_key_cb| is executed whenever the key needed to + // decrypt the stream is not available. + virtual void Initialize( + DemuxerStream* stream, + const PipelineStatusCB& init_cb, + const SetDecryptorReadyCB& set_decryptor_ready_cb, + const StatisticsCB& statistics_cb, + const BufferingStateCB& buffering_state_cb, + const PaintCB& paint_cb, + const base::Closure& ended_cb, + const PipelineStatusCB& error_cb, + const TimeDeltaCB& get_time_cb, + const base::Closure& waiting_for_decryption_key_cb) = 0; // Discards any video data and stops reading from |stream|, executing // |callback| when completed.
diff --git a/media/blink/BUILD.gn b/media/blink/BUILD.gn index bb52f5e..33d26d5 100644 --- a/media/blink/BUILD.gn +++ b/media/blink/BUILD.gn
@@ -83,7 +83,7 @@ } } -if (!is_mac && (!is_win || link_chrome_on_windows)) { +if (!is_mac) { # TODO(GYP): Make linking this work on the mac. test("media_blink_unittests") { deps = [
diff --git a/media/blink/webmediaplayer_impl.cc b/media/blink/webmediaplayer_impl.cc index a7a7201..148daf61 100644 --- a/media/blink/webmediaplayer_impl.cc +++ b/media/blink/webmediaplayer_impl.cc
@@ -692,6 +692,15 @@ base::saturated_cast<unsigned int>(init_data.size())); } +void WebMediaPlayerImpl::OnWaitingForDecryptionKey() { + client_->didBlockPlaybackWaitingForKey(); + + // TODO(jrummell): didResumePlaybackBlockedForKey() should only be called + // when a key has been successfully added (e.g. OnSessionKeysChange() with + // |has_additional_usable_key| = true). http://crbug.com/461903 + client_->didResumePlaybackBlockedForKey(); +} + void WebMediaPlayerImpl::SetCdm(CdmContext* cdm_context, const CdmAttachedCB& cdm_attached_cb) { pipeline_.SetCdm(cdm_context, cdm_attached_cb); @@ -903,7 +912,8 @@ BIND_TO_RENDER_LOOP(&WebMediaPlayerImpl::OnPipelineBufferingStateChanged), base::Bind(&WebMediaPlayerImpl::FrameReady, base::Unretained(this)), BIND_TO_RENDER_LOOP(&WebMediaPlayerImpl::OnDurationChanged), - BIND_TO_RENDER_LOOP(&WebMediaPlayerImpl::OnAddTextTrack)); + BIND_TO_RENDER_LOOP(&WebMediaPlayerImpl::OnAddTextTrack), + BIND_TO_RENDER_LOOP(&WebMediaPlayerImpl::OnWaitingForDecryptionKey)); } void WebMediaPlayerImpl::SetNetworkState(WebMediaPlayer::NetworkState state) {
diff --git a/media/blink/webmediaplayer_impl.h b/media/blink/webmediaplayer_impl.h index acfdf97..0dc60db 100644 --- a/media/blink/webmediaplayer_impl.h +++ b/media/blink/webmediaplayer_impl.h
@@ -212,6 +212,10 @@ void OnEncryptedMediaInitData(const std::string& init_data_type, const std::vector<uint8>& init_data); + // Called when a decoder detects that the key needed to decrypt the stream + // is not available. + void OnWaitingForDecryptionKey(); + void SetCdm(CdmContext* cdm_context, const CdmAttachedCB& cdm_attached_cb); // Called when a CDM has been attached to the |pipeline_|.
diff --git a/media/cast/sender/vp8_encoder.cc b/media/cast/sender/vp8_encoder.cc index fae960e..4d397b6 100644 --- a/media/cast/sender/vp8_encoder.cc +++ b/media/cast/sender/vp8_encoder.cc
@@ -80,9 +80,10 @@ << frame_size.ToString(); config_.g_w = frame_size.width(); config_.g_h = frame_size.height(); - CHECK_EQ(vpx_codec_enc_config_set(&encoder_, &config_), VPX_CODEC_OK) - << "Failed to update frame size in encoder config."; - return; + if (vpx_codec_enc_config_set(&encoder_, &config_) == VPX_CODEC_OK) + return; + DVLOG(1) << "libvpx rejected the attempt to use a smaller frame size in " + "the current instance."; } DVLOG(1) << "Destroying/Re-Creating encoder for larger frame size: "
diff --git a/media/filters/audio_decoder_selector_unittest.cc b/media/filters/audio_decoder_selector_unittest.cc index 36f7ca64..2bb1f6d2 100644 --- a/media/filters/audio_decoder_selector_unittest.cc +++ b/media/filters/audio_decoder_selector_unittest.cc
@@ -135,7 +135,8 @@ base::Unretained(this)), base::Bind(&AudioDecoderSelectorTest::MockOnDecoderSelected, base::Unretained(this)), - base::Bind(&AudioDecoderSelectorTest::OnDecoderOutput)); + base::Bind(&AudioDecoderSelectorTest::OnDecoderOutput), + base::Bind(&AudioDecoderSelectorTest::OnWaitingForDecryptionKey)); message_loop_.RunUntilIdle(); } @@ -151,6 +152,10 @@ NOTREACHED(); } + static void OnWaitingForDecryptionKey() { + NOTREACHED(); + } + // Declare |decoder_selector_| after |demuxer_stream_| and |decryptor_| since // |demuxer_stream_| and |decryptor_| should outlive |decoder_selector_|. scoped_ptr<StrictMock<MockDemuxerStream> > demuxer_stream_;
diff --git a/media/filters/decoder_selector.cc b/media/filters/decoder_selector.cc index f026acd..555a411 100644 --- a/media/filters/decoder_selector.cc +++ b/media/filters/decoder_selector.cc
@@ -75,13 +75,15 @@ DemuxerStream* stream, const SetDecryptorReadyCB& set_decryptor_ready_cb, const SelectDecoderCB& select_decoder_cb, - const typename Decoder::OutputCB& output_cb) { + const typename Decoder::OutputCB& output_cb, + const base::Closure& waiting_for_decryption_key_cb) { DVLOG(2) << __FUNCTION__; DCHECK(task_runner_->BelongsToCurrentThread()); DCHECK(stream); DCHECK(select_decoder_cb_.is_null()); set_decryptor_ready_cb_ = set_decryptor_ready_cb; + waiting_for_decryption_key_cb_ = waiting_for_decryption_key_cb; // Make sure |select_decoder_cb| runs on a different execution stack. select_decoder_cb_ = BindToCurrentLoop(select_decoder_cb); @@ -107,7 +109,7 @@ } decoder_.reset(new typename StreamTraits::DecryptingDecoderType( - task_runner_, set_decryptor_ready_cb_)); + task_runner_, set_decryptor_ready_cb_, waiting_for_decryption_key_cb_)); DecoderStreamTraits<StreamType>::InitializeDecoder( decoder_.get(), input_stream_, @@ -130,8 +132,8 @@ decoder_.reset(); - decrypted_stream_.reset( - new DecryptingDemuxerStream(task_runner_, set_decryptor_ready_cb_)); + decrypted_stream_.reset(new DecryptingDemuxerStream( + task_runner_, set_decryptor_ready_cb_, waiting_for_decryption_key_cb_)); decrypted_stream_->Initialize( input_stream_,
diff --git a/media/filters/decoder_selector.h b/media/filters/decoder_selector.h index d13eb9b..59c90f57 100644 --- a/media/filters/decoder_selector.h +++ b/media/filters/decoder_selector.h
@@ -70,7 +70,8 @@ void SelectDecoder(DemuxerStream* stream, const SetDecryptorReadyCB& set_decryptor_ready_cb, const SelectDecoderCB& select_decoder_cb, - const typename Decoder::OutputCB& output_cb); + const typename Decoder::OutputCB& output_cb, + const base::Closure& waiting_for_decryption_key_cb); private: void DecryptingDecoderInitDone(PipelineStatus status); @@ -86,6 +87,7 @@ SetDecryptorReadyCB set_decryptor_ready_cb_; SelectDecoderCB select_decoder_cb_; typename Decoder::OutputCB output_cb_; + base::Closure waiting_for_decryption_key_cb_; scoped_ptr<Decoder> decoder_; scoped_ptr<DecryptingDemuxerStream> decrypted_stream_;
diff --git a/media/filters/decoder_stream.cc b/media/filters/decoder_stream.cc index f9fa8b2..3a366d8 100644 --- a/media/filters/decoder_stream.cc +++ b/media/filters/decoder_stream.cc
@@ -83,7 +83,8 @@ DemuxerStream* stream, const InitCB& init_cb, const SetDecryptorReadyCB& set_decryptor_ready_cb, - const StatisticsCB& statistics_cb) { + const StatisticsCB& statistics_cb, + const base::Closure& waiting_for_decryption_key_cb) { FUNCTION_DVLOG(2); DCHECK(task_runner_->BelongsToCurrentThread()); DCHECK_EQ(state_, STATE_UNINITIALIZED); @@ -92,6 +93,7 @@ statistics_cb_ = statistics_cb; init_cb_ = init_cb; + waiting_for_decryption_key_cb_ = waiting_for_decryption_key_cb; stream_ = stream; state_ = STATE_INITIALIZING; @@ -212,7 +214,8 @@ base::Bind(&DecoderStream<StreamType>::OnDecoderSelected, weak_factory_.GetWeakPtr()), base::Bind(&DecoderStream<StreamType>::OnDecodeOutputReady, - weak_factory_.GetWeakPtr())); + weak_factory_.GetWeakPtr()), + waiting_for_decryption_key_cb_); } template <DemuxerStream::Type StreamType>
diff --git a/media/filters/decoder_stream.h b/media/filters/decoder_stream.h index b8a0d04..3c0e23ef 100644 --- a/media/filters/decoder_stream.h +++ b/media/filters/decoder_stream.h
@@ -61,7 +61,8 @@ void Initialize(DemuxerStream* stream, const InitCB& init_cb, const SetDecryptorReadyCB& set_decryptor_ready_cb, - const StatisticsCB& statistics_cb); + const StatisticsCB& statistics_cb, + const base::Closure& waiting_for_decryption_key_cb); // Reads a decoded Output and returns it via the |read_cb|. Note that // |read_cb| is always called asynchronously. This method should only be @@ -170,6 +171,7 @@ StatisticsCB statistics_cb_; InitCB init_cb_; + base::Closure waiting_for_decryption_key_cb_; ReadCB read_cb_; base::Closure reset_cb_;
diff --git a/media/filters/decrypting_audio_decoder.cc b/media/filters/decrypting_audio_decoder.cc index 0ca20f7..3425d0c2 100644 --- a/media/filters/decrypting_audio_decoder.cc +++ b/media/filters/decrypting_audio_decoder.cc
@@ -34,13 +34,16 @@ DecryptingAudioDecoder::DecryptingAudioDecoder( const scoped_refptr<base::SingleThreadTaskRunner>& task_runner, - const SetDecryptorReadyCB& set_decryptor_ready_cb) + const SetDecryptorReadyCB& set_decryptor_ready_cb, + const base::Closure& waiting_for_decryption_key_cb) : task_runner_(task_runner), state_(kUninitialized), + waiting_for_decryption_key_cb_(waiting_for_decryption_key_cb), set_decryptor_ready_cb_(set_decryptor_ready_cb), decryptor_(NULL), key_added_while_decode_pending_(false), - weak_factory_(this) {} + weak_factory_(this) { +} std::string DecryptingAudioDecoder::GetDisplayName() const { return "DecryptingAudioDecoder"; @@ -288,6 +291,7 @@ } state_ = kWaitingForKey; + waiting_for_decryption_key_cb_.Run(); return; }
diff --git a/media/filters/decrypting_audio_decoder.h b/media/filters/decrypting_audio_decoder.h index 67da6c0..30b0a63 100644 --- a/media/filters/decrypting_audio_decoder.h +++ b/media/filters/decrypting_audio_decoder.h
@@ -32,7 +32,8 @@ public: DecryptingAudioDecoder( const scoped_refptr<base::SingleThreadTaskRunner>& task_runner, - const SetDecryptorReadyCB& set_decryptor_ready_cb); + const SetDecryptorReadyCB& set_decryptor_ready_cb, + const base::Closure& waiting_for_decryption_key_cb); ~DecryptingAudioDecoder() override; // AudioDecoder implementation. @@ -96,6 +97,7 @@ OutputCB output_cb_; DecodeCB decode_cb_; base::Closure reset_cb_; + base::Closure waiting_for_decryption_key_cb_; // The current decoder configuration. AudioDecoderConfig config_;
diff --git a/media/filters/decrypting_audio_decoder_unittest.cc b/media/filters/decrypting_audio_decoder_unittest.cc index 49df3ce..1f8395bf 100644 --- a/media/filters/decrypting_audio_decoder_unittest.cc +++ b/media/filters/decrypting_audio_decoder_unittest.cc
@@ -63,7 +63,9 @@ message_loop_.message_loop_proxy(), base::Bind( &DecryptingAudioDecoderTest::RequestDecryptorNotification, - base::Unretained(this)))), + base::Unretained(this)), + base::Bind(&DecryptingAudioDecoderTest::OnWaitingForDecryptionKey, + base::Unretained(this)))), decryptor_(new StrictMock<MockDecryptor>()), num_decrypt_and_decode_calls_(0), num_frames_in_decryptor_(0), @@ -204,6 +206,7 @@ EXPECT_CALL(*decryptor_, DecryptAndDecodeAudio(encrypted_buffer_, _)) .WillRepeatedly(RunCallback<1>(Decryptor::kNoKey, Decryptor::AudioFrames())); + EXPECT_CALL(*this, OnWaitingForDecryptionKey()); decoder_->Decode(encrypted_buffer_, base::Bind(&DecryptingAudioDecoderTest::DecodeDone, base::Unretained(this))); @@ -252,6 +255,8 @@ MOCK_METHOD1(DecryptorSet, void(bool)); + MOCK_METHOD0(OnWaitingForDecryptionKey, void(void)); + base::MessageLoop message_loop_; scoped_ptr<DecryptingAudioDecoder> decoder_; scoped_ptr<StrictMock<MockDecryptor> > decryptor_;
diff --git a/media/filters/decrypting_demuxer_stream.cc b/media/filters/decrypting_demuxer_stream.cc index 601fd46..7a6f43c 100644 --- a/media/filters/decrypting_demuxer_stream.cc +++ b/media/filters/decrypting_demuxer_stream.cc
@@ -30,14 +30,17 @@ DecryptingDemuxerStream::DecryptingDemuxerStream( const scoped_refptr<base::SingleThreadTaskRunner>& task_runner, - const SetDecryptorReadyCB& set_decryptor_ready_cb) + const SetDecryptorReadyCB& set_decryptor_ready_cb, + const base::Closure& waiting_for_decryption_key_cb) : task_runner_(task_runner), state_(kUninitialized), + waiting_for_decryption_key_cb_(waiting_for_decryption_key_cb), demuxer_stream_(NULL), set_decryptor_ready_cb_(set_decryptor_ready_cb), decryptor_(NULL), key_added_while_decrypt_pending_(false), - weak_factory_(this) {} + weak_factory_(this) { +} void DecryptingDemuxerStream::Initialize(DemuxerStream* stream, const PipelineStatusCB& status_cb) { @@ -311,6 +314,7 @@ } state_ = kWaitingForKey; + waiting_for_decryption_key_cb_.Run(); return; }
diff --git a/media/filters/decrypting_demuxer_stream.h b/media/filters/decrypting_demuxer_stream.h index f66f9ab7..e8d82224 100644 --- a/media/filters/decrypting_demuxer_stream.h +++ b/media/filters/decrypting_demuxer_stream.h
@@ -30,7 +30,8 @@ public: DecryptingDemuxerStream( const scoped_refptr<base::SingleThreadTaskRunner>& task_runner, - const SetDecryptorReadyCB& set_decryptor_ready_cb); + const SetDecryptorReadyCB& set_decryptor_ready_cb, + const base::Closure& waiting_for_decryption_key_cb); // Cancels all pending operations immediately and fires all pending callbacks. ~DecryptingDemuxerStream() override; @@ -104,6 +105,7 @@ PipelineStatusCB init_cb_; ReadCB read_cb_; base::Closure reset_cb_; + base::Closure waiting_for_decryption_key_cb_; // Pointer to the input demuxer stream that will feed us encrypted buffers. DemuxerStream* demuxer_stream_;
diff --git a/media/filters/decrypting_demuxer_stream_unittest.cc b/media/filters/decrypting_demuxer_stream_unittest.cc index fa2a36c..3cba1f7 100644 --- a/media/filters/decrypting_demuxer_stream_unittest.cc +++ b/media/filters/decrypting_demuxer_stream_unittest.cc
@@ -77,7 +77,9 @@ message_loop_.message_loop_proxy(), base::Bind( &DecryptingDemuxerStreamTest::RequestDecryptorNotification, - base::Unretained(this)))), + base::Unretained(this)), + base::Bind(&DecryptingDemuxerStreamTest::OnWaitingForDecryptionKey, + base::Unretained(this)))), decryptor_(new StrictMock<MockDecryptor>()), is_decryptor_set_(false), input_audio_stream_( @@ -225,6 +227,7 @@ EXPECT_CALL(*decryptor_, Decrypt(_, encrypted_buffer_, _)) .WillRepeatedly(RunCallback<2>(Decryptor::kNoKey, scoped_refptr<DecoderBuffer>())); + EXPECT_CALL(*this, OnWaitingForDecryptionKey()); demuxer_stream_->Read(base::Bind(&DecryptingDemuxerStreamTest::BufferReady, base::Unretained(this))); message_loop_.RunUntilIdle(); @@ -260,6 +263,8 @@ MOCK_METHOD1(DecryptorSet, void(bool)); + MOCK_METHOD0(OnWaitingForDecryptionKey, void(void)); + base::MessageLoop message_loop_; scoped_ptr<DecryptingDemuxerStream> demuxer_stream_; scoped_ptr<StrictMock<MockDecryptor> > decryptor_;
diff --git a/media/filters/decrypting_video_decoder.cc b/media/filters/decrypting_video_decoder.cc index f4aa375..d9bba50 100644 --- a/media/filters/decrypting_video_decoder.cc +++ b/media/filters/decrypting_video_decoder.cc
@@ -23,14 +23,17 @@ DecryptingVideoDecoder::DecryptingVideoDecoder( const scoped_refptr<base::SingleThreadTaskRunner>& task_runner, - const SetDecryptorReadyCB& set_decryptor_ready_cb) + const SetDecryptorReadyCB& set_decryptor_ready_cb, + const base::Closure& waiting_for_decryption_key_cb) : task_runner_(task_runner), state_(kUninitialized), + waiting_for_decryption_key_cb_(waiting_for_decryption_key_cb), set_decryptor_ready_cb_(set_decryptor_ready_cb), decryptor_(NULL), key_added_while_decode_pending_(false), trace_id_(0), - weak_factory_(this) {} + weak_factory_(this) { +} std::string DecryptingVideoDecoder::GetDisplayName() const { return kDecoderName; @@ -270,6 +273,7 @@ } state_ = kWaitingForKey; + waiting_for_decryption_key_cb_.Run(); return; }
diff --git a/media/filters/decrypting_video_decoder.h b/media/filters/decrypting_video_decoder.h index 8e40502..a2a9528 100644 --- a/media/filters/decrypting_video_decoder.h +++ b/media/filters/decrypting_video_decoder.h
@@ -28,7 +28,8 @@ public: DecryptingVideoDecoder( const scoped_refptr<base::SingleThreadTaskRunner>& task_runner, - const SetDecryptorReadyCB& set_decryptor_ready_cb); + const SetDecryptorReadyCB& set_decryptor_ready_cb, + const base::Closure& waiting_for_decryption_key_cb); ~DecryptingVideoDecoder() override; // VideoDecoder implementation. @@ -88,6 +89,7 @@ OutputCB output_cb_; DecodeCB decode_cb_; base::Closure reset_cb_; + base::Closure waiting_for_decryption_key_cb_; VideoDecoderConfig config_;
diff --git a/media/filters/decrypting_video_decoder_unittest.cc b/media/filters/decrypting_video_decoder_unittest.cc index 11dc52a..285bab67 100644 --- a/media/filters/decrypting_video_decoder_unittest.cc +++ b/media/filters/decrypting_video_decoder_unittest.cc
@@ -57,7 +57,9 @@ message_loop_.message_loop_proxy(), base::Bind( &DecryptingVideoDecoderTest::RequestDecryptorNotification, - base::Unretained(this)))), + base::Unretained(this)), + base::Bind(&DecryptingVideoDecoderTest::OnWaitingForDecryptionKey, + base::Unretained(this)))), decryptor_(new StrictMock<MockDecryptor>()), num_decrypt_and_decode_calls_(0), num_frames_in_decryptor_(0), @@ -179,6 +181,7 @@ void EnterWaitingForKeyState() { EXPECT_CALL(*decryptor_, DecryptAndDecodeVideo(_, _)) .WillRepeatedly(RunCallback<1>(Decryptor::kNoKey, null_video_frame_)); + EXPECT_CALL(*this, OnWaitingForDecryptionKey()); decoder_->Decode(encrypted_buffer_, base::Bind(&DecryptingVideoDecoderTest::DecodeDone, base::Unretained(this))); @@ -227,6 +230,8 @@ MOCK_METHOD1(DecryptorSet, void(bool)); + MOCK_METHOD0(OnWaitingForDecryptionKey, void(void)); + base::MessageLoop message_loop_; scoped_ptr<DecryptingVideoDecoder> decoder_; scoped_ptr<StrictMock<MockDecryptor> > decryptor_; @@ -263,6 +268,7 @@ .WillRepeatedly(RunCallback<1>(false)); EXPECT_CALL(*decryptor_, RegisterNewKeyCB(Decryptor::kVideo, _)) .WillRepeatedly(SaveArg<1>(&key_added_cb_)); + EXPECT_CALL(*this, RequestDecryptorNotification(_)).Times(2); InitializeAndExpectStatus(TestVideoConfig::NormalEncrypted(), DECODER_ERROR_NOT_SUPPORTED); @@ -333,7 +339,7 @@ // Test the case where the a key is added when the decryptor is in // kPendingDecode state. -TEST_F(DecryptingVideoDecoderTest, KeyAdded_DruingPendingDecode) { +TEST_F(DecryptingVideoDecoderTest, KeyAdded_DuringPendingDecode) { Initialize(); EnterPendingDecodeState();
diff --git a/media/filters/video_decoder_selector_unittest.cc b/media/filters/video_decoder_selector_unittest.cc index f2dabdf..86f4c0ec 100644 --- a/media/filters/video_decoder_selector_unittest.cc +++ b/media/filters/video_decoder_selector_unittest.cc
@@ -131,6 +131,8 @@ base::Bind(&VideoDecoderSelectorTest::MockOnDecoderSelected, base::Unretained(this)), base::Bind(&VideoDecoderSelectorTest::FrameReady, + base::Unretained(this)), + base::Bind(&VideoDecoderSelectorTest::OnWaitingForDecryptionKey, base::Unretained(this))); message_loop_.RunUntilIdle(); } @@ -147,6 +149,10 @@ NOTREACHED(); } + void OnWaitingForDecryptionKey() { + NOTREACHED(); + } + // Declare |decoder_selector_| after |demuxer_stream_| and |decryptor_| since // |demuxer_stream_| and |decryptor_| should outlive |decoder_selector_|. scoped_ptr<StrictMock<MockDemuxerStream> > demuxer_stream_;
diff --git a/media/filters/video_frame_stream_unittest.cc b/media/filters/video_frame_stream_unittest.cc index f71c07f..a9f3b60 100644 --- a/media/filters/video_frame_stream_unittest.cc +++ b/media/filters/video_frame_stream_unittest.cc
@@ -125,6 +125,7 @@ MOCK_METHOD1(OnNewSpliceBuffer, void(base::TimeDelta)); MOCK_METHOD1(SetDecryptorReadyCallback, void(const media::DecryptorReadyCB&)); MOCK_METHOD1(DecryptorSet, void(bool)); + MOCK_METHOD0(OnWaitingForDecryptionKey, void(void)); void OnStatistics(const PipelineStatistics& statistics) { num_decoded_bytes_unreported_ -= statistics.video_bytes_decoded; @@ -155,7 +156,8 @@ base::Unretained(this)), base::Bind(&VideoFrameStreamTest::SetDecryptorReadyCallback, base::Unretained(this)), - base::Bind(&VideoFrameStreamTest::OnStatistics, + base::Bind(&VideoFrameStreamTest::OnStatistics, base::Unretained(this)), + base::Bind(&VideoFrameStreamTest::OnWaitingForDecryptionKey, base::Unretained(this))); message_loop_.RunUntilIdle(); } @@ -276,6 +278,8 @@ break; case DECRYPTOR_NO_KEY: + if (GetParam().is_encrypted) + EXPECT_CALL(*this, OnWaitingForDecryptionKey()); ExpectDecryptorNotification(); has_no_key_ = true; ReadOneFrame();
diff --git a/media/mojo/services/mojo_renderer_impl.cc b/media/mojo/services/mojo_renderer_impl.cc index 3bde3b25..e4a13326 100644 --- a/media/mojo/services/mojo_renderer_impl.cc +++ b/media/mojo/services/mojo_renderer_impl.cc
@@ -33,7 +33,8 @@ // Connection to |remote_media_renderer_| will error-out here. } -// TODO(xhwang): Support |paint_cb| if needed. +// TODO(xhwang): Support |paint_cb| and |waiting_for_decryption_key_cb|, +// if needed. void MojoRendererImpl::Initialize( DemuxerStreamProvider* demuxer_stream_provider, const PipelineStatusCB& init_cb, @@ -41,7 +42,8 @@ const BufferingStateCB& buffering_state_cb, const PaintCB& /* paint_cb */, const base::Closure& ended_cb, - const PipelineStatusCB& error_cb) { + const PipelineStatusCB& error_cb, + const base::Closure& /* waiting_for_decryption_key_cb */) { DVLOG(1) << __FUNCTION__; DCHECK(task_runner_->BelongsToCurrentThread()); DCHECK(demuxer_stream_provider);
diff --git a/media/mojo/services/mojo_renderer_impl.h b/media/mojo/services/mojo_renderer_impl.h index d1ddc31..338bcb8 100644 --- a/media/mojo/services/mojo_renderer_impl.h +++ b/media/mojo/services/mojo_renderer_impl.h
@@ -39,7 +39,8 @@ const BufferingStateCB& buffering_state_cb, const PaintCB& paint_cb, const base::Closure& ended_cb, - const PipelineStatusCB& error_cb) override; + const PipelineStatusCB& error_cb, + const base::Closure& waiting_for_decryption_key_cb) override; void SetCdm(CdmContext* cdm_context, const CdmAttachedCB& cdm_attached_cb) override; void Flush(const base::Closure& flush_cb) override;
diff --git a/media/mojo/services/mojo_renderer_service.cc b/media/mojo/services/mojo_renderer_service.cc index a737aa32..d4d2c9a 100644 --- a/media/mojo/services/mojo_renderer_service.cc +++ b/media/mojo/services/mojo_renderer_service.cc
@@ -120,7 +120,8 @@ base::Bind(&MojoRendererService::OnBufferingStateChanged, weak_this_), base::Bind(&PaintNothing), base::Bind(&MojoRendererService::OnRendererEnded, weak_this_), - base::Bind(&MojoRendererService::OnError, weak_this_)); + base::Bind(&MojoRendererService::OnError, weak_this_), + base::Bind(base::DoNothing)); } void MojoRendererService::OnRendererInitializeDone(
diff --git a/media/renderers/audio_renderer_impl.cc b/media/renderers/audio_renderer_impl.cc index 56f3da7..74ef1d2 100644 --- a/media/renderers/audio_renderer_impl.cc +++ b/media/renderers/audio_renderer_impl.cc
@@ -257,7 +257,8 @@ const StatisticsCB& statistics_cb, const BufferingStateCB& buffering_state_cb, const base::Closure& ended_cb, - const PipelineStatusCB& error_cb) { + const PipelineStatusCB& error_cb, + const base::Closure& waiting_for_decryption_key_cb) { DVLOG(1) << __FUNCTION__; DCHECK(task_runner_->BelongsToCurrentThread()); DCHECK(stream); @@ -317,7 +318,7 @@ audio_buffer_stream_->Initialize( stream, base::Bind(&AudioRendererImpl::OnAudioBufferStreamInitialized, weak_factory_.GetWeakPtr()), - set_decryptor_ready_cb, statistics_cb); + set_decryptor_ready_cb, statistics_cb, waiting_for_decryption_key_cb); } void AudioRendererImpl::OnAudioBufferStreamInitialized(bool success) {
diff --git a/media/renderers/audio_renderer_impl.h b/media/renderers/audio_renderer_impl.h index af7251a..1972c872 100644 --- a/media/renderers/audio_renderer_impl.h +++ b/media/renderers/audio_renderer_impl.h
@@ -80,7 +80,8 @@ const StatisticsCB& statistics_cb, const BufferingStateCB& buffering_state_cb, const base::Closure& ended_cb, - const PipelineStatusCB& error_cb) override; + const PipelineStatusCB& error_cb, + const base::Closure& waiting_for_decryption_key_cb) override; TimeSource* GetTimeSource() override; void Flush(const base::Closure& callback) override; void StartPlaying() override;
diff --git a/media/renderers/audio_renderer_impl_unittest.cc b/media/renderers/audio_renderer_impl_unittest.cc index b5035c6..98782c93 100644 --- a/media/renderers/audio_renderer_impl_unittest.cc +++ b/media/renderers/audio_renderer_impl_unittest.cc
@@ -113,8 +113,10 @@ MOCK_METHOD1(OnStatistics, void(const PipelineStatistics&)); MOCK_METHOD1(OnBufferingStateChange, void(BufferingState)); MOCK_METHOD1(OnError, void(PipelineStatus)); + MOCK_METHOD0(OnWaitingForDecryptionKey, void(void)); void InitializeRenderer(const PipelineStatusCB& pipeline_status_cb) { + EXPECT_CALL(*this, OnWaitingForDecryptionKey()).Times(0); renderer_->Initialize( &demuxer_stream_, pipeline_status_cb, SetDecryptorReadyCB(), base::Bind(&AudioRendererImplTest::OnStatistics, @@ -122,7 +124,9 @@ base::Bind(&AudioRendererImplTest::OnBufferingStateChange, base::Unretained(this)), base::Bind(&AudioRendererImplTest::OnEnded, base::Unretained(this)), - base::Bind(&AudioRendererImplTest::OnError, base::Unretained(this))); + base::Bind(&AudioRendererImplTest::OnError, base::Unretained(this)), + base::Bind(&AudioRendererImplTest::OnWaitingForDecryptionKey, + base::Unretained(this))); } void Initialize() {
diff --git a/media/renderers/renderer_impl.cc b/media/renderers/renderer_impl.cc index 74e09d7..93671851 100644 --- a/media/renderers/renderer_impl.cc +++ b/media/renderers/renderer_impl.cc
@@ -56,13 +56,15 @@ base::ResetAndReturn(&flush_cb_).Run(); } -void RendererImpl::Initialize(DemuxerStreamProvider* demuxer_stream_provider, - const PipelineStatusCB& init_cb, - const StatisticsCB& statistics_cb, - const BufferingStateCB& buffering_state_cb, - const PaintCB& paint_cb, - const base::Closure& ended_cb, - const PipelineStatusCB& error_cb) { +void RendererImpl::Initialize( + DemuxerStreamProvider* demuxer_stream_provider, + const PipelineStatusCB& init_cb, + const StatisticsCB& statistics_cb, + const BufferingStateCB& buffering_state_cb, + const PaintCB& paint_cb, + const base::Closure& ended_cb, + const PipelineStatusCB& error_cb, + const base::Closure& waiting_for_decryption_key_cb) { DVLOG(1) << __FUNCTION__; DCHECK(task_runner_->BelongsToCurrentThread()); DCHECK_EQ(state_, STATE_UNINITIALIZED); @@ -82,6 +84,7 @@ ended_cb_ = ended_cb; error_cb_ = error_cb; init_cb_ = init_cb; + waiting_for_decryption_key_cb_ = waiting_for_decryption_key_cb; state_ = STATE_INITIALIZING; InitializeAudioRenderer(); @@ -258,7 +261,8 @@ base::Bind(&RendererImpl::OnBufferingStateChanged, weak_this_, &audio_buffering_state_), base::Bind(&RendererImpl::OnAudioRendererEnded, weak_this_), - base::Bind(&RendererImpl::OnError, weak_this_)); + base::Bind(&RendererImpl::OnError, weak_this_), + waiting_for_decryption_key_cb_); } void RendererImpl::OnAudioRendererInitializeDone(PipelineStatus status) { @@ -307,7 +311,8 @@ base::Bind(&RendererImpl::OnVideoRendererEnded, weak_this_), base::Bind(&RendererImpl::OnError, weak_this_), base::Bind(&RendererImpl::GetMediaTimeForSyncingVideo, - base::Unretained(this))); + base::Unretained(this)), + waiting_for_decryption_key_cb_); } void RendererImpl::OnVideoRendererInitializeDone(PipelineStatus status) {
diff --git a/media/renderers/renderer_impl.h b/media/renderers/renderer_impl.h index 68a2f7e0..befa95c1 100644 --- a/media/renderers/renderer_impl.h +++ b/media/renderers/renderer_impl.h
@@ -49,7 +49,8 @@ const BufferingStateCB& buffering_state_cb, const PaintCB& paint_cb, const base::Closure& ended_cb, - const PipelineStatusCB& error_cb) final; + const PipelineStatusCB& error_cb, + const base::Closure& waiting_for_decryption_key_cb) final; void SetCdm(CdmContext* cdm_context, const CdmAttachedCB& cdm_attached_cb) final; void Flush(const base::Closure& flush_cb) final; @@ -133,6 +134,7 @@ PipelineStatusCB error_cb_; BufferingStateCB buffering_state_cb_; PaintCB paint_cb_; + base::Closure waiting_for_decryption_key_cb_; // Temporary callback used for Initialize() and Flush(). PipelineStatusCB init_cb_;
diff --git a/media/renderers/renderer_impl_unittest.cc b/media/renderers/renderer_impl_unittest.cc index 8f738b0..30bad2fe 100644 --- a/media/renderers/renderer_impl_unittest.cc +++ b/media/renderers/renderer_impl_unittest.cc
@@ -50,6 +50,7 @@ MOCK_METHOD1(OnUpdateStatistics, void(const PipelineStatistics&)); MOCK_METHOD1(OnBufferingStateChange, void(BufferingState)); MOCK_METHOD1(OnVideoFramePaint, void(const scoped_refptr<VideoFrame>&)); + MOCK_METHOD0(OnWaitingForDecryptionKey, void()); private: DISALLOW_COPY_AND_ASSIGN(CallbackHelper); @@ -88,7 +89,7 @@ // Sets up expectations to allow the audio renderer to initialize. void SetAudioRendererInitializeExpectations(PipelineStatus status) { EXPECT_CALL(*audio_renderer_, - Initialize(audio_stream_.get(), _, _, _, _, _, _)) + Initialize(audio_stream_.get(), _, _, _, _, _, _, _)) .WillOnce(DoAll(SaveArg<4>(&audio_buffering_state_cb_), SaveArg<5>(&audio_ended_cb_), SaveArg<6>(&audio_error_cb_), RunCallback<1>(status))); @@ -97,13 +98,14 @@ // Sets up expectations to allow the video renderer to initialize. void SetVideoRendererInitializeExpectations(PipelineStatus status) { EXPECT_CALL(*video_renderer_, - Initialize(video_stream_.get(), _, _, _, _, _, _, _, _)) + Initialize(video_stream_.get(), _, _, _, _, _, _, _, _, _)) .WillOnce(DoAll(SaveArg<4>(&video_buffering_state_cb_), SaveArg<6>(&video_ended_cb_), RunCallback<1>(status))); } void InitializeAndExpect(PipelineStatus start_status) { EXPECT_CALL(callbacks_, OnInitialize(start_status)); + EXPECT_CALL(callbacks_, OnWaitingForDecryptionKey()).Times(0); if (start_status == PIPELINE_OK && audio_stream_) { EXPECT_CALL(*audio_renderer_, GetTimeSource()) @@ -121,7 +123,9 @@ base::Bind(&CallbackHelper::OnVideoFramePaint, base::Unretained(&callbacks_)), base::Bind(&CallbackHelper::OnEnded, base::Unretained(&callbacks_)), - base::Bind(&CallbackHelper::OnError, base::Unretained(&callbacks_))); + base::Bind(&CallbackHelper::OnError, base::Unretained(&callbacks_)), + base::Bind(&CallbackHelper::OnWaitingForDecryptionKey, + base::Unretained(&callbacks_))); base::RunLoop().RunUntilIdle(); } @@ -433,7 +437,7 @@ // Force an audio error to occur during video renderer initialization. EXPECT_CALL(*video_renderer_, - Initialize(video_stream_.get(), _, _, _, _, _, _, _, _)) + Initialize(video_stream_.get(), _, _, _, _, _, _, _, _, _)) .WillOnce(DoAll(AudioError(&audio_error_cb_, PIPELINE_ERROR_DECODE), SaveArg<4>(&video_buffering_state_cb_), SaveArg<6>(&video_ended_cb_),
diff --git a/media/renderers/video_renderer_impl.cc b/media/renderers/video_renderer_impl.cc index 5e2819d..0ad19e4 100644 --- a/media/renderers/video_renderer_impl.cc +++ b/media/renderers/video_renderer_impl.cc
@@ -109,7 +109,8 @@ const PaintCB& paint_cb, const base::Closure& ended_cb, const PipelineStatusCB& error_cb, - const TimeDeltaCB& get_time_cb) { + const TimeDeltaCB& get_time_cb, + const base::Closure& waiting_for_decryption_key_cb) { DCHECK(task_runner_->BelongsToCurrentThread()); base::AutoLock auto_lock(lock_); DCHECK(stream); @@ -139,7 +140,7 @@ video_frame_stream_->Initialize( stream, base::Bind(&VideoRendererImpl::OnVideoFrameStreamInitialized, weak_factory_.GetWeakPtr()), - set_decryptor_ready_cb, statistics_cb); + set_decryptor_ready_cb, statistics_cb, waiting_for_decryption_key_cb); } void VideoRendererImpl::CreateVideoThread() {
diff --git a/media/renderers/video_renderer_impl.h b/media/renderers/video_renderer_impl.h index 69cf140..eec8b15 100644 --- a/media/renderers/video_renderer_impl.h +++ b/media/renderers/video_renderer_impl.h
@@ -60,7 +60,8 @@ const PaintCB& paint_cb, const base::Closure& ended_cb, const PipelineStatusCB& error_cb, - const TimeDeltaCB& get_time_cb) override; + const TimeDeltaCB& get_time_cb, + const base::Closure& waiting_for_decryption_key_cb) override; void Flush(const base::Closure& callback) override; void StartPlayingFrom(base::TimeDelta timestamp) override;
diff --git a/media/renderers/video_renderer_impl_unittest.cc b/media/renderers/video_renderer_impl_unittest.cc index c771ad4..d9cad51 100644 --- a/media/renderers/video_renderer_impl_unittest.cc +++ b/media/renderers/video_renderer_impl_unittest.cc
@@ -94,6 +94,7 @@ demuxer_stream_.set_liveness(DemuxerStream::LIVENESS_LIVE); EXPECT_CALL(*decoder_, Initialize(_, _, _, _)).WillOnce( DoAll(SaveArg<3>(&output_cb_), RunCallback<2>(decoder_status))); + EXPECT_CALL(*this, OnWaitingForDecryptionKey()).Times(0); renderer_->Initialize( &demuxer_stream_, status_cb, media::SetDecryptorReadyCB(), base::Bind(&VideoRendererImplTest::OnStatisticsUpdate, @@ -102,7 +103,9 @@ base::Unretained(&mock_cb_)), base::Bind(&StrictMock<MockCB>::Display, base::Unretained(&mock_cb_)), ended_event_.GetClosure(), error_event_.GetPipelineStatusCB(), - base::Bind(&VideoRendererImplTest::GetTime, base::Unretained(this))); + base::Bind(&VideoRendererImplTest::GetTime, base::Unretained(this)), + base::Bind(&VideoRendererImplTest::OnWaitingForDecryptionKey, + base::Unretained(this))); } void StartPlayingFrom(int milliseconds) { @@ -289,6 +292,8 @@ void OnStatisticsUpdate(const PipelineStatistics& stats) {} + MOCK_METHOD0(OnWaitingForDecryptionKey, void(void)); + base::MessageLoop message_loop_; // Used to protect |time_|.
diff --git a/media/test/pipeline_integration_test.cc b/media/test/pipeline_integration_test.cc index c2e23f8f..55bba587 100644 --- a/media/test/pipeline_integration_test.cc +++ b/media/test/pipeline_integration_test.cc
@@ -659,6 +659,10 @@ .WillRepeatedly(SaveArg<0>(&metadata_)); EXPECT_CALL(*this, OnBufferingStateChanged(BUFFERING_HAVE_ENOUGH)) .Times(AtMost(1)); + + // Encrypted content not used, so this is never called. + EXPECT_CALL(*this, OnWaitingForDecryptionKey()).Times(0); + demuxer_ = source->GetDemuxer().Pass(); pipeline_->Start( demuxer_.get(), CreateRenderer(), @@ -673,7 +677,9 @@ base::Bind(&PipelineIntegrationTest::OnVideoFramePaint, base::Unretained(this)), base::Closure(), base::Bind(&PipelineIntegrationTest::OnAddTextTrack, - base::Unretained(this))); + base::Unretained(this)), + base::Bind(&PipelineIntegrationTest::OnWaitingForDecryptionKey, + base::Unretained(this))); message_loop_.Run(); EXPECT_EQ(PIPELINE_OK, pipeline_status_); } @@ -694,6 +700,10 @@ .Times(AtMost(1)); EXPECT_CALL(*this, DecryptorAttached(true)); + // Encrypted content used but keys provided in advance, so this is + // never called. + EXPECT_CALL(*this, OnWaitingForDecryptionKey()).Times(0); + demuxer_ = source->GetDemuxer().Pass(); pipeline_->SetCdm(encrypted_media->GetCdmContext(), @@ -713,7 +723,9 @@ base::Bind(&PipelineIntegrationTest::OnVideoFramePaint, base::Unretained(this)), base::Closure(), base::Bind(&PipelineIntegrationTest::OnAddTextTrack, - base::Unretained(this))); + base::Unretained(this)), + base::Bind(&PipelineIntegrationTest::OnWaitingForDecryptionKey, + base::Unretained(this))); source->set_encrypted_media_init_data_cb( base::Bind(&FakeEncryptedMedia::OnEncryptedMediaInitData,
diff --git a/media/test/pipeline_integration_test_base.cc b/media/test/pipeline_integration_test_base.cc index d40b0dcb..e122d9a8 100644 --- a/media/test/pipeline_integration_test_base.cc +++ b/media/test/pipeline_integration_test_base.cc
@@ -121,6 +121,10 @@ base::Unretained(this))); } + // Should never be called as the required decryption keys for the encrypted + // media files are provided in advance. + EXPECT_CALL(*this, OnWaitingForDecryptionKey()).Times(0); + pipeline_->Start( demuxer_.get(), CreateRenderer(), base::Bind(&PipelineIntegrationTestBase::OnEnded, base::Unretained(this)), @@ -134,7 +138,9 @@ base::Bind(&PipelineIntegrationTestBase::OnVideoFramePaint, base::Unretained(this)), base::Closure(), base::Bind(&PipelineIntegrationTestBase::OnAddTextTrack, - base::Unretained(this))); + base::Unretained(this)), + base::Bind(&PipelineIntegrationTestBase::OnWaitingForDecryptionKey, + base::Unretained(this))); message_loop_.Run(); return pipeline_status_; }
diff --git a/media/test/pipeline_integration_test_base.h b/media/test/pipeline_integration_test_base.h index de6c0e0..716e27cf 100644 --- a/media/test/pipeline_integration_test_base.h +++ b/media/test/pipeline_integration_test_base.h
@@ -140,6 +140,7 @@ MOCK_METHOD2(OnAddTextTrack, void(const TextTrackConfig& config, const AddTextTrackDoneCB& done_cb)); + MOCK_METHOD0(OnWaitingForDecryptionKey, void(void)); }; } // namespace media
diff --git a/media/tools/player_x11/player_x11.cc b/media/tools/player_x11/player_x11.cc index afd5d0b..60eb45c 100644 --- a/media/tools/player_x11/player_x11.cc +++ b/media/tools/player_x11/player_x11.cc
@@ -149,7 +149,8 @@ base::Bind(&OnBufferingStateChanged), paint_cb, base::Bind(&DoNothing), - base::Bind(&OnAddTextTrack)); + base::Bind(&OnAddTextTrack), + base::Bind(&DoNothing)); // Wait until the pipeline is fully initialized. event.Wait();
diff --git a/native_client_sdk/doc_generated/reference/ideas.html b/native_client_sdk/doc_generated/reference/ideas.html index 863af86a..69422c7 100644 --- a/native_client_sdk/doc_generated/reference/ideas.html +++ b/native_client_sdk/doc_generated/reference/ideas.html
@@ -4,41 +4,42 @@ <span id="ideas"></span><h1 id="contributor-ideas"><span id="ideas"></span>Contributor Ideas</h1> <div class="contents local" id="contents" style="display: none"> <ul class="small-gap"> -<li><a class="reference internal" href="#contributing-me" id="id8">Contributing? Me‽</a></li> -<li><p class="first"><a class="reference internal" href="#id1" id="id9">Ideas</a></p> +<li><a class="reference internal" href="#contributing-me" id="id9">Contributing? Me‽</a></li> +<li><a class="reference internal" href="#google-summer-of-code" id="id10">Google Summer of Code</a></li> +<li><p class="first"><a class="reference internal" href="#id2" id="id11">Ideas</a></p> <ul class="small-gap"> -<li><p class="first"><a class="reference internal" href="#ports" id="id10">Ports</a></p> +<li><p class="first"><a class="reference internal" href="#ports" id="id12">Ports</a></p> <ul class="small-gap"> -<li><a class="reference internal" href="#new-filesystems" id="id11">New Filesystems</a></li> -<li><a class="reference internal" href="#open-source-porting" id="id12">Open Source Porting</a></li> +<li><a class="reference internal" href="#new-filesystems" id="id13">New Filesystems</a></li> +<li><a class="reference internal" href="#open-source-porting" id="id14">Open Source Porting</a></li> </ul> </li> -<li><p class="first"><a class="reference internal" href="#languages" id="id13">Languages</a></p> +<li><p class="first"><a class="reference internal" href="#languages" id="id15">Languages</a></p> <ul class="small-gap"> -<li><a class="reference internal" href="#rust" id="id14">Rust</a></li> -<li><a class="reference internal" href="#haskell" id="id15">Haskell</a></li> -<li><a class="reference internal" href="#julia" id="id16">Julia</a></li> -<li><a class="reference internal" href="#scala" id="id17">Scala</a></li> -<li><a class="reference internal" href="#elm" id="id18">Elm</a></li> -<li><a class="reference internal" href="#mono" id="id19">Mono</a></li> -<li><a class="reference internal" href="#perl" id="id20">Perl</a></li> +<li><a class="reference internal" href="#rust" id="id16">Rust</a></li> +<li><a class="reference internal" href="#haskell" id="id17">Haskell</a></li> +<li><a class="reference internal" href="#julia" id="id18">Julia</a></li> +<li><a class="reference internal" href="#scala" id="id19">Scala</a></li> +<li><a class="reference internal" href="#elm" id="id20">Elm</a></li> +<li><a class="reference internal" href="#mono" id="id21">Mono</a></li> +<li><a class="reference internal" href="#perl" id="id22">Perl</a></li> </ul> </li> -<li><a class="reference internal" href="#tcc" id="id21">TCC</a></li> -<li><p class="first"><a class="reference internal" href="#llvm-and-pnacl" id="id22">LLVM and PNaCl</a></p> +<li><a class="reference internal" href="#tcc" id="id23">TCC</a></li> +<li><p class="first"><a class="reference internal" href="#llvm-and-pnacl" id="id24">LLVM and PNaCl</a></p> <ul class="small-gap"> -<li><a class="reference internal" href="#sandboxing-optimizations" id="id23">Sandboxing Optimizations</a></li> -<li><a class="reference internal" href="#binary-size-reduction" id="id24">Binary Size Reduction</a></li> -<li><a class="reference internal" href="#vector-support" id="id25">Vector Support</a></li> -<li><a class="reference internal" href="#atomics" id="id26">Atomics</a></li> -<li><a class="reference internal" href="#security-enhanced-pnacl" id="id27">Security-enhanced PNaCl</a></li> +<li><a class="reference internal" href="#sandboxing-optimizations" id="id25">Sandboxing Optimizations</a></li> +<li><a class="reference internal" href="#binary-size-reduction" id="id26">Binary Size Reduction</a></li> +<li><a class="reference internal" href="#vector-support" id="id27">Vector Support</a></li> +<li><a class="reference internal" href="#atomics" id="id28">Atomics</a></li> +<li><a class="reference internal" href="#security-enhanced-pnacl" id="id29">Security-enhanced PNaCl</a></li> </ul> </li> -<li><p class="first"><a class="reference internal" href="#nacl" id="id28">NaCl</a></p> +<li><p class="first"><a class="reference internal" href="#nacl" id="id30">NaCl</a></p> <ul class="small-gap"> -<li><a class="reference internal" href="#auto-sandboxing" id="id29">Auto-Sandboxing</a></li> -<li><a class="reference internal" href="#new-sandbox" id="id30">New Sandbox</a></li> -<li><a class="reference internal" href="#bit-sandbox" id="id31">64-bit Sandbox</a></li> +<li><a class="reference internal" href="#auto-sandboxing" id="id31">Auto-Sandboxing</a></li> +<li><a class="reference internal" href="#new-sandbox" id="id32">New Sandbox</a></li> +<li><a class="reference internal" href="#bit-sandbox" id="id33">64-bit Sandbox</a></li> </ul> </li> </ul> @@ -57,7 +58,12 @@ this page please contact the <a class="reference external" href="https://groups.google.com/group/native-client-discuss">native-client-discuss</a> mailing list.</p> <p>If you like an idea on this page and would like to get started, contact the <a class="reference external" href="https://groups.google.com/group/native-client-discuss">native-client-discuss</a> mailing list so that we can help you find a mentor.</p> -<h2 id="id1">Ideas</h2> +<h2 id="google-summer-of-code">Google Summer of Code</h2> +<p>PNaCl participates in the <a class="reference external" href="https://www.google-melange.com/gsoc/homepage/google/gsoc2015">2015 Google Summer of Code</a> (see the <a class="reference external" href="https://www.google-melange.com/gsoc/org2/google/gsoc2015/pnacl">PNaCl GSoC +page</a>). <a class="reference external" href="https://www.google-melange.com/gsoc/document/show/gsoc_program/google/gsoc2015/help_page#4._How_does_a_student_apply">Student applications</a> are open March 16–27. Discuss project ideas no +<a class="reference external" href="https://groups.google.com/group/native-client-discuss">native-client-discuss</a>, and submit your proposal on the GSoC page by the +deadline.</p> +<h2 id="id2">Ideas</h2> <p>We’ve separated contributor ideas into broad areas of interest:</p> <ul class="small-gap"> <li><strong>Ports</strong> encompass all the code that <em>uses</em> the PNaCl platform. Put simply,
diff --git a/native_client_sdk/doc_generated/sdk/release-notes.html b/native_client_sdk/doc_generated/sdk/release-notes.html index 7a81d94..798946f 100644 --- a/native_client_sdk/doc_generated/sdk/release-notes.html +++ b/native_client_sdk/doc_generated/sdk/release-notes.html
@@ -4,6 +4,13 @@ <span id="sdk-release-notes"></span><h1 id="release-notes"><span id="sdk-release-notes"></span>Release Notes</h1> <p>The dates in the following release notes denote when Chrome and the NaCl SDK reached canary status. The stable release is typically 6 weeks later.</p> +<h2 id="chrome-pepper-43-03-april-2015">Chrome/Pepper 43 (03 April 2015)</h2> +<h3 id="pnacl">PNaCl</h3> +<ul class="small-gap"> +<li>The C11/C++11 <code>acquire</code>, <code>release</code>, and <code>acq_rel</code> memory orders are now +generated by default. The in-browser Chrome 42 translator supports them, the +SDK can therefore generate them.</li> +</ul> <h2 id="chrome-pepper-42-20-february-2015">Chrome/Pepper 42 (20 February 2015)</h2> <h3 id="sdk">SDK</h3> <ul class="small-gap"> @@ -16,17 +23,17 @@ <h3 id="nacl">NaCl</h3> <ul class="small-gap"> <li>The x86 NaCl validators accept instructions from the FMA3 extensions, as well -as AVX2 instructions (except <cite>VGATHER</cite>).</li> +as AVX2 instructions (except <code>VGATHER</code>).</li> </ul> -<h3 id="pnacl">PNaCl</h3> +<h3 id="id1">PNaCl</h3> <ul class="small-gap"> -<li>PNaCl supports C11/C++11 memory orders <cite>acquire</cite>, <cite>release</cite>, and <cite>acq_rel</cite>. It -used to upgrade all accesses to <cite>seq_cst</cite>. It still upgrades <cite>consume</cite> to -<cite>acquire</cite> (no compiler currently implements <cite>consume</cite>), and <cite>relaxed</cite> to -<cite>seq_cst</cite> (to conservatively avoid platform differences due to out-of-thin-air -problems). This is currently disabled by default in the SDK so that the -in-browser translator installed on users’ machines has time to gain this -support. Developers can turn it on by passing the +<li>PNaCl supports C11/C++11 memory orders <code>acquire</code>, <code>release</code>, and +<code>acq_rel</code>. It used to upgrade all accesses to <code>seq_cst</code>. It still upgrades +<code>consume</code> to <code>acquire</code> (no compiler currently implements <code>consume</code>), and +<code>relaxed</code> to <code>seq_cst</code> (to conservatively avoid platform differences due +to out-of-thin-air problems). This is currently disabled by default in the SDK +so that the in-browser translator installed on users’ machines has time to +gain this support. Developers can turn it on by passing the <code>-pnacl-memory-order-seq-cst-only=false</code> flag to <code>opt</code>.</li> <li>PNaCl handles nested struct type expansion, which allows it to better support non-C languages such as Rust.</li> @@ -34,11 +41,11 @@ operations. This is often encountered when using large consecutive bitfields.</li> </ul> <h2 id="chrome-pepper-41-09-january-2015">Chrome/Pepper 41 (09 January 2015)</h2> -<h3 id="id1">NaCl</h3> +<h3 id="id2">NaCl</h3> <ul class="small-gap"> <li>The x86 NaCl validators accept instructions from the AVX1 extensions.</li> </ul> -<h3 id="id2">PNaCl</h3> +<h3 id="id3">PNaCl</h3> <ul class="small-gap"> <li>PNaCl is now based on LLVM 3.5.</li> </ul> @@ -57,31 +64,31 @@ embeds.</li> </ul> <h2 id="chrome-pepper-38-15-august-2014">Chrome/Pepper 38 (15 August 2014)</h2> -<h3 id="id3">PNaCl</h3> +<h3 id="id4">PNaCl</h3> <ul class="small-gap"> <li>Compilation speed improvements due to validation caching of the translator and linker.</li> <li>Performance improvement of SIMD vector shuffle.</li> </ul> <h2 id="chrome-pepper-37-20-june-2014">Chrome/Pepper 37 (20 June 2014)</h2> -<h3 id="id4">PNaCl</h3> +<h3 id="id5">PNaCl</h3> <ul class="small-gap"> <li>2–10% translation time improvement.</li> <li>Improved vector load/store and shuffle performance.</li> </ul> -<h3 id="id5">Pepper</h3> +<h3 id="id6">Pepper</h3> <ul class="small-gap"> <li>Media Streams Input support.</li> <li>Compositor API.</li> <li>Hardware Decode API in development preview.</li> <li>Sync API in development preview.</li> </ul> -<h3 id="id6">SDK</h3> +<h3 id="id7">SDK</h3> <ul class="small-gap"> <li>Demo of a <a class="reference internal" href="/native-client/io2014.html#io2014"><em>full development environment in the browser</em></a>.</li> </ul> <h2 id="chrome-pepper-36-09-may-2014">Chrome/Pepper 36 (09 May 2014)</h2> -<h3 id="id7">PNaCl</h3> +<h3 id="id8">PNaCl</h3> <ul class="small-gap"> <li>Support <a class="reference external" href="http://clang.llvm.org/docs/LanguageExtensions.html#vectors-and-extended-vectors">LLVM vectors</a> and <a class="reference external" href="http://gcc.gnu.org/onlinedocs/gcc/Vector-Extensions.html">GCC vectors</a> for SIMD @@ -90,7 +97,7 @@ Chrome. More SIMD instructions will be added in later releases.</li> </ul> <h2 id="chrome-pepper-35-31-mar-2014">Chrome/Pepper 35 (31 Mar 2014)</h2> -<h3 id="id8">PNaCl</h3> +<h3 id="id9">PNaCl</h3> <ul class="small-gap"> <li>Upgraded LLVM to version 3.4.</li> <li>Translation now uses dynamic load balancing, making translation time faster.</li> @@ -98,7 +105,7 @@ Chrome, simplifying debugging with PNaCl. See <a class="reference internal" href="/native-client/devguide/devcycle/debugging.html#debugging-pnacl-pexes"><em>Debugging PNaCl pexes</em></a></li> </ul> <h2 id="chrome-pepper-34-20-feb-2014">Chrome/Pepper 34 (20 Feb 2014)</h2> -<h3 id="id9">Pepper</h3> +<h3 id="id10">Pepper</h3> <ul class="small-gap"> <li>Filesystems can now be passed from JavaScript to NaCl. The resulting <code>pp::Var</code> will contain a <code>pp::Resource</code> that can be given to the @@ -108,7 +115,7 @@ <a class="reference external" href="/native-client/pepper_dev/cpp/classpp_1_1_media_stream_video_track">pp::MediaStreamVideoTrack</a> for more details.</li> </ul> -<h3 id="id10">PNaCl</h3> +<h3 id="id11">PNaCl</h3> <ul class="small-gap"> <li>Parallel translation: at least 1.7x faster, even with older pexes.</li> <li>Intelligent abbreviations in the bitcode: 20% reduction in binary size using @@ -122,7 +129,7 @@ handling (see <a class="reference external" href="https://groups.google.com/forum/#!topic/native-client-discuss/0spfg6O04FM">announcement</a> for details).</li> </ul> -<h3 id="id11">SDK</h3> +<h3 id="id12">SDK</h3> <ul class="small-gap"> <li>The <code>nacl_io</code> library now includes a FUSE mount.</li> <li>In the SDK examples, <code>common.js</code> now loads the Release version of the @@ -236,7 +243,7 @@ <p>The Pepper 26 bundle includes a new HTTP filesystem type in the nacl_mounts library (which has been renamed nacl_io), changes to the example Makefiles, a simple new 3D example, and a threaded file IO example.</p> -<h3 id="id12">Build tools and toolchains</h3> +<h3 id="id13">Build tools and toolchains</h3> <ul class="small-gap"> <li><p class="first">Makefiles have been changed significantly:</p> <ul class="small-gap"> @@ -256,14 +263,14 @@ the same set of header files as host builds. Previously host and NaCl builds used different headers, which could cause build problems.</li> </ul> -<h3 id="id13">Libraries</h3> +<h3 id="id14">Libraries</h3> <ul class="small-gap"> <li>The nacl_mounts library has been renamed <strong>nacl_io</strong>, and has been expanded with a new type of mount, httpfs, which can be used to read URLs via HTTP. For details see <code>include/nacl_io/nacl_io.h</code>, as well as the <code>hello_nacl_io</code> example.</li> </ul> -<h3 id="id14">Examples</h3> +<h3 id="id15">Examples</h3> <ul class="small-gap"> <li>A new example, <strong>hello_world_instance3d</strong>, has been added to demonstrate a simplified 3D app.</li> @@ -285,7 +292,7 @@ operations, and ppapi_main, which lets you implement a Native Client module using a simple ppapi_main function), and two new examples that demonstrate how to use the nacl_mounts and ppapi_main libraries.</p> -<h3 id="id15">Build tools and toolchains</h3> +<h3 id="id16">Build tools and toolchains</h3> <ul class="small-gap"> <li><p class="first">The SDK includes a new toolchain to build Native Client executables (.nexe files) for <strong>ARM devices</strong>.</p> @@ -322,7 +329,7 @@ cannot make asynchronous PPAPI calls on a background thread without creating and using a message loop.</li> </ul> -<h3 id="id16">Libraries</h3> +<h3 id="id17">Libraries</h3> <p>The SDK includes two new libraries:</p> <ul class="small-gap"> <li><p class="first">The <strong>nacl_mounts</strong> library provides a virtual file system that your module @@ -356,7 +363,7 @@ <p>Header files for the new libraries are in the <code>include/</code> directory, source files are in the <code>src/</code> directory, and compiled libraries are in the <code>lib/</code> directory.</p> -<h3 id="id17">Examples</h3> +<h3 id="id18">Examples</h3> <ul class="small-gap"> <li><p class="first">The SDK includes two new examples:</p> <ul class="small-gap"> @@ -397,7 +404,7 @@ for “Portable Native Client”), a new library (pthreads-win32) for the Windows SDK, and an expanded list of attributes for Pepper 3D contexts that lets applications specify a GPU preference for low power or performance.</p> -<h3 id="id18">Build tools and toolchains</h3> +<h3 id="id19">Build tools and toolchains</h3> <ul class="small-gap"> <li>The SDK includes a new, experimental toolchain called <a class="reference external" href="http://nativeclient.googlecode.com/svn/data/site/pnacl.pdf">PNaCl</a> (pronounced “pinnacle”). The PNaCl toolchain produces architecture-independent executable @@ -413,7 +420,7 @@ names of your .nexe files and <code>create_nmf.py</code> will still be able to generate the appropriate Native Client manifest file for your application.</li> </ul> -<h3 id="id20">Examples</h3> +<h3 id="id21">Examples</h3> <ul class="small-gap"> <li>The SDK examples now build with four toolchains: the glibc and newlib toolchains, the experimental PNaCl toolchain, and the hosted toolchain on @@ -424,7 +431,7 @@ drawing function is now set up as the Flush() callback, which allows 2D drawing to occur as quickly as possible.</li> </ul> -<h3 id="id21">PPAPI</h3> +<h3 id="id22">PPAPI</h3> <ul class="small-gap"> <li>When creating a 3D rendering context, the <a class="reference external" href="/native-client/pepper_stable/c/group___enums#ga7df48e1c55f6401beea2a1b9c07967e8">attribute list</a> for the context can specify whether to prefer low power or performance for @@ -496,7 +503,7 @@ </ul> </li> </ul> -<h3 id="id22">Examples</h3> +<h3 id="id23">Examples</h3> <ul class="small-gap"> <li>On Linux and Windows systems, most of the examples now build with three toolchains: the Native Client glibc and newlib toolchains, and the native @@ -512,7 +519,7 @@ a list of changes between version 1 and version 2 of the manifest file format, and a support schedule for applications that use version 1.</li> </ul> -<h3 id="id23">PPAPI</h3> +<h3 id="id24">PPAPI</h3> <ul class="small-gap"> <li><a class="reference external" href="/native-client/pepper_stable/c/group___enums#ga21b811ac0484a214a8751aa3e1c959d9">PP_InputEvent_Modifier</a> has two new enum values (_ISLEFT and _ISRIGHT).</li> @@ -523,14 +530,14 @@ <p>The Pepper 22 bundle includes a <strong>command-line debugger</strong>, resources to enable <strong>hosted development on Windows</strong>, and changes to the example Makefiles (each example now builds both a debug and a release version).</p> -<h3 id="id24">Tools</h3> +<h3 id="id25">Tools</h3> <ul class="small-gap"> <li>The SDK now includes a <strong>command-line debugger</strong> that you can use to debug Native Client modules. See <a class="reference internal" href="/native-client/devguide/devcycle/debugging.html#devcycle-debugging"><em>Debugging with nacl-gdb</em></a> for instructions on how to use this debugger. For now, nacl-gdb only works on 64-bit Windows, 64-bit Linux, and 32-bit Linux systems. Support for Mac and 32-bit Windows systems will be added soon.</li> </ul> -<h3 id="id25">Windows SDK</h3> +<h3 id="id26">Windows SDK</h3> <ul class="small-gap"> <li><p class="first">Developers using the Windows SDK can now <strong>build a module as a Pepper plugin</strong> (sometimes called a “trusted” or “in-process” plugin) using the @@ -578,7 +585,7 @@ In the future, the SDK will include resources for hosted development on Mac and Linux as well as Windows. </aside> -<h3 id="id26">Examples</h3> +<h3 id="id27">Examples</h3> <ul class="small-gap"> <li>Each example in the SDK now builds both a debug and a release version. As before, most examples also build newlib and glibc versions, which means that @@ -592,7 +599,7 @@ of the module, and implements handleMessage() to respond to messages sent from the NaCl module to the JavaScript side of the application</li> </ul> -<h3 id="id27">PPAPI</h3> +<h3 id="id28">PPAPI</h3> <ul class="small-gap"> <li>The <code>CompletionCallbackFactory</code> class template now takes a thread traits class as its second parameter. For details see the <a class="reference external" href="/native-client/pepper_stable/cpp/classpp_1_1_completion_callback_factory#details">CompletionCallbackFactory
diff --git a/native_client_sdk/doc_generated/sitemap.html b/native_client_sdk/doc_generated/sitemap.html index f6cfcb25..53eba14 100644 --- a/native_client_sdk/doc_generated/sitemap.html +++ b/native_client_sdk/doc_generated/sitemap.html
@@ -42,6 +42,7 @@ </ul> </li> <li class="toctree-l1"><a class="reference internal" href="/native-client/sdk/release-notes.html">Release Notes</a><ul class="small-gap"> +<li class="toctree-l2"><a class="reference internal" href="/native-client/sdk/release-notes.html#chrome-pepper-43-03-april-2015">Chrome/Pepper 43 (03 April 2015)</a></li> <li class="toctree-l2"><a class="reference internal" href="/native-client/sdk/release-notes.html#chrome-pepper-42-20-february-2015">Chrome/Pepper 42 (20 February 2015)</a></li> <li class="toctree-l2"><a class="reference internal" href="/native-client/sdk/release-notes.html#chrome-pepper-41-09-january-2015">Chrome/Pepper 41 (09 January 2015)</a></li> <li class="toctree-l2"><a class="reference internal" href="/native-client/sdk/release-notes.html#chrome-pepper-40-november-07-2014">Chrome/Pepper 40 (November 07 2014)</a></li> @@ -384,7 +385,8 @@ <li class="toctree-l1"><a class="reference internal" href="/native-client/reference/index.html">Reference</a></li> <li class="toctree-l1"><a class="reference internal" href="/native-client/reference/ideas.html">Contributor Ideas</a><ul class="small-gap"> <li class="toctree-l2"><a class="reference internal" href="/native-client/reference/ideas.html#contributing-me">Contributing? Me‽</a></li> -<li class="toctree-l2"><a class="reference internal" href="/native-client/reference/ideas.html#id1">Ideas</a></li> +<li class="toctree-l2"><a class="reference internal" href="/native-client/reference/ideas.html#google-summer-of-code">Google Summer of Code</a></li> +<li class="toctree-l2"><a class="reference internal" href="/native-client/reference/ideas.html#id2">Ideas</a></li> </ul> </li> <li class="toctree-l1"><a class="reference internal" href="/native-client/reference/pnacl-bitcode-abi.html">PNaCl Bitcode Reference Manual</a><ul class="small-gap">
diff --git a/native_client_sdk/src/build_tools/build_app.py b/native_client_sdk/src/build_tools/build_app.py index 0c406c0..e0def78 100755 --- a/native_client_sdk/src/build_tools/build_app.py +++ b/native_client_sdk/src/build_tools/build_app.py
@@ -132,14 +132,20 @@ return list1 + [x for x in list2 if x not in list1] all_permissions = [] all_socket_permissions = [] + all_filesystem_permissions = [] for _, project in parse_dsc.GenerateProjects(tree): permissions = project.get('PERMISSIONS', []) all_permissions = MergeLists(all_permissions, permissions) socket_permissions = project.get('SOCKET_PERMISSIONS', []) all_socket_permissions = MergeLists(all_socket_permissions, socket_permissions) + filesystem_permissions = project.get('FILESYSTEM_PERMISSIONS', []) + all_filesystem_permissions = MergeLists(all_filesystem_permissions, + filesystem_permissions) if all_socket_permissions: all_permissions.append({'socket': all_socket_permissions}) + if all_filesystem_permissions: + all_permissions.append({'fileSystem': all_filesystem_permissions}) pretty_permissions = json.dumps(all_permissions, sort_keys=True, indent=4) for filename in ['background.js', 'icon128.png']:
diff --git a/native_client_sdk/src/doc/reference/ideas.rst b/native_client_sdk/src/doc/reference/ideas.rst index 71d4360..c9a3bfb3 100644 --- a/native_client_sdk/src/doc/reference/ideas.rst +++ b/native_client_sdk/src/doc/reference/ideas.rst
@@ -28,6 +28,18 @@ .. _native-client-discuss: https://groups.google.com/group/native-client-discuss +Google Summer of Code +===================== + +PNaCl participates in the `2015 Google Summer of Code`_ (see the `PNaCl GSoC +page`_). `Student applications`_ are open March 16–27. Discuss project ideas no +native-client-discuss_, and submit your proposal on the GSoC page by the +deadline. + +.. _PNaCl GSoC page: https://www.google-melange.com/gsoc/org2/google/gsoc2015/pnacl +.. _2015 Google Summer of Code: https://www.google-melange.com/gsoc/homepage/google/gsoc2015 +.. _Student applications: https://www.google-melange.com/gsoc/document/show/gsoc_program/google/gsoc2015/help_page#4._How_does_a_student_apply + Ideas =====
diff --git a/native_client_sdk/src/doc/sdk/release-notes.rst b/native_client_sdk/src/doc/sdk/release-notes.rst index f3ccf1537..06eb85777 100644 --- a/native_client_sdk/src/doc/sdk/release-notes.rst +++ b/native_client_sdk/src/doc/sdk/release-notes.rst
@@ -8,15 +8,15 @@ reached canary status. The stable release is typically 6 weeks later. -.. Chrome/Pepper 43 (03 April 2015) -.. =================================== -.. -.. PNaCl -.. ----- -.. -.. * The C11/C++11 `acquire`, `release`, and `acq_rel` memory orders are now - generated by default. The in-browser Chrome 42 translator supports them, the - SDK can therefore generate them. +Chrome/Pepper 43 (03 April 2015) +================================ + +PNaCl +----- + +* The C11/C++11 ``acquire``, ``release``, and ``acq_rel`` memory orders are now + generated by default. The in-browser Chrome 42 translator supports them, the + SDK can therefore generate them. Chrome/Pepper 42 (20 February 2015) =================================== @@ -34,18 +34,18 @@ ---- * The x86 NaCl validators accept instructions from the FMA3 extensions, as well - as AVX2 instructions (except `VGATHER`). + as AVX2 instructions (except ``VGATHER``). PNaCl ----- -* PNaCl supports C11/C++11 memory orders `acquire`, `release`, and `acq_rel`. It - used to upgrade all accesses to `seq_cst`. It still upgrades `consume` to - `acquire` (no compiler currently implements `consume`), and `relaxed` to - `seq_cst` (to conservatively avoid platform differences due to out-of-thin-air - problems). This is currently disabled by default in the SDK so that the - in-browser translator installed on users' machines has time to gain this - support. Developers can turn it on by passing the +* PNaCl supports C11/C++11 memory orders ``acquire``, ``release``, and + ``acq_rel``. It used to upgrade all accesses to ``seq_cst``. It still upgrades + ``consume`` to ``acquire`` (no compiler currently implements ``consume``), and + ``relaxed`` to ``seq_cst`` (to conservatively avoid platform differences due + to out-of-thin-air problems). This is currently disabled by default in the SDK + so that the in-browser translator installed on users' machines has time to + gain this support. Developers can turn it on by passing the ``-pnacl-memory-order-seq-cst-only=false`` flag to ``opt``. * PNaCl handles nested struct type expansion, which allows it to better support non-C languages such as Rust.
diff --git a/net/cert/x509_certificate_unittest.cc b/net/cert/x509_certificate_unittest.cc index f77c46c6..74ded45 100644 --- a/net/cert/x509_certificate_unittest.cc +++ b/net/cert/x509_certificate_unittest.cc
@@ -1011,7 +1011,7 @@ // be present. { true, "www.test.example", "*.test.example" }, { true, "test.example.co.uk", "*.example.co.uk" }, - { false, "test.example", "*.exmaple" }, + { false, "test.example", "*.example" }, { false, "example.co.uk", "*.co.uk" }, { false, "foo.com", "*.com" }, { false, "foo.us", "*.us" },
diff --git a/net/dns/mdns_client_impl.cc b/net/dns/mdns_client_impl.cc index 66873abc..3a594d5 100644 --- a/net/dns/mdns_client_impl.cc +++ b/net/dns/mdns_client_impl.cc
@@ -4,13 +4,16 @@ #include "net/dns/mdns_client_impl.h" +#include <algorithm> #include <queue> #include "base/bind.h" #include "base/message_loop/message_loop_proxy.h" #include "base/stl_util.h" +#include "base/time/clock.h" #include "base/time/default_clock.h" #include "base/time/time.h" +#include "base/timer/timer.h" #include "net/base/dns_util.h" #include "net/base/net_errors.h" #include "net/base/net_log.h" @@ -80,9 +83,7 @@ connection_->OnDatagramReceived(&response_, recv_addr_, rv); rv = socket_->RecvFrom( - response_.io_buffer(), - response_.io_buffer()->size(), - &recv_addr_, + response_.io_buffer(), response_.io_buffer()->size(), &recv_addr_, base::Bind(&MDnsConnection::SocketHandler::OnDatagramReceived, base::Unretained(this))); } while (rv > 0); @@ -195,7 +196,10 @@ delegate_->HandlePacket(response, bytes_read); } -MDnsClientImpl::Core::Core() : connection_(new MDnsConnection(this)) { +MDnsClientImpl::Core::Core(base::Clock* clock, base::Timer* timer) + : clock_(clock), + cleanup_timer_(timer), + connection_(new MDnsConnection(this)) { } MDnsClientImpl::Core::~Core() { @@ -241,8 +245,8 @@ for (unsigned i = 0; i < answer_count; i++) { offset = parser.GetOffset(); - scoped_ptr<const RecordParsed> record = RecordParsed::CreateFrom( - &parser, base::Time::Now()); + scoped_ptr<const RecordParsed> record = + RecordParsed::CreateFrom(&parser, clock_->Now()); if (!record) { DVLOG(1) << "Could not understand an mDNS record."; @@ -295,8 +299,7 @@ // Remove all cached records matching the nonexistent RR types. std::vector<const RecordParsed*> records_to_remove; - cache_.FindDnsRecords(0, record->name(), &records_to_remove, - base::Time::Now()); + cache_.FindDnsRecords(0, record->name(), &records_to_remove, clock_->Now()); for (std::vector<const RecordParsed*>::iterator i = records_to_remove.begin(); i != records_to_remove.end(); i++) { @@ -380,25 +383,26 @@ void MDnsClientImpl::Core::ScheduleCleanup(base::Time cleanup) { // Cleanup is already scheduled, no need to do anything. - if (cleanup == scheduled_cleanup_) return; + if (cleanup == scheduled_cleanup_) { + return; + } scheduled_cleanup_ = cleanup; // This cancels the previously scheduled cleanup. - cleanup_callback_.Reset(base::Bind( - &MDnsClientImpl::Core::DoCleanup, base::Unretained(this))); + cleanup_timer_->Stop(); // If |cleanup| is empty, then no cleanup necessary. if (cleanup != base::Time()) { - base::MessageLoop::current()->PostDelayedTask( - FROM_HERE, - cleanup_callback_.callback(), - cleanup - base::Time::Now()); + cleanup_timer_->Start( + FROM_HERE, std::max(base::TimeDelta(), cleanup - clock_->Now()), + base::Bind(&MDnsClientImpl::Core::DoCleanup, base::Unretained(this))); } } void MDnsClientImpl::Core::DoCleanup() { - cache_.CleanupRecords(base::Time::Now(), base::Bind( - &MDnsClientImpl::Core::OnRecordRemoved, base::Unretained(this))); + cache_.CleanupRecords(clock_->Now(), + base::Bind(&MDnsClientImpl::Core::OnRecordRemoved, + base::Unretained(this))); ScheduleCleanup(cache_.next_expiration()); } @@ -412,10 +416,17 @@ void MDnsClientImpl::Core::QueryCache( uint16 rrtype, const std::string& name, std::vector<const RecordParsed*>* records) const { - cache_.FindDnsRecords(rrtype, name, records, base::Time::Now()); + cache_.FindDnsRecords(rrtype, name, records, clock_->Now()); } -MDnsClientImpl::MDnsClientImpl() { +MDnsClientImpl::MDnsClientImpl() + : clock_(new base::DefaultClock), + cleanup_timer_(new base::Timer(false, false)) { +} + +MDnsClientImpl::MDnsClientImpl(scoped_ptr<base::Clock> clock, + scoped_ptr<base::Timer> timer) + : clock_(clock.Pass()), cleanup_timer_(timer.Pass()) { } MDnsClientImpl::~MDnsClientImpl() { @@ -423,7 +434,7 @@ bool MDnsClientImpl::StartListening(MDnsSocketFactory* socket_factory) { DCHECK(!core_.get()); - core_.reset(new Core()); + core_.reset(new Core(clock_.get(), cleanup_timer_.get())); if (!core_->Init(socket_factory)) { core_.reset(); return false; @@ -444,7 +455,7 @@ const std::string& name, MDnsListener::Delegate* delegate) { return scoped_ptr<net::MDnsListener>( - new MDnsListenerImpl(rrtype, name, delegate, this)); + new MDnsListenerImpl(rrtype, name, clock_.get(), delegate, this)); } scoped_ptr<MDnsTransaction> MDnsClientImpl::CreateTransaction( @@ -456,13 +467,18 @@ new MDnsTransactionImpl(rrtype, name, flags, callback, this)); } -MDnsListenerImpl::MDnsListenerImpl( - uint16 rrtype, - const std::string& name, - MDnsListener::Delegate* delegate, - MDnsClientImpl* client) - : rrtype_(rrtype), name_(name), client_(client), delegate_(delegate), - started_(false), active_refresh_(false) { +MDnsListenerImpl::MDnsListenerImpl(uint16 rrtype, + const std::string& name, + base::Clock* clock, + MDnsListener::Delegate* delegate, + MDnsClientImpl* client) + : rrtype_(rrtype), + name_(name), + clock_(clock), + client_(client), + delegate_(delegate), + started_(false), + active_refresh_(false) { } MDnsListenerImpl::~MDnsListenerImpl() { @@ -571,14 +587,10 @@ kListenerRefreshRatio2 * ttl_)); base::MessageLoop::current()->PostDelayedTask( - FROM_HERE, - next_refresh_.callback(), - next_refresh1 - base::Time::Now()); + FROM_HERE, next_refresh_.callback(), next_refresh1 - clock_->Now()); base::MessageLoop::current()->PostDelayedTask( - FROM_HERE, - next_refresh_.callback(), - next_refresh2 - base::Time::Now()); + FROM_HERE, next_refresh_.callback(), next_refresh2 - clock_->Now()); } void MDnsListenerImpl::DoRefresh() {
diff --git a/net/dns/mdns_client_impl.h b/net/dns/mdns_client_impl.h index 4ed85f2..a0c5b98 100644 --- a/net/dns/mdns_client_impl.h +++ b/net/dns/mdns_client_impl.h
@@ -6,6 +6,7 @@ #define NET_DNS_MDNS_CLIENT_IMPL_H_ #include <map> +#include <queue> #include <string> #include <utility> #include <vector> @@ -21,11 +22,16 @@ #include "net/udp/udp_server_socket.h" #include "net/udp/udp_socket.h" +namespace base { +class Clock; +class Timer; +} // namespace base + namespace net { class MDnsSocketFactoryImpl : public MDnsSocketFactory { public: - MDnsSocketFactoryImpl() {}; + MDnsSocketFactoryImpl() {} ~MDnsSocketFactoryImpl() override{}; void CreateSockets(ScopedVector<DatagramServerSocket>* sockets) override; @@ -109,7 +115,7 @@ // invalidate the core. class Core : public base::SupportsWeakPtr<Core>, MDnsConnection::Delegate { public: - Core(); + Core(base::Clock* clock, base::Timer* timer); ~Core() override; // Initialize the core. Returns true on success. @@ -132,6 +138,8 @@ void OnConnectionError(int error) override; private: + FRIEND_TEST_ALL_PREFIXES(MDnsTest, CacheCleanupWithShortTTL); + typedef std::pair<std::string, uint16> ListenerKey; typedef std::map<ListenerKey, ObserverList<MDnsListenerImpl>* > ListenerMap; @@ -159,7 +167,8 @@ MDnsCache cache_; - base::CancelableClosure cleanup_callback_; + base::Clock* clock_; + base::Timer* cleanup_timer_; base::Time scheduled_cleanup_; scoped_ptr<MDnsConnection> connection_; @@ -189,7 +198,15 @@ Core* core() { return core_.get(); } private: + FRIEND_TEST_ALL_PREFIXES(MDnsTest, CacheCleanupWithShortTTL); + + // Test constructor, takes a mock clock and mock timer. + MDnsClientImpl(scoped_ptr<base::Clock> clock, + scoped_ptr<base::Timer> cleanup_timer); + scoped_ptr<Core> core_; + scoped_ptr<base::Clock> clock_; + scoped_ptr<base::Timer> cleanup_timer_; DISALLOW_COPY_AND_ASSIGN(MDnsClientImpl); }; @@ -199,6 +216,7 @@ public: MDnsListenerImpl(uint16 rrtype, const std::string& name, + base::Clock* clock, MDnsListener::Delegate* delegate, MDnsClientImpl* client); @@ -229,6 +247,7 @@ uint16 rrtype_; std::string name_; + base::Clock* clock_; MDnsClientImpl* client_; MDnsListener::Delegate* delegate_;
diff --git a/net/dns/mdns_client_unittest.cc b/net/dns/mdns_client_unittest.cc index ba03082..70514f3 100644 --- a/net/dns/mdns_client_unittest.cc +++ b/net/dns/mdns_client_unittest.cc
@@ -6,6 +6,9 @@ #include "base/memory/ref_counted.h" #include "base/message_loop/message_loop.h" +#include "base/time/clock.h" +#include "base/time/default_clock.h" +#include "base/timer/mock_timer.h" #include "net/base/rand_callback.h" #include "net/base/test_completion_callback.h" #include "net/dns/mdns_client_impl.h" @@ -222,6 +225,38 @@ 0xc0, 0x32 }; +const uint8 kSamplePacket3[] = { + // Header + 0x00, 0x00, // ID is zeroed out + 0x81, 0x80, // Standard query response, RA, no error + 0x00, 0x00, // No questions (for simplicity) + 0x00, 0x02, // 2 RRs (answers) + 0x00, 0x00, // 0 authority RRs + 0x00, 0x00, // 0 additional RRs + + // Answer 1 + 0x07, '_', 'p', 'r', 'i', 'v', 'e', 't', // + 0x04, '_', 't', 'c', 'p', // + 0x05, 'l', 'o', 'c', 'a', 'l', // + 0x00, 0x00, 0x0c, // TYPE is PTR. + 0x00, 0x01, // CLASS is IN. + 0x00, 0x00, // TTL (4 bytes) is 1 second; + 0x00, 0x01, // + 0x00, 0x08, // RDLENGTH is 8 bytes. + 0x05, 'h', 'e', 'l', 'l', 'o', // + 0xc0, 0x0c, // + + // Answer 2 + 0x08, '_', 'p', 'r', 'i', 'n', 't', 'e', 'r', // + 0xc0, 0x14, // Pointer to "._tcp.local" + 0x00, 0x0c, // TYPE is PTR. + 0x00, 0x01, // CLASS is IN. + 0x00, 0x00, // TTL (4 bytes) is 3 seconds. + 0x00, 0x03, // + 0x00, 0x08, // RDLENGTH is 8 bytes. + 0x05, 'h', 'e', 'l', 'l', 'o', // + 0xc0, 0x32}; + const uint8 kQueryPacketPrivet[] = { // Header 0x00, 0x00, // ID is zeroed out @@ -389,9 +424,45 @@ int ttl_; }; +class MockClock : public base::DefaultClock { + public: + MockClock() : base::DefaultClock() {} + virtual ~MockClock() {} + + MOCK_METHOD0(Now, base::Time()); + + private: + DISALLOW_COPY_AND_ASSIGN(MockClock); +}; + +class MockTimer : public base::MockTimer { + public: + MockTimer() : base::MockTimer(false, false) {} + ~MockTimer() {} + + void Start(const tracked_objects::Location& posted_from, + base::TimeDelta delay, + const base::Closure& user_task) { + StartObserver(posted_from, delay, user_task); + base::MockTimer::Start(posted_from, delay, user_task); + } + + // StartObserver is invoked when MockTimer::Start() is called. + // Does not replace the behavior of MockTimer::Start(). + MOCK_METHOD3(StartObserver, + void(const tracked_objects::Location& posted_from, + base::TimeDelta delay, + const base::Closure& user_task)); + + private: + DISALLOW_COPY_AND_ASSIGN(MockTimer); +}; + +} // namespace + class MDnsTest : public ::testing::Test { public: - virtual void SetUp() override; + void SetUp() override; void DeleteTransaction(); void DeleteBothListeners(); void RunFor(base::TimeDelta time_period); @@ -403,12 +474,11 @@ MOCK_METHOD2(MockableRecordCallback2, void(MDnsTransaction::Result result, const RecordParsed* record)); - protected: void ExpectPacket(const uint8* packet, unsigned size); void SimulatePacketReceive(const uint8* packet, unsigned size); - MDnsClientImpl test_client_; + scoped_ptr<MDnsClientImpl> test_client_; IPEndPoint mdns_ipv4_endpoint_; StrictMock<MockMDnsSocketFactory> socket_factory_; @@ -429,7 +499,8 @@ }; void MDnsTest::SetUp() { - test_client_.StartListening(&socket_factory_); + test_client_.reset(new MDnsClientImpl()); + test_client_->StartListening(&socket_factory_); } void MDnsTest::SimulatePacketReceive(const uint8* packet, unsigned size) { @@ -471,12 +542,10 @@ PtrRecordCopyContainer record_privet; PtrRecordCopyContainer record_printer; - scoped_ptr<MDnsListener> listener_privet = - test_client_.CreateListener(dns_protocol::kTypePTR, "_privet._tcp.local", - &delegate_privet); - scoped_ptr<MDnsListener> listener_printer = - test_client_.CreateListener(dns_protocol::kTypePTR, "_printer._tcp.local", - &delegate_printer); + scoped_ptr<MDnsListener> listener_privet = test_client_->CreateListener( + dns_protocol::kTypePTR, "_privet._tcp.local", &delegate_privet); + scoped_ptr<MDnsListener> listener_printer = test_client_->CreateListener( + dns_protocol::kTypePTR, "_printer._tcp.local", &delegate_printer); ASSERT_TRUE(listener_privet->Start()); ASSERT_TRUE(listener_printer->Start()); @@ -515,9 +584,8 @@ PtrRecordCopyContainer record_privet; PtrRecordCopyContainer record_privet2; - scoped_ptr<MDnsListener> listener_privet = - test_client_.CreateListener(dns_protocol::kTypePTR, "_privet._tcp.local", - &delegate_privet); + scoped_ptr<MDnsListener> listener_privet = test_client_->CreateListener( + dns_protocol::kTypePTR, "_privet._tcp.local", &delegate_privet); ASSERT_TRUE(listener_privet->Start()); @@ -545,14 +613,75 @@ "hello._privet._tcp.local")); } +// Ensure that the cleanup task scheduler won't schedule cleanup tasks in the +// past if the system clock creeps past the expiration time while in the +// cleanup dispatcher. +TEST_F(MDnsTest, CacheCleanupWithShortTTL) { + // Use a nonzero starting time as a base. + base::Time start_time = base::Time() + base::TimeDelta::FromSeconds(1); + + MockClock* clock = new MockClock; + MockTimer* timer = new MockTimer; + + test_client_.reset( + new MDnsClientImpl(make_scoped_ptr(clock), make_scoped_ptr(timer))); + test_client_->StartListening(&socket_factory_); + + EXPECT_CALL(*timer, StartObserver(_, _, _)).Times(1); + EXPECT_CALL(*clock, Now()) + .Times(3) + .WillRepeatedly(Return(start_time)) + .RetiresOnSaturation(); + + // Receive two records with different TTL values. + // TTL(privet)=1.0s + // TTL(printer)=3.0s + StrictMock<MockListenerDelegate> delegate_privet; + StrictMock<MockListenerDelegate> delegate_printer; + + PtrRecordCopyContainer record_privet; + PtrRecordCopyContainer record_printer; + + scoped_ptr<MDnsListener> listener_privet = test_client_->CreateListener( + dns_protocol::kTypePTR, "_privet._tcp.local", &delegate_privet); + scoped_ptr<MDnsListener> listener_printer = test_client_->CreateListener( + dns_protocol::kTypePTR, "_printer._tcp.local", &delegate_printer); + + ASSERT_TRUE(listener_privet->Start()); + ASSERT_TRUE(listener_printer->Start()); + + EXPECT_CALL(delegate_privet, OnRecordUpdate(MDnsListener::RECORD_ADDED, _)) + .Times(Exactly(1)); + EXPECT_CALL(delegate_printer, OnRecordUpdate(MDnsListener::RECORD_ADDED, _)) + .Times(Exactly(1)); + + SimulatePacketReceive(kSamplePacket3, sizeof(kSamplePacket3)); + + EXPECT_CALL(delegate_privet, OnRecordUpdate(MDnsListener::RECORD_REMOVED, _)) + .Times(Exactly(1)); + + // Set the clock to 2.0s, which should clean up the 'privet' record, but not + // the printer. The mock clock will change Now() mid-execution from 2s to 4s. + // Note: expectations are FILO-ordered -- t+2 seconds is returned, then t+4. + EXPECT_CALL(*clock, Now()) + .WillOnce(Return(start_time + base::TimeDelta::FromSeconds(4))) + .RetiresOnSaturation(); + EXPECT_CALL(*clock, Now()) + .WillOnce(Return(start_time + base::TimeDelta::FromSeconds(2))) + .RetiresOnSaturation(); + + EXPECT_CALL(*timer, StartObserver(_, base::TimeDelta(), _)); + + timer->Fire(); +} + TEST_F(MDnsTest, MalformedPacket) { StrictMock<MockListenerDelegate> delegate_printer; PtrRecordCopyContainer record_printer; - scoped_ptr<MDnsListener> listener_printer = - test_client_.CreateListener(dns_protocol::kTypePTR, "_printer._tcp.local", - &delegate_printer); + scoped_ptr<MDnsListener> listener_printer = test_client_->CreateListener( + dns_protocol::kTypePTR, "_printer._tcp.local", &delegate_printer); ASSERT_TRUE(listener_printer->Start()); @@ -582,11 +711,10 @@ ExpectPacket(kQueryPacketPrivet, sizeof(kQueryPacketPrivet)); scoped_ptr<MDnsTransaction> transaction_privet = - test_client_.CreateTransaction( + test_client_->CreateTransaction( dns_protocol::kTypePTR, "_privet._tcp.local", - MDnsTransaction::QUERY_NETWORK | - MDnsTransaction::QUERY_CACHE | - MDnsTransaction::SINGLE_RESULT, + MDnsTransaction::QUERY_NETWORK | MDnsTransaction::QUERY_CACHE | + MDnsTransaction::SINGLE_RESULT, base::Bind(&MDnsTest::MockableRecordCallback, base::Unretained(this))); @@ -607,10 +735,9 @@ TEST_F(MDnsTest, TransactionCacheOnlyNoResult) { scoped_ptr<MDnsTransaction> transaction_privet = - test_client_.CreateTransaction( + test_client_->CreateTransaction( dns_protocol::kTypePTR, "_privet._tcp.local", - MDnsTransaction::QUERY_CACHE | - MDnsTransaction::SINGLE_RESULT, + MDnsTransaction::QUERY_CACHE | MDnsTransaction::SINGLE_RESULT, base::Bind(&MDnsTest::MockableRecordCallback, base::Unretained(this))); @@ -624,10 +751,8 @@ TEST_F(MDnsTest, TransactionWithCache) { // Listener to force the client to listen StrictMock<MockListenerDelegate> delegate_irrelevant; - scoped_ptr<MDnsListener> listener_irrelevant = - test_client_.CreateListener(dns_protocol::kTypeA, - "codereview.chromium.local", - &delegate_irrelevant); + scoped_ptr<MDnsListener> listener_irrelevant = test_client_->CreateListener( + dns_protocol::kTypeA, "codereview.chromium.local", &delegate_irrelevant); ASSERT_TRUE(listener_irrelevant->Start()); @@ -641,11 +766,10 @@ &PtrRecordCopyContainer::SaveWithDummyArg)); scoped_ptr<MDnsTransaction> transaction_privet = - test_client_.CreateTransaction( + test_client_->CreateTransaction( dns_protocol::kTypePTR, "_privet._tcp.local", - MDnsTransaction::QUERY_NETWORK | - MDnsTransaction::QUERY_CACHE | - MDnsTransaction::SINGLE_RESULT, + MDnsTransaction::QUERY_NETWORK | MDnsTransaction::QUERY_CACHE | + MDnsTransaction::SINGLE_RESULT, base::Bind(&MDnsTest::MockableRecordCallback, base::Unretained(this))); @@ -660,9 +784,8 @@ PtrRecordCopyContainer record_privet; - scoped_ptr<MDnsListener> listener_privet = - test_client_.CreateListener(dns_protocol::kTypePTR, "_privet._tcp.local", - &delegate_privet); + scoped_ptr<MDnsListener> listener_privet = test_client_->CreateListener( + dns_protocol::kTypePTR, "_privet._tcp.local", &delegate_privet); ASSERT_TRUE(listener_privet->Start()); @@ -683,11 +806,10 @@ ExpectPacket(kQueryPacketPrivet, sizeof(kQueryPacketPrivet)); scoped_ptr<MDnsTransaction> transaction_privet = - test_client_.CreateTransaction( + test_client_->CreateTransaction( dns_protocol::kTypePTR, "_privet._tcp.local", - MDnsTransaction::QUERY_NETWORK | - MDnsTransaction::QUERY_CACHE | - MDnsTransaction::SINGLE_RESULT, + MDnsTransaction::QUERY_NETWORK | MDnsTransaction::QUERY_CACHE | + MDnsTransaction::SINGLE_RESULT, base::Bind(&MDnsTest::MockableRecordCallback, base::Unretained(this))); @@ -705,10 +827,9 @@ ExpectPacket(kQueryPacketPrivet, sizeof(kQueryPacketPrivet)); scoped_ptr<MDnsTransaction> transaction_privet = - test_client_.CreateTransaction( + test_client_->CreateTransaction( dns_protocol::kTypePTR, "_privet._tcp.local", - MDnsTransaction::QUERY_NETWORK | - MDnsTransaction::QUERY_CACHE , + MDnsTransaction::QUERY_NETWORK | MDnsTransaction::QUERY_CACHE, base::Bind(&MDnsTest::MockableRecordCallback, base::Unretained(this))); @@ -742,13 +863,11 @@ TEST_F(MDnsTest, TransactionReentrantDelete) { ExpectPacket(kQueryPacketPrivet, sizeof(kQueryPacketPrivet)); - transaction_ = test_client_.CreateTransaction( + transaction_ = test_client_->CreateTransaction( dns_protocol::kTypePTR, "_privet._tcp.local", - MDnsTransaction::QUERY_NETWORK | - MDnsTransaction::QUERY_CACHE | - MDnsTransaction::SINGLE_RESULT, - base::Bind(&MDnsTest::MockableRecordCallback, - base::Unretained(this))); + MDnsTransaction::QUERY_NETWORK | MDnsTransaction::QUERY_CACHE | + MDnsTransaction::SINGLE_RESULT, + base::Bind(&MDnsTest::MockableRecordCallback, base::Unretained(this))); ASSERT_TRUE(transaction_->Start()); @@ -765,19 +884,16 @@ TEST_F(MDnsTest, TransactionReentrantDeleteFromCache) { StrictMock<MockListenerDelegate> delegate_irrelevant; - scoped_ptr<MDnsListener> listener_irrelevant = test_client_.CreateListener( - dns_protocol::kTypeA, "codereview.chromium.local", - &delegate_irrelevant); + scoped_ptr<MDnsListener> listener_irrelevant = test_client_->CreateListener( + dns_protocol::kTypeA, "codereview.chromium.local", &delegate_irrelevant); ASSERT_TRUE(listener_irrelevant->Start()); SimulatePacketReceive(kSamplePacket1, sizeof(kSamplePacket1)); - transaction_ = test_client_.CreateTransaction( + transaction_ = test_client_->CreateTransaction( dns_protocol::kTypePTR, "_privet._tcp.local", - MDnsTransaction::QUERY_NETWORK | - MDnsTransaction::QUERY_CACHE, - base::Bind(&MDnsTest::MockableRecordCallback, - base::Unretained(this))); + MDnsTransaction::QUERY_NETWORK | MDnsTransaction::QUERY_CACHE, + base::Bind(&MDnsTest::MockableRecordCallback, base::Unretained(this))); EXPECT_CALL(*this, MockableRecordCallback(MDnsTransaction::RESULT_RECORD, _)) .Times(Exactly(1)) @@ -791,22 +907,16 @@ TEST_F(MDnsTest, TransactionReentrantCacheLookupStart) { ExpectPacket(kQueryPacketPrivet, sizeof(kQueryPacketPrivet)); - scoped_ptr<MDnsTransaction> transaction1 = - test_client_.CreateTransaction( - dns_protocol::kTypePTR, "_privet._tcp.local", - MDnsTransaction::QUERY_NETWORK | - MDnsTransaction::QUERY_CACHE | + scoped_ptr<MDnsTransaction> transaction1 = test_client_->CreateTransaction( + dns_protocol::kTypePTR, "_privet._tcp.local", + MDnsTransaction::QUERY_NETWORK | MDnsTransaction::QUERY_CACHE | MDnsTransaction::SINGLE_RESULT, - base::Bind(&MDnsTest::MockableRecordCallback, - base::Unretained(this))); + base::Bind(&MDnsTest::MockableRecordCallback, base::Unretained(this))); - scoped_ptr<MDnsTransaction> transaction2 = - test_client_.CreateTransaction( - dns_protocol::kTypePTR, "_printer._tcp.local", - MDnsTransaction::QUERY_CACHE | - MDnsTransaction::SINGLE_RESULT, - base::Bind(&MDnsTest::MockableRecordCallback2, - base::Unretained(this))); + scoped_ptr<MDnsTransaction> transaction2 = test_client_->CreateTransaction( + dns_protocol::kTypePTR, "_printer._tcp.local", + MDnsTransaction::QUERY_CACHE | MDnsTransaction::SINGLE_RESULT, + base::Bind(&MDnsTest::MockableRecordCallback2, base::Unretained(this))); EXPECT_CALL(*this, MockableRecordCallback2(MDnsTransaction::RESULT_RECORD, _)) @@ -826,7 +936,7 @@ TEST_F(MDnsTest, GoodbyePacketNotification) { StrictMock<MockListenerDelegate> delegate_privet; - scoped_ptr<MDnsListener> listener_privet = test_client_.CreateListener( + scoped_ptr<MDnsListener> listener_privet = test_client_->CreateListener( dns_protocol::kTypePTR, "_privet._tcp.local", &delegate_privet); ASSERT_TRUE(listener_privet->Start()); @@ -838,9 +948,8 @@ TEST_F(MDnsTest, GoodbyePacketRemoval) { StrictMock<MockListenerDelegate> delegate_privet; - scoped_ptr<MDnsListener> listener_privet = - test_client_.CreateListener(dns_protocol::kTypePTR, "_privet._tcp.local", - &delegate_privet); + scoped_ptr<MDnsListener> listener_privet = test_client_->CreateListener( + dns_protocol::kTypePTR, "_privet._tcp.local", &delegate_privet); ASSERT_TRUE(listener_privet->Start()); EXPECT_CALL(delegate_privet, OnRecordUpdate(MDnsListener::RECORD_ADDED, _)) @@ -863,13 +972,11 @@ TEST_F(MDnsTest, ListenerReentrantDelete) { StrictMock<MockListenerDelegate> delegate_privet; - listener1_ = test_client_.CreateListener(dns_protocol::kTypePTR, - "_privet._tcp.local", - &delegate_privet); + listener1_ = test_client_->CreateListener( + dns_protocol::kTypePTR, "_privet._tcp.local", &delegate_privet); - listener2_ = test_client_.CreateListener(dns_protocol::kTypePTR, - "_privet._tcp.local", - &delegate_privet); + listener2_ = test_client_->CreateListener( + dns_protocol::kTypePTR, "_privet._tcp.local", &delegate_privet); ASSERT_TRUE(listener1_->Start()); @@ -896,9 +1003,8 @@ IPAddressNumber address; StrictMock<MockListenerDelegate> delegate_privet; - scoped_ptr<MDnsListener> listener_privet = - test_client_.CreateListener(dns_protocol::kTypeA, "privet.local", - &delegate_privet); + scoped_ptr<MDnsListener> listener_privet = test_client_->CreateListener( + dns_protocol::kTypeA, "privet.local", &delegate_privet); ASSERT_TRUE(listener_privet->Start()); @@ -914,16 +1020,14 @@ TEST_F(MDnsTest, NsecWithListener) { StrictMock<MockListenerDelegate> delegate_privet; - scoped_ptr<MDnsListener> listener_privet = - test_client_.CreateListener(dns_protocol::kTypeA, "_privet._tcp.local", - &delegate_privet); + scoped_ptr<MDnsListener> listener_privet = test_client_->CreateListener( + dns_protocol::kTypeA, "_privet._tcp.local", &delegate_privet); // Test to make sure nsec callback is NOT called for PTR // (which is marked as existing). StrictMock<MockListenerDelegate> delegate_privet2; - scoped_ptr<MDnsListener> listener_privet2 = - test_client_.CreateListener(dns_protocol::kTypePTR, "_privet._tcp.local", - &delegate_privet2); + scoped_ptr<MDnsListener> listener_privet2 = test_client_->CreateListener( + dns_protocol::kTypePTR, "_privet._tcp.local", &delegate_privet2); ASSERT_TRUE(listener_privet->Start()); @@ -936,11 +1040,10 @@ TEST_F(MDnsTest, NsecWithTransactionFromNetwork) { scoped_ptr<MDnsTransaction> transaction_privet = - test_client_.CreateTransaction( + test_client_->CreateTransaction( dns_protocol::kTypeA, "_privet._tcp.local", - MDnsTransaction::QUERY_NETWORK | - MDnsTransaction::QUERY_CACHE | - MDnsTransaction::SINGLE_RESULT, + MDnsTransaction::QUERY_NETWORK | MDnsTransaction::QUERY_CACHE | + MDnsTransaction::SINGLE_RESULT, base::Bind(&MDnsTest::MockableRecordCallback, base::Unretained(this))); @@ -958,9 +1061,8 @@ TEST_F(MDnsTest, NsecWithTransactionFromCache) { // Force mDNS to listen. StrictMock<MockListenerDelegate> delegate_irrelevant; - scoped_ptr<MDnsListener> listener_irrelevant = - test_client_.CreateListener(dns_protocol::kTypePTR, "_privet._tcp.local", - &delegate_irrelevant); + scoped_ptr<MDnsListener> listener_irrelevant = test_client_->CreateListener( + dns_protocol::kTypePTR, "_privet._tcp.local", &delegate_irrelevant); listener_irrelevant->Start(); SimulatePacketReceive(kSamplePacketNsec, @@ -970,11 +1072,10 @@ MockableRecordCallback(MDnsTransaction::RESULT_NSEC, NULL)); scoped_ptr<MDnsTransaction> transaction_privet_a = - test_client_.CreateTransaction( + test_client_->CreateTransaction( dns_protocol::kTypeA, "_privet._tcp.local", - MDnsTransaction::QUERY_NETWORK | - MDnsTransaction::QUERY_CACHE | - MDnsTransaction::SINGLE_RESULT, + MDnsTransaction::QUERY_NETWORK | MDnsTransaction::QUERY_CACHE | + MDnsTransaction::SINGLE_RESULT, base::Bind(&MDnsTest::MockableRecordCallback, base::Unretained(this))); @@ -984,11 +1085,10 @@ // valid answer to the query scoped_ptr<MDnsTransaction> transaction_privet_ptr = - test_client_.CreateTransaction( + test_client_->CreateTransaction( dns_protocol::kTypePTR, "_privet._tcp.local", - MDnsTransaction::QUERY_NETWORK | - MDnsTransaction::QUERY_CACHE | - MDnsTransaction::SINGLE_RESULT, + MDnsTransaction::QUERY_NETWORK | MDnsTransaction::QUERY_CACHE | + MDnsTransaction::SINGLE_RESULT, base::Bind(&MDnsTest::MockableRecordCallback, base::Unretained(this))); @@ -999,9 +1099,8 @@ TEST_F(MDnsTest, NsecConflictRemoval) { StrictMock<MockListenerDelegate> delegate_privet; - scoped_ptr<MDnsListener> listener_privet = - test_client_.CreateListener(dns_protocol::kTypeA, "_privet._tcp.local", - &delegate_privet); + scoped_ptr<MDnsListener> listener_privet = test_client_->CreateListener( + dns_protocol::kTypeA, "_privet._tcp.local", &delegate_privet); ASSERT_TRUE(listener_privet->Start()); @@ -1029,9 +1128,8 @@ TEST_F(MDnsTest, RefreshQuery) { StrictMock<MockListenerDelegate> delegate_privet; - scoped_ptr<MDnsListener> listener_privet = - test_client_.CreateListener(dns_protocol::kTypeA, "_privet._tcp.local", - &delegate_privet); + scoped_ptr<MDnsListener> listener_privet = test_client_->CreateListener( + dns_protocol::kTypeA, "_privet._tcp.local", &delegate_privet); listener_privet->SetActiveRefresh(true); ASSERT_TRUE(listener_privet->Start()); @@ -1087,7 +1185,7 @@ protected: // Follow successful connection initialization. - virtual void SetUp() override { + void SetUp() override { socket_ipv4_ = new MockMDnsDatagramServerSocket(ADDRESS_FAMILY_IPV4); socket_ipv6_ = new MockMDnsDatagramServerSocket(ADDRESS_FAMILY_IPV6); factory_.PushSocket(socket_ipv6_); @@ -1219,6 +1317,4 @@ callback.Run(OK); } -} // namespace - } // namespace net
diff --git a/net/proxy/proxy_script_decider.cc b/net/proxy/proxy_script_decider.cc index 7e5544a..3d830fc 100644 --- a/net/proxy/proxy_script_decider.cc +++ b/net/proxy/proxy_script_decider.cc
@@ -476,7 +476,6 @@ proxy_script_fetcher_->Cancel(); break; default: - NOTREACHED(); break; }
diff --git a/net/proxy/proxy_script_decider_unittest.cc b/net/proxy/proxy_script_decider_unittest.cc index 8914f5b..f26e5e1 100644 --- a/net/proxy/proxy_script_decider_unittest.cc +++ b/net/proxy/proxy_script_decider_unittest.cc
@@ -428,6 +428,16 @@ EXPECT_EQ(rule.url, decider_->effective_config().pac_url()); } +// Regression test for http://crbug.com/409698. +// This test lets the state machine get into state QUICK_CHECK_COMPLETE, then +// destroys the decider, causing a cancel. +TEST_F(ProxyScriptDeciderQuickCheckTest, CancelPartway) { + resolver_.set_synchronous_mode(false); + resolver_.set_ondemand_mode(true); + EXPECT_EQ(ERR_IO_PENDING, StartDecider()); + decider_.reset(NULL); +} + // Fails at WPAD (downloading), but succeeds in choosing the custom PAC. TEST(ProxyScriptDeciderTest, AutodetectFailCustomSuccess1) { Rules rules;
diff --git a/pdf/pdfium/pdfium_engine.cc b/pdf/pdfium/pdfium_engine.cc index b179e1e..8f48768 100644 --- a/pdf/pdfium/pdfium_engine.cc +++ b/pdf/pdfium/pdfium_engine.cc
@@ -1614,25 +1614,27 @@ FORM_DoDocumentAAction(form_, FPDFDOC_AACTION_DP); } -PDFiumPage::Area PDFiumEngine::GetCharIndex( - const pp::MouseInputEvent& event, int* page_index, - int* char_index, PDFiumPage::LinkTarget* target) { +PDFiumPage::Area PDFiumEngine::GetCharIndex(const pp::MouseInputEvent& event, + int* page_index, + int* char_index, + int* form_type, + PDFiumPage::LinkTarget* target) { // First figure out which page this is in. pp::Point mouse_point = event.GetPosition(); - pp::Point point( - static_cast<int>((mouse_point.x() + position_.x()) / current_zoom_), - static_cast<int>((mouse_point.y() + position_.y()) / current_zoom_)); - return GetCharIndex(point, page_index, char_index, target); + return GetCharIndex(mouse_point, page_index, char_index, form_type, target); } -PDFiumPage::Area PDFiumEngine::GetCharIndex( - const pp::Point& point, - int* page_index, - int* char_index, - PDFiumPage::LinkTarget* target) { +PDFiumPage::Area PDFiumEngine::GetCharIndex(const pp::Point& point, + int* page_index, + int* char_index, + int* form_type, + PDFiumPage::LinkTarget* target) { int page = -1; + pp::Point point_in_page( + static_cast<int>((point.x() + position_.x()) / current_zoom_), + static_cast<int>((point.y() + position_.y()) / current_zoom_)); for (size_t i = 0; i < visible_pages_.size(); ++i) { - if (pages_[visible_pages_[i]]->rect().Contains(point)) { + if (pages_[visible_pages_[i]]->rect().Contains(point_in_page)) { page = visible_pages_[i]; break; } @@ -1648,15 +1650,11 @@ } *page_index = page; - return pages_[page]->GetCharIndex(point, current_rotation_, char_index, - target); + return pages_[page]->GetCharIndex( + point_in_page, current_rotation_, char_index, form_type, target); } bool PDFiumEngine::OnMouseDown(const pp::MouseInputEvent& event) { - if (event.GetButton() != PP_INPUTEVENT_MOUSEBUTTON_LEFT && - event.GetButton() != PP_INPUTEVENT_MOUSEBUTTON_RIGHT) { - return false; - } if (event.GetButton() == PP_INPUTEVENT_MOUSEBUTTON_RIGHT) { if (!selection_.size()) return false; @@ -1672,15 +1670,18 @@ selection_.clear(); return true; } + if (event.GetButton() != PP_INPUTEVENT_MOUSEBUTTON_LEFT) + return false; SelectionChangeInvalidator selection_invalidator(this); selection_.clear(); int page_index = -1; int char_index = -1; + int form_type = FPDF_FORMFIELD_UNKNOWN; PDFiumPage::LinkTarget target; - PDFiumPage::Area area = GetCharIndex(event, &page_index, - &char_index, &target); + PDFiumPage::Area area = + GetCharIndex(event, &page_index, &char_index, &form_type, &target); mouse_down_state_.Set(area, target); // Decide whether to open link or not based on user action in mouse up and @@ -1701,16 +1702,14 @@ DeviceToPage(page_index, point.x(), point.y(), &page_x, &page_y); FORM_OnLButtonDown(form_, pages_[page_index]->GetPage(), 0, page_x, page_y); - int control = FPDPage_HasFormFieldAtPoint( - form_, pages_[page_index]->GetPage(), page_x, page_y); - if (control > FPDF_FORMFIELD_UNKNOWN) { // returns -1 sometimes... + if (form_type > FPDF_FORMFIELD_UNKNOWN) { // returns -1 sometimes... + mouse_down_state_.Set(PDFiumPage::NONSELECTABLE_AREA, target); + bool is_valid_control = (form_type == FPDF_FORMFIELD_TEXTFIELD || + form_type == FPDF_FORMFIELD_COMBOBOX); #ifdef PDF_USE_XFA - client_->FormTextFieldFocusChange(control == FPDF_FORMFIELD_TEXTFIELD || - control == FPDF_FORMFIELD_COMBOBOX || control == FPDF_FORMFIELD_XFA); -#else - client_->FormTextFieldFocusChange(control == FPDF_FORMFIELD_TEXTFIELD || - control == FPDF_FORMFIELD_COMBOBOX); + is_valid_control |= (form_type == FPDF_FORMFIELD_XFA); #endif + client_->FormTextFieldFocusChange(is_valid_control); return true; // Return now before we get into the selection code. } } @@ -1769,9 +1768,10 @@ int page_index = -1; int char_index = -1; + int form_type = FPDF_FORMFIELD_UNKNOWN; PDFiumPage::LinkTarget target; PDFiumPage::Area area = - GetCharIndex(event, &page_index, &char_index, &target); + GetCharIndex(event, &page_index, &char_index, &form_type, &target); // Open link on mouse up for same link for which mouse down happened earlier. if (mouse_down_state_.Matches(area, target)) { @@ -1801,9 +1801,10 @@ bool PDFiumEngine::OnMouseMove(const pp::MouseInputEvent& event) { int page_index = -1; int char_index = -1; + int form_type = FPDF_FORMFIELD_UNKNOWN; PDFiumPage::LinkTarget target; PDFiumPage::Area area = - GetCharIndex(event, &page_index, &char_index, &target); + GetCharIndex(event, &page_index, &char_index, &form_type, &target); // Clear |mouse_down_state_| if mouse moves away from where the mouse down // happened. @@ -1822,7 +1823,21 @@ break; case PDFiumPage::NONSELECTABLE_AREA: default: - cursor = PP_CURSORTYPE_POINTER; + switch (form_type) { + case FPDF_FORMFIELD_PUSHBUTTON: + case FPDF_FORMFIELD_CHECKBOX: + case FPDF_FORMFIELD_RADIOBUTTON: + case FPDF_FORMFIELD_COMBOBOX: + case FPDF_FORMFIELD_LISTBOX: + cursor = PP_CURSORTYPE_HAND; + break; + case FPDF_FORMFIELD_TEXTFIELD: + cursor = PP_CURSORTYPE_IBEAM; + break; + default: + cursor = PP_CURSORTYPE_POINTER; + break; + } break; } @@ -1830,24 +1845,7 @@ double page_x, page_y; pp::Point point = event.GetPosition(); DeviceToPage(page_index, point.x(), point.y(), &page_x, &page_y); - FORM_OnMouseMove(form_, pages_[page_index]->GetPage(), 0, page_x, page_y); - int control = FPDPage_HasFormFieldAtPoint( - form_, pages_[page_index]->GetPage(), page_x, page_y); - switch (control) { - case FPDF_FORMFIELD_PUSHBUTTON: - case FPDF_FORMFIELD_CHECKBOX: - case FPDF_FORMFIELD_RADIOBUTTON: - case FPDF_FORMFIELD_COMBOBOX: - case FPDF_FORMFIELD_LISTBOX: - cursor = PP_CURSORTYPE_HAND; - break; - case FPDF_FORMFIELD_TEXTFIELD: - cursor = PP_CURSORTYPE_IBEAM; - break; - default: - break; - } } client_->UpdateCursor(cursor); @@ -2321,15 +2319,16 @@ } std::string PDFiumEngine::GetLinkAtPosition(const pp::Point& point) { + std::string url; int temp; + int page_index = -1; + int form_type = FPDF_FORMFIELD_UNKNOWN; PDFiumPage::LinkTarget target; - pp::Point point_in_page( - static_cast<int>((point.x() + position_.x()) / current_zoom_), - static_cast<int>((point.y() + position_.y()) / current_zoom_)); - PDFiumPage::Area area = GetCharIndex(point_in_page, &temp, &temp, &target); + PDFiumPage::Area area = + GetCharIndex(point, &page_index, &temp, &form_type, &target); if (area == PDFiumPage::WEBLINK_AREA) - return target.url; - return std::string(); + url = target.url; + return url; } bool PDFiumEngine::IsSelecting() {
diff --git a/pdf/pdfium/pdfium_engine.h b/pdf/pdfium/pdfium_engine.h index 44ed9ae..ac05303 100644 --- a/pdf/pdfium/pdfium_engine.h +++ b/pdf/pdfium/pdfium_engine.h
@@ -310,10 +310,12 @@ PDFiumPage::Area GetCharIndex(const pp::MouseInputEvent& event, int* page_index, int* char_index, + int* form_type, PDFiumPage::LinkTarget* target); PDFiumPage::Area GetCharIndex(const pp::Point& point, int* page_index, int* char_index, + int* form_type, PDFiumPage::LinkTarget* target); void OnSingleClick(int page_index, int char_index);
diff --git a/pdf/pdfium/pdfium_page.cc b/pdf/pdfium/pdfium_page.cc index 1335f07..e514af33 100644 --- a/pdf/pdfium/pdfium_page.cc +++ b/pdf/pdfium/pdfium_page.cc
@@ -258,6 +258,7 @@ PDFiumPage::Area PDFiumPage::GetCharIndex(const pp::Point& point, int rotation, int* char_index, + int* form_type, LinkTarget* target) { if (!available_) return NONSELECTABLE_AREA; @@ -270,6 +271,13 @@ GetTextPage(), new_x, new_y, kTolerance, kTolerance); *char_index = rv; + int control = + FPDPage_HasFormFieldAtPoint(engine_->form(), GetPage(), new_x, new_y); + if (control > FPDF_FORMFIELD_UNKNOWN) { + *form_type = control; + return PDFiumPage::NONSELECTABLE_AREA; + } + FPDF_LINK link = FPDFLink_GetLinkAtPoint(GetPage(), new_x, new_y); if (link) { // We don't handle all possible link types of the PDF. For example,
diff --git a/pdf/pdfium/pdfium_page.h b/pdf/pdfium/pdfium_page.h index de4317e..d4174f54 100644 --- a/pdf/pdfium/pdfium_page.h +++ b/pdf/pdfium/pdfium_page.h
@@ -64,7 +64,7 @@ // Target is optional. It will be filled in for WEBLINK_AREA or // DOCLINK_AREA only. Area GetCharIndex(const pp::Point& point, int rotation, int* char_index, - LinkTarget* target); + int* form_type, LinkTarget* target); // Gets the character at the given index. base::char16 GetCharAtIndex(int index);
diff --git a/ppapi/examples/BUILD.gn b/ppapi/examples/BUILD.gn index fedb176..9369c585 100644 --- a/ppapi/examples/BUILD.gn +++ b/ppapi/examples/BUILD.gn
@@ -32,5 +32,6 @@ "//ppapi/examples/video_capture", "//ppapi/examples/video_decode", "//ppapi/examples/video_effects", + "//ppapi/examples/video_encode", ] }
diff --git a/ppapi/examples/video_encode/BUILD.gn b/ppapi/examples/video_encode/BUILD.gn new file mode 100644 index 0000000..eaa3586f --- /dev/null +++ b/ppapi/examples/video_encode/BUILD.gn
@@ -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. + +import("//ppapi/examples/ppapi_example.gni") + +ppapi_example("video_encode") { + output_name = "ppapi_example_video_encode" + sources = [ + "video_encode.cc", + ] + deps = [ + "//ppapi/cpp", + ] +}
diff --git a/ppapi/examples/video_encode/video_encode.cc b/ppapi/examples/video_encode/video_encode.cc new file mode 100644 index 0000000..26c66df --- /dev/null +++ b/ppapi/examples/video_encode/video_encode.cc
@@ -0,0 +1,502 @@ +// 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 <math.h> +#include <stdio.h> +#include <string.h> + +#include <iostream> +#include <sstream> +#include <vector> + +#include "ppapi/c/pp_errors.h" +#include "ppapi/c/ppb_console.h" +#include "ppapi/cpp/input_event.h" +#include "ppapi/cpp/instance.h" +#include "ppapi/cpp/media_stream_video_track.h" +#include "ppapi/cpp/module.h" +#include "ppapi/cpp/rect.h" +#include "ppapi/cpp/var.h" +#include "ppapi/cpp/var_array_buffer.h" +#include "ppapi/cpp/var_dictionary.h" +#include "ppapi/cpp/video_encoder.h" +#include "ppapi/cpp/video_frame.h" +#include "ppapi/utility/completion_callback_factory.h" + +// TODO(llandwerlin): turn on by default when we have software encode. +// #define USE_VP8_INSTEAD_OF_H264 + +// When compiling natively on Windows, PostMessage can be #define-d to +// something else. +#ifdef PostMessage +#undef PostMessage +#endif + +// Use assert as a poor-man's CHECK, even in non-debug mode. +// Since <assert.h> redefines assert on every inclusion (it doesn't use +// include-guards), make sure this is the last file #include'd in this file. +#undef NDEBUG +#include <assert.h> + +namespace { + +std::string VideoProfileToString(PP_VideoProfile profile) { + switch (profile) { + case PP_VIDEOPROFILE_H264BASELINE: + return "h264baseline"; + case PP_VIDEOPROFILE_H264MAIN: + return "h264main"; + case PP_VIDEOPROFILE_H264EXTENDED: + return "h264extended"; + case PP_VIDEOPROFILE_H264HIGH: + return "h264high"; + case PP_VIDEOPROFILE_H264HIGH10PROFILE: + return "h264high10"; + case PP_VIDEOPROFILE_H264HIGH422PROFILE: + return "h264high422"; + case PP_VIDEOPROFILE_H264HIGH444PREDICTIVEPROFILE: + return "h264high444predictive"; + case PP_VIDEOPROFILE_H264SCALABLEBASELINE: + return "h264scalablebaseline"; + case PP_VIDEOPROFILE_H264SCALABLEHIGH: + return "h264scalablehigh"; + case PP_VIDEOPROFILE_H264STEREOHIGH: + return "h264stereohigh"; + case PP_VIDEOPROFILE_H264MULTIVIEWHIGH: + return "h264multiviewhigh"; + case PP_VIDEOPROFILE_VP8_ANY: + return "vp8"; + case PP_VIDEOPROFILE_VP9_ANY: + return "vp9"; + // No default to catch unhandled profiles. + } + return "unknown"; +} + +std::string HardwareAccelerationToString(PP_HardwareAcceleration acceleration) { + switch (acceleration) { + case PP_HARDWAREACCELERATION_ONLY: + return "hardware"; + case PP_HARDWAREACCELERATION_WITHFALLBACK: + return "hardware/software"; + case PP_HARDWAREACCELERATION_NONE: + return "software"; + // No default to catch unhandled accelerations. + } + return "unknown"; +} + +// This object is the global object representing this plugin library as long +// as it is loaded. +class VideoEncoderModule : public pp::Module { + public: + VideoEncoderModule() : pp::Module() {} + virtual ~VideoEncoderModule() {} + + virtual pp::Instance* CreateInstance(PP_Instance instance); +}; + +class VideoEncoderInstance : public pp::Instance { + public: + VideoEncoderInstance(PP_Instance instance, pp::Module* module); + virtual ~VideoEncoderInstance(); + + // pp::Instance implementation. + virtual void HandleMessage(const pp::Var& var_message); + + private: + void ConfigureTrack(); + void OnConfiguredTrack(int32_t result); + void ProbeEncoder(); + void OnEncoderProbed(int32_t result, + const std::vector<PP_VideoProfileDescription> profiles); + void OnInitializedEncoder(int32_t result); + void ScheduleNextEncode(); + void GetEncoderFrameTick(int32_t result); + void GetEncoderFrame(const pp::VideoFrame& track_frame); + void OnEncoderFrame(int32_t result, + pp::VideoFrame encoder_frame, + pp::VideoFrame track_frame); + int32_t CopyVideoFrame(pp::VideoFrame dest, pp::VideoFrame src); + void EncodeFrame(const pp::VideoFrame& frame); + void OnEncodeDone(int32_t result); + void OnGetBitstreamBuffer(int32_t result, PP_BitstreamBuffer buffer); + void StartTrackFrames(); + void StopTrackFrames(); + void OnTrackFrame(int32_t result, pp::VideoFrame frame); + + void StopEncode(); + + void LogError(int32_t error, const std::string& message); + void Log(const std::string& message); + + void PostDataMessage(const void* buffer, uint32_t size); + void PostSignalMessage(const char* name); + + bool is_encoding_; + bool is_receiving_track_frames_; + + pp::VideoEncoder video_encoder_; + pp::MediaStreamVideoTrack video_track_; + pp::CompletionCallbackFactory<VideoEncoderInstance> callback_factory_; + + PP_VideoProfile video_profile_; + PP_VideoFrame_Format frame_format_; + + pp::Size requested_size_; + pp::Size frame_size_; + pp::Size encoder_size_; + uint32_t encoded_frames_; + + pp::VideoFrame current_track_frame_; +}; + +VideoEncoderInstance::VideoEncoderInstance(PP_Instance instance, + pp::Module* module) + : pp::Instance(instance), + is_encoding_(false), + callback_factory_(this), +#if defined(USE_VP8_INSTEAD_OF_H264) + video_profile_(PP_VIDEOPROFILE_VP8_ANY), +#else + video_profile_(PP_VIDEOPROFILE_H264MAIN), +#endif + frame_format_(PP_VIDEOFRAME_FORMAT_I420), + encoded_frames_(0) { +} + +VideoEncoderInstance::~VideoEncoderInstance() { +} + +void VideoEncoderInstance::ConfigureTrack() { + if (encoder_size_.IsEmpty()) + frame_size_ = requested_size_; + else + frame_size_ = encoder_size_; + + int32_t attrib_list[] = {PP_MEDIASTREAMVIDEOTRACK_ATTRIB_FORMAT, + frame_format_, + PP_MEDIASTREAMVIDEOTRACK_ATTRIB_WIDTH, + frame_size_.width(), + PP_MEDIASTREAMVIDEOTRACK_ATTRIB_HEIGHT, + frame_size_.height(), + PP_MEDIASTREAMVIDEOTRACK_ATTRIB_NONE}; + + pp::VarDictionary dict; + dict.Set(pp::Var("status"), pp::Var("configuring video track")); + dict.Set(pp::Var("width"), pp::Var(frame_size_.width())); + dict.Set(pp::Var("height"), pp::Var(frame_size_.height())); + PostMessage(dict); + + video_track_.Configure( + attrib_list, + callback_factory_.NewCallback(&VideoEncoderInstance::OnConfiguredTrack)); +} + +void VideoEncoderInstance::OnConfiguredTrack(int32_t result) { + if (result != PP_OK) { + LogError(result, "Cannot configure track"); + return; + } + + if (is_encoding_) { + StartTrackFrames(); + ScheduleNextEncode(); + } else + ProbeEncoder(); +} + +void VideoEncoderInstance::ProbeEncoder() { + video_encoder_ = pp::VideoEncoder(this); + video_encoder_.GetSupportedProfiles(callback_factory_.NewCallbackWithOutput( + &VideoEncoderInstance::OnEncoderProbed)); +} + +void VideoEncoderInstance::OnEncoderProbed( + int32_t result, + const std::vector<PP_VideoProfileDescription> profiles) { + bool has_required_profile = false; + + Log("Available profiles:"); + for (const PP_VideoProfileDescription& profile : profiles) { + std::ostringstream oss; + oss << " profile=" << VideoProfileToString(profile.profile) + << " max_resolution=" << profile.max_resolution.width << "x" + << profile.max_resolution.height + << " max_framerate=" << profile.max_framerate_numerator << "/" + << profile.max_framerate_denominator << " acceleration=" + << HardwareAccelerationToString(profile.acceleration); + Log(oss.str()); + + has_required_profile |= profile.profile == video_profile_; + } + + if (!has_required_profile) { + std::ostringstream oss; + oss << "Cannot find required video profile: "; + oss << VideoProfileToString(video_profile_); + LogError(PP_ERROR_FAILED, oss.str()); + return; + } + + video_encoder_ = pp::VideoEncoder(this); + + pp::VarDictionary dict; + dict.Set(pp::Var("status"), pp::Var("initializing encoder")); + dict.Set(pp::Var("width"), pp::Var(encoder_size_.width())); + dict.Set(pp::Var("height"), pp::Var(encoder_size_.height())); + PostMessage(dict); + + int32_t error = video_encoder_.Initialize( + frame_format_, frame_size_, video_profile_, 2000000, + PP_HARDWAREACCELERATION_WITHFALLBACK, + callback_factory_.NewCallback( + &VideoEncoderInstance::OnInitializedEncoder)); + if (error != PP_OK_COMPLETIONPENDING) { + LogError(error, "Cannot initialize encoder"); + return; + } +} + +void VideoEncoderInstance::OnInitializedEncoder(int32_t result) { + if (result != PP_OK) { + LogError(result, "Encoder initialization failed"); + return; + } + + is_encoding_ = true; + + if (video_encoder_.GetFrameCodedSize(&encoder_size_) != PP_OK) { + LogError(result, "Cannot get encoder coded frame size"); + return; + } + + pp::VarDictionary dict; + dict.Set(pp::Var("status"), pp::Var("encoder initialized")); + dict.Set(pp::Var("width"), pp::Var(encoder_size_.width())); + dict.Set(pp::Var("height"), pp::Var(encoder_size_.height())); + PostMessage(dict); + + video_encoder_.GetBitstreamBuffer(callback_factory_.NewCallbackWithOutput( + &VideoEncoderInstance::OnGetBitstreamBuffer)); + + if (encoder_size_ != frame_size_) + ConfigureTrack(); + else { + StartTrackFrames(); + ScheduleNextEncode(); + } +} + +void VideoEncoderInstance::ScheduleNextEncode() { + pp::Module::Get()->core()->CallOnMainThread( + 1000 / 30, + callback_factory_.NewCallback(&VideoEncoderInstance::GetEncoderFrameTick), + 0); +} + +void VideoEncoderInstance::GetEncoderFrameTick(int32_t result) { + if (is_encoding_) { + if (!current_track_frame_.is_null()) { + pp::VideoFrame frame = current_track_frame_; + current_track_frame_.detach(); + GetEncoderFrame(frame); + } + ScheduleNextEncode(); + } +} + +void VideoEncoderInstance::GetEncoderFrame(const pp::VideoFrame& track_frame) { + video_encoder_.GetVideoFrame(callback_factory_.NewCallbackWithOutput( + &VideoEncoderInstance::OnEncoderFrame, track_frame)); +} + +void VideoEncoderInstance::OnEncoderFrame(int32_t result, + pp::VideoFrame encoder_frame, + pp::VideoFrame track_frame) { + if (result == PP_ERROR_ABORTED) { + video_track_.RecycleFrame(track_frame); + return; + } + if (result != PP_OK) { + video_track_.RecycleFrame(track_frame); + LogError(result, "Cannot get video frame from video encoder"); + return; + } + + track_frame.GetSize(&frame_size_); + + if (frame_size_ != encoder_size_) { + video_track_.RecycleFrame(track_frame); + LogError(PP_ERROR_FAILED, "MediaStreamVideoTrack frame size incorrect"); + return; + } + + if (CopyVideoFrame(encoder_frame, track_frame) == PP_OK) + EncodeFrame(encoder_frame); + video_track_.RecycleFrame(track_frame); +} + +int32_t VideoEncoderInstance::CopyVideoFrame(pp::VideoFrame dest, + pp::VideoFrame src) { + if (dest.GetDataBufferSize() < src.GetDataBufferSize()) { + std::ostringstream oss; + oss << "Incorrect destination video frame buffer size : " + << dest.GetDataBufferSize() << " < " << src.GetDataBufferSize(); + LogError(PP_ERROR_FAILED, oss.str()); + return PP_ERROR_FAILED; + } + + memcpy(dest.GetDataBuffer(), src.GetDataBuffer(), src.GetDataBufferSize()); + return PP_OK; +} + +void VideoEncoderInstance::EncodeFrame(const pp::VideoFrame& frame) { + video_encoder_.Encode( + frame, PP_FALSE, + callback_factory_.NewCallback(&VideoEncoderInstance::OnEncodeDone)); +} + +void VideoEncoderInstance::OnEncodeDone(int32_t result) { + if (result == PP_ERROR_ABORTED) + return; + if (result != PP_OK) + LogError(result, "Encode failed"); +} + +void VideoEncoderInstance::OnGetBitstreamBuffer(int32_t result, + PP_BitstreamBuffer buffer) { + if (result == PP_ERROR_ABORTED) + return; + if (result != PP_OK) { + LogError(result, "Cannot get bitstream buffer"); + return; + } + + encoded_frames_++; + PostDataMessage(buffer.buffer, buffer.size); + video_encoder_.RecycleBitstreamBuffer(buffer); + + video_encoder_.GetBitstreamBuffer(callback_factory_.NewCallbackWithOutput( + &VideoEncoderInstance::OnGetBitstreamBuffer)); +} + +void VideoEncoderInstance::StartTrackFrames() { + is_receiving_track_frames_ = true; + video_track_.GetFrame(callback_factory_.NewCallbackWithOutput( + &VideoEncoderInstance::OnTrackFrame)); +} + +void VideoEncoderInstance::StopTrackFrames() { + is_receiving_track_frames_ = false; + if (!current_track_frame_.is_null()) { + video_track_.RecycleFrame(current_track_frame_); + current_track_frame_.detach(); + } +} + +void VideoEncoderInstance::OnTrackFrame(int32_t result, pp::VideoFrame frame) { + if (result == PP_ERROR_ABORTED) + return; + + if (!current_track_frame_.is_null()) { + video_track_.RecycleFrame(current_track_frame_); + current_track_frame_.detach(); + } + + if (result != PP_OK) { + LogError(result, "Cannot get video frame from video track"); + return; + } + + current_track_frame_ = frame; + if (is_receiving_track_frames_) + video_track_.GetFrame(callback_factory_.NewCallbackWithOutput( + &VideoEncoderInstance::OnTrackFrame)); +} + +void VideoEncoderInstance::StopEncode() { + video_encoder_.Close(); + StopTrackFrames(); + video_track_.Close(); + is_encoding_ = false; + encoded_frames_ = 0; +} + +// + +void VideoEncoderInstance::HandleMessage(const pp::Var& var_message) { + if (!var_message.is_dictionary()) { + LogToConsole(PP_LOGLEVEL_ERROR, pp::Var("Invalid message!")); + return; + } + + pp::VarDictionary dict_message(var_message); + std::string command = dict_message.Get("command").AsString(); + + if (command == "start") { + requested_size_ = pp::Size(dict_message.Get("width").AsInt(), + dict_message.Get("height").AsInt()); + pp::Var var_track = dict_message.Get("track"); + if (!var_track.is_resource()) { + LogToConsole(PP_LOGLEVEL_ERROR, pp::Var("Given track is not a resource")); + return; + } + pp::Resource resource_track = var_track.AsResource(); + video_track_ = pp::MediaStreamVideoTrack(resource_track); + video_encoder_ = pp::VideoEncoder(); + ConfigureTrack(); + } else if (command == "stop") { + StopEncode(); + PostSignalMessage("stopped"); + } else { + LogToConsole(PP_LOGLEVEL_ERROR, pp::Var("Invalid command!")); + } +} + +void VideoEncoderInstance::PostDataMessage(const void* buffer, uint32_t size) { + pp::VarDictionary dictionary; + + dictionary.Set(pp::Var("name"), pp::Var("data")); + + pp::VarArrayBuffer array_buffer(size); + void* data_ptr = array_buffer.Map(); + memcpy(data_ptr, buffer, size); + array_buffer.Unmap(); + dictionary.Set(pp::Var("data"), array_buffer); + + PostMessage(dictionary); +} + +void VideoEncoderInstance::PostSignalMessage(const char* name) { + pp::VarDictionary dictionary; + dictionary.Set(pp::Var("name"), pp::Var(name)); + + PostMessage(dictionary); +} + +void VideoEncoderInstance::LogError(int32_t error, const std::string& message) { + std::string msg("Error: "); + msg.append(pp::Var(error).DebugString()); + msg.append(" : "); + msg.append(message); + LogToConsole(PP_LOGLEVEL_ERROR, pp::Var(msg)); +} + +void VideoEncoderInstance::Log(const std::string& message) { + LogToConsole(PP_LOGLEVEL_LOG, pp::Var(message)); +} + +pp::Instance* VideoEncoderModule::CreateInstance(PP_Instance instance) { + return new VideoEncoderInstance(instance, this); +} + +} // anonymous namespace + +namespace pp { +// Factory function for your specialization of the Module object. +Module* CreateModule() { + return new VideoEncoderModule(); +} +} // namespace pp
diff --git a/ppapi/examples/video_encode/video_encode.html b/ppapi/examples/video_encode/video_encode.html new file mode 100644 index 0000000..803c1f4 --- /dev/null +++ b/ppapi/examples/video_encode/video_encode.html
@@ -0,0 +1,127 @@ +<!DOCTYPE html> +<html> + <!-- + 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. + --> +<head> + <title>Video Encoder Example</title> + <style type="text/css"> + #video { + position: fixed; + } + #video-playback { + position: fixed; + left: 640px; + } + #plugin { + position: fixed; + } + </style> + <script type="text/javascript"> + var plugin; + var track; + var video; + + function $(id) { + return document.getElementById(id); + } + + function success(stream) { + track = stream.getVideoTracks()[0]; + video.src = URL.createObjectURL(stream); + video.play(); + + plugin.postMessage({ + command: 'start', + track: track, + width: 640, + height: 480 + }); + } + + function failure(e) { + console.log("Error: ", e); + } + + function startRecord() { + console.log("starting record"); + navigator.webkitGetUserMedia({audio: false, video: true}, + success, failure); + } + + function stopRecord() { + plugin.postMessage({ + command: "stop" + }); + var video = $('video'); + video.pause(); + track.stop(); + } + + function saveBlob(blob) { + var blobUrl = URL.createObjectURL(blob); + window.location = blobUrl; + } + + function handleMessage(msg) { + if (msg.data.name == 'started') { + console.log('recording!'); + } else if (msg.data.name == 'data') { + appendData(msg.data.data); + } else if (msg.data.name == 'stopped') { + console.log('done recording! bytes: ' + dataArray.byteLength); + } + } + + function resetData() { + window.dataArray = new ArrayBuffer(0); + } + + function appendData(data) { + var tmp = new Uint8Array(dataArray.byteLength + data.byteLength); + tmp.set(new Uint8Array(dataArray), 0 ); + tmp.set(new Uint8Array(data), dataArray.byteLength); + dataArray = tmp.buffer; + $('length').innerHTML = ' Size: ' + dataArray.byteLength + ' bytes'; + } + + function initialize() { + plugin = $('plugin'); + plugin.addEventListener('message', handleMessage, false); + + video = $('video'); + + $('start').addEventListener('click', function (e) { + resetData(); + startRecord(); + }); + $('stop').addEventListener('click', function (e) { + stopRecord(); + }); + $('download').addEventListener('click', function (e) { + saveBlob(new Blob([dataArray], { type: "application/octet-stream" })); + }); + } + + document.addEventListener('DOMContentLoaded', initialize, false); + </script> +</head> + +<body> + <h1>Video Encoder API Example</h1><br> + This example demonstrates receiving frames from a video MediaStreamTrack and + encoding them in a plugin. + <br> + <input type="button" id="start" value="Start Recording"/> + <input type="button" id="stop" value="Stop Recording"/> + <input type="button" id="download" value="Download Recording"/> + <div id="length"></div> + <br> + <div> + <embed id="plugin" type="application/x-ppapi-example-video-encode"/> + <video id="video" width="640" height="480"/> + </div> +</body> +</html>
diff --git a/ppapi/ppapi_tests.gypi b/ppapi/ppapi_tests.gypi index 562903d..3267e0b 100644 --- a/ppapi/ppapi_tests.gypi +++ b/ppapi/ppapi_tests.gypi
@@ -498,6 +498,16 @@ ], }, { + 'target_name': 'ppapi_example_video_encode', + 'dependencies': [ + 'ppapi_example_skeleton', + 'ppapi.gyp:ppapi_cpp', + ], + 'sources': [ + 'examples/video_encode/video_encode.cc', + ], + }, + { # GN version: //ppapi/example/video_capture 'target_name': 'ppapi_example_vc', 'dependencies': [
diff --git a/remoting/app_remoting_webapp.gyp b/remoting/app_remoting_webapp.gyp index de11d0f..e179f1e78 100644 --- a/remoting/app_remoting_webapp.gyp +++ b/remoting/app_remoting_webapp.gyp
@@ -62,6 +62,29 @@ '<@(remoting_webapp_js_proto_files)', ], }, + { + 'action_name': 'Verify >(ar_app_name) feedback_consent.html', + 'variables': { + 'success_stamp': '<(PRODUCT_DIR)/>(_target_name)_feedback_consent_jscompile.stamp', + }, + 'inputs': [ + '<@(ar_feedback_consent_js_files)', + '<@(remoting_webapp_js_proto_files)', + # Include zip as input so that this action is run after the build. + '<(zip_path)', + ], + 'outputs': [ + '<(success_stamp)', + ], + 'action': [ + 'python', '../third_party/closure_compiler/checker.py', + '--strict', + '--no-single-file', + '--success-stamp', '<(success_stamp)', + '<@(ar_feedback_consent_js_files)', + '<@(remoting_webapp_js_proto_files)', + ], + }, ], # actions }], ], # conditions
diff --git a/remoting/app_remoting_webapp_build.gypi b/remoting/app_remoting_webapp_build.gypi index 9e739f7..cdd5ecf5 100644 --- a/remoting/app_remoting_webapp_build.gypi +++ b/remoting/app_remoting_webapp_build.gypi
@@ -6,15 +6,12 @@ 'includes': [ 'remoting_version.gypi', 'remoting_locales.gypi', + 'remoting_options.gypi', 'remoting_webapp_files.gypi', 'app_remoting_webapp_files.gypi', ], 'variables': { - 'chromium_code': 1, - - 'run_jscompile%': 0, - # The ar_service_environment variable is used to define the target # environment for the app being built. # The allowed values are dev, test, staging, and prod. @@ -58,6 +55,7 @@ 'ar_generated_html_files': [ '<(SHARED_INTERMEDIATE_DIR)/>(_target_name)/main.html', '<(SHARED_INTERMEDIATE_DIR)/>(_target_name)/wcs_sandbox.html', + '<(SHARED_INTERMEDIATE_DIR)/>(_target_name)/feedback_consent.html', ], 'ar_webapp_files': [ '<@(ar_app_specific_files)', @@ -189,6 +187,28 @@ '<@(remoting_webapp_wcs_sandbox_html_js_files)', ], }, + { + 'action_name': 'Build ">(ar_app_name)" feedback_consent.html', + 'inputs': [ + '<(DEPTH)/remoting/webapp/build-html.py', + '<(ar_feedback_consent_template)', + '<@(ar_feedback_consent_template_files)', + ], + 'outputs': [ + '<(SHARED_INTERMEDIATE_DIR)/>(_target_name)/feedback_consent.html', + ], + 'action': [ + 'python', '<(DEPTH)/remoting/webapp/build-html.py', + '<(SHARED_INTERMEDIATE_DIR)/>(_target_name)/feedback_consent.html', + '<(ar_feedback_consent_template)', + '--template-dir', + '<(DEPTH)/remoting', + '--templates', + '<@(ar_feedback_consent_template_files)', + '--js', + '<@(ar_feedback_consent_js_files)', + ], + }, ], # actions 'conditions': [ ['buildtype == "Dev"', {
diff --git a/remoting/app_remoting_webapp_files.gypi b/remoting/app_remoting_webapp_files.gypi index cd9bf8c..5df8b8e 100644 --- a/remoting/app_remoting_webapp_files.gypi +++ b/remoting/app_remoting_webapp_files.gypi
@@ -6,13 +6,29 @@ 'variables': { 'ar_shared_resource_files': [ 'webapp/app_remoting/html/ar_dialog.css', + 'webapp/app_remoting/html/ar_main.css', 'webapp/app_remoting/html/feedback_consent.css', - 'webapp/app_remoting/html/feedback_consent.html', 'webapp/app_remoting/html/context_menu.css', 'resources/drag.webp', '<@(remoting_webapp_resource_files)', ], + # Variables for feedback_consent.html. + 'ar_feedback_consent_template': + '<(DEPTH)/remoting/webapp/app_remoting/html/template_feedback_consent.html', + 'ar_feedback_consent_template_files': [ + ], + 'ar_feedback_consent_js_files': [ + 'webapp/app_remoting/js/feedback_consent.js', + 'webapp/base/js/base.js', + 'webapp/crd/js/error.js', + 'webapp/crd/js/oauth2_api.js', + 'webapp/crd/js/oauth2_api_impl.js', + 'webapp/crd/js/plugin_settings.js', + 'webapp/crd/js/l10n.js', + 'webapp/crd/js/xhr.js', + ], + # Variables for main.html. # These template files are used to construct the webapp html files. 'ar_main_template': @@ -74,7 +90,7 @@ 'app_remoting_webapp_localizable_files': [ '<(ar_main_template)', '<@(ar_main_template_files)', - 'webapp/app_remoting/html/feedback_consent.html', + '<(ar_feedback_consent_template)', '<@(ar_all_js_files)', ],
diff --git a/remoting/base/auth_token_util.cc b/remoting/base/auth_token_util.cc deleted file mode 100644 index 45caa92..0000000 --- a/remoting/base/auth_token_util.cc +++ /dev/null
@@ -1,34 +0,0 @@ -// Copyright (c) 2011 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "remoting/base/auth_token_util.h" -#include "remoting/base/constants.h" - -namespace remoting { - -void ParseAuthTokenWithService(const std::string& auth_service_with_token, - std::string* auth_token, - std::string* auth_service) { - size_t delimiter_pos = auth_service_with_token.find(':'); - if (delimiter_pos == std::string::npos) { - // Legacy case: there is no delimiter. Assume the whole string is the - // auth_token, and that we're using the default service. - // - // TODO(ajwong): Remove this defaulting once all webclients are migrated. - // BUG:83897 - auth_token->assign(auth_service_with_token); - auth_service->assign(kChromotingTokenDefaultServiceName); - } else { - auth_service->assign(auth_service_with_token.substr(0, delimiter_pos)); - - // Make sure there is *something* after the delimiter before doing substr. - if (delimiter_pos < auth_service_with_token.size()) { - auth_token->assign(auth_service_with_token.substr(delimiter_pos + 1)); - } else { - auth_token->clear(); - } - } -} - -} // namespace remoting
diff --git a/remoting/base/auth_token_util.h b/remoting/base/auth_token_util.h deleted file mode 100644 index 309a888..0000000 --- a/remoting/base/auth_token_util.h +++ /dev/null
@@ -1,20 +0,0 @@ -// Copyright (c) 2011 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef REMOTING_BASE_AUTH_TOKEN_UTIL_H_ -#define REMOTING_BASE_AUTH_TOKEN_UTIL_H_ - -#include <string> - -namespace remoting { - -// Given a string of the form "auth_service:auth_token" parses it into its -// component pieces. -void ParseAuthTokenWithService(const std::string& auth_service_with_token, - std::string* auth_token, - std::string* auth_service); - -} // namespace remoting - -#endif // REMOTING_BASE_AUTH_TOKEN_UTIL_H_
diff --git a/remoting/base/auth_token_util_unittest.cc b/remoting/base/auth_token_util_unittest.cc deleted file mode 100644 index 2732b44..0000000 --- a/remoting/base/auth_token_util_unittest.cc +++ /dev/null
@@ -1,36 +0,0 @@ -// Copyright (c) 2011 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "remoting/base/auth_token_util.h" -#include "remoting/base/constants.h" -#include "testing/gtest/include/gtest/gtest.h" - -namespace remoting { -namespace { - -TEST(AuthTokenUtilTest, ParseAuthTokenWithService) { - std::string auth_token; - std::string auth_service; - - ParseAuthTokenWithService("service:token", &auth_token, &auth_service); - EXPECT_EQ("token", auth_token); - EXPECT_EQ("service", auth_service); - - // Check for legacy support. - ParseAuthTokenWithService("token2", &auth_token, &auth_service); - EXPECT_EQ("token2", auth_token); - EXPECT_EQ(std::string(kChromotingTokenDefaultServiceName), auth_service); - - ParseAuthTokenWithService("just_service:", &auth_token, &auth_service); - EXPECT_EQ("", auth_token); - EXPECT_EQ("just_service", auth_service); - - ParseAuthTokenWithService("yay:token:has:colons", &auth_token, &auth_service); - EXPECT_EQ("token:has:colons", auth_token); - EXPECT_EQ("yay", auth_service); -} - -} // namespace - -} // namespace remoting
diff --git a/remoting/base/constants.cc b/remoting/base/constants.cc index 00995702..172c73e 100644 --- a/remoting/base/constants.cc +++ b/remoting/base/constants.cc
@@ -6,8 +6,6 @@ namespace remoting { -const char kChromotingTokenDefaultServiceName[] = "chromiumsync"; - const char kChromotingXmlNamespace[] = "google:remoting"; const char kAudioChannelName[] = "audio";
diff --git a/remoting/base/constants.h b/remoting/base/constants.h index 80c557266..43e3564 100644 --- a/remoting/base/constants.h +++ b/remoting/base/constants.h
@@ -7,11 +7,6 @@ namespace remoting { -// Service name used for authentication. -// TODO(ajwong): Remove this once we've killed off XmppToken usage. -// BUG:83897 -extern const char kChromotingTokenDefaultServiceName[]; - // Namespace used for chromoting XMPP stanzas. extern const char kChromotingXmlNamespace[];
diff --git a/remoting/client/jni/chromoting_jni_instance.cc b/remoting/client/jni/chromoting_jni_instance.cc index 2c77fda..6cfc8870e 100644 --- a/remoting/client/jni/chromoting_jni_instance.cc +++ b/remoting/client/jni/chromoting_jni_instance.cc
@@ -63,7 +63,6 @@ xmpp_config_.use_tls = kXmppUseTls; xmpp_config_.username = username; xmpp_config_.auth_token = auth_token; - xmpp_config_.auth_service = "oauth2"; // Initialize |authenticator_|. scoped_ptr<protocol::ThirdPartyClientAuthenticator::TokenFetcher>
diff --git a/remoting/host/BUILD.gn b/remoting/host/BUILD.gn index 12c6bd0..3b0e4ac 100644 --- a/remoting/host/BUILD.gn +++ b/remoting/host/BUILD.gn
@@ -34,13 +34,13 @@ "//ui/events:dom4_keycode_converter", ] - if (is_linux) { + if (is_linux && !is_chromeos) { libs += [ "pam" ] } if (use_x11) { configs += [ - #TODO : (kelvinp) Add GTK to the configs. + # TODO(kelvinp): Add GTK to the configs. "//build/config/linux:x11", ] } else { @@ -83,7 +83,6 @@ "continue_window_linux.cc", "disconnect_window_linux.cc", "local_input_monitor_x11.cc", - "remoting_me2me_host.cc", ] }
diff --git a/remoting/host/host_config.h b/remoting/host/host_config.h index 198ddbb..1ec35ce9c8 100644 --- a/remoting/host/host_config.h +++ b/remoting/host/host_config.h
@@ -27,12 +27,8 @@ extern const char kHostOwnerEmailConfigPath[]; // Login used to authenticate in XMPP network (could be a service account). extern const char kXmppLoginConfigPath[]; -// Auth token used to authenticate to XMPP network. -extern const char kXmppAuthTokenConfigPath[]; // OAuth refresh token used to fetch an access token for the XMPP network. extern const char kOAuthRefreshTokenConfigPath[]; -// Auth service used to authenticate to XMPP network. -extern const char kXmppAuthServiceConfigPath[]; // Unique identifier of the host used to register the host in directory. // Normally a random UUID. extern const char kHostIdConfigPath[];
diff --git a/remoting/host/host_config_constants.cc b/remoting/host/host_config_constants.cc index c98e182..62631c2c 100644 --- a/remoting/host/host_config_constants.cc +++ b/remoting/host/host_config_constants.cc
@@ -13,9 +13,7 @@ const char kHostOwnerConfigPath[] = "host_owner"; const char kHostOwnerEmailConfigPath[] = "host_owner_email"; const char kXmppLoginConfigPath[] = "xmpp_login"; -const char kXmppAuthTokenConfigPath[] = "xmpp_auth_token"; const char kOAuthRefreshTokenConfigPath[] = "oauth_refresh_token"; -const char kXmppAuthServiceConfigPath[] = "xmpp_auth_service"; const char kHostIdConfigPath[] = "host_id"; const char kHostNameConfigPath[] = "host_name"; const char kHostSecretHashConfigPath[] = "host_secret_hash";
diff --git a/remoting/host/host_config_unittest.cc b/remoting/host/host_config_unittest.cc index 5e6fab6c..3500381 100644 --- a/remoting/host/host_config_unittest.cc +++ b/remoting/host/host_config_unittest.cc
@@ -17,7 +17,7 @@ const char* kTestConfig = "{\n" " \"xmpp_login\" : \"test@gmail.com\",\n" -" \"xmpp_auth_token\" : \"TEST_AUTH_TOKEN\",\n" +" \"oauth_refresh_token\" : \"TEST_REFRESH_TOKEN\",\n" " \"host_id\" : \"TEST_HOST_ID\",\n" " \"host_name\" : \"TEST_MACHINE_NAME\",\n" " \"private_key\" : \"TEST_PRIVATE_KEY\"\n" @@ -57,8 +57,8 @@ std::string value; EXPECT_TRUE(target->GetString(kXmppLoginConfigPath, &value)); EXPECT_EQ("test@gmail.com", value); - EXPECT_TRUE(target->GetString(kXmppAuthTokenConfigPath, &value)); - EXPECT_EQ("TEST_AUTH_TOKEN", value); + EXPECT_TRUE(target->GetString(kOAuthRefreshTokenConfigPath, &value)); + EXPECT_EQ("TEST_REFRESH_TOKEN", value); EXPECT_TRUE(target->GetString(kHostIdConfigPath, &value)); EXPECT_EQ("TEST_HOST_ID", value); EXPECT_TRUE(target->GetString(kHostNameConfigPath, &value)); @@ -77,8 +77,8 @@ scoped_ptr<base::DictionaryValue> target(HostConfigFromJsonFile(test_file)); ASSERT_TRUE(target); - std::string new_auth_token_value = "NEW_AUTH_TOKEN"; - target->SetString(kXmppAuthTokenConfigPath, new_auth_token_value); + std::string new_refresh_token_value = "NEW_REFRESH_TOKEN"; + target->SetString(kOAuthRefreshTokenConfigPath, new_refresh_token_value); ASSERT_TRUE(HostConfigToJsonFile(*target, test_file)); // Now read the file again and check that the value has been written. @@ -88,8 +88,8 @@ std::string value; EXPECT_TRUE(reader->GetString(kXmppLoginConfigPath, &value)); EXPECT_EQ("test@gmail.com", value); - EXPECT_TRUE(reader->GetString(kXmppAuthTokenConfigPath, &value)); - EXPECT_EQ(new_auth_token_value, value); + EXPECT_TRUE(reader->GetString(kOAuthRefreshTokenConfigPath, &value)); + EXPECT_EQ(new_refresh_token_value, value); EXPECT_TRUE(reader->GetString(kHostIdConfigPath, &value)); EXPECT_EQ("TEST_HOST_ID", value); EXPECT_TRUE(reader->GetString(kHostNameConfigPath, &value));
diff --git a/remoting/host/host_signaling_manager.cc b/remoting/host/host_signaling_manager.cc index 99ad431b..f9bb941 100644 --- a/remoting/host/host_signaling_manager.cc +++ b/remoting/host/host_signaling_manager.cc
@@ -43,18 +43,14 @@ scoped_ptr<DnsBlackholeChecker> dns_blackhole_checker(new DnsBlackholeChecker( url_request_context_getter, talkgadget_prefix_policy)); + scoped_ptr<OAuthTokenGetter> oauth_token_getter(new OAuthTokenGetter( + oauth_credentials.Pass(), url_request_context_getter, false)); scoped_ptr<SignalingConnector> signaling_connector(new SignalingConnector( signal_strategy.get(), dns_blackhole_checker.Pass(), + oauth_token_getter.Pass(), base::Bind(&Listener::OnAuthFailed, base::Unretained(listener)))); - if (!oauth_credentials->refresh_token.empty()) { - scoped_ptr<OAuthTokenGetter> oauth_token_getter(new OAuthTokenGetter( - oauth_credentials.Pass(), url_request_context_getter, false)); - - signaling_connector->EnableOAuth(oauth_token_getter.Pass()); - } - scoped_ptr<HeartbeatSender> heartbeat_sender(new HeartbeatSender( base::Bind(&Listener::OnHeartbeatSuccessful, base::Unretained(listener)), base::Bind(&Listener::OnUnknownHostIdError, base::Unretained(listener)),
diff --git a/remoting/host/it2me/it2me_native_messaging_host.cc b/remoting/host/it2me/it2me_native_messaging_host.cc index 148dc01..7af2db74 100644 --- a/remoting/host/it2me/it2me_native_messaging_host.cc +++ b/remoting/host/it2me/it2me_native_messaging_host.cc
@@ -12,13 +12,13 @@ #include "base/json/json_reader.h" #include "base/json/json_writer.h" #include "base/strings/string_number_conversions.h" +#include "base/strings/string_util.h" #include "base/strings/stringize_macros.h" #include "base/threading/thread.h" #include "base/values.h" #include "media/base/media.h" #include "net/base/net_util.h" #include "net/url_request/url_request_context_getter.h" -#include "remoting/base/auth_token_util.h" #include "remoting/base/service_urls.h" #include "remoting/host/chromoting_host_context.h" #include "remoting/host/host_exit_codes.h" @@ -164,16 +164,19 @@ return; } - ParseAuthTokenWithService(auth_service_with_token, - &xmpp_config.auth_token, - &xmpp_config.auth_service); - if (xmpp_config.auth_token.empty()) { - SendErrorAndExit( - response.Pass(), - "Invalid 'authServiceWithToken': " + auth_service_with_token); + // For backward compatibility the webapp still passes OAuth service as part of + // the authServiceWithToken field. But auth service part is always expected to + // be set to oauth2. + const char kOAuth2ServicePrefix[] = "oauth2:"; + if (!StartsWithASCII(auth_service_with_token, kOAuth2ServicePrefix, true)) { + SendErrorAndExit(response.Pass(), "Invalid 'authServiceWithToken': " + + auth_service_with_token); return; } + xmpp_config.auth_token = + auth_service_with_token.substr(strlen(kOAuth2ServicePrefix)); + #if !defined(NDEBUG) std::string address; if (!message.GetString("xmppServerAddress", &address)) {
diff --git a/remoting/host/remoting_me2me_host.cc b/remoting/host/remoting_me2me_host.cc index 8cf6cce..51331685 100644 --- a/remoting/host/remoting_me2me_host.cc +++ b/remoting/host/remoting_me2me_host.cc
@@ -947,29 +947,13 @@ return false; } - // Use an XMPP connection to the Talk network for session signalling. + // Use an XMPP connection to the Talk network for session signaling. if (!config.GetString(kXmppLoginConfigPath, &xmpp_server_config_.username) || - !(config.GetString(kXmppAuthTokenConfigPath, - &xmpp_server_config_.auth_token) || - config.GetString(kOAuthRefreshTokenConfigPath, - &oauth_refresh_token_))) { + !config.GetString(kOAuthRefreshTokenConfigPath, &oauth_refresh_token_)) { LOG(ERROR) << "XMPP credentials are not defined in the config."; return false; } - if (!oauth_refresh_token_.empty()) { - // SignalingConnector (inside HostSignalingManager) is responsible for - // getting OAuth token. - xmpp_server_config_.auth_token = ""; - xmpp_server_config_.auth_service = "oauth2"; - } else if (!config.GetString(kXmppAuthServiceConfigPath, - &xmpp_server_config_.auth_service)) { - // For the me2me host, we default to ClientLogin token for chromiumsync - // because earlier versions of the host had no HTTP stack with which to - // request an OAuth2 access token. - xmpp_server_config_.auth_service = kChromotingTokenDefaultServiceName; - } - if (config.GetString(kHostOwnerConfigPath, &host_owner_)) { // Service account configs have a host_owner, different from the xmpp_login. use_service_account_ = true;
diff --git a/remoting/host/signaling_connector.cc b/remoting/host/signaling_connector.cc index adc1571..7359e154 100644 --- a/remoting/host/signaling_connector.cc +++ b/remoting/host/signaling_connector.cc
@@ -26,10 +26,12 @@ SignalingConnector::SignalingConnector( XmppSignalStrategy* signal_strategy, scoped_ptr<DnsBlackholeChecker> dns_blackhole_checker, + scoped_ptr<OAuthTokenGetter> oauth_token_getter, const base::Closure& auth_failed_callback) : signal_strategy_(signal_strategy), auth_failed_callback_(auth_failed_callback), dns_blackhole_checker_(dns_blackhole_checker.Pass()), + oauth_token_getter_(oauth_token_getter.Pass()), reconnect_attempts_(0) { DCHECK(!auth_failed_callback_.is_null()); DCHECK(dns_blackhole_checker_.get()); @@ -45,11 +47,6 @@ net::NetworkChangeNotifier::RemoveIPAddressObserver(this); } -void SignalingConnector::EnableOAuth( - scoped_ptr<OAuthTokenGetter> oauth_token_getter) { - oauth_token_getter_ = oauth_token_getter.Pass(); -} - void SignalingConnector::OnSignalStrategyStateChange( SignalStrategy::State state) { DCHECK(CalledOnValidThread()); @@ -110,7 +107,7 @@ DCHECK_EQ(status, OAuthTokenGetter::SUCCESS); HOST_LOG << "Received user info."; - signal_strategy_->SetAuthInfo(user_email, access_token, "oauth2"); + signal_strategy_->SetAuthInfo(user_email, access_token); // Now that we've refreshed the token and verified that it's for the correct // user account, try to connect using the new token.
diff --git a/remoting/host/signaling_connector.h b/remoting/host/signaling_connector.h index acb6921..8a59e903 100644 --- a/remoting/host/signaling_connector.h +++ b/remoting/host/signaling_connector.h
@@ -34,13 +34,10 @@ SignalingConnector( XmppSignalStrategy* signal_strategy, scoped_ptr<DnsBlackholeChecker> dns_blackhole_checker, + scoped_ptr<OAuthTokenGetter> oauth_token_getter, const base::Closure& auth_failed_callback); ~SignalingConnector() override; - // May be called immediately after the constructor to enable OAuth - // access token updating. - void EnableOAuth(scoped_ptr<OAuthTokenGetter> oauth_token_getter); - // OAuthTokenGetter callback. void OnAccessToken(OAuthTokenGetter::Status status, const std::string& user_email,
diff --git a/remoting/remoting.gyp b/remoting/remoting.gyp index 0f40d356..a0da127b 100644 --- a/remoting/remoting.gyp +++ b/remoting/remoting.gyp
@@ -4,27 +4,6 @@ { 'variables': { - 'chromium_code': 1, - - # Set this to run the jscompile checks after building the webapp. - 'run_jscompile%': 1, - - # Set this to enable cast mode on the android client. - 'enable_cast%': 0, - - 'variables': { - 'conditions': [ - # Enable the multi-process host on Windows by default. - ['OS=="win"', { - 'remoting_multi_process%': 1, - }, { - 'remoting_multi_process%': 0, - }], - ], - }, - - 'remoting_multi_process%': '<(remoting_multi_process)', - 'remoting_rdp_session%': 1, 'branding_path': '../remoting/branding_<(branding)', @@ -44,11 +23,6 @@ '<!(python -c "import uuid; print uuid.uuid5(uuid.UUID(\'655bd819-c08c-4b04-80c2-f160739ff6ef\'), \'<(version_full)\')")', 'rdp_desktop_session_clsid': '<!(python -c "import uuid; print uuid.uuid5(uuid.UUID(\'6a7699f0-ee43-43e7-aa30-a6738f9bd470\'), \'<(version_full)\')")', - - # Java is not available on Windows bots, so we need to disable - # JScompile checks. - 'run_jscompile': 0, - }], ], }, @@ -61,6 +35,7 @@ 'remoting_host_srcs.gypi', 'remoting_key_tester.gypi', 'remoting_locales.gypi', + 'remoting_options.gypi', 'remoting_srcs.gypi', 'remoting_test.gypi', 'remoting_version.gypi',
diff --git a/remoting/remoting_host.gypi b/remoting/remoting_host.gypi index e818a971..33d1e4a 100644 --- a/remoting/remoting_host.gypi +++ b/remoting/remoting_host.gypi
@@ -75,11 +75,6 @@ ], }] ], - 'link_settings': { - 'libraries': [ - '-lpam', - ], - }, }], ['chromeos==1', { 'dependencies' : [ @@ -102,7 +97,6 @@ 'host/linux/x_server_clipboard.cc', 'host/linux/x_server_clipboard.h', 'host/local_input_monitor_x11.cc', - 'host/remoting_me2me_host.cc', ], 'conditions': [ ['use_ash==1', { @@ -144,7 +138,6 @@ 'link_settings': { 'libraries': [ '$(SDKROOT)/System/Library/Frameworks/OpenGL.framework', - 'libpam.a', ], }, }], @@ -420,6 +413,8 @@ 'dependencies': [ '../base/base.gyp:base', '../base/base.gyp:base_i18n', + '../components/components.gyp:policy', + '../components/components.gyp:policy_component_common', '../net/net.gyp:net', '../third_party/webrtc/modules/modules.gyp:desktop_capture', 'remoting_base', @@ -435,14 +430,26 @@ 'host/curtain_mode_linux.cc', 'host/curtain_mode_mac.cc', 'host/curtain_mode_win.cc', + 'host/pam_authorization_factory_posix.cc', + 'host/pam_authorization_factory_posix.h', 'host/posix/signal_handler.cc', 'host/posix/signal_handler.h', + 'host/remoting_me2me_host.cc', ], 'conditions': [ - ['os_posix != 1', { - 'sources/': [ - ['exclude', '^host/posix/'], - ], + ['OS=="linux"', { + 'link_settings': { + 'libraries': [ + '-lpam', + ], + }, + }], + ['OS=="mac"', { + 'link_settings': { + 'libraries': [ + 'libpam.a', + ], + }, }], ], # end of 'conditions' }, # end of target 'remoting_me2me_host_static'
diff --git a/remoting/remoting_host_linux.gypi b/remoting/remoting_host_linux.gypi index 5ef7418..f9b89ea 100644 --- a/remoting/remoting_host_linux.gypi +++ b/remoting/remoting_host_linux.gypi
@@ -41,6 +41,18 @@ ], 'action': [ 'zip', '-j', '-0', '<@(_outputs)', '<@(_inputs)' ], }, + { + # Copy the debian package file, which has version info in it, + # to a consistent filename for use on Chromoting swarming bots. + 'action_name': 'Copy debian package.', + 'inputs': [ + '<@(deb_filename)', + ], + 'outputs': [ + '<(PRODUCT_DIR)/remoting-me2me-host.deb', + ], + 'action': [ 'cp', '<@(_inputs)', '<@(_outputs)'], + }, ], }, { 'target_name': 'remoting_me2me_host_deb_installer',
diff --git a/remoting/remoting_host_srcs.gypi b/remoting/remoting_host_srcs.gypi index fbdfc71..9c99640 100644 --- a/remoting/remoting_host_srcs.gypi +++ b/remoting/remoting_host_srcs.gypi
@@ -187,8 +187,6 @@ 'host/pairing_registry_delegate_mac.cc', 'host/pairing_registry_delegate_win.cc', 'host/pairing_registry_delegate_win.h', - 'host/pam_authorization_factory_posix.cc', - 'host/pam_authorization_factory_posix.h', 'host/pin_hash.cc', 'host/pin_hash.h', 'host/policy_watcher.cc', @@ -197,7 +195,6 @@ 'host/register_support_host_request.h', 'host/remote_input_filter.cc', 'host/remote_input_filter.h', - 'host/remoting_me2me_host.cc', 'host/resizing_host_observer.cc', 'host/resizing_host_observer.h', 'host/sas_injector.h',
diff --git a/remoting/remoting_key_tester.gypi b/remoting/remoting_key_tester.gypi index d85a321..68db9b0 100644 --- a/remoting/remoting_key_tester.gypi +++ b/remoting/remoting_key_tester.gypi
@@ -55,7 +55,8 @@ 'action_name': 'jscompile remoting_key_tester', 'inputs': [ '<@(remoting_key_tester_js_files)', - 'webapp/js_proto/chrome_proto.js' + 'webapp/js_proto/chrome_proto.js', + 'webapp/js_proto/chrome_event_proto.js', ], 'outputs': [ '<(success_stamp)', @@ -66,7 +67,8 @@ '--no-single-file', '--success-stamp', '<(success_stamp)', '<@(remoting_key_tester_js_files)', - 'webapp/js_proto/chrome_proto.js' + 'webapp/js_proto/chrome_proto.js', + 'webapp/js_proto/chrome_event_proto.js', ], }, ], # actions
diff --git a/remoting/remoting_options.gypi b/remoting/remoting_options.gypi new file mode 100644 index 0000000..56d339e --- /dev/null +++ b/remoting/remoting_options.gypi
@@ -0,0 +1,40 @@ +# 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. + +{ + 'variables': { + 'chromium_code': 1, + + # Set this to run the jscompile checks after building the webapp. + 'run_jscompile%': 1, + + # Set this to enable cast mode on the android client. + 'enable_cast%': 0, + + 'variables': { + 'conditions': [ + # Enable the multi-process host on Windows by default. + ['OS=="win"', { + 'remoting_multi_process%': 1, + }, { + 'remoting_multi_process%': 0, + }], + ], + }, + 'remoting_multi_process%': '<(remoting_multi_process)', + + 'remoting_rdp_session%': 1, + + 'branding_path': '../remoting/branding_<(branding)', + + 'conditions': [ + ['OS=="win"', { + # Java is not available on Windows bots, so we need to disable + # JScompile checks. + 'run_jscompile': 0, + }], + ], + }, + +}
diff --git a/remoting/remoting_srcs.gypi b/remoting/remoting_srcs.gypi index df1fbc7..4093c8e 100644 --- a/remoting/remoting_srcs.gypi +++ b/remoting/remoting_srcs.gypi
@@ -5,8 +5,6 @@ { 'variables': { 'remoting_base_sources': [ - 'base/auth_token_util.cc', - 'base/auth_token_util.h', 'base/auto_thread.cc', 'base/auto_thread.h', 'base/auto_thread_task_runner.cc',
diff --git a/remoting/remoting_test.gypi b/remoting/remoting_test.gypi index 7d3c50b..2c34855 100644 --- a/remoting/remoting_test.gypi +++ b/remoting/remoting_test.gypi
@@ -107,7 +107,6 @@ '../testing/gmock/include', ], 'sources': [ - 'base/auth_token_util_unittest.cc', 'base/auto_thread_task_runner_unittest.cc', 'base/auto_thread_unittest.cc', 'base/breakpad_win_unittest.cc',
diff --git a/remoting/remoting_webapp.gypi b/remoting/remoting_webapp.gypi index 7d72c67..e7b00fd 100644 --- a/remoting/remoting_webapp.gypi +++ b/remoting/remoting_webapp.gypi
@@ -24,6 +24,7 @@ 'variables': { 'success_stamp': '<(PRODUCT_DIR)/<(_target_name)_jscompile.stamp', 'success_stamp_bt': '<(PRODUCT_DIR)/<(_target_name)_bt_jscompile.stamp', + 'success_stamp_ut': '<(PRODUCT_DIR)/<(_target_name)_ut_jscompile.stamp', }, 'actions': [ { @@ -49,7 +50,7 @@ 'inputs': [ '<@(remoting_webapp_crd_js_files)', '<@(remoting_webapp_browsertest_all_js_files)', - '<@(remoting_webapp_js_proto_files)', + '<@(remoting_webapp_browsertest_js_proto_files)', ], 'outputs': [ '<(success_stamp_bt)', @@ -61,7 +62,27 @@ '--success-stamp', '<(success_stamp_bt)', '<@(remoting_webapp_crd_js_files)', '<@(remoting_webapp_browsertest_all_js_files)', - '<@(remoting_webapp_js_proto_files)', + '<@(remoting_webapp_browsertest_js_proto_files)', + ], + }, + { + 'action_name': 'Verify remoting webapp unittests', + 'inputs': [ + '<@(remoting_webapp_crd_js_files)', + '<@(remoting_webapp_unittest_all_js_files)', + '<@(remoting_webapp_unittest_js_proto_files)', + ], + 'outputs': [ + '<(success_stamp_ut)', + ], + 'action': [ + 'python', '../third_party/closure_compiler/checker.py', + '--strict', + '--no-single-file', + '--success-stamp', '<(success_stamp_ut)', + '<@(remoting_webapp_crd_js_files)', + '<@(remoting_webapp_unittest_all_js_files)', + '<@(remoting_webapp_unittest_js_proto_files)', ], }, ], # actions
diff --git a/remoting/remoting_webapp_files.gypi b/remoting/remoting_webapp_files.gypi index 129f198b..ad13a552 100644 --- a/remoting/remoting_webapp_files.gypi +++ b/remoting/remoting_webapp_files.gypi
@@ -14,19 +14,16 @@ # These provide type information for jscompile. 'remoting_webapp_js_proto_files': [ 'webapp/js_proto/chrome_proto.js', + 'webapp/js_proto/chrome_cast_proto.js', + 'webapp/js_proto/chrome_event_proto.js', 'webapp/js_proto/dom_proto.js', 'webapp/js_proto/remoting_proto.js', - 'webapp/js_proto/test_proto.js', ], # - # Webapp browsertest and unittest JavaScript files. + # Webapp browsertest JavaScript files. # - # Shared files for tests. - 'remoting_webapp_test_js_common_files': [ - 'webapp/unittests/mock_signal_strategy.js', - ], # Browser test files. 'remoting_webapp_browsertest_js_files': [ 'webapp/browser_test/browser_test.js', @@ -34,21 +31,34 @@ 'webapp/browser_test/cancel_pin_browser_test.js', 'webapp/browser_test/invalid_pin_browser_test.js', 'webapp/browser_test/it2me_browser_test.js', - 'webapp/browser_test/mock_client_plugin.js', - 'webapp/browser_test/mock_host_list_api.js', - 'webapp/browser_test/mock_identity.js', - 'webapp/browser_test/mock_oauth2_api.js', - 'webapp/browser_test/mock_session_connector.js', 'webapp/browser_test/scrollbar_browser_test.js', 'webapp/browser_test/timeout_waiter.js', 'webapp/browser_test/unauthenticated_browser_test.js', 'webapp/browser_test/update_pin_browser_test.js', ], + # Browser test files. + 'remoting_webapp_browsertest_js_mock_files': [ + 'webapp/browser_test/mock_client_plugin.js', + 'webapp/browser_test/mock_host_list_api.js', + 'webapp/browser_test/mock_identity.js', + 'webapp/browser_test/mock_oauth2_api.js', + 'webapp/browser_test/mock_session_connector.js', + 'webapp/unittests/mock_signal_strategy.js', + ], + 'remoting_webapp_browsertest_js_proto_files': [ + 'webapp/js_proto/sinon_proto.js', + 'webapp/js_proto/test_proto.js', + '<@(remoting_webapp_js_proto_files)', + ], 'remoting_webapp_browsertest_all_js_files': [ '<@(remoting_webapp_browsertest_js_files)', - '<@(remoting_webapp_test_js_common_files)', + '<@(remoting_webapp_browsertest_js_mock_files)', ], + # + # Webapp unittest JavaScript files. + # + # These product files are excluded from our JavaScript unittest 'remoting_webapp_unittest_exclude_js_files': [ # background.js is where the onLoad handler is defined, which @@ -57,8 +67,6 @@ ], # The unit test cases for the webapp 'remoting_webapp_unittest_js_files': [ - 'webapp/unittests/chrome_mocks.js', - 'webapp/js_proto/chrome_proto.js', 'webapp/unittests/apps_v2_migration_unittest.js', 'webapp/unittests/base_unittest.js', 'webapp/unittests/desktop_viewport_unittest.js', @@ -76,10 +84,29 @@ 'webapp/unittests/xmpp_login_handler_unittest.js', 'webapp/unittests/xmpp_stream_parser_unittest.js', ], + 'remoting_webapp_unittest_js_mock_files': [ + # Some proto files can be repurposed as simple mocks for the unittests. + # Note that some defs in chrome_proto are overwritten by chrome_mocks. + 'webapp/js_proto/chrome_proto.js', + 'webapp/unittests/chrome_mocks.js', + 'webapp/unittests/mock_signal_strategy.js', + 'webapp/unittests/sinon_helpers.js', + 'webapp/unittests/test_start.js', + ], + # Prototypes for objects that are not mocked. + 'remoting_webapp_unittest_js_proto_files': [ + 'webapp/js_proto/chrome_cast_proto.js', + 'webapp/js_proto/dom_proto.js', + 'webapp/js_proto/remoting_proto.js', + 'webapp/js_proto/qunit_proto.js', + 'webapp/js_proto/sinon_proto.js', + 'webapp/js_proto/sinon_stub_proto.js', + ], 'remoting_webapp_unittest_all_js_files': [ '<@(remoting_webapp_unittest_js_files)', - '<@(remoting_webapp_test_js_common_files)', + '<@(remoting_webapp_unittest_js_mock_files)', ], + # All the files needed to run the unittests. 'remoting_webapp_unittest_all_files': [ 'webapp/crd/html/menu_button.css', '<@(remoting_webapp_unittest_all_js_files)', @@ -127,6 +154,7 @@ 'webapp/crd/js/client_screen.js', 'webapp/crd/js/client_session.js', 'webapp/crd/js/clipboard.js', + 'webapp/crd/js/credentials_provider.js', 'webapp/crd/js/desktop_connected_view.js', 'webapp/crd/js/hangout_session.js', 'webapp/crd/js/host_desktop.js',
diff --git a/remoting/signaling/xmpp_signal_strategy.cc b/remoting/signaling/xmpp_signal_strategy.cc index 806852e..5ad0c03 100644 --- a/remoting/signaling/xmpp_signal_strategy.cc +++ b/remoting/signaling/xmpp_signal_strategy.cc
@@ -83,7 +83,7 @@ settings.set_user(login_jid.node()); settings.set_host(login_jid.domain()); settings.set_resource(resource_name_); - settings.set_token_service(xmpp_server_config_.auth_service); + settings.set_token_service("oauth2"); settings.set_auth_token(buzz::AUTH_MECHANISM_GOOGLE_TOKEN, xmpp_server_config_.auth_token); @@ -203,12 +203,10 @@ } void XmppSignalStrategy::SetAuthInfo(const std::string& username, - const std::string& auth_token, - const std::string& auth_service) { + const std::string& auth_token) { DCHECK(CalledOnValidThread()); xmpp_server_config_.username = username; xmpp_server_config_.auth_token = auth_token; - xmpp_server_config_.auth_service = auth_service; } void XmppSignalStrategy::SetResourceName(const std::string &resource_name) { @@ -269,13 +267,8 @@ buzz::PreXmppAuth* XmppSignalStrategy::CreatePreXmppAuth( const buzz::XmppClientSettings& settings) { buzz::Jid jid(settings.user(), settings.host(), buzz::STR_EMPTY); - std::string mechanism = notifier::kDefaultGaiaAuthMechanism; - if (settings.token_service() == "oauth2") { - mechanism = "X-OAUTH2"; - } - return new notifier::GaiaTokenPreXmppAuth( - jid.Str(), settings.auth_token(), settings.token_service(), mechanism); + jid.Str(), settings.auth_token(), settings.token_service(), "X-OAUTH2"); } } // namespace remoting
diff --git a/remoting/signaling/xmpp_signal_strategy.h b/remoting/signaling/xmpp_signal_strategy.h index 18ae841..2d8268b786 100644 --- a/remoting/signaling/xmpp_signal_strategy.h +++ b/remoting/signaling/xmpp_signal_strategy.h
@@ -50,7 +50,6 @@ std::string username; std::string auth_token; - std::string auth_service; }; XmppSignalStrategy( @@ -77,8 +76,7 @@ // access token is renewed). It is OK to call this even when we are in the // CONNECTED state. It will be used on the next Connect() call. void SetAuthInfo(const std::string& username, - const std::string& auth_token, - const std::string& auth_service); + const std::string& auth_token); // Use this method to override the default resource name used (optional). // This will be used on the next Connect() call.
diff --git a/remoting/webapp/app_remoting/html/ar_main.css b/remoting/webapp/app_remoting/html/ar_main.css new file mode 100644 index 0000000..56cd979 --- /dev/null +++ b/remoting/webapp/app_remoting/html/ar_main.css
@@ -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. + */ + +html { + background-image: radial-gradient(#444, #111); +} \ No newline at end of file
diff --git a/remoting/webapp/app_remoting/html/feedback_consent.html b/remoting/webapp/app_remoting/html/template_feedback_consent.html similarity index 89% rename from remoting/webapp/app_remoting/html/feedback_consent.html rename to remoting/webapp/app_remoting/html/template_feedback_consent.html index adaf745f8..a0cb8da 100644 --- a/remoting/webapp/app_remoting/html/feedback_consent.html +++ b/remoting/webapp/app_remoting/html/template_feedback_consent.html
@@ -13,12 +13,9 @@ <link rel="stylesheet" href="feedback_consent.css"> <link rel="stylesheet" href="main.css"> <link rel="stylesheet" href="message_window.css"> - <script src="error.js"></script> - <script src="feedback_consent.js"></script> - <script src="oauth2_api_impl.js"></script> - <script src="plugin_settings.js"></script> - <script src="l10n.js"></script> - <script src="xhr.js"></script> + + <meta-include type="javascript"/> + <title i18n-content="FEEDBACK_CONSENT_TITLE"></title> </head> <body>
diff --git a/remoting/webapp/app_remoting/html/template_lg.html b/remoting/webapp/app_remoting/html/template_lg.html index 9b666acfa..32bb369 100644 --- a/remoting/webapp/app_remoting/html/template_lg.html +++ b/remoting/webapp/app_remoting/html/template_lg.html
@@ -9,11 +9,12 @@ <head> <meta charset="utf-8"> <link rel="icon" type="image/png" href="icon16.png"> - <link rel="stylesheet" href="open_sans.css"> + <link rel="stylesheet" href="ar_main.css"> <link rel="stylesheet" href="connection_stats.css"> <link rel="stylesheet" href="context_menu.css"> <link rel="stylesheet" href="main.css"> <link rel="stylesheet" href="menu_button.css"> + <link rel="stylesheet" href="open_sans.css"> <meta-include type="javascript"/>
diff --git a/remoting/webapp/app_remoting/js/app_remoting.js b/remoting/webapp/app_remoting/js/app_remoting.js index 2aab7393..de4700a9 100644 --- a/remoting/webapp/app_remoting/js/app_remoting.js +++ b/remoting/webapp/app_remoting/js/app_remoting.js
@@ -190,7 +190,7 @@ method: 'POST', url: that.runApplicationUrl(), onDone: parseAppHostResponse, - oauthToken: token, + oauthToken: token }); }; @@ -238,9 +238,12 @@ * @return {void} Nothing. */ remoting.AppRemoting.prototype.handleConnected = function(clientSession) { - remoting.clientSession.sendClientMessage( - 'setUserDisplayInfo', - JSON.stringify({fullName: remoting.identity.getCachedUserFullName()})); + remoting.identity.getUserInfo().then( + function(userInfo) { + remoting.clientSession.sendClientMessage( + 'setUserDisplayInfo', + JSON.stringify({fullName: userInfo.name})); + }); // Set up a ping at 10-second intervals to test the connection speed. function ping() {
diff --git a/remoting/webapp/app_remoting/js/feedback_consent.js b/remoting/webapp/app_remoting/js/feedback_consent.js index 6691ed2..f792376 100644 --- a/remoting/webapp/app_remoting/js/feedback_consent.js +++ b/remoting/webapp/app_remoting/js/feedback_consent.js
@@ -15,7 +15,7 @@ * @type {string} The network stats at the time the feedback consent dialog * was shown. */ -var connectionStats = null; +var connectionStats = ''; /** * @type {string} "no" => user did not request a VM reset; "yes" => VM was @@ -102,8 +102,8 @@ */ function generateId() { var idArray = new Uint8Array(20); - crypto.getRandomValues(idArray); - return btoa(String.fromCharCode.apply(null, idArray)); + window.crypto.getRandomValues(idArray); + return window.btoa(String.fromCharCode.apply(null, idArray)); } /** @@ -123,10 +123,6 @@ 'abandonHost': 'true', 'crashServiceReportId': crashServiceReportId }; - var headers = { - 'Authorization': 'OAuth ' + token, - 'Content-type': 'application/json' - }; var uri = remoting.settings.APP_REMOTING_API_BASE_URL + '/applications/' + remoting.settings.getAppRemotingApplicationId() + '/hosts/' + hostId + @@ -139,7 +135,13 @@ showError(); } }; - remoting.xhr.post(uri, onDone, JSON.stringify(body), headers); + remoting.xhr.start({ + method: 'POST', + url: uri, + onDone: onDone, + jsonContent: body, + oauthToken: token + }); } else { getUserInfo(); } @@ -184,6 +186,7 @@ } } +/** @param {Event} event */ function onLearnMore(event) { event.preventDefault(); // Clicking the link should not tick the checkbox. var learnMoreLink = document.getElementById('learn-more');
diff --git a/remoting/webapp/base/js/auth_init.js b/remoting/webapp/base/js/auth_init.js index c67e454..009edd14 100644 --- a/remoting/webapp/base/js/auth_init.js +++ b/remoting/webapp/base/js/auth_init.js
@@ -42,12 +42,14 @@ } } - remoting.identity.getUserInfo().then(function(userInfo) { - onUserInfoAvailable(userInfo.email, userInfo.name); - }).catch(function(error) { - onGetIdentityInfoError( - /** @type {remoting.Error} */ (error)); - }); + remoting.identity.getUserInfo().then( + /** @param {{email:string, name:string}} userInfo */ + function(userInfo) { + onUserInfoAvailable(userInfo.email, userInfo.name); + }).catch(function(error) { + onGetIdentityInfoError( + /** @type {remoting.Error} */ (error)); + }); }; /** @@ -64,4 +66,4 @@ window.location.reload(); } }); -}; \ No newline at end of file +};
diff --git a/remoting/webapp/base/js/ipc.js b/remoting/webapp/base/js/ipc.js index a940a28..955d150 100644 --- a/remoting/webapp/base/js/ipc.js +++ b/remoting/webapp/base/js/ipc.js
@@ -89,7 +89,7 @@ /** * @param {string} methodName - * @param {function(...?)} handler The handler can be invoked by calling + * @param {Function} handler The handler can be invoked by calling * base.Ipc.invoke(|methodName|, arg1, arg2, ...) * Async handlers that return promises are currently not supported. * @return {boolean} Whether the handler is successfully registered. @@ -145,8 +145,8 @@ * * @param {string} methodName * @param {...} var_args - * @return A Promise that would resolve to the return value of the handler or - * reject if the handler throws an exception. + * @return {Promise} A Promise that would resolve to the return value of the + * handler or reject if the handler throws an exception. */ base.Ipc.invoke = function(methodName, var_args) { var params = Array.prototype.slice.call(arguments, 1);
diff --git a/remoting/webapp/browser_test/mock_client_plugin.js b/remoting/webapp/browser_test/mock_client_plugin.js index 09858e0a1..8a8dafa 100644 --- a/remoting/webapp/browser_test/mock_client_plugin.js +++ b/remoting/webapp/browser_test/mock_client_plugin.js
@@ -46,10 +46,9 @@ window.setTimeout(onDone.bind(null, true), 0); }; -remoting.MockClientPlugin.prototype.connect = function( - hostJid, hostPublicKey, localJid, sharedSecret, - authenticationMethods, authenticationTag, - clientPairingId, clientPairedSecret) { + +remoting.MockClientPlugin.prototype.connect = + function(host, localJid, credentialsProvider) { base.debug.assert(this.connectionStatusUpdateHandler_ != null); window.setTimeout( this.connectionStatusUpdateHandler_.bind( @@ -79,16 +78,9 @@ remoting.MockClientPlugin.prototype.sendClipboardItem = function(mimeType, item) {}; -remoting.MockClientPlugin.prototype.useAsyncPinDialog = function() {}; - remoting.MockClientPlugin.prototype.requestPairing = function(clientName, onDone) {}; -remoting.MockClientPlugin.prototype.onPinFetched = function(pin) {}; - -remoting.MockClientPlugin.prototype.onThirdPartyTokenFetched = - function(token, sharedSecret) {}; - remoting.MockClientPlugin.prototype.pauseAudio = function(pause) {}; remoting.MockClientPlugin.prototype.pauseVideo = function(pause) {}; @@ -142,12 +134,6 @@ remoting.MockClientPlugin.prototype.setMouseCursorHandler = function(handler) {}; -remoting.MockClientPlugin.prototype.setFetchThirdPartyTokenHandler = - function(handler) {}; - -remoting.MockClientPlugin.prototype.setFetchPinHandler = - function(handler) {}; - /** * @constructor * @implements {remoting.HostDesktop}
diff --git a/remoting/webapp/crd/html/template_unittest.html b/remoting/webapp/crd/html/template_unittest.html index eb99c5c2..cce27c7 100644 --- a/remoting/webapp/crd/html/template_unittest.html +++ b/remoting/webapp/crd/html/template_unittest.html
@@ -22,6 +22,7 @@ <script src="blanketjs/qunit_adapter.js"></script> <script src="sinonjs/sinon.js"></script> <script src="sinonjs/sinon-qunit.js"></script> + <script src="test_start.js"></script> <!-- product files and unit test files--> <meta-include type="javascript"/>
diff --git a/remoting/webapp/crd/js/apps_v2_migration.js b/remoting/webapp/crd/js/apps_v2_migration.js index 3f49883f..aab9994 100644 --- a/remoting/webapp/crd/js/apps_v2_migration.js +++ b/remoting/webapp/crd/js/apps_v2_migration.js
@@ -22,9 +22,9 @@ var MIGRATION_KEY_ = 'remoting-v2-migration'; /** - * @constructor * @param {string} email * @param {string} fullName + * @constructor */ remoting.MigrationSettings = function(email, fullName) { this.email = email; @@ -88,16 +88,14 @@ if (base.isAppsV2()) { chrome.storage.local.remove(MIGRATION_KEY_); } else { - /** - * @param {string} email - * @param {string} fullName - */ - remoting.identity.getUserInfo().then(function(userInfo) { - var preference = {}; - preference[MIGRATION_KEY_] = - new remoting.MigrationSettings(userInfo.email, userInfo.name); - chrome.storage.local.set(preference); - }).catch(base.doNothing); + remoting.identity.getUserInfo().then( + /** @param {{email:string, name:string}} userInfo */ + function(userInfo) { + var preference = {}; + preference[MIGRATION_KEY_] = + new remoting.MigrationSettings(userInfo.email, userInfo.name); + chrome.storage.local.set(preference); + }).catch(base.doNothing); } };
diff --git a/remoting/webapp/crd/js/client_plugin.js b/remoting/webapp/crd/js/client_plugin.js index a7fdd34..cf4360d 100644 --- a/remoting/webapp/crd/js/client_plugin.js +++ b/remoting/webapp/crd/js/client_plugin.js
@@ -34,25 +34,12 @@ remoting.ClientPlugin.prototype.initialize = function(onDone) {}; /** - * @param {string} hostJid The jid of the host to connect to. - * @param {string} hostPublicKey The base64 encoded version of the host's - * public key. + * @param {remoting.Host} host The host to connect to. * @param {string} localJid Local jid. - * @param {string} sharedSecret The access code for IT2Me or the PIN - * for Me2Me. - * @param {string} authenticationMethods Comma-separated list of - * authentication methods the client should attempt to use. - * @param {string} authenticationTag A host-specific tag to mix into - * authentication hashes. - * @param {string} clientPairingId For paired Me2Me connections, the - * pairing id for this client, as issued by the host. - * @param {string} clientPairedSecret For paired Me2Me connections, the - * paired secret for this client, as issued by the host. + * @param {remoting.CredentialsProvider} credentialsProvider */ -remoting.ClientPlugin.prototype.connect = function( - hostJid, hostPublicKey, localJid, sharedSecret, - authenticationMethods, authenticationTag, - clientPairingId, clientPairedSecret) {}; +remoting.ClientPlugin.prototype.connect = + function(host, localJid, credentialsProvider) {}; /** * @param {number} key The keycode to inject. @@ -98,11 +85,6 @@ function(mimeType, item) {}; /** - * Tell the plugin to request a PIN asynchronously. - */ -remoting.ClientPlugin.prototype.useAsyncPinDialog = function() {}; - -/** * Request that this client be paired with the current host. * * @param {string} clientName The human-readable name of the client. @@ -113,27 +95,11 @@ function(clientName, onDone) {}; /** - * Called when a PIN is obtained from the user. - * - * @param {string} pin The PIN. - */ -remoting.ClientPlugin.prototype.onPinFetched = function(pin) {}; - -/** * Allows automatic mouse-lock. */ remoting.ClientPlugin.prototype.allowMouseLock = function() {}; /** - * Sets the third party authentication token and shared secret. - * - * @param {string} token The token received from the token URL. - * @param {string} sharedSecret Shared secret received from the token URL. - */ -remoting.ClientPlugin.prototype.onThirdPartyTokenFetched = - function(token, sharedSecret) {}; - -/** * @param {boolean} pause True to pause the audio stream; false to resume it. */ remoting.ClientPlugin.prototype.pauseAudio = function(pause) {}; @@ -223,23 +189,6 @@ function(handler) {}; /** - * @param {function(string, string, string):void} handler Callback for - * fetching third-party tokens. The first parameter is the token URL; the - * second is the public key of the host; the third is the OAuth2 scope - * being requested. - */ -remoting.ClientPlugin.prototype.setFetchThirdPartyTokenHandler = - function(handler) {}; - -/** - * @param {function(boolean):void} handler Callback for fetching a PIN from - * the user. The parameter is true if PIN pairing is supported by the - * host, or false otherwise. - */ -remoting.ClientPlugin.prototype.setFetchPinHandler = - function(handler) {}; - -/** * @param {function({rects:Array<Array<number>>}):void|null} handler Callback * to receive dirty region information for each video frame, for debugging. */
diff --git a/remoting/webapp/crd/js/client_plugin_impl.js b/remoting/webapp/crd/js/client_plugin_impl.js index 2d3efe0..45b95ba 100644 --- a/remoting/webapp/crd/js/client_plugin_impl.js +++ b/remoting/webapp/crd/js/client_plugin_impl.js
@@ -77,22 +77,11 @@ * @private */ this.onConnectionReadyHandler_ = function(ready) {}; - - /** - * @param {string} tokenUrl Token-request URL, received from the host. - * @param {string} hostPublicKey Public key for the host. - * @param {string} scope OAuth scope to request the token for. - * @private - */ - this.fetchThirdPartyTokenHandler_ = function( - tokenUrl, hostPublicKey, scope) {}; /** * @param {!Array<string>} capabilities The negotiated capabilities. * @private */ this.onSetCapabilitiesHandler_ = function (capabilities) {}; - /** @private */ - this.fetchPinHandler_ = function (supportsPairing) {}; /** * @param {string} data Remote gnubbyd data. * @private @@ -168,6 +157,9 @@ this.hostDesktop_ = new remoting.ClientPlugin.HostDesktopImpl( this, this.postMessage_.bind(this)); + + /** @private {remoting.CredentialsProvider} */ + this.credentials_ = null; }; /** @@ -282,21 +274,6 @@ }; /** - * @param {function(string, string, string):void} handler - */ -remoting.ClientPluginImpl.prototype.setFetchThirdPartyTokenHandler = - function(handler) { - this.fetchThirdPartyTokenHandler_ = handler; -}; - -/** - * @param {function(boolean):void} handler - */ -remoting.ClientPluginImpl.prototype.setFetchPinHandler = function(handler) { - this.fetchPinHandler_ = handler; -}; - -/** * @param {?function({rects:Array<Array<number>>}):void} handler */ remoting.ClientPluginImpl.prototype.setDebugDirtyRegionHandler = @@ -436,9 +413,10 @@ // client and host support pairing. If the client doesn't support pairing, // then the value won't be there at all, so give it a default of false. var pairingSupported = getBooleanAttr(message.data, 'pairingSupported', - false) - this.fetchPinHandler_(pairingSupported); - + false); + this.credentials_.getPIN(pairingSupported).then( + this.onPinFetched_.bind(this) + ); } else if (message.method == 'setCapabilities') { /** @type {!Array<string>} */ var capabilities = tokenize(getStringAttr(message.data, 'capabilities')); @@ -448,8 +426,9 @@ var tokenUrl = getStringAttr(message.data, 'tokenUrl'); var hostPublicKey = getStringAttr(message.data, 'hostPublicKey'); var scope = getStringAttr(message.data, 'scope'); - this.fetchThirdPartyTokenHandler_(tokenUrl, hostPublicKey, scope); - + this.credentials_.getThirdPartyToken(tokenUrl, hostPublicKey, scope).then( + this.onThirdPartyTokenFetched_.bind(this) + ); } else if (message.method == 'pairingResponse') { var clientId = getStringAttr(message.data, 'clientId'); var sharedSecret = getStringAttr(message.data, 'sharedSecret'); @@ -590,25 +569,12 @@ }; /** - * @param {string} hostJid The jid of the host to connect to. - * @param {string} hostPublicKey The base64 encoded version of the host's - * public key. + * @param {remoting.Host} host The host to connect to. * @param {string} localJid Local jid. - * @param {string} sharedSecret The access code for IT2Me or the PIN - * for Me2Me. - * @param {string} authenticationMethods Comma-separated list of - * authentication methods the client should attempt to use. - * @param {string} authenticationTag A host-specific tag to mix into - * authentication hashes. - * @param {string} clientPairingId For paired Me2Me connections, the - * pairing id for this client, as issued by the host. - * @param {string} clientPairedSecret For paired Me2Me connections, the - * paired secret for this client, as issued by the host. + * @param {remoting.CredentialsProvider} credentialsProvider */ -remoting.ClientPluginImpl.prototype.connect = function( - hostJid, hostPublicKey, localJid, sharedSecret, - authenticationMethods, authenticationTag, - clientPairingId, clientPairedSecret) { +remoting.ClientPluginImpl.prototype.connect = + function(host, localJid, credentialsProvider) { var keyFilter = ''; if (remoting.platformIsMac()) { keyFilter = 'mac'; @@ -623,17 +589,20 @@ parseInt((remoting.getChromeVersion() || '0').split('.')[0], 10) >= 42; this.plugin_.postMessage(JSON.stringify( { method: 'delegateLargeCursors', data: {} })); + var methods = 'third_party,spake2_pair,spake2_hmac,spake2_plain'; + this.credentials_ = credentialsProvider; + this.useAsyncPinDialog_(); this.plugin_.postMessage(JSON.stringify( { method: 'connect', data: { - hostJid: hostJid, - hostPublicKey: hostPublicKey, + hostJid: host.jabberId, + hostPublicKey: host.publicKey, localJid: localJid, - sharedSecret: sharedSecret, - authenticationMethods: authenticationMethods, - authenticationTag: authenticationTag, + sharedSecret: '', + authenticationMethods: methods, + authenticationTag: host.hostId, capabilities: this.capabilities_.join(" "), - clientPairingId: clientPairingId, - clientPairedSecret: clientPairedSecret, + clientPairingId: credentialsProvider.getPairingInfo().id, + clientPairedSecret: credentialsProvider.getPairingInfo().secret, keyFilter: keyFilter, enableVideoDecodeRenderer: enableVideoDecodeRenderer } @@ -790,8 +759,9 @@ * Called when a PIN is obtained from the user. * * @param {string} pin The PIN. + * @private */ -remoting.ClientPluginImpl.prototype.onPinFetched = +remoting.ClientPluginImpl.prototype.onPinFetched_ = function(pin) { if (!this.hasFeature(remoting.ClientPlugin.Feature.ASYNC_PIN)) { return; @@ -802,8 +772,9 @@ /** * Tells the plugin to ask for the PIN asynchronously. + * @private */ -remoting.ClientPluginImpl.prototype.useAsyncPinDialog = +remoting.ClientPluginImpl.prototype.useAsyncPinDialog_ = function() { if (!this.hasFeature(remoting.ClientPlugin.Feature.ASYNC_PIN)) { return; @@ -823,14 +794,14 @@ /** * Sets the third party authentication token and shared secret. * - * @param {string} token The token received from the token URL. - * @param {string} sharedSecret Shared secret received from the token URL. + * @param {remoting.ThirdPartyToken} token + * @private */ -remoting.ClientPluginImpl.prototype.onThirdPartyTokenFetched = function( - token, sharedSecret) { +remoting.ClientPluginImpl.prototype.onThirdPartyTokenFetched_ = function( + token) { this.plugin_.postMessage(JSON.stringify( { method: 'onThirdPartyTokenFetched', - data: { token: token, sharedSecret: sharedSecret}})); + data: { token: token.token, sharedSecret: token.secret}})); }; /**
diff --git a/remoting/webapp/crd/js/client_session.js b/remoting/webapp/crd/js/client_session.js index dc2a2a9..3d4753b 100644 --- a/remoting/webapp/crd/js/client_session.js +++ b/remoting/webapp/crd/js/client_session.js
@@ -34,31 +34,17 @@ /** * @param {remoting.Host} host The host to connect to. * @param {remoting.SignalStrategy} signalStrategy Signal strategy. + * @param {remoting.CredentialsProvider} credentialsProvider + * The credentialsProvider to authenticate the client with the host. * @param {HTMLElement} container Container element for the client view. - * @param {string} accessCode The IT2Me access code. Blank for Me2Me. - * @param {function(boolean, function(string): void): void} fetchPin - * Called by Me2Me connections when a PIN needs to be obtained - * interactively. - * @param {function(string, string, string, - * function(string, string): void): void} - * fetchThirdPartyToken Called by Me2Me connections when a third party - * authentication token must be obtained. - * @param {string} authenticationMethods Comma-separated list of - * authentication methods the client should attempt to use. * @param {remoting.DesktopConnectedView.Mode} mode The mode of this connection. - * @param {string} clientPairingId For paired Me2Me connections, the - * pairing id for this client, as issued by the host. - * @param {string} clientPairedSecret For paired Me2Me connections, the - * paired secret for this client, as issued by the host. * @param {string} defaultRemapKeys The default set of remap keys, to use * when the client doesn't define any. * @constructor * @extends {base.EventSourceImpl} */ -remoting.ClientSession = function(host, signalStrategy, container, accessCode, - fetchPin, fetchThirdPartyToken, - authenticationMethods, mode, clientPairingId, - clientPairedSecret, defaultRemapKeys) { +remoting.ClientSession = function(host, signalStrategy, credentialsProvider, + container, mode, defaultRemapKeys) { /** @private */ this.state_ = remoting.ClientSession.State.CREATED; @@ -67,18 +53,9 @@ /** @private */ this.host_ = host; + /** @private */ - this.accessCode_ = accessCode; - /** @private */ - this.fetchPin_ = fetchPin; - /** @private */ - this.fetchThirdPartyToken_ = fetchThirdPartyToken; - /** @private */ - this.authenticationMethods_ = authenticationMethods; - /** @private */ - this.clientPairingId_ = clientPairingId; - /** @private */ - this.clientPairedSecret_ = clientPairedSecret; + this.credentialsProvider_ = credentialsProvider; /** @private */ this.uiHandler_ = new remoting.DesktopConnectedView( @@ -310,7 +287,8 @@ plugin.setCastExtensionHandler( this.processCastExtensionMessage_.bind(this)); - this.initiateConnection_(); + this.plugin_.connect( + this.host_, this.signalStrategy_.getJid(), this.credentialsProvider_); }; /** @@ -321,7 +299,7 @@ this.removePlugin(); this.error_ = error; this.setState_(remoting.ClientSession.State.FAILED); -} +}; /** * Deletes the <embed> element from the container, without sending a @@ -460,64 +438,6 @@ }; /** - * @private - */ -remoting.ClientSession.prototype.initiateConnection_ = function() { - /** @type {remoting.ClientSession} */ - var that = this; - - /** @param {string} sharedSecret Shared secret. */ - function onSharedSecretReceived(sharedSecret) { - that.plugin_.connect(that.host_.jabberId, that.host_.publicKey, - that.signalStrategy_.getJid(), sharedSecret, - that.authenticationMethods_, that.host_.hostId, - that.clientPairingId_, that.clientPairedSecret_); - } - - this.getSharedSecret_(onSharedSecretReceived); -}; - -/** - * Gets shared secret to be used for connection. - * - * @param {function(string)} callback Callback called with the shared secret. - * @return {void} Nothing. - * @private - */ -remoting.ClientSession.prototype.getSharedSecret_ = function(callback) { - /** @type remoting.ClientSession */ - var that = this; - if (this.plugin_.hasFeature(remoting.ClientPlugin.Feature.THIRD_PARTY_AUTH)) { - /** @type{function(string, string, string): void} */ - var fetchThirdPartyToken = function(tokenUrl, hostPublicKey, scope) { - that.fetchThirdPartyToken_( - tokenUrl, hostPublicKey, scope, - that.plugin_.onThirdPartyTokenFetched.bind(that.plugin_)); - }; - this.plugin_.setFetchThirdPartyTokenHandler(fetchThirdPartyToken); - } - if (this.accessCode_) { - // Shared secret was already supplied before connecting (It2Me case). - callback(this.accessCode_); - } else if (this.plugin_.hasFeature( - remoting.ClientPlugin.Feature.ASYNC_PIN)) { - // Plugin supports asynchronously asking for the PIN. - this.plugin_.useAsyncPinDialog(); - /** @param {boolean} pairingSupported */ - var fetchPin = function(pairingSupported) { - that.fetchPin_(pairingSupported, - that.plugin_.onPinFetched.bind(that.plugin_)); - }; - this.plugin_.setFetchPinHandler(fetchPin); - callback(''); - } else { - // Clients that don't support asking for a PIN asynchronously also don't - // support pairing, so request the PIN now without offering to remember it. - this.fetchPin_(false, callback); - } -}; - -/** * Callback that the plugin invokes to indicate that the connection * status has changed. *
diff --git a/remoting/webapp/crd/js/credentials_provider.js b/remoting/webapp/crd/js/credentials_provider.js new file mode 100644 index 0000000..b1d9e20 --- /dev/null +++ b/remoting/webapp/crd/js/credentials_provider.js
@@ -0,0 +1,100 @@ +// 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. + +'use strict'; + +var remoting = remoting || {}; + +/** @typedef {{id: string, secret: string}} */ +remoting.PairingInfo; + +/** @typedef {{token: string, secret: string}} */ +remoting.ThirdPartyToken; + +/** + * Parameters for the remoting.CredentialsProvider constructor. + * + * fetchPin: Called by Me2Me connections when a PIN needs to be obtained + * interactively. + * + * pairingInfo: The pairing info for Me2Me Connections. + * + * accessCode: It2Me access code. If present, the |fetchPin| callback will be + * ignored. + * + * fetchThirdPartyToken: Called when a third party authentication token + * is needed + * + * @typedef {{ + * accessCode: (string|undefined), + * fetchPin: (function(boolean,function(string): void)|undefined), + * pairingInfo: (remoting.PairingInfo|undefined), + * fetchThirdPartyToken: + * (function(string ,string , string, + * function(string, string):void) | undefined) + * }} + */ +remoting.CredentialsProviderParams; + +/** + * @param {remoting.CredentialsProviderParams} args + * @constructor + */ +remoting.CredentialsProvider = function(args) { + /** @private */ + this.fetchPin_ = (args.accessCode) ? this.getAccessCode_ : args.fetchPin; + /** @private */ + this.pairingInfo_ = args.pairingInfo; + /** @private */ + this.accessCode_ = args.accessCode; + /** @private */ + this.fetchThirdPartyToken_ = args.fetchThirdPartyToken; +}; + +/** @returns {void} */ +remoting.CredentialsProvider.prototype.getAccessCode_ = function( + /** boolean */ supportsPairing, /** Function */ callback) { + callback(this.accessCode_); +}; + +/** @returns {remoting.PairingInfo} */ +remoting.CredentialsProvider.prototype.getPairingInfo = function() { + return this.pairingInfo_ || { id: '', secret: ''}; +}; + +/** + * @param {boolean} pairingSupported Whether pairing is supported by the host. + * @returns {Promise<string>} + */ +remoting.CredentialsProvider.prototype.getPIN = function(pairingSupported) { + var that = this; + if (!this.fetchPin_) { + Promise.resolve(''); + } + return new Promise(function(/** function(string) */ resolve) { + that.fetchPin_(pairingSupported, resolve); + }); +}; + +/** + * @param {string} tokenUrl Token-issue URL received from the host. + * @param {string} hostPublicKey Host public key (DER and Base64 encoded). + * @param {string} scope OAuth scope to request the token for. + * + * @returns {Promise<remoting.ThirdPartyToken>} + */ +remoting.CredentialsProvider.prototype.getThirdPartyToken = function( + tokenUrl, hostPublicKey, scope) { + var that = this; + if (!this.fetchThirdPartyToken_) { + Promise.resolve({token: '', secret: ''}); + } + return new Promise(function(/** Function */ resolve) { + var onTokenFetched = function(/** string */ token, /** string */ secret) { + resolve({token: token, secret: secret}); + }; + that.fetchThirdPartyToken_(tokenUrl, hostPublicKey, scope, onTokenFetched); + }); +}; +
diff --git a/remoting/webapp/crd/js/fallback_signal_strategy.js b/remoting/webapp/crd/js/fallback_signal_strategy.js index 030bfb42..f250144 100644 --- a/remoting/webapp/crd/js/fallback_signal_strategy.js +++ b/remoting/webapp/crd/js/fallback_signal_strategy.js
@@ -112,16 +112,10 @@ /** * @type {Array<{strategyType: remoting.SignalStrategy.Type, - progress: remoting.FallbackSignalStrategy.Progress, - * elapsed: number}>} + progress: remoting.FallbackSignalStrategy.Progress}>} */ this.connectionSetupResults_ = []; - /** - * @type {number} - * @private - */ - this.startTime_ = 0; }; /** @@ -178,7 +172,6 @@ this.username_ = username; this.authToken_ = authToken; this.state_ = this.State.PRIMARY_PENDING; - this.startTime_ = new Date().getTime(); this.primary_.setIncomingStanzaCallback(this.onIncomingStanzaCallback_); this.primary_.connect(server, username, authToken); this.primaryConnectTimerId_ = @@ -211,8 +204,7 @@ for (var i = 0; i < this.connectionSetupResults_.length; ++i) { var result = this.connectionSetupResults_[i]; this.logToServer_.logSignalStrategyProgress(result.strategyType, - result.progress, - result.elapsed); + result.progress); } this.connectionSetupResults_ = []; }; @@ -391,8 +383,7 @@ progress); this.connectionSetupResults_.push({ 'strategyType': strategy.getType(), - 'progress': progress, - 'elapsed': new Date().getTime() - this.startTime_ + 'progress': progress }); if (this.logToServer_) { this.sendConnectionSetupResultsInternal_();
diff --git a/remoting/webapp/crd/js/host_controller.js b/remoting/webapp/crd/js/host_controller.js index 4a37ee2..17e29edd 100644 --- a/remoting/webapp/crd/js/host_controller.js +++ b/remoting/webapp/crd/js/host_controller.js
@@ -184,16 +184,18 @@ private_key: privateKey }; var hostOwner = clientBaseJid; - var hostOwnerEmail = remoting.identity.getCachedEmail(); - if (hostOwner != xmppLogin) { - hostConfig['host_owner'] = hostOwner; - if (hostOwnerEmail != hostOwner) { - hostConfig['host_owner_email'] = hostOwnerEmail; - } - } - that.hostDaemonFacade_.startDaemon( - hostConfig, consent, onStarted.bind(null, hostName, publicKey), - onStartError); + remoting.identity.getEmail().then( + function(/** string */ hostOwnerEmail) { + if (hostOwner != xmppLogin) { + hostConfig['host_owner'] = hostOwner; + if (hostOwnerEmail != hostOwner) { + hostConfig['host_owner_email'] = hostOwnerEmail; + } + } + that.hostDaemonFacade_.startDaemon( + hostConfig, consent, onStarted.bind(null, hostName, publicKey), + onStartError); + }); } /** @@ -248,13 +250,14 @@ onError); } else { // No authorization code returned, use regular user credential flow. - that.hostDaemonFacade_.getPinHash( - newHostId, hostPin, startHostWithHash.bind( - null, hostName, publicKey, privateKey, - remoting.identity.getCachedEmail(), - remoting.oauth2.getRefreshToken(), - remoting.identity.getCachedEmail()), - onError); + remoting.identity.getEmail().then( + function(/** string */ email) { + that.hostDaemonFacade_.getPinHash( + newHostId, hostPin, startHostWithHash.bind( + null, hostName, publicKey, privateKey, + email, remoting.oauth2.getRefreshToken(), email), + onError); + }); } } else { console.log('Failed to register the host. Status: ' + xhr.status +
diff --git a/remoting/webapp/crd/js/host_screen.js b/remoting/webapp/crd/js/host_screen.js index 183deb7f..cb3695d 100644 --- a/remoting/webapp/crd/js/host_screen.js +++ b/remoting/webapp/crd/js/host_screen.js
@@ -94,10 +94,12 @@ base.debug.assert(hostSession_ === null); hostSession_ = new remoting.HostSession(); - var email = /** @type {string} */ (remoting.identity.getCachedEmail()); - hostSession_.connect( - hostFacade, email, token, onHostStateChanged_, - onNatTraversalPolicyChanged_, logDebugInfo_, it2meConnectFailed_); + remoting.identity.getEmail().then( + function(/** string */ email) { + hostSession_.connect( + hostFacade, email, token, onHostStateChanged_, + onNatTraversalPolicyChanged_, logDebugInfo_, it2meConnectFailed_); + }); }; /** @@ -336,4 +338,4 @@ } } -})(); \ No newline at end of file +})();
diff --git a/remoting/webapp/crd/js/identity.js b/remoting/webapp/crd/js/identity.js index b2f2c5a3..dfa7f987 100644 --- a/remoting/webapp/crd/js/identity.js +++ b/remoting/webapp/crd/js/identity.js
@@ -13,9 +13,6 @@ var remoting = remoting || {}; /** - * TODO(jamiewalch): Remove remoting.OAuth2 from this type annotation when - * the Apps v2 work is complete. - * * @type {remoting.Identity} */ remoting.identity = null; @@ -163,29 +160,6 @@ }; /** - * Gets the user's email address, or null if no successful call to - * getUserInfo has been made. - * - * @return {?string} The cached email address, if available. - */ -remoting.Identity.prototype.getCachedEmail = function() { - return this.email_; -}; - -/** - * Gets the user's full name. - * - * This will return null if either: - * No successful call to getUserInfo has been made, or - * The webapp doesn't have permission to access this value. - * - * @return {?string} The cached user's full name, if available. - */ -remoting.Identity.prototype.getCachedUserFullName = function() { - return this.fullName_; -}; - -/** * Callback for the getAuthToken API. * * @param {boolean} interactive The value of the "interactive" parameter to
diff --git a/remoting/webapp/crd/js/log_to_server.js b/remoting/webapp/crd/js/log_to_server.js index 8b87f1b5c..d76b33f 100644 --- a/remoting/webapp/crd/js/log_to_server.js +++ b/remoting/webapp/crd/js/log_to_server.js
@@ -25,7 +25,7 @@ /** @private */ this.sessionIdGenerationTime_ = 0; /** @private */ - this.sessionStartTime_ = 0; + this.sessionStartTime_ = new Date().getTime(); /** @private */ this.signalStrategy_ = signalStrategy; /** @private */ @@ -60,12 +60,6 @@ remoting.LogToServer.prototype.logClientSessionStateChange = function(state, connectionError) { this.maybeExpireSessionId_(); - // Set the session start time if we haven't done so already. - if (remoting.LogToServer.isStartOfSession_(state)) { - if (this.sessionStartTime_ == 0) { - this.sessionStartTime_ = new Date().getTime(); - } - } // Log the session state change. var entry = remoting.ServerLogEntry.makeClientSessionStateChange( state, connectionError, this.mode_); @@ -73,15 +67,6 @@ entry.addChromeVersionField(); entry.addWebappVersionField(); entry.addSessionIdField(this.sessionId_); - // Maybe clear the session start time, and log the session duration. - if (remoting.LogToServer.shouldAddDuration_(state) && - (this.sessionStartTime_ != 0)) { - entry.addSessionDurationField( - (new Date().getTime() - this.sessionStartTime_) / 1000.0); - if (remoting.LogToServer.isEndOfSession_(state)) { - this.sessionStartTime_ = 0; - } - } this.log_(entry); // Don't accumulate connection statistics across state changes. this.logAccumulatedStatistics_(); @@ -104,13 +89,12 @@ /** * @param {remoting.SignalStrategy.Type} strategyType * @param {remoting.FallbackSignalStrategy.Progress} progress - * @param {number} elapsedTimeInMs */ remoting.LogToServer.prototype.logSignalStrategyProgress = - function(strategyType, progress, elapsedTimeInMs) { + function(strategyType, progress) { this.maybeExpireSessionId_(); var entry = remoting.ServerLogEntry.makeSignalStrategyProgress( - this.sessionId_, strategyType, progress, elapsedTimeInMs); + this.sessionId_, strategyType, progress); this.log_(entry); }; @@ -143,20 +127,6 @@ (state == remoting.ClientSession.State.CONNECTION_CANCELED)); }; -/** - * Whether the duration should be added to the log entry for this state. - * - * @private - * @param {remoting.ClientSession.State} state - * @return {boolean} - */ -remoting.LogToServer.shouldAddDuration_ = function(state) { - // Duration is added to log entries at the end of the session, as well as at - // some intermediate states where it is relevant (e.g. to determine how long - // it took for a session to become CONNECTED). - return (remoting.LogToServer.isEndOfSession_(state) || - (state == remoting.ClientSession.State.CONNECTED)); -}; /** * Logs connection statistics. @@ -203,6 +173,10 @@ * @param {remoting.ServerLogEntry} entry */ remoting.LogToServer.prototype.log_ = function(entry) { + // Log the time taken to get to this point from the time this session started. + var elapsedTimeInMs = new Date().getTime() - this.sessionStartTime_; + entry.addElapsedTimeMs(elapsedTimeInMs); + // Send the stanza to the debug log. console.log('Enqueueing log entry:'); entry.toDebugLog(1);
diff --git a/remoting/webapp/crd/js/oauth2.js b/remoting/webapp/crd/js/oauth2.js index 1074ed2..0ad1f7a7 100644 --- a/remoting/webapp/crd/js/oauth2.js +++ b/remoting/webapp/crd/js/oauth2.js
@@ -23,7 +23,10 @@ remoting.oauth2 = null; -/** @constructor */ +/** + * @constructor + * @extends {remoting.Identity} + */ remoting.OAuth2 = function() { }; @@ -445,31 +448,3 @@ reject); }); }; - -/** - * If the user's email address is cached, return it, otherwise return null. - * - * @return {?string} The email address, if it has been cached by a previous call - * to getEmail or getUserInfo, otherwise null. - */ -remoting.OAuth2.prototype.getCachedEmail = function() { - var value = window.localStorage.getItem(this.KEY_EMAIL_); - if (typeof value == 'string') { - return value; - } - return null; -}; - -/** - * If the user's full name is cached, return it, otherwise return null. - * - * @return {?string} The user's full name, if it has been cached by a previous - * call to getUserInfo, otherwise null. - */ -remoting.OAuth2.prototype.getCachedUserFullName = function() { - var value = window.localStorage.getItem(this.KEY_FULLNAME_); - if (typeof value == 'string') { - return value; - } - return null; -};
diff --git a/remoting/webapp/crd/js/server_log_entry.js b/remoting/webapp/crd/js/server_log_entry.js index 7d848aa5..02e6feb 100644 --- a/remoting/webapp/crd/js/server_log_entry.js +++ b/remoting/webapp/crd/js/server_log_entry.js
@@ -47,8 +47,8 @@ remoting.ServerLogEntry.KEY_SIGNAL_STRATEGY_PROGRESS_ = 'signal-strategy-progress'; /** @private */ -remoting.ServerLogEntry.KEY_SIGNAL_STRATEGY_ELAPSED_TIME_ = - 'signal-strategy-elapsed-time'; +remoting.ServerLogEntry.KEY_ELAPSED_TIME_MS_ = 'elapsed-time'; + /** * @private @@ -119,8 +119,6 @@ } }; -/** @private */ -remoting.ServerLogEntry.KEY_SESSION_DURATION_ = 'session-duration'; /** @private */ remoting.ServerLogEntry.VALUE_EVENT_NAME_CONNECTION_STATISTICS_ = @@ -242,17 +240,6 @@ }; /** - * Adds a session duration to a log entry. - * - * @param {number} sessionDuration - */ -remoting.ServerLogEntry.prototype.addSessionDurationField = function( - sessionDuration) { - this.set_(remoting.ServerLogEntry.KEY_SESSION_DURATION_, - sessionDuration.toString()); -}; - -/** * Makes a log entry for a set of connection statistics. * Returns null if all the statistics were zero. * @@ -357,11 +344,10 @@ * @param {string} sessionId * @param {remoting.SignalStrategy.Type} strategyType * @param {remoting.FallbackSignalStrategy.Progress} progress - * @param {number} elapsedTimeInMs * @return {remoting.ServerLogEntry} */ remoting.ServerLogEntry.makeSignalStrategyProgress = - function(sessionId, strategyType, progress, elapsedTimeInMs) { + function(sessionId, strategyType, progress) { var entry = new remoting.ServerLogEntry(); entry.set_(remoting.ServerLogEntry.KEY_ROLE_, remoting.ServerLogEntry.VALUE_ROLE_CLIENT_); @@ -371,8 +357,6 @@ entry.addSessionIdField(sessionId); entry.set_(remoting.ServerLogEntry.KEY_SIGNAL_STRATEGY_TYPE_, strategyType); entry.set_(remoting.ServerLogEntry.KEY_SIGNAL_STRATEGY_PROGRESS_, progress); - entry.set_(remoting.ServerLogEntry.KEY_SIGNAL_STRATEGY_ELAPSED_TIME_, - String(elapsedTimeInMs)); return entry; }; @@ -467,6 +451,18 @@ }; /** + * Adds a field to this log entry specifying the elapsed time since the start of + * the session to the current session state. + * @param {number} elapsedTimeInMs + */ +remoting.ServerLogEntry.prototype.addElapsedTimeMs = + function(elapsedTimeInMs) { + this.set_(remoting.ServerLogEntry.KEY_ELAPSED_TIME_MS_, + String(elapsedTimeInMs)); +}; + + +/** * Adds a field specifying the browser version to this log entry. */ remoting.ServerLogEntry.prototype.addChromeVersionField = function() {
diff --git a/remoting/webapp/crd/js/session_connector_impl.js b/remoting/webapp/crd/js/session_connector_impl.js index a89fdd4f1..fdbd6f0 100644 --- a/remoting/webapp/crd/js/session_connector_impl.js +++ b/remoting/webapp/crd/js/session_connector_impl.js
@@ -117,32 +117,6 @@ */ remoting.SessionConnectorImpl.prototype.reset = function() { /** - * For paired connections, the client id of this device, issued by the host. - * - * @type {string} - * @private - */ - this.clientPairingId_ = ''; - - /** - * For paired connections, the paired secret for this device, issued by the - * host. - * - * @type {string} - * @private - */ - this.clientPairedSecret_ = ''; - - /** - * String used to authenticate to the host on connection. For IT2Me, this is - * the access code; for Me2Me it is the PIN. - * - * @type {string} - * @private - */ - this.passPhrase_ = ''; - - /** * @type {remoting.Host} * @private */ @@ -167,19 +141,10 @@ this.pendingXhr_ = null; /** - * Function to interactively obtain the PIN from the user. - * @type {function(boolean, function(string):void):void} + * @type {remoting.CredentialsProvider} * @private */ - this.fetchPin_ = function(onPinFetched) {}; - - /** - * @type {function(string, string, string, - * function(string, string):void): void} - * @private - */ - this.fetchThirdPartyToken_ = function( - tokenUrl, hostPublicKey, scope, onThirdPartyTokenFetched) {}; + this.credentialsProvider_ = null; }; /** @@ -191,10 +156,6 @@ * @param {remoting.Host} host The Me2Me host to which to connect. * @param {function(boolean, function(string):void):void} fetchPin Function to * interactively obtain the PIN from the user. - * @param {function(string, string, string, - * function(string, string): void): void} - * fetchThirdPartyToken Function to obtain a token from a third party - * authentication server. * @param {string} clientPairingId The client id issued by the host when * this device was paired, if it is already paired. * @param {string} clientPairedSecret The shared secret issued by the host when @@ -206,8 +167,12 @@ clientPairingId, clientPairedSecret) { this.connectionMode_ = remoting.DesktopConnectedView.Mode.ME2ME; this.logHostOfflineErrors_ = false; - this.connectMe2MeInternal_(host, fetchPin, fetchThirdPartyToken, - clientPairingId, clientPairedSecret); + var credentialsProvider = new remoting.CredentialsProvider({ + fetchPin: fetchPin, + pairingInfo: { id: clientPairingId, secret: clientPairedSecret }, + fetchThirdPartyToken: fetchThirdPartyToken + }); + this.connectInternal_(host, credentialsProvider); }; /** @@ -222,8 +187,7 @@ remoting.SessionConnectorImpl.prototype.retryConnectMe2Me = function(host) { this.connectionMode_ = remoting.DesktopConnectedView.Mode.ME2ME; this.logHostOfflineErrors_ = true; - this.connectMe2MeInternal_(host, this.fetchPin_, this.fetchThirdPartyToken_, - this.clientPairingId_, this.clientPairedSecret_); + this.connectInternal_(host, this.credentialsProvider_); }; /** @@ -240,7 +204,10 @@ function(host, fetchThirdPartyToken) { this.connectionMode_ = remoting.DesktopConnectedView.Mode.APP_REMOTING; this.logHostOfflineErrors_ = true; - this.connectMe2MeInternal_(host, function() {}, fetchThirdPartyToken, '', ''); + var credentialsProvider = new remoting.CredentialsProvider({ + fetchThirdPartyToken : fetchThirdPartyToken + }); + this.connectInternal_(host, credentialsProvider); }; /** @@ -251,38 +218,26 @@ */ remoting.SessionConnectorImpl.prototype.updatePairingInfo = function(clientId, sharedSecret) { - this.clientPairingId_ = clientId; - this.clientPairedSecret_ = sharedSecret; + var pairingInfo = this.credentialsProvider_.getPairingInfo(); + pairingInfo.id = clientId; + pairingInfo.secret = sharedSecret; }; /** - * Initiate a Me2Me connection. + * Initiates a connection. * * @param {remoting.Host} host the Host to connect to. - * @param {function(boolean, function(string):void):void} fetchPin Function to - * interactively obtain the PIN from the user. - * @param {function(string, string, string, - * function(string, string): void): void} - * fetchThirdPartyToken Function to obtain a token from a third party - * authentication server. - * @param {string} clientPairingId The client id issued by the host when - * this device was paired, if it is already paired. - * @param {string} clientPairedSecret The shared secret issued by the host when - * this device was paired, if it is already paired. + * @param {remoting.CredentialsProvider} credentialsProvider * @return {void} Nothing. * @private */ -remoting.SessionConnectorImpl.prototype.connectMe2MeInternal_ = - function(host, fetchPin, fetchThirdPartyToken, - clientPairingId, clientPairedSecret) { +remoting.SessionConnectorImpl.prototype.connectInternal_ = + function(host, credentialsProvider) { // Cancel any existing connect operation. this.cancel(); this.host_ = host; - this.fetchPin_ = fetchPin; - this.fetchThirdPartyToken_ = fetchThirdPartyToken; - this.updatePairingInfo(clientPairingId, clientPairedSecret); - + this.credentialsProvider_ = credentialsProvider; this.connectSignaling_(); }; @@ -305,9 +260,10 @@ this.onError_(remoting.Error.INVALID_ACCESS_CODE); return; } - var hostId = normalizedAccessCode.substring(0, kSupportIdLen); - this.passPhrase_ = normalizedAccessCode; + this.credentialsProvider_ = new remoting.CredentialsProvider({ + accessCode: normalizedAccessCode + }); this.connectionMode_ = remoting.DesktopConnectedView.Mode.IT2ME; remoting.identity.getToken().then( this.connectIT2MeWithToken_.bind(this, hostId), @@ -325,9 +281,7 @@ return; } this.logHostOfflineErrors_ = false; - this.connectMe2MeInternal_(this.host_, this.fetchPin_, - this.fetchThirdPartyToken_, this.clientPairingId_, - this.clientPairedSecret_); + this.connectInternal_(this.host_, this.credentialsProvider_); }; /** @@ -484,13 +438,9 @@ this.clientSession_ = null; } - var authenticationMethods = - 'third_party,spake2_pair,spake2_hmac,spake2_plain'; this.clientSession_ = new remoting.ClientSession( - this.host_, this.signalStrategy_, this.clientContainer_, this.passPhrase_, - this.fetchPin_, this.fetchThirdPartyToken_, authenticationMethods, - this.connectionMode_, this.clientPairingId_, this.clientPairedSecret_, - this.defaultRemapKeys_); + this.host_, this.signalStrategy_, this.credentialsProvider_, + this.clientContainer_, this.connectionMode_, this.defaultRemapKeys_); this.clientSession_.logHostOfflineErrors(this.logHostOfflineErrors_); this.clientSession_.addEventListener( remoting.ClientSession.Events.stateChanged, @@ -533,7 +483,10 @@ break; case remoting.ClientSession.State.CONNECTING: - console.log('Connecting as ' + remoting.identity.getCachedEmail()); + remoting.identity.getEmail().then( + function(/** string */ email) { + console.log('Connecting as ' + email); + }); break; case remoting.ClientSession.State.INITIALIZING:
diff --git a/remoting/webapp/crd/js/xmpp_login_handler.js b/remoting/webapp/crd/js/xmpp_login_handler.js index 74be464..f91ef55 100644 --- a/remoting/webapp/crd/js/xmpp_login_handler.js +++ b/remoting/webapp/crd/js/xmpp_login_handler.js
@@ -65,6 +65,12 @@ this.streamParser_ = null; } +/** @return {function(string, remoting.XmppStreamParser):void} */ +remoting.XmppLoginHandler.prototype.getHandshakeDoneCallbackForTesting = + function() { + return this.onHandshakeDoneCallback_; +}; + /** * States the handshake goes through. States are iterated from INIT to DONE * sequentially, except for ERROR state which may be accepted at any point.
diff --git a/remoting/webapp/js_proto/chrome_cast_proto.js b/remoting/webapp/js_proto/chrome_cast_proto.js new file mode 100644 index 0000000..58fa914 --- /dev/null +++ b/remoting/webapp/js_proto/chrome_cast_proto.js
@@ -0,0 +1,129 @@ +// 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. + +// This file contains various hacks needed to inform JSCompiler of various +// WebKit- and Chrome-specific properties and methods. It is used only with +// JSCompiler to verify the type-correctness of our code. + +/** @type {Object} */ +chrome.cast = {}; + +/** @constructor */ +chrome.cast.AutoJoinPolicy = function() {}; + +/** @type {chrome.cast.AutoJoinPolicy} */ +chrome.cast.AutoJoinPolicy.PAGE_SCOPED; + +/** @type {chrome.cast.AutoJoinPolicy} */ +chrome.cast.AutoJoinPolicy.ORIGIN_SCOPED; + +/** @type {chrome.cast.AutoJoinPolicy} */ +chrome.cast.AutoJoinPolicy.TAB_AND_ORIGIN_SCOPED; + +/** @constructor */ +chrome.cast.DefaultActionPolicy = function() {}; + +/** @type {chrome.cast.DefaultActionPolicy} */ +chrome.cast.DefaultActionPolicy.CAST_THIS_TAB; + +/** @type {chrome.cast.DefaultActionPolicy} */ +chrome.cast.DefaultActionPolicy.CREATE_SESSION; + +/** @constructor */ +chrome.cast.Error = function() {}; + +/** @constructor */ +chrome.cast.ReceiverAvailability = function() {}; + +/** @type {chrome.cast.ReceiverAvailability} */ +chrome.cast.ReceiverAvailability.AVAILABLE; + +/** @type {chrome.cast.ReceiverAvailability} */ +chrome.cast.ReceiverAvailability.UNAVAILABLE; + +/** @type {Object} */ +chrome.cast.media = {}; + +/** @constructor */ +chrome.cast.media.Media = function() { + /** @type {number} */ + this.mediaSessionId = 0; +}; + +/** @constructor */ +chrome.cast.Session = function() { + /** @type {Array<chrome.cast.media.Media>} */ + this.media = []; + + /** @type {string} */ + this.sessionId = ''; +}; + +/** + * @param {string} namespace + * @param {Object} message + * @param {function():void} successCallback + * @param {function(chrome.cast.Error):void} errorCallback + */ +chrome.cast.Session.prototype.sendMessage = + function(namespace, message, successCallback, errorCallback) {}; + +/** + * @param {function(chrome.cast.media.Media):void} listener + */ +chrome.cast.Session.prototype.addMediaListener = function(listener) {}; + +/** + * @param {function(boolean):void} listener + */ +chrome.cast.Session.prototype.addUpdateListener = function(listener) {}; + +/** + * @param {string} namespace + * @param {function(string, string):void} listener + */ +chrome.cast.Session.prototype.addMessageListener = + function(namespace, listener){}; + +/** + * @param {function():void} successCallback + * @param {function(chrome.cast.Error):void} errorCallback + */ +chrome.cast.Session.prototype.stop = + function(successCallback, errorCallback) {}; + +/** + * @constructor + * @param {string} applicationID + */ +chrome.cast.SessionRequest = function(applicationID) {}; + +/** + * @constructor + * @param {chrome.cast.SessionRequest} sessionRequest + * @param {function(chrome.cast.Session):void} sessionListener + * @param {function(chrome.cast.ReceiverAvailability):void} receiverListener + * @param {chrome.cast.AutoJoinPolicy=} opt_autoJoinPolicy + * @param {chrome.cast.DefaultActionPolicy=} opt_defaultActionPolicy + */ +chrome.cast.ApiConfig = function(sessionRequest, + sessionListener, + receiverListener, + opt_autoJoinPolicy, + opt_defaultActionPolicy) {}; + +/** + * @param {chrome.cast.ApiConfig} apiConfig + * @param {function():void} onInitSuccess + * @param {function(chrome.cast.Error):void} onInitError + */ +chrome.cast.initialize = + function(apiConfig, onInitSuccess, onInitError) {}; + +/** + * @param {function(chrome.cast.Session):void} successCallback + * @param {function(chrome.cast.Error):void} errorCallback + */ +chrome.cast.requestSession = + function(successCallback, errorCallback) {};
diff --git a/remoting/webapp/js_proto/chrome_event_proto.js b/remoting/webapp/js_proto/chrome_event_proto.js new file mode 100644 index 0000000..317f711f --- /dev/null +++ b/remoting/webapp/js_proto/chrome_event_proto.js
@@ -0,0 +1,12 @@ +// 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. + +/** @constructor */ +chrome.Event = function() {}; + +/** @param {Function} callback */ +chrome.Event.prototype.addListener = function(callback) {}; + +/** @param {Function} callback */ +chrome.Event.prototype.removeListener = function(callback) {};
diff --git a/remoting/webapp/js_proto/chrome_proto.js b/remoting/webapp/js_proto/chrome_proto.js index afa0d03..6ecead2 100644 --- a/remoting/webapp/js_proto/chrome_proto.js +++ b/remoting/webapp/js_proto/chrome_proto.js
@@ -6,15 +6,6 @@ // WebKit- and Chrome-specific properties and methods. It is used only with // JSCompiler to verify the type-correctness of our code. -/** @constructor */ -chrome.Event = function() {}; - -/** @param {Function} callback */ -chrome.Event.prototype.addListener = function(callback) {}; - -/** @param {Function} callback */ -chrome.Event.prototype.removeListener = function(callback) {}; - /** @type {Object} */ chrome.app = {}; @@ -438,128 +429,6 @@ } /** @type {Object} */ -chrome.cast = {}; - -/** @constructor */ -chrome.cast.AutoJoinPolicy = function() {}; - -/** @type {chrome.cast.AutoJoinPolicy} */ -chrome.cast.AutoJoinPolicy.PAGE_SCOPED; - -/** @type {chrome.cast.AutoJoinPolicy} */ -chrome.cast.AutoJoinPolicy.ORIGIN_SCOPED; - -/** @type {chrome.cast.AutoJoinPolicy} */ -chrome.cast.AutoJoinPolicy.TAB_AND_ORIGIN_SCOPED; - -/** @constructor */ -chrome.cast.DefaultActionPolicy = function() {}; - -/** @type {chrome.cast.DefaultActionPolicy} */ -chrome.cast.DefaultActionPolicy.CAST_THIS_TAB; - -/** @type {chrome.cast.DefaultActionPolicy} */ -chrome.cast.DefaultActionPolicy.CREATE_SESSION; - -/** @constructor */ -chrome.cast.Error = function() {}; - -/** @constructor */ -chrome.cast.ReceiverAvailability = function() {}; - -/** @type {chrome.cast.ReceiverAvailability} */ -chrome.cast.ReceiverAvailability.AVAILABLE; - -/** @type {chrome.cast.ReceiverAvailability} */ -chrome.cast.ReceiverAvailability.UNAVAILABLE; - -/** @type {Object} */ -chrome.cast.media = {}; - -/** @constructor */ -chrome.cast.media.Media = function() { - /** @type {number} */ - this.mediaSessionId = 0; -}; - -/** @constructor */ -chrome.cast.Session = function() { - /** @type {Array<chrome.cast.media.Media>} */ - this.media = []; - - /** @type {string} */ - this.sessionId = ''; -}; - -/** - * @param {string} namespace - * @param {Object} message - * @param {function():void} successCallback - * @param {function(chrome.cast.Error):void} errorCallback - */ -chrome.cast.Session.prototype.sendMessage = - function(namespace, message, successCallback, errorCallback) {}; - -/** - * @param {function(chrome.cast.media.Media):void} listener - */ -chrome.cast.Session.prototype.addMediaListener = function(listener) {}; - -/** - * @param {function(boolean):void} listener - */ -chrome.cast.Session.prototype.addUpdateListener = function(listener) {}; - -/** - * @param {string} namespace - * @param {function(string, string):void} listener - */ -chrome.cast.Session.prototype.addMessageListener = - function(namespace, listener){}; - -/** - * @param {function():void} successCallback - * @param {function(chrome.cast.Error):void} errorCallback - */ -chrome.cast.Session.prototype.stop = - function(successCallback, errorCallback) {}; - -/** - * @constructor - * @param {string} applicationID - */ -chrome.cast.SessionRequest = function(applicationID) {}; - -/** - * @constructor - * @param {chrome.cast.SessionRequest} sessionRequest - * @param {function(chrome.cast.Session):void} sessionListener - * @param {function(chrome.cast.ReceiverAvailability):void} receiverListener - * @param {chrome.cast.AutoJoinPolicy=} opt_autoJoinPolicy - * @param {chrome.cast.DefaultActionPolicy=} opt_defaultActionPolicy - */ -chrome.cast.ApiConfig = function(sessionRequest, - sessionListener, - receiverListener, - opt_autoJoinPolicy, - opt_defaultActionPolicy) {}; - -/** - * @param {chrome.cast.ApiConfig} apiConfig - * @param {function():void} onInitSuccess - * @param {function(chrome.cast.Error):void} onInitError - */ -chrome.cast.initialize = - function(apiConfig, onInitSuccess, onInitError) {}; - -/** - * @param {function(chrome.cast.Session):void} successCallback - * @param {function(chrome.cast.Error):void} errorCallback - */ -chrome.cast.requestSession = - function(successCallback, errorCallback) {}; - -/** @type {Object} */ chrome.sockets = {}; /** @type {Object} */
diff --git a/remoting/webapp/js_proto/dom_proto.js b/remoting/webapp/js_proto/dom_proto.js index 14d8abb3..f8233bd 100644 --- a/remoting/webapp/js_proto/dom_proto.js +++ b/remoting/webapp/js_proto/dom_proto.js
@@ -45,6 +45,12 @@ /** @type {string} */ Element.prototype.localName; +/** @type {number} */ +Element.prototype.offsetRight; + +/** @type {number} */ +Element.prototype.offsetBottom; + /** @type {string} */ Element.prototype.textContent;
diff --git a/remoting/webapp/js_proto/qunit_proto.js b/remoting/webapp/js_proto/qunit_proto.js new file mode 100644 index 0000000..dd5745f --- /dev/null +++ b/remoting/webapp/js_proto/qunit_proto.js
@@ -0,0 +1,87 @@ +// 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. + +// This file contains various hacks needed to inform JSCompiler of various +// QUnit-specific properties and methods. It is used only with JSCompiler to +// verify the type-correctness of our code. + + +/** @type {Object} */ +var QUnit = QUnit || {}; + +/** @constructor */ +QUnit.Test = function() {}; + +/** @type {QUnit.Clock} */ +QUnit.Test.prototype.clock = new QUnit.Clock(); + +/** @constructor */ +QUnit.Clock = function() {}; + +/** @param {number} ticks */ +QUnit.Clock.prototype.tick = function(ticks) {}; + + +/** + * @param {string} desc + * @param {Function} f + */ +QUnit.asyncTest = function(desc, f) {}; + +/** + * @param {*} a + * @param {*} b + */ +QUnit.deepEqual = function(a, b) {}; + +/** + * @param {*} a + * @param {*} b + */ +QUnit.equal = function(a, b) {}; + +/** + * @param {*} a + */ +QUnit.expect = function(a) {}; + +/** + * @param {string} desc + * @param {Object=} dict + */ +QUnit.module = function(desc, dict) {}; + +/** + * @param {*} a + * @param {*} b + * @param {string} desc + */ +QUnit.notEqual = function(a, b, desc) {}; + +/** + * @param {boolean} cond + * @param {string=} desc + * @return {boolean} + */ +QUnit.ok = function(cond, desc) {}; + +QUnit.start = function() {}; + +/** + * @param {string} desc + * @param {Function} f + */ +QUnit.test = function(desc, f) {}; + +/** @param {Function} f */ +QUnit.testStart = function(f) {}; + + +var deepEqual = QUnit.deepEqual; +var equal = QUnit.equal; +var expect = QUnit.expect; +var module = QUnit.module; +var notEqual = QUnit.notEqual; +var ok = QUnit.ok; +var test = QUnit.test;
diff --git a/remoting/webapp/js_proto/sinon_proto.js b/remoting/webapp/js_proto/sinon_proto.js new file mode 100644 index 0000000..bc39ea5 --- /dev/null +++ b/remoting/webapp/js_proto/sinon_proto.js
@@ -0,0 +1,113 @@ +// 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. + +var sinon = sinon || {}; + +/** @type {Object} */ +sinon.assert = {}; + +/** + * @param {(sinon.Spy|Function)} f + */ +sinon.assert.called = function(f) {}; + +/** + * @param {(sinon.Spy|Function)} f + */ +sinon.assert.calledOnce = function(f) {}; + +/** + * @param {(sinon.Spy|Function)} f + * @param {...} data + */ +sinon.assert.calledWith = function(f, data) {}; + +/** + * @param {(sinon.Spy|Function)} f + */ +sinon.assert.notCalled = function(f) {}; + +/** @constructor */ +sinon.Expectation = function() {}; + +/** @return {sinon.Expectation} */ +sinon.Expectation.prototype.once = function() {}; + +/** + * @param {...} data + * @return {sinon.Expectation} + */ +sinon.Expectation.prototype.withArgs = function(data) {}; + +/** @return {boolean} */ +sinon.Expectation.prototype.verify = function() {}; + +/** @param {...} data */ +sinon.Expectation.prototype.returns = function(data) {}; + +/** + * @param {Object} obj + * @return {sinon.Mock} + */ +sinon.mock = function(obj) {}; + +/** @constructor */ +sinon.Mock = function() {}; + +/** + * @param {string} method + * @return {sinon.Expectation} + */ +sinon.Mock.prototype.expects = function(method) {}; + +/** @type {function(...):Function} */ +sinon.spy = function() {}; + +/** + * This is a jscompile type that can be OR'ed with the actual type to make + * jscompile aware of the sinon.spy functions that are added to the base + * type. + * Example: Instead of specifying a type of + * {function():void} + * the following can be used to add the sinon.spy functions: + * {(sinon.Spy|function():void)} + * + * @constructor + */ +sinon.Spy = function() {}; + +/** @type {number} */ +sinon.Spy.prototype.callCount; + +/** @type {boolean} */ +sinon.Spy.prototype.called = false; + +/** @type {function(...):boolean} */ +sinon.Spy.prototype.calledWith = function() {}; + +/** @type {function(number):{args:Array}} */ +sinon.Spy.prototype.getCall = function(index) {}; + +sinon.Spy.prototype.reset = function() {}; + +/** + * @param {Object} obj + * @param {string} method + * @return {sinon.TestStub} + */ +sinon.stub = function(obj, method) {}; + +/** @constructor */ +sinon.TestStub = function() {}; + +/** @type {function(number):{args:Array}} */ +sinon.TestStub.prototype.getCall = function(index) {}; + +sinon.TestStub.prototype.restore = function() {}; + +/** @param {*} a */ +sinon.TestStub.prototype.returns = function(a) {}; + +/** @type {function(string, (string|Array<string>)=):sinon.Expectation} */ +sinon.TestStub.prototype.withArgs = function(messageName, opt_args) {};
diff --git a/remoting/webapp/js_proto/sinon_stub_proto.js b/remoting/webapp/js_proto/sinon_stub_proto.js new file mode 100644 index 0000000..28e7d50 --- /dev/null +++ b/remoting/webapp/js_proto/sinon_stub_proto.js
@@ -0,0 +1,31 @@ +// 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. + +// How to create sinon.stubs that work with jscompile. +// +// To create the stub: +// sinon.$setupStub(<object>, <function-name>) +// +// To access the stub in unittests: +// <object>.<function-name>.$testStub.<sinon-test> +// +// For example: +// sinon.$setupStub(chrome.socket, 'create'); +// chrome.socket.create.$testStub.restore(); +// +// For jscompile to analyze these corectly, you'll also need to add an entry +// in this file for any object you stub out this way. For example: +// chrome.socket.create.$testStub = new sinon.TestStub(); + +base.debug.assert.$testStub = new sinon.TestStub(); +base.isAppsV2.$testStub = new sinon.TestStub(); + +chrome.i18n.getMessage.$testStub = new sinon.TestStub(); + +chrome.socket.connect.$testStub = new sinon.TestStub(); +chrome.socket.create.$testStub = new sinon.TestStub(); +chrome.socket.destroy.$testStub = new sinon.TestStub(); +chrome.socket.read.$testStub = new sinon.TestStub(); +chrome.socket.secure.$testStub = new sinon.TestStub(); +chrome.socket.write.$testStub = new sinon.TestStub();
diff --git a/remoting/webapp/js_proto/test_proto.js b/remoting/webapp/js_proto/test_proto.js index 41124ba9..6689cfd 100644 --- a/remoting/webapp/js_proto/test_proto.js +++ b/remoting/webapp/js_proto/test_proto.js
@@ -9,16 +9,12 @@ /** @suppress {duplicate} */ var browserTest = browserTest || {}; -/** @suppress {duplicate} */ -var sinon = sinon || {}; - /** @interface */ browserTest.TestableClass = function() {}; /** @param {*} data */ browserTest.TestableClass.prototype.run = function(data) {}; -sinon.spy = function() {}; /** @constructor */ window.DomAutomationControllerMessage = function() {
diff --git a/remoting/webapp/unittests/apps_v2_migration_unittest.js b/remoting/webapp/unittests/apps_v2_migration_unittest.js index 6bc8db9..805995aa 100644 --- a/remoting/webapp/unittests/apps_v2_migration_unittest.js +++ b/remoting/webapp/unittests/apps_v2_migration_unittest.js
@@ -2,10 +2,16 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. +/** + * @fileoverview + * @suppress {checkTypes|checkVars|reportUnknownTypes|visibility} + */ + (function() { 'use strict'; +/** @type {sinon.TestStub} */ var mockIsAppsV2 = null; var mockChromeStorage = {}; @@ -22,10 +28,10 @@ /** * @param {string} v1UserName * @param {string} v1UserEmail - * @param {string} currentEmail - * @param {boolean} v1HasHost + * @param {boolean} v1HasHosts */ function setMigrationData_(v1UserName, v1UserEmail, v1HasHosts) { + /** @return {!Promise} */ remoting.identity.getUserInfo = function() { if (base.isAppsV2()) { return Promise.resolve( @@ -35,10 +41,13 @@ {email: v1UserEmail, name: v1UserName}); } }; + /** @return {!Promise} */ remoting.identity.getEmail = function() { - return remoting.identity.getUserInfo().then(function(info) { - return info.email; - }); + return remoting.identity.getUserInfo().then( + /** @param {{email:string, name:string}} info */ + function(info) { + return info.email; + }); }; mockIsAppsV2.returns(false); @@ -50,8 +59,8 @@ module('AppsV2Migration', { setup: function() { chromeMocks.activate(['storage']); - mockIsAppsV2 = sinon.stub(base, 'isAppsV2'); - remoting.identity = {}; + mockIsAppsV2 = sinon.$setupStub(base, 'isAppsV2'); + remoting.identity = new remoting.Identity(); }, teardown: function() { chromeMocks.restore(); @@ -89,6 +98,7 @@ setMigrationData_('v1userName', 'v1user@gmail.com', true); mockIsAppsV2.returns(true); remoting.AppsV2Migration.hasHostsInV1App().then( + /** @param {{email:string, name:string}} result */ function(result) { QUnit.equal(result.email, 'v1user@gmail.com'); QUnit.equal(result.fullName, 'v1userName'); @@ -100,10 +110,9 @@ QUnit.asyncTest( 'saveUserInfo() should clear the preferences on v2', function() { - setMigrationData_('v1userName', 'v1user@gmail.com', 'v2user@gmail.com', - true); + setMigrationData_('v1userName', 'v1user@gmail.com', true); mockIsAppsV2.returns(true); - remoting.AppsV2Migration.saveUserInfo(true); + remoting.AppsV2Migration.saveUserInfo(); remoting.AppsV2Migration.hasHostsInV1App().then(fail, pass); });
diff --git a/remoting/webapp/unittests/base_unittest.js b/remoting/webapp/unittests/base_unittest.js index 6ffc8c9..288ff91 100644 --- a/remoting/webapp/unittests/base_unittest.js +++ b/remoting/webapp/unittests/base_unittest.js
@@ -22,14 +22,14 @@ var src = { a: 'a', b: 'b'}; var dest = { a: 'a'}; - sinon.spy(base.debug, 'assert'); + sinon.$setupStub(base.debug, 'assert'); try { base.mix(dest, src); } catch (e) { } finally { sinon.assert.called(base.debug.assert); - base.debug.assert.restore(); + base.debug.assert.$testStub.restore(); } }); @@ -72,9 +72,14 @@ test('dispose(obj) should invoke the dispose method on |obj|', function() { - var obj = { - dispose: sinon.spy() - }; + /** + * @constructor + * @implements {base.Disposable} + */ + base.MockDisposable = function() {}; + base.MockDisposable.prototype.dispose = sinon.spy(); + + var obj = new base.MockDisposable(); base.dispose(obj); sinon.assert.called(obj.dispose); }); @@ -111,9 +116,14 @@ }); QUnit.asyncTest('Promise.sleep(delay) should fulfill the promise after |delay|', + /** + * 'this' is not defined for jscompile, so it can't figure out the type of + * this.clock. + * @suppress {reportUnknownTypes|checkVars|checkTypes} + */ function() { var isCalled = false; - var clock = this.clock; + var clock = /** @type {QUnit.Clock} */ (this.clock); base.Promise.sleep(100).then(function(){ isCalled = true; @@ -129,18 +139,18 @@ window.requestAnimationFrame(function(){ ok(!isCalled, 'Promise.sleep() should not be fulfilled prematurely.'); clock.tick(101); - }.bind(this)); + }); }); QUnit.asyncTest('Promise.negate should fulfill iff the promise does not.', function() { base.Promise.negate(Promise.reject()).then( - ok.bind(null, true), - ok.bind(null, false)); + QUnit.ok.bind(null, true), + /** @type {Function} */ (QUnit.ok.bind(null, false))); base.Promise.negate(Promise.resolve()).then( - ok.bind(null, false), - ok.bind(null, true)); + QUnit.ok.bind(null, false), + /** @type {Function} */ (QUnit.ok.bind(null, true))); window.requestAnimationFrame(function(){ QUnit.start(); }); @@ -149,21 +159,25 @@ module('base.Deferred'); QUnit.asyncTest('resolve() should fulfill the underlying promise.', function() { + /** @returns {Promise} */ function async() { var deferred = new base.Deferred(); deferred.resolve('bar'); return deferred.promise(); } - async().then(function(value){ - QUnit.equal(value, 'bar'); - QUnit.start(); - }, function() { - QUnit.ok(false, 'The reject handler should not be invoked.'); - }); + async().then( + /** @param {string} value */ + function(value){ + QUnit.equal(value, 'bar'); + QUnit.start(); + }, function() { + QUnit.ok(false, 'The reject handler should not be invoked.'); + }); }); QUnit.asyncTest('reject() should fail the underlying promise.', function() { + /** @returns {Promise} */ function async() { var deferred = new base.Deferred(); deferred.reject('bar'); @@ -179,6 +193,7 @@ }); +/** @type {base.EventSourceImpl} */ var source = null; var listener = null; @@ -229,13 +244,13 @@ test('raiseEvent() should assert when undeclared events are raised', function() { - sinon.spy(base.debug, 'assert'); + sinon.$setupStub(base.debug, 'assert'); try { source.raiseEvent('undefined'); } catch (e) { } finally { sinon.assert.called(base.debug.assert); - base.debug.assert.restore(); + base.debug.assert.$testStub.restore(); } }); @@ -268,6 +283,7 @@ }); test('encodeUtf8() can encode UTF8 strings', function() { + /** @type {function(ArrayBuffer):Array} */ function toJsArray(arrayBuffer) { var result = []; var array = new Uint8Array(arrayBuffer);
diff --git a/remoting/webapp/unittests/chrome_mocks.js b/remoting/webapp/unittests/chrome_mocks.js index be55785..fb65437 100644 --- a/remoting/webapp/unittests/chrome_mocks.js +++ b/remoting/webapp/unittests/chrome_mocks.js
@@ -9,6 +9,16 @@ var chromeMocks = {}; +/** @constructor */ +chrome.Event = function() {}; + +/** @param {Function} callback */ +chrome.Event.prototype.addListener = function(callback) {}; + +/** @param {Function} callback */ +chrome.Event.prototype.removeListener = function(callback) {}; + + (function(){ /**
diff --git a/remoting/webapp/unittests/desktop_viewport_unittest.js b/remoting/webapp/unittests/desktop_viewport_unittest.js index 054bf57..238c925 100644 --- a/remoting/webapp/unittests/desktop_viewport_unittest.js +++ b/remoting/webapp/unittests/desktop_viewport_unittest.js
@@ -6,16 +6,26 @@ 'use strict'; -module('DesktopViewport'); - +/** + * @param {number} width + * @param {number} height + * @return {{width:number, height:number}} + */ function size(width, height) { return {width: width, height: height}; } +/** + * @param {number} x + * @param {number} y + * @return {{x:number, y:number}} + */ function dpi(x, y) { return {x: x, y: y}; } +module('DesktopViewport'); + test('choosePluginSize() handles low-DPI client & host', function() { // 1. Client & host size the same.
diff --git a/remoting/webapp/unittests/dns_blackhole_checker_unittest.js b/remoting/webapp/unittests/dns_blackhole_checker_unittest.js index d6e7d22..6f5b0b2e 100644 --- a/remoting/webapp/unittests/dns_blackhole_checker_unittest.js +++ b/remoting/webapp/unittests/dns_blackhole_checker_unittest.js
@@ -2,13 +2,26 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. +/** + * @fileoverview + * TODO(garykac): Create interface for SignalStrategy. + * @suppress {checkTypes|checkVars|reportUnknownTypes|visibility} + */ + (function() { 'use strict'; +/** @type {(sinon.Spy|function(remoting.SignalStrategy.State))} */ var onStateChange = null; + +/** @type {(sinon.Spy|function(Element):void)} */ var onIncomingStanzaCallback = null; + +/** @type {remoting.DnsBlackholeChecker} */ var checker = null; + +/** @type {remoting.MockSignalStrategy} */ var signalStrategy = null; var fakeXhrs; @@ -19,7 +32,6 @@ fakeXhrs.push(xhr); }; - onStateChange = sinon.spy(); onIncomingStanzaCallback = sinon.spy(); signalStrategy = new remoting.MockSignalStrategy();
diff --git a/remoting/webapp/unittests/event_hook_unittest.js b/remoting/webapp/unittests/event_hook_unittest.js index ee67d1f4..15135bde 100644 --- a/remoting/webapp/unittests/event_hook_unittest.js +++ b/remoting/webapp/unittests/event_hook_unittest.js
@@ -2,19 +2,40 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. +/** + * @fileoverview + * TODO(garykac) Remove suppression once chromeMocks has been replaced. + * @suppress {checkTypes|checkVars|reportUnknownTypes} + */ + (function() { 'use strict'; +/** @type {base.EventSourceImpl} */ var eventSource = null; + +/** @type {HTMLElement} */ var domElement = null; + +/** @type {chromeMocks.Event} */ var myChromeEvent = null; + +/** @type {Listener} */ var listener = null; +/** + * @param {HTMLElement} element + * @constructor + */ var Listener = function(element) { - this.onChromeEvent = sinon.stub(); - this.onClickEvent = sinon.stub(); - this.onCustomEvent = sinon.stub(); + /** @type {(sinon.Spy|function(...?))} */ + this.onChromeEvent = sinon.spy(); + /** @type {(sinon.Spy|function(...?))} */ + this.onClickEvent = sinon.spy(); + /** @type {(sinon.Spy|function(...?))} */ + this.onCustomEvent = sinon.spy(); + this.eventHooks_ = new base.Disposables( new base.DomEventHook(element, 'click', this.onClickEvent.bind(this), false), @@ -35,7 +56,7 @@ module('base.EventHook', { setup: function() { - domElement = document.createElement('div'); + domElement = /** @type {HTMLElement} */ (document.createElement('div')); eventSource = new base.EventSourceImpl(); eventSource.defineEvents(['customEvent']); myChromeEvent = new chromeMocks.Event();
diff --git a/remoting/webapp/unittests/fallback_signal_strategy_unittest.js b/remoting/webapp/unittests/fallback_signal_strategy_unittest.js index 959902ba..9f97a729 100644 --- a/remoting/webapp/unittests/fallback_signal_strategy_unittest.js +++ b/remoting/webapp/unittests/fallback_signal_strategy_unittest.js
@@ -2,15 +2,23 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. +/** + * @fileoverview + * TODO(garykac): Create interfaces for LogToServer and SignalStrategy. + * @suppress {checkTypes|checkVars|reportUnknownTypes|visibility} + */ + (function() { 'use strict'; - +/** @constructor */ var MockLogToServer = function() { + /** @type {(sinon.Spy|Function)} */ this.logSignalStrategyProgress = sinon.spy(); }; +/** @type {function(...)} */ MockLogToServer.prototype.assertProgress = function() { equal(this.logSignalStrategyProgress.callCount * 2, arguments.length); for (var i = 0; i < this.logSignalStrategyProgress.callCount; ++i) { @@ -20,13 +28,29 @@ } }; +/** @type {(sinon.Spy|function(remoting.SignalStrategy.State))} */ var onStateChange = null; + +/** @type {(sinon.Spy|function(Element):void)} */ var onIncomingStanzaCallback = null; + +/** @type {remoting.FallbackSignalStrategy} */ var strategy = null; + +/** @type {remoting.SignalStrategy} */ var primary = null; + +/** @type {remoting.SignalStrategy} */ var secondary = null; + +/** @type {MockLogToServer} */ var logToServer = null; +/** + * @param {remoting.MockSignalStrategy} baseSignalStrategy + * @param {remoting.SignalStrategy.State} state + * @param {boolean} expectCallback + */ function setState(baseSignalStrategy, state, expectCallback) { onStateChange.reset(); baseSignalStrategy.setStateForTesting(state);
diff --git a/remoting/webapp/unittests/ipc_unittest.js b/remoting/webapp/unittests/ipc_unittest.js index 9434cab..e786147 100644 --- a/remoting/webapp/unittests/ipc_unittest.js +++ b/remoting/webapp/unittests/ipc_unittest.js
@@ -6,6 +6,7 @@ 'use strict'; +/** @type {base.Ipc} */ var ipc_; function pass() { @@ -62,7 +63,7 @@ function() { var handler = sinon.spy(); ipc_.register('foo', handler); - ipc_.unregister('foo', handler); + ipc_.unregister('foo'); base.Ipc.invoke('foo', 'hello', 'world').then(fail, function(error) { sinon.assert.notCalled(handler); QUnit.equal(error, base.Ipc.Error.UNSUPPORTED_REQUEST_TYPE);
diff --git a/remoting/webapp/unittests/it2me_helpee_channel_unittest.js b/remoting/webapp/unittests/it2me_helpee_channel_unittest.js index 85bee2b..30d060d 100644 --- a/remoting/webapp/unittests/it2me_helpee_channel_unittest.js +++ b/remoting/webapp/unittests/it2me_helpee_channel_unittest.js
@@ -2,6 +2,11 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. +/** + * @fileoverview + * @suppress {checkTypes|checkVars|reportUnknownTypes|visibility} + */ + (function() { 'use strict';
diff --git a/remoting/webapp/unittests/it2me_helper_channel_unittest.js b/remoting/webapp/unittests/it2me_helper_channel_unittest.js index f0a0fa2..aa25693f 100644 --- a/remoting/webapp/unittests/it2me_helper_channel_unittest.js +++ b/remoting/webapp/unittests/it2me_helper_channel_unittest.js
@@ -2,6 +2,11 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. +/** + * @fileoverview + * @suppress {checkTypes|checkVars|reportUnknownTypes|visibility} + */ + (function() { 'use strict';
diff --git a/remoting/webapp/unittests/it2me_service_unittest.js b/remoting/webapp/unittests/it2me_service_unittest.js index 1bd66f5..a9a71b0 100644 --- a/remoting/webapp/unittests/it2me_service_unittest.js +++ b/remoting/webapp/unittests/it2me_service_unittest.js
@@ -2,6 +2,11 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. +/** + * @fileoverview + * @suppress {checkTypes|checkVars|reportUnknownTypes|visibility} + */ + (function() { 'use strict'; @@ -129,4 +134,4 @@ sinon.assert.called(randomPort.disconnect); }); -})(); \ No newline at end of file +})();
diff --git a/remoting/webapp/unittests/l10n_unittest.js b/remoting/webapp/unittests/l10n_unittest.js index 6ac3680f..043aaab 100644 --- a/remoting/webapp/unittests/l10n_unittest.js +++ b/remoting/webapp/unittests/l10n_unittest.js
@@ -8,10 +8,10 @@ module('l10n', { setup: function() { - sinon.stub(chrome.i18n, 'getMessage'); + sinon.$setupStub(chrome.i18n, 'getMessage'); }, teardown: function() { - chrome.i18n.getMessage.restore(); + chrome.i18n.getMessage.$testStub.restore(); } }); @@ -23,7 +23,8 @@ test('localizeElementFromTag() should replace innerText by default', function() { var element = document.createElement('div'); - chrome.i18n.getMessage.withArgs('tag').returns('<b>Hello World</b>'); + chrome.i18n.getMessage.$testStub.withArgs('tag') + .returns('<b>Hello World</b>'); l10n.localizeElementFromTag(element, 'tag'); @@ -33,7 +34,8 @@ test('localizeElementFromTag() should replace innerHTML if flag is set', function() { var element = document.createElement('div'); - chrome.i18n.getMessage.withArgs('tag').returns('<b>Hello World</b>'); + chrome.i18n.getMessage.$testStub.withArgs('tag') + .returns('<b>Hello World</b>'); l10n.localizeElementFromTag(element, 'tag', null, true); @@ -46,7 +48,8 @@ function() { var element = document.createElement('div'); element.setAttribute('i18n-content', 'tag'); - chrome.i18n.getMessage.withArgs('tag').returns('<b>Hello World</b>'); + chrome.i18n.getMessage.$testStub.withArgs('tag') + .returns('<b>Hello World</b>'); l10n.localizeElement(element); @@ -59,7 +62,7 @@ function() { var fixture = document.getElementById('qunit-fixture'); fixture.innerHTML = '<div class="target" i18n-title="tag"></div>'; - chrome.i18n.getMessage.withArgs('tag').returns('localized title'); + chrome.i18n.getMessage.$testStub.withArgs('tag').returns('localized title'); l10n.localize(); @@ -76,7 +79,7 @@ 'i18n-value-2="param2">' + '</div>'; - chrome.i18n.getMessage.withArgs('tag', ['param1', 'param2']) + chrome.i18n.getMessage.$testStub.withArgs('tag', ['param1', 'param2']) .returns('localized'); l10n.localize(); @@ -91,7 +94,7 @@ '<div class="target" i18n-content="tag"' + ' i18n-value-name-1="tag1" i18n-value-name-2="tag2"></div>'; - var getMessage = chrome.i18n.getMessage; + var getMessage = chrome.i18n.getMessage.$testStub; getMessage.withArgs('tag1').returns('param1'); getMessage.withArgs('tag2').returns('param2'); getMessage.withArgs('tag', ['param1', 'param2']).returns('localized');
diff --git a/remoting/webapp/unittests/menu_button_unittest.js b/remoting/webapp/unittests/menu_button_unittest.js index 7337134..1367b0da 100644 --- a/remoting/webapp/unittests/menu_button_unittest.js +++ b/remoting/webapp/unittests/menu_button_unittest.js
@@ -6,8 +6,11 @@ 'use strict'; +/** @type {(sinon.Spy|function():void)} */ var onShow = null; +/** @type {(sinon.Spy|function():void)} */ var onHide = null; +/** @type {remoting.MenuButton} */ var menuButton = null; module('MenuButton', { @@ -20,11 +23,12 @@ '<li id="menu-option-1">Option 1</li>' + '</ul>' + '</span>'; - onShow = sinon.spy(); - onHide = sinon.spy(); + onShow = /** @type {(sinon.Spy|function():void)} */ (sinon.spy()); + onHide = /** @type {(sinon.Spy|function():void)} */ (sinon.spy()); menuButton = new remoting.MenuButton( document.getElementById('menu-button-container'), - onShow, onHide); + /** @type {function():void} */ (onShow), + /** @type {function():void} */ (onHide)); }, teardown: function() { onShow = null; @@ -87,4 +91,4 @@ ok(style.backgroundImage == 'none'); }); -}()); \ No newline at end of file +}());
diff --git a/remoting/webapp/unittests/mock_signal_strategy.js b/remoting/webapp/unittests/mock_signal_strategy.js index 46e27f36..6935b05 100644 --- a/remoting/webapp/unittests/mock_signal_strategy.js +++ b/remoting/webapp/unittests/mock_signal_strategy.js
@@ -9,8 +9,8 @@ /** - * @param {string} jid - * @param {remoting.SignalStrategy.Type} type + * @param {string=} jid + * @param {remoting.SignalStrategy.Type=} type * * @implements {remoting.SignalStrategy} * @constructor
diff --git a/remoting/webapp/unittests/sinon_helpers.js b/remoting/webapp/unittests/sinon_helpers.js new file mode 100644 index 0000000..763a9391 --- /dev/null +++ b/remoting/webapp/unittests/sinon_helpers.js
@@ -0,0 +1,21 @@ +// 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. + +var sinonHelpers = {}; + +sinonHelpers.reset = function() { + +/** + * @param {Object} obj + * @param {string} method + * @return {sinon.TestStub} + * @suppress {reportUnknownTypes} + */ +sinon.$setupStub = function(obj, method) { + sinon.stub(obj, method); + obj[method].$testStub = /** @type {sinon.TestStub} */ (obj[method]); + return obj[method].$testStub; +}; + +};
diff --git a/remoting/webapp/unittests/test_start.js b/remoting/webapp/unittests/test_start.js new file mode 100644 index 0000000..8159ce7 --- /dev/null +++ b/remoting/webapp/unittests/test_start.js
@@ -0,0 +1,12 @@ +// 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. + +// Global test setup. +// This code is run before each test in every module. + +QUnit.testStart( + /** @param {{module:string, name:string}} details */ + function(details) { + sinonHelpers.reset(); + });
diff --git a/remoting/webapp/unittests/xhr_unittest.js b/remoting/webapp/unittests/xhr_unittest.js index 804f7159..ea32042 100644 --- a/remoting/webapp/unittests/xhr_unittest.js +++ b/remoting/webapp/unittests/xhr_unittest.js
@@ -2,6 +2,11 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. +/** + * @fileoverview + * @suppress {checkTypes|checkVars|reportUnknownTypes} + */ + (function() { 'use strict';
diff --git a/remoting/webapp/unittests/xmpp_connection_unittest.js b/remoting/webapp/unittests/xmpp_connection_unittest.js index a36261f..38aa6c2 100644 --- a/remoting/webapp/unittests/xmpp_connection_unittest.js +++ b/remoting/webapp/unittests/xmpp_connection_unittest.js
@@ -10,37 +10,44 @@ var testToken = 'testToken'; var socketId = 3; -var onStateChange = null; +/** @type {(sinon.Spy|function(remoting.SignalStrategy.State):void)} */ +var onStateChange = function() {}; + var onStanzaStr = null; + +/** @type {remoting.XmppConnection} */ var connection = null; module('XmppConnection', { setup: function() { onStateChange = sinon.spy(); onStanzaStr = sinon.spy(); + /** @param {Element} stanza */ function onStanza(stanza) { onStanzaStr(new XMLSerializer().serializeToString(stanza)); } - sinon.stub(chrome.socket, 'create'); - sinon.stub(chrome.socket, 'connect'); - sinon.stub(chrome.socket, 'write'); - sinon.stub(chrome.socket, 'read'); - sinon.stub(chrome.socket, 'destroy'); - sinon.stub(chrome.socket, 'secure'); + sinon.$setupStub(chrome.socket, 'create'); + sinon.$setupStub(chrome.socket, 'connect'); + sinon.$setupStub(chrome.socket, 'write'); + sinon.$setupStub(chrome.socket, 'read'); + sinon.$setupStub(chrome.socket, 'destroy'); + sinon.$setupStub(chrome.socket, 'secure'); connection = new remoting.XmppConnection(); - connection.setStateChangedCallback(onStateChange); + connection.setStateChangedCallback( + /** @type {function(remoting.SignalStrategy.State):void} */ + (onStateChange)); connection.setIncomingStanzaCallback(onStanza); }, teardown: function() { - chrome.socket.create.restore(); - chrome.socket.connect.restore(); - chrome.socket.write.restore(); - chrome.socket.read.restore(); - chrome.socket.destroy.restore(); - chrome.socket.secure.restore(); + chrome.socket.create.$testStub.restore(); + chrome.socket.connect.$testStub.restore(); + chrome.socket.write.$testStub.restore(); + chrome.socket.read.$testStub.restore(); + chrome.socket.destroy.$testStub.restore(); + chrome.socket.secure.$testStub.restore(); } }); @@ -50,11 +57,11 @@ sinon.assert.calledWith(onStateChange, remoting.SignalStrategy.State.CONNECTING); sinon.assert.calledWith(chrome.socket.create, "tcp", {}); - chrome.socket.create.getCall(0).args[2]({socketId: socketId}); + chrome.socket.create.$testStub.getCall(0).args[2]({socketId: socketId}); sinon.assert.calledWith( chrome.socket.connect, socketId, "xmpp.example.com", 123); - chrome.socket.connect.getCall(0).args[3](-1); + chrome.socket.connect.$testStub.getCall(0).args[3](-1); QUnit.equal(connection.getError(), remoting.Error.NETWORK_FAILURE); }); @@ -66,11 +73,11 @@ sinon.assert.calledWith(onStateChange, remoting.SignalStrategy.State.CONNECTING); sinon.assert.calledWith(chrome.socket.create, "tcp", {}); - chrome.socket.create.getCall(0).args[2]({socketId: socketId}); + chrome.socket.create.$testStub.getCall(0).args[2]({socketId: socketId}); sinon.assert.calledWith( chrome.socket.connect, socketId, "xmpp.example.com", 123); - chrome.socket.connect.getCall(0).args[3](0); + chrome.socket.connect.$testStub.getCall(0).args[3](0); sinon.assert.calledWith(onStateChange, remoting.SignalStrategy.State.HANDSHAKE); @@ -78,8 +85,9 @@ var parser = new remoting.XmppStreamParser(); var parserMock = sinon.mock(parser); var setCallbacksCalled = parserMock.expects('setCallbacks').once(); - connection.loginHandler_.onHandshakeDoneCallback_('test@example.com/123123', - parser); + var handshakeDoneCallback = + connection.loginHandler_.getHandshakeDoneCallbackForTesting(); + handshakeDoneCallback('test@example.com/123123', parser); sinon.assert.calledWith(onStateChange, remoting.SignalStrategy.State.CONNECTED); setCallbacksCalled.verify(); @@ -88,7 +96,7 @@ var data = base.encodeUtf8('<iq id="1">hello</iq>'); sinon.assert.calledWith(chrome.socket.read, socketId); var appendDataCalled = parserMock.expects('appendData').once().withArgs(data); - chrome.socket.read.getCall(0).args[1]({resultCode: 0, data: data}); + chrome.socket.read.$testStub.getCall(0).args[1]({resultCode: 0, data: data}); appendDataCalled.verify(); });
diff --git a/remoting/webapp/unittests/xmpp_login_handler_unittest.js b/remoting/webapp/unittests/xmpp_login_handler_unittest.js index 2b1adfd..1421651 100644 --- a/remoting/webapp/unittests/xmpp_login_handler_unittest.js +++ b/remoting/webapp/unittests/xmpp_login_handler_unittest.js
@@ -9,22 +9,45 @@ var testUsername = 'testUsername@gmail.com'; var testToken = 'testToken'; -var sendMessage = null; -var startTls = null; -var onHandshakeDone = null; -var onStanzaStr = null; -var onError = null; +/** @type {(sinon.Spy|function(string):void)} */ +var sendMessage_spy = function(msg) {}; +/** @type {function(string):void} */ +var sendMessage = function(msg) {}; + +/** @type {(sinon.Spy|function():void)} */ +var startTls_spy = function() {}; +/** @type {function():void} */ +var startTls = function() {}; + +/** @type {(sinon.Spy|function(string, remoting.XmppStreamParser):void)} */ +var onHandshakeDone_spy = function(name, parser) {}; +/** @type {function(string, remoting.XmppStreamParser):void} */ +var onHandshakeDone = function(name, parser) {}; + +/** @type {(sinon.Spy|function(remoting.Error, string):void)} */ +var onError_spy = function(error, message) {}; +/** @type {function(remoting.Error, string):void} */ +var onError = function(error, message) {}; + +/** @type {remoting.XmppLoginHandler} */ var loginHandler = null; module('XmppLoginHandler', { setup: function() { - sendMessage = sinon.spy(); - startTls = sinon.spy(); - onHandshakeDone = sinon.spy(); - onError = sinon.spy(); + sendMessage_spy = sinon.spy(); + sendMessage = /** @type {function(string):void} */ (sendMessage_spy); + startTls_spy = sinon.spy(); + startTls = /** @type {function():void} */ (startTls_spy); + onHandshakeDone_spy = sinon.spy(); + onHandshakeDone = + /** @type {function(string, remoting.XmppStreamParser):void} */ + (onHandshakeDone_spy); + onError_spy = sinon.spy(); + onError = /** @type {function(remoting.Error, string):void} */(onError_spy); + loginHandler = new remoting.XmppLoginHandler( - 'google.com', testUsername, testToken, false, sendMessage, - startTls, onHandshakeDone, onError); + 'google.com', testUsername, testToken, false, + sendMessage, startTls, onHandshakeDone, onError); } }); @@ -33,7 +56,7 @@ loginHandler.start(); sinon.assert.calledWith(startTls); - startTls.reset(); + startTls_spy.reset(); loginHandler.onTlsStarted(); var cookie = window.btoa("\0" + testUsername + "\0" + testToken); @@ -47,7 +70,7 @@ 'auth:allow-non-google-login="true" ' + 'xmlns:auth="http://www.google.com/talk/protocol/auth">' + cookie + '</auth>'); - sendMessage.reset(); + sendMessage_spy.reset(); loginHandler.onDataReceived(base.encodeUtf8( '<stream:stream from="google.com" id="DCDDE5171CB2154A" version="1.0" ' + @@ -79,7 +102,7 @@ '<iq type="set" id="1">' + '<session xmlns="urn:ietf:params:xml:ns:xmpp-session"/>' + '</iq>'); - sendMessage.reset(); + sendMessage_spy.reset(); loginHandler.onDataReceived(base.encodeUtf8( '<stream:stream from="google.com" id="104FA10576E2AA80" version="1.0" ' + @@ -110,7 +133,7 @@ '<stream:stream to="google.com" version="1.0" xmlns="jabber:client" ' + 'xmlns:stream="http://etherx.jabber.org/streams">' + '<starttls xmlns="urn:ietf:params:xml:ns:xmpp-tls"/>'); - sendMessage.reset(); + sendMessage_spy.reset(); loginHandler.onDataReceived(base.encodeUtf8( '<stream:stream from="google.com" id="78A87C70559EF28A" version="1.0" ' +
diff --git a/remoting/webapp/unittests/xmpp_stream_parser_unittest.js b/remoting/webapp/unittests/xmpp_stream_parser_unittest.js index 21a972e..ec6cc45 100644 --- a/remoting/webapp/unittests/xmpp_stream_parser_unittest.js +++ b/remoting/webapp/unittests/xmpp_stream_parser_unittest.js
@@ -6,14 +6,20 @@ 'use strict'; +/** @type {Function} */ var onStanzaStr = null; -var onError = null; + +/** @type {function(string):void} */ +var onError = function(msg) {}; + +/** @type {remoting.XmppStreamParser} */ var parser = null; module('XmppStreamParser', { setup: function() { onStanzaStr = sinon.spy(); - onError = sinon.spy(); + onError = /** @type {function(string):void} */ (sinon.spy()); + /** @param {Element} stanza */ function onStanza(stanza) { onStanzaStr(new XMLSerializer().serializeToString(stanza)); }
diff --git a/sandbox/linux/integration_tests/bpf_dsl_seccomp_unittest.cc b/sandbox/linux/integration_tests/bpf_dsl_seccomp_unittest.cc index 2d337c6..8e7e144b 100644 --- a/sandbox/linux/integration_tests/bpf_dsl_seccomp_unittest.cc +++ b/sandbox/linux/integration_tests/bpf_dsl_seccomp_unittest.cc
@@ -651,6 +651,10 @@ return UnsafeTrap(AllowRedirectedSyscall, NULL); } +#if !defined(ADDRESS_SANITIZER) +// ASan does not allow changing the signal handler for SIGBUS, and treats it as +// a fatal signal. + int bus_handler_fd_ = -1; void SigBusHandler(int, siginfo_t* info, void* void_context) { @@ -679,6 +683,7 @@ BPF_ASSERT(close(fds[1]) == 0); BPF_ASSERT(c == 0x55); } +#endif // !defined(ADDRESS_SANITIZER) BPF_TEST_C(SandboxBPF, SigMask, RedirectAllSyscallsPolicy) { // Signal masks are potentially tricky to handle. For instance, if we
diff --git a/skia/BUILD.gn b/skia/BUILD.gn index 8c843c9c..3e3bc0c 100644 --- a/skia/BUILD.gn +++ b/skia/BUILD.gn
@@ -255,7 +255,6 @@ "/wd4554", # 'operator' : check operator precedence for possible error "/wd4748", # compiler will disable optimizations if a function has inline # assembly code contains flow control(jmp or jcc) statements. - "/wd4800", # forcing value to bool 'true/false'(assigning int to bool). ] } @@ -343,7 +342,6 @@ "//third_party/skia/include/utils/SkLayer.h", "//third_party/skia/include/utils/SkMeshUtils.h", "//third_party/skia/include/utils/SkNinePatch.h", - "//third_party/skia/include/utils/SkParse.h", "//third_party/skia/include/utils/SkParsePaint.h", "//third_party/skia/include/utils/SkParsePath.h", "//third_party/skia/include/utils/SkRandom.h", @@ -364,8 +362,6 @@ "//third_party/skia/src/utils/SkMeshUtils.cpp", "//third_party/skia/src/utils/SkNinePatch.cpp", "//third_party/skia/src/utils/SkOSFile.cpp", - "//third_party/skia/src/utils/SkParse.cpp", - "//third_party/skia/src/utils/SkParseColor.cpp", "//third_party/skia/src/utils/SkParsePath.cpp", "//third_party/skia/src/utils/SkPathUtils.cpp", "//third_party/skia/src/utils/SkSHA1.cpp",
diff --git a/skia/skia_library.gypi b/skia/skia_library.gypi index 2163a797..04e428a 100644 --- a/skia/skia_library.gypi +++ b/skia/skia_library.gypi
@@ -102,7 +102,6 @@ '../third_party/skia/include/utils/SkLayer.h', '../third_party/skia/include/utils/SkMeshUtils.h', '../third_party/skia/include/utils/SkNinePatch.h', - '../third_party/skia/include/utils/SkParse.h', '../third_party/skia/include/utils/SkParsePaint.h', '../third_party/skia/include/utils/SkParsePath.h', '../third_party/skia/include/utils/SkRandom.h', @@ -124,8 +123,6 @@ '../third_party/skia/src/utils/SkMeshUtils.cpp', '../third_party/skia/src/utils/SkNinePatch.cpp', '../third_party/skia/src/utils/SkOSFile.cpp', - '../third_party/skia/src/utils/SkParse.cpp', - '../third_party/skia/src/utils/SkParseColor.cpp', '../third_party/skia/src/utils/SkParsePath.cpp', '../third_party/skia/src/utils/SkPathUtils.cpp', '../third_party/skia/src/utils/SkSHA1.cpp',
diff --git a/storage/browser/blob/blob_storage_context.cc b/storage/browser/blob/blob_storage_context.cc index 5170ceb3..b673930 100644 --- a/storage/browser/blob/blob_storage_context.cc +++ b/storage/browser/blob/blob_storage_context.cc
@@ -375,8 +375,8 @@ bool BlobStorageContext::AppendBlob( const std::string& target_blob_uuid, const InternalBlobData& blob, - size_t offset, - size_t length, + uint64_t offset, + uint64_t length, InternalBlobData::Builder* target_blob_builder) { DCHECK(length > 0); @@ -395,10 +395,10 @@ for (; iter != items.end() && length > 0; ++iter) { scoped_refptr<ShareableBlobDataItem> shareable_item = iter->get(); const BlobDataItem& item = *(shareable_item->item()); - size_t item_length = item.length(); + uint64_t item_length = item.length(); DCHECK_GT(item_length, offset); - size_t current_length = item_length - offset; - size_t new_length = current_length > length ? length : current_length; + uint64_t current_length = item_length - offset; + uint64_t new_length = current_length > length ? length : current_length; bool reusing_blob_item = offset == 0 && new_length == item.length(); UMA_HISTOGRAM_BOOLEAN("Storage.Blob.ReusedItem", reusing_blob_item);
diff --git a/storage/browser/blob/blob_storage_context.h b/storage/browser/blob/blob_storage_context.h index 175e90020..cf73c8a 100644 --- a/storage/browser/blob/blob_storage_context.h +++ b/storage/browser/blob/blob_storage_context.h
@@ -122,8 +122,8 @@ // have to split an item. bool AppendBlob(const std::string& target_blob_uuid, const InternalBlobData& blob, - size_t offset, - size_t length, + uint64_t offset, + uint64_t length, InternalBlobData::Builder* target_blob_data); bool IsInUse(const std::string& uuid);
diff --git a/testing/buildbot/chromium.webkit.json b/testing/buildbot/chromium.webkit.json index 5831f7f2..de068686 100644 --- a/testing/buildbot/chromium.webkit.json +++ b/testing/buildbot/chromium.webkit.json
@@ -1,5 +1,11 @@ { "WebKit Linux": { + "gtest_tests": [ + "blink_heap_unittests", + "blink_platform_unittests", + "webkit_unit_tests", + "wtf_unittests" + ], "scripts": [ { "name": "webkit_lint",
diff --git a/testing/chromoting/chromoting_integration_tests.isolate b/testing/chromoting/chromoting_integration_tests.isolate index be04bd6..2df2a15 100644 --- a/testing/chromoting/chromoting_integration_tests.isolate +++ b/testing/chromoting/chromoting_integration_tests.isolate
@@ -30,6 +30,7 @@ '../../remoting/tools/internal/test-account-host-config.json', '<(PRODUCT_DIR)/remoting/com.google.chrome.remote_desktop.json', '<(PRODUCT_DIR)/remoting/com.google.chrome.remote_assistance.json', + '<(PRODUCT_DIR)/remoting-me2me-host.deb', ], }, }],
diff --git a/third_party/libjingle/README.chromium b/third_party/libjingle/README.chromium index 84b983f..f1a210d 100644 --- a/third_party/libjingle/README.chromium +++ b/third_party/libjingle/README.chromium
@@ -1,7 +1,7 @@ Name: libjingle URL: http://code.google.com/p/webrtc/ Version: unknown -Revision: 8542 +Revision: 8550 License: BSD License File: source/talk/COPYING Security Critical: yes
diff --git a/tools/auto_bisect/bisect_perf_regression.py b/tools/auto_bisect/bisect_perf_regression.py index 71f701c..746952eb 100755 --- a/tools/auto_bisect/bisect_perf_regression.py +++ b/tools/auto_bisect/bisect_perf_regression.py
@@ -2645,7 +2645,8 @@ '(default), Release_x64 or "Debug".') group.add_argument('--builder_type', default=fetch_build.PERF_BUILDER, choices=[fetch_build.PERF_BUILDER, - fetch_build.FULL_BUILDER, ''], + fetch_build.FULL_BUILDER, + fetch_build.ANDROID_CHROME_PERF_BUILDER, ''], help='Type of builder to get build from. This ' 'determines both the bot that builds and the ' 'place where archived builds are downloaded from. '
diff --git a/tools/clang/blink_gc_plugin/BlinkGCPlugin.cpp b/tools/clang/blink_gc_plugin/BlinkGCPlugin.cpp index fb87ce8..dc36bef 100644 --- a/tools/clang/blink_gc_plugin/BlinkGCPlugin.cpp +++ b/tools/clang/blink_gc_plugin/BlinkGCPlugin.cpp
@@ -315,6 +315,20 @@ return true; } + bool VisitUnresolvedMemberExpr(UnresolvedMemberExpr* member) { + for (Decl* decl : member->decls()) { + if (CXXMethodDecl* method = dyn_cast<CXXMethodDecl>(decl)) { + if (method->getParent() == receiver_->record() && + Config::GetTraceMethodType(method) == + Config::TRACE_AFTER_DISPATCH_METHOD) { + dispatched_to_receiver_ = true; + return true; + } + } + } + return true; + } + private: RecordInfo* receiver_; bool dispatched_to_receiver_; @@ -325,8 +339,12 @@ // - A base is traced if a base-qualified call to a trace method is found. class CheckTraceVisitor : public RecursiveASTVisitor<CheckTraceVisitor> { public: - CheckTraceVisitor(CXXMethodDecl* trace, RecordInfo* info) - : trace_(trace), info_(info), delegates_to_traceimpl_(false) {} + CheckTraceVisitor(CXXMethodDecl* trace, RecordInfo* info, RecordCache* cache) + : trace_(trace), + info_(info), + cache_(cache), + delegates_to_traceimpl_(false) { + } bool delegates_to_traceimpl() const { return delegates_to_traceimpl_; } @@ -541,12 +559,48 @@ if (!IsTraceCallName(func_name)) return false; - RecordInfo::Bases::iterator iter = info_->GetBases().find(callee_record); - if (iter == info_->GetBases().end()) - return false; + for (auto& base : info_->GetBases()) { + // We want to deal with omitted trace() function in an intermediary + // class in the class hierarchy, e.g.: + // class A : public GarbageCollected<A> { trace() { ... } }; + // class B : public A { /* No trace(); have nothing to trace. */ }; + // class C : public B { trace() { B::trace(visitor); } } + // where, B::trace() is actually A::trace(), and in some cases we get + // A as |callee_record| instead of B. We somehow need to mark B as + // traced if we find A::trace() call. + // + // To solve this, here we keep going up the class hierarchy as long as + // they are not required to have a trace method. The implementation is + // a simple DFS, where |base_records| represents the set of base classes + // we need to visit. - iter->second.MarkTraced(); - return true; + std::vector<CXXRecordDecl*> base_records; + base_records.push_back(base.first); + + while (!base_records.empty()) { + CXXRecordDecl* base_record = base_records.back(); + base_records.pop_back(); + + if (base_record == callee_record) { + // If we find a matching trace method, pretend the user has written + // a correct trace() method of the base; in the example above, we + // find A::trace() here and mark B as correctly traced. + base.second.MarkTraced(); + return true; + } + + if (RecordInfo* base_info = cache_->Lookup(base_record)) { + if (!base_info->RequiresTraceMethod()) { + // If this base class is not required to have a trace method, then + // the actual trace method may be defined in an ancestor. + for (auto& inner_base : base_info->GetBases()) + base_records.push_back(inner_base.first); + } + } + } + } + + return false; } bool CheckTraceFieldCall(CXXMemberCallExpr* call) { @@ -609,7 +663,8 @@ }; // Nested checking for weak callbacks. - CheckTraceVisitor(RecordInfo* info) : trace_(0), info_(info) {} + CheckTraceVisitor(RecordInfo* info) + : trace_(nullptr), info_(info), cache_(nullptr) {} bool IsWeakCallback() { return !trace_; } @@ -643,6 +698,7 @@ CXXMethodDecl* trace_; RecordInfo* info_; + RecordCache* cache_; bool delegates_to_traceimpl_; }; @@ -1365,7 +1421,8 @@ // Determine what type of tracing method this is (dispatch or trace). void CheckTraceOrDispatchMethod(RecordInfo* parent, CXXMethodDecl* method) { Config::TraceMethodType trace_type = Config::GetTraceMethodType(method); - if (trace_type != Config::TRACE_METHOD || + if (trace_type == Config::TRACE_AFTER_DISPATCH_METHOD || + trace_type == Config::TRACE_AFTER_DISPATCH_IMPL_METHOD || !parent->GetTraceDispatchMethod()) { CheckTraceMethod(parent, method, trace_type); } @@ -1387,7 +1444,7 @@ } } - CheckTraceVisitor visitor(trace, parent); + CheckTraceVisitor visitor(trace, parent, &cache_); visitor.TraverseCXXMethodDecl(trace); // Skip reporting if this trace method is a just delegate to
diff --git a/tools/clang/blink_gc_plugin/CMakeLists.txt b/tools/clang/blink_gc_plugin/CMakeLists.txt index c511edf..7f1dee3 100644 --- a/tools/clang/blink_gc_plugin/CMakeLists.txt +++ b/tools/clang/blink_gc_plugin/CMakeLists.txt
@@ -1,6 +1,6 @@ # This line is read by update.sh and other scripts in tools/clang/scripts # Note: The spaces are significant. -set(LIBRARYNAME BlinkGCPlugin_14) +set(LIBRARYNAME BlinkGCPlugin) add_llvm_loadable_module("lib${LIBRARYNAME}" BlinkGCPlugin.cpp
diff --git a/tools/clang/blink_gc_plugin/Config.h b/tools/clang/blink_gc_plugin/Config.h index c2d39b7..02cbee9a 100644 --- a/tools/clang/blink_gc_plugin/Config.h +++ b/tools/clang/blink_gc_plugin/Config.h
@@ -236,7 +236,7 @@ if (name == kTraceAfterDispatchName) return TRACE_AFTER_DISPATCH_METHOD; if (name == kTraceImplName) - return TRACE_AFTER_DISPATCH_METHOD; + return TRACE_IMPL_METHOD; if (name == kTraceAfterDispatchImplName) return TRACE_AFTER_DISPATCH_IMPL_METHOD;
diff --git a/tools/clang/blink_gc_plugin/Edge.h b/tools/clang/blink_gc_plugin/Edge.h index d0b78b5..7659968 100644 --- a/tools/clang/blink_gc_plugin/Edge.h +++ b/tools/clang/blink_gc_plugin/Edge.h
@@ -24,6 +24,7 @@ // Bare-bones visitor. class EdgeVisitor { public: + virtual ~EdgeVisitor() {} virtual void VisitValue(Value*) {} virtual void VisitRawPtr(RawPtr*) {} virtual void VisitRefPtr(RefPtr*) {}
diff --git a/tools/clang/blink_gc_plugin/RecordInfo.cpp b/tools/clang/blink_gc_plugin/RecordInfo.cpp index 0257415..bda33fa9 100644 --- a/tools/clang/blink_gc_plugin/RecordInfo.cpp +++ b/tools/clang/blink_gc_plugin/RecordInfo.cpp
@@ -427,39 +427,50 @@ if (Config::IsGCBase(name_)) return; CXXMethodDecl* trace = nullptr; + CXXMethodDecl* trace_impl = nullptr; CXXMethodDecl* trace_after_dispatch = nullptr; bool has_adjust_and_mark = false; bool has_is_heap_object_alive = false; - for (CXXRecordDecl::method_iterator it = record_->method_begin(); - it != record_->method_end(); - ++it) { - switch (Config::GetTraceMethodType(*it)) { + for (Decl* decl : record_->decls()) { + CXXMethodDecl* method = dyn_cast<CXXMethodDecl>(decl); + if (!method) { + if (FunctionTemplateDecl* func_template = + dyn_cast<FunctionTemplateDecl>(decl)) + method = dyn_cast<CXXMethodDecl>(func_template->getTemplatedDecl()); + } + if (!method) + continue; + + switch (Config::GetTraceMethodType(method)) { case Config::TRACE_METHOD: - trace = *it; + trace = method; break; case Config::TRACE_AFTER_DISPATCH_METHOD: - trace_after_dispatch = *it; + trace_after_dispatch = method; break; case Config::TRACE_IMPL_METHOD: + trace_impl = method; + break; case Config::TRACE_AFTER_DISPATCH_IMPL_METHOD: break; case Config::NOT_TRACE_METHOD: - if (it->getNameAsString() == kFinalizeName) { - finalize_dispatch_method_ = *it; - } else if (it->getNameAsString() == kAdjustAndMarkName) { + if (method->getNameAsString() == kFinalizeName) { + finalize_dispatch_method_ = method; + } else if (method->getNameAsString() == kAdjustAndMarkName) { has_adjust_and_mark = true; - } else if (it->getNameAsString() == kIsHeapObjectAliveName) { + } else if (method->getNameAsString() == kIsHeapObjectAliveName) { has_is_heap_object_alive = true; } break; } } + // Record if class defines the two GCMixin methods. has_gc_mixin_methods_ = has_adjust_and_mark && has_is_heap_object_alive ? kTrue : kFalse; if (trace_after_dispatch) { trace_method_ = trace_after_dispatch; - trace_dispatch_method_ = trace; + trace_dispatch_method_ = trace_impl ? trace_impl : trace; } else { // TODO: Can we never have a dispatch method called trace without the same // class defining a traceAfterDispatch method?
diff --git a/tools/clang/blink_gc_plugin/RecordInfo.h b/tools/clang/blink_gc_plugin/RecordInfo.h index 82fb604..da2f415 100644 --- a/tools/clang/blink_gc_plugin/RecordInfo.h +++ b/tools/clang/blink_gc_plugin/RecordInfo.h
@@ -23,6 +23,7 @@ class GraphPoint { public: GraphPoint() : traced_(false) {} + virtual ~GraphPoint() {} void MarkTraced() { traced_ = true; } bool IsProperlyTraced() { return traced_ || !NeedsTracing().IsNeeded(); } virtual const TracingStatus NeedsTracing() = 0;
diff --git a/tools/clang/blink_gc_plugin/tests/test.sh b/tools/clang/blink_gc_plugin/tests/test.sh index 02c7477..95bb261 100755 --- a/tools/clang/blink_gc_plugin/tests/test.sh +++ b/tools/clang/blink_gc_plugin/tests/test.sh
@@ -29,6 +29,7 @@ flags="$(cat "${3}")" fi local output="$("${CLANG_PATH}" -c -Wno-c++11-extensions \ + -Wno-inaccessible-base \ -Xclang -load -Xclang "${PLUGIN_PATH}" \ -Xclang -add-plugin -Xclang blink-gc-plugin ${flags} ${1} 2>&1)" local json="${input%cpp}graph.json"
diff --git a/tools/clang/blink_gc_plugin/tests/trace_after_dispatch_impl.cpp b/tools/clang/blink_gc_plugin/tests/trace_after_dispatch_impl.cpp index 706624d..53a6855 100644 --- a/tools/clang/blink_gc_plugin/tests/trace_after_dispatch_impl.cpp +++ b/tools/clang/blink_gc_plugin/tests/trace_after_dispatch_impl.cpp
@@ -6,9 +6,11 @@ namespace blink { -void TraceAfterDispatchInlinedBase::trace(Visitor* visitor) { - // Implement a simple form of manual dispatching, because BlinkGCPlugin gets - // angry if dispatching statements are missing. +template <typename VisitorDispatcher> +inline void TraceAfterDispatchInlinedBase::traceImpl( + VisitorDispatcher visitor) { + // Implement a simple form of manual dispatching, because BlinkGCPlugin + // checks if the tracing is dispatched to all derived classes. // // This function has to be implemented out-of-line, since we need to know the // definition of derived classes here. @@ -21,6 +23,15 @@ } void TraceAfterDispatchExternBase::trace(Visitor* visitor) { + traceImpl(visitor); +} + +void TraceAfterDispatchExternBase::trace(InlinedGlobalMarkingVisitor visitor) { + traceImpl(visitor); +} + +template <typename VisitorDispatcher> +inline void TraceAfterDispatchExternBase::traceImpl(VisitorDispatcher visitor) { if (tag_ == DERIVED) { static_cast<TraceAfterDispatchExternDerived*>(this)->traceAfterDispatch( visitor); @@ -33,6 +44,11 @@ traceAfterDispatchImpl(visitor); } +void TraceAfterDispatchExternBase::traceAfterDispatch( + InlinedGlobalMarkingVisitor visitor) { + traceAfterDispatchImpl(visitor); +} + template <typename VisitorDispatcher> inline void TraceAfterDispatchExternBase::traceAfterDispatchImpl( VisitorDispatcher visitor) { @@ -43,6 +59,11 @@ traceAfterDispatchImpl(visitor); } +void TraceAfterDispatchExternDerived::traceAfterDispatch( + InlinedGlobalMarkingVisitor visitor) { + traceAfterDispatchImpl(visitor); +} + template <typename VisitorDispatcher> inline void TraceAfterDispatchExternDerived::traceAfterDispatchImpl( VisitorDispatcher visitor) {
diff --git a/tools/clang/blink_gc_plugin/tests/trace_after_dispatch_impl.h b/tools/clang/blink_gc_plugin/tests/trace_after_dispatch_impl.h index e55c06e..fe25279 100644 --- a/tools/clang/blink_gc_plugin/tests/trace_after_dispatch_impl.h +++ b/tools/clang/blink_gc_plugin/tests/trace_after_dispatch_impl.h
@@ -23,12 +23,19 @@ public: explicit TraceAfterDispatchInlinedBase(ClassTag tag) : tag_(tag) {} - void trace(Visitor* visitor); + void trace(Visitor* visitor) { traceImpl(visitor); } + void trace(InlinedGlobalMarkingVisitor visitor) { traceImpl(visitor); } void traceAfterDispatch(Visitor* visitor) { traceAfterDispatchImpl(visitor); } + void traceAfterDispatch(InlinedGlobalMarkingVisitor visitor) { + traceAfterDispatchImpl(visitor); + } private: template <typename VisitorDispatcher> + void traceImpl(VisitorDispatcher visitor); + + template <typename VisitorDispatcher> void traceAfterDispatchImpl(VisitorDispatcher visitor) { visitor->trace(x_base_); } @@ -42,6 +49,9 @@ TraceAfterDispatchInlinedDerived() : TraceAfterDispatchInlinedBase(DERIVED) {} void traceAfterDispatch(Visitor* visitor) { traceAfterDispatchImpl(visitor); } + void traceAfterDispatch(InlinedGlobalMarkingVisitor visitor) { + traceAfterDispatchImpl(visitor); + } private: template <typename VisitorDispatcher> @@ -59,11 +69,16 @@ explicit TraceAfterDispatchExternBase(ClassTag tag) : tag_(tag) {} void trace(Visitor* visitor); + void trace(InlinedGlobalMarkingVisitor visitor); void traceAfterDispatch(Visitor* visitor); + void traceAfterDispatch(InlinedGlobalMarkingVisitor visitor); private: template <typename VisitorDispatcher> + void traceImpl(VisitorDispatcher visitor); + + template <typename VisitorDispatcher> void traceAfterDispatchImpl(VisitorDispatcher visitor); ClassTag tag_; @@ -75,6 +90,7 @@ TraceAfterDispatchExternDerived() : TraceAfterDispatchExternBase(DERIVED) {} void traceAfterDispatch(Visitor* visitor); + void traceAfterDispatch(InlinedGlobalMarkingVisitor visitor); private: template <typename VisitorDispatcher>
diff --git a/tools/clang/blink_gc_plugin/tests/trace_after_dispatch_impl_error.cpp b/tools/clang/blink_gc_plugin/tests/trace_after_dispatch_impl_error.cpp index 1ea19364..23798f7 100644 --- a/tools/clang/blink_gc_plugin/tests/trace_after_dispatch_impl_error.cpp +++ b/tools/clang/blink_gc_plugin/tests/trace_after_dispatch_impl_error.cpp
@@ -6,24 +6,37 @@ namespace blink { -void TraceAfterDispatchInlinedBase::trace(Visitor* visitor) { - // Implement a simple form of manual dispatching, because BlinkGCPlugin gets - // angry if dispatching statements are missing. +template <typename VisitorDispatcher> +inline void TraceAfterDispatchInlinedBase::traceImpl( + VisitorDispatcher visitor) { + // Implement a simple form of manual dispatching, because BlinkGCPlugin + // checks if the tracing is dispatched to all derived classes. // // This function has to be implemented out-of-line, since we need to know the // definition of derived classes here. if (tag_ == DERIVED) { - static_cast<TraceAfterDispatchInlinedDerived*>(this)->traceAfterDispatch( - visitor); + // Missing dispatch call: + // static_cast<TraceAfterDispatchInlinedDerived*>(this)->traceAfterDispatch( + // visitor); } else { traceAfterDispatch(visitor); } } void TraceAfterDispatchExternBase::trace(Visitor* visitor) { + traceImpl(visitor); +} + +void TraceAfterDispatchExternBase::trace(InlinedGlobalMarkingVisitor visitor) { + traceImpl(visitor); +} + +template <typename VisitorDispatcher> +inline void TraceAfterDispatchExternBase::traceImpl(VisitorDispatcher visitor) { if (tag_ == DERIVED) { - static_cast<TraceAfterDispatchExternDerived*>(this)->traceAfterDispatch( - visitor); + // Missing dispatch call: + // static_cast<TraceAfterDispatchExternDerived*>(this)->traceAfterDispatch( + // visitor); } else { traceAfterDispatch(visitor); } @@ -33,6 +46,11 @@ traceAfterDispatchImpl(visitor); } +void TraceAfterDispatchExternBase::traceAfterDispatch( + InlinedGlobalMarkingVisitor visitor) { + traceAfterDispatchImpl(visitor); +} + template <typename VisitorDispatcher> inline void TraceAfterDispatchExternBase::traceAfterDispatchImpl( VisitorDispatcher visitor) { @@ -43,6 +61,11 @@ traceAfterDispatchImpl(visitor); } +void TraceAfterDispatchExternDerived::traceAfterDispatch( + InlinedGlobalMarkingVisitor visitor) { + traceAfterDispatchImpl(visitor); +} + template <typename VisitorDispatcher> inline void TraceAfterDispatchExternDerived::traceAfterDispatchImpl( VisitorDispatcher visitor) {
diff --git a/tools/clang/blink_gc_plugin/tests/trace_after_dispatch_impl_error.h b/tools/clang/blink_gc_plugin/tests/trace_after_dispatch_impl_error.h index 441ef32..b480e39 100644 --- a/tools/clang/blink_gc_plugin/tests/trace_after_dispatch_impl_error.h +++ b/tools/clang/blink_gc_plugin/tests/trace_after_dispatch_impl_error.h
@@ -23,12 +23,19 @@ public: explicit TraceAfterDispatchInlinedBase(ClassTag tag) : tag_(tag) {} - void trace(Visitor* visitor); + void trace(Visitor* visitor) { traceImpl(visitor); } + void trace(InlinedGlobalMarkingVisitor visitor) { traceImpl(visitor); } void traceAfterDispatch(Visitor* visitor) { traceAfterDispatchImpl(visitor); } + void traceAfterDispatch(InlinedGlobalMarkingVisitor visitor) { + traceAfterDispatchImpl(visitor); + } private: template <typename VisitorDispatcher> + void traceImpl(VisitorDispatcher visitor); + + template <typename VisitorDispatcher> void traceAfterDispatchImpl(VisitorDispatcher visitor) { // No trace call; should get a warning. } @@ -42,6 +49,9 @@ TraceAfterDispatchInlinedDerived() : TraceAfterDispatchInlinedBase(DERIVED) {} void traceAfterDispatch(Visitor* visitor) { traceAfterDispatchImpl(visitor); } + void traceAfterDispatch(InlinedGlobalMarkingVisitor visitor) { + traceAfterDispatchImpl(visitor); + } private: template <typename VisitorDispatcher> @@ -58,11 +68,16 @@ explicit TraceAfterDispatchExternBase(ClassTag tag) : tag_(tag) {} void trace(Visitor* visitor); + void trace(InlinedGlobalMarkingVisitor visitor); void traceAfterDispatch(Visitor* visitor); + void traceAfterDispatch(InlinedGlobalMarkingVisitor visitor); private: template <typename VisitorDispatcher> + void traceImpl(VisitorDispatcher visitor); + + template <typename VisitorDispatcher> void traceAfterDispatchImpl(VisitorDispatcher visitor); ClassTag tag_; @@ -74,6 +89,7 @@ TraceAfterDispatchExternDerived() : TraceAfterDispatchExternBase(DERIVED) {} void traceAfterDispatch(Visitor* visitor); + void traceAfterDispatch(InlinedGlobalMarkingVisitor visitor); private: template <typename VisitorDispatcher>
diff --git a/tools/clang/blink_gc_plugin/tests/trace_after_dispatch_impl_error.txt b/tools/clang/blink_gc_plugin/tests/trace_after_dispatch_impl_error.txt index 68b5a72..058fccb8 100644 --- a/tools/clang/blink_gc_plugin/tests/trace_after_dispatch_impl_error.txt +++ b/tools/clang/blink_gc_plugin/tests/trace_after_dispatch_impl_error.txt
@@ -1,28 +1,34 @@ +trace_after_dispatch_impl_error.cpp:10:1: warning: [blink-gc] Missing dispatch to class 'TraceAfterDispatchInlinedDerived' in manual trace dispatch. +inline void TraceAfterDispatchInlinedBase::traceImpl( +^ +trace_after_dispatch_impl_error.cpp:35:1: warning: [blink-gc] Missing dispatch to class 'TraceAfterDispatchExternDerived' in manual trace dispatch. +inline void TraceAfterDispatchExternBase::traceImpl(VisitorDispatcher visitor) { +^ In file included from trace_after_dispatch_impl_error.cpp:5: -./trace_after_dispatch_impl_error.h:32:3: warning: [blink-gc] Class 'TraceAfterDispatchInlinedBase' has untraced fields that require tracing. +./trace_after_dispatch_impl_error.h:39:3: warning: [blink-gc] Class 'TraceAfterDispatchInlinedBase' has untraced fields that require tracing. void traceAfterDispatchImpl(VisitorDispatcher visitor) { ^ -./trace_after_dispatch_impl_error.h:37:3: note: [blink-gc] Untraced field 'x_base_' declared here: +./trace_after_dispatch_impl_error.h:44:3: note: [blink-gc] Untraced field 'x_base_' declared here: Member<X> x_base_; ^ -./trace_after_dispatch_impl_error.h:48:3: warning: [blink-gc] Base class 'TraceAfterDispatchInlinedBase' of derived class 'TraceAfterDispatchInlinedDerived' requires tracing. +./trace_after_dispatch_impl_error.h:58:3: warning: [blink-gc] Base class 'TraceAfterDispatchInlinedBase' of derived class 'TraceAfterDispatchInlinedDerived' requires tracing. void traceAfterDispatchImpl(VisitorDispatcher visitor) { ^ -./trace_after_dispatch_impl_error.h:48:3: warning: [blink-gc] Class 'TraceAfterDispatchInlinedDerived' has untraced fields that require tracing. -./trace_after_dispatch_impl_error.h:52:3: note: [blink-gc] Untraced field 'x_derived_' declared here: +./trace_after_dispatch_impl_error.h:58:3: warning: [blink-gc] Class 'TraceAfterDispatchInlinedDerived' has untraced fields that require tracing. +./trace_after_dispatch_impl_error.h:62:3: note: [blink-gc] Untraced field 'x_derived_' declared here: Member<X> x_derived_; ^ -trace_after_dispatch_impl_error.cpp:37:1: warning: [blink-gc] Class 'TraceAfterDispatchExternBase' has untraced fields that require tracing. +trace_after_dispatch_impl_error.cpp:55:1: warning: [blink-gc] Class 'TraceAfterDispatchExternBase' has untraced fields that require tracing. inline void TraceAfterDispatchExternBase::traceAfterDispatchImpl( ^ -./trace_after_dispatch_impl_error.h:69:3: note: [blink-gc] Untraced field 'x_base_' declared here: +./trace_after_dispatch_impl_error.h:84:3: note: [blink-gc] Untraced field 'x_base_' declared here: Member<X> x_base_; ^ -trace_after_dispatch_impl_error.cpp:47:1: warning: [blink-gc] Base class 'TraceAfterDispatchExternBase' of derived class 'TraceAfterDispatchExternDerived' requires tracing. +trace_after_dispatch_impl_error.cpp:70:1: warning: [blink-gc] Base class 'TraceAfterDispatchExternBase' of derived class 'TraceAfterDispatchExternDerived' requires tracing. inline void TraceAfterDispatchExternDerived::traceAfterDispatchImpl( ^ -trace_after_dispatch_impl_error.cpp:47:1: warning: [blink-gc] Class 'TraceAfterDispatchExternDerived' has untraced fields that require tracing. -./trace_after_dispatch_impl_error.h:82:3: note: [blink-gc] Untraced field 'x_derived_' declared here: +trace_after_dispatch_impl_error.cpp:70:1: warning: [blink-gc] Class 'TraceAfterDispatchExternDerived' has untraced fields that require tracing. +./trace_after_dispatch_impl_error.h:98:3: note: [blink-gc] Untraced field 'x_derived_' declared here: Member<X> x_derived_; ^ -6 warnings generated. +8 warnings generated.
diff --git a/tools/clang/blink_gc_plugin/tests/traceimpl_omitted_trace.cpp b/tools/clang/blink_gc_plugin/tests/traceimpl_omitted_trace.cpp new file mode 100644 index 0000000..b6dc2dff --- /dev/null +++ b/tools/clang/blink_gc_plugin/tests/traceimpl_omitted_trace.cpp
@@ -0,0 +1,7 @@ +// 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 "traceimpl_omitted_trace.h" + +// Nothing to define here.
diff --git a/tools/clang/blink_gc_plugin/tests/traceimpl_omitted_trace.h b/tools/clang/blink_gc_plugin/tests/traceimpl_omitted_trace.h new file mode 100644 index 0000000..3c5e955 --- /dev/null +++ b/tools/clang/blink_gc_plugin/tests/traceimpl_omitted_trace.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 TRACEIMPL_OMITTED_TRACE_H_ +#define TRACEIMPL_OMITTED_TRACE_H_ + +#include "heap/stubs.h" + +namespace blink { + +class A : public GarbageCollected<A> { + public: + virtual void trace(Visitor* visitor) { traceImpl(visitor); } + virtual void trace(InlinedGlobalMarkingVisitor visitor) { + traceImpl(visitor); + } + + private: + template <typename VisitorDispatcher> + void traceImpl(VisitorDispatcher visitor) {} +}; + +class B : public A { + // trace() isn't necessary because we've got nothing to trace here. +}; + +class C : public B { + public: + void trace(Visitor* visitor) override { traceImpl(visitor); } + void trace(InlinedGlobalMarkingVisitor visitor) override { + traceImpl(visitor); + } + + private: + template <typename VisitorDispatcher> + void traceImpl(VisitorDispatcher visitor) { + // B::trace() is actually A::trace(), and in certain cases we only get + // limited information like "there is a function call that will be resolved + // to A::trace()". We still want to mark B as traced. + B::trace(visitor); + } +}; + +} + +#endif // TRACEIMPL_OMITTED_TRACE_H_
diff --git a/tools/clang/blink_gc_plugin/tests/traceimpl_omitted_trace.txt b/tools/clang/blink_gc_plugin/tests/traceimpl_omitted_trace.txt new file mode 100644 index 0000000..8b13789 --- /dev/null +++ b/tools/clang/blink_gc_plugin/tests/traceimpl_omitted_trace.txt
@@ -0,0 +1 @@ +
diff --git a/tools/clang/scripts/blink_gc_plugin_flags.sh b/tools/clang/scripts/blink_gc_plugin_flags.sh index 3654808..38ea72d 100755 --- a/tools/clang/scripts/blink_gc_plugin_flags.sh +++ b/tools/clang/scripts/blink_gc_plugin_flags.sh
@@ -13,9 +13,6 @@ else LIBSUFFIX=so fi -LIBNAME=\ -$(grep 'set(LIBRARYNAME' "$SRC_DIR"/tools/clang/blink_gc_plugin/CMakeLists.txt \ - | cut -d ' ' -f 2 | tr -d ')') FLAGS="" PREFIX="-Xclang -plugin-arg-blink-gc-plugin -Xclang" @@ -31,5 +28,5 @@ fi done -echo -Xclang -load -Xclang $CLANG_LIB_PATH/lib$LIBNAME.$LIBSUFFIX \ +echo -Xclang -load -Xclang $CLANG_LIB_PATH/libBlinkGCPlugin.$LIBSUFFIX \ -Xclang -add-plugin -Xclang blink-gc-plugin $FLAGS
diff --git a/tools/clang/scripts/package.sh b/tools/clang/scripts/package.sh index e0c0fcc4..453a166 100755 --- a/tools/clang/scripts/package.sh +++ b/tools/clang/scripts/package.sh
@@ -52,6 +52,7 @@ LLVM_BUILD_DIR="${THIS_DIR}/../../../third_party/llvm-build" LLVM_BIN_DIR="${LLVM_BUILD_DIR}/Release+Asserts/bin" LLVM_LIB_DIR="${LLVM_BUILD_DIR}/Release+Asserts/lib" +STAMP_FILE="${LLVM_DIR}/../llvm-build/cr_build_revision" echo "Diff in llvm:" | tee buildlog.txt svn stat "${LLVM_DIR}" 2>&1 | tee -a buildlog.txt @@ -86,8 +87,7 @@ "${THIS_DIR}"/update.sh --bootstrap --force-local-build --run-tests \ ${extra_flags} 2>&1 | tee -a buildlog.txt -R=$("${LLVM_BIN_DIR}/clang" --version | \ - sed -ne 's/clang version .*(trunk \([0-9]*\))/\1/p') +R=$(cat "${STAMP_FILE}") PDIR=clang-$R rm -rf $PDIR @@ -122,11 +122,7 @@ # Copy plugins. Some of the dylibs are pretty big, so copy only the ones we # care about. cp "${LLVM_LIB_DIR}/libFindBadConstructs.${SO_EXT}" $PDIR/lib - -BLINKGCPLUGIN_LIBNAME=\ -$(grep 'set(LIBRARYNAME' "$THIS_DIR"/../blink_gc_plugin/CMakeLists.txt \ - | cut -d ' ' -f 2 | tr -d ')') -cp "${LLVM_LIB_DIR}/lib${BLINKGCPLUGIN_LIBNAME}.${SO_EXT}" $PDIR/lib +cp "${LLVM_LIB_DIR}/libBlinkGCPlugin.${SO_EXT}" $PDIR/lib if [[ -n "${gcc_toolchain}" ]]; then # Copy the stdlibc++.so.6 we linked Clang against so it can run. @@ -182,3 +178,5 @@ echo To upload, run: echo gsutil cp -a public-read $PDIR.tgz \ gs://chromium-browser-clang/$PLATFORM/$PDIR.tgz + +# FIXME: Warn if the file already exists on the server.
diff --git a/tools/clang/scripts/plugin_flags.sh b/tools/clang/scripts/plugin_flags.sh index 81fe0f1d..41c25c8 100755 --- a/tools/clang/scripts/plugin_flags.sh +++ b/tools/clang/scripts/plugin_flags.sh
@@ -17,6 +17,4 @@ fi echo -Xclang -load -Xclang $CLANG_LIB_PATH/libFindBadConstructs.$LIBSUFFIX \ - -Xclang -add-plugin -Xclang find-bad-constructs \ - -Xclang -plugin-arg-find-bad-constructs -Xclang check-weak-ptr-factory-order \ - -Xclang -plugin-arg-find-bad-constructs -Xclang strict-virtual-specifiers + -Xclang -add-plugin -Xclang find-bad-constructs
diff --git a/tools/clang/scripts/repackage.sh b/tools/clang/scripts/repackage.sh deleted file mode 100755 index e19ab7e8..0000000 --- a/tools/clang/scripts/repackage.sh +++ /dev/null
@@ -1,67 +0,0 @@ -#!/bin/bash -# 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 script will check out llvm and clang, build a full package -# with the latest plugin revisions and then repackage an existing -# clang-package with the new plugin revisions. - -# The new package can be uploaded to replace the existing clang -# package at the same clang revision. - -THIS_DIR="$(dirname "${0}")" -LLVM_BUILD_DIR="${THIS_DIR}/../../../third_party/llvm-build" -LLVM_TAR_DIR="${LLVM_BUILD_DIR}/Release+Asserts" -LLVM_BIN_DIR="${LLVM_TAR_DIR}/bin" -LLVM_LIB_DIR="${LLVM_TAR_DIR}/lib" - -set -eu - -if [ "$(uname -s)" = "Darwin" ]; then - PLATFORM=Mac - SO_EXT="dylib" -else - PLATFORM=Linux_x64 - SO_EXT="so" -fi - -# Build clang with the new plugin revisions. -"$THIS_DIR"/package.sh $@ - -R=$("${LLVM_BIN_DIR}/clang" --version | \ - sed -ne 's/clang version .*(trunk \([0-9]*\))/\1/p') -PDIR=clang-$R - -if [ ! -f "$PDIR.tgz" ]; then - echo "Could not find package archive $PDIR.tgz generated by package.sh" - exit 1 -fi - -# We don't want to change the clang binary, so fetch the current clang -# package and add the plugin shared-libraries to the existing package. -rm -rf $LLVM_BUILD_DIR -"$THIS_DIR"/update.sh - -LIBNAME=\ -$(grep 'set(LIBRARYNAME' "$THIS_DIR"/../blink_gc_plugin/CMakeLists.txt \ - | cut -d ' ' -f 2 | tr -d ')') -LIBFILE=lib$LIBNAME.$SO_EXT - -# Check that we are actually creating the plugin at a new revision. -if [ -f "$LLVM_LIB_DIR/$LIBFILE" ]; then - echo "The plugin revision $LIBNAME is already in the existing package." - exit 1 -fi - -cp $PDIR/lib/$LIBFILE "$LLVM_LIB_DIR/" -if [ "$(uname -s)" = "Darwin" ]; then - tar zcf ${PDIR}_repack.tgz -C "$LLVM_TAR_DIR" bin include lib buildlog.txt -else - tar zcf ${PDIR}_repack.tgz -C "$LLVM_TAR_DIR" bin lib buildlog.txt -fi - -echo The clang package has been repackaged with $LIBNAME -echo To upload, run: -echo gsutil cp -a public-read ${PDIR}_repack.tgz \ - gs://chromium-browser-clang/$PLATFORM/$PDIR.tgz
diff --git a/tools/clang/scripts/update.sh b/tools/clang/scripts/update.sh index e8b929f..798f7d2 100755 --- a/tools/clang/scripts/update.sh +++ b/tools/clang/scripts/update.sh
@@ -8,7 +8,12 @@ # Do NOT CHANGE this if you don't know what you're doing -- see # https://code.google.com/p/chromium/wiki/UpdatingClang # Reverting problematic clang rolls is safe, though. -CLANG_REVISION=223108 +CLANG_REVISION=230914 + +# This is incremented when pushing a new build of Clang at the same revision. +CLANG_SUB_REVISION=1 + +PACKAGE_VERSION="${CLANG_REVISION}-${CLANG_SUB_REVISION}" THIS_DIR="$(dirname "${0}")" LLVM_DIR="${THIS_DIR}/../../../third_party/llvm" @@ -88,7 +93,7 @@ force_local_build=yes ;; --print-revision) - echo $CLANG_REVISION + echo $PACKAGE_VERSION exit 0 ;; --run-tests) @@ -198,8 +203,8 @@ PREVIOUSLY_BUILT_REVISON=$(cat "${STAMP_FILE}") if [[ -z "$force_local_build" ]] && \ [[ "${PREVIOUSLY_BUILT_REVISON}" = \ - "${CLANG_AND_PLUGINS_REVISION}" ]]; then - echo "Clang already at ${CLANG_AND_PLUGINS_REVISION}" + "${PACKAGE_VERSION}" ]]; then + echo "Clang already at ${PACKAGE_VERSION}" exit 0 fi fi @@ -211,7 +216,7 @@ # Check if there's a prebuilt binary and if so just fetch that. That's faster, # and goma relies on having matching binary hashes on client and server too. CDS_URL=https://commondatastorage.googleapis.com/chromium-browser-clang - CDS_FILE="clang-${CLANG_REVISION}.tgz" + CDS_FILE="clang-${PACKAGE_VERSION}.tgz" CDS_OUT_DIR=$(mktemp -d -t clang_download.XXXXXX) CDS_OUTPUT="${CDS_OUT_DIR}/${CDS_FILE}" if [ "${OS}" = "Linux" ]; then @@ -233,12 +238,12 @@ rm -rf "${LLVM_BUILD_DIR}" mkdir -p "${LLVM_BUILD_DIR}" tar -xzf "${CDS_OUTPUT}" -C "${LLVM_BUILD_DIR}" - echo clang "${CLANG_REVISION}" unpacked - echo "${CLANG_AND_PLUGINS_REVISION}" > "${STAMP_FILE}" + echo clang "${PACKAGE_VERSION}" unpacked + echo "${PACKAGE_VERSION}" > "${STAMP_FILE}" rm -rf "${CDS_OUT_DIR}" exit 0 else - echo Did not find prebuilt clang at r"${CLANG_REVISION}", building + echo Did not find prebuilt clang "${PACKAGE_VERSION}", building fi fi @@ -282,6 +287,8 @@ "${CLANG_DIR}/lib/Sema/SemaExprCXX.cpp" \ "${CLANG_DIR}/test/SemaCXX/default2.cpp" \ "${CLANG_DIR}/test/SemaCXX/typo-correction-delayed.cpp" \ + "${COMPILER_RT_DIR}/lib/sanitizer_common/sanitizer_stoptheworld_linux_libcdep.cc" \ + "${COMPILER_RT_DIR}/test/tsan/signal_segv_handler.cc" \ ; do if [[ -e "${i}" ]]; then rm -f "${i}" # For unversioned files. @@ -364,349 +371,6 @@ patch -p0 popd - # Apply r223211: "Revert r222997." - pushd "${LLVM_DIR}" - cat << 'EOF' | ---- a/lib/Transforms/Instrumentation/MemorySanitizer.cpp -+++ b/lib/Transforms/Instrumentation/MemorySanitizer.cpp -@@ -921,8 +921,6 @@ struct MemorySanitizerVisitor : public InstVisitor<MemorySanitizerVisitor> { - Value *OriginPtr = - getOriginPtrForArgument(&FArg, EntryIRB, ArgOffset); - setOrigin(A, EntryIRB.CreateLoad(OriginPtr)); -- } else { -- setOrigin(A, getCleanOrigin()); - } - } - ArgOffset += RoundUpToAlignment(Size, kShadowTLSAlignment); -@@ -942,13 +940,15 @@ struct MemorySanitizerVisitor : public InstVisitor<MemorySanitizerVisitor> { - /// \brief Get the origin for a value. - Value *getOrigin(Value *V) { - if (!MS.TrackOrigins) return nullptr; -- if (!PropagateShadow) return getCleanOrigin(); -- if (isa<Constant>(V)) return getCleanOrigin(); -- assert((isa<Instruction>(V) || isa<Argument>(V)) && -- "Unexpected value type in getOrigin()"); -- Value *Origin = OriginMap[V]; -- assert(Origin && "Missing origin"); -- return Origin; -+ if (isa<Instruction>(V) || isa<Argument>(V)) { -+ Value *Origin = OriginMap[V]; -+ if (!Origin) { -+ DEBUG(dbgs() << "NO ORIGIN: " << *V << "\n"); -+ Origin = getCleanOrigin(); -+ } -+ return Origin; -+ } -+ return getCleanOrigin(); - } - - /// \brief Get the origin for i-th argument of the instruction I. -@@ -1088,7 +1088,6 @@ struct MemorySanitizerVisitor : public InstVisitor<MemorySanitizerVisitor> { - IRB.CreateStore(getCleanShadow(&I), ShadowPtr); - - setShadow(&I, getCleanShadow(&I)); -- setOrigin(&I, getCleanOrigin()); - } - - void visitAtomicRMWInst(AtomicRMWInst &I) { -EOF - patch -p1 - popd - - # Apply r223219: "Preserve LD_LIBRARY_PATH when using the 'env' command" - pushd "${CLANG_DIR}" - cat << 'EOF' | ---- a/test/Driver/env.c -+++ b/test/Driver/env.c -@@ -5,12 +5,14 @@ - // REQUIRES: shell - // - // The PATH variable is heavily used when trying to find a linker. --// RUN: env -i LC_ALL=C %clang -no-canonical-prefixes %s -### -o %t.o 2>&1 \ -+// RUN: env -i LC_ALL=C LD_LIBRARY_PATH="$LD_LIBRARY_PATH" \ -+// RUN: %clang -no-canonical-prefixes %s -### -o %t.o 2>&1 \ - // RUN: --target=i386-unknown-linux \ - // RUN: --sysroot=%S/Inputs/basic_linux_tree \ - // RUN: | FileCheck --check-prefix=CHECK-LD-32 %s - // --// RUN: env -i LC_ALL=C PATH="" %clang -no-canonical-prefixes %s -### -o %t.o 2>&1 \ -+// RUN: env -i LC_ALL=C PATH="" LD_LIBRARY_PATH="$LD_LIBRARY_PATH" \ -+// RUN: %clang -no-canonical-prefixes %s -### -o %t.o 2>&1 \ - // RUN: --target=i386-unknown-linux \ - // RUN: --sysroot=%S/Inputs/basic_linux_tree \ - // RUN: | FileCheck --check-prefix=CHECK-LD-32 %s -EOF - patch -p1 - popd - - # Revert r220714: "Frontend: Define __EXCEPTIONS if -fexceptions is passed" - pushd "${CLANG_DIR}" - cat << 'EOF' | ---- a/lib/Frontend/InitPreprocessor.cpp -+++ b/lib/Frontend/InitPreprocessor.cpp -@@ -566,7 +566,7 @@ static void InitializePredefinedMacros(const TargetInfo &TI, - Builder.defineMacro("__BLOCKS__"); - } - -- if (!LangOpts.MSVCCompat && LangOpts.Exceptions) -+ if (!LangOpts.MSVCCompat && LangOpts.CXXExceptions) - Builder.defineMacro("__EXCEPTIONS"); - if (!LangOpts.MSVCCompat && LangOpts.RTTI) - Builder.defineMacro("__GXX_RTTI"); -diff --git a/test/Frontend/exceptions.c b/test/Frontend/exceptions.c -index 981b5b9..4bbaaa3 100644 ---- a/test/Frontend/exceptions.c -+++ b/test/Frontend/exceptions.c -@@ -1,9 +1,6 @@ --// RUN: %clang_cc1 -fms-compatibility -fexceptions -fcxx-exceptions -DMS_MODE -verify %s -+// RUN: %clang_cc1 -fms-compatibility -fexceptions -fcxx-exceptions -verify %s - // expected-no-diagnostics - --// RUN: %clang_cc1 -fms-compatibility -fexceptions -verify %s --// expected-no-diagnostics -- --#if defined(MS_MODE) && defined(__EXCEPTIONS) -+#if defined(__EXCEPTIONS) - #error __EXCEPTIONS should not be defined. - #endif -diff --git a/test/Preprocessor/predefined-exceptions.m b/test/Preprocessor/predefined-exceptions.m -index 0791075..c13f429 100644 ---- a/test/Preprocessor/predefined-exceptions.m -+++ b/test/Preprocessor/predefined-exceptions.m -@@ -1,6 +1,6 @@ - // RUN: %clang_cc1 -x objective-c -fobjc-exceptions -fexceptions -E -dM %s | FileCheck -check-prefix=CHECK-OBJC-NOCXX %s - // CHECK-OBJC-NOCXX: #define OBJC_ZEROCOST_EXCEPTIONS 1 --// CHECK-OBJC-NOCXX: #define __EXCEPTIONS 1 -+// CHECK-OBJC-NOCXX-NOT: #define __EXCEPTIONS 1 - - // RUN: %clang_cc1 -x objective-c++ -fobjc-exceptions -fexceptions -fcxx-exceptions -E -dM %s | FileCheck -check-prefix=CHECK-OBJC-CXX %s - // CHECK-OBJC-CXX: #define OBJC_ZEROCOST_EXCEPTIONS 1 -EOF - patch -p1 - popd - - # Apply r223177: "Ensure typos in the default values of template parameters get diagnosed." - pushd "${CLANG_DIR}" - cat << 'EOF' | ---- a/lib/Parse/ParseTemplate.cpp -+++ b/lib/Parse/ParseTemplate.cpp -@@ -676,7 +676,7 @@ Parser::ParseNonTypeTemplateParameter(unsigned Depth, unsigned Position) { - GreaterThanIsOperatorScope G(GreaterThanIsOperator, false); - EnterExpressionEvaluationContext Unevaluated(Actions, Sema::Unevaluated); - -- DefaultArg = ParseAssignmentExpression(); -+ DefaultArg = Actions.CorrectDelayedTyposInExpr(ParseAssignmentExpression()); - if (DefaultArg.isInvalid()) - SkipUntil(tok::comma, tok::greater, StopAtSemi | StopBeforeMatch); - } -diff --git a/test/SemaCXX/default2.cpp b/test/SemaCXX/default2.cpp -index 1626044..c4d40b4 100644 ---- a/test/SemaCXX/default2.cpp -+++ b/test/SemaCXX/default2.cpp -@@ -122,3 +122,9 @@ class XX { - void A(int length = -1 ) { } - void B() { A(); } - }; -+ -+template <int I = (1 * I)> struct S {}; // expected-error-re {{use of undeclared identifier 'I'{{$}}}} -+S<1> s; -+ -+template <int I1 = I2, int I2 = 1> struct T {}; // expected-error-re {{use of undeclared identifier 'I2'{{$}}}} -+T<0, 1> t; -diff --git a/test/SemaCXX/typo-correction-delayed.cpp b/test/SemaCXX/typo-correction-delayed.cpp -index bff1d76..7bf9258 100644 ---- a/test/SemaCXX/typo-correction-delayed.cpp -+++ b/test/SemaCXX/typo-correction-delayed.cpp -@@ -102,3 +102,7 @@ void f(int *i) { - __atomic_load(i, i, something_something); // expected-error-re {{use of undeclared identifier 'something_something'{{$}}}} - } - } -+ -+const int DefaultArg = 9; // expected-note {{'DefaultArg' declared here}} -+template <int I = defaultArg> struct S {}; // expected-error {{use of undeclared identifier 'defaultArg'; did you mean 'DefaultArg'?}} -+S<1> s; -EOF - patch -p1 - popd - - # Apply r223209: "Handle delayed corrections in a couple more error paths in ParsePostfixExpressionSuffix." - pushd "${CLANG_DIR}" - cat << 'EOF' | ---- a/lib/Parse/ParseExpr.cpp -+++ b/lib/Parse/ParseExpr.cpp -@@ -1390,6 +1390,7 @@ Parser::ParsePostfixExpressionSuffix(ExprResult LHS) { - SourceLocation OpenLoc = ConsumeToken(); - - if (ParseSimpleExpressionList(ExecConfigExprs, ExecConfigCommaLocs)) { -+ (void)Actions.CorrectDelayedTyposInExpr(LHS); - LHS = ExprError(); - } - -@@ -1440,6 +1441,7 @@ Parser::ParsePostfixExpressionSuffix(ExprResult LHS) { - if (Tok.isNot(tok::r_paren)) { - if (ParseExpressionList(ArgExprs, CommaLocs, &Sema::CodeCompleteCall, - LHS.get())) { -+ (void)Actions.CorrectDelayedTyposInExpr(LHS); - LHS = ExprError(); - } - } -diff --git a/test/SemaCXX/typo-correction-delayed.cpp b/test/SemaCXX/typo-correction-delayed.cpp -index 7bf9258..f7ef015 100644 ---- a/test/SemaCXX/typo-correction-delayed.cpp -+++ b/test/SemaCXX/typo-correction-delayed.cpp -@@ -106,3 +106,9 @@ void f(int *i) { - const int DefaultArg = 9; // expected-note {{'DefaultArg' declared here}} - template <int I = defaultArg> struct S {}; // expected-error {{use of undeclared identifier 'defaultArg'; did you mean 'DefaultArg'?}} - S<1> s; -+ -+namespace foo {} -+void test_paren_suffix() { -+ foo::bar({5, 6}); // expected-error-re {{no member named 'bar' in namespace 'foo'{{$}}}} \ -+ // expected-error {{expected expression}} -+} -EOF - patch -p1 - popd - - # Apply r223705: "Handle possible TypoExprs in member initializers." - pushd "${CLANG_DIR}" - cat << 'EOF' | ---- a/lib/Sema/SemaDeclCXX.cpp -+++ b/lib/Sema/SemaDeclCXX.cpp -@@ -2813,6 +2813,11 @@ Sema::BuildMemInitializer(Decl *ConstructorD, - SourceLocation IdLoc, - Expr *Init, - SourceLocation EllipsisLoc) { -+ ExprResult Res = CorrectDelayedTyposInExpr(Init); -+ if (!Res.isUsable()) -+ return true; -+ Init = Res.get(); -+ - if (!ConstructorD) - return true; - -diff --git a/test/SemaCXX/typo-correction-delayed.cpp b/test/SemaCXX/typo-correction-delayed.cpp -index f7ef015..d303b58 100644 ---- a/test/SemaCXX/typo-correction-delayed.cpp -+++ b/test/SemaCXX/typo-correction-delayed.cpp -@@ -112,3 +112,10 @@ void test_paren_suffix() { - foo::bar({5, 6}); // expected-error-re {{no member named 'bar' in namespace 'foo'{{$}}}} \ - // expected-error {{expected expression}} - } -+ -+const int kNum = 10; // expected-note {{'kNum' declared here}} -+class SomeClass { -+ int Kind; -+public: -+ explicit SomeClass() : Kind(kSum) {} // expected-error {{use of undeclared identifier 'kSum'; did you mean 'kNum'?}} -+}; -EOF - patch -p1 - popd - - # Apply r224172: "Typo correction: Ignore temporary binding exprs after overload resolution" - pushd "${CLANG_DIR}" - cat << 'EOF' | ---- a/lib/Sema/SemaExprCXX.cpp -+++ b/lib/Sema/SemaExprCXX.cpp -@@ -6105,8 +6105,13 @@ public: - auto Result = BaseTransform::RebuildCallExpr(Callee, LParenLoc, Args, - RParenLoc, ExecConfig); - if (auto *OE = dyn_cast<OverloadExpr>(Callee)) { -- if (!Result.isInvalid() && Result.get()) -- OverloadResolution[OE] = cast<CallExpr>(Result.get())->getCallee(); -+ if (!Result.isInvalid() && Result.get()) { -+ Expr *ResultCall = Result.get(); -+ if (auto *BE = dyn_cast<CXXBindTemporaryExpr>(ResultCall)) -+ ResultCall = BE->getSubExpr(); -+ if (auto *CE = dyn_cast<CallExpr>(ResultCall)) -+ OverloadResolution[OE] = CE->getCallee(); -+ } - } - return Result; - } -diff --git a/test/SemaCXX/typo-correction-delayed.cpp b/test/SemaCXX/typo-correction-delayed.cpp -index d303b58..d42888f 100644 ---- a/test/SemaCXX/typo-correction-delayed.cpp -+++ b/test/SemaCXX/typo-correction-delayed.cpp -@@ -119,3 +119,23 @@ class SomeClass { - public: - explicit SomeClass() : Kind(kSum) {} // expected-error {{use of undeclared identifier 'kSum'; did you mean 'kNum'?}} - }; -+ -+extern "C" int printf(const char *, ...); -+ -+// There used to be an issue with typo resolution inside overloads. -+struct AssertionResult { -+ ~AssertionResult(); -+ operator bool(); -+ int val; -+}; -+AssertionResult Compare(const char *a, const char *b); -+AssertionResult Compare(int a, int b); -+int main() { -+ // expected-note@+1 {{'result' declared here}} -+ const char *result; -+ // expected-error@+1 {{use of undeclared identifier 'resulta'; did you mean 'result'?}} -+ if (AssertionResult ar = (Compare("value1", resulta))) -+ ; -+ else -+ printf("ar: %d\n", ar.val); -+} -EOF - patch -p1 - popd - - # Apply r224173: "Implement feedback on r224172 in PR21899" - pushd "${CLANG_DIR}" - cat << 'EOF' | ---- a/lib/Sema/SemaExprCXX.cpp -+++ b/lib/Sema/SemaExprCXX.cpp -@@ -6105,7 +6105,7 @@ public: - auto Result = BaseTransform::RebuildCallExpr(Callee, LParenLoc, Args, - RParenLoc, ExecConfig); - if (auto *OE = dyn_cast<OverloadExpr>(Callee)) { -- if (!Result.isInvalid() && Result.get()) { -+ if (Result.isUsable()) { - Expr *ResultCall = Result.get(); - if (auto *BE = dyn_cast<CXXBindTemporaryExpr>(ResultCall)) - ResultCall = BE->getSubExpr(); -diff --git a/test/SemaCXX/typo-correction-delayed.cpp b/test/SemaCXX/typo-correction-delayed.cpp -index d42888f..7879d29 100644 ---- a/test/SemaCXX/typo-correction-delayed.cpp -+++ b/test/SemaCXX/typo-correction-delayed.cpp -@@ -120,22 +120,13 @@ public: - explicit SomeClass() : Kind(kSum) {} // expected-error {{use of undeclared identifier 'kSum'; did you mean 'kNum'?}} - }; - --extern "C" int printf(const char *, ...); -- - // There used to be an issue with typo resolution inside overloads. --struct AssertionResult { -- ~AssertionResult(); -- operator bool(); -- int val; --}; --AssertionResult Compare(const char *a, const char *b); --AssertionResult Compare(int a, int b); --int main() { -+struct AssertionResult { ~AssertionResult(); }; -+AssertionResult Overload(const char *a); -+AssertionResult Overload(int a); -+void UseOverload() { - // expected-note@+1 {{'result' declared here}} - const char *result; - // expected-error@+1 {{use of undeclared identifier 'resulta'; did you mean 'result'?}} -- if (AssertionResult ar = (Compare("value1", resulta))) -- ; -- else -- printf("ar: %d\n", ar.val); -+ Overload(resulta); - } -EOF - patch -p1 - popd - # This Go bindings test doesn't work after the bootstrap build on Linux. (PR21552) pushd "${LLVM_DIR}" cat << 'EOF' | @@ -723,6 +387,7 @@ patch -p0 popd + fi # Echo all commands. @@ -975,4 +640,4 @@ fi # After everything is done, log success for this revision. -echo "${CLANG_AND_PLUGINS_REVISION}" > "${STAMP_FILE}" +echo "${PACKAGE_VERSION}" > "${STAMP_FILE}"
diff --git a/tools/gn/c_include_iterator.h b/tools/gn/c_include_iterator.h index 86c5ede..94ebca14 100644 --- a/tools/gn/c_include_iterator.h +++ b/tools/gn/c_include_iterator.h
@@ -52,4 +52,4 @@ DISALLOW_COPY_AND_ASSIGN(CIncludeIterator); }; -#endif // TOOLS_GN_INCLUDE_ITERATOR_H_ +#endif // TOOLS_GN_C_INCLUDE_ITERATOR_H_
diff --git a/tools/gn/commands.h b/tools/gn/commands.h index dd2cb1b..239c07b5 100644 --- a/tools/gn/commands.h +++ b/tools/gn/commands.h
@@ -173,4 +173,4 @@ } // namespace commands -#endif // TOOLS_GN_COMMANDS_H +#endif // TOOLS_GN_COMMANDS_H_
diff --git a/tools/gn/example/hello_shared.h b/tools/gn/example/hello_shared.h index f62b5ee..7af804b3 100644 --- a/tools/gn/example/hello_shared.h +++ b/tools/gn/example/hello_shared.h
@@ -2,8 +2,8 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#ifndef HELLO_SHARED_H_ -#define HELLO_SHARED_H_ +#ifndef TOOLS_GN_EXAMPLE_HELLO_SHARED_H_ +#define TOOLS_GN_EXAMPLE_HELLO_SHARED_H_ #if defined(WIN32) @@ -17,16 +17,16 @@ #else -#if defined(HELLO_IMPLEMENTATION) +#if defined(HELLO_SHARED_IMPLEMENTATION) #define HELLO_EXPORT __attribute__((visibility("default"))) #define HELLO_EXPORT_PRIVATE __attribute__((visibility("default"))) #else #define HELLO_EXPORT #define HELLO_EXPORT_PRIVATE -#endif // defined(HELLO_IMPLEMENTATION) +#endif // defined(HELLO_SHARED_IMPLEMENTATION) #endif HELLO_EXPORT const char* GetSharedText(); -#endif // HELLO_SHARED_H_ +#endif // TOOLS_GN_EXAMPLE_HELLO_SHARED_H_
diff --git a/tools/gn/example/hello_static.h b/tools/gn/example/hello_static.h index 248ca050..f15a633 100644 --- a/tools/gn/example/hello_static.h +++ b/tools/gn/example/hello_static.h
@@ -2,9 +2,9 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#ifndef HELLO_STATIC_H_ -#define HELLO_STATIC_H_ +#ifndef TOOLS_GN_EXAMPLE_HELLO_STATIC_H_ +#define TOOLS_GN_EXAMPLE_HELLO_STATIC_H_ const char* GetStaticText(); -#endif // HELLO_STATIC_H_ +#endif // TOOLS_GN_EXAMPLE_HELLO_STATIC_H_
diff --git a/tools/gn/ninja_build_writer.h b/tools/gn/ninja_build_writer.h index 427b54e..6f7bf38 100644 --- a/tools/gn/ninja_build_writer.h +++ b/tools/gn/ninja_build_writer.h
@@ -58,5 +58,5 @@ DISALLOW_COPY_AND_ASSIGN(NinjaBuildWriter); }; -#endif // TOOLS_GN_NINJA_BUILD_GENERATOR_H_ +#endif // TOOLS_GN_NINJA_BUILD_WRITER_H_
diff --git a/tools/gn/substitution_list.h b/tools/gn/substitution_list.h index 3a45ba8..f3e3c01 100644 --- a/tools/gn/substitution_list.h +++ b/tools/gn/substitution_list.h
@@ -2,8 +2,8 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#ifndef TOOLS_GN_SUBSTUTITION_LIST_H -#define TOOLS_GN_SUBSTUTITION_LIST_H +#ifndef TOOLS_GN_SUBSTITUTION_LIST_H_ +#define TOOLS_GN_SUBSTITUTION_LIST_H_ #include <string> #include <vector> @@ -43,4 +43,4 @@ std::vector<SubstitutionType> required_types_; }; -#endif // TOOLS_GN_SUBSTUTITION_LIST_H +#endif // TOOLS_GN_SUBSTITUTION_LIST_H_
diff --git a/tools/ipc_fuzzer/mutate/generate.cc b/tools/ipc_fuzzer/mutate/generate.cc index ba3dc997..aa4b09b 100644 --- a/tools/ipc_fuzzer/mutate/generate.cc +++ b/tools/ipc_fuzzer/mutate/generate.cc
@@ -992,7 +992,8 @@ static bool Generate(content::SyntheticGesturePacket* p, Generator* generator) { scoped_ptr<content::SyntheticGestureParams> gesture_params; - switch (RandInRange(3)) { + switch (RandInRange( + content::SyntheticGestureParams::SYNTHETIC_GESTURE_TYPE_MAX + 1)) { case content::SyntheticGestureParams::GestureType:: SMOOTH_SCROLL_GESTURE: { content::SyntheticSmoothScrollGestureParams* params = @@ -1008,6 +1009,18 @@ gesture_params.reset(params); break; } + case content::SyntheticGestureParams::GestureType::SMOOTH_DRAG_GESTURE: { + content::SyntheticSmoothDragGestureParams* params = + new content::SyntheticSmoothDragGestureParams(); + if (!GenerateParam(¶ms->start_point, generator)) + return false; + if (!GenerateParam(¶ms->distances, generator)) + return false; + if (!GenerateParam(¶ms->speed_in_pixels_s, generator)) + return false; + gesture_params.reset(params); + break; + } case content::SyntheticGestureParams::GestureType::PINCH_GESTURE: { content::SyntheticPinchGestureParams* params = new content::SyntheticPinchGestureParams();
diff --git a/tools/metrics/histograms/histograms.xml b/tools/metrics/histograms/histograms.xml index 79775fa..469d2a6d 100644 --- a/tools/metrics/histograms/histograms.xml +++ b/tools/metrics/histograms/histograms.xml
@@ -6488,6 +6488,80 @@ </summary> </histogram> +<histogram name="EasyUnlock.AuthProximity.RemoteDeviceModelHash" + enum="EasyUnlockDeviceModelHash"> + <owner>tengs@chromium.org</owner> + <owner>xiaowenx@chromium.org</owner> + <summary> + The hash of the phone model used to successfully sign in or unlock using + Smart Lock. + </summary> + <details> + This hash is calculated by taking the first 4 bytes of the MD5 hash of the + device model. + </details> +</histogram> + +<histogram name="EasyUnlock.AuthProximity.RollingRssi" units="dBm"> + <owner>tengs@chromium.org</owner> + <owner>xiaowenx@chromium.org</owner> + <summary> + Measures the exponentially weighted rolling average of the received signal + strength indicator (RSSI) of the phone when the user successfully unlocks or + signs in using Smart Lock. + </summary> + <details> + The exponentially weighted averaging formula is: + + rollingRssi = (1 - weight) * rollingRssi + weight * currentRssi; + + RSSI readings are inherently noisy, so this averaging gives a smoothed RSSI + value to work with as a heuristic for proximity. + + If no RSSI was read, then a sentinel value of 127 will be recorded. + </details> +</histogram> + +<histogram name="EasyUnlock.AuthProximity.TimeSinceLastZeroRssi" + units="milliseconds"> + <owner>tengs@chromium.org</owner> + <owner>xiaowenx@chromium.org</owner> + <summary> + Measures the time delta in milliseconds since the last zero RSSI value was + read to when the user successfully unlocks or signs in using Smart Lock. + </summary> + <details> + A zero RSSI value is special because both Bluetooth devices in a connection + attempt to maintain by adjusting their transmit power levels. This time + delta can be used as a possible heuristic to determine that the phone is + close to the local device. + + If no RSSI was read, then an overflow value will be recorded. + </details> +</histogram> + +<histogram name="EasyUnlock.AuthProximity.TransmitPowerDelta" units="dBm"> + <owner>tengs@chromium.org</owner> + <owner>xiaowenx@chromium.org</owner> + <summary> + Measures the difference between the current transmit power and the maximum + transmit power of the local device when the user successfully unlocks or + signs in using Smart Lock. + </summary> + <details> + Devices connected using classic Bluetooth adjust their transmit power + dynamically to optimize power and signal strength. The difference between + the current transmit power and maximum transmit power can be used as a + heurstic to determine if the phone is close to the local device. + + According to the Bluetooth specs, there are three classes of devices, with a + maximum transmit power of 20, 4, and 0 dBm respectively. + + If no transmit power was read, then a sentinel value of 127 will be + recorded. + </details> +</histogram> + <histogram name="EasyUnlock.ClickedButton" enum="EasyUnlockButton"> <owner>joshwoodward@google.com</owner> <owner>tbarzic@chromium.org</owner> @@ -8368,6 +8442,16 @@ </summary> </histogram> +<histogram name="Extensions.BadMessageFunctionName" enum="ExtensionFunctions"> + <owner>kalman@chromium.org</owner> + <summary> + The number of times each Extension function call sends a bad message, + killing the renderer. This may indicate a bug in that API's implementation + on the renderer. Note a similar, aggregate metric is BadMessageTerminate_EFD + which counts the number of bad messages that are sent overall. + </summary> +</histogram> + <histogram name="Extensions.CheckForExternalUpdatesTime"> <owner>rkaplow@chromium.org</owner> <summary> @@ -33448,6 +33532,14 @@ </summary> </histogram> +<histogram name="Session.TotalDuration" units="milliseconds"> + <owner>mariakhomenko@chromium.org</owner> + <owner>fqian@chromium.org</owner> + <summary> + The length of a session (launch/foregrounding to backgrounding) on mobile. + </summary> +</histogram> + <histogram name="SessionCrashed.Bubble" enum="SessionCrashedBubbleUserAction"> <owner>yiyaoliu@chromium.org</owner> <summary>How did the user interact with the SessionCrashed Bubble?</summary> @@ -37644,6 +37736,33 @@ </summary> </histogram> +<histogram name="Startup.PreMainMessageLoopRunImplStep1Time" + units="milliseconds"> + <owner>rkaplow@chromium.org</owner> + <summary> + The amount of time that elapsed during the first untracked section of + ChromeBrowserMainParts::PreMainMessageLoopRunImpl. + </summary> +</histogram> + +<histogram name="Startup.PreMainMessageLoopRunImplStep2Time" + units="milliseconds"> + <owner>rkaplow@chromium.org</owner> + <summary> + The amount of time that elapsed during the second untracked section of + ChromeBrowserMainParts::PreMainMessageLoopRunImpl. Not written for Android. + </summary> +</histogram> + +<histogram name="Startup.PreMainMessageLoopRunImplStep3Time" + units="milliseconds"> + <owner>rkaplow@chromium.org</owner> + <summary> + The amount of time that elapsed during the third untracked section of + ChromeBrowserMainParts::PreMainMessageLoopRunImpl. Not written for Android. + </summary> +</histogram> + <histogram name="Startup.PreMainMessageLoopRunImplTime" units="milliseconds"> <obsolete> Deprecated as of 2/2015. @@ -41145,8 +41264,8 @@ <owner>ulan@chromium.org</owner> <summary> Number of garbage collections that a detached global context survives, - recorded after each major garbage collection. - Values greater than 7 indicate a memory leak. + recorded after each major garbage collection. Values greater than 7 indicate + a memory leak. </summary> </histogram> @@ -43706,6 +43825,16 @@ <summary>Number of times that each menu item is clicked.</summary> </histogram> +<histogram name="WrenchMenu.OpeningAnimationFrameTimes" units="milliseconds"> + <owner>kkimlabs@chromium.org</owner> + <summary> + Frame times of Android wrench menu opening animation. For example, if the + menu opening animation ran exactly at 60fps for a second, then each frame + time is 16ms. Therefore total ~60 number of 16ms value will be recorded. If + the anmation was janky, we will see >16ms data points in the histogram. + </summary> +</histogram> + <histogram name="WrenchMenu.RecentTabsSubMenu" enum="RecentTabsAction"> <owner>rpop@chromium.org</owner> <summary> @@ -43723,7 +43852,7 @@ </histogram> <histogram name="WrenchMenu.TouchDuration" units="milliseconds"> - <owner>kkimlabs@google.com</owner> + <owner>kkimlabs@chromium.org</owner> <summary> Time difference between touch down and touch up on Android wrench button. </summary> @@ -46615,6 +46744,13 @@ <int value="9" label="No recent updates"/> </enum> +<enum name="EasyUnlockDeviceModelHash" type="int"> + <int value="-1168032746" label="Motorola Nexus 6"/> + <int value="-617422855" label="LGE Nexus 4"/> + <int value="1286382027" label="Motorola XT1095"/> + <int value="1881443083" label="LGE Nexus 5"/> +</enum> + <enum name="EasyUnlockHasSecureScreenLock" type="int"> <int value="0" label="Lacks secure screen lock"/> <int value="1" label="Has secure screen lock"/>
diff --git a/tools/perf/benchmarks/draw_properties.py b/tools/perf/benchmarks/draw_properties.py index 9ac9ff2..aa0e12d0 100644 --- a/tools/perf/benchmarks/draw_properties.py +++ b/tools/perf/benchmarks/draw_properties.py
@@ -8,6 +8,7 @@ import page_sets +@benchmark.Disabled() # http://crbug.com/463111 class DrawPropertiesToughScrolling(benchmark.Benchmark): test = draw_properties.DrawProperties page_set = page_sets.ToughScrollingCasesPageSet @@ -15,6 +16,8 @@ def Name(cls): return 'draw_properties.tough_scrolling' + +@benchmark.Disabled() # http://crbug.com/463111 class DrawPropertiesTop25(benchmark.Benchmark): """Measures the relative performance of CalcDrawProperties vs computing draw properties from property trees.
diff --git a/tools/perf/benchmarks/page_cycler.py b/tools/perf/benchmarks/page_cycler.py index c4837d0f..7655255 100644 --- a/tools/perf/benchmarks/page_cycler.py +++ b/tools/perf/benchmarks/page_cycler.py
@@ -195,7 +195,7 @@ return 'page_cycler.tough_layout_cases' -# crbug.com/273986: This test is really flakey on xp. +# crbug.com/273986: This test is flakey on Windows. @benchmark.Disabled('win') class PageCyclerTypical25(_PageCycler): """Page load time benchmark for a 25 typical web pages. @@ -211,6 +211,21 @@ def CreatePageSet(self, options): return page_sets.Typical25PageSet(run_no_page_interactions=True) +# crbug.com/273986: This test is flakey on Windows. +@benchmark.Disabled # crbug.com/463346: Test is crashing Chrome. +class PageCyclerOopifTypical25(_PageCycler): + """ A varation of the benchmark above, but running in --site-per-process + to allow measuring performance of out-of-process iframes. + """ + @classmethod + def Name(cls): + return 'page_cycler_oopif.typical_25' + + def CustomizeBrowserOptions(self, options): + options.AppendExtraBrowserArgs(['--site-per-process']) + + def CreatePageSet(self, options): + return page_sets.Typical25PageSet(run_no_page_interactions=True) @benchmark.Disabled # crbug.com/443730 class PageCyclerBigJs(_PageCycler): @@ -218,4 +233,3 @@ @classmethod def Name(cls): return 'page_cycler.big_js' -
diff --git a/tools/perf/benchmarks/rasterize_and_record_micro.py b/tools/perf/benchmarks/rasterize_and_record_micro.py index 81b450ec..88ddaad2 100644 --- a/tools/perf/benchmarks/rasterize_and_record_micro.py +++ b/tools/perf/benchmarks/rasterize_and_record_micro.py
@@ -46,7 +46,7 @@ """Measures rasterize and record performance on the top 25 web pages. http://www.chromium.org/developers/design-documents/rendering-benchmarks""" - page_set = page_sets.Top25SmoothPageSet + page_set = page_sets.Top25PageSet @classmethod def Name(cls):
diff --git a/tools/perf/page_sets/data/top_25_smooth.json b/tools/perf/page_sets/data/top_25_smooth.json new file mode 100644 index 0000000..59fb8ed --- /dev/null +++ b/tools/perf/page_sets/data/top_25_smooth.json
@@ -0,0 +1,40 @@ +{ + "description": "Describes the Web Page Replay archives for a page set. Don't edit by hand! Use record_wpr for updating.", + "archives": { + "top_25_003.wpr": [ + "Facebook" + ], + "top_25_001.wpr": [ + "https://plus.google.com/110031535020051778989/posts" + ], + "top_25_002.wpr": [ + "https://www.google.com/search?q=cats&tbm=isch" + ], + "top_25_000.wpr": [ + "https://www.google.com/#hl=en&q=barack+obama", + "https://mail.google.com/mail/", + "https://www.google.com/calendar/", + "https://drive.google.com", + "https://docs.google.com/document/d/1X-IKNjtEnx-WW5JIKRLsyhz5sbsat3mfTpAPUSX3_s4/view", + "http://www.youtube.com", + "http://googlewebmastercentral.blogspot.com/", + "http://en.blog.wordpress.com/2012/09/04/freshly-pressed-editors-picks-for-august-2012/", + "http://www.facebook.com/barackobama", + "http://www.linkedin.com/in/linustorvalds", + "http://en.wikipedia.org/wiki/Wikipedia", + "https://twitter.com/katyperry", + "http://pinterest.com", + "http://espn.go.com", + "http://news.yahoo.com", + "http://www.cnn.com", + "http://www.weather.com/weather/right-now/Mountain+View+CA+94043", + "http://www.amazon.com", + "http://www.ebay.com", + "http://games.yahoo.com", + "http://booking.com", + "http://answers.yahoo.com", + "http://sports.yahoo.com/", + "http://techcrunch.com" + ] + } +} \ No newline at end of file
diff --git a/tools/perf/page_sets/top_25_pages.py b/tools/perf/page_sets/top_25_pages.py new file mode 100644 index 0000000..c6ba4cd --- /dev/null +++ b/tools/perf/page_sets/top_25_pages.py
@@ -0,0 +1,59 @@ +# 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. +from telemetry.page import page +from telemetry.page import page_set + +from page_sets import top_pages + + +class Top25PageSet(page_set.PageSet): + + """ Page set consists of top 25 pages with only navigation actions. """ + + def __init__(self): + super(Top25PageSet, self).__init__( + user_agent_type='desktop', + archive_data_file='data/top_25.json', + bucket=page_set.PARTNER_BUCKET) + + self.AddUserStory(top_pages.GoogleWebSearchPage(self)) + self.AddUserStory(top_pages.GmailPage(self)) + self.AddUserStory(top_pages.GoogleCalendarPage(self)) + self.AddUserStory(top_pages.GoogleImageSearchPage(self)) + self.AddUserStory(top_pages.GoogleDocPage(self)) + self.AddUserStory(top_pages.GooglePlusPage(self)) + self.AddUserStory(top_pages.YoutubePage(self)) + self.AddUserStory(top_pages.BlogspotPage(self)) + self.AddUserStory(top_pages.WordpressPage(self)) + self.AddUserStory(top_pages.FacebookPage(self)) + self.AddUserStory(top_pages.LinkedinPage(self)) + self.AddUserStory(top_pages.WikipediaPage(self)) + self.AddUserStory(top_pages.TwitterPage(self)) + self.AddUserStory(top_pages.PinterestPage(self)) + self.AddUserStory(top_pages.ESPNPage(self)) + self.AddUserStory(top_pages.WeatherPage(self)) + self.AddUserStory(top_pages.YahooGamesPage(self)) + + other_urls = [ + # Why: #1 news worldwide (Alexa global) + 'http://news.yahoo.com', + # Why: #2 news worldwide + 'http://www.cnn.com', + # Why: #1 world commerce website by visits; #3 commerce in the US by + # time spent + 'http://www.amazon.com', + # Why: #1 commerce website by time spent by users in US + 'http://www.ebay.com', + # Why: #1 Alexa recreation + 'http://booking.com', + # Why: #1 Alexa reference + 'http://answers.yahoo.com', + # Why: #1 Alexa sports + 'http://sports.yahoo.com/', + # Why: top tech blog + 'http://techcrunch.com' + ] + + for url in other_urls: + self.AddUserStory(page.Page(url, self))
diff --git a/tools/perf/page_sets/top_25_smooth.py b/tools/perf/page_sets/top_25_smooth.py index cf5d8fc0..5088a82 100644 --- a/tools/perf/page_sets/top_25_smooth.py +++ b/tools/perf/page_sets/top_25_smooth.py
@@ -93,7 +93,7 @@ def __init__(self): super(Top25SmoothPageSet, self).__init__( user_agent_type='desktop', - archive_data_file='data/top_25.json', + archive_data_file='data/top_25_smooth.json', bucket=page_set_module.PARTNER_BUCKET) self.AddUserStory(_CreatePageClassWithSmoothInteractions(
diff --git a/tools/telemetry/telemetry/core/backends/chrome_inspector/inspector_backend.py b/tools/telemetry/telemetry/core/backends/chrome_inspector/inspector_backend.py index b8483be1..59cc374 100644 --- a/tools/telemetry/telemetry/core/backends/chrome_inspector/inspector_backend.py +++ b/tools/telemetry/telemetry/core/backends/chrome_inspector/inspector_backend.py
@@ -17,7 +17,6 @@ from telemetry.core.backends.chrome_inspector import inspector_runtime from telemetry.core.backends.chrome_inspector import inspector_websocket from telemetry.core.backends.chrome_inspector import websocket -from telemetry.core.heap import model as heap_model_module from telemetry.image_processing import image_util from telemetry.timeline import model as timeline_model_module from telemetry.timeline import trace_data as trace_data_module @@ -240,25 +239,3 @@ self._page.CollectGarbage() except (socket.error, websocket.WebSocketException) as e: self._HandleError(e) - - def TakeJSHeapSnapshot(self, timeout=120): - snapshot = [] - - def OnNotification(res): - if res['method'] == 'HeapProfiler.addHeapSnapshotChunk': - snapshot.append(res['params']['chunk']) - - try: - self._websocket.RegisterDomain('HeapProfiler', OnNotification) - - self._websocket.SyncRequest({'method': 'Page.getResourceTree'}, timeout) - self._websocket.SyncRequest({'method': 'Debugger.enable'}, timeout) - self._websocket.SyncRequest( - {'method': 'HeapProfiler.takeHeapSnapshot'}, timeout) - except (socket.error, websocket.WebSocketException) as e: - self._HandleError(e) - - snapshot = ''.join(snapshot) - - self.UnregisterDomain('HeapProfiler') - return heap_model_module.Model(snapshot)
diff --git a/tools/telemetry/telemetry/core/heap/__init__.py b/tools/telemetry/telemetry/core/heap/__init__.py deleted file mode 100644 index e69de29..0000000 --- a/tools/telemetry/telemetry/core/heap/__init__.py +++ /dev/null
diff --git a/tools/telemetry/telemetry/core/heap/chrome_js_heap_snapshot_parser.py b/tools/telemetry/telemetry/core/heap/chrome_js_heap_snapshot_parser.py deleted file mode 100644 index 9706dad..0000000 --- a/tools/telemetry/telemetry/core/heap/chrome_js_heap_snapshot_parser.py +++ /dev/null
@@ -1,248 +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. - -import json - -from telemetry.core.heap import live_heap_object -from telemetry.core.heap import retaining_edge - - -class ChromeJsHeapSnapshotParser(object): - """ Parser for the heap snapshot. - - The heap snapshot JSON format is defined by HeapSnapshotJSONSerializer in V8. - - The snapshot contains a list of integers describing nodes (types, names, etc.) - and a list of integers describing edges (types, the node the edge points to, - etc.) and a string table. All strings are expressed as indices to the string - table. - - In addition, the snapshot contains meta information describing the data fields - for nodes and the data fields for edges. - - Attributes: - _node_dict: {int -> LiveHeapObject}, maps integer ids to LiveHeapObject - objects. - _node_list: [int], the raw node data of the heap snapshot. - _edge_list: [int], the raw edge data of the heap snapshot. - _node_types: [str], the possible node types in the heap snapshot. - _edge_types: [str], the possible edge types in the heap snapshot. - _node_fields: [str], the fields present in the heap snapshot for each node. - _edge_fields: [str], the fields present in the heap snapshot for each node. - _node_type_ix: int, index of the node type field. - _node_name_ix: int, index of the node name field. - _node_id_ix: int, index of the node id field. - _node_edge_count_ix: int, index of the node edge count field. - _node_field_count: int, number of node fields. - _edge_type_ix: int, index of the edge type field. - _edge_name_or_ix_ix: int, index of the "edge name or index" field. - _edge_to_node_ix: int, index of the "to node for an edge" field. - _edge_field_count: int, number of edge fields. - """ - - def __init__(self, raw_data): - heap = json.loads(raw_data) - self._node_dict = {} - - # Read the snapshot components (nodes, edges, strings, metadata). - self._node_list = heap['nodes'] - self._edge_list = heap['edges'] - self._strings = heap['strings'] - - self._node_types = heap['snapshot']['meta']['node_types'][0] - self._edge_types = heap['snapshot']['meta']['edge_types'][0] - node_fields = heap['snapshot']['meta']['node_fields'] - edge_fields = heap['snapshot']['meta']['edge_fields'] - - # Find the indices of the required node and edge fields based on the - # metadata. - self._node_type_ix = node_fields.index('type') - self._node_name_ix = node_fields.index('name') - self._node_id_ix = node_fields.index('id') - self._node_edge_count_ix = node_fields.index('edge_count') - self._node_field_count = len(node_fields) - - self._edge_type_ix = edge_fields.index('type') - self._edge_name_or_ix_ix = edge_fields.index('name_or_index') - self._edge_to_node_ix = edge_fields.index('to_node') - self._edge_field_count = len(edge_fields) - - self._ParseSnapshot() - - @staticmethod - def CanImport(raw_data): - heap = json.loads(raw_data) - if ('nodes' not in heap or 'edges' not in heap or 'strings' not in heap or - 'snapshot' not in heap or 'meta' not in heap['snapshot']): - return False - meta = heap['snapshot']['meta'] - if ('node_types' not in meta or 'edge_types' not in meta or - 'node_fields' not in meta or 'edge_fields' not in meta): - return False - node_fields = meta['node_fields'] - edge_fields = meta['edge_fields'] - if ('type' not in node_fields or 'name' not in node_fields or - 'id' not in node_fields or 'edge_count' not in node_fields): - return False - if ('type' not in edge_fields or 'name_or_index' not in edge_fields or - 'to_node' not in edge_fields): - return False - return True - - def GetAllLiveHeapObjects(self): - return self._node_dict.values() - - @staticmethod - def LiveHeapObjectToJavaScript(heap_object): - return heap_object.name or str(heap_object) - - @staticmethod - def RetainingEdgeToJavaScript(edge): - if edge.type_string == 'property': - return '.' + edge.name_string - if edge.type_string == 'element': - return '[' + edge.name_string + ']' - return str(edge) - - def _ParseSnapshot(self): - """Parses the stored JSON snapshot data. - - Fills in self._node_dict with LiveHeapObject objects constructed based on - the heap snapshot. The LiveHeapObject objects contain the associated - RetainingEdge objects. - """ - edge_start_ix = 0 - for ix in xrange(0, len(self._node_list), self._node_field_count): - edge_start_ix = self._ReadNodeFromIndex(ix, edge_start_ix) - - # Add pointers to the endpoints to the edges, and associate the edges with - # the "to" nodes. - for node_id in self._node_dict: - n = self._node_dict[node_id] - for e in n.edges_from: - self._node_dict[e.to_object_id].AddEdgeTo(e) - e.SetFromObject(n) - e.SetToObject(self._node_dict[e.to_object_id]) - - def _ReadNodeFromIndex(self, ix, edges_start): - """Reads the data for a node from the heap snapshot. - - If the index contains an interesting node, constructs a Node object and adds - it to self._node_dict. - - Args: - ix: int, index into the self._node_list array. - edges_start: int, the index of the edge array where the edges for the node - start. - Returns: - int, the edge start index for the next node. - - Raises: - Exception: The node list of the snapshot is malformed. - """ - if ix + self._node_field_count > len(self._node_list): - raise Exception('Snapshot node list too short') - - type_ix = self._node_list[ix + self._node_type_ix] - type_string = self._node_types[int(type_ix)] - - # edges_end is noninclusive (the index of the first edge that is not part of - # this node). - edge_count = self._node_list[ix + self._node_edge_count_ix] - edges_end = edges_start + edge_count * self._edge_field_count - - if ChromeJsHeapSnapshotParser._IsNodeTypeUninteresting(type_string): - return edges_end - - name_ix = self._node_list[ix + self._node_name_ix] - node_id = self._node_list[ix + self._node_id_ix] - - def ConstructorName(type_string, node_name_ix): - if type_string == 'object': - return self._strings[int(node_name_ix)] - return '(%s)' % type_string - - ctor_name = ConstructorName(type_string, name_ix) - n = live_heap_object.LiveHeapObject(node_id, type_string, ctor_name) - if type_string == 'string': - n.string = self._strings[int(name_ix)] - - for edge_ix in xrange(edges_start, edges_end, self._edge_field_count): - edge = self._ReadEdgeFromIndex(node_id, edge_ix) - if edge: - # The edge will be associated with the other endpoint when all the data - # has been read. - n.AddEdgeFrom(edge) - - self._node_dict[node_id] = n - return edges_end - - @staticmethod - def _IsNodeTypeUninteresting(type_string): - """Helper function for filtering out nodes from the heap snapshot. - - Args: - type_string: str, type of the node. - Returns: - bool, True if the node is of an uninteresting type and shouldn't be - included in the heap snapshot analysis. - """ - uninteresting_types = ('hidden', 'code', 'number', 'native', 'synthetic') - return type_string in uninteresting_types - - @staticmethod - def _IsEdgeTypeUninteresting(edge_type_string): - """Helper function for filtering out edges from the heap snapshot. - - Args: - edge_type_string: str, type of the edge. - Returns: - bool, True if the edge is of an uninteresting type and shouldn't be - included in the heap snapshot analysis. - """ - uninteresting_types = ('weak', 'hidden', 'internal') - return edge_type_string in uninteresting_types - - def _ReadEdgeFromIndex(self, node_id, edge_ix): - """Reads the data for an edge from the heap snapshot. - - Args: - node_id: int, id of the node which is the starting point of the edge. - edge_ix: int, index into the self._edge_list array. - Returns: - Edge, if the index contains an interesting edge, otherwise None. - Raises: - Exception: The node list of the snapshot is malformed. - """ - if edge_ix + self._edge_field_count > len(self._edge_list): - raise Exception('Snapshot edge list too short') - - edge_type_ix = self._edge_list[edge_ix + self._edge_type_ix] - edge_type_string = self._edge_types[int(edge_type_ix)] - - if ChromeJsHeapSnapshotParser._IsEdgeTypeUninteresting(edge_type_string): - return None - - child_name_or_ix = self._edge_list[edge_ix + self._edge_name_or_ix_ix] - child_node_ix = self._edge_list[edge_ix + self._edge_to_node_ix] - - # The child_node_ix is an index into the node list. Read the actual - # node information. - child_node_type_ix = self._node_list[child_node_ix + self._node_type_ix] - child_node_type_string = self._node_types[int(child_node_type_ix)] - child_node_id = self._node_list[child_node_ix + self._node_id_ix] - - if ChromeJsHeapSnapshotParser._IsNodeTypeUninteresting( - child_node_type_string): - return None - - child_name_string = '' - # For element nodes, the child has no name (only an index). - if (edge_type_string == 'element' or - int(child_name_or_ix) >= len(self._strings)): - child_name_string = str(child_name_or_ix) - else: - child_name_string = self._strings[int(child_name_or_ix)] - return retaining_edge.RetainingEdge(node_id, child_node_id, - edge_type_string, child_name_string)
diff --git a/tools/telemetry/telemetry/core/heap/chrome_js_heap_snapshot_parser_unittest.py b/tools/telemetry/telemetry/core/heap/chrome_js_heap_snapshot_parser_unittest.py deleted file mode 100644 index 94bb49a..0000000 --- a/tools/telemetry/telemetry/core/heap/chrome_js_heap_snapshot_parser_unittest.py +++ /dev/null
@@ -1,57 +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. - -import json -import unittest - -from telemetry.core.heap import chrome_js_heap_snapshot_parser - - -class ChromeJsHeapSnapshotParserUnittest(unittest.TestCase): - def _HeapSnapshotData(self, node_types, edge_types, node_fields, edge_fields, - node_list, edge_list, strings): - """Helper for creating heap snapshot data.""" - return {'snapshot': {'meta': {'node_types': [node_types], - 'edge_types': [edge_types], - 'node_fields': node_fields, - 'edge_fields': edge_fields}}, - 'nodes': node_list, - 'edges': edge_list, - 'strings': strings} - - def testParseSimpleSnapshot(self): - # Create a snapshot containing 2 nodes and an edge between them. - node_types = ['object'] - edge_types = ['property'] - node_fields = ['type', 'name', 'id', 'edge_count'] - edge_fields = ['type', 'name_or_index', 'to_node'] - node_list = [0, 0, 0, 1, - 0, 1, 1, 0] - edge_list = [0, 2, 4] - strings = ['node1', 'node2', 'edge1'] - heap = self._HeapSnapshotData(node_types, edge_types, node_fields, - edge_fields, node_list, edge_list, strings) - objects = list(chrome_js_heap_snapshot_parser.ChromeJsHeapSnapshotParser( - json.dumps(heap)).GetAllLiveHeapObjects()) - self.assertEqual(2, len(objects)) - if objects[0].edges_from: - from_ix = 0 - to_ix = 1 - else: - from_ix = 1 - to_ix = 0 - self.assertEqual('node1', objects[from_ix].class_name) - self.assertEqual('node2', objects[to_ix].class_name) - self.assertEqual(1, len(objects[from_ix].edges_from)) - self.assertEqual(0, len(objects[from_ix].edges_to)) - self.assertEqual(0, len(objects[to_ix].edges_from)) - self.assertEqual(1, len(objects[to_ix].edges_to)) - self.assertEqual('node1', - objects[from_ix].edges_from[0].from_object.class_name) - self.assertEqual('node2', - objects[from_ix].edges_from[0].to_object.class_name) - self.assertEqual('edge1', objects[from_ix].edges_from[0].name_string) - self.assertEqual('node1', objects[to_ix].edges_to[0].from_object.class_name) - self.assertEqual('node2', objects[to_ix].edges_to[0].to_object.class_name) - self.assertEqual('edge1', objects[to_ix].edges_to[0].name_string)
diff --git a/tools/telemetry/telemetry/core/heap/live_heap_object.py b/tools/telemetry/telemetry/core/heap/live_heap_object.py deleted file mode 100644 index c8be3df..0000000 --- a/tools/telemetry/telemetry/core/heap/live_heap_object.py +++ /dev/null
@@ -1,57 +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. - -class LiveHeapObject(object): - """Data structure for representing an object in the heap snapshot. - - Attributes: - object_id: int, identifier for the object. - type_string: str, describes the type of the node. - class_name: str, describes the class of the JavaScript object - represented by this LiveHeapObject. - edges_to: [RetainingEdge], edges whose end point this LiveHeapObject is. - edges_from: [RetainingEdge], edges whose start point this LiveHeapObject is. - string: str, for string LiveHeapObjects, contains the string the - LiveHeapObject represents. Empty string for LiveHeapObjects which are - not strings. - name: str, how to refer to this LiveHeapObject. - """ - - def __init__(self, object_id, type_string, class_name): - """Initializes the LiveHeapObject object. - - Args: - object_id: int, identifier for the LiveHeapObject. - type_string: str, the type of the node. - class_name: str, the class of the object this LiveHeapObject represents. - """ - self.object_id = object_id - self.type_string = type_string - self.class_name = class_name - self.edges_to = [] - self.edges_from = [] - self.string = '' - self.name = '' - - def AddEdgeTo(self, edge): - """Associates an Edge with the LiveHeapObject (the end point). - - Args: - edge: Edge, an edge whose end point this LiveHeapObject is. - """ - self.edges_to.append(edge) - - def AddEdgeFrom(self, edge): - """Associates an Edge with the LiveHeapObject (the start point). - - Args: - edge: Edge, an edge whose start point this LiveHeapObject is. - """ - self.edges_from.append(edge) - - def __str__(self): - prefix = 'LiveHeapObject(' + str(self.object_id) + ' ' - if self.type_string == 'object': - return prefix + self.class_name + ')' - return prefix + self.type_string + ')'
diff --git a/tools/telemetry/telemetry/core/heap/model.py b/tools/telemetry/telemetry/core/heap/model.py deleted file mode 100644 index 551716e6..0000000 --- a/tools/telemetry/telemetry/core/heap/model.py +++ /dev/null
@@ -1,22 +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. - -from telemetry.core.heap import chrome_js_heap_snapshot_parser - - -class Model(object): - """ The heap snapshot model is a set of LiveHeapObjects. The LiveHeapObjects - contain the RetainingEdge objects describing the relationships between the - LiveHeapObjects.""" - - def __init__(self, raw_data): - if not chrome_js_heap_snapshot_parser.ChromeJsHeapSnapshotParser.CanImport( - raw_data): - raise ValueError("Cannot import snapshot data") - parser = chrome_js_heap_snapshot_parser.ChromeJsHeapSnapshotParser(raw_data) - self._all_live_heap_objects = parser.GetAllLiveHeapObjects() - - @property - def all_live_heap_objects(self): - return self._all_live_heap_objects
diff --git a/tools/telemetry/telemetry/core/heap/retaining_edge.py b/tools/telemetry/telemetry/core/heap/retaining_edge.py deleted file mode 100644 index d6b9978c..0000000 --- a/tools/telemetry/telemetry/core/heap/retaining_edge.py +++ /dev/null
@@ -1,52 +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. - -class RetainingEdge(object): - """Data structure for representing a retainer relationship between objects. - - Attributes: - from_object_id: int, id of the object which is the start point of this - RetainingEdge. Used when the corresponding LiveHeapObject object is not - yet contstructed. - to_object_id: int, id of the object which is the end point of this - RetainingEdge. Used when the corresponding LiveHeapObject object is not - yet contstructed. - from_object: LiveHeapObject, the start point of this RetainingEdge. - to_object: LiveHeapObject, the end point of this RetainingEdge. - type_string: str, the type of the RetainingEdge. - name_string: str, the JavaScript attribute name this RetainingEdge - represents. - """ - - def __init__(self, from_object_id, to_object_id, type_string, name_string): - """Initializes the RetainingEdge object. - - Args: - from_object_id: int, id of the object which is the start point of this - RetainingEdge. Used when the corresponding LiveHeapObject object is - not yet contstructed. - to_object_id: int, id of the object which is the end point of this - RetainingEdge. Used when the corresponding LiveHeapObject object is - not yet contstructed. - type_string: str, the type of the RetainingEdge. - name_string: str, the JavaScript attribute name this RetainingEdge - represents. - """ - self.from_object_id = from_object_id - self.to_object_id = to_object_id - self.from_object = {} - self.to_object = {} - self.type_string = type_string - self.name_string = name_string - - def SetFromObject(self, obj): - self.from_object = obj - return self - - def SetToObject(self, obj): - self.to_object = obj - return self - - def __str__(self): - return 'RetainingEdge(' + self.type_string + ' ' + self.name_string + ')'
diff --git a/tools/telemetry/telemetry/core/web_contents.py b/tools/telemetry/telemetry/core/web_contents.py index 38232360..71a5c76 100644 --- a/tools/telemetry/telemetry/core/web_contents.py +++ b/tools/telemetry/telemetry/core/web_contents.py
@@ -174,9 +174,6 @@ def StopTimelineRecording(self): self._inspector_backend.StopTimelineRecording() - def TakeJSHeapSnapshot(self, timeout=120): - return self._inspector_backend.TakeJSHeapSnapshot(timeout) - def IsAlive(self): """Whether the WebContents is still operating normally.
diff --git a/tools/telemetry/telemetry/results/csv_pivot_table_output_formatter.py b/tools/telemetry/telemetry/results/csv_pivot_table_output_formatter.py index eb3a1223..c7f66fd3 100644 --- a/tools/telemetry/telemetry/results/csv_pivot_table_output_formatter.py +++ b/tools/telemetry/telemetry/results/csv_pivot_table_output_formatter.py
@@ -45,8 +45,8 @@ for run in page_test_results.all_page_runs: run_index = page_test_results.all_page_runs.index(run) page_dict = { - 'page': run.page.display_name, - 'page_set': run.page.page_set.Name(), + 'page': run.user_story.display_name, + 'page_set': run.user_story.page_set.Name(), 'run_index': run_index, } for value in run.values:
diff --git a/tools/telemetry/telemetry/results/gtest_progress_reporter.py b/tools/telemetry/telemetry/results/gtest_progress_reporter.py index 26b2d6c..87c03f7 100644 --- a/tools/telemetry/telemetry/results/gtest_progress_reporter.py +++ b/tools/telemetry/telemetry/results/gtest_progress_reporter.py
@@ -81,7 +81,7 @@ (len(page_test_results.failures), unit)) for failed_run in failed_runs: print >> self._output_stream, '[ FAILED ] %s' % ( - failed_run.page.display_name) + failed_run.user_story.display_name) print >> self._output_stream count = len(failed_runs) unit = 'TEST' if count == 1 else 'TESTS'
diff --git a/tools/telemetry/telemetry/results/json_output_formatter.py b/tools/telemetry/telemetry/results/json_output_formatter.py index db7b13b..7ef539d 100644 --- a/tools/telemetry/telemetry/results/json_output_formatter.py +++ b/tools/telemetry/telemetry/results/json_output_formatter.py
@@ -36,7 +36,7 @@ def _GetAllPages(page_test_results): - pages = set(page_run.page for page_run in + pages = set(page_run.user_story for page_run in page_test_results.all_page_runs) return pages
diff --git a/tools/telemetry/telemetry/results/page_run_unittest.py b/tools/telemetry/telemetry/results/page_run_unittest.py deleted file mode 100644 index 23ce506..0000000 --- a/tools/telemetry/telemetry/results/page_run_unittest.py +++ /dev/null
@@ -1,65 +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. - -import os -import unittest - -from telemetry import page as page_module -from telemetry.page import page_set -from telemetry.results import page_run -from telemetry.value import failure -from telemetry.value import scalar -from telemetry.value import skip - - -class PageRunTest(unittest.TestCase): - def setUp(self): - self.page_set = page_set.PageSet(file_path=os.path.dirname(__file__)) - self.page_set.AddUserStory(page_module.Page( - 'http://www.bar.com/', self.page_set, self.page_set.base_dir)) - - @property - def pages(self): - return self.page_set.pages - - def testPageRunFailed(self): - run = page_run.PageRun(self.pages[0]) - run.AddValue(failure.FailureValue.FromMessage(self.pages[0], 'test')) - self.assertFalse(run.ok) - self.assertTrue(run.failed) - self.assertFalse(run.skipped) - - run = page_run.PageRun(self.pages[0]) - run.AddValue(scalar.ScalarValue(self.pages[0], 'a', 's', 1)) - run.AddValue(failure.FailureValue.FromMessage(self.pages[0], 'test')) - self.assertFalse(run.ok) - self.assertTrue(run.failed) - self.assertFalse(run.skipped) - - def testPageRunSkipped(self): - run = page_run.PageRun(self.pages[0]) - run.AddValue(failure.FailureValue.FromMessage(self.pages[0], 'test')) - run.AddValue(skip.SkipValue(self.pages[0], 'test')) - self.assertFalse(run.ok) - self.assertFalse(run.failed) - self.assertTrue(run.skipped) - - run = page_run.PageRun(self.pages[0]) - run.AddValue(scalar.ScalarValue(self.pages[0], 'a', 's', 1)) - run.AddValue(skip.SkipValue(self.pages[0], 'test')) - self.assertFalse(run.ok) - self.assertFalse(run.failed) - self.assertTrue(run.skipped) - - def testPageRunSucceeded(self): - run = page_run.PageRun(self.pages[0]) - self.assertTrue(run.ok) - self.assertFalse(run.failed) - self.assertFalse(run.skipped) - - run = page_run.PageRun(self.pages[0]) - run.AddValue(scalar.ScalarValue(self.pages[0], 'a', 's', 1)) - self.assertTrue(run.ok) - self.assertFalse(run.failed) - self.assertFalse(run.skipped)
diff --git a/tools/telemetry/telemetry/results/page_test_results.py b/tools/telemetry/telemetry/results/page_test_results.py index 819684f..497a3ae 100644 --- a/tools/telemetry/telemetry/results/page_test_results.py +++ b/tools/telemetry/telemetry/results/page_test_results.py
@@ -12,8 +12,8 @@ import traceback from telemetry import value as value_module -from telemetry.results import page_run from telemetry.results import progress_reporter as progress_reporter_module +from telemetry.results import user_story_run from telemetry.util import cloud_storage from telemetry.value import failure from telemetry.value import skip @@ -94,7 +94,7 @@ @property def current_page(self): assert self._current_page_run, 'Not currently running test.' - return self._current_page_run.page + return self._current_page_run.user_story @property def current_page_run(self): @@ -108,7 +108,7 @@ @property def pages_that_succeeded(self): """Returns the set of pages that succeeded.""" - pages = set(run.page for run in self.all_page_runs) + pages = set(run.user_story for run in self.all_page_runs) pages.difference_update(self.pages_that_failed) return pages @@ -118,7 +118,7 @@ failed_pages = set() for run in self.all_page_runs: if run.failed: - failed_pages.add(run.page) + failed_pages.add(run.user_story) return failed_pages @property @@ -150,7 +150,7 @@ def WillRunPage(self, page): assert not self._current_page_run, 'Did not call DidRunPage.' - self._current_page_run = page_run.PageRun(page) + self._current_page_run = user_story_run.UserStoryRun(page) self._progress_reporter.WillRunPage(self) def DidRunPage(self, page, discard_run=False): # pylint: disable=W0613
diff --git a/tools/telemetry/telemetry/results/page_test_results_unittest.py b/tools/telemetry/telemetry/results/page_test_results_unittest.py index 21006a1..b9022b0 100644 --- a/tools/telemetry/telemetry/results/page_test_results_unittest.py +++ b/tools/telemetry/telemetry/results/page_test_results_unittest.py
@@ -55,7 +55,7 @@ results.DidRunPage(self.pages[1]) self.assertTrue(results.all_page_runs[0].skipped) - self.assertEqual(self.pages[0], results.all_page_runs[0].page) + self.assertEqual(self.pages[0], results.all_page_runs[0].user_story) self.assertEqual(set([self.pages[0], self.pages[1]]), results.pages_that_succeeded)
diff --git a/tools/telemetry/telemetry/results/page_run.py b/tools/telemetry/telemetry/results/user_story_run.py similarity index 79% rename from tools/telemetry/telemetry/results/page_run.py rename to tools/telemetry/telemetry/results/user_story_run.py index 72bd4084..eafa1d3f 100644 --- a/tools/telemetry/telemetry/results/page_run.py +++ b/tools/telemetry/telemetry/results/user_story_run.py
@@ -1,4 +1,4 @@ -# Copyright 2014 The Chromium Authors. All rights reserved. +# 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. @@ -6,21 +6,21 @@ from telemetry.value import skip -class PageRun(object): - def __init__(self, page): - self._page = page +class UserStoryRun(object): + def __init__(self, user_story): + self._user_story = user_story self._values = [] def AddValue(self, value): self._values.append(value) @property - def page(self): - return self._page + def user_story(self): + return self._user_story @property def values(self): - """The values that correspond to this page run.""" + """The values that correspond to this user_story run.""" return self._values @property
diff --git a/tools/telemetry/telemetry/results/user_story_run_unittest.py b/tools/telemetry/telemetry/results/user_story_run_unittest.py new file mode 100644 index 0000000..4aa3cf6 --- /dev/null +++ b/tools/telemetry/telemetry/results/user_story_run_unittest.py
@@ -0,0 +1,74 @@ +# 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 +import unittest + +from telemetry import user_story as user_story_module +from telemetry.results import user_story_run +from telemetry.user_story import shared_user_story_state +from telemetry.user_story import user_story_set +from telemetry.value import failure +from telemetry.value import scalar +from telemetry.value import skip + + +# pylint: disable=abstract-method +class SharedUserStoryStateBar(shared_user_story_state.SharedUserStoryState): + pass + +class UserStoryFoo(user_story_module.UserStory): + def __init__(self, name='', labels=None): + super(UserStoryFoo, self).__init__( + SharedUserStoryStateBar, name, labels) + +class UserStoryRunTest(unittest.TestCase): + def setUp(self): + self.user_story_set = user_story_set.UserStorySet() + self.user_story_set.AddUserStory(UserStoryFoo()) + + @property + def user_stories(self): + return self.user_story_set.user_stories + + def testUserStoryRunFailed(self): + run = user_story_run.UserStoryRun(self.user_stories[0]) + run.AddValue(failure.FailureValue.FromMessage(self.user_stories[0], 'test')) + self.assertFalse(run.ok) + self.assertTrue(run.failed) + self.assertFalse(run.skipped) + + run = user_story_run.UserStoryRun(self.user_stories[0]) + run.AddValue(scalar.ScalarValue(self.user_stories[0], 'a', 's', 1)) + run.AddValue(failure.FailureValue.FromMessage(self.user_stories[0], 'test')) + self.assertFalse(run.ok) + self.assertTrue(run.failed) + self.assertFalse(run.skipped) + + def testUserStoryRunSkipped(self): + run = user_story_run.UserStoryRun(self.user_stories[0]) + run.AddValue(failure.FailureValue.FromMessage(self.user_stories[0], 'test')) + run.AddValue(skip.SkipValue(self.user_stories[0], 'test')) + self.assertFalse(run.ok) + self.assertFalse(run.failed) + self.assertTrue(run.skipped) + + run = user_story_run.UserStoryRun(self.user_stories[0]) + run.AddValue(scalar.ScalarValue(self.user_stories[0], 'a', 's', 1)) + run.AddValue(skip.SkipValue(self.user_stories[0], 'test')) + self.assertFalse(run.ok) + self.assertFalse(run.failed) + self.assertTrue(run.skipped) + + def testUserStoryRunSucceeded(self): + run = user_story_run.UserStoryRun(self.user_stories[0]) + self.assertTrue(run.ok) + self.assertFalse(run.failed) + self.assertFalse(run.skipped) + + run = user_story_run.UserStoryRun(self.user_stories[0]) + run.AddValue(scalar.ScalarValue(self.user_stories[0], 'a', 's', 1)) + self.assertTrue(run.ok) + self.assertFalse(run.failed) + self.assertFalse(run.skipped)
diff --git a/tools/telemetry/telemetry/unittest_util/run_tests.py b/tools/telemetry/telemetry/unittest_util/run_tests.py index 8539e5d3..b4f6b8db 100644 --- a/tools/telemetry/telemetry/unittest_util/run_tests.py +++ b/tools/telemetry/telemetry/unittest_util/run_tests.py
@@ -141,16 +141,9 @@ def GetClassifier(args, possible_browser): def ClassifyTest(test_set, test): name = test.id() - if args.positional_args: - if _MatchesSelectedTest(name, args.positional_args, - args.exact_test_filter): - assert hasattr(test, '_testMethodName') - method = getattr(test, test._testMethodName) # pylint: disable=W0212 - if decorators.ShouldBeIsolated(method, possible_browser): - test_set.isolated_tests.append(typ.TestInput(name)) - else: - test_set.parallel_tests.append(typ.TestInput(name)) - else: + if (not args.positional_args + or _MatchesSelectedTest(name, args.positional_args, + args.exact_test_filter)): assert hasattr(test, '_testMethodName') method = getattr(test, test._testMethodName) # pylint: disable=W0212 should_skip, reason = decorators.ShouldSkip(method, possible_browser)
diff --git a/tools/telemetry/telemetry/web_perf/metrics/rendering_stats.py b/tools/telemetry/telemetry/web_perf/metrics/rendering_stats.py index 5f9278d5..ed39e53 100644 --- a/tools/telemetry/telemetry/web_perf/metrics/rendering_stats.py +++ b/tools/telemetry/telemetry/web_perf/metrics/rendering_stats.py
@@ -20,7 +20,7 @@ FORWARD_SCROLL_UPDATE_COMP_NAME = ( 'INPUT_EVENT_LATENCY_FORWARD_SCROLL_UPDATE_TO_MAIN_COMPONENT') # This is when the input event has reached swap buffer. -END_COMP_NAME = 'INPUT_EVENT_LATENCY_TERMINATED_FRAME_SWAP_COMPONENT' +END_COMP_NAME = 'INPUT_EVENT_GPU_SWAP_BUFFER_COMPONENT' # Name for a main thread scroll update latency event. SCROLL_UPDATE_EVENT_NAME = 'InputLatency:ScrollUpdate'
diff --git a/tools/valgrind/drmemory/suppressions.txt b/tools/valgrind/drmemory/suppressions.txt index d6f60966..c429a9f1 100644 --- a/tools/valgrind/drmemory/suppressions.txt +++ b/tools/valgrind/drmemory/suppressions.txt
@@ -742,3 +742,20 @@ *!content::ContentMainRunnerImpl::Run *!content::ContentMain *!content::LaunchTests + +UNINITIALIZED READ +name=http://crbug.com/463204 +skia.dll!_ltod3 +skia.dll!SkPaint::measure_text +skia.dll!SkPaint::measureText +content.dll!content::DoPreSandboxWarmupForTypeface +content.dll!content::`anonymous namespace'::WarmupDirectWrite + +UNADDRESSABLE ACCESS +name=http://crbug.com/463261 +... +blink_web.dll!blink::WebFrameWidgetImpl::selectionBounds +content.dll!content::RenderWidget::GetSelectionBounds +content.dll!content::RenderWidget::UpdateSelectionBounds +content.dll!content::RenderWidget::willBeginCompositorFrame +cc.dll!base::internal::InvokeHelper<>::MakeItSo
diff --git a/ui/accessibility/ax_tree_serializer.h b/ui/accessibility/ax_tree_serializer.h index f1cbfce..53e515a 100644 --- a/ui/accessibility/ax_tree_serializer.h +++ b/ui/accessibility/ax_tree_serializer.h
@@ -292,36 +292,39 @@ // with the LCA. AXSourceNode lca = LeastCommonAncestor(node); - if (client_root_) { - bool need_delete = false; - if (tree_->IsValid(lca)) { - // Check for any reparenting within this subtree - if there is - // any, we need to delete and reserialize the whole subtree - // that contains the old and new parents of the reparented node. - if (AnyDescendantWasReparented(lca, &lca)) - need_delete = true; - } - - if (!tree_->IsValid(lca)) { - // If there's no LCA, just tell the client to destroy the whole - // tree and then we'll serialize everything from the new root. - out_update->node_id_to_clear = client_root_->id; - Reset(); - } else if (need_delete) { - // Otherwise, if we need to reserialize a subtree, first we need - // to delete those nodes in our client tree so that - // SerializeChangedNodes() will be sure to send them again. - out_update->node_id_to_clear = tree_->GetId(lca); - ClientTreeNode* client_lca = ClientTreeNodeById(tree_->GetId(lca)); - CHECK(client_lca); - for (size_t i = 0; i < client_lca->children.size(); ++i) { - client_id_map_.erase(client_lca->children[i]->id); - DeleteClientSubtree(client_lca->children[i]); - delete client_lca->children[i]; + // This loop computes the least common ancestor that includes the old + // and new parents of any nodes that have been reparented, and clears the + // whole client subtree of that LCA if necessary. If we do end up clearing + // any client nodes, keep looping because we have to search for more + // nodes that may have been reparented from this new LCA. + bool need_delete; + do { + need_delete = false; + if (client_root_) { + if (tree_->IsValid(lca)) { + // Check for any reparenting within this subtree - if there is + // any, we need to delete and reserialize the whole subtree + // that contains the old and new parents of the reparented node. + if (AnyDescendantWasReparented(lca, &lca)) + need_delete = true; } - client_lca->children.clear(); + + if (!tree_->IsValid(lca)) { + // If there's no LCA, just tell the client to destroy the whole + // tree and then we'll serialize everything from the new root. + out_update->node_id_to_clear = client_root_->id; + Reset(); + } else if (need_delete) { + // Otherwise, if we need to reserialize a subtree, first we need + // to delete those nodes in our client tree so that + // SerializeChangedNodes() will be sure to send them again. + out_update->node_id_to_clear = tree_->GetId(lca); + ClientTreeNode* client_lca = ClientTreeNodeById(tree_->GetId(lca)); + CHECK(client_lca); + DeleteClientSubtree(client_lca); + } } - } + } while (need_delete); // Serialize from the LCA, or from the root if there isn't one. if (!tree_->IsValid(lca))
diff --git a/ui/android/java/src/org/chromium/ui/picker/MultiFieldTimePickerDialog.java b/ui/android/java/src/org/chromium/ui/picker/MultiFieldTimePickerDialog.java index d03c1650..f8647ec 100644 --- a/ui/android/java/src/org/chromium/ui/picker/MultiFieldTimePickerDialog.java +++ b/ui/android/java/src/org/chromium/ui/picker/MultiFieldTimePickerDialog.java
@@ -155,11 +155,14 @@ mMinuteSpinner.setMaxValue(59); } - if (step >= HOUR_IN_MILLIS) { + mMinuteSpinner.setValue(minute); + if (step % HOUR_IN_MILLIS == 0) { mMinuteSpinner.setEnabled(false); + // TODO(tkent): We should set minutes value of + // WebDateTimeChooserParams::stepBase. + mMinuteSpinner.setValue(minMinute); } - mMinuteSpinner.setValue(minute); mMinuteSpinner.setFormatter(twoDigitPaddingFormatter); if (step >= MINUTE_IN_MILLIS) {
diff --git a/ui/app_list/BUILD.gn b/ui/app_list/BUILD.gn index f1fae35..8758ad4 100644 --- a/ui/app_list/BUILD.gn +++ b/ui/app_list/BUILD.gn
@@ -218,69 +218,67 @@ ] } -if (!is_win || link_chrome_on_windows) { - test("app_list_unittests") { - sources = [ - "app_list_item_list_unittest.cc", - "app_list_model_unittest.cc", - "folder_image_unittest.cc", - "pagination_model_unittest.cc", - "search/history_data_store_unittest.cc", - "search/mixer_unittest.cc", - "search/term_break_iterator_unittest.cc", - "search/tokenized_string_char_iterator_unittest.cc", - "search/tokenized_string_match_unittest.cc", - "search/tokenized_string_unittest.cc", - "test/run_all_unittests.cc", +test("app_list_unittests") { + sources = [ + "app_list_item_list_unittest.cc", + "app_list_model_unittest.cc", + "folder_image_unittest.cc", + "pagination_model_unittest.cc", + "search/history_data_store_unittest.cc", + "search/mixer_unittest.cc", + "search/term_break_iterator_unittest.cc", + "search/tokenized_string_char_iterator_unittest.cc", + "search/tokenized_string_match_unittest.cc", + "search/tokenized_string_unittest.cc", + "test/run_all_unittests.cc", + ] + + configs += [ "//build/config/compiler:no_size_t_to_int_warning" ] + + deps = [ + ":app_list", + ":test_support", + "//base", + "//base/test:test_support", + "//skia", + "//testing/gtest", + "//ui/base", + "//ui/compositor", + "//ui/events", + "//ui/events:test_support", + "//ui/gl", + "//ui/resources", + "//ui/resources:ui_test_pak", + ] + + if (toolkit_views) { + sources += [ + "views/app_list_main_view_unittest.cc", + "views/app_list_view_unittest.cc", + "views/apps_grid_view_unittest.cc", + "views/contents_view_unittest.cc", + "views/folder_header_view_unittest.cc", + "views/search_box_view_unittest.cc", + "views/search_result_list_view_unittest.cc", + "views/speech_view_unittest.cc", + "views/test/apps_grid_view_test_api.cc", + "views/test/apps_grid_view_test_api.h", ] - - configs += [ "//build/config/compiler:no_size_t_to_int_warning" ] - - deps = [ - ":app_list", - ":test_support", - "//base", - "//base/test:test_support", - "//skia", - "//testing/gtest", - "//ui/base", - "//ui/compositor", - "//ui/events", - "//ui/events:test_support", - "//ui/gl", - "//ui/resources", - "//ui/resources:ui_test_pak", + deps += [ + "//ui/views", + "//ui/views:test_support", ] + } - if (toolkit_views) { - sources += [ - "views/app_list_main_view_unittest.cc", - "views/app_list_view_unittest.cc", - "views/apps_grid_view_unittest.cc", - "views/contents_view_unittest.cc", - "views/folder_header_view_unittest.cc", - "views/search_box_view_unittest.cc", - "views/search_result_list_view_unittest.cc", - "views/speech_view_unittest.cc", - "views/test/apps_grid_view_test_api.cc", - "views/test/apps_grid_view_test_api.h", - ] - deps += [ - "//ui/views", - "//ui/views:test_support", - ] - } - - if (is_mac) { - sources += [ - "cocoa/app_list_view_controller_unittest.mm", - "cocoa/app_list_window_controller_unittest.mm", - "cocoa/apps_grid_controller_unittest.mm", - "cocoa/apps_search_box_controller_unittest.mm", - "cocoa/apps_search_results_controller_unittest.mm", - "cocoa/test/apps_grid_controller_test_helper.h", - "cocoa/test/apps_grid_controller_test_helper.mm", - ] - } + if (is_mac) { + sources += [ + "cocoa/app_list_view_controller_unittest.mm", + "cocoa/app_list_window_controller_unittest.mm", + "cocoa/apps_grid_controller_unittest.mm", + "cocoa/apps_search_box_controller_unittest.mm", + "cocoa/apps_search_results_controller_unittest.mm", + "cocoa/test/apps_grid_controller_test_helper.h", + "cocoa/test/apps_grid_controller_test_helper.mm", + ] } }
diff --git a/ui/app_list/PRESUBMIT.py b/ui/app_list/PRESUBMIT.py index 3e3d954e..73df615 100644 --- a/ui/app_list/PRESUBMIT.py +++ b/ui/app_list/PRESUBMIT.py
@@ -23,7 +23,7 @@ sources = lambda x: input_api.FilterSourceFile( x, white_list = INCLUDE_CPP_FILES_ONLY, black_list = black_list) return input_api.canned_checks.CheckChangeLintsClean( - input_api, output_api, sources, []) + input_api, output_api, sources, lint_filters=[], verbose_level=1) def CheckChangeOnUpload(input_api, output_api): results = []
diff --git a/ui/app_list/views/app_list_view.cc b/ui/app_list/views/app_list_view.cc index c1bdb1ed..216abf4 100644 --- a/ui/app_list/views/app_list_view.cc +++ b/ui/app_list/views/app_list_view.cc
@@ -83,6 +83,25 @@ return true; } +// This view forwards the focus to the search box widget by providing it as a +// FocusTraversable when a focus search is provided. +class SearchBoxFocusHost : public views::View { + public: + explicit SearchBoxFocusHost(views::Widget* search_box_widget) + : search_box_widget_(search_box_widget) {} + + ~SearchBoxFocusHost() override {} + + views::FocusTraversable* GetFocusTraversable() override { + return search_box_widget_; + } + + private: + views::Widget* search_box_widget_; + + DISALLOW_COPY_AND_ASSIGN(SearchBoxFocusHost); +}; + // The view for the App List overlay, which appears as a white rounded // rectangle with the given radius. class AppListOverlayView : public views::View { @@ -182,6 +201,7 @@ : delegate_(delegate), app_list_main_view_(nullptr), speech_view_(nullptr), + search_box_focus_host_(nullptr), search_box_widget_(nullptr), search_box_view_(nullptr), overlay_view_(nullptr), @@ -463,6 +483,15 @@ search_box_widget_->Init(search_box_widget_params); search_box_widget_->SetContentsView(search_box_view_); + // The search box will not naturally receive focus by itself (because it is in + // a separate widget). Create this SearchBoxFocusHost in the main widget to + // forward the focus search into to the search box. + search_box_focus_host_ = new SearchBoxFocusHost(search_box_widget_); + AddChildView(search_box_focus_host_); + search_box_widget_->SetFocusTraversableParentView(search_box_focus_host_); + search_box_widget_->SetFocusTraversableParent( + GetWidget()->GetFocusTraversable()); + #if defined(USE_AURA) // Mouse events on the search box shadow should not be captured. aura::Window* window = search_box_widget_->GetNativeWindow();
diff --git a/ui/app_list/views/app_list_view.h b/ui/app_list/views/app_list_view.h index 1634cef..b62f9d35 100644 --- a/ui/app_list/views/app_list_view.h +++ b/ui/app_list/views/app_list_view.h
@@ -173,6 +173,7 @@ AppListMainView* app_list_main_view_; SpeechView* speech_view_; + views::View* search_box_focus_host_; // Owned by the views hierarchy. views::Widget* search_box_widget_; // Owned by the app list's widget. SearchBoxView* search_box_view_; // Owned by |search_box_widget_|.
diff --git a/ui/app_list/views/search_result_page_view.cc b/ui/app_list/views/search_result_page_view.cc index 04c9443..2af6d583 100644 --- a/ui/app_list/views/search_result_page_view.cc +++ b/ui/app_list/views/search_result_page_view.cc
@@ -4,6 +4,8 @@ #include "ui/app_list/views/search_result_page_view.h" +#include <algorithm> + #include "ui/app_list/app_list_constants.h" #include "ui/app_list/app_list_switches.h" #include "ui/app_list/app_list_view_delegate.h"
diff --git a/ui/app_list/views/start_page_view.cc b/ui/app_list/views/start_page_view.cc index c546b2d..401aae1 100644 --- a/ui/app_list/views/start_page_view.cc +++ b/ui/app_list/views/start_page_view.cc
@@ -4,6 +4,8 @@ #include "ui/app_list/views/start_page_view.h" +#include <string> + #include "base/i18n/rtl.h" #include "base/metrics/histogram_macros.h" #include "base/strings/utf_string_conversions.h"
diff --git a/ui/aura/BUILD.gn b/ui/aura/BUILD.gn index 9a330fb..bcf1065 100644 --- a/ui/aura/BUILD.gn +++ b/ui/aura/BUILD.gn
@@ -243,63 +243,61 @@ } } -if (!is_win || link_chrome_on_windows) { - executable("bench") { - output_name = "aura_bench" - testonly = true +executable("bench") { + output_name = "aura_bench" + testonly = true - sources = [ - "bench/bench_main.cc", - ] + sources = [ + "bench/bench_main.cc", + ] - deps = [ - ":test_support", - "//base", - "//base:i18n", - "//cc", - "//gpu/command_buffer/client:gles2_interface", - "//skia", - "//third_party/icu", - "//ui/base", - "//ui/compositor", - "//ui/compositor:test_support", - "//ui/events", - "//ui/gfx", - "//ui/gfx/geometry", - "//ui/gl", - ] + deps = [ + ":test_support", + "//base", + "//base:i18n", + "//cc", + "//gpu/command_buffer/client:gles2_interface", + "//skia", + "//third_party/icu", + "//ui/base", + "//ui/compositor", + "//ui/compositor:test_support", + "//ui/events", + "//ui/gfx", + "//ui/gfx/geometry", + "//ui/gl", + ] - if (use_x11) { - deps += [ "//ui/gfx/x" ] - } + if (use_x11) { + deps += [ "//ui/gfx/x" ] } +} - test("aura_unittests") { - sources = [ - "gestures/gesture_recognizer_unittest.cc", - "test/run_all_unittests.cc", - "window_event_dispatcher_unittest.cc", - "window_targeter_unittest.cc", - "window_unittest.cc", - ] +test("aura_unittests") { + sources = [ + "gestures/gesture_recognizer_unittest.cc", + "test/run_all_unittests.cc", + "window_event_dispatcher_unittest.cc", + "window_targeter_unittest.cc", + "window_unittest.cc", + ] - deps = [ - ":test_support", - "//base/allocator", - "//base/test:test_support", - "//skia", - "//testing/gtest", - "//ui/base:test_support", - "//ui/compositor:test_support", - "//ui/events:test_support", - "//ui/events:gesture_detection", - "//ui/gfx", - "//ui/gfx/geometry", - "//ui/gl", - ] + deps = [ + ":test_support", + "//base/allocator", + "//base/test:test_support", + "//skia", + "//testing/gtest", + "//ui/base:test_support", + "//ui/compositor:test_support", + "//ui/events:test_support", + "//ui/events:gesture_detection", + "//ui/gfx", + "//ui/gfx/geometry", + "//ui/gl", + ] - if (is_linux) { - deps += [ "//third_party/mesa" ] - } + if (is_linux) { + deps += [ "//third_party/mesa" ] } }
diff --git a/ui/aura/demo/demo_main.cc b/ui/aura/demo/demo_main.cc index c589824..e7ed3680 100644 --- a/ui/aura/demo/demo_main.cc +++ b/ui/aura/demo/demo_main.cc
@@ -23,6 +23,7 @@ #include "ui/events/event.h" #include "ui/gfx/canvas.h" #include "ui/gfx/geometry/rect.h" +#include "ui/gfx/skia_util.h" #include "ui/gl/gl_surface.h" #if defined(USE_X11) @@ -63,6 +64,14 @@ void OnCaptureLost() override {} void OnPaint(gfx::Canvas* canvas) override { canvas->DrawColor(color_, SkXfermode::kSrc_Mode); + gfx::Rect r; + canvas->GetClipBounds(&r); + // Fill with a non-solid color so that the compositor will exercise its + // texture upload path. + while (!r.IsEmpty()) { + r.Inset(2, 2); + canvas->FillRect(r, color_, SkXfermode::kXor_Mode); + } } void OnDeviceScaleFactorChanged(float device_scale_factor) override {} void OnWindowDestroying(aura::Window* window) override {}
diff --git a/ui/aura/env.cc b/ui/aura/env.cc index d205ae98..4d2db40d 100644 --- a/ui/aura/env.cc +++ b/ui/aura/env.cc
@@ -43,6 +43,11 @@ } // static +Env* Env::GetInstanceDontCreate() { + return lazy_tls_ptr.Pointer()->Get(); +} + +// static void Env::DeleteInstance() { delete lazy_tls_ptr.Pointer()->Get(); }
diff --git a/ui/aura/env.h b/ui/aura/env.h index 4ae2d694..9b84c3b 100644 --- a/ui/aura/env.h +++ b/ui/aura/env.h
@@ -37,6 +37,7 @@ // nativeviewportservice lives in the same process as the viewmanager. static void CreateInstance(bool create_event_source); static Env* GetInstance(); + static Env* GetInstanceDontCreate(); static void DeleteInstance(); void AddObserver(EnvObserver* observer);
diff --git a/ui/events/ozone/evdev/input_device_factory_evdev.cc b/ui/events/ozone/evdev/input_device_factory_evdev.cc index e2140f66..bb5dbe7 100644 --- a/ui/events/ozone/evdev/input_device_factory_evdev.cc +++ b/ui/events/ozone/evdev/input_device_factory_evdev.cc
@@ -229,7 +229,7 @@ base::WorkerPool::PostTask(FROM_HERE, base::Bind(&OpenInputDevice, base::Passed(¶ms), task_runner_, reply_callback), - true /* task_is_slow */); + false /* task_is_slow */); } void InputDeviceFactoryEvdev::RemoveInputDevice(const base::FilePath& path) {
diff --git a/ui/file_manager/audio_player/audio_player.html b/ui/file_manager/audio_player/audio_player.html index 3d95596..0b225f9 100644 --- a/ui/file_manager/audio_player/audio_player.html +++ b/ui/file_manager/audio_player/audio_player.html
@@ -40,10 +40,11 @@ <script src="../file_manager/foreground/js/metadata/content_metadata_provider.js"></script> <script src="../file_manager/foreground/js/metadata/external_metadata_provider.js"></script> - <script src="../file_manager/foreground/js/metadata/file_system_metadata.js"></script> <script src="../file_manager/foreground/js/metadata/file_system_metadata_provider.js"></script> <script src="../file_manager/foreground/js/metadata/metadata_cache_item.js"></script> <script src="../file_manager/foreground/js/metadata/metadata_item.js"></script> + <script src="../file_manager/foreground/js/metadata/metadata_model.js"></script> + <script src="../file_manager/foreground/js/metadata/multi_metadata_provider.js"></script> <script src="../file_manager/foreground/js/metadata/thumbnail_model.js"></script> <script src="js/audio_player.js"></script>
diff --git a/ui/file_manager/audio_player/js/audio_player.js b/ui/file_manager/audio_player/js/audio_player.js index f5e172d..a4d81ef 100644 --- a/ui/file_manager/audio_player/js/audio_player.js +++ b/ui/file_manager/audio_player/js/audio_player.js
@@ -17,8 +17,7 @@ this.container_ = container; this.volumeManager_ = new VolumeManagerWrapper( VolumeManagerWrapper.DriveEnabledStatus.DRIVE_ENABLED); - this.fileSystemMetadata_ = FileSystemMetadata.create( - new MetadataProviderCache(), this.volumeManager_); + this.metadataModel_ = new MetadataModel.create(this.volumeManager_); this.selectedEntry_ = null; this.model_ = new AudioPlayerModel(); @@ -238,7 +237,7 @@ * @private */ AudioPlayer.prototype.fetchMetadata_ = function(entry, callback) { - this.fileSystemMetadata_.get( + this.metadataModel_.get( [entry], ['mediaTitle', 'mediaArtist', 'present']).then( function(generation, metadata) { // Do nothing if another load happened since the metadata request.
diff --git a/ui/file_manager/audio_player/js/audio_player_scripts.js b/ui/file_manager/audio_player/js/audio_player_scripts.js index a4d5a978..db67180 100644 --- a/ui/file_manager/audio_player/js/audio_player_scripts.js +++ b/ui/file_manager/audio_player/js/audio_player_scripts.js
@@ -35,10 +35,11 @@ <include src="../../file_manager/foreground/js/metadata/content_metadata_provider.js"> <include src="../../file_manager/foreground/js/metadata/external_metadata_provider.js"> -<include src="../../file_manager/foreground/js/metadata/file_system_metadata.js"> <include src="../../file_manager/foreground/js/metadata/file_system_metadata_provider.js"> <include src="../../file_manager/foreground/js/metadata/metadata_cache_item.js"> <include src="../../file_manager/foreground/js/metadata/metadata_item.js"> +<include src="../../file_manager/foreground/js/metadata/metadata_model.js"> +<include src="../../file_manager/foreground/js/metadata/multi_metadata_provider.js"> <include src="../../file_manager/foreground/js/metadata/thumbnail_model.js"> <include src="audio_player.js"/>
diff --git a/ui/file_manager/file_manager/foreground/css/file_manager.css b/ui/file_manager/file_manager/foreground/css/file_manager.css index 3f48669..a4b785b 100644 --- a/ui/file_manager/file_manager/foreground/css/file_manager.css +++ b/ui/file_manager/file_manager/foreground/css/file_manager.css
@@ -1247,6 +1247,15 @@ } } +@-webkit-keyframes fadeOut { + from { + opacity: 1; + } + to { + opacity: 0; + } +} + /* Table splitter element */ .table-header-splitter { background-image: -webkit-image-set( @@ -1370,24 +1379,32 @@ } #list-container list li .detail-thumbnail { + height: 28px; + overflow: hidden; + position: absolute; + width: 28px; +} + +#list-container list li .detail-thumbnail > .thumbnail { -webkit-user-drag: none; background-color: rgb(245, 245, 245); background-position: center; background-size: cover; border-radius: 14px; - height: 28px; - opacity: 0; - overflow: hidden; - position: absolute; - transition: opacity 220ms ease; - width: 28px; -} - -#list-container list li .detail-thumbnail.loaded { + height: 100%; opacity: 1; + position: absolute; + width: 100%; } -body.check-select #list-container list li[selected] .detail-thumbnail.loaded { +#list-container list li .detail-thumbnail > .thumbnail.animate { + -webkit-animation: fadeIn 220ms ease; +} + +body.check-select #list-container list li[selected] .detail-thumbnail +> .thumbnail { + /* Fade out after checkmark fades in. */ + -webkit-animation: fadeOut 0ms 220ms ease backwards; opacity: 0; }
diff --git a/ui/file_manager/file_manager/foreground/js/compiled_resources.gyp b/ui/file_manager/file_manager/foreground/js/compiled_resources.gyp index 1a651b4..684ad36 100644 --- a/ui/file_manager/file_manager/foreground/js/compiled_resources.gyp +++ b/ui/file_manager/file_manager/foreground/js/compiled_resources.gyp
@@ -89,12 +89,13 @@ './launch_param.js', './metadata/content_metadata_provider.js', './metadata/external_metadata_provider.js', - './metadata/file_system_metadata.js', './metadata/file_system_metadata_provider.js', './metadata/metadata_cache.js', './metadata/metadata_cache_item.js', './metadata/metadata_cache_set.js', './metadata/metadata_item.js', + './metadata/metadata_model.js', + './metadata/multi_metadata_provider.js', './metadata/new_metadata_provider.js', './metadata/thumbnail_model.js', './metadata_update_controller.js',
diff --git a/ui/file_manager/file_manager/foreground/js/dialog_action_controller.js b/ui/file_manager/file_manager/foreground/js/dialog_action_controller.js index 0505c5d3..aa49006 100644 --- a/ui/file_manager/file_manager/foreground/js/dialog_action_controller.js +++ b/ui/file_manager/file_manager/foreground/js/dialog_action_controller.js
@@ -9,7 +9,7 @@ * @param {DialogType} dialogType Dialog type. * @param {!DialogFooter} dialogFooter Dialog footer. * @param {!DirectoryModel} directoryModel Directory model. - * @param {!FileSystemMetadata} fileSystemMetadata Metadata cache. + * @param {!MetadataModel} metadataModel Metadata cache. * @param {!VolumeManagerWrapper} volumeManager Volume manager. * @param {!FileFilter} fileFilter File filter model. * @param {!NamingController} namingController Naming controller. @@ -23,7 +23,7 @@ dialogType, dialogFooter, directoryModel, - fileSystemMetadata, + metadataModel, volumeManager, fileFilter, namingController, @@ -51,11 +51,11 @@ this.directoryModel_ = directoryModel; /** - * @type {!FileSystemMetadata} + * @type {!MetadataModel} * @const * @private */ - this.fileSystemMetadata_ = fileSystemMetadata; + this.metadataModel_ = metadataModel; /** * @type {!VolumeManagerWrapper} @@ -369,7 +369,7 @@ // TODO(mtomasz): Use Entry instead of URLs, if possible. util.URLsToEntries(selection.urls, function(entries) { - this.fileSystemMetadata_.get(entries, ['present']).then(onProperties); + this.metadataModel_.get(entries, ['present']).then(onProperties); }.bind(this)); };
diff --git a/ui/file_manager/file_manager/foreground/js/directory_contents.js b/ui/file_manager/file_manager/foreground/js/directory_contents.js index 9fbab186..a0b2405f 100644 --- a/ui/file_manager/file_manager/foreground/js/directory_contents.js +++ b/ui/file_manager/file_manager/foreground/js/directory_contents.js
@@ -393,18 +393,18 @@ /** * File list. - * @param {!FileSystemMetadata} fileSystemMetadata + * @param {!MetadataModel} metadataModel * @constructor * @extends {cr.ui.ArrayDataModel} */ -function FileListModel(fileSystemMetadata) { +function FileListModel(metadataModel) { cr.ui.ArrayDataModel.call(this, []); /** - * @private {!FileSystemMetadata} + * @private {!MetadataModel} * @const */ - this.fileSystemMetadata_ = fileSystemMetadata; + this.metadataModel_ = metadataModel; // Initialize compare functions. this.setCompareFunction('name', @@ -483,7 +483,7 @@ return a.isDirectory === this.isDescendingOrder_ ? 1 : -1; var properties = - this.fileSystemMetadata_.getCache([a, b], ['modificationTime']); + this.metadataModel_.getCache([a, b], ['modificationTime']); var aTime = properties[0].modificationTime || 0; var bTime = properties[1].modificationTime || 0; @@ -508,7 +508,7 @@ if (a.isDirectory !== b.isDirectory) return a.isDirectory === this.isDescendingOrder_ ? 1 : -1; - var properties = this.fileSystemMetadata_.getCache([a, b], ['size']); + var properties = this.metadataModel_.getCache([a, b], ['size']); var aSize = properties[0].size || 0; var bSize = properties[1].size || 0; @@ -539,20 +539,20 @@ * TODO(yoshiki): remove this. crbug.com/224869. * * @param {FileFilter} fileFilter The file-filter context. - * @param {!FileSystemMetadata} fileSystemMetadata + * @param {!MetadataModel} metadataModel * @constructor */ -function FileListContext(fileFilter, fileSystemMetadata) { +function FileListContext(fileFilter, metadataModel) { /** * @type {FileListModel} */ - this.fileList = new FileListModel(fileSystemMetadata); + this.fileList = new FileListModel(metadataModel); /** - * @public {!FileSystemMetadata} + * @public {!MetadataModel} * @const */ - this.fileSystemMetadata = fileSystemMetadata; + this.metadataModel = metadataModel; /** * @type {FileFilter} @@ -656,7 +656,7 @@ DirectoryContents.prototype.createMetadataSnapshot = function() { var snapshot = {}; var entries = /** @type {!Array<!Entry>} */ (this.fileList_.slice()); - var metadata = this.context_.fileSystemMetadata.getCache( + var metadata = this.context_.metadataModel.getCache( entries, ['modificationTime']); for (var i = 0; i < entries.length; i++) { snapshot[entries[i].toURL()] = metadata[i]; @@ -693,7 +693,7 @@ if (this.metadataSnapshot_) { var updatedIndexes = []; var entries = /** @type {!Array<!Entry>} */ (this.fileList_.slice()); - var newMetadatas = this.context_.fileSystemMetadata.getCache( + var newMetadatas = this.context_.metadataModel.getCache( entries, ['modificationTime']); for (var i = 0; i < entries.length; i++) { @@ -789,6 +789,7 @@ } var updatedList = []; + var updatedIndexes = []; for (var i = 0; i < this.fileList_.length; i++) { var url = this.fileList_.item(i).toURL(); @@ -800,17 +801,21 @@ if (url in updatedMap) { updatedList.push(updatedMap[url]); + updatedIndexes.push(i); delete updatedMap[url]; } } + if (updatedIndexes.length > 0) + this.fileList_.updateIndexes(updatedIndexes); + var addedList = []; for (var url in updatedMap) { addedList.push(updatedMap[url]); } if (removedUrls.length > 0) - this.context_.fileSystemMetadata.notifyEntriesRemoved(removedUrls); + this.context_.metadataModel.notifyEntriesRemoved(removedUrls); this.prefetchMetadata(updatedList, true, function() { this.onNewEntries_(true, addedList); @@ -975,8 +980,8 @@ DirectoryContents.prototype.prefetchMetadata = function(entries, refresh, callback) { if (refresh) - this.context_.fileSystemMetadata.notifyEntriesChanged(entries); - this.context_.fileSystemMetadata.get( + this.context_.metadataModel.notifyEntriesChanged(entries); + this.context_.metadataModel.get( entries, this.context_.prefetchPropertyNames).then(callback); };
diff --git a/ui/file_manager/file_manager/foreground/js/directory_model.js b/ui/file_manager/file_manager/foreground/js/directory_model.js index 188499b..bb014b7 100644 --- a/ui/file_manager/file_manager/foreground/js/directory_model.js +++ b/ui/file_manager/file_manager/foreground/js/directory_model.js
@@ -14,8 +14,7 @@ * @param {boolean} singleSelection True if only one file could be selected * at the time. * @param {FileFilter} fileFilter Instance of FileFilter. - * @param {!MetadataProviderCache} metadataProviderCache Metadata cache. - * @param {!FileSystemMetadata} fileSystemMetadata Metadata model. + * @param {!MetadataModel} metadataModel Metadata model. * service. * @param {VolumeManagerWrapper} volumeManager The volume manager. * @param {!FileOperationManager} fileOperationManager File operation manager. @@ -23,7 +22,7 @@ * @extends {cr.EventTarget} */ function DirectoryModel(singleSelection, fileFilter, - metadataProviderCache, fileSystemMetadata, + metadataModel, volumeManager, fileOperationManager) { this.fileListSelection_ = singleSelection ? new FileListSingleSelectionModel() : new FileListSelectionModel(); @@ -43,12 +42,11 @@ this.onFilterChanged_.bind(this)); this.currentFileListContext_ = - new FileListContext(fileFilter, fileSystemMetadata); + new FileListContext(fileFilter, metadataModel); this.currentDirContents_ = DirectoryContents.createForDirectory(this.currentFileListContext_, null); - this.metadataProviderCache_ = metadataProviderCache; - this.fileSystemMetadata_ = fileSystemMetadata; + this.metadataModel_ = metadataModel; this.volumeManager_ = volumeManager; this.volumeManager_.volumeInfoList.addEventListener( @@ -496,7 +494,7 @@ }.bind(this); // Clear the table, and start scanning. - this.metadataProviderCache_.clearAll(); + this.metadataModel_.clearAllCache(); cr.dispatchSimpleEvent(this, 'scan-started'); var fileList = this.getFileList(); fileList.splice(0, fileList.length); @@ -846,7 +844,7 @@ then(function(newEntry) { // Refresh the cache. - this.fileSystemMetadata_.notifyEntriesCreated([newEntry]); + this.metadataModel_.notifyEntriesCreated([newEntry]); return new Promise(function(onFulfilled, onRejected) { dirContents.prefetchMetadata( [newEntry], false, onFulfilled.bind(null, newEntry));
diff --git a/ui/file_manager/file_manager/foreground/js/file_manager.js b/ui/file_manager/file_manager/foreground/js/file_manager.js index 1d00a42..aa993f4a 100644 --- a/ui/file_manager/file_manager/foreground/js/file_manager.js +++ b/ui/file_manager/file_manager/foreground/js/file_manager.js
@@ -54,15 +54,9 @@ this.mediaImportHandler_ = null; /** - * @private {!MetadataProviderCache} - * @const + * @private {MetadataModel} */ - this.metadataProviderCache_ = new MetadataProviderCache(); - - /** - * @private {FileSystemMetadata} - */ - this.fileSystemMetadata_ = null; + this.metadataModel_ = null; /** * @private {ThumbnailModel} @@ -490,7 +484,7 @@ this.ui_.multiProfileShareDialog, assert(this.backgroundPage_.background.progressCenter), assert(this.fileOperationManager_), - assert(this.fileSystemMetadata_), + assert(this.metadataModel_), assert(this.thumbnailModel_), assert(this.directoryModel_), assert(this.volumeManager_), @@ -694,10 +688,8 @@ // Create the metadata cache. assert(this.volumeManager_); - this.fileSystemMetadata_ = FileSystemMetadata.create( - this.metadataProviderCache_, - this.volumeManager_); - this.thumbnailModel_ = new ThumbnailModel(this.fileSystemMetadata_); + this.metadataModel_ = MetadataModel.create(this.volumeManager_); + this.thumbnailModel_ = new ThumbnailModel(this.metadataModel_); // Create the root view of FileManager. assert(this.dialogDom_); @@ -722,11 +714,11 @@ * @private */ FileManager.prototype.initAdditionalUI_ = function(callback) { - assert(this.fileSystemMetadata_); + assert(this.metadataModel_); assert(this.volumeManager_); assert(this.historyLoader_); assert(this.dialogDom_); - assert(this.fileSystemMetadata_); + assert(this.metadataModel_); // Cache nodes we'll be manipulating. var dom = this.dialogDom_; @@ -741,14 +733,14 @@ table.importEnabled = false; FileTable.decorate( table, - this.fileSystemMetadata_, + this.metadataModel_, this.volumeManager_, this.historyLoader_, this.dialogType == DialogType.FULL_PAGE); var grid = queryRequiredElement(dom, '.thumbnail-grid'); FileGrid.decorate( grid, - this.fileSystemMetadata_, + this.metadataModel_, this.volumeManager_, this.historyLoader_); @@ -839,12 +831,11 @@ assert(this.volumeManager_); assert(this.fileOperationManager_); - assert(this.fileSystemMetadata_); + assert(this.metadataModel_); this.directoryModel_ = new DirectoryModel( singleSelection, this.fileFilter_, - this.metadataProviderCache_, - this.fileSystemMetadata_, + this.metadataModel_, this.volumeManager_, this.fileOperationManager_); @@ -887,14 +878,13 @@ this.metadataUpdateController_ = new MetadataUpdateController( this.ui_.listContainer, this.directoryModel_, - this.metadataProviderCache_, - this.fileSystemMetadata_); + this.metadataModel_); // Create task controller. this.taskController_ = new TaskController( this.dialogType, this.ui_, - this.fileSystemMetadata_, + this.metadataModel_, this.selectionHandler_, this.metadataUpdateController_, function() { return new FileTasks(this); }.bind(this)); @@ -929,7 +919,7 @@ this.dialogType, this.ui_.dialogFooter, this.directoryModel_, - this.fileSystemMetadata_, + this.metadataModel_, this.volumeManager_, this.fileFilter_, this.namingController_, @@ -948,7 +938,7 @@ DirectoryTree.decorate(directoryTree, assert(this.directoryModel_), assert(this.volumeManager_), - assert(this.fileSystemMetadata_), + assert(this.metadataModel_), fakeEntriesVisible); directoryTree.dataModel = new NavigationListModel( this.volumeManager_, this.folderShortcutsModel_); @@ -1282,10 +1272,10 @@ }; /** - * @return {!FileSystemMetadata} + * @return {!MetadataModel} */ - FileManager.prototype.getFileSystemMetadata = function() { - return assert(this.fileSystemMetadata_); + FileManager.prototype.getMetadataModel = function() { + return assert(this.metadataModel_); }; /**
diff --git a/ui/file_manager/file_manager/foreground/js/file_manager_commands.js b/ui/file_manager/file_manager/foreground/js/file_manager_commands.js index 5443c9fa..5786fe70 100644 --- a/ui/file_manager/file_manager/foreground/js/file_manager_commands.js +++ b/ui/file_manager/file_manager/foreground/js/file_manager_commands.js
@@ -133,7 +133,7 @@ hasDirectory = hasDirectory || entry.isDirectory; if (!entry || hasDirectory) return false; - var metadata = fileManager.getFileSystemMetadata().getCache( + var metadata = fileManager.getMetadataModel().getCache( [entry], ['hosted', 'pinned'])[0]; if (metadata.hosted) return false; @@ -892,7 +892,7 @@ return; var currentEntry; var error = false; - var fileSystemMetadata = fileManager.getFileSystemMetadata(); + var metadataModel = fileManager.getMetadataModel(); var steps = { // Pick an entry and pin it. start: function() { @@ -911,14 +911,14 @@ // Convert to boolean. error = !!chrome.runtime.lastError; if (error && pin) { - fileSystemMetadata.get([currentEntry], ['size']).then( + metadataModel.get([currentEntry], ['size']).then( function(results) { steps.showError(results[0].size); }); return; } - fileSystemMetadata.notifyEntriesChanged([currentEntry]); - fileSystemMetadata.get([currentEntry], ['pinned']).then(steps.updateUI); + metadataModel.notifyEntriesChanged([currentEntry]); + metadataModel.get([currentEntry], ['pinned']).then(steps.updateUI); }, // Update the user interface according to the cache state.
diff --git a/ui/file_manager/file_manager/foreground/js/file_selection.js b/ui/file_manager/file_manager/foreground/js/file_selection.js index edbf40e..3d2f852 100644 --- a/ui/file_manager/file_manager/foreground/js/file_selection.js +++ b/ui/file_manager/file_manager/foreground/js/file_selection.js
@@ -109,7 +109,7 @@ */ FileSelection.prototype.completeInit = function() { if (!this.asyncInitPromise_) { - this.asyncInitPromise_ = this.fileManager_.getFileSystemMetadata().get( + this.asyncInitPromise_ = this.fileManager_.getMetadataModel().get( this.entries, ['availableOffline', 'contentMimeType'] ).then(function(props) { var present = props.filter(function(p) { return p.availableOffline; });
diff --git a/ui/file_manager/file_manager/foreground/js/file_tasks.js b/ui/file_manager/file_manager/foreground/js/file_tasks.js index 5b405aa..b8459df9 100644 --- a/ui/file_manager/file_manager/foreground/js/file_tasks.js +++ b/ui/file_manager/file_manager/foreground/js/file_tasks.js
@@ -504,14 +504,14 @@ }; var fm = this.fileManager_; - var fileSystemMetadata = this.fileManager_.getFileSystemMetadata(); + var metadataModel = this.fileManager_.getMetadataModel(); var entries = assert(this.entries_); var isDriveOffline = fm.volumeManager.getDriveConnectionState().type === VolumeManagerCommon.DriveConnectionType.OFFLINE; if (fm.isOnDrive() && isDriveOffline) { - fileSystemMetadata.get(entries, ['availableOffline', 'hosted']).then( + metadataModel.get(entries, ['availableOffline', 'hosted']).then( function(props) { if (areAll(props, 'availableOffline')) { callback(); @@ -539,7 +539,7 @@ VolumeManagerCommon.DriveConnectionType.METERED; if (fm.isOnDrive() && isOnMetered) { - fileSystemMetadata.get(entries, ['availableWhenMetered', 'size']).then( + metadataModel.get(entries, ['availableWhenMetered', 'size']).then( function(props) { if (areAll(props, 'availableWhenMetered')) { callback();
diff --git a/ui/file_manager/file_manager/foreground/js/file_tasks_unittest.js b/ui/file_manager/file_manager/foreground/js/file_tasks_unittest.js index 6d5bb8d..f5e4809 100644 --- a/ui/file_manager/file_manager/foreground/js/file_tasks_unittest.js +++ b/ui/file_manager/file_manager/foreground/js/file_tasks_unittest.js
@@ -55,7 +55,7 @@ openSuggestAppsDialog: function( entry, onSuccess, onCancelled, onFailure) {} }, - getFileSystemMetadata: function() {} + getMetadataModel: function() {} }; }
diff --git a/ui/file_manager/file_manager/foreground/js/file_transfer_controller.js b/ui/file_manager/file_manager/foreground/js/file_transfer_controller.js index adc9be54..5ef1622 100644 --- a/ui/file_manager/file_manager/foreground/js/file_transfer_controller.js +++ b/ui/file_manager/file_manager/foreground/js/file_transfer_controller.js
@@ -24,7 +24,7 @@ * @param {!ProgressCenter} progressCenter To notify starting copy operation. * @param {!FileOperationManager} fileOperationManager File operation manager * instance. - * @param {!FileSystemMetadata} fileSystemMetadata Metadata cache service. + * @param {!MetadataModel} metadataModel Metadata cache service. * @param {!ThumbnailModel} thumbnailModel * @param {!DirectoryModel} directoryModel Directory model instance. * @param {!VolumeManagerWrapper} volumeManager Volume manager instance. @@ -38,7 +38,7 @@ multiProfileShareDialog, progressCenter, fileOperationManager, - fileSystemMetadata, + metadataModel, thumbnailModel, directoryModel, volumeManager, @@ -65,11 +65,11 @@ this.fileOperationManager_ = fileOperationManager; /** - * @type {!FileSystemMetadata} + * @type {!MetadataModel} * @private * @const */ - this.fileSystemMetadata_ = fileSystemMetadata; + this.metadataModel_ = metadataModel; /** * @type {!ThumbnailModel} @@ -1106,7 +1106,7 @@ this.preloadThumbnailImage_(entries[0]); } - this.fileSystemMetadata_.get(entries, ['externalFileUrl']).then( + this.metadataModel_.get(entries, ['externalFileUrl']).then( function(metadataList) { // |Copy| is the only menu item affected by allDriveFilesAvailable_. // It could be open right now, update its UI.
diff --git a/ui/file_manager/file_manager/foreground/js/main_scripts.js b/ui/file_manager/file_manager/foreground/js/main_scripts.js index fdc23be..4ac3b91fe 100644 --- a/ui/file_manager/file_manager/foreground/js/main_scripts.js +++ b/ui/file_manager/file_manager/foreground/js/main_scripts.js
@@ -109,11 +109,12 @@ //<include src="launch_param.js"> //<include src="metadata/content_metadata_provider.js"> //<include src="metadata/external_metadata_provider.js"> -//<include src="metadata/file_system_metadata.js"> //<include src="metadata/file_system_metadata_provider.js"> //<include src="metadata/metadata_cache.js"> //<include src="metadata/metadata_cache_item.js"> //<include src="metadata/metadata_item.js"> +//<include src="metadata/metadata_model.js"> +//<include src="metadata/multi_metadata_provider.js"> //<include src="metadata/thumbnail_model.js"> //<include src="metadata_update_controller.js"> //<include src="naming_controller.js">
diff --git a/ui/file_manager/file_manager/foreground/js/main_window_component.js b/ui/file_manager/file_manager/foreground/js/main_window_component.js index 754d3363..1a33690 100644 --- a/ui/file_manager/file_manager/foreground/js/main_window_component.js +++ b/ui/file_manager/file_manager/foreground/js/main_window_component.js
@@ -282,7 +282,7 @@ selection.indexes[0]); // If the item is in renaming process, we don't allow to change // directory. - if (!item.hasAttribute('renaming')) { + if (item && !item.hasAttribute('renaming')) { event.preventDefault(); this.directoryModel_.changeDirectoryEntry(selection.entries[0]); }
diff --git a/ui/file_manager/file_manager/foreground/js/metadata/compiled_resources.gyp b/ui/file_manager/file_manager/foreground/js/metadata/compiled_resources.gyp index 669a54c..15bcbaf 100644 --- a/ui/file_manager/file_manager/foreground/js/metadata/compiled_resources.gyp +++ b/ui/file_manager/file_manager/foreground/js/metadata/compiled_resources.gyp
@@ -18,6 +18,7 @@ 'function_parallel.js', ], 'externs': [ + '../../../../externs/exif_entry.js', '../../../../externs/platform_worker.js', ] },
diff --git a/ui/file_manager/file_manager/foreground/js/metadata/content_metadata_provider.js b/ui/file_manager/file_manager/foreground/js/metadata/content_metadata_provider.js index d245b95..b263a90 100644 --- a/ui/file_manager/file_manager/foreground/js/metadata/content_metadata_provider.js +++ b/ui/file_manager/file_manager/foreground/js/metadata/content_metadata_provider.js
@@ -3,17 +3,15 @@ // found in the LICENSE file. /** - * @param {!MetadataProviderCache} cache * @param {!MessagePort=} opt_messagePort Message port overriding the default * worker port. * @extends {NewMetadataProvider} * @constructor * @struct */ -function ContentMetadataProvider(cache, opt_messagePort) { +function ContentMetadataProvider(opt_messagePort) { NewMetadataProvider.call( this, - cache, ContentMetadataProvider.PROPERTY_NAMES); /** @@ -96,11 +94,14 @@ /** * @override */ -ContentMetadataProvider.prototype.getImpl = function(requests) { +ContentMetadataProvider.prototype.get = function(requests) { + if (!requests.length) + return Promise.resolve([]); + var promises = []; for (var i = 0; i < requests.length; i++) { promises.push(new Promise(function(request, fulfill) { - this.fetch(request.entry, request.names, fulfill); + this.getImpl_(request.entry, request.names, fulfill); }.bind(this, requests[i]))); } return Promise.all(promises); @@ -112,8 +113,9 @@ * @param {!Array<string>} names Requested metadata type. * @param {function(Object)} callback Callback expects a map from metadata type * to metadata value. This callback is called asynchronously. + * @private */ -ContentMetadataProvider.prototype.fetch = function(entry, names, callback) { +ContentMetadataProvider.prototype.getImpl_ = function(entry, names, callback) { if (entry.isDirectory) { setTimeout(callback.bind(null, {}), 0); return;
diff --git a/ui/file_manager/file_manager/foreground/js/metadata/content_metadata_provider_unittest.js b/ui/file_manager/file_manager/foreground/js/metadata/content_metadata_provider_unittest.js index e60977b..d77ec3c 100644 --- a/ui/file_manager/file_manager/foreground/js/metadata/content_metadata_provider_unittest.js +++ b/ui/file_manager/file_manager/foreground/js/metadata/content_metadata_provider_unittest.js
@@ -31,20 +31,21 @@ }, start: function() {} }; - var cache = new MetadataProviderCache(); - var provider = new ContentMetadataProvider(cache, port); - reportPromise(provider.get( - [entryA, entryB], - ['contentThumbnailUrl', 'contentThumbnailTransform']).then( - function(results) { - assertEquals(2, results.length); - assertEquals('filesystem://A,url', results[0].contentThumbnailUrl); - assertEquals( - 'filesystem://A,transform', - results[0].contentThumbnailTransform); - assertEquals('filesystem://B,url', results[1].contentThumbnailUrl); - assertEquals( - 'filesystem://B,transform', - results[1].contentThumbnailTransform); - }), callback); + var provider = new ContentMetadataProvider(port); + reportPromise(provider.get([ + new MetadataRequest( + entryA, ['contentThumbnailUrl', 'contentThumbnailTransform']), + new MetadataRequest( + entryB, ['contentThumbnailUrl', 'contentThumbnailTransform']) + ]).then(function(results) { + assertEquals(2, results.length); + assertEquals('filesystem://A,url', results[0].contentThumbnailUrl); + assertEquals( + 'filesystem://A,transform', + results[0].contentThumbnailTransform); + assertEquals('filesystem://B,url', results[1].contentThumbnailUrl); + assertEquals( + 'filesystem://B,transform', + results[1].contentThumbnailTransform); + }), callback); }
diff --git a/ui/file_manager/file_manager/foreground/js/metadata/external_metadata_provider.js b/ui/file_manager/file_manager/foreground/js/metadata/external_metadata_provider.js index f6cc007..261072053 100644 --- a/ui/file_manager/file_manager/foreground/js/metadata/external_metadata_provider.js +++ b/ui/file_manager/file_manager/foreground/js/metadata/external_metadata_provider.js
@@ -6,14 +6,12 @@ * Metadata provider for FileEntry#getMetadata. * TODO(hirono): Rename thumbnailUrl with externalThumbnailUrl. * - * @param {!MetadataProviderCache} cache * @constructor * @extends {NewMetadataProvider} * @struct */ -function ExternalMetadataProvider(cache) { - NewMetadataProvider.call( - this, cache, ExternalMetadataProvider.PROPERTY_NAMES); +function ExternalMetadataProvider() { + NewMetadataProvider.call(this, ExternalMetadataProvider.PROPERTY_NAMES); } /** @@ -44,7 +42,9 @@ /** * @override */ -ExternalMetadataProvider.prototype.getImpl = function(requests) { +ExternalMetadataProvider.prototype.get = function(requests) { + if (!requests.length) + return Promise.resolve([]); return new Promise(function(fulfill) { var urls = []; for (var i = 0; i < requests.length; i++) {
diff --git a/ui/file_manager/file_manager/foreground/js/metadata/external_metadata_provider_unittest.js b/ui/file_manager/file_manager/foreground/js/metadata/external_metadata_provider_unittest.js index b5a0509..198ef3e 100644 --- a/ui/file_manager/file_manager/foreground/js/metadata/external_metadata_provider_unittest.js +++ b/ui/file_manager/file_manager/foreground/js/metadata/external_metadata_provider_unittest.js
@@ -34,20 +34,19 @@ }, runtime: {lastError: null} }; - var cache = new MetadataProviderCache(); - var provider = new ExternalMetadataProvider(cache); - reportPromise(provider.get( - [entryA, entryB], - ['modificationTime', 'size']).then( - function(results) { - assertEquals(2, results.length); - assertEquals( - new Date(2015, 0, 1).toString(), - results[0].modificationTime.toString()); - assertEquals(1024, results[0].size); - assertEquals( - new Date(2015, 1, 2).toString(), - results[1].modificationTime.toString()); - assertEquals(2048, results[1].size); - }), callback); + var provider = new ExternalMetadataProvider(); + reportPromise(provider.get([ + new MetadataRequest(entryA, ['modificationTime', 'size']), + new MetadataRequest(entryB, ['modificationTime', 'size']), + ]).then(function(results) { + assertEquals(2, results.length); + assertEquals( + new Date(2015, 0, 1).toString(), + results[0].modificationTime.toString()); + assertEquals(1024, results[0].size); + assertEquals( + new Date(2015, 1, 2).toString(), + results[1].modificationTime.toString()); + assertEquals(2048, results[1].size); + }), callback); }
diff --git a/ui/file_manager/file_manager/foreground/js/metadata/file_system_metadata.js b/ui/file_manager/file_manager/foreground/js/metadata/file_system_metadata.js deleted file mode 100644 index 8841cf1..0000000 --- a/ui/file_manager/file_manager/foreground/js/metadata/file_system_metadata.js +++ /dev/null
@@ -1,199 +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. - -/** - * @param {!MetadataProviderCache} cache - * @param {!FileSystemMetadataProvider} fileSystemMetadataProvider - * @param {!ExternalMetadataProvider} externalMetadataProvider - * @param {!ContentMetadataProvider} contentMetadataProvider - * @param {!VolumeManagerCommon.VolumeInfoProvider} volumeManager - * @constructor - * @struct - */ -function FileSystemMetadata( - cache, - fileSystemMetadataProvider, - externalMetadataProvider, - contentMetadataProvider, - volumeManager) { - /** - * @private {!MetadataProviderCache} - * @const - */ - this.cache_ = cache; - - /** - * @private {!FileSystemMetadataProvider} - * @const - */ - this.fileSystemMetadataProvider_ = fileSystemMetadataProvider; - - /** - * @private {!ExternalMetadataProvider} - * @const - */ - this.externalMetadataProvider_ = externalMetadataProvider; - - /** - * @private {!ContentMetadataProvider} - * @const - */ - this.contentMetadataProvider_ = contentMetadataProvider; - - /** - * @private {!VolumeManagerCommon.VolumeInfoProvider} - * @const - */ - this.volumeManager_ = volumeManager; -} - -/** - * @param {!MetadataProviderCache} cache - * @param {!VolumeManagerCommon.VolumeInfoProvider} volumeManager - * @return {!FileSystemMetadata} - */ -FileSystemMetadata.create = function(cache, volumeManager) { - return new FileSystemMetadata( - cache, - new FileSystemMetadataProvider(cache), - new ExternalMetadataProvider(cache), - new ContentMetadataProvider(cache), - volumeManager); -}; - -/** - * Obtains metadata for entries. - * @param {!Array<!Entry>} entries Entries. - * @param {!Array<string>} names Metadata property names to be obtained. - * @return {!Promise<!Array<!MetadataItem>>} - */ -FileSystemMetadata.prototype.get = function(entries, names) { - var localEntries = []; - var externalEntries = []; - for (var i = 0; i < entries.length; i++) { - var volumeInfo = this.volumeManager_.getVolumeInfo(entries[i]); - if (volumeInfo && - (volumeInfo.volumeType === VolumeManagerCommon.VolumeType.DRIVE || - volumeInfo.volumeType === VolumeManagerCommon.VolumeType.PROVIDED)) { - externalEntries.push(entries[i]); - } else { - localEntries.push(entries[i]); - } - } - - // Group property names. - var fileSystemPropertyNames = []; - var externalPropertyNames = []; - var contentPropertyNames = []; - var fallbackContentPropertyNames = []; - for (var i = 0; i < names.length; i++) { - var name = names[i]; - var isFileSystemProperty = - FileSystemMetadataProvider.PROPERTY_NAMES.indexOf(name) !== -1; - var isExternalProperty = - ExternalMetadataProvider.PROPERTY_NAMES.indexOf(name) !== -1; - var isContentProperty = - ContentMetadataProvider.PROPERTY_NAMES.indexOf(name) !== -1; - assert(isFileSystemProperty || isExternalProperty || isContentProperty); - assert(!(isFileSystemProperty && isContentProperty)); - // If the property can be obtained both from ExternalProvider and from - // ContentProvider, we can obtain the property from ExternalProvider without - // fetching file content. On the other hand, the values from - // ExternalProvider may be out of sync if the file is 'dirty'. Thus we - // fallback to ContentProvider if the file is dirty. See below. - if (isExternalProperty && isContentProperty) { - externalPropertyNames.push(name); - fallbackContentPropertyNames.push(name); - continue; - } - if (isFileSystemProperty) - fileSystemPropertyNames.push(name); - if (isExternalProperty) - externalPropertyNames.push(name); - if (isContentProperty) - contentPropertyNames.push(name); - } - - // Obtain each group of property names. - var resultPromises = []; - var get = function(provider, entries, names) { - return provider.get(entries, names).then(function(results) { - return {entries: entries, results: results}; - }); - }; - resultPromises.push(get( - this.fileSystemMetadataProvider_, localEntries, fileSystemPropertyNames)); - resultPromises.push(get( - this.externalMetadataProvider_, externalEntries, externalPropertyNames)); - resultPromises.push(get( - this.contentMetadataProvider_, entries, contentPropertyNames)); - if (fallbackContentPropertyNames.length) { - var dirtyEntriesPromise = this.externalMetadataProvider_.get( - externalEntries, ['dirty']).then(function(results) { - return externalEntries.filter(function(entry, index) { - return results[index].dirty; - }); - }); - resultPromises.push(dirtyEntriesPromise.then(function(dirtyEntries) { - return get( - this.contentMetadataProvider_, - localEntries.concat(dirtyEntries), - fallbackContentPropertyNames); - }.bind(this))); - } - - // Merge results. - return Promise.all(resultPromises).then(function(resultsList) { - var integratedResults = {}; - for (var i = 0; i < resultsList.length; i++) { - var inEntries = resultsList[i].entries; - var results = resultsList[i].results; - for (var j = 0; j < inEntries.length; j++) { - var url = inEntries[j].toURL(); - integratedResults[url] = integratedResults[url] || new MetadataItem(); - for (var name in results[j]) { - integratedResults[url][name] = results[j][name]; - } - } - } - return entries.map(function(entry) { - return integratedResults[entry.toURL()]; - }); - }); -}; - -/** - * Obtains metadata cache for entries. - * @param {!Array<!Entry>} entries Entries. - * @param {!Array<string>} names Metadata property names to be obtained. - * @return {!Array<!MetadataItem>} - */ -FileSystemMetadata.prototype.getCache = function(entries, names) { - return this.cache_.get(entries, names); -}; - -/** - * Clears old metadata for newly created entries. - * @param {!Array<!Entry>} entries - */ -FileSystemMetadata.prototype.notifyEntriesCreated = function(entries) { - this.cache_.clear(util.entriesToURLs(entries)); -}; - -/** - * Clears metadata for deleted entries. - * @param {!Array<string>} urls Note it is not an entry list because we cannot - * obtain entries after removing them from the file system. - */ -FileSystemMetadata.prototype.notifyEntriesRemoved = function(urls) { - this.cache_.clear(urls); -}; - -/** - * Invalidates metadata for updated entries. - * @param {!Array<!Entry>} entries - */ -FileSystemMetadata.prototype.notifyEntriesChanged = function(entries) { - this.cache_.invalidate(this.cache_.generateRequestId(), entries); -};
diff --git a/ui/file_manager/file_manager/foreground/js/metadata/file_system_metadata_provider.js b/ui/file_manager/file_manager/foreground/js/metadata/file_system_metadata_provider.js index 01c8519..41b40f6f 100644 --- a/ui/file_manager/file_manager/foreground/js/metadata/file_system_metadata_provider.js +++ b/ui/file_manager/file_manager/foreground/js/metadata/file_system_metadata_provider.js
@@ -5,14 +5,12 @@ /** * Metadata provider for FileEntry#getMetadata. * - * @param {!MetadataProviderCache} cache * @constructor * @extends {NewMetadataProvider} * @struct */ -function FileSystemMetadataProvider(cache) { - NewMetadataProvider.call( - this, cache, FileSystemMetadataProvider.PROPERTY_NAMES); +function FileSystemMetadataProvider() { + NewMetadataProvider.call(this, FileSystemMetadataProvider.PROPERTY_NAMES); } /** @@ -27,7 +25,9 @@ /** * @override */ -FileSystemMetadataProvider.prototype.getImpl = function(requests) { +FileSystemMetadataProvider.prototype.get = function(requests) { + if (!requests.length) + return Promise.resolve([]); return Promise.all(requests.map(function(request) { return Promise.all([ new Promise(function(fulfill, reject) {
diff --git a/ui/file_manager/file_manager/foreground/js/metadata/file_system_metadata_provider_unittest.js b/ui/file_manager/file_manager/foreground/js/metadata/file_system_metadata_provider_unittest.js index 3f81abd..bd90df8 100644 --- a/ui/file_manager/file_manager/foreground/js/metadata/file_system_metadata_provider_unittest.js +++ b/ui/file_manager/file_manager/foreground/js/metadata/file_system_metadata_provider_unittest.js
@@ -40,45 +40,44 @@ } function testFileSystemMetadataProviderBasic(callback) { - var cache = new MetadataProviderCache(); - var provider = new FileSystemMetadataProvider(cache); - reportPromise(provider.get( - [entryA, entryB], - ['modificationTime', 'size', 'contentMimeType', - 'present', 'availableOffline']).then( - function(results) { - assertEquals(2, results.length); - assertEquals( - new Date(2015, 1, 1).toString(), - results[0].modificationTime.toString()); - assertEquals(1024, results[0].size); - assertEquals('application/A', results[0].contentMimeType); - assertTrue(results[0].present); - assertTrue(results[0].availableOffline); - assertEquals( - new Date(2015, 2, 2).toString(), - results[1].modificationTime.toString()); - assertEquals(2048, results[1].size); - assertEquals('application/B', results[1].contentMimeType); - assertTrue(results[1].present); - assertTrue(results[1].availableOffline); - }), callback); + var provider = new FileSystemMetadataProvider(); + var names = [ + 'modificationTime', 'size', 'contentMimeType', 'present', + 'availableOffline']; + reportPromise(provider.get([ + new MetadataRequest(entryA, names), + new MetadataRequest(entryB, names) + ]).then(function(results) { + assertEquals(2, results.length); + assertEquals( + new Date(2015, 1, 1).toString(), + results[0].modificationTime.toString()); + assertEquals(1024, results[0].size); + assertEquals('application/A', results[0].contentMimeType); + assertTrue(results[0].present); + assertTrue(results[0].availableOffline); + assertEquals( + new Date(2015, 2, 2).toString(), + results[1].modificationTime.toString()); + assertEquals(2048, results[1].size); + assertEquals('application/B', results[1].contentMimeType); + assertTrue(results[1].present); + assertTrue(results[1].availableOffline); + }), callback); } function testFileSystemMetadataProviderPartialRequest(callback) { - var cache = new MetadataProviderCache(); - var provider = new FileSystemMetadataProvider(cache); + var provider = new FileSystemMetadataProvider(); reportPromise(provider.get( - [entryA], - ['modificationTime', 'size']).then( - function(results) { - assertEquals(1, results.length); - assertEquals( - new Date(2015, 1, 1).toString(), - results[0].modificationTime.toString()); - assertEquals(1024, results[0].size); - // When contentMimeType is not requested, this shouldn't try to get - // MIME type. - assertFalse(chrome.fileManagerPrivate.isGetMimeTypeCalled_); - }), callback); + [new MetadataRequest(entryA, ['modificationTime', 'size'])]).then( + function(results) { + assertEquals(1, results.length); + assertEquals( + new Date(2015, 1, 1).toString(), + results[0].modificationTime.toString()); + assertEquals(1024, results[0].size); + // When contentMimeType is not requested, this shouldn't try to get + // MIME type. + assertFalse(chrome.fileManagerPrivate.isGetMimeTypeCalled_); + }), callback); }
diff --git a/ui/file_manager/file_manager/foreground/js/metadata/file_system_metadata_unittest.js b/ui/file_manager/file_manager/foreground/js/metadata/file_system_metadata_unittest.js deleted file mode 100644 index 1650b7c..0000000 --- a/ui/file_manager/file_manager/foreground/js/metadata/file_system_metadata_unittest.js +++ /dev/null
@@ -1,141 +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. - -var entryA = { - toURL: function() { return 'filesystem://A'; } -}; - -var entryB = { - toURL: function() { return 'filesystem://B'; } -}; - -var entryC = { - toURL: function() { return 'filesystem://C'; } -}; - -var volumeManager = { - getVolumeInfo: function(entry) { - if (entry.toURL() === 'filesystem://A') { - return { - volumeType: VolumeManagerCommon.VolumeType.DOWNLOADS - }; - } else if (entry.toURL() === 'filesystem://B') { - return { - volumeType: VolumeManagerCommon.VolumeType.DRIVE - }; - } else if (entry.toURL() === 'filesystem://C') { - return { - volumeType: VolumeManagerCommon.VolumeType.DRIVE - }; - } - assertNotReached(); - } -}; - -function testFileSystemMetadataBasic(callback) { - var cache = new MetadataProviderCache(); - var model = new FileSystemMetadata( - cache, - // Mocking FileSystemMetadataProvider. - { - get: function(entries, names) { - assertEquals(1, entries.length); - assertEquals('filesystem://A', entries[0].toURL()); - assertArrayEquals(['size', 'modificationTime'], names); - return Promise.resolve( - [{modificationTime: new Date(2015, 0, 1), size: 1024}]); - } - }, - // Mocking ExternalMetadataProvider. - { - get: function(entries, names) { - assertEquals(1, entries.length); - assertEquals('filesystem://B', entries[0].toURL()); - assertArrayEquals(['size', 'modificationTime'], names); - return Promise.resolve( - [{modificationTime: new Date(2015, 1, 2), size: 2048}]); - } - }, - // Mocking ContentMetadataProvider. - { - get: function(entries, names) { - assertEquals(2, entries.length); - assertEquals('filesystem://A', entries[0].toURL()); - assertEquals('filesystem://B', entries[1].toURL()); - assertArrayEquals(['contentThumbnailUrl'], names); - return Promise.resolve([ - {contentThumbnailUrl: 'THUMBNAIL_URL_A'}, - {contentThumbnailUrl: 'THUMBNAIL_URL_B'} - ]); - } - }, - // Mocking VolumeManagerWrapper. - volumeManager); - reportPromise( - model.get( - [entryA, entryB], - ['size', 'modificationTime', 'contentThumbnailUrl']).then( - function(results) { - assertEquals(2, results.length); - assertEquals( - new Date(2015, 0, 1).toString(), - results[0].modificationTime.toString()); - assertEquals(1024, results[0].size); - assertEquals('THUMBNAIL_URL_A', results[0].contentThumbnailUrl); - assertEquals( - new Date(2015, 1, 2).toString(), - results[1].modificationTime.toString()); - assertEquals(2048, results[1].size); - assertEquals('THUMBNAIL_URL_B', results[1].contentThumbnailUrl); - }), callback); -} - -function testFileSystemMetadataExternalAndContentProperty(callback) { - var cache = new MetadataProviderCache(); - var model = new FileSystemMetadata( - cache, - // Mocking FileSystemMetadataProvider. - { - get: function(entries, names) { - assertEquals(0, names.length); - return Promise.resolve([{}]); - } - }, - // Mocking ExternalMetadataProvider. - { - get: function(entries, names) { - assertEquals(2, entries.length); - assertEquals('filesystem://B', entries[0].toURL()); - assertEquals('filesystem://C', entries[1].toURL()); - return Promise.resolve([ - {dirty: false, imageWidth: 200}, - {dirty: true, imageWidth: 400} - ]); - } - }, - // Mocking ContentMetadataProvider. - { - get: function(entries, names) { - if (names.length == 0) - return Promise.resolve(entries.map(function() { return {}; })); - assertEquals(2, entries.length); - assertEquals('filesystem://A', entries[0].toURL()); - assertEquals('filesystem://C', entries[1].toURL()); - assertArrayEquals(['imageWidth'], names); - return Promise.resolve([ - {imageWidth: 100}, - {imageWidth: 300} - ]); - } - }, - // Mocking VolumeManagerWrapper. - volumeManager); - reportPromise(model.get([entryA, entryB, entryC], ['imageWidth']).then( - function(results) { - assertEquals(3, results.length); - assertEquals(100, results[0].imageWidth); - assertEquals(200, results[1].imageWidth); - assertEquals(300, results[2].imageWidth); - }), callback); -}
diff --git a/ui/file_manager/file_manager/foreground/js/metadata/metadata_model.js b/ui/file_manager/file_manager/foreground/js/metadata/metadata_model.js new file mode 100644 index 0000000..bd46fa8 --- /dev/null +++ b/ui/file_manager/file_manager/foreground/js/metadata/metadata_model.js
@@ -0,0 +1,240 @@ +// 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. + +/** + * @param {!NewMetadataProvider} rawProvider + * @constructor + * @struct + */ +function MetadataModel(rawProvider) { + /** + * @private {!NewMetadataProvider} + * @const + */ + this.rawProvider_ = rawProvider; + + /** + * @private {!MetadataProviderCache} + * @const + */ + this.cache_ = new MetadataProviderCache(); + + /** + * @private {!Array<!MetadataProviderCallbackRequest<T>>} + * @const + */ + this.callbackRequests_ = []; +} + +/** + * @param {!VolumeManagerCommon.VolumeInfoProvider} volumeManager + * @return {!MetadataModel} + */ +MetadataModel.create = function(volumeManager) { + return new MetadataModel( + new MultiMetadataProvider( + new FileSystemMetadataProvider(), + new ExternalMetadataProvider(), + new ContentMetadataProvider(), + volumeManager)); +}; + +/** + * @return {!NewMetadataProvider} + */ +MetadataModel.prototype.getProvider = function() { + return this.rawProvider_; +}; + +/** + * Obtains metadata for entries. + * @param {!Array<!Entry>} entries Entries. + * @param {!Array<string>} names Metadata property names to be obtained. + * @return {!Promise<!Array<!MetadataItem>>} + */ +MetadataModel.prototype.get = function(entries, names) { + this.rawProvider_.checkPropertyNames(names); + + // Check if the results are cached or not. + if (this.cache_.hasFreshCache(entries, names)) + return Promise.resolve(this.getCache(entries, names)); + + // The LRU cache may be cached out when the callback is completed. + // To hold cached values, create snapshot of the cache for entries. + var requestId = this.cache_.generateRequestId(); + var snapshot = this.cache_.createSnapshot(entries); + var requests = snapshot.createRequests(entries, names); + snapshot.startRequests(requestId, requests); + this.cache_.startRequests(requestId, requests); + + // Register callback. + var promise = new Promise(function(fulfill) { + this.callbackRequests_.push(new MetadataProviderCallbackRequest( + entries, names, snapshot, fulfill)); + }.bind(this)); + + // If the requests are not empty, call the requests. + if (requests.length) { + this.rawProvider_.get(requests).then(function(list) { + // Obtain requested entries and ensure all the requested properties are + // contained in the result. + var requestedEntries = []; + for (var i = 0; i < requests.length; i++) { + requestedEntries.push(requests[i].entry); + for (var j = 0; j < requests[i].names.length; j++) { + var name = requests[i].names[j]; + if (!(name in list[i])) + list[i][name] = undefined; + } + } + + // Store cache. + this.cache_.storeProperties(requestId, requestedEntries, list); + + // Invoke callbacks. + var i = 0; + while (i < this.callbackRequests_.length) { + if (this.callbackRequests_[i].storeProperties( + requestId, requestedEntries, list)) { + // Callback was called. + this.callbackRequests_.splice(i, 1); + } else { + i++; + } + } + }.bind(this)); + } + + return promise; +}; + +/** + * Obtains metadata cache for entries. + * @param {!Array<!Entry>} entries Entries. + * @param {!Array<string>} names Metadata property names to be obtained. + * @return {!Array<!MetadataItem>} + */ +MetadataModel.prototype.getCache = function(entries, names) { + // Check if the property name is correct or not. + this.rawProvider_.checkPropertyNames(names); + return this.cache_.get(entries, names); +}; + +/** + * Clears old metadata for newly created entries. + * @param {!Array<!Entry>} entries + */ +MetadataModel.prototype.notifyEntriesCreated = function(entries) { + this.cache_.clear(util.entriesToURLs(entries)); +}; + +/** + * Clears metadata for deleted entries. + * @param {!Array<string>} urls Note it is not an entry list because we cannot + * obtain entries after removing them from the file system. + */ +MetadataModel.prototype.notifyEntriesRemoved = function(urls) { + this.cache_.clear(urls); +}; + +/** + * Invalidates metadata for updated entries. + * @param {!Array<!Entry>} entries + */ +MetadataModel.prototype.notifyEntriesChanged = function(entries) { + this.cache_.invalidate(this.cache_.generateRequestId(), entries); +}; + +/** + * Clears all cache. + */ +MetadataModel.prototype.clearAllCache = function() { + this.cache_.clearAll(); +}; + +/** + * Adds event listener to internal cache object. + * @param {string} type + * @param {function(Event):undefined} callback + */ +MetadataModel.prototype.addEventListener = function(type, callback) { + this.cache_.addEventListener(type, callback); +}; + +/** + * @param {!Array<!Entry>} entries + * @param {!Array<string>} names + * @param {!MetadataCacheSet} cache + * @param {function(!MetadataItem):undefined} fulfill + * @constructor + * @struct + */ +function MetadataProviderCallbackRequest(entries, names, cache, fulfill) { + /** + * @private {!Array<!Entry>} + * @const + */ + this.entries_ = entries; + + /** + * @private {!Array<string>} + * @const + */ + this.names_ = names; + + /** + * @private {!MetadataCacheSet} + * @const + */ + this.cache_ = cache; + + /** + * @private {function(!MetadataItem):undefined} + * @const + */ + this.fulfill_ = fulfill; +} + +/** + * Stores properties to snapshot cache of the callback request. + * If all the requested property are served, it invokes the callback. + * @param {number} requestId + * @param {!Array<!Entry>} entries + * @param {!Array<!MetadataItem>} objects + * @return {boolean} Whether the callback is invoked or not. + */ +MetadataProviderCallbackRequest.prototype.storeProperties = function( + requestId, entries, objects) { + this.cache_.storeProperties(requestId, entries, objects); + if (this.cache_.hasFreshCache(this.entries_, this.names_)) { + this.fulfill_(this.cache_.get(this.entries_, this.names_)); + return true; + } + return false; +}; + +/** + * Helper wrapper for LRUCache. + * @constructor + * @extends {MetadataCacheSet} + * @struct + */ +function MetadataProviderCache() { + MetadataCacheSet.call(this, new MetadataCacheSetStorageForObject({})); + + /** + * @private {number} + */ + this.requestIdCounter_ = 0; +} + +MetadataProviderCache.prototype.__proto__ = MetadataCacheSet.prototype; + +/** + * Generates a unique request ID every time when it is called. + * @return {number} + */ +MetadataProviderCache.prototype.generateRequestId = function() { + return this.requestIdCounter_++; +};
diff --git a/ui/file_manager/file_manager/foreground/js/metadata/new_metadata_provider_unittest.html b/ui/file_manager/file_manager/foreground/js/metadata/metadata_model_unittest.html similarity index 88% rename from ui/file_manager/file_manager/foreground/js/metadata/new_metadata_provider_unittest.html rename to ui/file_manager/file_manager/foreground/js/metadata/metadata_model_unittest.html index 476242cd..974816d 100644 --- a/ui/file_manager/file_manager/foreground/js/metadata/new_metadata_provider_unittest.html +++ b/ui/file_manager/file_manager/foreground/js/metadata/metadata_model_unittest.html
@@ -14,6 +14,7 @@ <script src="../../../common/js/unittest_util.js"></script> <script src="metadata_cache_item.js"></script> <script src="metadata_item.js"></script> +<script src="metadata_model.js"></script> <script src="new_metadata_provider.js"></script> -<script src="new_metadata_provider_unittest.js"></script> +<script src="metadata_model_unittest.js"></script>
diff --git a/ui/file_manager/file_manager/foreground/js/metadata/metadata_model_unittest.js b/ui/file_manager/file_manager/foreground/js/metadata/metadata_model_unittest.js new file mode 100644 index 0000000..64dd6c9e --- /dev/null +++ b/ui/file_manager/file_manager/foreground/js/metadata/metadata_model_unittest.js
@@ -0,0 +1,172 @@ +// 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. + +function TestMetadataProvider() { + NewMetadataProvider.call(this, ['property', 'propertyA', 'propertyB']); + this.requestCount = 0; +} + +TestMetadataProvider.prototype.__proto__ = NewMetadataProvider.prototype; + +TestMetadataProvider.prototype.get = function(requests) { + this.requestCount++; + return Promise.resolve(requests.map(function(request) { + var entry = request.entry; + var names = request.names; + var result = {}; + for (var i = 0; i < names.length; i++) { + result[names[i]] = entry.toURL() + ':' + names[i]; + } + return result; + })); +}; + +function TestEmptyMetadataProvider() { + NewMetadataProvider.call(this, ['property']); +} + +TestEmptyMetadataProvider.prototype.__proto__ = NewMetadataProvider.prototype; + +TestEmptyMetadataProvider.prototype.get = function(requests) { + return Promise.resolve(requests.map(function() { + return {}; + })); +}; + +function ManualTestMetadataProvider() { + NewMetadataProvider.call( + this, ['propertyA', 'propertyB', 'propertyC']); + this.callback = []; +} + +ManualTestMetadataProvider.prototype.__proto__ = NewMetadataProvider.prototype; + +ManualTestMetadataProvider.prototype.get = function(requests) { + return new Promise(function(fulfill) { + this.callback.push(fulfill); + }.bind(this)); +}; + +var entryA = { + toURL: function() { return "filesystem://A"; } +}; + +var entryB = { + toURL: function() { return "filesystem://B"; } +}; + +function testMetadataModelBasic(callback) { + var model = new MetadataModel(new TestMetadataProvider()); + reportPromise(model.get([entryA, entryB], ['property']).then( + function(results) { + assertEquals(1, model.getProvider().requestCount); + assertEquals('filesystem://A:property', results[0].property); + assertEquals('filesystem://B:property', results[1].property); + }), callback); +} + +function testMetadataModelRequestForCachedProperty(callback) { + var model = new MetadataModel(new TestMetadataProvider()); + reportPromise(model.get([entryA, entryB], ['property']).then( + function() { + // All the result should be cached here. + return model.get([entryA, entryB], ['property']); + }).then(function(results) { + assertEquals(1, model.getProvider().requestCount); + assertEquals('filesystem://A:property', results[0].property); + assertEquals('filesystem://B:property', results[1].property); + }), callback); +} + +function testMetadataModelRequestForCachedAndNonCachedProperty(callback) { + var model = new MetadataModel(new TestMetadataProvider()); + reportPromise(model.get([entryA, entryB], ['propertyA']).then( + function() { + assertEquals(1, model.getProvider().requestCount); + // propertyB has not been cached here. + return model.get([entryA, entryB], ['propertyA', 'propertyB']); + }).then(function(results) { + assertEquals(2, model.getProvider().requestCount); + assertEquals('filesystem://A:propertyA', results[0].propertyA); + assertEquals('filesystem://A:propertyB', results[0].propertyB); + assertEquals('filesystem://B:propertyA', results[1].propertyA); + assertEquals('filesystem://B:propertyB', results[1].propertyB); + }), callback); +} + +function testMetadataModelRequestForCachedAndNonCachedEntry(callback) { + var model = new MetadataModel(new TestMetadataProvider()); + reportPromise(model.get([entryA], ['property']).then( + function() { + assertEquals(1, model.getProvider().requestCount); + // entryB has not been cached here. + return model.get([entryA, entryB], ['property']); + }).then(function(results) { + assertEquals(2, model.getProvider().requestCount); + assertEquals('filesystem://A:property', results[0].property); + assertEquals('filesystem://B:property', results[1].property); + }), callback); +} + +function testMetadataModelRequestBeforeCompletingPreviousRequest( + callback) { + var model = new MetadataModel(new TestMetadataProvider()); + model.get([entryA], ['property']); + assertEquals(1, model.getProvider().requestCount); + // The result of first call has not been fetched yet. + reportPromise(model.get([entryA], ['property']).then( + function(results) { + assertEquals(1, model.getProvider().requestCount); + assertEquals('filesystem://A:property', results[0].property); + }), callback); +} + +function testMetadataModelNotUpdateCachedResultAfterRequest( + callback) { + var model = new MetadataModel(new ManualTestMetadataProvider()); + var promise = model.get([entryA], ['propertyA']); + model.getProvider().callback[0]([{propertyA: 'valueA1'}]); + reportPromise(promise.then(function() { + // 'propertyA' is cached here. + var promise1 = model.get([entryA], ['propertyA', 'propertyB']); + var promise2 = model.get([entryA], ['propertyC']); + // Returns propertyC. + model.getProvider().callback[2]( + [{propertyA: 'valueA2', propertyC: 'valueC'}]); + model.getProvider().callback[1]([{propertyB: 'valueB'}]); + return Promise.all([promise1, promise2]); + }).then(function(results) { + // The result should be cached value at the time when get was called. + assertEquals('valueA1', results[0][0].propertyA); + assertEquals('valueB', results[0][0].propertyB); + assertEquals('valueC', results[1][0].propertyC); + }), callback); +} + +function testMetadataModelGetCache(callback) { + var model = new MetadataModel(new TestMetadataProvider()); + var promise = model.get([entryA], ['property']); + var cache = model.getCache([entryA], ['property']); + assertEquals(null, cache[0].property); + reportPromise(promise.then(function() { + var cache = model.getCache([entryA], ['property']); + assertEquals(1, model.getProvider().requestCount); + assertEquals('filesystem://A:property', cache[0].property); + }), callback); +} + +function testMetadataModelUnknownProperty() { + var model = new MetadataModel(new TestMetadataProvider()); + assertThrows(function() { + model.get([entryA], ['unknown']); + }); +} + +function testMetadataModelEmptyResult(callback) { + var model = new MetadataModel(new TestEmptyMetadataProvider()); + // getImpl returns empty result. + reportPromise(model.get([entryA], ['property']).then(function(results) { + assertEquals(undefined, results[0].property); + }), callback); +}
diff --git a/ui/file_manager/file_manager/foreground/js/metadata/multi_metadata_provider.js b/ui/file_manager/file_manager/foreground/js/metadata/multi_metadata_provider.js new file mode 100644 index 0000000..ae1a123 --- /dev/null +++ b/ui/file_manager/file_manager/foreground/js/metadata/multi_metadata_provider.js
@@ -0,0 +1,170 @@ +// 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. + +/** + * @param {!FileSystemMetadataProvider} fileSystemMetadataProvider + * @param {!ExternalMetadataProvider} externalMetadataProvider + * @param {!ContentMetadataProvider} contentMetadataProvider + * @param {!VolumeManagerCommon.VolumeInfoProvider} volumeManager + * @constructor + * @extends {NewMetadataProvider} + * @struct + */ +function MultiMetadataProvider( + fileSystemMetadataProvider, + externalMetadataProvider, + contentMetadataProvider, + volumeManager) { + NewMetadataProvider.call( + this, + FileSystemMetadataProvider.PROPERTY_NAMES.concat( + ExternalMetadataProvider.PROPERTY_NAMES).concat( + ContentMetadataProvider.PROPERTY_NAMES)); + + /** + * @private {!FileSystemMetadataProvider} + * @const + */ + this.fileSystemMetadataProvider_ = fileSystemMetadataProvider; + + /** + * @private {!ExternalMetadataProvider} + * @const + */ + this.externalMetadataProvider_ = externalMetadataProvider; + + /** + * @private {!ContentMetadataProvider} + * @const + */ + this.contentMetadataProvider_ = contentMetadataProvider; + + /** + * @private {!VolumeManagerCommon.VolumeInfoProvider} + * @const + */ + this.volumeManager_ = volumeManager; +} + +MultiMetadataProvider.prototype.__proto__ = NewMetadataProvider.prototype; + +/** + * Obtains metadata for entries. + * @param {!Array<!MetadataRequest>} requests + * @return {!Promise<!Array<!MetadataItem>>} + */ +MultiMetadataProvider.prototype.get = function(requests) { + var fileSystemRequests = []; + var externalRequests = []; + var contentRequests = []; + var fallbackContentRequests = []; + requests.forEach(function(request) { + // Group property names. + var fileSystemPropertyNames = []; + var externalPropertyNames = []; + var contentPropertyNames = []; + var fallbackContentPropertyNames = []; + for (var i = 0; i < request.names.length; i++) { + var name = request.names[i]; + var isFileSystemProperty = + FileSystemMetadataProvider.PROPERTY_NAMES.indexOf(name) !== -1; + var isExternalProperty = + ExternalMetadataProvider.PROPERTY_NAMES.indexOf(name) !== -1; + var isContentProperty = + ContentMetadataProvider.PROPERTY_NAMES.indexOf(name) !== -1; + assert(isFileSystemProperty || isExternalProperty || isContentProperty); + assert(!(isFileSystemProperty && isContentProperty)); + // If the property can be obtained both from ExternalProvider and from + // ContentProvider, we can obtain the property from ExternalProvider + // without fetching file content. On the other hand, the values from + // ExternalProvider may be out of sync if the file is 'dirty'. Thus we + // fallback to ContentProvider if the file is dirty. See below. + if (isExternalProperty && isContentProperty) { + externalPropertyNames.push(name); + fallbackContentPropertyNames.push(name); + continue; + } + if (isFileSystemProperty) + fileSystemPropertyNames.push(name); + if (isExternalProperty) + externalPropertyNames.push(name); + if (isContentProperty) + contentPropertyNames.push(name); + } + var volumeInfo = this.volumeManager_.getVolumeInfo(request.entry); + var addRequests = function(list, names) { + if (names.length) + list.push(new MetadataRequest(request.entry, names)); + }; + if (volumeInfo && + (volumeInfo.volumeType === VolumeManagerCommon.VolumeType.DRIVE || + volumeInfo.volumeType === VolumeManagerCommon.VolumeType.PROVIDED)) { + if (fallbackContentPropertyNames.length && + externalPropertyNames.indexOf('dirty') === -1) { + externalPropertyNames.push('dirty'); + } + addRequests(externalRequests, externalPropertyNames); + addRequests(contentRequests, contentPropertyNames); + addRequests(fallbackContentRequests, fallbackContentPropertyNames); + } else { + addRequests(fileSystemRequests, fileSystemPropertyNames); + addRequests( + contentRequests, + contentPropertyNames.concat(fallbackContentPropertyNames)); + } + }.bind(this)); + + var get = function(provider, inRequests) { + return provider.get(inRequests).then(function(results) { + return { + requests: inRequests, + results: results + }; + }); + }; + var fileSystemPromise = get( + this.fileSystemMetadataProvider_, fileSystemRequests); + var externalPromise = get(this.externalMetadataProvider_, externalRequests); + var contentPromise = get(this.contentMetadataProvider_, contentRequests); + var fallbackContentPromise = externalPromise.then( + function(requestsAndResults) { + var requests = requestsAndResults.requests; + var results = requestsAndResults.results; + var dirtyMap = []; + for (var i = 0; i < results.length; i++) { + dirtyMap[requests[i].entry.toURL()] = results[i].dirty; + } + return get( + this.contentMetadataProvider_, + fallbackContentRequests.filter( + function(request) { + return dirtyMap[request.entry.toURL()]; + })); + }.bind(this)); + + // Merge results. + return Promise.all([ + fileSystemPromise, + externalPromise, + contentPromise, + fallbackContentPromise + ]).then(function(resultsList) { + var integratedResults = {}; + for (var i = 0; i < resultsList.length; i++) { + var inRequests = resultsList[i].requests; + var results = resultsList[i].results; + assert(inRequests.length === results.length); + for (var j = 0; j < results.length; j++) { + var url = inRequests[j].entry.toURL(); + integratedResults[url] = integratedResults[url] || new MetadataItem(); + for (var name in results[j]) { + integratedResults[url][name] = results[j][name]; + } + } + } + return requests.map(function(request) { + return integratedResults[request.entry.toURL()] || new MetadataItem(); + }); + }); +};
diff --git a/ui/file_manager/file_manager/foreground/js/metadata/file_system_metadata_unittest.html b/ui/file_manager/file_manager/foreground/js/metadata/multi_metadata_provider_unittest.html similarity index 89% rename from ui/file_manager/file_manager/foreground/js/metadata/file_system_metadata_unittest.html rename to ui/file_manager/file_manager/foreground/js/metadata/multi_metadata_provider_unittest.html index 7c23ebc7..2d2bc622 100644 --- a/ui/file_manager/file_manager/foreground/js/metadata/file_system_metadata_unittest.html +++ b/ui/file_manager/file_manager/foreground/js/metadata/multi_metadata_provider_unittest.html
@@ -16,9 +16,9 @@ <script src="../../../common/js/volume_manager_common.js"></script> <script src="content_metadata_provider.js"></script> <script src="external_metadata_provider.js"></script> -<script src="file_system_metadata.js"></script> <script src="file_system_metadata_provider.js"></script> <script src="metadata_cache_item.js"></script> <script src="metadata_item.js"></script> +<script src="multi_metadata_provider.js"></script> -<script src="file_system_metadata_unittest.js"></script> +<script src="multi_metadata_provider_unittest.js"></script>
diff --git a/ui/file_manager/file_manager/foreground/js/metadata/multi_metadata_provider_unittest.js b/ui/file_manager/file_manager/foreground/js/metadata/multi_metadata_provider_unittest.js new file mode 100644 index 0000000..41fcfdea --- /dev/null +++ b/ui/file_manager/file_manager/foreground/js/metadata/multi_metadata_provider_unittest.js
@@ -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. + +var entryA = { + toURL: function() { return 'filesystem://A'; } +}; + +var entryB = { + toURL: function() { return 'filesystem://B'; } +}; + +var entryC = { + toURL: function() { return 'filesystem://C'; } +}; + +var volumeManager = { + getVolumeInfo: function(entry) { + if (entry.toURL() === 'filesystem://A') { + return { + volumeType: VolumeManagerCommon.VolumeType.DOWNLOADS + }; + } else if (entry.toURL() === 'filesystem://B') { + return { + volumeType: VolumeManagerCommon.VolumeType.DRIVE + }; + } else if (entry.toURL() === 'filesystem://C') { + return { + volumeType: VolumeManagerCommon.VolumeType.DRIVE + }; + } + assertNotReached(); + } +}; + +function testMultiMetadataProviderBasic(callback) { + var model = new MultiMetadataProvider( + // Mocking FileSystemMetadataProvider. + { + get: function(requests) { + assertEquals(1, requests.length); + assertEquals('filesystem://A', requests[0].entry.toURL()); + assertArrayEquals(['size', 'modificationTime'], requests[0].names); + return Promise.resolve( + [{modificationTime: new Date(2015, 0, 1), size: 1024}]); + } + }, + // Mocking ExternalMetadataProvider. + { + get: function(requests) { + assertEquals(1, requests.length); + assertEquals('filesystem://B', requests[0].entry.toURL()); + assertArrayEquals(['size', 'modificationTime'], requests[0].names); + return Promise.resolve( + [{modificationTime: new Date(2015, 1, 2), size: 2048}]); + } + }, + // Mocking ContentMetadataProvider. + { + get: function(requests) { + if (requests.length === 0) + return Promise.resolve([]); + assertEquals(2, requests.length); + assertEquals('filesystem://A', requests[0].entry.toURL()); + assertEquals('filesystem://B', requests[1].entry.toURL()); + assertArrayEquals(['contentThumbnailUrl'], requests[0].names); + assertArrayEquals(['contentThumbnailUrl'], requests[1].names); + return Promise.resolve([ + {contentThumbnailUrl: 'THUMBNAIL_URL_A'}, + {contentThumbnailUrl: 'THUMBNAIL_URL_B'} + ]); + } + }, + // Mocking VolumeManagerWrapper. + volumeManager); + reportPromise(model.get([ + new MetadataRequest( + entryA, ['size', 'modificationTime', 'contentThumbnailUrl']), + new MetadataRequest( + entryB, ['size', 'modificationTime', 'contentThumbnailUrl']) + ]).then(function(results) { + assertEquals(2, results.length); + assertEquals( + new Date(2015, 0, 1).toString(), + results[0].modificationTime.toString()); + assertEquals(1024, results[0].size); + assertEquals('THUMBNAIL_URL_A', results[0].contentThumbnailUrl); + assertEquals( + new Date(2015, 1, 2).toString(), + results[1].modificationTime.toString()); + assertEquals(2048, results[1].size); + assertEquals('THUMBNAIL_URL_B', results[1].contentThumbnailUrl); + }), callback); +} + +function testMultiMetadataProviderExternalAndContentProperty(callback) { + var model = new MultiMetadataProvider( + // Mocking FileSystemMetadataProvider. + { + get: function(requests) { + assertEquals(0, requests.length); + return Promise.resolve([]); + } + }, + // Mocking ExternalMetadataProvider. + { + get: function(requests) { + assertEquals(2, requests.length); + assertEquals('filesystem://B', requests[0].entry.toURL()); + assertEquals('filesystem://C', requests[1].entry.toURL()); + assertArrayEquals(['imageWidth', 'dirty'], requests[0].names); + assertArrayEquals(['imageWidth', 'dirty'], requests[1].names); + return Promise.resolve([ + {dirty: false, imageWidth: 200}, + {dirty: true, imageWidth: 400} + ]); + } + }, + // Mocking ContentMetadataProvider. + { + get: function(requests) { + assertEquals(1, requests.length); + assertTrue(requests[0].entry.toURL() in this.results_); + return Promise.resolve([ + this.results_[requests[0].entry.toURL()] + ]); + }, + results_: { + 'filesystem://A': {imageWidth: 100}, + 'filesystem://C': {imageWidth: 300} + } + }, + // Mocking VolumeManagerWrapper. + volumeManager); + reportPromise(model.get([ + new MetadataRequest(entryA, ['imageWidth']), + new MetadataRequest(entryB, ['imageWidth']), + new MetadataRequest(entryC, ['imageWidth']) + ]).then(function(results) { + assertEquals(3, results.length); + assertEquals(100, results[0].imageWidth); + assertEquals(200, results[1].imageWidth); + assertEquals(300, results[2].imageWidth); + }), callback); +}
diff --git a/ui/file_manager/file_manager/foreground/js/metadata/new_metadata_provider.js b/ui/file_manager/file_manager/foreground/js/metadata/new_metadata_provider.js index fc088271..282bbbf 100644 --- a/ui/file_manager/file_manager/foreground/js/metadata/new_metadata_provider.js +++ b/ui/file_manager/file_manager/foreground/js/metadata/new_metadata_provider.js
@@ -4,18 +4,11 @@ /** * TODO(hirono): Remove 'New' from the name after removing old MetadataProvider. - * @param {!MetadataProviderCache} cache * @param {!Array<string>} validPropertyNames * @constructor * @struct */ -function NewMetadataProvider(cache, validPropertyNames) { - /** - * @private {!MetadataProviderCache} - * @const - */ - this.cache_ = cache; - +function NewMetadataProvider(validPropertyNames) { /** * Set of valid property names. Key is the name of property and value is * always true. @@ -26,14 +19,15 @@ for (var i = 0; i < validPropertyNames.length; i++) { this.validPropertyNames_[validPropertyNames[i]] = true; } - - /** - * @private {!Array<!MetadataProviderCallbackRequest<T>>} - * @const - */ - this.callbackRequests_ = []; } +NewMetadataProvider.prototype.checkPropertyNames = function(names) { + // Check if the property name is correct or not. + for (var i = 0; i < names.length; i++) { + assert(this.validPropertyNames_[names[i]]); + } +}; + /** * Obtains the metadata for the request. * @param {!Array<!MetadataRequest>} requests @@ -41,162 +35,5 @@ * should not return rejected promise. Instead it should return undefined * property for property error, and should return empty MetadataItem for * entry error. - * @protected */ -NewMetadataProvider.prototype.getImpl; - -/** - * Obtains metadata for entries. - * @param {!Array<!Entry>} entries Entries. - * @param {!Array<string>} names Metadata property names to be obtained. - * @return {!Promise<!Array<!MetadataItem>>} - */ -NewMetadataProvider.prototype.get = function(entries, names) { - // Check if the property name is correct or not. - for (var i = 0; i < names.length; i++) { - assert(this.validPropertyNames_[names[i]]); - } - - // Check if the results are cached or not. - if (this.cache_.hasFreshCache(entries, names)) - return Promise.resolve(this.getCache(entries, names)); - - // The LRU cache may be cached out when the callback is completed. - // To hold cached values, create snapshot of the cache for entries. - var requestId = this.cache_.generateRequestId(); - var snapshot = this.cache_.createSnapshot(entries); - var requests = snapshot.createRequests(entries, names); - snapshot.startRequests(requestId, requests); - this.cache_.startRequests(requestId, requests); - - // Register callback. - var promise = new Promise(function(fulfill) { - this.callbackRequests_.push(new MetadataProviderCallbackRequest( - entries, names, snapshot, fulfill)); - }.bind(this)); - - // If the requests are not empty, call the requests. - if (requests.length) { - this.getImpl(requests).then(function(list) { - // Obtain requested entries and ensure all the requested properties are - // contained in the result. - var requestedEntries = []; - for (var i = 0; i < requests.length; i++) { - requestedEntries.push(requests[i].entry); - for (var j = 0; j < requests[i].names.length; j++) { - var name = requests[i].names[j]; - if (!(name in list[i])) - list[i][name] = undefined; - } - } - - // Store cache. - this.cache_.storeProperties(requestId, requestedEntries, list); - - // Invoke callbacks. - var i = 0; - while (i < this.callbackRequests_.length) { - if (this.callbackRequests_[i].storeProperties( - requestId, requestedEntries, list)) { - // Callback was called. - this.callbackRequests_.splice(i, 1); - } else { - i++; - } - } - }.bind(this)); - } - - return promise; -}; - -/** - * Obtains metadata cache for entries. - * @param {!Array<!Entry>} entries Entries. - * @param {!Array<string>} names Metadata property names to be obtained. - * @return {!Array<!MetadataItem>} - */ -NewMetadataProvider.prototype.getCache = function(entries, names) { - // Check if the property name is correct or not. - for (var i = 0; i < names.length; i++) { - assert(this.validPropertyNames_[names[i]]); - } - return this.cache_.get(entries, names); -}; - -/** - * @param {!Array<!Entry>} entries - * @param {!Array<string>} names - * @param {!MetadataCacheSet} cache - * @param {function(!MetadataItem):undefined} fulfill - * @constructor - * @struct - */ -function MetadataProviderCallbackRequest(entries, names, cache, fulfill) { - /** - * @private {!Array<!Entry>} - * @const - */ - this.entries_ = entries; - - /** - * @private {!Array<string>} - * @const - */ - this.names_ = names; - - /** - * @private {!MetadataCacheSet} - * @const - */ - this.cache_ = cache; - - /** - * @private {function(!MetadataItem):undefined} - * @const - */ - this.fulfill_ = fulfill; -} - -/** - * Stores properties to snapshot cache of the callback request. - * If all the requested property are served, it invokes the callback. - * @param {number} requestId - * @param {!Array<!Entry>} entries - * @param {!Array<!MetadataItem>} objects - * @return {boolean} Whether the callback is invoked or not. - */ -MetadataProviderCallbackRequest.prototype.storeProperties = function( - requestId, entries, objects) { - this.cache_.storeProperties(requestId, entries, objects); - if (this.cache_.hasFreshCache(this.entries_, this.names_)) { - this.fulfill_(this.cache_.get(this.entries_, this.names_)); - return true; - } - return false; -}; - -/** - * Helper wrapper for LRUCache. - * @constructor - * @extends {MetadataCacheSet} - * @struct - */ -function MetadataProviderCache() { - MetadataCacheSet.call(this, new MetadataCacheSetStorageForObject({})); - - /** - * @private {number} - */ - this.requestIdCounter_ = 0; -} - -MetadataProviderCache.prototype.__proto__ = MetadataCacheSet.prototype; - -/** - * Generates a unique request ID every time when it is called. - * @return {number} - */ -MetadataProviderCache.prototype.generateRequestId = function() { - return this.requestIdCounter_++; -}; +NewMetadataProvider.prototype.get;
diff --git a/ui/file_manager/file_manager/foreground/js/metadata/new_metadata_provider_unittest.js b/ui/file_manager/file_manager/foreground/js/metadata/new_metadata_provider_unittest.js deleted file mode 100644 index 54cda9f8..0000000 --- a/ui/file_manager/file_manager/foreground/js/metadata/new_metadata_provider_unittest.js +++ /dev/null
@@ -1,180 +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. - -function TestMetadataProvider(cache) { - NewMetadataProvider.call(this, cache, ['property', 'propertyA', 'propertyB']); - this.requestCount = 0; -} - -TestMetadataProvider.prototype.__proto__ = NewMetadataProvider.prototype; - -TestMetadataProvider.prototype.getImpl = function(requests) { - this.requestCount++; - return Promise.resolve(requests.map(function(request) { - var entry = request.entry; - var names = request.names; - var result = {}; - for (var i = 0; i < names.length; i++) { - result[names[i]] = entry.toURL() + ':' + names[i]; - } - return result; - })); -}; - -function TestEmptyMetadataProvider(cache) { - NewMetadataProvider.call(this, cache, ['property']); -} - -TestEmptyMetadataProvider.prototype.__proto__ = NewMetadataProvider.prototype; - -TestEmptyMetadataProvider.prototype.getImpl = function(requests) { - return Promise.resolve(requests.map(function() { - return {}; - })); -}; - -function ManualTestMetadataProvider(cache) { - NewMetadataProvider.call( - this, cache, ['propertyA', 'propertyB', 'propertyC']); - this.callback = []; -} - -ManualTestMetadataProvider.prototype.__proto__ = NewMetadataProvider.prototype; - -ManualTestMetadataProvider.prototype.getImpl = function(requests) { - return new Promise(function(fulfill) { - this.callback.push(fulfill); - }.bind(this)); -}; - -var entryA = { - toURL: function() { return "filesystem://A"; } -}; - -var entryB = { - toURL: function() { return "filesystem://B"; } -}; - -function testNewMetadataProviderBasic(callback) { - var cache = new MetadataProviderCache(); - var provider = new TestMetadataProvider(cache); - reportPromise(provider.get([entryA, entryB], ['property']).then( - function(results) { - assertEquals(1, provider.requestCount); - assertEquals('filesystem://A:property', results[0].property); - assertEquals('filesystem://B:property', results[1].property); - }), callback); -} - -function testNewMetadataProviderRequestForCachedProperty(callback) { - var cache = new MetadataProviderCache(); - var provider = new TestMetadataProvider(cache); - reportPromise(provider.get([entryA, entryB], ['property']).then( - function() { - // All the result should be cached here. - return provider.get([entryA, entryB], ['property']); - }).then(function(results) { - assertEquals(1, provider.requestCount); - assertEquals('filesystem://A:property', results[0].property); - assertEquals('filesystem://B:property', results[1].property); - }), callback); -} - -function testNewMetadataProviderRequestForCachedAndNonCachedProperty(callback) { - var cache = new MetadataProviderCache(); - var provider = new TestMetadataProvider(cache); - reportPromise(provider.get([entryA, entryB], ['propertyA']).then( - function() { - assertEquals(1, provider.requestCount); - // propertyB has not been cached here. - return provider.get([entryA, entryB], ['propertyA', 'propertyB']); - }).then(function(results) { - assertEquals(2, provider.requestCount); - assertEquals('filesystem://A:propertyA', results[0].propertyA); - assertEquals('filesystem://A:propertyB', results[0].propertyB); - assertEquals('filesystem://B:propertyA', results[1].propertyA); - assertEquals('filesystem://B:propertyB', results[1].propertyB); - }), callback); -} - -function testNewMetadataProviderRequestForCachedAndNonCachedEntry(callback) { - var cache = new MetadataProviderCache(); - var provider = new TestMetadataProvider(cache); - reportPromise(provider.get([entryA], ['property']).then( - function() { - assertEquals(1, provider.requestCount); - // entryB has not been cached here. - return provider.get([entryA, entryB], ['property']); - }).then(function(results) { - assertEquals(2, provider.requestCount); - assertEquals('filesystem://A:property', results[0].property); - assertEquals('filesystem://B:property', results[1].property); - }), callback); -} - -function testNewMetadataProviderRequestBeforeCompletingPreviousRequest( - callback) { - var cache = new MetadataProviderCache(); - var provider = new TestMetadataProvider(cache); - provider.get([entryA], ['property']); - assertEquals(1, provider.requestCount); - // The result of first call has not been fetched yet. - reportPromise(provider.get([entryA], ['property']).then( - function(results) { - assertEquals(1, provider.requestCount); - assertEquals('filesystem://A:property', results[0].property); - }), callback); -} - -function testNewMetadataProviderNotUpdateCachedResultAfterRequest( - callback) { - var cache = new MetadataProviderCache(); - var provider = new ManualTestMetadataProvider(cache); - var promise = provider.get([entryA], ['propertyA']); - provider.callback[0]([{propertyA: 'valueA1'}]); - reportPromise(promise.then(function() { - // 'propertyA' is cached here. - var promise1 = provider.get([entryA], ['propertyA', 'propertyB']); - var promise2 = provider.get([entryA], ['propertyC']); - // Returns propertyC. - provider.callback[2]([{propertyA: 'valueA2', propertyC: 'valueC'}]); - provider.callback[1]([{propertyB: 'valueB'}]); - return Promise.all([promise1, promise2]); - }).then(function(results) { - // The result should be cached value at the time when get was called. - assertEquals('valueA1', results[0][0].propertyA); - assertEquals('valueB', results[0][0].propertyB); - assertEquals('valueC', results[1][0].propertyC); - }), callback); -} - -function testNewMetadataProviderGetCache(callback) { - var cache = new MetadataProviderCache(); - var provider = new TestMetadataProvider(cache); - var promise = provider.get([entryA], ['property']); - var cache = provider.getCache([entryA], ['property']); - assertEquals(null, cache[0].property); - reportPromise(promise.then(function() { - var cache = provider.getCache([entryA], ['property']); - assertEquals(1, provider.requestCount); - assertEquals('filesystem://A:property', cache[0].property); - }), callback); -} - -function testNewMetadataProviderUnknownProperty() { - var cache = new MetadataProviderCache(); - var provider = new TestMetadataProvider(cache); - assertThrows(function() { - provider.get([entryA], ['unknown']); - }); -} - -function testNewMetadataProviderEmptyResult(callback) { - var cache = new MetadataProviderCache(); - var provider = new TestEmptyMetadataProvider(cache); - // getImpl returns empty result. - reportPromise(provider.get([entryA], ['property']).then(function(results) { - assertEquals(undefined, results[0].property); - }), callback); -}
diff --git a/ui/file_manager/file_manager/foreground/js/metadata/thumbnail_model.js b/ui/file_manager/file_manager/foreground/js/metadata/thumbnail_model.js index 16f4a5f..e5b690e 100644 --- a/ui/file_manager/file_manager/foreground/js/metadata/thumbnail_model.js +++ b/ui/file_manager/file_manager/foreground/js/metadata/thumbnail_model.js
@@ -3,16 +3,16 @@ // found in the LICENSE file. /** - * @param {!FileSystemMetadata} fileSystemMetadata + * @param {!MetadataModel} metadataModel * @struct * @constructor */ -function ThumbnailModel(fileSystemMetadata) { +function ThumbnailModel(metadataModel) { /** - * @private {!FileSystemMetadata} + * @private {!MetadataModel} * @const */ - this.fileSystemMetadata_ = fileSystemMetadata; + this.metadataModel_ = metadataModel; } /** @@ -21,7 +21,7 @@ */ ThumbnailModel.prototype.get = function(entries) { var results = {}; - return this.fileSystemMetadata_.get( + return this.metadataModel_.get( entries, [ 'modificationTime', @@ -53,7 +53,7 @@ contentRequestEntries.push(entries[i]); } if (contentRequestEntries.length) { - return this.fileSystemMetadata_.get( + return this.metadataModel_.get( contentRequestEntries, [ 'contentThumbnailUrl',
diff --git a/ui/file_manager/file_manager/foreground/js/metadata_update_controller.js b/ui/file_manager/file_manager/foreground/js/metadata_update_controller.js index 67a32e2f..08b3465 100644 --- a/ui/file_manager/file_manager/foreground/js/metadata_update_controller.js +++ b/ui/file_manager/file_manager/foreground/js/metadata_update_controller.js
@@ -6,15 +6,13 @@ * Controller for list contents update. * @param {!ListContainer} listContainer * @param {!DirectoryModel} directoryModel - * @param {!MetadataProviderCache} metadataProviderCache - * @param {!FileSystemMetadata} fileSystemMetadata + * @param {!MetadataModel} metadataModel * @constructor * @struct */ function MetadataUpdateController(listContainer, directoryModel, - metadataProviderCache, - fileSystemMetadata) { + metadataModel) { /** * @private {!DirectoryModel} * @const @@ -22,10 +20,10 @@ this.directoryModel_ = directoryModel; /** - * @private {!FileSystemMetadata} + * @private {!MetadataModel} * @const */ - this.fileSystemMetadata_ = fileSystemMetadata; + this.metadataModel_ = metadataModel; /** * @private {!ListContainer} @@ -36,7 +34,7 @@ chrome.fileManagerPrivate.onPreferencesChanged.addListener( this.onPreferencesChanged_.bind(this)); this.onPreferencesChanged_(); - metadataProviderCache.addEventListener( + metadataModel.addEventListener( 'update', this.onCachedMetadataUpdate_.bind(this)); // Update metadata to change 'Today' and 'Yesterday' dates. @@ -70,11 +68,11 @@ // changed. var isFakeEntry = util.isFakeEntry(directoryEntry); var changedEntries = (isFakeEntry ? [] : [directoryEntry]).concat(entries); - this.fileSystemMetadata_.notifyEntriesChanged(changedEntries); + this.metadataModel_.notifyEntriesChanged(changedEntries); // We don't pass callback here. When new metadata arrives, we have an // observer registered to update the UI. - this.fileSystemMetadata_.get( + this.metadataModel_.get( changedEntries, this.directoryModel_.getPrefetchPropertyNames()); }; @@ -97,7 +95,7 @@ MetadataUpdateController.prototype.dailyUpdateModificationTime_ = function() { var entries = /** @type {!Array<!Entry>} */( this.directoryModel_.getFileList().slice()); - this.fileSystemMetadata_.get(entries, ['modificationTime']).then(function() { + this.metadataModel_.get(entries, ['modificationTime']).then(function() { this.listContainer_.currentView.updateListItemsMetadata( 'filesystem', entries); }.bind(this));
diff --git a/ui/file_manager/file_manager/foreground/js/task_controller.js b/ui/file_manager/file_manager/foreground/js/task_controller.js index 90da38012..4cb37d1 100644 --- a/ui/file_manager/file_manager/foreground/js/task_controller.js +++ b/ui/file_manager/file_manager/foreground/js/task_controller.js
@@ -5,7 +5,7 @@ /** * @param {DialogType} dialogType * @param {!FileManagerUI} ui - * @param {!FileSystemMetadata} fileSystemMetadata + * @param {!MetadataModel} metadataModel * @param {!FileSelectionHandler} selectionHandler * @param {!MetadataUpdateController} metadataUpdateController * @param {function():!FileTasks} createTask @@ -13,7 +13,7 @@ * @struct */ function TaskController( - dialogType, ui, fileSystemMetadata, selectionHandler, + dialogType, ui, metadataModel, selectionHandler, metadataUpdateController, createTask) { /** * @type {DialogType} @@ -30,11 +30,11 @@ this.ui_ = ui; /** - * @type {!FileSystemMetadata} + * @type {!MetadataModel} * @const * @private */ - this.fileSystemMetadata_ = fileSystemMetadata; + this.metadataModel_ = metadataModel; /** * @type {!FileSelectionHandler} @@ -263,7 +263,7 @@ * @private */ TaskController.prototype.getMimeType_ = function(entry) { - return this.fileSystemMetadata_.get([entry], ['contentMimeType']).then( + return this.metadataModel_.get([entry], ['contentMimeType']).then( function(properties) { if (properties[0].contentMimeType) return properties[0].contentMimeType; @@ -367,7 +367,7 @@ */ TaskController.prototype.doEntryAction = function(entry) { if (this.dialogType_ == DialogType.FULL_PAGE) { - this.fileSystemMetadata_.get([entry], ['contentMimeType']).then( + this.metadataModel_.get([entry], ['contentMimeType']).then( function(props) { var tasks = this.createTask_(); tasks.init([entry], [props[0].contentMimeType || '']);
diff --git a/ui/file_manager/file_manager/foreground/js/task_controller_unittest.js b/ui/file_manager/file_manager/foreground/js/task_controller_unittest.js index 15f3325..62e66f7 100644 --- a/ui/file_manager/file_manager/foreground/js/task_controller_unittest.js +++ b/ui/file_manager/file_manager/foreground/js/task_controller_unittest.js
@@ -6,11 +6,11 @@ recordEnum: function() {} }; -function MockFileSystemMetadata(properties) { +function MockMetadataModel(properties) { this.properties_ = properties; } -MockFileSystemMetadata.prototype.get = function() { +MockMetadataModel.prototype.get = function() { return Promise.resolve([this.properties_]); }; @@ -48,7 +48,7 @@ defaultActionMenuItem: document.createElement('div') } }, - new MockFileSystemMetadata({}), + new MockMetadataModel({}), new cr.EventTarget(), null, function() { @@ -61,7 +61,7 @@ isOnDrive: function() { return true; }, - getFileSystemMetadata: function() {} + getMetadataModel: function() {} }); }); @@ -98,7 +98,7 @@ } } }, - new MockFileSystemMetadata({contentMimeType: 'application/rtf'}), + new MockMetadataModel({contentMimeType: 'application/rtf'}), new cr.EventTarget(), null, null); @@ -141,7 +141,7 @@ } } }, - new MockFileSystemMetadata({}), + new MockMetadataModel({}), new cr.EventTarget(), null, null); @@ -171,7 +171,7 @@ defaultActionMenuItem: document.createElement('div') } }, - new MockFileSystemMetadata({contentMimeType: 'image/png'}), + new MockMetadataModel({contentMimeType: 'image/png'}), new cr.EventTarget(), null, null);
diff --git a/ui/file_manager/file_manager/foreground/js/ui/directory_tree.js b/ui/file_manager/file_manager/foreground/js/ui/directory_tree.js index d254c49..8e6e1dea 100644 --- a/ui/file_manager/file_manager/foreground/js/ui/directory_tree.js +++ b/ui/file_manager/file_manager/foreground/js/ui/directory_tree.js
@@ -396,8 +396,8 @@ */ SubDirectoryItem.prototype.updateSharedStatusIcon = function() { var icon = this.querySelector('.icon'); - this.parentTree_.fileSystemMetadata.notifyEntriesChanged([this.dirEntry_]); - this.parentTree_.fileSystemMetadata.get([this.dirEntry_], ['shared']).then( + this.parentTree_.metadataModel.notifyEntriesChanged([this.dirEntry_]); + this.parentTree_.metadataModel.get([this.dirEntry_], ['shared']).then( function(metadata) { icon.classList.toggle('shared', metadata[0] && metadata[0].shared); }); @@ -792,15 +792,14 @@ * @param {HTMLElement} el Element to be DirectoryTree. * @param {!DirectoryModel} directoryModel Current DirectoryModel. * @param {!VolumeManagerWrapper} volumeManager VolumeManager of the system. - * @param {!FileSystemMetadata} fileSystemMetadata Shared MetadataCache - * instance. + * @param {!MetadataModel} metadataModel Shared MetadataModel instance. * @param {boolean} fakeEntriesVisible True if it should show the fakeEntries. */ DirectoryTree.decorate = function( - el, directoryModel, volumeManager, fileSystemMetadata, fakeEntriesVisible) { + el, directoryModel, volumeManager, metadataModel, fakeEntriesVisible) { el.__proto__ = DirectoryTree.prototype; /** @type {DirectoryTree} */ (el).decorateDirectoryTree( - directoryModel, volumeManager, fileSystemMetadata, fakeEntriesVisible); + directoryModel, volumeManager, metadataModel, fakeEntriesVisible); }; DirectoryTree.prototype = { @@ -839,11 +838,11 @@ }, /** - * The reference to shared FileSystemMetadata instance. - * @type {!FileSystemMetadata} + * The reference to shared MetadataModel instance. + * @type {!MetadataModel} */ - get fileSystemMetadata() { - return this.fileSystemMetadata_; + get metadataModel() { + return this.metadataModel_; }, set dataModel(dataModel) { @@ -959,18 +958,17 @@ * Decorates an element. * @param {!DirectoryModel} directoryModel Current DirectoryModel. * @param {!VolumeManagerWrapper} volumeManager VolumeManager of the system. - * @param {!FileSystemMetadata} fileSystemMetadata Shared MetadataCache - * instance. + * @param {!MetadataModel} metadataModel Shared MetadataModel instance. * @param {boolean} fakeEntriesVisible True if it should show the fakeEntries. */ DirectoryTree.prototype.decorateDirectoryTree = function( - directoryModel, volumeManager, fileSystemMetadata, fakeEntriesVisible) { + directoryModel, volumeManager, metadataModel, fakeEntriesVisible) { cr.ui.Tree.prototype.decorate.call(this); this.sequence_ = 0; this.directoryModel_ = directoryModel; this.volumeManager_ = volumeManager; - this.fileSystemMetadata_ = fileSystemMetadata; + this.metadataModel_ = metadataModel; this.models_ = []; this.fileFilter_ = this.directoryModel_.getFileFilter();
diff --git a/ui/file_manager/file_manager/foreground/js/ui/file_grid.js b/ui/file_manager/file_manager/foreground/js/ui/file_grid.js index db001f07..728dc30 100644 --- a/ui/file_manager/file_manager/foreground/js/ui/file_grid.js +++ b/ui/file_manager/file_manager/foreground/js/ui/file_grid.js
@@ -22,15 +22,15 @@ /** * Decorates an HTML element to be a FileGrid. * @param {!Element} self The grid to decorate. - * @param {!FileSystemMetadata} fileSystemMetadata File system metadata. + * @param {!MetadataModel} metadataModel File system metadata. * @param {VolumeManagerWrapper} volumeManager Volume manager instance. * @param {!importer.HistoryLoader} historyLoader */ FileGrid.decorate = function( - self, fileSystemMetadata, volumeManager, historyLoader) { + self, metadataModel, volumeManager, historyLoader) { cr.ui.Grid.decorate(self); self.__proto__ = FileGrid.prototype; - self.fileSystemMetadata_ = fileSystemMetadata; + self.metadataModel_ = metadataModel; self.volumeManager_ = volumeManager; self.historyLoader_ = historyLoader; @@ -138,7 +138,7 @@ FileGrid.decorateThumbnailBox_(assertInstanceof(box, HTMLDivElement), entry, - this.fileSystemMetadata_, + this.metadataModel_, this.volumeManager_, this.historyLoader_, this.listThumbnailLoader_); @@ -168,7 +168,7 @@ * Decorates thumbnail. * @param {cr.ui.ListItem} li List item. * @param {!Entry} entry Entry to render a thumbnail for. - * @param {!FileSystemMetadata} fileSystemMetadata To retrieve metadata. + * @param {!MetadataModel} metadataModel To retrieve metadata. * @param {VolumeManagerWrapper} volumeManager Volume manager instance. * @param {!importer.HistoryLoader} historyLoader * @private @@ -176,13 +176,13 @@ FileGrid.decorateThumbnail_ = function( li, entry, - fileSystemMetadata, + metadataModel, volumeManager, historyLoader, listThumbnailLoader) { li.className = 'thumbnail-item'; if (entry) - filelist.decorateListItem(li, entry, fileSystemMetadata); + filelist.decorateListItem(li, entry, metadataModel); var frame = li.ownerDocument.createElement('div'); frame.className = 'thumbnail-frame'; @@ -193,7 +193,7 @@ FileGrid.decorateThumbnailBox_( assertInstanceof(box, HTMLDivElement), entry, - fileSystemMetadata, + metadataModel, volumeManager, historyLoader, listThumbnailLoader); @@ -219,7 +219,7 @@ * * @param {!HTMLDivElement} box Box to decorate. * @param {Entry} entry Entry which thumbnail is generating for. - * @param {!FileSystemMetadata} fileSystemMetadata To retrieve metadata. + * @param {!MetadataModel} metadataModel To retrieve metadata. * @param {VolumeManagerWrapper} volumeManager Volume manager instance. * @param {!importer.HistoryLoader} historyLoader * @param {function(HTMLImageElement)=} opt_imageLoadCallback Callback called @@ -227,7 +227,7 @@ * @private */ FileGrid.decorateThumbnailBox_ = function( - box, entry, fileSystemMetadata, volumeManager, historyLoader, + box, entry, metadataModel, volumeManager, historyLoader, listThumbnailLoader, opt_imageLoadCallback) { box.className = 'img-container'; @@ -242,7 +242,7 @@ if (entry.isDirectory) { box.setAttribute('generic-thumbnail', 'folder'); - var shared = !!fileSystemMetadata.getCache([entry], ['shared'])[0].shared; + var shared = !!metadataModel.getCache([entry], ['shared'])[0].shared; box.classList.toggle('shared', shared); if (opt_imageLoadCallback) @@ -279,7 +279,7 @@ thumbnail.style.backgroundImage = 'url(' + dataUrl + ')'; thumbnail.addEventListener('webkitAnimationEnd', function() { // Remove animation css once animation is completed in order not to animate - // agein when an item is attached to the dom again. + // again when an item is attached to the dom again. thumbnail.classList.remove('animate'); for (var i = 0; i < oldThumbnails.length; i++) { @@ -366,7 +366,7 @@ FileGrid.decorateThumbnail_( li, entry, - grid.fileSystemMetadata_, + grid.metadataModel_, grid.volumeManager_, grid.historyLoader_, grid.listThumbnailLoader_);
diff --git a/ui/file_manager/file_manager/foreground/js/ui/file_table.js b/ui/file_manager/file_manager/foreground/js/ui/file_table.js index 7d62b53..860da24e 100644 --- a/ui/file_manager/file_manager/foreground/js/ui/file_table.js +++ b/ui/file_manager/file_manager/foreground/js/ui/file_table.js
@@ -224,7 +224,7 @@ /** * Decorates the element. * @param {!Element} self Table to decorate. - * @param {!FileSystemMetadata} fileSystemMetadata To retrieve + * @param {!MetadataModel} metadataModel To retrieve * metadata. * @param {VolumeManagerWrapper} volumeManager To retrieve volume info. * @param {!importer.HistoryLoader} historyLoader @@ -232,11 +232,11 @@ * False if a file open/save dialog. */ FileTable.decorate = function( - self, fileSystemMetadata, volumeManager, historyLoader, fullPage) { + self, metadataModel, volumeManager, historyLoader, fullPage) { cr.ui.Table.decorate(self); FileTableList.decorate(self.list); self.__proto__ = FileTable.prototype; - self.fileSystemMetadata_ = fileSystemMetadata; + self.metadataModel_ = metadataModel; self.volumeManager_ = volumeManager; self.historyLoader_ = historyLoader; @@ -394,7 +394,8 @@ var box = listItem.querySelector('.detail-thumbnail'); if (box) { this.setThumbnailImage_( - assertInstanceof(box, HTMLDivElement), event.dataUrl); + assertInstanceof(box, HTMLDivElement), event.dataUrl, + true /* with animation */); } } }; @@ -494,9 +495,12 @@ return true; // Check if the point is on the column contents or not. - var item = this.list.getListItemByIndex(itemIndex); switch (this.columnModel.columns_[hitColumn.index].id) { case 'name': + var item = this.list.getListItemByIndex(itemIndex); + if (!item) + return false; + var spanElement = item.querySelector('.filename-label span'); var spanRect = spanElement.getBoundingClientRect(); // The this.list.cachedBounds_ object is set by @@ -564,7 +568,7 @@ * @private */ FileTable.prototype.updateSize_ = function(div, entry) { - var metadata = this.fileSystemMetadata_.getCache( + var metadata = this.metadataModel_.getCache( [entry], ['size', 'hosted'])[0]; var size = metadata.size; if (size === null || size === undefined) { @@ -694,7 +698,7 @@ * @private */ FileTable.prototype.updateDate_ = function(div, entry) { - var modTime = this.fileSystemMetadata_.getCache( + var modTime = this.metadataModel_.getCache( [entry], ['modificationTime'])[0].modificationTime; if (!modTime) { @@ -776,7 +780,7 @@ forEachCell('.table-row-cell > .date', function(item, entry, listItem) { filelist.updateListItemExternalProps( listItem, - this.fileSystemMetadata_.getCache( + this.metadataModel_.getCache( [entry], ['availableOffline', 'customIconUrl', 'shared'])[0]); }); } else if (type === 'import-history') { @@ -795,7 +799,7 @@ */ FileTable.prototype.renderTableRow_ = function(baseRenderFunction, entry) { var item = baseRenderFunction(entry, this); - filelist.decorateListItem(item, entry, this.fileSystemMetadata_); + filelist.decorateListItem(item, entry, this.metadataModel_); return item; }; @@ -814,7 +818,8 @@ if (this.listThumbnailLoader_ && this.listThumbnailLoader_.getThumbnailFromCache(entry)) { this.setThumbnailImage_( - box, this.listThumbnailLoader_.getThumbnailFromCache(entry).dataUrl); + box, this.listThumbnailLoader_.getThumbnailFromCache(entry).dataUrl, + false /* without animation */); } return box; @@ -824,12 +829,31 @@ * Sets thumbnail image to the box. * @param {!HTMLDivElement} box Detail thumbnail div element. * @param {string} dataUrl Data url of thumbnail. + * @param {boolean} shouldAnimate Whether the thumbnail is shown with animation + * or not. * @private */ -FileTable.prototype.setThumbnailImage_ = function(box, dataUrl) { - // TODO(yawano): Add transition animation for thumbnail update. - box.style.backgroundImage = 'url(' + dataUrl + ')'; - box.classList.add('loaded'); +FileTable.prototype.setThumbnailImage_ = function(box, dataUrl, shouldAnimate) { + var oldThumbnails = box.querySelectorAll('.thumbnail'); + + var thumbnail = box.ownerDocument.createElement('div'); + thumbnail.classList.add('thumbnail'); + thumbnail.style.backgroundImage = 'url(' + dataUrl + ')'; + thumbnail.addEventListener('webkitAnimationEnd', function() { + // Remove animation css once animation is completed in order not to animate + // again when an item is attached to the dom again. + thumbnail.classList.remove('animate'); + + for (var i = 0; i < oldThumbnails.length; i++) { + if (box.contains(oldThumbnails[i])) + box.removeChild(oldThumbnails[i]); + } + }); + + if (shouldAnimate) + thumbnail.classList.add('animate'); + + box.appendChild(thumbnail); }; /** @@ -866,15 +890,15 @@ * Common item decoration for table's and grid's items. * @param {cr.ui.ListItem} li List item. * @param {Entry} entry The entry. - * @param {!FileSystemMetadata} fileSystemMetadata Cache to + * @param {!MetadataModel} metadataModel Cache to * retrieve metadada. */ -filelist.decorateListItem = function(li, entry, fileSystemMetadata) { +filelist.decorateListItem = function(li, entry, metadataModel) { li.classList.add(entry.isDirectory ? 'directory' : 'file'); // The metadata may not yet be ready. In that case, the list item will be // updated when the metadata is ready via updateListItemsMetadata. For files // not on an external backend, externalProps is not available. - var externalProps = fileSystemMetadata.getCache( + var externalProps = metadataModel.getCache( [entry], ['hosted', 'availableOffline', 'customIconUrl', 'shared'])[0]; filelist.updateListItemExternalProps(li, externalProps);
diff --git a/ui/file_manager/file_manager/main.html b/ui/file_manager/file_manager/main.html index 5600fccc92..f3572ef 100644 --- a/ui/file_manager/file_manager/main.html +++ b/ui/file_manager/file_manager/main.html
@@ -131,11 +131,12 @@ <script src="foreground/js/launch_param.js"></script> <script src="foreground/js/metadata/content_metadata_provider.js"></script> <script src="foreground/js/metadata/external_metadata_provider.js"></script> - <script src="foreground/js/metadata/file_system_metadata.js"></script> <script src="foreground/js/metadata/file_system_metadata_provider.js"></script> <script src="foreground/js/metadata/metadata_cache.js"></script> <script src="foreground/js/metadata/metadata_cache_item.js"></script> <script src="foreground/js/metadata/metadata_item.js"></script> + <script src="foreground/js/metadata/metadata_model.js"></script> + <script src="foreground/js/metadata/multi_metadata_provider.js"></script> <script src="foreground/js/metadata_update_controller.js"></script> <script src="foreground/js/naming_controller.js"></script> <script src="foreground/js/navigation_list_model.js"></script>
diff --git a/ui/file_manager/gallery/gallery.html b/ui/file_manager/gallery/gallery.html index 00f049b..b012927 100644 --- a/ui/file_manager/gallery/gallery.html +++ b/ui/file_manager/gallery/gallery.html
@@ -54,14 +54,15 @@ <script src="../file_manager/common/js/volume_manager_common.js"></script> <script src="../file_manager/foreground/js/metadata/content_metadata_provider.js"></script> + <script src="../file_manager/foreground/js/metadata/exif_constants.js"></script> <script src="../file_manager/foreground/js/metadata/external_metadata_provider.js"></script> - <script src="../file_manager/foreground/js/metadata/file_system_metadata.js"></script> <script src="../file_manager/foreground/js/metadata/file_system_metadata_provider.js"></script> <script src="../file_manager/foreground/js/metadata/metadata_cache.js"></script> <script src="../file_manager/foreground/js/metadata/metadata_cache_item.js"></script> <script src="../file_manager/foreground/js/metadata/metadata_item.js"></script> + <script src="../file_manager/foreground/js/metadata/metadata_model.js"></script> + <script src="../file_manager/foreground/js/metadata/multi_metadata_provider.js"></script> <script src="../file_manager/foreground/js/metadata/thumbnail_model.js"></script> - <script src="../file_manager/foreground/js/metadata/exif_constants.js"></script> <script src="../file_manager/foreground/js/mouse_inactivity_watcher.js"></script> <script src="../file_manager/foreground/js/share_client.js"></script> <script src="../file_manager/foreground/js/thumbnail_loader.js"></script>
diff --git a/ui/file_manager/gallery/js/compiled_resources.gyp b/ui/file_manager/gallery/js/compiled_resources.gyp index ad5166f4..f4a7be9 100644 --- a/ui/file_manager/gallery/js/compiled_resources.gyp +++ b/ui/file_manager/gallery/js/compiled_resources.gyp
@@ -69,12 +69,13 @@ '../../file_manager/foreground/js/metadata/content_metadata_provider.js', '../../file_manager/foreground/js/metadata/exif_constants.js', '../../file_manager/foreground/js/metadata/external_metadata_provider.js', - '../../file_manager/foreground/js/metadata/file_system_metadata.js', '../../file_manager/foreground/js/metadata/file_system_metadata_provider.js', '../../file_manager/foreground/js/metadata/metadata_cache.js', '../../file_manager/foreground/js/metadata/metadata_cache_item.js', '../../file_manager/foreground/js/metadata/metadata_cache_set.js', '../../file_manager/foreground/js/metadata/metadata_item.js', + '../../file_manager/foreground/js/metadata/metadata_model.js', + '../../file_manager/foreground/js/metadata/multi_metadata_provider.js', '../../file_manager/foreground/js/metadata/new_metadata_provider.js', '../../file_manager/foreground/js/mouse_inactivity_watcher.js', '../../file_manager/foreground/js/share_client.js',
diff --git a/ui/file_manager/gallery/js/gallery.js b/ui/file_manager/gallery/js/gallery.js index a835bfa3..3ed7817 100644 --- a/ui/file_manager/gallery/js/gallery.js +++ b/ui/file_manager/gallery/js/gallery.js
@@ -53,11 +53,10 @@ this.metadataCache_ = this.context_.metadataCache; this.volumeManager_ = volumeManager; /** - * @private {!FileSystemMetadata} + * @private {!MetadataModel} * @const */ - this.fileSystemMetadata_ = FileSystemMetadata.create( - new MetadataProviderCache(), volumeManager); + this.metadataModel_ = MetadataModel.create(volumeManager); this.selectedEntry_ = null; this.metadataCacheObserverId_ = null; this.onExternallyUnmountedBound_ = this.onExternallyUnmounted_.bind(this); @@ -65,7 +64,7 @@ this.dataModel_ = new GalleryDataModel( this.context_.metadataCache, - this.fileSystemMetadata_); + this.metadataModel_); var downloadVolumeInfo = this.volumeManager_.getCurrentProfileVolumeInfo( VolumeManagerCommon.VolumeType.DOWNLOADS); downloadVolumeInfo.resolveDisplayRoot().then(function(entry) { @@ -393,7 +392,7 @@ locationInfo, clonedMetadata, self.metadataCache_, - self.fileSystemMetadata_, + self.metadataModel_, /* original */ true)); }); self.dataModel_.push.apply(self.dataModel_, items);
diff --git a/ui/file_manager/gallery/js/gallery_data_model.js b/ui/file_manager/gallery/js/gallery_data_model.js index 5b80f77..f9f3287c 100644 --- a/ui/file_manager/gallery/js/gallery_data_model.js +++ b/ui/file_manager/gallery/js/gallery_data_model.js
@@ -6,12 +6,12 @@ * Data model for gallery. * * @param {!MetadataCache} metadataCache Metadata cache. - * @param {!FileSystemMetadata} fileSystemMetadata + * @param {!MetadataModel} metadataModel * @param {!EntryListWatcher=} opt_watcher Entry list watcher. * @constructor * @extends {cr.ui.ArrayDataModel} */ -function GalleryDataModel(metadataCache, fileSystemMetadata, opt_watcher) { +function GalleryDataModel(metadataCache, metadataModel, opt_watcher) { cr.ui.ArrayDataModel.call(this, []); /** @@ -23,10 +23,10 @@ /** * File system metadata. - * @private {!FileSystemMetadata} + * @private {!MetadataModel} * @const */ - this.fileSystemMetadata_ = fileSystemMetadata; + this.metadataModel_ = metadataModel; /** * Directory where the image is saved if the image is located in a read-only @@ -102,7 +102,7 @@ oldLocationInfo, oldMetadata, this.metadataCache_, - this.fileSystemMetadata_, + this.metadataModel_, item.isOriginal()); // The item must be added behind the existing item so that it does // not change the index of the existing item.
diff --git a/ui/file_manager/gallery/js/gallery_data_model_unittest.js b/ui/file_manager/gallery/js/gallery_data_model_unittest.js index bad20791..f2b7a3ab 100644 --- a/ui/file_manager/gallery/js/gallery_data_model_unittest.js +++ b/ui/file_manager/gallery/js/gallery_data_model_unittest.js
@@ -11,7 +11,7 @@ var metadataCache = new MockMetadataCache(); model = new GalleryDataModel( metadataCache, - /* Mock FileSystemMetadata */{}, + /* Mock MetadataModel */{}, /* Mock EntryListWatcher */{}); fileSystem = new MockFileSystem('volumeId'); item = new Gallery.Item(
diff --git a/ui/file_manager/gallery/js/gallery_item.js b/ui/file_manager/gallery/js/gallery_item.js index 2db056dc..6d87f3e 100644 --- a/ui/file_manager/gallery/js/gallery_item.js +++ b/ui/file_manager/gallery/js/gallery_item.js
@@ -9,13 +9,13 @@ * @param {!EntryLocation} locationInfo Entry location information. * @param {!Object} metadata Metadata for the entry. * @param {!MetadataCache} metadataCache Metadata cache instance. - * @param {!FileSystemMetadata} fileSystemMetadata File system metadata. + * @param {!MetadataModel} metadataModel File system metadata. * @param {boolean} original Whether the entry is original or edited. * @constructor * @struct */ Gallery.Item = function( - entry, locationInfo, metadata, metadataCache, fileSystemMetadata, + entry, locationInfo, metadata, metadataCache, metadataModel, original) { /** * @type {!FileEntry} @@ -43,11 +43,11 @@ this.metadataCache_ = metadataCache; /** - * @type {!FileSystemMetadata} + * @type {!MetadataModel} * @private * @const */ - this.fileSystemMetadata_ = fileSystemMetadata; + this.metadataModel_ = metadataModel; // TODO(yawano): Change this.contentImage and this.screenImage to private // fields and provide utility methods for them (e.g. revokeFullImageCache). @@ -271,7 +271,7 @@ opt_callback(false); } }.bind(this)); - this.fileSystemMetadata_.notifyEntriesChanged([this.entry_]); + this.metadataModel_.notifyEntriesChanged([this.entry_]); }.bind(this); var onError = function(error) { @@ -282,7 +282,7 @@ }; var doSave = function(newFile, fileEntry) { - var metadataPromise = this.fileSystemMetadata_.get( + var metadataPromise = this.metadataModel_.get( [fileEntry], ['mediaMimeType', 'contentMimeType', 'ifd', 'exifLittleEndian']); metadataPromise.then(function(metadataItems) {
diff --git a/ui/file_manager/gallery/js/gallery_item_unittest.js b/ui/file_manager/gallery/js/gallery_item_unittest.js index 8a7b25df..ce10ef12 100644 --- a/ui/file_manager/gallery/js/gallery_item_unittest.js +++ b/ui/file_manager/gallery/js/gallery_item_unittest.js
@@ -63,7 +63,7 @@ {isReadOnly: false}, {name: 'oldMetadata'}, metadataCache, - // Mock of FileSystemMetadata. + // Mock of MetadataModel. { get: function() { return Promise.resolve([{}]);
diff --git a/ui/file_manager/gallery/js/gallery_scripts.js b/ui/file_manager/gallery/js/gallery_scripts.js index df653f5..c288391 100644 --- a/ui/file_manager/gallery/js/gallery_scripts.js +++ b/ui/file_manager/gallery/js/gallery_scripts.js
@@ -46,14 +46,15 @@ //<include src="../../file_manager/common/js/util.js"> //<include src="../../file_manager/common/js/volume_manager_common.js"> //<include src="../../file_manager/foreground/js/metadata/content_metadata_provider.js"> +//<include src="../../file_manager/foreground/js/metadata/exif_constants.js"> //<include src="../../file_manager/foreground/js/metadata/external_metadata_provider.js"> -//<include src="../../file_manager/foreground/js/metadata/file_system_metadata.js"> //<include src="../../file_manager/foreground/js/metadata/file_system_metadata_provider.js"> //<include src="../../file_manager/foreground/js/metadata/metadata_cache.js"> //<include src="../../file_manager/foreground/js/metadata/metadata_cache_item.js"> //<include src="../../file_manager/foreground/js/metadata/metadata_item.js"> +//<include src="../../file_manager/foreground/js/metadata/metadata_model.js"> +//<include src="../../file_manager/foreground/js/metadata/multi_metadata_provider.js"> //<include src="../../file_manager/foreground/js/metadata/thumbnail_model.js"> -//<include src="../../file_manager/foreground/js/metadata/exif_constants.js"> //<include src="../../file_manager/foreground/js/mouse_inactivity_watcher.js"> //<include src="../../file_manager/foreground/js/share_client.js"> //<include src="../../file_manager/foreground/js/thumbnail_loader.js">
diff --git a/ui/gfx/x/x11_error_tracker.cc b/ui/gfx/x/x11_error_tracker.cc index 110f79c..859e718 100644 --- a/ui/gfx/x/x11_error_tracker.cc +++ b/ui/gfx/x/x11_error_tracker.cc
@@ -2,9 +2,9 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#include "base/logging.h" #include "ui/gfx/x/x11_error_tracker.h" +#include "base/logging.h" #include "ui/gfx/x/x11_types.h" namespace { @@ -16,7 +16,8 @@ g_x11_error_code = error->error_code; return 0; } -} + +} // namespace namespace gfx {
diff --git a/ui/gl/gl_surface.h b/ui/gl/gl_surface.h index a6e6ff1d..b67ca69 100644 --- a/ui/gl/gl_surface.h +++ b/ui/gl/gl_surface.h
@@ -156,6 +156,15 @@ static scoped_refptr<GLSurface> CreateViewGLSurface( gfx::AcceleratedWidget window); +#if defined(USE_OZONE) + // Create a GL surface that renders directly into a window with surfaceless + // semantics - there is no default framebuffer and the primary surface must + // be presented as an overlay. If surfaceless mode is not supported or + // enabled it will return a null pointer. + static scoped_refptr<GLSurface> CreateSurfacelessViewGLSurface( + gfx::AcceleratedWidget window); +#endif // defined(USE_OZONE) + // Create a GL surface used for offscreen rendering. static scoped_refptr<GLSurface> CreateOffscreenGLSurface( const gfx::Size& size);
diff --git a/ui/gl/gl_surface_ozone.cc b/ui/gl/gl_surface_ozone.cc index f79b6d0..47ea8d6 100644 --- a/ui/gl/gl_surface_ozone.cc +++ b/ui/gl/gl_surface_ozone.cc
@@ -4,16 +4,20 @@ #include "ui/gl/gl_surface.h" +#include "base/bind.h" #include "base/logging.h" #include "base/memory/ref_counted.h" #include "ui/gfx/native_widget_types.h" #include "ui/gl/gl_context.h" #include "ui/gl/gl_image.h" +#include "ui/gl/gl_image_linux_dma_buffer.h" #include "ui/gl/gl_implementation.h" #include "ui/gl/gl_surface_egl.h" #include "ui/gl/gl_surface_osmesa.h" #include "ui/gl/gl_surface_stub.h" +#include "ui/gl/scoped_binders.h" #include "ui/gl/scoped_make_current.h" +#include "ui/ozone/public/native_pixmap.h" #include "ui/ozone/public/surface_factory_ozone.h" #include "ui/ozone/public/surface_ozone_egl.h" @@ -157,7 +161,7 @@ return SwapBuffersAsync(callback); } - private: + protected: ~GLSurfaceOzoneSurfaceless() override { Destroy(); // EGL surface must be destroyed before SurfaceOzone } @@ -196,6 +200,157 @@ DISALLOW_COPY_AND_ASSIGN(GLSurfaceOzoneSurfaceless); }; +// This provides surface-like semantics implemented through surfaceless. +// A framebuffer is bound automatically. +class GL_EXPORT GLSurfaceOzoneSurfacelessSurfaceImpl + : public GLSurfaceOzoneSurfaceless { + public: + GLSurfaceOzoneSurfacelessSurfaceImpl( + scoped_ptr<ui::SurfaceOzoneEGL> ozone_surface, + AcceleratedWidget widget) + : GLSurfaceOzoneSurfaceless(ozone_surface.Pass(), widget), + fbo_(0), + current_surface_(0) { + for (auto& texture : textures_) + texture = 0; + } + + unsigned int GetBackingFrameBufferObject() override { return fbo_; } + + bool OnMakeCurrent(GLContext* context) override { + if (!fbo_) { + glGenFramebuffersEXT(1, &fbo_); + if (!fbo_) + return false; + glGenTextures(arraysize(textures_), textures_); + if (!CreatePixmaps()) + return false; + } + BindFramebuffer(); + glBindFramebufferEXT(GL_FRAMEBUFFER, fbo_); + return SurfacelessEGL::OnMakeCurrent(context); + } + + bool Resize(const gfx::Size& size) override { + if (size == GetSize()) + return true; + return GLSurfaceOzoneSurfaceless::Resize(size) && CreatePixmaps(); + } + + bool SupportsPostSubBuffer() override { return false; } + + bool SwapBuffers() override { + if (!images_[current_surface_]->ScheduleOverlayPlane( + widget_, 0, OverlayTransform::OVERLAY_TRANSFORM_NONE, + gfx::Rect(GetSize()), gfx::RectF(1, 1))) + return false; + if (!GLSurfaceOzoneSurfaceless::SwapBuffers()) + return false; + current_surface_ ^= 1; + BindFramebuffer(); + return true; + } + + bool SwapBuffersAsync(const SwapCompletionCallback& callback) override { + if (!images_[current_surface_]->ScheduleOverlayPlane( + widget_, 0, OverlayTransform::OVERLAY_TRANSFORM_NONE, + gfx::Rect(GetSize()), gfx::RectF(1, 1))) + return false; + if (!GLSurfaceOzoneSurfaceless::SwapBuffersAsync(callback)) + return false; + current_surface_ ^= 1; + BindFramebuffer(); + return true; + } + + void Destroy() override { + GLContext* current_context = GLContext::GetCurrent(); + DCHECK(current_context && current_context->IsCurrent(this)); + glBindFramebufferEXT(GL_FRAMEBUFFER, 0); + if (fbo_) { + glDeleteTextures(arraysize(textures_), textures_); + for (auto& texture : textures_) + texture = 0; + glDeleteFramebuffersEXT(1, &fbo_); + fbo_ = 0; + } + for (auto image : images_) { + if (image) + image->Destroy(true); + } + } + + private: + class SurfaceImage : public GLImageLinuxDMABuffer { + public: + SurfaceImage(const gfx::Size& size, unsigned internalformat) + : GLImageLinuxDMABuffer(size, internalformat) {} + + bool Initialize(scoped_refptr<ui::NativePixmap> pixmap, + gfx::GpuMemoryBuffer::Format format) { + base::FileDescriptor handle(pixmap->GetDmaBufFd(), false); + if (!GLImageLinuxDMABuffer::Initialize(handle, format, + pixmap->GetDmaBufPitch())) + return false; + pixmap_ = pixmap; + return true; + } + bool ScheduleOverlayPlane(gfx::AcceleratedWidget widget, + int z_order, + gfx::OverlayTransform transform, + const gfx::Rect& bounds_rect, + const gfx::RectF& crop_rect) override { + return ui::SurfaceFactoryOzone::GetInstance()->ScheduleOverlayPlane( + widget, z_order, transform, pixmap_, bounds_rect, crop_rect); + } + + private: + ~SurfaceImage() override {} + + scoped_refptr<ui::NativePixmap> pixmap_; + }; + + ~GLSurfaceOzoneSurfacelessSurfaceImpl() override { + DCHECK(!fbo_); + for (size_t i = 0; i < arraysize(textures_); i++) + DCHECK(!textures_[i]) << "texture " << i << " not released"; + } + + void BindFramebuffer() { + ScopedFrameBufferBinder fb(fbo_); + glFramebufferTexture2DEXT(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, + GL_TEXTURE_2D, textures_[current_surface_], 0); + } + + bool CreatePixmaps() { + if (!fbo_) + return true; + for (size_t i = 0; i < arraysize(textures_); i++) { + scoped_refptr<ui::NativePixmap> pixmap = + ui::SurfaceFactoryOzone::GetInstance()->CreateNativePixmap( + widget_, GetSize(), ui::SurfaceFactoryOzone::RGBA_8888, + ui::SurfaceFactoryOzone::SCANOUT); + if (!pixmap) + return false; + scoped_refptr<SurfaceImage> image = new SurfaceImage(GetSize(), GL_RGBA); + if (!image->Initialize(pixmap, gfx::GpuMemoryBuffer::Format::BGRA_8888)) + return false; + images_[i] = image; + // Bind image to texture. + ScopedTextureBinder binder(GL_TEXTURE_2D, textures_[i]); + if (!images_[i]->BindTexImage(GL_TEXTURE_2D)) + return false; + } + return true; + } + + GLuint fbo_; + GLuint textures_[2]; + scoped_refptr<GLImage> images_[2]; + int current_surface_; + DISALLOW_COPY_AND_ASSIGN(GLSurfaceOzoneSurfacelessSurfaceImpl); +}; + } // namespace // static @@ -217,6 +372,27 @@ } // static +scoped_refptr<GLSurface> GLSurface::CreateSurfacelessViewGLSurface( + gfx::AcceleratedWidget window) { + if (GetGLImplementation() == kGLImplementationEGLGLES2 && + window != kNullAcceleratedWidget && + GLSurfaceEGL::IsEGLSurfacelessContextSupported() && + ui::SurfaceFactoryOzone::GetInstance()->CanShowPrimaryPlaneAsOverlay()) { + scoped_ptr<ui::SurfaceOzoneEGL> surface_ozone = + ui::SurfaceFactoryOzone::GetInstance() + ->CreateSurfacelessEGLSurfaceForWidget(window); + if (!surface_ozone) + return nullptr; + scoped_refptr<GLSurface> surface; + surface = new GLSurfaceOzoneSurfaceless(surface_ozone.Pass(), window); + if (surface->Initialize()) + return surface; + } + + return nullptr; +} + +// static scoped_refptr<GLSurface> GLSurface::CreateViewGLSurface( gfx::AcceleratedWidget window) { if (GetGLImplementation() == kGLImplementationOSMesaGL) { @@ -236,7 +412,8 @@ ->CreateSurfacelessEGLSurfaceForWidget(window); if (!surface_ozone) return NULL; - surface = new GLSurfaceOzoneSurfaceless(surface_ozone.Pass(), window); + surface = new GLSurfaceOzoneSurfacelessSurfaceImpl(surface_ozone.Pass(), + window); } else { scoped_ptr<ui::SurfaceOzoneEGL> surface_ozone = ui::SurfaceFactoryOzone::GetInstance()->CreateEGLSurfaceForWidget(
diff --git a/ui/keyboard/BUILD.gn b/ui/keyboard/BUILD.gn index b504ba2..66a98a4 100644 --- a/ui/keyboard/BUILD.gn +++ b/ui/keyboard/BUILD.gn
@@ -93,33 +93,31 @@ path = rebase_path("//third_party/google_input_tools") } -if (!is_win || link_chrome_on_windows) { - test("keyboard_unittests") { - sources = [ - "keyboard_controller_unittest.cc", - "test/run_all_unittests.cc", - ] +test("keyboard_unittests") { + sources = [ + "keyboard_controller_unittest.cc", + "test/run_all_unittests.cc", + ] - deps = [ - ":keyboard", - "//base", - "//base/allocator", - "//base/test:test_support", - "//content", - "//skia", - "//testing/gtest", - "//ui/aura:test_support", - "//ui/base", - "//ui/base/ime", - "//ui/base:test_support", - "//ui/compositor:test_support", - "//ui/events:test_support", - "//ui/gfx", - "//ui/gfx/geometry", - "//ui/gl", - "//ui/resources:ui_test_pak", - "//ui/wm", - "//url", - ] - } + deps = [ + ":keyboard", + "//base", + "//base/allocator", + "//base/test:test_support", + "//content", + "//skia", + "//testing/gtest", + "//ui/aura:test_support", + "//ui/base", + "//ui/base/ime", + "//ui/base:test_support", + "//ui/compositor:test_support", + "//ui/events:test_support", + "//ui/gfx", + "//ui/gfx/geometry", + "//ui/gl", + "//ui/resources:ui_test_pak", + "//ui/wm", + "//url", + ] }
diff --git a/ui/message_center/BUILD.gn b/ui/message_center/BUILD.gn index b295019..cedc5b9 100644 --- a/ui/message_center/BUILD.gn +++ b/ui/message_center/BUILD.gn
@@ -176,65 +176,63 @@ ] } -if (!is_win || link_chrome_on_windows) { - test("message_center_unittests") { - sources = [ - "test/run_all_unittests.cc", +test("message_center_unittests") { + sources = [ + "test/run_all_unittests.cc", + ] + + deps = [ + ":message_center", + ":test_support", + "//base", + "//base/allocator", + "//base/test:test_support", + "//skia", + "//testing/gtest", + "//ui/base", + "//ui/events", + "//ui/gfx", + "//ui/gfx/geometry", + "//ui/gl", + "//ui/resources", + "//ui/resources:ui_test_pak", + "//url", + ] + + if (enable_notifications && !is_android) { + sources += [ + "cocoa/notification_controller_unittest.mm", + "cocoa/popup_collection_unittest.mm", + "cocoa/popup_controller_unittest.mm", + "cocoa/settings_controller_unittest.mm", + "cocoa/status_item_view_unittest.mm", + "cocoa/tray_controller_unittest.mm", + "cocoa/tray_view_controller_unittest.mm", + "message_center_impl_unittest.cc", + "message_center_tray_unittest.cc", + "notification_delegate_unittest.cc", + "notification_list_unittest.cc", ] - deps = [ - ":message_center", - ":test_support", - "//base", - "//base/allocator", - "//base/test:test_support", - "//skia", - "//testing/gtest", - "//ui/base", - "//ui/events", - "//ui/gfx", - "//ui/gfx/geometry", - "//ui/gl", - "//ui/resources", - "//ui/resources:ui_test_pak", - "//url", - ] + if (is_mac) { + deps += [ "//ui/gfx:test_support" ] + } - if (enable_notifications && !is_android) { + if (toolkit_views && !is_mac) { sources += [ - "cocoa/notification_controller_unittest.mm", - "cocoa/popup_collection_unittest.mm", - "cocoa/popup_controller_unittest.mm", - "cocoa/settings_controller_unittest.mm", - "cocoa/status_item_view_unittest.mm", - "cocoa/tray_controller_unittest.mm", - "cocoa/tray_view_controller_unittest.mm", - "message_center_impl_unittest.cc", - "message_center_tray_unittest.cc", - "notification_delegate_unittest.cc", - "notification_list_unittest.cc", + "views/bounded_label_unittest.cc", + "views/message_center_view_unittest.cc", + "views/message_popup_collection_unittest.cc", + "views/notification_view_unittest.cc", + "views/notifier_settings_view_unittest.cc", ] - - if (is_mac) { - deps += [ "//ui/gfx:test_support" ] - } - - if (toolkit_views && !is_mac) { - sources += [ - "views/bounded_label_unittest.cc", - "views/message_center_view_unittest.cc", - "views/message_popup_collection_unittest.cc", - "views/notification_view_unittest.cc", - "views/notifier_settings_view_unittest.cc", - ] - deps += [ - # Compositor is needed by message_center_view_unittest.cc and for the - # fonts used by bounded_label_unittest.cc. - "//ui/compositor", - "//ui/views", - "//ui/views:test_support", - ] - } - } # enable_notifications && !is_android - } + deps += [ + # Compositor is needed by message_center_view_unittest.cc and for the + # fonts used by bounded_label_unittest.cc. + "//ui/compositor", + "//ui/views", + "//ui/views:test_support", + ] + } + } # enable_notifications && !is_android }
diff --git a/ui/ozone/platform/dri/BUILD.gn b/ui/ozone/platform/dri/BUILD.gn index d796a60..f7c55c5 100644 --- a/ui/ozone/platform/dri/BUILD.gn +++ b/ui/ozone/platform/dri/BUILD.gn
@@ -52,8 +52,8 @@ "dri_window_delegate_manager.h", "dri_window_manager.cc", "dri_window_manager.h", - "dri_wrapper.cc", - "dri_wrapper.h", + "drm_device.cc", + "drm_device.h", "drm_device_generator.cc", "drm_device_generator.h", "drm_device_manager.cc", @@ -149,14 +149,14 @@ "gbm_buffer.h", "gbm_buffer_base.cc", "gbm_buffer_base.h", + "gbm_device.cc", + "gbm_device.h", "gbm_surface.cc", "gbm_surface.h", "gbm_surface_factory.cc", "gbm_surface_factory.h", "gbm_surfaceless.cc", "gbm_surfaceless.h", - "gbm_wrapper.cc", - "gbm_wrapper.h", "ozone_platform_gbm.cc", "ozone_platform_gbm.h", ]
diff --git a/ui/ozone/platform/dri/crtc_controller.cc b/ui/ozone/platform/dri/crtc_controller.cc index b5dcb14..d9e86f23 100644 --- a/ui/ozone/platform/dri/crtc_controller.cc +++ b/ui/ozone/platform/dri/crtc_controller.cc
@@ -6,13 +6,13 @@ #include "base/logging.h" #include "base/time/time.h" -#include "ui/ozone/platform/dri/dri_wrapper.h" +#include "ui/ozone/platform/dri/drm_device.h" #include "ui/ozone/platform/dri/page_flip_observer.h" #include "ui/ozone/platform/dri/scanout_buffer.h" namespace ui { -CrtcController::CrtcController(const scoped_refptr<DriWrapper>& drm, +CrtcController::CrtcController(const scoped_refptr<DrmDevice>& drm, uint32_t crtc, uint32_t connector) : drm_(drm),
diff --git a/ui/ozone/platform/dri/crtc_controller.h b/ui/ozone/platform/dri/crtc_controller.h index 01dc9a6..827515ce 100644 --- a/ui/ozone/platform/dri/crtc_controller.h +++ b/ui/ozone/platform/dri/crtc_controller.h
@@ -18,7 +18,7 @@ namespace ui { -class DriWrapper; +class DrmDevice; class PageFlipObserver; // Wrapper around a CRTC. @@ -29,14 +29,14 @@ class OZONE_EXPORT CrtcController : public base::SupportsWeakPtr<CrtcController> { public: - CrtcController(const scoped_refptr<DriWrapper>& drm, + CrtcController(const scoped_refptr<DrmDevice>& drm, uint32_t crtc, uint32_t connector); ~CrtcController(); uint32_t crtc() const { return crtc_; } uint32_t connector() const { return connector_; } - const scoped_refptr<DriWrapper>& drm() const { return drm_; } + const scoped_refptr<DrmDevice>& drm() const { return drm_; } bool is_disabled() const { return is_disabled_; } bool page_flip_pending() const { return page_flip_pending_; } uint64_t time_of_last_flip() const { return time_of_last_flip_; } @@ -75,7 +75,7 @@ void RemoveObserver(PageFlipObserver* observer); private: - scoped_refptr<DriWrapper> drm_; + scoped_refptr<DrmDevice> drm_; HardwareDisplayPlaneManager* overlay_plane_manager_; // Not owned.
diff --git a/ui/ozone/platform/dri/display_snapshot_dri.cc b/ui/ozone/platform/dri/display_snapshot_dri.cc index 1ad9fb2c..164d5ee 100644 --- a/ui/ozone/platform/dri/display_snapshot_dri.cc +++ b/ui/ozone/platform/dri/display_snapshot_dri.cc
@@ -14,7 +14,7 @@ #include "ui/display/util/edid_parser.h" #include "ui/ozone/platform/dri/display_mode_dri.h" #include "ui/ozone/platform/dri/dri_util.h" -#include "ui/ozone/platform/dri/dri_wrapper.h" +#include "ui/ozone/platform/dri/drm_device.h" #if !defined(DRM_MODE_CONNECTOR_DSI) #define DRM_MODE_CONNECTOR_DSI 16 @@ -46,7 +46,7 @@ } } -bool IsAspectPreserving(DriWrapper* drm, drmModeConnector* connector) { +bool IsAspectPreserving(DrmDevice* drm, drmModeConnector* connector) { ScopedDrmPropertyPtr property(drm->GetProperty(connector, "scaling mode")); if (!property) return false; @@ -67,7 +67,7 @@ } // namespace -DisplaySnapshotDri::DisplaySnapshotDri(const scoped_refptr<DriWrapper>& drm, +DisplaySnapshotDri::DisplaySnapshotDri(const scoped_refptr<DrmDevice>& drm, drmModeConnector* connector, drmModeCrtc* crtc, uint32_t index)
diff --git a/ui/ozone/platform/dri/display_snapshot_dri.h b/ui/ozone/platform/dri/display_snapshot_dri.h index 0a7052b..2ba799034 100644 --- a/ui/ozone/platform/dri/display_snapshot_dri.h +++ b/ui/ozone/platform/dri/display_snapshot_dri.h
@@ -11,17 +11,17 @@ namespace ui { -class DriWrapper; +class DrmDevice; class DisplaySnapshotDri : public DisplaySnapshot { public: - DisplaySnapshotDri(const scoped_refptr<DriWrapper>& drm, + DisplaySnapshotDri(const scoped_refptr<DrmDevice>& drm, drmModeConnector* connector, drmModeCrtc* crtc, uint32_t index); ~DisplaySnapshotDri() override; - scoped_refptr<DriWrapper> drm() const { return drm_; } + scoped_refptr<DrmDevice> drm() const { return drm_; } // Native properties of a display used by the DRI implementation in // configuring this display. uint32_t connector() const { return connector_; } @@ -32,7 +32,7 @@ std::string ToString() const override; private: - scoped_refptr<DriWrapper> drm_; + scoped_refptr<DrmDevice> drm_; uint32_t connector_; uint32_t crtc_; ScopedDrmPropertyPtr dpms_property_;
diff --git a/ui/ozone/platform/dri/dri.gypi b/ui/ozone/platform/dri/dri.gypi index 77795af..e44b3b1 100644 --- a/ui/ozone/platform/dri/dri.gypi +++ b/ui/ozone/platform/dri/dri.gypi
@@ -74,8 +74,8 @@ 'dri_window_delegate_manager.h', 'dri_window_manager.cc', 'dri_window_manager.h', - 'dri_wrapper.cc', - 'dri_wrapper.h', + 'drm_device.cc', + 'drm_device.h', 'drm_device_generator.cc', 'drm_device_generator.h', 'drm_device_manager.cc', @@ -124,8 +124,8 @@ 'hardware_display_controller_unittest.cc', 'hardware_display_plane_manager_unittest.cc', 'screen_manager_unittest.cc', - 'test/mock_dri_wrapper.cc', - 'test/mock_dri_wrapper.h', + 'test/mock_drm_device.cc', + 'test/mock_drm_device.h', ], }, },
diff --git a/ui/ozone/platform/dri/dri_buffer.cc b/ui/ozone/platform/dri/dri_buffer.cc index 9fa284f..bd2c2c2 100644 --- a/ui/ozone/platform/dri/dri_buffer.cc +++ b/ui/ozone/platform/dri/dri_buffer.cc
@@ -5,7 +5,7 @@ #include "ui/ozone/platform/dri/dri_buffer.h" #include "base/logging.h" -#include "ui/ozone/platform/dri/dri_wrapper.h" +#include "ui/ozone/platform/dri/drm_device.h" namespace ui { @@ -34,8 +34,8 @@ } // namespace -DriBuffer::DriBuffer(const scoped_refptr<DriWrapper>& dri) - : dri_(dri), handle_(0), framebuffer_(0) { +DriBuffer::DriBuffer(const scoped_refptr<DrmDevice>& drm) + : drm_(drm), handle_(0), framebuffer_(0) { } DriBuffer::~DriBuffer() { @@ -43,26 +43,26 @@ return; if (framebuffer_) - dri_->RemoveFramebuffer(framebuffer_); + drm_->RemoveFramebuffer(framebuffer_); SkImageInfo info; void* pixels = const_cast<void*>(surface_->peekPixels(&info, NULL)); if (!pixels) return; - dri_->DestroyDumbBuffer(info, handle_, stride_, pixels); + drm_->DestroyDumbBuffer(info, handle_, stride_, pixels); } bool DriBuffer::Initialize(const SkImageInfo& info, bool should_register_framebuffer) { void* pixels = NULL; - if (!dri_->CreateDumbBuffer(info, &handle_, &stride_, &pixels)) { + if (!drm_->CreateDumbBuffer(info, &handle_, &stride_, &pixels)) { VLOG(2) << "Cannot create drm dumb buffer"; return false; } if (should_register_framebuffer && - !dri_->AddFramebuffer( + !drm_->AddFramebuffer( info.width(), info.height(), GetColorDepth(info.colorType()), info.bytesPerPixel() << 3, stride_, handle_, &framebuffer_)) { VLOG(2) << "Failed to register framebuffer: " << strerror(errno); @@ -100,7 +100,7 @@ DriBufferGenerator::~DriBufferGenerator() {} scoped_refptr<ScanoutBuffer> DriBufferGenerator::Create( - const scoped_refptr<DriWrapper>& drm, + const scoped_refptr<DrmDevice>& drm, const gfx::Size& size) { scoped_refptr<DriBuffer> buffer(new DriBuffer(drm)); SkImageInfo info = SkImageInfo::MakeN32Premul(size.width(), size.height());
diff --git a/ui/ozone/platform/dri/dri_buffer.h b/ui/ozone/platform/dri/dri_buffer.h index 7bcca1b..0b9f8e68 100644 --- a/ui/ozone/platform/dri/dri_buffer.h +++ b/ui/ozone/platform/dri/dri_buffer.h
@@ -13,14 +13,14 @@ namespace ui { -class DriWrapper; +class DrmDevice; // Wrapper for a DRM allocated buffer. Keeps track of the native properties of // the buffer and wraps the pixel memory into a SkSurface which can be used to // draw into using Skia. class OZONE_EXPORT DriBuffer : public ScanoutBuffer { public: - DriBuffer(const scoped_refptr<DriWrapper>& dri); + DriBuffer(const scoped_refptr<DrmDevice>& drm); // Allocates the backing pixels and wraps them in |surface_|. |info| is used // to describe the buffer characteristics (size, color format). @@ -38,7 +38,7 @@ protected: ~DriBuffer() override; - scoped_refptr<DriWrapper> dri_; + scoped_refptr<DrmDevice> drm_; // Wrapper around the native pixel memory. skia::RefPtr<SkSurface> surface_; @@ -62,7 +62,7 @@ ~DriBufferGenerator() override; // ScanoutBufferGenerator: - scoped_refptr<ScanoutBuffer> Create(const scoped_refptr<DriWrapper>& drm, + scoped_refptr<ScanoutBuffer> Create(const scoped_refptr<DrmDevice>& drm, const gfx::Size& size) override; private:
diff --git a/ui/ozone/platform/dri/dri_console_buffer.cc b/ui/ozone/platform/dri/dri_console_buffer.cc index 204590f..91aba48 100644 --- a/ui/ozone/platform/dri/dri_console_buffer.cc +++ b/ui/ozone/platform/dri/dri_console_buffer.cc
@@ -9,14 +9,14 @@ #include "third_party/skia/include/core/SkCanvas.h" #include "ui/ozone/platform/dri/dri_util.h" -#include "ui/ozone/platform/dri/dri_wrapper.h" +#include "ui/ozone/platform/dri/drm_device.h" #include "ui/ozone/platform/dri/scoped_drm_types.h" namespace ui { -DriConsoleBuffer::DriConsoleBuffer(const scoped_refptr<DriWrapper>& dri, +DriConsoleBuffer::DriConsoleBuffer(const scoped_refptr<DrmDevice>& drm, uint32_t framebuffer) - : dri_(dri), + : drm_(drm), handle_(0), framebuffer_(framebuffer), mmap_base_(NULL), @@ -30,7 +30,7 @@ } bool DriConsoleBuffer::Initialize() { - ScopedDrmFramebufferPtr fb(dri_->GetFramebuffer(framebuffer_)); + ScopedDrmFramebufferPtr fb(drm_->GetFramebuffer(framebuffer_)); if (!fb) return false; @@ -41,7 +41,7 @@ mmap_size_ = info.getSafeSize(stride_); - if (!MapDumbBuffer(dri_->get_fd(), fb->handle, mmap_size_, &mmap_base_)) { + if (!MapDumbBuffer(drm_->get_fd(), fb->handle, mmap_size_, &mmap_base_)) { mmap_base_ = NULL; return false; }
diff --git a/ui/ozone/platform/dri/dri_console_buffer.h b/ui/ozone/platform/dri/dri_console_buffer.h index 6a9c3cca..e174955 100644 --- a/ui/ozone/platform/dri/dri_console_buffer.h +++ b/ui/ozone/platform/dri/dri_console_buffer.h
@@ -14,7 +14,7 @@ namespace ui { -class DriWrapper; +class DrmDevice; // Wrapper for the console buffer. This is the buffer that is allocated by // default by the system and is used when no application is controlling the @@ -22,7 +22,7 @@ // memory into a SkSurface which can be used to draw into using Skia. class DriConsoleBuffer { public: - DriConsoleBuffer(const scoped_refptr<DriWrapper>& dri, uint32_t framebuffer); + DriConsoleBuffer(const scoped_refptr<DrmDevice>& drm, uint32_t framebuffer); ~DriConsoleBuffer(); SkCanvas* canvas() { return surface_->getCanvas(); } @@ -34,7 +34,7 @@ bool Initialize(); protected: - scoped_refptr<DriWrapper> dri_; + scoped_refptr<DrmDevice> drm_; // Wrapper around the native pixel memory. skia::RefPtr<SkSurface> surface_;
diff --git a/ui/ozone/platform/dri/dri_gpu_platform_support.cc b/ui/ozone/platform/dri/dri_gpu_platform_support.cc index d4116bf..c9736a2 100644 --- a/ui/ozone/platform/dri/dri_gpu_platform_support.cc +++ b/ui/ozone/platform/dri/dri_gpu_platform_support.cc
@@ -11,7 +11,7 @@ #include "ui/ozone/common/gpu/ozone_gpu_messages.h" #include "ui/ozone/platform/dri/dri_window_delegate_impl.h" #include "ui/ozone/platform/dri/dri_window_delegate_manager.h" -#include "ui/ozone/platform/dri/dri_wrapper.h" +#include "ui/ozone/platform/dri/drm_device.h" #include "ui/ozone/platform/dri/native_display_delegate_dri.h" namespace ui {
diff --git a/ui/ozone/platform/dri/dri_surface.cc b/ui/ozone/platform/dri/dri_surface.cc index 89107f2b..5fb108c 100644 --- a/ui/ozone/platform/dri/dri_surface.cc +++ b/ui/ozone/platform/dri/dri_surface.cc
@@ -14,16 +14,16 @@ #include "ui/ozone/platform/dri/dri_buffer.h" #include "ui/ozone/platform/dri/dri_vsync_provider.h" #include "ui/ozone/platform/dri/dri_window_delegate_impl.h" -#include "ui/ozone/platform/dri/dri_wrapper.h" +#include "ui/ozone/platform/dri/drm_device.h" #include "ui/ozone/platform/dri/hardware_display_controller.h" namespace ui { namespace { -scoped_refptr<DriBuffer> AllocateBuffer(const scoped_refptr<DriWrapper>& dri, +scoped_refptr<DriBuffer> AllocateBuffer(const scoped_refptr<DrmDevice>& drm, const gfx::Size& size) { - scoped_refptr<DriBuffer> buffer(new DriBuffer(dri)); + scoped_refptr<DriBuffer> buffer(new DriBuffer(drm)); SkImageInfo info = SkImageInfo::MakeN32Premul(size.width(), size.height()); bool initialized = @@ -58,7 +58,7 @@ // For the display buffers use the mode size since a |viewport_size| smaller // than the display size will not scanout. for (size_t i = 0; i < arraysize(buffers_); ++i) - buffers_[i] = AllocateBuffer(controller->GetAllocationDriWrapper(), + buffers_[i] = AllocateBuffer(controller->GetAllocationDrmDevice(), controller->GetModeSize()); }
diff --git a/ui/ozone/platform/dri/dri_surface_unittest.cc b/ui/ozone/platform/dri/dri_surface_unittest.cc index 53d155a..949c8c5 100644 --- a/ui/ozone/platform/dri/dri_surface_unittest.cc +++ b/ui/ozone/platform/dri/dri_surface_unittest.cc
@@ -12,7 +12,7 @@ #include "ui/ozone/platform/dri/dri_surface.h" #include "ui/ozone/platform/dri/dri_window_delegate.h" #include "ui/ozone/platform/dri/hardware_display_controller.h" -#include "ui/ozone/platform/dri/test/mock_dri_wrapper.h" +#include "ui/ozone/platform/dri/test/mock_drm_device.h" namespace { @@ -26,7 +26,7 @@ class MockDriWindowDelegate : public ui::DriWindowDelegate { public: - MockDriWindowDelegate(ui::DriWrapper* drm) { + MockDriWindowDelegate(ui::DrmDevice* drm) { controller_.reset(new ui::HardwareDisplayController(make_scoped_ptr( new ui::CrtcController(drm, kDefaultCrtc, kDefaultConnector)))); scoped_refptr<ui::DriBuffer> buffer(new ui::DriBuffer(drm)); @@ -69,7 +69,7 @@ protected: scoped_ptr<base::MessageLoop> message_loop_; - scoped_refptr<ui::MockDriWrapper> drm_; + scoped_refptr<ui::MockDrmDevice> drm_; scoped_ptr<MockDriWindowDelegate> window_delegate_; scoped_ptr<ui::DriSurface> surface_; @@ -81,7 +81,7 @@ message_loop_.reset(new base::MessageLoopForUI); std::vector<uint32_t> crtcs; crtcs.push_back(kDefaultCrtc); - drm_ = new ui::MockDriWrapper(true, crtcs, kPlanesPerCrtc); + drm_ = new ui::MockDrmDevice(true, crtcs, kPlanesPerCrtc); window_delegate_.reset(new MockDriWindowDelegate(drm_.get())); surface_.reset(new ui::DriSurface(window_delegate_.get())); surface_->ResizeCanvas(gfx::Size(kDefaultMode.hdisplay,
diff --git a/ui/ozone/platform/dri/dri_util.cc b/ui/ozone/platform/dri/dri_util.cc index 7849efdc..338c411 100644 --- a/ui/ozone/platform/dri/dri_util.cc +++ b/ui/ozone/platform/dri/dri_util.cc
@@ -2,7 +2,6 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#include "base/strings/stringprintf.h" #include "ui/ozone/platform/dri/dri_util.h" #include <errno.h> @@ -13,7 +12,8 @@ #include <xf86drm.h> #include <xf86drmMode.h> -#include "ui/ozone/platform/dri/dri_wrapper.h" +#include "base/strings/stringprintf.h" +#include "ui/ozone/platform/dri/drm_device.h" #include "ui/ozone/platform/dri/screen_manager.h" namespace ui { @@ -142,7 +142,7 @@ return true; } -void ForceInitializationOfPrimaryDisplay(const scoped_refptr<DriWrapper>& drm, +void ForceInitializationOfPrimaryDisplay(const scoped_refptr<DrmDevice>& drm, ScreenManager* screen_manager) { LOG(WARNING) << "Forcing initialization of primary display."; ScopedVector<HardwareDisplayControllerInfo> displays =
diff --git a/ui/ozone/platform/dri/dri_util.h b/ui/ozone/platform/dri/dri_util.h index 742f512f..eb83939 100644 --- a/ui/ozone/platform/dri/dri_util.h +++ b/ui/ozone/platform/dri/dri_util.h
@@ -15,7 +15,7 @@ namespace ui { -class DriWrapper; +class DrmDevice; class ScreenManager; // Representation of the information required to initialize and configure a @@ -49,7 +49,7 @@ uint32_t size, void** pixels); -void ForceInitializationOfPrimaryDisplay(const scoped_refptr<DriWrapper>& drm, +void ForceInitializationOfPrimaryDisplay(const scoped_refptr<DrmDevice>& drm, ScreenManager* screen_manager); base::FilePath GetPrimaryDisplayCardPath();
diff --git a/ui/ozone/platform/dri/dri_window_delegate_impl.cc b/ui/ozone/platform/dri/dri_window_delegate_impl.cc index af81012d..9a9c8a33 100644 --- a/ui/ozone/platform/dri/dri_window_delegate_impl.cc +++ b/ui/ozone/platform/dri/dri_window_delegate_impl.cc
@@ -9,7 +9,7 @@ #include "third_party/skia/include/core/SkDevice.h" #include "third_party/skia/include/core/SkSurface.h" #include "ui/ozone/platform/dri/dri_buffer.h" -#include "ui/ozone/platform/dri/dri_wrapper.h" +#include "ui/ozone/platform/dri/drm_device.h" #include "ui/ozone/platform/dri/drm_device_manager.h" #include "ui/ozone/platform/dri/screen_manager.h" @@ -181,9 +181,9 @@ } void DriWindowDelegateImpl::UpdateWidgetToDrmDeviceMapping() { - scoped_refptr<DriWrapper> drm = nullptr; + scoped_refptr<DrmDevice> drm = nullptr; if (controller_) - drm = controller_->GetAllocationDriWrapper(); + drm = controller_->GetAllocationDrmDevice(); device_manager_->UpdateDrmDevice(widget_, drm); } @@ -194,7 +194,7 @@ cursor_buffers_[i] = nullptr; } } else { - scoped_refptr<DriWrapper> drm = controller_->GetAllocationDriWrapper(); + scoped_refptr<DrmDevice> drm = controller_->GetAllocationDrmDevice(); uint64_t cursor_width = 64; uint64_t cursor_height = 64;
diff --git a/ui/ozone/platform/dri/dri_window_delegate_impl_unittest.cc b/ui/ozone/platform/dri/dri_window_delegate_impl_unittest.cc index 95068bd..b02ee8fa 100644 --- a/ui/ozone/platform/dri/dri_window_delegate_impl_unittest.cc +++ b/ui/ozone/platform/dri/dri_window_delegate_impl_unittest.cc
@@ -18,7 +18,7 @@ #include "ui/ozone/platform/dri/drm_device_manager.h" #include "ui/ozone/platform/dri/hardware_display_controller.h" #include "ui/ozone/platform/dri/screen_manager.h" -#include "ui/ozone/platform/dri/test/mock_dri_wrapper.h" +#include "ui/ozone/platform/dri/test/mock_drm_device.h" #include "ui/ozone/public/surface_ozone_canvas.h" namespace { @@ -33,7 +33,7 @@ const int kDefaultCursorSize = 64; std::vector<skia::RefPtr<SkSurface>> GetCursorBuffers( - const scoped_refptr<ui::MockDriWrapper> drm) { + const scoped_refptr<ui::MockDrmDevice> drm) { std::vector<skia::RefPtr<SkSurface>> cursor_buffers; for (const skia::RefPtr<SkSurface>& cursor_buffer : drm->buffers()) { if (cursor_buffer->width() == kDefaultCursorSize && @@ -56,7 +56,7 @@ protected: scoped_ptr<base::MessageLoop> message_loop_; - scoped_refptr<ui::MockDriWrapper> dri_; + scoped_refptr<ui::MockDrmDevice> drm_; scoped_ptr<ui::DriBufferGenerator> buffer_generator_; scoped_ptr<ui::ScreenManager> screen_manager_; scoped_ptr<ui::DrmDeviceManager> drm_device_manager_; @@ -68,14 +68,14 @@ void DriWindowDelegateImplTest::SetUp() { message_loop_.reset(new base::MessageLoopForUI); - dri_ = new ui::MockDriWrapper(); + drm_ = new ui::MockDrmDevice(); buffer_generator_.reset(new ui::DriBufferGenerator()); screen_manager_.reset(new ui::ScreenManager(buffer_generator_.get())); - screen_manager_->AddDisplayController(dri_, kDefaultCrtc, kDefaultConnector); + screen_manager_->AddDisplayController(drm_, kDefaultCrtc, kDefaultConnector); screen_manager_->ConfigureDisplayController( - dri_, kDefaultCrtc, kDefaultConnector, gfx::Point(), kDefaultMode); + drm_, kDefaultCrtc, kDefaultConnector, gfx::Point(), kDefaultMode); - drm_device_manager_.reset(new ui::DrmDeviceManager(dri_)); + drm_device_manager_.reset(new ui::DrmDeviceManager(drm_)); window_delegate_manager_.reset(new ui::DriWindowDelegateManager()); scoped_ptr<ui::DriWindowDelegate> window_delegate( @@ -109,7 +109,7 @@ ->SetCursor(cursor_bitmaps, gfx::Point(4, 2), 0); SkBitmap cursor; - std::vector<skia::RefPtr<SkSurface>> cursor_buffers = GetCursorBuffers(dri_); + std::vector<skia::RefPtr<SkSurface>> cursor_buffers = GetCursorBuffers(drm_); EXPECT_EQ(2u, cursor_buffers.size()); // Buffers 1 is the cursor backbuffer we just drew in. @@ -130,7 +130,7 @@ TEST_F(DriWindowDelegateImplTest, CheckCursorSurfaceAfterChangingDevice) { // Add another device. - scoped_refptr<ui::MockDriWrapper> drm = new ui::MockDriWrapper(); + scoped_refptr<ui::MockDrmDevice> drm = new ui::MockDrmDevice(); screen_manager_->AddDisplayController(drm, kDefaultCrtc, kDefaultConnector); screen_manager_->ConfigureDisplayController( drm, kDefaultCrtc, kDefaultConnector,
diff --git a/ui/ozone/platform/dri/dri_wrapper.cc b/ui/ozone/platform/dri/drm_device.cc similarity index 72% rename from ui/ozone/platform/dri/dri_wrapper.cc rename to ui/ozone/platform/dri/drm_device.cc index 87b250ec..e51059d 100644 --- a/ui/ozone/platform/dri/dri_wrapper.cc +++ b/ui/ozone/platform/dri/drm_device.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 "ui/ozone/platform/dri/dri_wrapper.h" +#include "ui/ozone/platform/dri/drm_device.h" #include <fcntl.h> #include <sys/mman.h> @@ -27,13 +27,13 @@ struct PageFlipPayload { PageFlipPayload(const scoped_refptr<base::TaskRunner>& task_runner, - const DriWrapper::PageFlipCallback& callback) + const DrmDevice::PageFlipCallback& callback) : task_runner(task_runner), callback(callback) {} // Task runner for the thread scheduling the page flip event. This is used to // run the callback on the same thread the callback was created on. scoped_refptr<base::TaskRunner> task_runner; - DriWrapper::PageFlipCallback callback; + DrmDevice::PageFlipCallback callback; }; bool DrmCreateDumbBuffer(int fd, @@ -99,8 +99,8 @@ } // namespace -class DriWrapper::IOWatcher - : public base::RefCountedThreadSafe<DriWrapper::IOWatcher>, +class DrmDevice::IOWatcher + : public base::RefCountedThreadSafe<DrmDevice::IOWatcher>, public base::MessagePumpLibevent::Watcher { public: IOWatcher(int fd, @@ -173,7 +173,7 @@ DISALLOW_COPY_AND_ASSIGN(IOWatcher); }; -DriWrapper::DriWrapper(const base::FilePath& device_path) +DrmDevice::DrmDevice(const base::FilePath& device_path) : device_path_(device_path), file_(device_path, base::File::FLAG_OPEN | base::File::FLAG_READ | @@ -183,16 +183,16 @@ << "': " << base::File::ErrorToString(file_.error_details()); } -DriWrapper::DriWrapper(const base::FilePath& device_path, base::File file) +DrmDevice::DrmDevice(const base::FilePath& device_path, base::File file) : device_path_(device_path), file_(file.Pass()) { } -DriWrapper::~DriWrapper() { +DrmDevice::~DrmDevice() { if (watcher_) watcher_->Shutdown(); } -bool DriWrapper::Initialize() { +bool DrmDevice::Initialize() { // Ignore devices that cannot perform modesetting. if (!CanQueryForResources(file_.GetPlatformFile())) { VLOG(2) << "Cannot query for resources for '" << device_path_.value() @@ -211,33 +211,33 @@ return true; } -void DriWrapper::InitializeTaskRunner( +void DrmDevice::InitializeTaskRunner( const scoped_refptr<base::SingleThreadTaskRunner>& task_runner) { DCHECK(!task_runner_); task_runner_ = task_runner; watcher_ = new IOWatcher(file_.GetPlatformFile(), task_runner_); } -ScopedDrmCrtcPtr DriWrapper::GetCrtc(uint32_t crtc_id) { +ScopedDrmCrtcPtr DrmDevice::GetCrtc(uint32_t crtc_id) { DCHECK(file_.IsValid()); return ScopedDrmCrtcPtr(drmModeGetCrtc(file_.GetPlatformFile(), crtc_id)); } -bool DriWrapper::SetCrtc(uint32_t crtc_id, - uint32_t framebuffer, - std::vector<uint32_t> connectors, - drmModeModeInfo* mode) { +bool DrmDevice::SetCrtc(uint32_t crtc_id, + uint32_t framebuffer, + std::vector<uint32_t> connectors, + drmModeModeInfo* mode) { DCHECK(file_.IsValid()); DCHECK(!connectors.empty()); DCHECK(mode); - TRACE_EVENT2("dri", "DriWrapper::SetCrtc", "crtc", crtc_id, "size", + TRACE_EVENT2("dri", "DrmDevice::SetCrtc", "crtc", crtc_id, "size", gfx::Size(mode->hdisplay, mode->vdisplay).ToString()); return !drmModeSetCrtc(file_.GetPlatformFile(), crtc_id, framebuffer, 0, 0, vector_as_array(&connectors), connectors.size(), mode); } -bool DriWrapper::SetCrtc(drmModeCrtc* crtc, std::vector<uint32_t> connectors) { +bool DrmDevice::SetCrtc(drmModeCrtc* crtc, std::vector<uint32_t> connectors) { DCHECK(file_.IsValid()); // If there's no buffer then the CRTC was disabled. if (!crtc->buffer_id) @@ -245,58 +245,54 @@ DCHECK(!connectors.empty()); - TRACE_EVENT1("dri", "DriWrapper::RestoreCrtc", - "crtc", crtc->crtc_id); + TRACE_EVENT1("dri", "DrmDevice::RestoreCrtc", "crtc", crtc->crtc_id); return !drmModeSetCrtc(file_.GetPlatformFile(), crtc->crtc_id, crtc->buffer_id, crtc->x, crtc->y, vector_as_array(&connectors), connectors.size(), &crtc->mode); } -bool DriWrapper::DisableCrtc(uint32_t crtc_id) { +bool DrmDevice::DisableCrtc(uint32_t crtc_id) { DCHECK(file_.IsValid()); - TRACE_EVENT1("dri", "DriWrapper::DisableCrtc", - "crtc", crtc_id); + TRACE_EVENT1("dri", "DrmDevice::DisableCrtc", "crtc", crtc_id); return !drmModeSetCrtc(file_.GetPlatformFile(), crtc_id, 0, 0, 0, NULL, 0, NULL); } -ScopedDrmConnectorPtr DriWrapper::GetConnector(uint32_t connector_id) { +ScopedDrmConnectorPtr DrmDevice::GetConnector(uint32_t connector_id) { DCHECK(file_.IsValid()); - TRACE_EVENT1("dri", "DriWrapper::GetConnector", "connector", connector_id); + TRACE_EVENT1("dri", "DrmDevice::GetConnector", "connector", connector_id); return ScopedDrmConnectorPtr( drmModeGetConnector(file_.GetPlatformFile(), connector_id)); } -bool DriWrapper::AddFramebuffer(uint32_t width, - uint32_t height, - uint8_t depth, - uint8_t bpp, - uint32_t stride, - uint32_t handle, - uint32_t* framebuffer) { +bool DrmDevice::AddFramebuffer(uint32_t width, + uint32_t height, + uint8_t depth, + uint8_t bpp, + uint32_t stride, + uint32_t handle, + uint32_t* framebuffer) { DCHECK(file_.IsValid()); - TRACE_EVENT1("dri", "DriWrapper::AddFramebuffer", - "handle", handle); + TRACE_EVENT1("dri", "DrmDevice::AddFramebuffer", "handle", handle); return !drmModeAddFB(file_.GetPlatformFile(), width, height, depth, bpp, stride, handle, framebuffer); } -bool DriWrapper::RemoveFramebuffer(uint32_t framebuffer) { +bool DrmDevice::RemoveFramebuffer(uint32_t framebuffer) { DCHECK(file_.IsValid()); - TRACE_EVENT1("dri", "DriWrapper::RemoveFramebuffer", - "framebuffer", framebuffer); + TRACE_EVENT1("dri", "DrmDevice::RemoveFramebuffer", "framebuffer", + framebuffer); return !drmModeRmFB(file_.GetPlatformFile(), framebuffer); } -bool DriWrapper::PageFlip(uint32_t crtc_id, - uint32_t framebuffer, - bool is_sync, - const PageFlipCallback& callback) { +bool DrmDevice::PageFlip(uint32_t crtc_id, + uint32_t framebuffer, + bool is_sync, + const PageFlipCallback& callback) { DCHECK(file_.IsValid()); - TRACE_EVENT2("dri", "DriWrapper::PageFlip", - "crtc", crtc_id, - "framebuffer", framebuffer); + TRACE_EVENT2("dri", "DrmDevice::PageFlip", "crtc", crtc_id, "framebuffer", + framebuffer); if (watcher_) watcher_->SetPaused(is_sync); @@ -329,14 +325,13 @@ return false; } -bool DriWrapper::PageFlipOverlay(uint32_t crtc_id, - uint32_t framebuffer, - const gfx::Rect& location, - const gfx::Rect& source, - int overlay_plane) { +bool DrmDevice::PageFlipOverlay(uint32_t crtc_id, + uint32_t framebuffer, + const gfx::Rect& location, + const gfx::Rect& source, + int overlay_plane) { DCHECK(file_.IsValid()); - TRACE_EVENT2("dri", "DriWrapper::PageFlipOverlay", - "crtc", crtc_id, + TRACE_EVENT2("dri", "DrmDevice::PageFlipOverlay", "crtc", crtc_id, "framebuffer", framebuffer); return !drmModeSetPlane(file_.GetPlatformFile(), overlay_plane, crtc_id, framebuffer, 0, location.x(), location.y(), @@ -344,19 +339,17 @@ source.y(), source.width(), source.height()); } -ScopedDrmFramebufferPtr DriWrapper::GetFramebuffer(uint32_t framebuffer) { +ScopedDrmFramebufferPtr DrmDevice::GetFramebuffer(uint32_t framebuffer) { DCHECK(file_.IsValid()); - TRACE_EVENT1("dri", "DriWrapper::GetFramebuffer", - "framebuffer", framebuffer); + TRACE_EVENT1("dri", "DrmDevice::GetFramebuffer", "framebuffer", framebuffer); return ScopedDrmFramebufferPtr( drmModeGetFB(file_.GetPlatformFile(), framebuffer)); } -ScopedDrmPropertyPtr DriWrapper::GetProperty(drmModeConnector* connector, - const char* name) { - TRACE_EVENT2("dri", "DriWrapper::GetProperty", - "connector", connector->connector_id, - "name", name); +ScopedDrmPropertyPtr DrmDevice::GetProperty(drmModeConnector* connector, + const char* name) { + TRACE_EVENT2("dri", "DrmDevice::GetProperty", "connector", + connector->connector_id, "name", name); for (int i = 0; i < connector->count_props; ++i) { ScopedDrmPropertyPtr property( drmModeGetProperty(file_.GetPlatformFile(), connector->props[i])); @@ -370,25 +363,24 @@ return ScopedDrmPropertyPtr(); } -bool DriWrapper::SetProperty(uint32_t connector_id, - uint32_t property_id, - uint64_t value) { +bool DrmDevice::SetProperty(uint32_t connector_id, + uint32_t property_id, + uint64_t value) { DCHECK(file_.IsValid()); return !drmModeConnectorSetProperty(file_.GetPlatformFile(), connector_id, property_id, value); } -bool DriWrapper::GetCapability(uint64_t capability, uint64_t* value) { +bool DrmDevice::GetCapability(uint64_t capability, uint64_t* value) { DCHECK(file_.IsValid()); return !drmGetCap(file_.GetPlatformFile(), capability, value); } -ScopedDrmPropertyBlobPtr DriWrapper::GetPropertyBlob( - drmModeConnector* connector, const char* name) { +ScopedDrmPropertyBlobPtr DrmDevice::GetPropertyBlob(drmModeConnector* connector, + const char* name) { DCHECK(file_.IsValid()); - TRACE_EVENT2("dri", "DriWrapper::GetPropertyBlob", - "connector", connector->connector_id, - "name", name); + TRACE_EVENT2("dri", "DrmDevice::GetPropertyBlob", "connector", + connector->connector_id, "name", name); for (int i = 0; i < connector->count_props; ++i) { ScopedDrmPropertyPtr property( drmModeGetProperty(file_.GetPlatformFile(), connector->props[i])); @@ -404,28 +396,28 @@ return ScopedDrmPropertyBlobPtr(); } -bool DriWrapper::SetCursor(uint32_t crtc_id, - uint32_t handle, - const gfx::Size& size) { +bool DrmDevice::SetCursor(uint32_t crtc_id, + uint32_t handle, + const gfx::Size& size) { DCHECK(file_.IsValid()); - TRACE_EVENT1("dri", "DriWrapper::SetCursor", "handle", handle); + TRACE_EVENT1("dri", "DrmDevice::SetCursor", "handle", handle); return !drmModeSetCursor(file_.GetPlatformFile(), crtc_id, handle, size.width(), size.height()); } -bool DriWrapper::MoveCursor(uint32_t crtc_id, const gfx::Point& point) { +bool DrmDevice::MoveCursor(uint32_t crtc_id, const gfx::Point& point) { DCHECK(file_.IsValid()); return !drmModeMoveCursor(file_.GetPlatformFile(), crtc_id, point.x(), point.y()); } -bool DriWrapper::CreateDumbBuffer(const SkImageInfo& info, - uint32_t* handle, - uint32_t* stride, - void** pixels) { +bool DrmDevice::CreateDumbBuffer(const SkImageInfo& info, + uint32_t* handle, + uint32_t* stride, + void** pixels) { DCHECK(file_.IsValid()); - TRACE_EVENT0("dri", "DriWrapper::CreateDumbBuffer"); + TRACE_EVENT0("dri", "DrmDevice::CreateDumbBuffer"); if (!DrmCreateDumbBuffer(file_.GetPlatformFile(), info, handle, stride)) return false; @@ -438,22 +430,22 @@ return true; } -void DriWrapper::DestroyDumbBuffer(const SkImageInfo& info, - uint32_t handle, - uint32_t stride, - void* pixels) { +void DrmDevice::DestroyDumbBuffer(const SkImageInfo& info, + uint32_t handle, + uint32_t stride, + void* pixels) { DCHECK(file_.IsValid()); - TRACE_EVENT1("dri", "DriWrapper::DestroyDumbBuffer", "handle", handle); + TRACE_EVENT1("dri", "DrmDevice::DestroyDumbBuffer", "handle", handle); munmap(pixels, info.getSafeSize(stride)); DrmDestroyDumbBuffer(file_.GetPlatformFile(), handle); } -bool DriWrapper::SetMaster() { +bool DrmDevice::SetMaster() { DCHECK(file_.IsValid()); return (drmSetMaster(file_.GetPlatformFile()) == 0); } -bool DriWrapper::DropMaster() { +bool DrmDevice::DropMaster() { DCHECK(file_.IsValid()); return (drmDropMaster(file_.GetPlatformFile()) == 0); }
diff --git a/ui/ozone/platform/dri/dri_wrapper.h b/ui/ozone/platform/dri/drm_device.h similarity index 93% rename from ui/ozone/platform/dri/dri_wrapper.h rename to ui/ozone/platform/dri/drm_device.h index 27582dbb..73b42bc 100644 --- a/ui/ozone/platform/dri/dri_wrapper.h +++ b/ui/ozone/platform/dri/drm_device.h
@@ -2,8 +2,8 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#ifndef UI_OZONE_PLATFORM_DRI_DRI_WRAPPER_H_ -#define UI_OZONE_PLATFORM_DRI_DRI_WRAPPER_H_ +#ifndef UI_OZONE_PLATFORM_DRI_DRM_DEVICE_H_ +#define UI_OZONE_PLATFORM_DRI_DRM_DEVICE_H_ #include <stdint.h> @@ -38,14 +38,14 @@ // Wraps DRM calls into a nice interface. Used to provide different // implementations of the DRM calls. For the actual implementation the DRM API // would be called. In unit tests this interface would be stubbed. -class OZONE_EXPORT DriWrapper : public base::RefCountedThreadSafe<DriWrapper> { +class OZONE_EXPORT DrmDevice : public base::RefCountedThreadSafe<DrmDevice> { public: typedef base::Callback<void(unsigned int /* frame */, unsigned int /* seconds */, unsigned int /* useconds */)> PageFlipCallback; - DriWrapper(const base::FilePath& device_path); - DriWrapper(const base::FilePath& device_path, base::File file); + DrmDevice(const base::FilePath& device_path); + DrmDevice(const base::FilePath& device_path, base::File file); // Open device. virtual bool Initialize(); @@ -141,7 +141,6 @@ uint32_t handle, const gfx::Size& size); - // Move the cursor on CRTC |crtc_id| to (x, y); virtual bool MoveCursor(uint32_t crtc_id, const gfx::Point& point); @@ -166,9 +165,9 @@ HardwareDisplayPlaneManager* plane_manager() { return plane_manager_.get(); } protected: - friend class base::RefCountedThreadSafe<DriWrapper>; + friend class base::RefCountedThreadSafe<DrmDevice>; - virtual ~DriWrapper(); + virtual ~DrmDevice(); scoped_ptr<HardwareDisplayPlaneManager> plane_manager_; @@ -187,9 +186,9 @@ // Watcher for |fd_| listening for page flip events. scoped_refptr<IOWatcher> watcher_; - DISALLOW_COPY_AND_ASSIGN(DriWrapper); + DISALLOW_COPY_AND_ASSIGN(DrmDevice); }; } // namespace ui -#endif // UI_OZONE_PLATFORM_DRI_DRI_WRAPPER_H_ +#endif // UI_OZONE_PLATFORM_DRI_DRM_DEVICE_H_
diff --git a/ui/ozone/platform/dri/drm_device_generator.cc b/ui/ozone/platform/dri/drm_device_generator.cc index 13985db..f6f6f33 100644 --- a/ui/ozone/platform/dri/drm_device_generator.cc +++ b/ui/ozone/platform/dri/drm_device_generator.cc
@@ -4,7 +4,7 @@ #include "ui/ozone/platform/dri/drm_device_generator.h" -#include "ui/ozone/platform/dri/dri_wrapper.h" +#include "ui/ozone/platform/dri/drm_device.h" namespace ui { @@ -14,10 +14,10 @@ DrmDeviceGenerator::~DrmDeviceGenerator() { } -scoped_refptr<DriWrapper> DrmDeviceGenerator::CreateDevice( +scoped_refptr<DrmDevice> DrmDeviceGenerator::CreateDevice( const base::FilePath& device_path, base::File file) { - scoped_refptr<DriWrapper> drm = new DriWrapper(device_path, file.Pass()); + scoped_refptr<DrmDevice> drm = new DrmDevice(device_path, file.Pass()); if (drm->Initialize()) return drm;
diff --git a/ui/ozone/platform/dri/drm_device_generator.h b/ui/ozone/platform/dri/drm_device_generator.h index acd25c02..8d59f72 100644 --- a/ui/ozone/platform/dri/drm_device_generator.h +++ b/ui/ozone/platform/dri/drm_device_generator.h
@@ -10,7 +10,7 @@ namespace ui { -class DriWrapper; +class DrmDevice; class DrmDeviceGenerator { public: @@ -19,7 +19,7 @@ // Creates a DRM device for |file|. |device_path| describes the location of // the DRM device. - virtual scoped_refptr<DriWrapper> CreateDevice( + virtual scoped_refptr<DrmDevice> CreateDevice( const base::FilePath& device_path, base::File file);
diff --git a/ui/ozone/platform/dri/drm_device_manager.cc b/ui/ozone/platform/dri/drm_device_manager.cc index 5bbfd94e..d04aee0 100644 --- a/ui/ozone/platform/dri/drm_device_manager.cc +++ b/ui/ozone/platform/dri/drm_device_manager.cc
@@ -4,12 +4,12 @@ #include "ui/ozone/platform/dri/drm_device_manager.h" -#include "ui/ozone/platform/dri/dri_wrapper.h" +#include "ui/ozone/platform/dri/drm_device.h" namespace ui { DrmDeviceManager::DrmDeviceManager( - const scoped_refptr<DriWrapper>& primary_device) + const scoped_refptr<DrmDevice>& primary_device) : primary_device_(primary_device) { } @@ -17,9 +17,8 @@ DCHECK(drm_device_map_.empty()); } -void DrmDeviceManager::UpdateDrmDevice( - gfx::AcceleratedWidget widget, - const scoped_refptr<DriWrapper>& device) { +void DrmDeviceManager::UpdateDrmDevice(gfx::AcceleratedWidget widget, + const scoped_refptr<DrmDevice>& device) { base::AutoLock lock(lock_); drm_device_map_[widget] = device; } @@ -31,7 +30,7 @@ drm_device_map_.erase(it); } -scoped_refptr<DriWrapper> DrmDeviceManager::GetDrmDevice( +scoped_refptr<DrmDevice> DrmDeviceManager::GetDrmDevice( gfx::AcceleratedWidget widget) { base::AutoLock lock(lock_); if (widget == gfx::kNullAcceleratedWidget)
diff --git a/ui/ozone/platform/dri/drm_device_manager.h b/ui/ozone/platform/dri/drm_device_manager.h index 03133abb..5a7431e 100644 --- a/ui/ozone/platform/dri/drm_device_manager.h +++ b/ui/ozone/platform/dri/drm_device_manager.h
@@ -14,28 +14,28 @@ namespace ui { -class DriWrapper; +class DrmDevice; // Tracks the mapping between widgets and the DRM devices used to allocate // buffers for the window represented by the widget. class OZONE_EXPORT DrmDeviceManager { public: - DrmDeviceManager(const scoped_refptr<DriWrapper>& primary_device); + DrmDeviceManager(const scoped_refptr<DrmDevice>& primary_device); ~DrmDeviceManager(); // Updates the device associated with |widget|. void UpdateDrmDevice(gfx::AcceleratedWidget widget, - const scoped_refptr<DriWrapper>& device); + const scoped_refptr<DrmDevice>& device); // Removes the device associated with |widget|. void RemoveDrmDevice(gfx::AcceleratedWidget widget); // Returns the device associated with |widget|. If there is no association // returns |primary_device_|. - scoped_refptr<DriWrapper> GetDrmDevice(gfx::AcceleratedWidget widget); + scoped_refptr<DrmDevice> GetDrmDevice(gfx::AcceleratedWidget widget); private: - std::map<gfx::AcceleratedWidget, scoped_refptr<DriWrapper>> drm_device_map_; + std::map<gfx::AcceleratedWidget, scoped_refptr<DrmDevice>> drm_device_map_; // This device represents the primary graphics device and is used when: // 1) 'widget == kNullAcceleratedWidget' when the API requesting a buffer has @@ -43,7 +43,7 @@ // for video buffers), or // 2) in order to allocate buffers for unmatched surfaces (surfaces without a // display; ie: when in headless mode). - scoped_refptr<DriWrapper> primary_device_; + scoped_refptr<DrmDevice> primary_device_; // This class is accessed from the main thread and the IO thread. This lock // protects access to the device map.
diff --git a/ui/ozone/platform/dri/gbm.gypi b/ui/ozone/platform/dri/gbm.gypi index f59833b61..19d3a0d2 100644 --- a/ui/ozone/platform/dri/gbm.gypi +++ b/ui/ozone/platform/dri/gbm.gypi
@@ -37,14 +37,14 @@ 'gbm_buffer.h', 'gbm_buffer_base.cc', 'gbm_buffer_base.h', + 'gbm_device.cc', + 'gbm_device.h', 'gbm_surface.cc', 'gbm_surface.h', 'gbm_surface_factory.cc', 'gbm_surface_factory.h', 'gbm_surfaceless.cc', 'gbm_surfaceless.h', - 'gbm_wrapper.cc', - 'gbm_wrapper.h', 'ozone_platform_gbm.cc', 'ozone_platform_gbm.h', ],
diff --git a/ui/ozone/platform/dri/gbm_buffer.cc b/ui/ozone/platform/dri/gbm_buffer.cc index 371e9ab..30f0ad85 100644 --- a/ui/ozone/platform/dri/gbm_buffer.cc +++ b/ui/ozone/platform/dri/gbm_buffer.cc
@@ -11,7 +11,7 @@ #include "base/logging.h" #include "base/trace_event/trace_event.h" -#include "ui/ozone/platform/dri/gbm_wrapper.h" +#include "ui/ozone/platform/dri/gbm_device.h" namespace ui { @@ -31,7 +31,7 @@ } // namespace -GbmBuffer::GbmBuffer(const scoped_refptr<GbmWrapper>& gbm, +GbmBuffer::GbmBuffer(const scoped_refptr<GbmDevice>& gbm, gbm_bo* bo, bool scanout) : GbmBufferBase(gbm, bo, scanout) { @@ -44,7 +44,7 @@ // static scoped_refptr<GbmBuffer> GbmBuffer::CreateBuffer( - const scoped_refptr<GbmWrapper>& gbm, + const scoped_refptr<GbmDevice>& gbm, SurfaceFactoryOzone::BufferFormat format, const gfx::Size& size, bool scanout) {
diff --git a/ui/ozone/platform/dri/gbm_buffer.h b/ui/ozone/platform/dri/gbm_buffer.h index 2af83de..7e34068d1 100644 --- a/ui/ozone/platform/dri/gbm_buffer.h +++ b/ui/ozone/platform/dri/gbm_buffer.h
@@ -16,18 +16,18 @@ namespace ui { -class GbmWrapper; +class GbmDevice; class GbmBuffer : public GbmBufferBase { public: static scoped_refptr<GbmBuffer> CreateBuffer( - const scoped_refptr<GbmWrapper>& gbm, + const scoped_refptr<GbmDevice>& gbm, SurfaceFactoryOzone::BufferFormat format, const gfx::Size& size, bool scanout); private: - GbmBuffer(const scoped_refptr<GbmWrapper>& gbm, gbm_bo* bo, bool scanout); + GbmBuffer(const scoped_refptr<GbmDevice>& gbm, gbm_bo* bo, bool scanout); ~GbmBuffer() override; DISALLOW_COPY_AND_ASSIGN(GbmBuffer);
diff --git a/ui/ozone/platform/dri/gbm_buffer_base.cc b/ui/ozone/platform/dri/gbm_buffer_base.cc index c4b69ff..ca835e3 100644 --- a/ui/ozone/platform/dri/gbm_buffer_base.cc +++ b/ui/ozone/platform/dri/gbm_buffer_base.cc
@@ -7,7 +7,7 @@ #include <gbm.h> #include "base/logging.h" -#include "ui/ozone/platform/dri/dri_wrapper.h" +#include "ui/ozone/platform/dri/drm_device.h" namespace ui { @@ -21,23 +21,20 @@ } // namespace -GbmBufferBase::GbmBufferBase(const scoped_refptr<DriWrapper>& dri, +GbmBufferBase::GbmBufferBase(const scoped_refptr<DrmDevice>& drm, gbm_bo* bo, bool scanout) - : dri_(dri), bo_(bo), framebuffer_(0) { - if (scanout && !dri_->AddFramebuffer(gbm_bo_get_width(bo), - gbm_bo_get_height(bo), - kColorDepth, - kPixelDepth, - gbm_bo_get_stride(bo), - gbm_bo_get_handle(bo).u32, - &framebuffer_)) + : drm_(drm), bo_(bo), framebuffer_(0) { + if (scanout && + !drm_->AddFramebuffer(gbm_bo_get_width(bo), gbm_bo_get_height(bo), + kColorDepth, kPixelDepth, gbm_bo_get_stride(bo), + gbm_bo_get_handle(bo).u32, &framebuffer_)) LOG(ERROR) << "Failed to register buffer"; } GbmBufferBase::~GbmBufferBase() { if (framebuffer_) - dri_->RemoveFramebuffer(framebuffer_); + drm_->RemoveFramebuffer(framebuffer_); } uint32_t GbmBufferBase::GetFramebufferId() const {
diff --git a/ui/ozone/platform/dri/gbm_buffer_base.h b/ui/ozone/platform/dri/gbm_buffer_base.h index 7f79f86..9152483 100644 --- a/ui/ozone/platform/dri/gbm_buffer_base.h +++ b/ui/ozone/platform/dri/gbm_buffer_base.h
@@ -11,7 +11,7 @@ namespace ui { -class DriWrapper; +class DrmDevice; // Wrapper for a GBM buffer. The base class provides common functionality // required to prepare the buffer for scanout. It does not provide any ownership @@ -27,11 +27,11 @@ gfx::Size GetSize() const override; protected: - GbmBufferBase(const scoped_refptr<DriWrapper>& dri, gbm_bo* bo, bool scanout); + GbmBufferBase(const scoped_refptr<DrmDevice>& drm, gbm_bo* bo, bool scanout); ~GbmBufferBase() override; private: - scoped_refptr<DriWrapper> dri_; + scoped_refptr<DrmDevice> drm_; gbm_bo* bo_; uint32_t framebuffer_;
diff --git a/ui/ozone/platform/dri/gbm_device.cc b/ui/ozone/platform/dri/gbm_device.cc new file mode 100644 index 0000000..e726c2f --- /dev/null +++ b/ui/ozone/platform/dri/gbm_device.cc
@@ -0,0 +1,37 @@ +// 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/ozone/platform/dri/gbm_device.h" + +#include <gbm.h> + +namespace ui { + +GbmDevice::GbmDevice(const base::FilePath& device_path) + : DrmDevice(device_path), device_(nullptr) { +} + +GbmDevice::GbmDevice(const base::FilePath& device_path, base::File file) + : DrmDevice(device_path, file.Pass()), device_(nullptr) { +} + +GbmDevice::~GbmDevice() { + if (device_) + gbm_device_destroy(device_); +} + +bool GbmDevice::Initialize() { + if (!DrmDevice::Initialize()) + return false; + + device_ = gbm_create_device(get_fd()); + if (!device_) { + LOG(ERROR) << "Unable to initialize GBM"; + return false; + } + + return true; +} + +} // namespace ui
diff --git a/ui/ozone/platform/dri/gbm_device.h b/ui/ozone/platform/dri/gbm_device.h new file mode 100644 index 0000000..da884e5 --- /dev/null +++ b/ui/ozone/platform/dri/gbm_device.h
@@ -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. + +#ifndef UI_OZONE_PLATFORM_DRI_GBM_DEVICE_H_ +#define UI_OZONE_PLATFORM_DRI_GBM_DEVICE_H_ + +#include "ui/ozone/platform/dri/drm_device.h" + +struct gbm_device; + +namespace ui { + +class GbmDevice : public DrmDevice { + public: + GbmDevice(const base::FilePath& device_path); + GbmDevice(const base::FilePath& device_path, base::File file); + ~GbmDevice() override; + + gbm_device* device() const { return device_; } + + // DrmDevice implementation: + bool Initialize() override; + + private: + gbm_device* device_; + + DISALLOW_COPY_AND_ASSIGN(GbmDevice); +}; + +} // namespace ui + +#endif // UI_OZONE_PLATFORM_DRI_GBM_DEVICE_H_
diff --git a/ui/ozone/platform/dri/gbm_surface.cc b/ui/ozone/platform/dri/gbm_surface.cc index e3b6252..ab8e5e3 100644 --- a/ui/ozone/platform/dri/gbm_surface.cc +++ b/ui/ozone/platform/dri/gbm_surface.cc
@@ -11,7 +11,7 @@ #include "ui/ozone/platform/dri/dri_buffer.h" #include "ui/ozone/platform/dri/dri_window_delegate.h" #include "ui/ozone/platform/dri/gbm_buffer_base.h" -#include "ui/ozone/platform/dri/gbm_wrapper.h" +#include "ui/ozone/platform/dri/gbm_device.h" #include "ui/ozone/platform/dri/hardware_display_controller.h" #include "ui/ozone/platform/dri/scanout_buffer.h" @@ -22,12 +22,12 @@ class GbmSurfaceBuffer : public GbmBufferBase { public: static scoped_refptr<GbmSurfaceBuffer> CreateBuffer( - const scoped_refptr<DriWrapper>& dri, + const scoped_refptr<DrmDevice>& drm, gbm_bo* buffer); static scoped_refptr<GbmSurfaceBuffer> GetBuffer(gbm_bo* buffer); private: - GbmSurfaceBuffer(const scoped_refptr<DriWrapper>& dri, gbm_bo* bo); + GbmSurfaceBuffer(const scoped_refptr<DrmDevice>& drm, gbm_bo* bo); ~GbmSurfaceBuffer() override; static void Destroy(gbm_bo* buffer, void* data); @@ -42,9 +42,9 @@ DISALLOW_COPY_AND_ASSIGN(GbmSurfaceBuffer); }; -GbmSurfaceBuffer::GbmSurfaceBuffer(const scoped_refptr<DriWrapper>& dri, +GbmSurfaceBuffer::GbmSurfaceBuffer(const scoped_refptr<DrmDevice>& drm, gbm_bo* bo) - : GbmBufferBase(dri, bo, true) { + : GbmBufferBase(drm, bo, true) { if (GetFramebufferId()) { self_ = this; gbm_bo_set_user_data(bo, this, GbmSurfaceBuffer::Destroy); @@ -55,10 +55,10 @@ // static scoped_refptr<GbmSurfaceBuffer> GbmSurfaceBuffer::CreateBuffer( - const scoped_refptr<DriWrapper>& dri, + const scoped_refptr<DrmDevice>& drm, gbm_bo* buffer) { - scoped_refptr<GbmSurfaceBuffer> scoped_buffer(new GbmSurfaceBuffer(dri, - buffer)); + scoped_refptr<GbmSurfaceBuffer> scoped_buffer( + new GbmSurfaceBuffer(drm, buffer)); if (!scoped_buffer->GetFramebufferId()) return NULL; @@ -80,7 +80,7 @@ } // namespace GbmSurface::GbmSurface(DriWindowDelegate* window_delegate, - const scoped_refptr<GbmWrapper>& gbm) + const scoped_refptr<GbmDevice>& gbm) : GbmSurfaceless(window_delegate, NULL), gbm_(gbm), native_surface_(NULL),
diff --git a/ui/ozone/platform/dri/gbm_surface.h b/ui/ozone/platform/dri/gbm_surface.h index e0e3c47..c549d9a 100644 --- a/ui/ozone/platform/dri/gbm_surface.h +++ b/ui/ozone/platform/dri/gbm_surface.h
@@ -18,7 +18,7 @@ class DriBuffer; class DriWindowDelegate; -class GbmWrapper; +class GbmDevice; // Extends the GBM surfaceless functionality and adds an implicit surface for // the primary plane. Arbitrary buffers can still be allocated and displayed as @@ -27,7 +27,7 @@ class GbmSurface : public GbmSurfaceless { public: GbmSurface(DriWindowDelegate* window_delegate, - const scoped_refptr<GbmWrapper>& gbm); + const scoped_refptr<GbmDevice>& gbm); ~GbmSurface() override; bool Initialize(); @@ -42,7 +42,7 @@ void OnSwapBuffersCallback(const SwapCompletionCallback& callback, gbm_bo* pending_buffer); - scoped_refptr<GbmWrapper> gbm_; + scoped_refptr<GbmDevice> gbm_; // The native GBM surface. In EGL this represents the EGLNativeWindowType. gbm_surface* native_surface_;
diff --git a/ui/ozone/platform/dri/gbm_surface_factory.cc b/ui/ozone/platform/dri/gbm_surface_factory.cc index 2017535..b9c8f9f 100644 --- a/ui/ozone/platform/dri/gbm_surface_factory.cc +++ b/ui/ozone/platform/dri/gbm_surface_factory.cc
@@ -14,13 +14,14 @@ #include "ui/ozone/platform/dri/dri_window_delegate_manager.h" #include "ui/ozone/platform/dri/drm_device_manager.h" #include "ui/ozone/platform/dri/gbm_buffer.h" +#include "ui/ozone/platform/dri/gbm_device.h" #include "ui/ozone/platform/dri/gbm_surface.h" #include "ui/ozone/platform/dri/gbm_surfaceless.h" -#include "ui/ozone/platform/dri/gbm_wrapper.h" #include "ui/ozone/platform/dri/hardware_display_controller.h" #include "ui/ozone/public/native_pixmap.h" #include "ui/ozone/public/overlay_candidates_ozone.h" #include "ui/ozone/public/ozone_switches.h" +#include "ui/ozone/public/surface_ozone_canvas.h" #include "ui/ozone/public/surface_ozone_egl.h" namespace ui { @@ -92,7 +93,7 @@ } int GbmSurfaceFactory::GetDrmFd() { - scoped_refptr<GbmWrapper> gbm = GetGbmDevice(gfx::kNullAcceleratedWidget); + scoped_refptr<GbmDevice> gbm = GetGbmDevice(gfx::kNullAcceleratedWidget); DCHECK(gbm); return gbm->get_fd(); } @@ -119,9 +120,15 @@ return LoadDefaultEGLGLES2Bindings(add_gl_library, set_gl_get_proc_address); } +scoped_ptr<SurfaceOzoneCanvas> GbmSurfaceFactory::CreateCanvasForWidget( + gfx::AcceleratedWidget widget) { + LOG(FATAL) << "Software rendering mode is not supported with GBM platform"; + return nullptr; +} + scoped_ptr<SurfaceOzoneEGL> GbmSurfaceFactory::CreateEGLSurfaceForWidget( gfx::AcceleratedWidget widget) { - scoped_refptr<GbmWrapper> gbm = GetGbmDevice(widget); + scoped_refptr<GbmDevice> gbm = GetGbmDevice(widget); DCHECK(gbm); scoped_ptr<GbmSurface> surface( @@ -150,7 +157,7 @@ if (usage == MAP) return nullptr; - scoped_refptr<GbmWrapper> gbm = GetGbmDevice(widget); + scoped_refptr<GbmDevice> gbm = GetGbmDevice(widget); DCHECK(gbm); scoped_refptr<GbmBuffer> buffer = @@ -213,9 +220,9 @@ return false; } -scoped_refptr<GbmWrapper> GbmSurfaceFactory::GetGbmDevice( +scoped_refptr<GbmDevice> GbmSurfaceFactory::GetGbmDevice( gfx::AcceleratedWidget widget) { - return static_cast<GbmWrapper*>( + return static_cast<GbmDevice*>( drm_device_manager_->GetDrmDevice(widget).get()); }
diff --git a/ui/ozone/platform/dri/gbm_surface_factory.h b/ui/ozone/platform/dri/gbm_surface_factory.h index 1b913c0..7b10b08 100644 --- a/ui/ozone/platform/dri/gbm_surface_factory.h +++ b/ui/ozone/platform/dri/gbm_surface_factory.h
@@ -12,7 +12,7 @@ class DriWindowDelegate; class DriWindowDelegateManager; class DrmDeviceManager; -class GbmWrapper; +class GbmDevice; class GbmSurfaceFactory : public DriSurfaceFactory { public: @@ -29,6 +29,8 @@ bool LoadEGLGLES2Bindings( AddGLLibraryCallback add_gl_library, SetGLGetProcAddressProcCallback set_gl_get_proc_address) override; + scoped_ptr<SurfaceOzoneCanvas> CreateCanvasForWidget( + gfx::AcceleratedWidget widget) override; scoped_ptr<ui::SurfaceOzoneEGL> CreateEGLSurfaceForWidget( gfx::AcceleratedWidget w) override; scoped_ptr<SurfaceOzoneEGL> CreateSurfacelessEGLSurfaceForWidget( @@ -50,7 +52,7 @@ bool CanCreateNativePixmap(BufferUsage usage) override; private: - scoped_refptr<GbmWrapper> GetGbmDevice(gfx::AcceleratedWidget widget); + scoped_refptr<GbmDevice> GetGbmDevice(gfx::AcceleratedWidget widget); bool allow_surfaceless_;
diff --git a/ui/ozone/platform/dri/gbm_surfaceless.cc b/ui/ozone/platform/dri/gbm_surfaceless.cc index 6745a20..30e18e7 100644 --- a/ui/ozone/platform/dri/gbm_surfaceless.cc +++ b/ui/ozone/platform/dri/gbm_surfaceless.cc
@@ -8,7 +8,7 @@ #include "base/bind_helpers.h" #include "ui/ozone/platform/dri/dri_vsync_provider.h" #include "ui/ozone/platform/dri/dri_window_delegate.h" -#include "ui/ozone/platform/dri/dri_wrapper.h" +#include "ui/ozone/platform/dri/drm_device.h" #include "ui/ozone/platform/dri/drm_device_manager.h" #include "ui/ozone/platform/dri/gbm_buffer.h" #include "ui/ozone/platform/dri/hardware_display_controller.h" @@ -59,14 +59,14 @@ bool GbmSurfaceless::IsUniversalDisplayLinkDevice() { if (!drm_device_manager_) return false; - scoped_refptr<DriWrapper> drm_primary = + scoped_refptr<DrmDevice> drm_primary = drm_device_manager_->GetDrmDevice(gfx::kNullAcceleratedWidget); DCHECK(drm_primary); HardwareDisplayController* controller = window_delegate_->GetController(); if (!controller) return false; - scoped_refptr<DriWrapper> drm = controller->GetAllocationDriWrapper(); + scoped_refptr<DrmDevice> drm = controller->GetAllocationDrmDevice(); DCHECK(drm); return drm_primary != drm;
diff --git a/ui/ozone/platform/dri/gbm_wrapper.cc b/ui/ozone/platform/dri/gbm_wrapper.cc deleted file mode 100644 index e0d1f17..0000000 --- a/ui/ozone/platform/dri/gbm_wrapper.cc +++ /dev/null
@@ -1,37 +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 "ui/ozone/platform/dri/gbm_wrapper.h" - -#include <gbm.h> - -namespace ui { - -GbmWrapper::GbmWrapper(const base::FilePath& device_path) - : DriWrapper(device_path), device_(nullptr) { -} - -GbmWrapper::GbmWrapper(const base::FilePath& device_path, base::File file) - : DriWrapper(device_path, file.Pass()), device_(nullptr) { -} - -GbmWrapper::~GbmWrapper() { - if (device_) - gbm_device_destroy(device_); -} - -bool GbmWrapper::Initialize() { - if (!DriWrapper::Initialize()) - return false; - - device_ = gbm_create_device(get_fd()); - if (!device_) { - LOG(ERROR) << "Unable to initialize GBM"; - return false; - } - - return true; -} - -} // namespace ui
diff --git a/ui/ozone/platform/dri/gbm_wrapper.h b/ui/ozone/platform/dri/gbm_wrapper.h deleted file mode 100644 index 3df2550..0000000 --- a/ui/ozone/platform/dri/gbm_wrapper.h +++ /dev/null
@@ -1,34 +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 UI_OZONE_PLATFORM_DRI_GBM_WRAPPER_H_ -#define UI_OZONE_PLATFORM_DRI_GBM_WRAPPER_H_ - -#include "ui/ozone/platform/dri/dri_wrapper.h" - -struct gbm_device; - -namespace ui { - -class GbmWrapper : public DriWrapper { - public: - GbmWrapper(const base::FilePath& device_path); - GbmWrapper(const base::FilePath& device_path, base::File file); - - gbm_device* device() const { return device_; } - - // DriWrapper implementation: - bool Initialize() override; - - private: - ~GbmWrapper() override; - - gbm_device* device_; - - DISALLOW_COPY_AND_ASSIGN(GbmWrapper); -}; - -} // namespace ui - -#endif // UI_OZONE_PLATFORM_DRI_GBM_WRAPPER_H_
diff --git a/ui/ozone/platform/dri/hardware_display_controller.cc b/ui/ozone/platform/dri/hardware_display_controller.cc index faee6e6..0615067 100644 --- a/ui/ozone/platform/dri/hardware_display_controller.cc +++ b/ui/ozone/platform/dri/hardware_display_controller.cc
@@ -17,7 +17,7 @@ #include "ui/gfx/geometry/size.h" #include "ui/ozone/platform/dri/crtc_controller.h" #include "ui/ozone/platform/dri/dri_buffer.h" -#include "ui/ozone/platform/dri/dri_wrapper.h" +#include "ui/ozone/platform/dri/drm_device.h" #include "ui/ozone/public/native_pixmap.h" namespace ui { @@ -157,7 +157,7 @@ } scoped_ptr<CrtcController> HardwareDisplayController::RemoveCrtc( - const scoped_refptr<DriWrapper>& drm, + const scoped_refptr<DrmDevice>& drm, uint32_t crtc) { for (ScopedVector<CrtcController>::iterator it = crtc_controllers_.begin(); it != crtc_controllers_.end(); ++it) { @@ -191,7 +191,7 @@ return nullptr; } -bool HardwareDisplayController::HasCrtc(const scoped_refptr<DriWrapper>& drm, +bool HardwareDisplayController::HasCrtc(const scoped_refptr<DrmDevice>& drm, uint32_t crtc) const { for (size_t i = 0; i < crtc_controllers_.size(); ++i) if (crtc_controllers_[i]->drm() == drm && @@ -260,7 +260,7 @@ } } -scoped_refptr<DriWrapper> HardwareDisplayController::GetAllocationDriWrapper() +scoped_refptr<DrmDevice> HardwareDisplayController::GetAllocationDrmDevice() const { DCHECK(!crtc_controllers_.empty()); // TODO(dnicoara) When we support mirroring across DRM devices, figure out
diff --git a/ui/ozone/platform/dri/hardware_display_controller.h b/ui/ozone/platform/dri/hardware_display_controller.h index 7f015a5..e32ba63 100644 --- a/ui/ozone/platform/dri/hardware_display_controller.h +++ b/ui/ozone/platform/dri/hardware_display_controller.h
@@ -31,7 +31,7 @@ class CrtcController; class ScanoutBuffer; -class DriWrapper; +class DrmDevice; // The HDCOz will handle modesettings and scannout operations for hardware // devices. @@ -134,9 +134,9 @@ bool MoveCursor(const gfx::Point& location); void AddCrtc(scoped_ptr<CrtcController> controller); - scoped_ptr<CrtcController> RemoveCrtc(const scoped_refptr<DriWrapper>& drm, + scoped_ptr<CrtcController> RemoveCrtc(const scoped_refptr<DrmDevice>& drm, uint32_t crtc); - bool HasCrtc(const scoped_refptr<DriWrapper>& drm, uint32_t crtc) const; + bool HasCrtc(const scoped_refptr<DrmDevice>& drm, uint32_t crtc) const; bool IsMirrored() const; bool IsDisabled() const; gfx::Size GetModeSize() const; @@ -152,7 +152,7 @@ return crtc_controllers_.get(); } - scoped_refptr<DriWrapper> GetAllocationDriWrapper() const; + scoped_refptr<DrmDevice> GetAllocationDrmDevice() const; private: // Returns true if any of the CRTCs is waiting for a page flip. @@ -185,7 +185,7 @@ std::deque<PageFlipRequest> requests_; scoped_refptr<ScanoutBuffer> cursor_buffer_; - base::ScopedPtrHashMap<DriWrapper*, HardwareDisplayPlaneList> + base::ScopedPtrHashMap<DrmDevice*, HardwareDisplayPlaneList> owned_hardware_planes_; // Stores the CRTC configuration. This is used to identify monitors and
diff --git a/ui/ozone/platform/dri/hardware_display_controller_unittest.cc b/ui/ozone/platform/dri/hardware_display_controller_unittest.cc index 6a20ac121..f63c136 100644 --- a/ui/ozone/platform/dri/hardware_display_controller_unittest.cc +++ b/ui/ozone/platform/dri/hardware_display_controller_unittest.cc
@@ -7,9 +7,9 @@ #include "third_party/skia/include/core/SkCanvas.h" #include "ui/ozone/platform/dri/crtc_controller.h" #include "ui/ozone/platform/dri/dri_buffer.h" -#include "ui/ozone/platform/dri/dri_wrapper.h" +#include "ui/ozone/platform/dri/drm_device.h" #include "ui/ozone/platform/dri/hardware_display_controller.h" -#include "ui/ozone/platform/dri/test/mock_dri_wrapper.h" +#include "ui/ozone/platform/dri/test/mock_drm_device.h" #include "ui/ozone/public/native_pixmap.h" namespace { @@ -58,7 +58,7 @@ protected: scoped_ptr<ui::HardwareDisplayController> controller_; - scoped_refptr<ui::MockDriWrapper> drm_; + scoped_refptr<ui::MockDrmDevice> drm_; int page_flips_; @@ -70,7 +70,7 @@ std::vector<uint32_t> crtcs; crtcs.push_back(kPrimaryCrtc); crtcs.push_back(kSecondaryCrtc); - drm_ = new ui::MockDriWrapper(false, crtcs, kPlanesPerCrtc); + drm_ = new ui::MockDrmDevice(false, crtcs, kPlanesPerCrtc); controller_.reset(new ui::HardwareDisplayController( scoped_ptr<ui::CrtcController>(new ui::CrtcController( drm_.get(), kPrimaryCrtc, kPrimaryConnector))));
diff --git a/ui/ozone/platform/dri/hardware_display_plane.cc b/ui/ozone/platform/dri/hardware_display_plane.cc index 89bc882..cb50c6c 100644 --- a/ui/ozone/platform/dri/hardware_display_plane.cc +++ b/ui/ozone/platform/dri/hardware_display_plane.cc
@@ -10,7 +10,7 @@ #include "base/logging.h" #include "ui/gfx/geometry/rect.h" -#include "ui/ozone/platform/dri/dri_wrapper.h" +#include "ui/ozone/platform/dri/drm_device.h" namespace ui { @@ -33,7 +33,7 @@ return possible_crtcs_ & (1 << crtc_index); } -bool HardwareDisplayPlane::Initialize(DriWrapper* drm) { +bool HardwareDisplayPlane::Initialize(DrmDevice* drm) { return true; }
diff --git a/ui/ozone/platform/dri/hardware_display_plane.h b/ui/ozone/platform/dri/hardware_display_plane.h index e8589317..2fffae4 100644 --- a/ui/ozone/platform/dri/hardware_display_plane.h +++ b/ui/ozone/platform/dri/hardware_display_plane.h
@@ -18,7 +18,7 @@ namespace ui { -class DriWrapper; +class DrmDevice; class OZONE_EXPORT HardwareDisplayPlane { public: @@ -27,7 +27,7 @@ virtual ~HardwareDisplayPlane(); - bool Initialize(DriWrapper* drm); + bool Initialize(DrmDevice* drm); bool CanUseForCrtc(uint32_t crtc_index);
diff --git a/ui/ozone/platform/dri/hardware_display_plane_manager.cc b/ui/ozone/platform/dri/hardware_display_plane_manager.cc index 2a8b7cc..0c0b321c 100644 --- a/ui/ozone/platform/dri/hardware_display_plane_manager.cc +++ b/ui/ozone/platform/dri/hardware_display_plane_manager.cc
@@ -11,7 +11,7 @@ #include "base/logging.h" #include "ui/gfx/geometry/rect.h" #include "ui/ozone/platform/dri/crtc_controller.h" -#include "ui/ozone/platform/dri/dri_wrapper.h" +#include "ui/ozone/platform/dri/drm_device.h" #include "ui/ozone/platform/dri/hardware_display_controller.h" #include "ui/ozone/platform/dri/scanout_buffer.h" #include "ui/ozone/public/ozone_switches.h" @@ -65,7 +65,7 @@ HardwareDisplayPlaneManager::~HardwareDisplayPlaneManager() { } -bool HardwareDisplayPlaneManager::Initialize(DriWrapper* drm) { +bool HardwareDisplayPlaneManager::Initialize(DrmDevice* drm) { drm_ = drm; ScopedDrmResourcesPtr resources(drmModeGetResources(drm->get_fd())); if (!resources) {
diff --git a/ui/ozone/platform/dri/hardware_display_plane_manager.h b/ui/ozone/platform/dri/hardware_display_plane_manager.h index d25b7d5f..49593e0 100644 --- a/ui/ozone/platform/dri/hardware_display_plane_manager.h +++ b/ui/ozone/platform/dri/hardware_display_plane_manager.h
@@ -23,7 +23,7 @@ namespace ui { -class DriWrapper; +class DrmDevice; class CrtcController; // This contains the list of planes controlled by one HDC on a given DRM fd. @@ -77,7 +77,7 @@ // This parses information from the drm driver, adding any new planes // or crtcs found. - bool Initialize(DriWrapper* drm); + bool Initialize(DrmDevice* drm); // Assign hardware planes from the |planes_| list to |overlay_list| entries, // recording the plane IDs in the |plane_list|. Only planes compatible with @@ -112,7 +112,7 @@ // Object containing the connection to the graphics device and wraps the API // calls to control it. Not owned. - DriWrapper* drm_; + DrmDevice* drm_; ScopedVector<HardwareDisplayPlane> planes_; std::vector<uint32_t> crtcs_;
diff --git a/ui/ozone/platform/dri/hardware_display_plane_manager_legacy.cc b/ui/ozone/platform/dri/hardware_display_plane_manager_legacy.cc index 3853ff5..b41f456 100644 --- a/ui/ozone/platform/dri/hardware_display_plane_manager_legacy.cc +++ b/ui/ozone/platform/dri/hardware_display_plane_manager_legacy.cc
@@ -6,7 +6,7 @@ #include "base/bind.h" #include "ui/ozone/platform/dri/crtc_controller.h" -#include "ui/ozone/platform/dri/dri_wrapper.h" +#include "ui/ozone/platform/dri/drm_device.h" #include "ui/ozone/platform/dri/scanout_buffer.h" namespace ui {
diff --git a/ui/ozone/platform/dri/hardware_display_plane_manager_unittest.cc b/ui/ozone/platform/dri/hardware_display_plane_manager_unittest.cc index 7e5dade..5ee02543 100644 --- a/ui/ozone/platform/dri/hardware_display_plane_manager_unittest.cc +++ b/ui/ozone/platform/dri/hardware_display_plane_manager_unittest.cc
@@ -13,7 +13,7 @@ #include "ui/ozone/platform/dri/hardware_display_plane_manager_legacy.h" #include "ui/ozone/platform/dri/overlay_plane.h" #include "ui/ozone/platform/dri/scanout_buffer.h" -#include "ui/ozone/platform/dri/test/mock_dri_wrapper.h" +#include "ui/ozone/platform/dri/test/mock_drm_device.h" namespace { @@ -232,8 +232,7 @@ TEST(HardwareDisplayPlaneManagerLegacyTest, UnusedPlanesAreReleased) { std::vector<uint32_t> crtcs; crtcs.push_back(100); - scoped_refptr<ui::MockDriWrapper> drm = - new ui::MockDriWrapper(false, crtcs, 2); + scoped_refptr<ui::MockDrmDevice> drm = new ui::MockDrmDevice(false, crtcs, 2); ui::OverlayPlaneList assigns; scoped_refptr<FakeScanoutBuffer> fake_buffer = new FakeScanoutBuffer(); assigns.push_back(ui::OverlayPlane(fake_buffer));
diff --git a/ui/ozone/platform/dri/native_display_delegate_dri.cc b/ui/ozone/platform/dri/native_display_delegate_dri.cc index af18bb59..b6dedffda 100644 --- a/ui/ozone/platform/dri/native_display_delegate_dri.cc +++ b/ui/ozone/platform/dri/native_display_delegate_dri.cc
@@ -15,7 +15,7 @@ #include "ui/ozone/platform/dri/display_mode_dri.h" #include "ui/ozone/platform/dri/display_snapshot_dri.h" #include "ui/ozone/platform/dri/dri_util.h" -#include "ui/ozone/platform/dri/dri_wrapper.h" +#include "ui/ozone/platform/dri/drm_device.h" #include "ui/ozone/platform/dri/drm_device_generator.h" #include "ui/ozone/platform/dri/screen_manager.h" #include "ui/ozone/public/ozone_switches.h" @@ -61,7 +61,7 @@ crtc_(snapshot->crtc()), connector_(snapshot->connector()) {} - DisplaySnapshotComparator(const scoped_refptr<DriWrapper>& drm, + DisplaySnapshotComparator(const scoped_refptr<DrmDevice>& drm, uint32_t crtc, uint32_t connector) : drm_(drm), crtc_(crtc), connector_(connector) {} @@ -72,7 +72,7 @@ } private: - scoped_refptr<DriWrapper> drm_; + scoped_refptr<DrmDevice> drm_; uint32_t crtc_; uint32_t connector_; }; @@ -81,7 +81,7 @@ public: explicit FindByDevicePath(const base::FilePath& path) : path_(path) {} - bool operator()(const scoped_refptr<DriWrapper>& device) { + bool operator()(const scoped_refptr<DrmDevice>& device) { return device->device_path() == path_; } @@ -93,7 +93,7 @@ NativeDisplayDelegateDri::NativeDisplayDelegateDri( ScreenManager* screen_manager, - const scoped_refptr<DriWrapper>& primary_device, + const scoped_refptr<DrmDevice>& primary_device, scoped_ptr<DrmDeviceGenerator> drm_device_generator) : screen_manager_(screen_manager), drm_device_generator_(drm_device_generator.Pass()) { @@ -213,7 +213,7 @@ return; } - scoped_refptr<DriWrapper> device = + scoped_refptr<DrmDevice> device = drm_device_generator_->CreateDevice(path, file.Pass()); if (!device) { VLOG(2) << "Could not initialize DRM device for '" << path.value() << "'";
diff --git a/ui/ozone/platform/dri/native_display_delegate_dri.h b/ui/ozone/platform/dri/native_display_delegate_dri.h index 88d1cb6..55c554c 100644 --- a/ui/ozone/platform/dri/native_display_delegate_dri.h +++ b/ui/ozone/platform/dri/native_display_delegate_dri.h
@@ -22,14 +22,14 @@ class DisplaySnapshotDri; class DisplayMode; class DisplayModeDri; -class DriWrapper; +class DrmDevice; class DrmDeviceGenerator; class ScreenManager; class NativeDisplayDelegateDri { public: NativeDisplayDelegateDri(ScreenManager* screen_manager, - const scoped_refptr<DriWrapper>& primary_device, + const scoped_refptr<DrmDevice>& primary_device, scoped_ptr<DrmDeviceGenerator> device_generator); ~NativeDisplayDelegateDri(); @@ -77,7 +77,7 @@ ScreenManager* screen_manager_; // Not owned. scoped_ptr<DrmDeviceGenerator> drm_device_generator_; scoped_refptr<base::SingleThreadTaskRunner> io_task_runner_; - std::vector<scoped_refptr<DriWrapper>> devices_; + std::vector<scoped_refptr<DrmDevice>> devices_; // Modes can be shared between different displays, so we need to keep track // of them independently for cleanup. ScopedVector<const DisplayMode> cached_modes_;
diff --git a/ui/ozone/platform/dri/ozone_platform_dri.cc b/ui/ozone/platform/dri/ozone_platform_dri.cc index 8dd7838..71552d4c 100644 --- a/ui/ozone/platform/dri/ozone_platform_dri.cc +++ b/ui/ozone/platform/dri/ozone_platform_dri.cc
@@ -22,7 +22,7 @@ #include "ui/ozone/platform/dri/dri_window_delegate_impl.h" #include "ui/ozone/platform/dri/dri_window_delegate_manager.h" #include "ui/ozone/platform/dri/dri_window_manager.h" -#include "ui/ozone/platform/dri/dri_wrapper.h" +#include "ui/ozone/platform/dri/drm_device.h" #include "ui/ozone/platform/dri/drm_device_generator.h" #include "ui/ozone/platform/dri/drm_device_manager.h" #include "ui/ozone/platform/dri/native_display_delegate_dri.h" @@ -49,7 +49,7 @@ class OzonePlatformDri : public OzonePlatform { public: OzonePlatformDri() - : dri_(new DriWrapper(GetPrimaryDisplayCardPath())), + : drm_(new DrmDevice(GetPrimaryDisplayCardPath())), buffer_generator_(new DriBufferGenerator()), screen_manager_(new ScreenManager(buffer_generator_.get())), device_manager_(CreateDeviceManager()), @@ -88,21 +88,21 @@ scoped_ptr<NativeDisplayDelegate> CreateNativeDisplayDelegate() override { return make_scoped_ptr(new NativeDisplayDelegateProxy( gpu_platform_support_host_.get(), device_manager_.get(), - display_manager_.get(), dri_->device_path())); + display_manager_.get(), drm_->device_path())); } void InitializeUI() override { - if (!dri_->Initialize()) + if (!drm_->Initialize()) LOG(FATAL) << "Failed to initialize primary DRM device"; // This makes sure that simple targets that do not handle display // configuration can still use the primary display. - ForceInitializationOfPrimaryDisplay(dri_, screen_manager_.get()); - drm_device_manager_.reset(new DrmDeviceManager(dri_)); + ForceInitializationOfPrimaryDisplay(drm_, screen_manager_.get()); + drm_device_manager_.reset(new DrmDeviceManager(drm_)); display_manager_.reset(new DisplayManager()); surface_factory_ozone_.reset( new DriSurfaceFactory(&window_delegate_manager_)); scoped_ptr<NativeDisplayDelegateDri> ndd(new NativeDisplayDelegateDri( - screen_manager_.get(), dri_, + screen_manager_.get(), drm_, scoped_ptr<DrmDeviceGenerator>(new DrmDeviceGenerator()))); gpu_platform_support_.reset(new DriGpuPlatformSupport( drm_device_manager_.get(), &window_delegate_manager_, @@ -132,7 +132,7 @@ void InitializeGPU() override {} private: - scoped_refptr<DriWrapper> dri_; + scoped_refptr<DrmDevice> drm_; scoped_ptr<DrmDeviceManager> drm_device_manager_; scoped_ptr<DriBufferGenerator> buffer_generator_; scoped_ptr<ScreenManager> screen_manager_;
diff --git a/ui/ozone/platform/dri/ozone_platform_gbm.cc b/ui/ozone/platform/dri/ozone_platform_gbm.cc index 7c237df..15d5466 100644 --- a/ui/ozone/platform/dri/ozone_platform_gbm.cc +++ b/ui/ozone/platform/dri/ozone_platform_gbm.cc
@@ -26,9 +26,9 @@ #include "ui/ozone/platform/dri/drm_device_generator.h" #include "ui/ozone/platform/dri/drm_device_manager.h" #include "ui/ozone/platform/dri/gbm_buffer.h" +#include "ui/ozone/platform/dri/gbm_device.h" #include "ui/ozone/platform/dri/gbm_surface.h" #include "ui/ozone/platform/dri/gbm_surface_factory.h" -#include "ui/ozone/platform/dri/gbm_wrapper.h" #include "ui/ozone/platform/dri/native_display_delegate_dri.h" #include "ui/ozone/platform/dri/native_display_delegate_proxy.h" #include "ui/ozone/platform/dri/scanout_buffer.h" @@ -76,9 +76,9 @@ ~GbmBufferGenerator() override {} // ScanoutBufferGenerator: - scoped_refptr<ScanoutBuffer> Create(const scoped_refptr<DriWrapper>& drm, + scoped_refptr<ScanoutBuffer> Create(const scoped_refptr<DrmDevice>& drm, const gfx::Size& size) override { - scoped_refptr<GbmWrapper> gbm(static_cast<GbmWrapper*>(drm.get())); + scoped_refptr<GbmDevice> gbm(static_cast<GbmDevice*>(drm.get())); return GbmBuffer::CreateBuffer(gbm, SurfaceFactoryOzone::RGBA_8888, size, true); } @@ -93,9 +93,9 @@ ~GbmDeviceGenerator() override {} // DrmDeviceGenerator: - scoped_refptr<DriWrapper> CreateDevice(const base::FilePath& path, - base::File file) override { - scoped_refptr<DriWrapper> drm = new GbmWrapper(path, file.Pass()); + scoped_refptr<DrmDevice> CreateDevice(const base::FilePath& path, + base::File file) override { + scoped_refptr<DrmDevice> drm = new GbmDevice(path, file.Pass()); if (drm->Initialize()) return drm; @@ -175,7 +175,7 @@ void InitializeGPU() override { gl_api_loader_.reset(new GlApiLoader()); // Async page flips are supported only on surfaceless mode. - gbm_ = new GbmWrapper(GetPrimaryDisplayCardPath()); + gbm_ = new GbmDevice(GetPrimaryDisplayCardPath()); if (!gbm_->Initialize()) LOG(FATAL) << "Failed to initialize primary DRM device"; @@ -204,7 +204,7 @@ bool use_surfaceless_; base::FilePath primary_graphics_card_path_; scoped_ptr<GlApiLoader> gl_api_loader_; - scoped_refptr<GbmWrapper> gbm_; + scoped_refptr<GbmDevice> gbm_; scoped_ptr<DrmDeviceManager> drm_device_manager_; scoped_ptr<GbmBufferGenerator> buffer_generator_; scoped_ptr<ScreenManager> screen_manager_;
diff --git a/ui/ozone/platform/dri/scanout_buffer.h b/ui/ozone/platform/dri/scanout_buffer.h index cf653322..bfe1990a 100644 --- a/ui/ozone/platform/dri/scanout_buffer.h +++ b/ui/ozone/platform/dri/scanout_buffer.h
@@ -12,7 +12,7 @@ namespace ui { -class DriWrapper; +class DrmDevice; // Abstraction for a DRM buffer that can be scanned-out of. class ScanoutBuffer : public base::RefCountedThreadSafe<ScanoutBuffer> { @@ -37,7 +37,7 @@ virtual ~ScanoutBufferGenerator() {} virtual scoped_refptr<ScanoutBuffer> Create( - const scoped_refptr<DriWrapper>& drm, + const scoped_refptr<DrmDevice>& drm, const gfx::Size& size) = 0; };
diff --git a/ui/ozone/platform/dri/screen_manager.cc b/ui/ozone/platform/dri/screen_manager.cc index fbf2edef..a2b0ee8 100644 --- a/ui/ozone/platform/dri/screen_manager.cc +++ b/ui/ozone/platform/dri/screen_manager.cc
@@ -13,7 +13,7 @@ #include "ui/ozone/platform/dri/crtc_controller.h" #include "ui/ozone/platform/dri/dri_console_buffer.h" #include "ui/ozone/platform/dri/dri_util.h" -#include "ui/ozone/platform/dri/dri_wrapper.h" +#include "ui/ozone/platform/dri/drm_device.h" #include "ui/ozone/platform/dri/hardware_display_controller.h" #include "ui/ozone/platform/dri/scanout_buffer.h" @@ -23,10 +23,10 @@ // Copies the contents of the saved framebuffer from the CRTCs in |controller| // to the new modeset buffer |buffer|. -void FillModesetBuffer(const scoped_refptr<DriWrapper>& dri, +void FillModesetBuffer(const scoped_refptr<DrmDevice>& drm, HardwareDisplayController* controller, ScanoutBuffer* buffer) { - DriConsoleBuffer modeset_buffer(dri, buffer->GetFramebufferId()); + DriConsoleBuffer modeset_buffer(drm, buffer->GetFramebufferId()); if (!modeset_buffer.Initialize()) { LOG(ERROR) << "Failed to grab framebuffer " << buffer->GetFramebufferId(); return; @@ -40,7 +40,7 @@ // If the display controller is in mirror mode, the CRTCs should be sharing // the same framebuffer. - DriConsoleBuffer saved_buffer(dri, crtcs[0]->saved_crtc()->buffer_id); + DriConsoleBuffer saved_buffer(drm, crtcs[0]->saved_crtc()->buffer_id); if (!saved_buffer.Initialize()) { LOG(ERROR) << "Failed to grab saved framebuffer " << crtcs[0]->saved_crtc()->buffer_id; @@ -69,10 +69,10 @@ ScreenManager::~ScreenManager() { } -void ScreenManager::AddDisplayController(const scoped_refptr<DriWrapper>& dri, +void ScreenManager::AddDisplayController(const scoped_refptr<DrmDevice>& drm, uint32_t crtc, uint32_t connector) { - HardwareDisplayControllers::iterator it = FindDisplayController(dri, crtc); + HardwareDisplayControllers::iterator it = FindDisplayController(drm, crtc); // TODO(dnicoara): Turn this into a DCHECK when async display configuration is // properly supported. (When there can't be a race between forcing initial // display configuration in ScreenManager and NativeDisplayDelegate creating @@ -83,12 +83,11 @@ } controllers_.push_back(new HardwareDisplayController( - scoped_ptr<CrtcController>(new CrtcController(dri, crtc, connector)))); + scoped_ptr<CrtcController>(new CrtcController(drm, crtc, connector)))); } -void ScreenManager::RemoveDisplayController( - const scoped_refptr<DriWrapper>& drm, - uint32_t crtc) { +void ScreenManager::RemoveDisplayController(const scoped_refptr<DrmDevice>& drm, + uint32_t crtc) { HardwareDisplayControllers::iterator it = FindDisplayController(drm, crtc); if (it != controllers_.end()) { bool is_mirrored = (*it)->IsMirrored(); @@ -102,7 +101,7 @@ } bool ScreenManager::ConfigureDisplayController( - const scoped_refptr<DriWrapper>& drm, + const scoped_refptr<DrmDevice>& drm, uint32_t crtc, uint32_t connector, const gfx::Point& origin, @@ -156,7 +155,7 @@ } bool ScreenManager::DisableDisplayController( - const scoped_refptr<DriWrapper>& drm, + const scoped_refptr<DrmDevice>& drm, uint32_t crtc) { HardwareDisplayControllers::iterator it = FindDisplayController(drm, crtc); if (it != controllers_.end()) { @@ -193,7 +192,7 @@ } ScreenManager::HardwareDisplayControllers::iterator -ScreenManager::FindDisplayController(const scoped_refptr<DriWrapper>& drm, +ScreenManager::FindDisplayController(const scoped_refptr<DrmDevice>& drm, uint32_t crtc) { for (HardwareDisplayControllers::iterator it = controllers_.begin(); it != controllers_.end(); @@ -223,7 +222,7 @@ const gfx::Point& origin, const drmModeModeInfo& mode) { DCHECK(!controller->crtc_controllers().empty()); - scoped_refptr<DriWrapper> drm = controller->GetAllocationDriWrapper(); + scoped_refptr<DrmDevice> drm = controller->GetAllocationDrmDevice(); controller->set_origin(origin); // Create a surface suitable for the current controller. @@ -250,7 +249,7 @@ bool ScreenManager::HandleMirrorMode( HardwareDisplayControllers::iterator original, HardwareDisplayControllers::iterator mirror, - const scoped_refptr<DriWrapper>& drm, + const scoped_refptr<DrmDevice>& drm, uint32_t crtc, uint32_t connector) { (*mirror)->AddCrtc((*original)->RemoveCrtc(drm, crtc));
diff --git a/ui/ozone/platform/dri/screen_manager.h b/ui/ozone/platform/dri/screen_manager.h index 5eaaa46..bf8fed9 100644 --- a/ui/ozone/platform/dri/screen_manager.h +++ b/ui/ozone/platform/dri/screen_manager.h
@@ -22,7 +22,7 @@ namespace ui { -class DriWrapper; +class DrmDevice; class ScanoutBufferGenerator; // Responsible for keeping track of active displays and configuring them. @@ -33,18 +33,18 @@ // Register a display controller. This must be called before trying to // configure it. - void AddDisplayController(const scoped_refptr<DriWrapper>& dri, + void AddDisplayController(const scoped_refptr<DrmDevice>& drm, uint32_t crtc, uint32_t connector); // Remove a display controller from the list of active controllers. The // controller is removed since it was disconnected. - void RemoveDisplayController(const scoped_refptr<DriWrapper>& dri, + void RemoveDisplayController(const scoped_refptr<DrmDevice>& drm, uint32_t crtc); // Configure a display controller. The display controller is identified by // (|crtc|, |connector|) and the controller is modeset using |mode|. - bool ConfigureDisplayController(const scoped_refptr<DriWrapper>& dri, + bool ConfigureDisplayController(const scoped_refptr<DrmDevice>& drm, uint32_t crtc, uint32_t connector, const gfx::Point& origin, @@ -52,7 +52,7 @@ // Disable the display controller identified by |crtc|. Note, the controller // may still be connected, so this does not remove the controller. - bool DisableDisplayController(const scoped_refptr<DriWrapper>& dri, + bool DisableDisplayController(const scoped_refptr<DrmDevice>& drm, uint32_t crtc); // Returns a reference to the display controller configured to display within @@ -69,7 +69,7 @@ // Returns an iterator into |controllers_| for the controller identified by // (|crtc|, |connector|). HardwareDisplayControllers::iterator FindDisplayController( - const scoped_refptr<DriWrapper>& drm, + const scoped_refptr<DrmDevice>& drm, uint32_t crtc); // Returns an iterator into |controllers_| for the controller located at @@ -87,7 +87,7 @@ // controller is currently present. bool HandleMirrorMode(HardwareDisplayControllers::iterator original, HardwareDisplayControllers::iterator mirror, - const scoped_refptr<DriWrapper>& drm, + const scoped_refptr<DrmDevice>& drm, uint32_t crtc, uint32_t connector);
diff --git a/ui/ozone/platform/dri/screen_manager_unittest.cc b/ui/ozone/platform/dri/screen_manager_unittest.cc index 1501b71..58e08d1 100644 --- a/ui/ozone/platform/dri/screen_manager_unittest.cc +++ b/ui/ozone/platform/dri/screen_manager_unittest.cc
@@ -7,7 +7,7 @@ #include "ui/ozone/platform/dri/dri_buffer.h" #include "ui/ozone/platform/dri/hardware_display_controller.h" #include "ui/ozone/platform/dri/screen_manager.h" -#include "ui/ozone/platform/dri/test/mock_dri_wrapper.h" +#include "ui/ozone/platform/dri/test/mock_drm_device.h" namespace { @@ -64,7 +64,7 @@ } void SetUp() override { - dri_ = new ui::MockDriWrapper(); + drm_ = new ui::MockDrmDevice(); buffer_generator_.reset(new ui::DriBufferGenerator()); screen_manager_.reset(new ui::ScreenManager(buffer_generator_.get())); screen_manager_->AddObserver(&observer_); @@ -72,11 +72,11 @@ void TearDown() override { screen_manager_->RemoveObserver(&observer_); screen_manager_.reset(); - dri_ = nullptr; + drm_ = nullptr; } protected: - scoped_refptr<ui::MockDriWrapper> dri_; + scoped_refptr<ui::MockDrmDevice> drm_; scoped_ptr<ui::DriBufferGenerator> buffer_generator_; scoped_ptr<ui::ScreenManager> screen_manager_; @@ -91,21 +91,21 @@ } TEST_F(ScreenManagerTest, CheckWithValidController) { - screen_manager_->AddDisplayController(dri_, kPrimaryCrtc, kPrimaryConnector); + screen_manager_->AddDisplayController(drm_, kPrimaryCrtc, kPrimaryConnector); screen_manager_->ConfigureDisplayController( - dri_, kPrimaryCrtc, kPrimaryConnector, GetPrimaryBounds().origin(), + drm_, kPrimaryCrtc, kPrimaryConnector, GetPrimaryBounds().origin(), kDefaultMode); ui::HardwareDisplayController* controller = screen_manager_->GetDisplayController(GetPrimaryBounds()); EXPECT_TRUE(controller); - EXPECT_TRUE(controller->HasCrtc(dri_, kPrimaryCrtc)); + EXPECT_TRUE(controller->HasCrtc(drm_, kPrimaryCrtc)); } TEST_F(ScreenManagerTest, CheckWithInvalidBounds) { - screen_manager_->AddDisplayController(dri_, kPrimaryCrtc, kPrimaryConnector); + screen_manager_->AddDisplayController(drm_, kPrimaryCrtc, kPrimaryConnector); screen_manager_->ConfigureDisplayController( - dri_, kPrimaryCrtc, kPrimaryConnector, GetPrimaryBounds().origin(), + drm_, kPrimaryCrtc, kPrimaryConnector, GetPrimaryBounds().origin(), kDefaultMode); EXPECT_TRUE(screen_manager_->GetDisplayController(GetPrimaryBounds())); @@ -113,14 +113,14 @@ } TEST_F(ScreenManagerTest, CheckForSecondValidController) { - screen_manager_->AddDisplayController(dri_, kPrimaryCrtc, kPrimaryConnector); + screen_manager_->AddDisplayController(drm_, kPrimaryCrtc, kPrimaryConnector); screen_manager_->ConfigureDisplayController( - dri_, kPrimaryCrtc, kPrimaryConnector, GetPrimaryBounds().origin(), + drm_, kPrimaryCrtc, kPrimaryConnector, GetPrimaryBounds().origin(), kDefaultMode); - screen_manager_->AddDisplayController(dri_, kSecondaryCrtc, + screen_manager_->AddDisplayController(drm_, kSecondaryCrtc, kSecondaryConnector); screen_manager_->ConfigureDisplayController( - dri_, kSecondaryCrtc, kSecondaryConnector, GetSecondaryBounds().origin(), + drm_, kSecondaryCrtc, kSecondaryConnector, GetSecondaryBounds().origin(), kDefaultMode); EXPECT_TRUE(screen_manager_->GetDisplayController(GetPrimaryBounds())); @@ -128,33 +128,33 @@ } TEST_F(ScreenManagerTest, CheckControllerAfterItIsRemoved) { - screen_manager_->AddDisplayController(dri_, kPrimaryCrtc, kPrimaryConnector); + screen_manager_->AddDisplayController(drm_, kPrimaryCrtc, kPrimaryConnector); screen_manager_->ConfigureDisplayController( - dri_, kPrimaryCrtc, kPrimaryConnector, GetPrimaryBounds().origin(), + drm_, kPrimaryCrtc, kPrimaryConnector, GetPrimaryBounds().origin(), kDefaultMode); EXPECT_EQ(1, observer_.num_displays_changed()); EXPECT_EQ(0, observer_.num_displays_removed()); EXPECT_TRUE(screen_manager_->GetDisplayController(GetPrimaryBounds())); - screen_manager_->RemoveDisplayController(dri_, kPrimaryCrtc); + screen_manager_->RemoveDisplayController(drm_, kPrimaryCrtc); EXPECT_EQ(1, observer_.num_displays_changed()); EXPECT_EQ(1, observer_.num_displays_removed()); EXPECT_FALSE(screen_manager_->GetDisplayController(GetPrimaryBounds())); } TEST_F(ScreenManagerTest, CheckDuplicateConfiguration) { - screen_manager_->AddDisplayController(dri_, kPrimaryCrtc, kPrimaryConnector); + screen_manager_->AddDisplayController(drm_, kPrimaryCrtc, kPrimaryConnector); screen_manager_->ConfigureDisplayController( - dri_, kPrimaryCrtc, kPrimaryConnector, GetPrimaryBounds().origin(), + drm_, kPrimaryCrtc, kPrimaryConnector, GetPrimaryBounds().origin(), kDefaultMode); - uint32_t framebuffer = dri_->current_framebuffer(); + uint32_t framebuffer = drm_->current_framebuffer(); screen_manager_->ConfigureDisplayController( - dri_, kPrimaryCrtc, kPrimaryConnector, GetPrimaryBounds().origin(), + drm_, kPrimaryCrtc, kPrimaryConnector, GetPrimaryBounds().origin(), kDefaultMode); // Should reuse existing framebuffer. - EXPECT_EQ(framebuffer, dri_->current_framebuffer()); + EXPECT_EQ(framebuffer, drm_->current_framebuffer()); EXPECT_EQ(2, observer_.num_displays_changed()); EXPECT_EQ(0, observer_.num_displays_removed()); @@ -164,14 +164,14 @@ } TEST_F(ScreenManagerTest, CheckChangingMode) { - screen_manager_->AddDisplayController(dri_, kPrimaryCrtc, kPrimaryConnector); + screen_manager_->AddDisplayController(drm_, kPrimaryCrtc, kPrimaryConnector); screen_manager_->ConfigureDisplayController( - dri_, kPrimaryCrtc, kPrimaryConnector, GetPrimaryBounds().origin(), + drm_, kPrimaryCrtc, kPrimaryConnector, GetPrimaryBounds().origin(), kDefaultMode); drmModeModeInfo new_mode = kDefaultMode; new_mode.vdisplay = 10; screen_manager_->ConfigureDisplayController( - dri_, kPrimaryCrtc, kPrimaryConnector, GetPrimaryBounds().origin(), + drm_, kPrimaryCrtc, kPrimaryConnector, GetPrimaryBounds().origin(), new_mode); EXPECT_EQ(2, observer_.num_displays_changed()); @@ -187,14 +187,14 @@ } TEST_F(ScreenManagerTest, CheckForControllersInMirroredMode) { - screen_manager_->AddDisplayController(dri_, kPrimaryCrtc, kPrimaryConnector); + screen_manager_->AddDisplayController(drm_, kPrimaryCrtc, kPrimaryConnector); screen_manager_->ConfigureDisplayController( - dri_, kPrimaryCrtc, kPrimaryConnector, GetPrimaryBounds().origin(), + drm_, kPrimaryCrtc, kPrimaryConnector, GetPrimaryBounds().origin(), kDefaultMode); - screen_manager_->AddDisplayController(dri_, kSecondaryCrtc, + screen_manager_->AddDisplayController(drm_, kSecondaryCrtc, kSecondaryConnector); screen_manager_->ConfigureDisplayController( - dri_, kSecondaryCrtc, kSecondaryConnector, GetPrimaryBounds().origin(), + drm_, kSecondaryCrtc, kSecondaryConnector, GetPrimaryBounds().origin(), kDefaultMode); EXPECT_EQ(2, observer_.num_displays_changed()); @@ -204,55 +204,55 @@ } TEST_F(ScreenManagerTest, CheckMirrorModeTransitions) { - screen_manager_->AddDisplayController(dri_, kPrimaryCrtc, kPrimaryConnector); + screen_manager_->AddDisplayController(drm_, kPrimaryCrtc, kPrimaryConnector); screen_manager_->ConfigureDisplayController( - dri_, kPrimaryCrtc, kPrimaryConnector, GetPrimaryBounds().origin(), + drm_, kPrimaryCrtc, kPrimaryConnector, GetPrimaryBounds().origin(), kDefaultMode); - screen_manager_->AddDisplayController(dri_, kSecondaryCrtc, + screen_manager_->AddDisplayController(drm_, kSecondaryCrtc, kSecondaryConnector); screen_manager_->ConfigureDisplayController( - dri_, kSecondaryCrtc, kSecondaryConnector, GetSecondaryBounds().origin(), + drm_, kSecondaryCrtc, kSecondaryConnector, GetSecondaryBounds().origin(), kDefaultMode); EXPECT_TRUE(screen_manager_->GetDisplayController(GetPrimaryBounds())); EXPECT_TRUE(screen_manager_->GetDisplayController(GetSecondaryBounds())); screen_manager_->ConfigureDisplayController( - dri_, kPrimaryCrtc, kPrimaryConnector, GetPrimaryBounds().origin(), + drm_, kPrimaryCrtc, kPrimaryConnector, GetPrimaryBounds().origin(), kDefaultMode); screen_manager_->ConfigureDisplayController( - dri_, kSecondaryCrtc, kSecondaryConnector, GetPrimaryBounds().origin(), + drm_, kSecondaryCrtc, kSecondaryConnector, GetPrimaryBounds().origin(), kDefaultMode); EXPECT_TRUE(screen_manager_->GetDisplayController(GetPrimaryBounds())); EXPECT_FALSE(screen_manager_->GetDisplayController(GetSecondaryBounds())); screen_manager_->ConfigureDisplayController( - dri_, kPrimaryCrtc, kPrimaryConnector, GetSecondaryBounds().origin(), + drm_, kPrimaryCrtc, kPrimaryConnector, GetSecondaryBounds().origin(), kDefaultMode); screen_manager_->ConfigureDisplayController( - dri_, kSecondaryCrtc, kSecondaryConnector, GetPrimaryBounds().origin(), + drm_, kSecondaryCrtc, kSecondaryConnector, GetPrimaryBounds().origin(), kDefaultMode); EXPECT_TRUE(screen_manager_->GetDisplayController(GetPrimaryBounds())); EXPECT_TRUE(screen_manager_->GetDisplayController(GetSecondaryBounds())); } TEST_F(ScreenManagerTest, MonitorGoneInMirrorMode) { - screen_manager_->AddDisplayController(dri_, kPrimaryCrtc, kPrimaryConnector); + screen_manager_->AddDisplayController(drm_, kPrimaryCrtc, kPrimaryConnector); screen_manager_->ConfigureDisplayController( - dri_, kPrimaryCrtc, kPrimaryConnector, GetPrimaryBounds().origin(), + drm_, kPrimaryCrtc, kPrimaryConnector, GetPrimaryBounds().origin(), kDefaultMode); - screen_manager_->AddDisplayController(dri_, kSecondaryCrtc, + screen_manager_->AddDisplayController(drm_, kSecondaryCrtc, kSecondaryConnector); screen_manager_->ConfigureDisplayController( - dri_, kSecondaryCrtc, kSecondaryConnector, GetPrimaryBounds().origin(), + drm_, kSecondaryCrtc, kSecondaryConnector, GetPrimaryBounds().origin(), kDefaultMode); EXPECT_EQ(2, observer_.num_displays_changed()); EXPECT_EQ(1, observer_.num_displays_removed()); - screen_manager_->RemoveDisplayController(dri_, kSecondaryCrtc); + screen_manager_->RemoveDisplayController(drm_, kSecondaryCrtc); EXPECT_TRUE(screen_manager_->ConfigureDisplayController( - dri_, kPrimaryCrtc, kPrimaryConnector, GetPrimaryBounds().origin(), + drm_, kPrimaryCrtc, kPrimaryConnector, GetPrimaryBounds().origin(), kDefaultMode)); EXPECT_EQ(3, observer_.num_displays_changed()); EXPECT_EQ(1, observer_.num_displays_removed()); @@ -262,23 +262,23 @@ } TEST_F(ScreenManagerTest, DoNotEnterMirrorModeUnlessSameBounds) { - screen_manager_->AddDisplayController(dri_, kPrimaryCrtc, kPrimaryConnector); - screen_manager_->AddDisplayController(dri_, kSecondaryCrtc, + screen_manager_->AddDisplayController(drm_, kPrimaryCrtc, kPrimaryConnector); + screen_manager_->AddDisplayController(drm_, kSecondaryCrtc, kSecondaryConnector); // Configure displays in extended mode. screen_manager_->ConfigureDisplayController( - dri_, kPrimaryCrtc, kPrimaryConnector, GetPrimaryBounds().origin(), + drm_, kPrimaryCrtc, kPrimaryConnector, GetPrimaryBounds().origin(), kDefaultMode); screen_manager_->ConfigureDisplayController( - dri_, kSecondaryCrtc, kSecondaryConnector, GetSecondaryBounds().origin(), + drm_, kSecondaryCrtc, kSecondaryConnector, GetSecondaryBounds().origin(), kDefaultMode); drmModeModeInfo new_mode = kDefaultMode; new_mode.vdisplay = 10; // Shouldn't enter mirror mode unless the display bounds are the same. screen_manager_->ConfigureDisplayController( - dri_, kSecondaryCrtc, kSecondaryConnector, GetPrimaryBounds().origin(), + drm_, kSecondaryCrtc, kSecondaryConnector, GetPrimaryBounds().origin(), new_mode); EXPECT_FALSE( @@ -286,34 +286,34 @@ } TEST_F(ScreenManagerTest, ReuseFramebufferIfDisabledThenReEnabled) { - screen_manager_->AddDisplayController(dri_, kPrimaryCrtc, kPrimaryConnector); + screen_manager_->AddDisplayController(drm_, kPrimaryCrtc, kPrimaryConnector); screen_manager_->ConfigureDisplayController( - dri_, kPrimaryCrtc, kPrimaryConnector, GetPrimaryBounds().origin(), + drm_, kPrimaryCrtc, kPrimaryConnector, GetPrimaryBounds().origin(), kDefaultMode); - uint32_t framebuffer = dri_->current_framebuffer(); + uint32_t framebuffer = drm_->current_framebuffer(); - screen_manager_->DisableDisplayController(dri_, kPrimaryCrtc); - EXPECT_EQ(0u, dri_->current_framebuffer()); + screen_manager_->DisableDisplayController(drm_, kPrimaryCrtc); + EXPECT_EQ(0u, drm_->current_framebuffer()); screen_manager_->ConfigureDisplayController( - dri_, kPrimaryCrtc, kPrimaryConnector, GetPrimaryBounds().origin(), + drm_, kPrimaryCrtc, kPrimaryConnector, GetPrimaryBounds().origin(), kDefaultMode); // Should reuse existing framebuffer. - EXPECT_EQ(framebuffer, dri_->current_framebuffer()); + EXPECT_EQ(framebuffer, drm_->current_framebuffer()); } TEST_F(ScreenManagerTest, CheckMirrorModeAfterBeginReEnabled) { - screen_manager_->AddDisplayController(dri_, kPrimaryCrtc, kPrimaryConnector); + screen_manager_->AddDisplayController(drm_, kPrimaryCrtc, kPrimaryConnector); screen_manager_->ConfigureDisplayController( - dri_, kPrimaryCrtc, kPrimaryConnector, GetPrimaryBounds().origin(), + drm_, kPrimaryCrtc, kPrimaryConnector, GetPrimaryBounds().origin(), kDefaultMode); - screen_manager_->DisableDisplayController(dri_, kPrimaryCrtc); + screen_manager_->DisableDisplayController(drm_, kPrimaryCrtc); - screen_manager_->AddDisplayController(dri_, kSecondaryCrtc, + screen_manager_->AddDisplayController(drm_, kSecondaryCrtc, kSecondaryConnector); screen_manager_->ConfigureDisplayController( - dri_, kSecondaryCrtc, kSecondaryConnector, GetPrimaryBounds().origin(), + drm_, kSecondaryCrtc, kSecondaryConnector, GetPrimaryBounds().origin(), kDefaultMode); ui::HardwareDisplayController* controller = @@ -322,7 +322,7 @@ EXPECT_FALSE(controller->IsMirrored()); screen_manager_->ConfigureDisplayController( - dri_, kPrimaryCrtc, kPrimaryConnector, GetPrimaryBounds().origin(), + drm_, kPrimaryCrtc, kPrimaryConnector, GetPrimaryBounds().origin(), kDefaultMode); EXPECT_TRUE(controller); EXPECT_TRUE(controller->IsMirrored()); @@ -330,16 +330,16 @@ TEST_F(ScreenManagerTest, CheckProperConfigurationWithDifferentDeviceAndSameCrtc) { - scoped_refptr<ui::MockDriWrapper> dri2 = new ui::MockDriWrapper(); + scoped_refptr<ui::MockDrmDevice> drm2 = new ui::MockDrmDevice(); - screen_manager_->AddDisplayController(dri_, kPrimaryCrtc, kPrimaryConnector); - screen_manager_->AddDisplayController(dri2, kPrimaryCrtc, kPrimaryConnector); + screen_manager_->AddDisplayController(drm_, kPrimaryCrtc, kPrimaryConnector); + screen_manager_->AddDisplayController(drm2, kPrimaryCrtc, kPrimaryConnector); screen_manager_->ConfigureDisplayController( - dri_, kPrimaryCrtc, kPrimaryConnector, GetPrimaryBounds().origin(), + drm_, kPrimaryCrtc, kPrimaryConnector, GetPrimaryBounds().origin(), kDefaultMode); screen_manager_->ConfigureDisplayController( - dri2, kPrimaryCrtc, kPrimaryConnector, GetSecondaryBounds().origin(), + drm2, kPrimaryCrtc, kPrimaryConnector, GetSecondaryBounds().origin(), kDefaultMode); ui::HardwareDisplayController* controller1 = @@ -348,6 +348,6 @@ screen_manager_->GetDisplayController(GetSecondaryBounds()); EXPECT_NE(controller1, controller2); - EXPECT_EQ(dri_, controller1->crtc_controllers()[0]->drm()); - EXPECT_EQ(dri2, controller2->crtc_controllers()[0]->drm()); + EXPECT_EQ(drm_, controller1->crtc_controllers()[0]->drm()); + EXPECT_EQ(drm2, controller2->crtc_controllers()[0]->drm()); }
diff --git a/ui/ozone/platform/dri/test/mock_dri_wrapper.cc b/ui/ozone/platform/dri/test/mock_dri_wrapper.cc deleted file mode 100644 index 4c33e01..0000000 --- a/ui/ozone/platform/dri/test/mock_dri_wrapper.cc +++ /dev/null
@@ -1,224 +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 "ui/ozone/platform/dri/test/mock_dri_wrapper.h" - -#include <xf86drm.h> -#include <xf86drmMode.h> - -#include "base/logging.h" -#include "third_party/skia/include/core/SkCanvas.h" -#include "ui/ozone/platform/dri/hardware_display_plane_manager_legacy.h" - -namespace ui { - -namespace { - -template<class Object> Object* DrmAllocator() { - return static_cast<Object*>(drmMalloc(sizeof(Object))); -} - -class MockHardwareDisplayPlaneManager - : public HardwareDisplayPlaneManagerLegacy { - public: - MockHardwareDisplayPlaneManager(DriWrapper* drm, - std::vector<uint32_t> crtcs, - size_t planes_per_crtc) { - const int kPlaneBaseId = 50; - drm_ = drm; - crtcs_.swap(crtcs); - for (size_t crtc_idx = 0; crtc_idx < crtcs_.size(); crtc_idx++) { - for (size_t i = 0; i < planes_per_crtc; i++) { - planes_.push_back( - new HardwareDisplayPlane(kPlaneBaseId + i, 1 << crtc_idx)); - } - } - } -}; - -} // namespace - -MockDriWrapper::MockDriWrapper() - : DriWrapper(base::FilePath(), base::File()), - get_crtc_call_count_(0), - set_crtc_call_count_(0), - restore_crtc_call_count_(0), - add_framebuffer_call_count_(0), - remove_framebuffer_call_count_(0), - page_flip_call_count_(0), - overlay_flip_call_count_(0), - set_crtc_expectation_(true), - add_framebuffer_expectation_(true), - page_flip_expectation_(true), - create_dumb_buffer_expectation_(true), - current_framebuffer_(0) { - plane_manager_.reset(new HardwareDisplayPlaneManagerLegacy()); -} - -MockDriWrapper::MockDriWrapper(bool use_sync_flips, - std::vector<uint32_t> crtcs, - size_t planes_per_crtc) - : DriWrapper(base::FilePath(), base::File()), - get_crtc_call_count_(0), - set_crtc_call_count_(0), - restore_crtc_call_count_(0), - add_framebuffer_call_count_(0), - remove_framebuffer_call_count_(0), - page_flip_call_count_(0), - overlay_flip_call_count_(0), - overlay_clear_call_count_(0), - set_crtc_expectation_(true), - add_framebuffer_expectation_(true), - page_flip_expectation_(true), - create_dumb_buffer_expectation_(true), - use_sync_flips_(use_sync_flips), - current_framebuffer_(0) { - plane_manager_.reset( - new MockHardwareDisplayPlaneManager(this, crtcs, planes_per_crtc)); -} - -MockDriWrapper::~MockDriWrapper() { -} - -ScopedDrmCrtcPtr MockDriWrapper::GetCrtc(uint32_t crtc_id) { - get_crtc_call_count_++; - return ScopedDrmCrtcPtr(DrmAllocator<drmModeCrtc>()); -} - -bool MockDriWrapper::SetCrtc(uint32_t crtc_id, - uint32_t framebuffer, - std::vector<uint32_t> connectors, - drmModeModeInfo* mode) { - current_framebuffer_ = framebuffer; - set_crtc_call_count_++; - return set_crtc_expectation_; -} - -bool MockDriWrapper::SetCrtc(drmModeCrtc* crtc, - std::vector<uint32_t> connectors) { - restore_crtc_call_count_++; - return true; -} - -bool MockDriWrapper::DisableCrtc(uint32_t crtc_id) { - current_framebuffer_ = 0; - return true; -} - -ScopedDrmConnectorPtr MockDriWrapper::GetConnector(uint32_t connector_id) { - return ScopedDrmConnectorPtr(DrmAllocator<drmModeConnector>()); -} - -bool MockDriWrapper::AddFramebuffer(uint32_t width, - uint32_t height, - uint8_t depth, - uint8_t bpp, - uint32_t stride, - uint32_t handle, - uint32_t* framebuffer) { - add_framebuffer_call_count_++; - *framebuffer = add_framebuffer_call_count_; - return add_framebuffer_expectation_; -} - -bool MockDriWrapper::RemoveFramebuffer(uint32_t framebuffer) { - remove_framebuffer_call_count_++; - return true; -} - -ScopedDrmFramebufferPtr MockDriWrapper::GetFramebuffer(uint32_t framebuffer) { - return ScopedDrmFramebufferPtr(); -} - -bool MockDriWrapper::PageFlip(uint32_t crtc_id, - uint32_t framebuffer, - bool is_sync, - const PageFlipCallback& callback) { - page_flip_call_count_++; - current_framebuffer_ = framebuffer; - if (page_flip_expectation_) { - if (use_sync_flips_) - callback.Run(0, 0, 0); - else - callbacks_.push(callback); - } - - return page_flip_expectation_; -} - -bool MockDriWrapper::PageFlipOverlay(uint32_t crtc_id, - uint32_t framebuffer, - const gfx::Rect& location, - const gfx::Rect& source, - int overlay_plane) { - if (!framebuffer) - overlay_clear_call_count_++; - overlay_flip_call_count_++; - return true; -} - -ScopedDrmPropertyPtr MockDriWrapper::GetProperty(drmModeConnector* connector, - const char* name) { - return ScopedDrmPropertyPtr(DrmAllocator<drmModePropertyRes>()); -} - -bool MockDriWrapper::SetProperty(uint32_t connector_id, - uint32_t property_id, - uint64_t value) { - return true; -} - -bool MockDriWrapper::GetCapability(uint64_t capability, uint64_t* value) { - return true; -} - -ScopedDrmPropertyBlobPtr MockDriWrapper::GetPropertyBlob( - drmModeConnector* connector, - const char* name) { - return ScopedDrmPropertyBlobPtr(DrmAllocator<drmModePropertyBlobRes>()); -} - -bool MockDriWrapper::SetCursor(uint32_t crtc_id, - uint32_t handle, - const gfx::Size& size) { - return true; -} - -bool MockDriWrapper::MoveCursor(uint32_t crtc_id, const gfx::Point& point) { - return true; -} - -bool MockDriWrapper::CreateDumbBuffer(const SkImageInfo& info, - uint32_t* handle, - uint32_t* stride, - void** pixels) { - if (!create_dumb_buffer_expectation_) - return false; - - *handle = 0; - *stride = info.minRowBytes(); - *pixels = new char[info.getSafeSize(*stride)]; - buffers_.push_back( - skia::AdoptRef(SkSurface::NewRasterDirect(info, *pixels, *stride))); - buffers_.back()->getCanvas()->clear(SK_ColorBLACK); - - return true; -} - -void MockDriWrapper::DestroyDumbBuffer(const SkImageInfo& info, - uint32_t handle, - uint32_t stride, - void* pixels) { - delete[] static_cast<char*>(pixels); -} - -void MockDriWrapper::RunCallbacks() { - while (!callbacks_.empty()) { - PageFlipCallback callback = callbacks_.front(); - callbacks_.pop(); - callback.Run(0, 0, 0); - } -} - -} // namespace ui
diff --git a/ui/ozone/platform/dri/test/mock_drm_device.cc b/ui/ozone/platform/dri/test/mock_drm_device.cc new file mode 100644 index 0000000..460ecbb --- /dev/null +++ b/ui/ozone/platform/dri/test/mock_drm_device.cc
@@ -0,0 +1,225 @@ +// 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 "ui/ozone/platform/dri/test/mock_drm_device.h" + +#include <xf86drm.h> +#include <xf86drmMode.h> + +#include "base/logging.h" +#include "third_party/skia/include/core/SkCanvas.h" +#include "ui/ozone/platform/dri/hardware_display_plane_manager_legacy.h" + +namespace ui { + +namespace { + +template <class Object> +Object* DrmAllocator() { + return static_cast<Object*>(drmMalloc(sizeof(Object))); +} + +class MockHardwareDisplayPlaneManager + : public HardwareDisplayPlaneManagerLegacy { + public: + MockHardwareDisplayPlaneManager(DrmDevice* drm, + std::vector<uint32_t> crtcs, + size_t planes_per_crtc) { + const int kPlaneBaseId = 50; + drm_ = drm; + crtcs_.swap(crtcs); + for (size_t crtc_idx = 0; crtc_idx < crtcs_.size(); crtc_idx++) { + for (size_t i = 0; i < planes_per_crtc; i++) { + planes_.push_back( + new HardwareDisplayPlane(kPlaneBaseId + i, 1 << crtc_idx)); + } + } + } +}; + +} // namespace + +MockDrmDevice::MockDrmDevice() + : DrmDevice(base::FilePath(), base::File()), + get_crtc_call_count_(0), + set_crtc_call_count_(0), + restore_crtc_call_count_(0), + add_framebuffer_call_count_(0), + remove_framebuffer_call_count_(0), + page_flip_call_count_(0), + overlay_flip_call_count_(0), + set_crtc_expectation_(true), + add_framebuffer_expectation_(true), + page_flip_expectation_(true), + create_dumb_buffer_expectation_(true), + current_framebuffer_(0) { + plane_manager_.reset(new HardwareDisplayPlaneManagerLegacy()); +} + +MockDrmDevice::MockDrmDevice(bool use_sync_flips, + std::vector<uint32_t> crtcs, + size_t planes_per_crtc) + : DrmDevice(base::FilePath(), base::File()), + get_crtc_call_count_(0), + set_crtc_call_count_(0), + restore_crtc_call_count_(0), + add_framebuffer_call_count_(0), + remove_framebuffer_call_count_(0), + page_flip_call_count_(0), + overlay_flip_call_count_(0), + overlay_clear_call_count_(0), + set_crtc_expectation_(true), + add_framebuffer_expectation_(true), + page_flip_expectation_(true), + create_dumb_buffer_expectation_(true), + use_sync_flips_(use_sync_flips), + current_framebuffer_(0) { + plane_manager_.reset( + new MockHardwareDisplayPlaneManager(this, crtcs, planes_per_crtc)); +} + +MockDrmDevice::~MockDrmDevice() { +} + +ScopedDrmCrtcPtr MockDrmDevice::GetCrtc(uint32_t crtc_id) { + get_crtc_call_count_++; + return ScopedDrmCrtcPtr(DrmAllocator<drmModeCrtc>()); +} + +bool MockDrmDevice::SetCrtc(uint32_t crtc_id, + uint32_t framebuffer, + std::vector<uint32_t> connectors, + drmModeModeInfo* mode) { + current_framebuffer_ = framebuffer; + set_crtc_call_count_++; + return set_crtc_expectation_; +} + +bool MockDrmDevice::SetCrtc(drmModeCrtc* crtc, + std::vector<uint32_t> connectors) { + restore_crtc_call_count_++; + return true; +} + +bool MockDrmDevice::DisableCrtc(uint32_t crtc_id) { + current_framebuffer_ = 0; + return true; +} + +ScopedDrmConnectorPtr MockDrmDevice::GetConnector(uint32_t connector_id) { + return ScopedDrmConnectorPtr(DrmAllocator<drmModeConnector>()); +} + +bool MockDrmDevice::AddFramebuffer(uint32_t width, + uint32_t height, + uint8_t depth, + uint8_t bpp, + uint32_t stride, + uint32_t handle, + uint32_t* framebuffer) { + add_framebuffer_call_count_++; + *framebuffer = add_framebuffer_call_count_; + return add_framebuffer_expectation_; +} + +bool MockDrmDevice::RemoveFramebuffer(uint32_t framebuffer) { + remove_framebuffer_call_count_++; + return true; +} + +ScopedDrmFramebufferPtr MockDrmDevice::GetFramebuffer(uint32_t framebuffer) { + return ScopedDrmFramebufferPtr(); +} + +bool MockDrmDevice::PageFlip(uint32_t crtc_id, + uint32_t framebuffer, + bool is_sync, + const PageFlipCallback& callback) { + page_flip_call_count_++; + current_framebuffer_ = framebuffer; + if (page_flip_expectation_) { + if (use_sync_flips_) + callback.Run(0, 0, 0); + else + callbacks_.push(callback); + } + + return page_flip_expectation_; +} + +bool MockDrmDevice::PageFlipOverlay(uint32_t crtc_id, + uint32_t framebuffer, + const gfx::Rect& location, + const gfx::Rect& source, + int overlay_plane) { + if (!framebuffer) + overlay_clear_call_count_++; + overlay_flip_call_count_++; + return true; +} + +ScopedDrmPropertyPtr MockDrmDevice::GetProperty(drmModeConnector* connector, + const char* name) { + return ScopedDrmPropertyPtr(DrmAllocator<drmModePropertyRes>()); +} + +bool MockDrmDevice::SetProperty(uint32_t connector_id, + uint32_t property_id, + uint64_t value) { + return true; +} + +bool MockDrmDevice::GetCapability(uint64_t capability, uint64_t* value) { + return true; +} + +ScopedDrmPropertyBlobPtr MockDrmDevice::GetPropertyBlob( + drmModeConnector* connector, + const char* name) { + return ScopedDrmPropertyBlobPtr(DrmAllocator<drmModePropertyBlobRes>()); +} + +bool MockDrmDevice::SetCursor(uint32_t crtc_id, + uint32_t handle, + const gfx::Size& size) { + return true; +} + +bool MockDrmDevice::MoveCursor(uint32_t crtc_id, const gfx::Point& point) { + return true; +} + +bool MockDrmDevice::CreateDumbBuffer(const SkImageInfo& info, + uint32_t* handle, + uint32_t* stride, + void** pixels) { + if (!create_dumb_buffer_expectation_) + return false; + + *handle = 0; + *stride = info.minRowBytes(); + *pixels = new char[info.getSafeSize(*stride)]; + buffers_.push_back( + skia::AdoptRef(SkSurface::NewRasterDirect(info, *pixels, *stride))); + buffers_.back()->getCanvas()->clear(SK_ColorBLACK); + + return true; +} + +void MockDrmDevice::DestroyDumbBuffer(const SkImageInfo& info, + uint32_t handle, + uint32_t stride, + void* pixels) { + delete[] static_cast<char*>(pixels); +} + +void MockDrmDevice::RunCallbacks() { + while (!callbacks_.empty()) { + PageFlipCallback callback = callbacks_.front(); + callbacks_.pop(); + callback.Run(0, 0, 0); + } +} + +} // namespace ui
diff --git a/ui/ozone/platform/dri/test/mock_dri_wrapper.h b/ui/ozone/platform/dri/test/mock_drm_device.h similarity index 85% rename from ui/ozone/platform/dri/test/mock_dri_wrapper.h rename to ui/ozone/platform/dri/test/mock_drm_device.h index 87253d8..d3268e1 100644 --- a/ui/ozone/platform/dri/test/mock_dri_wrapper.h +++ b/ui/ozone/platform/dri/test/mock_drm_device.h
@@ -2,27 +2,27 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#ifndef UI_OZONE_PLATFORM_DRI_TEST_MOCK_DRI_WRAPPER_H_ -#define UI_OZONE_PLATFORM_DRI_TEST_MOCK_DRI_WRAPPER_H_ +#ifndef UI_OZONE_PLATFORM_DRI_TEST_MOCK_DRM_DEVICE_H_ +#define UI_OZONE_PLATFORM_DRI_TEST_MOCK_DRM_DEVICE_H_ #include <queue> #include <vector> #include "skia/ext/refptr.h" #include "third_party/skia/include/core/SkSurface.h" -#include "ui/ozone/platform/dri/dri_wrapper.h" +#include "ui/ozone/platform/dri/drm_device.h" namespace ui { class CrtcController; -// The real DriWrapper makes actual DRM calls which we can't use in unit tests. -class MockDriWrapper : public ui::DriWrapper { +// The real DrmDevice makes actual DRM calls which we can't use in unit tests. +class MockDrmDevice : public ui::DrmDevice { public: - MockDriWrapper(); - MockDriWrapper(bool use_sync_flips, - std::vector<uint32_t> crtcs, - size_t planes_per_crtc); + MockDrmDevice(); + MockDrmDevice(bool use_sync_flips, + std::vector<uint32_t> crtcs, + size_t planes_per_crtc); int get_get_crtc_call_count() const { return get_crtc_call_count_; } int get_set_crtc_call_count() const { return set_crtc_call_count_; } @@ -47,13 +47,13 @@ uint32_t current_framebuffer() const { return current_framebuffer_; } - const std::vector<skia::RefPtr<SkSurface> > buffers() const { + const std::vector<skia::RefPtr<SkSurface>> buffers() const { return buffers_; } void RunCallbacks(); - // DriWrapper: + // DrmDevice: ScopedDrmCrtcPtr GetCrtc(uint32_t crtc_id) override; bool SetCrtc(uint32_t crtc_id, uint32_t framebuffer, @@ -102,7 +102,7 @@ void* pixels) override; private: - ~MockDriWrapper() override; + ~MockDrmDevice() override; int get_crtc_call_count_; int set_crtc_call_count_; @@ -122,13 +122,13 @@ uint32_t current_framebuffer_; - std::vector<skia::RefPtr<SkSurface> > buffers_; + std::vector<skia::RefPtr<SkSurface>> buffers_; std::queue<PageFlipCallback> callbacks_; - DISALLOW_COPY_AND_ASSIGN(MockDriWrapper); + DISALLOW_COPY_AND_ASSIGN(MockDrmDevice); }; } // namespace ui -#endif // UI_OZONE_PLATFORM_DRI_TEST_MOCK_DRI_WRAPPER_H_ +#endif // UI_OZONE_PLATFORM_DRI_TEST_MOCK_DRM_DEVICE_H_
diff --git a/ui/snapshot/BUILD.gn b/ui/snapshot/BUILD.gn index b93fc6f..a9e5b0b 100644 --- a/ui/snapshot/BUILD.gn +++ b/ui/snapshot/BUILD.gn
@@ -56,37 +56,35 @@ } } -if (!is_win || link_chrome_on_windows) { - test("snapshot_unittests") { - sources = [ - "snapshot_aura_unittest.cc", - "snapshot_mac_unittest.mm", - "test/run_all_unittests.cc", - ] +test("snapshot_unittests") { + sources = [ + "snapshot_aura_unittest.cc", + "snapshot_mac_unittest.mm", + "test/run_all_unittests.cc", + ] - deps = [ - ":snapshot", - "//base", - "//base/allocator", - "//base/test:test_support", - "//skia", - "//testing/gtest", - "//ui/base", + deps = [ + ":snapshot", + "//base", + "//base/allocator", + "//base/test:test_support", + "//skia", + "//testing/gtest", + "//ui/base", + "//ui/compositor:test_support", + "//ui/gfx", + "//ui/gfx/geometry", + "//ui/gl", + ] + + if (use_aura) { + deps += [ + "//ui/aura:test_support", + "//ui/compositor", "//ui/compositor:test_support", - "//ui/gfx", - "//ui/gfx/geometry", - "//ui/gl", + "//ui/wm", ] - - if (use_aura) { - deps += [ - "//ui/aura:test_support", - "//ui/compositor", - "//ui/compositor:test_support", - "//ui/wm", - ] - } else { - sources -= [ "snapshot_aura_unittest.cc" ] - } + } else { + sources -= [ "snapshot_aura_unittest.cc" ] } }
diff --git a/ui/views/BUILD.gn b/ui/views/BUILD.gn index 2d9e813..922ce0c 100644 --- a/ui/views/BUILD.gn +++ b/ui/views/BUILD.gn
@@ -162,104 +162,102 @@ } } -if (!is_win || link_chrome_on_windows) { - test("views_unittests") { - sources = gypi_values.views_unittests_sources +test("views_unittests") { + sources = gypi_values.views_unittests_sources - deps = [ - ":test_support", - "//base", - "//base:i18n", - "//base/allocator", - "//base/test:test_support", - "//skia", - "//testing/gtest", - "//third_party/icu", - "//ui/accessibility", - "//ui/aura", - "//ui/base", - "//ui/base/ime", - "//ui/base:test_support", - "//ui/compositor:test_support", - "//ui/events:test_support", - "//ui/events:events_base", - "//ui/events/platform", - "//ui/gfx", - "//ui/gfx/geometry", - "//ui/gl", - "//ui/resources", - "//ui/strings", - "//ui/wm", - "//url", + deps = [ + ":test_support", + "//base", + "//base:i18n", + "//base/allocator", + "//base/test:test_support", + "//skia", + "//testing/gtest", + "//third_party/icu", + "//ui/accessibility", + "//ui/aura", + "//ui/base", + "//ui/base/ime", + "//ui/base:test_support", + "//ui/compositor:test_support", + "//ui/events:test_support", + "//ui/events:events_base", + "//ui/events/platform", + "//ui/gfx", + "//ui/gfx/geometry", + "//ui/gl", + "//ui/resources", + "//ui/strings", + "//ui/wm", + "//url", + ] + + if (is_win) { + deps += [ + "//third_party/iaccessible2", + "//third_party/wtl", + ] + libs = [ + "imm32.lib", + "oleacc.lib", + "comctl32.lib", ] - if (is_win) { - deps += [ - "//third_party/iaccessible2", - "//third_party/wtl", - ] - libs = [ - "imm32.lib", - "oleacc.lib", - "comctl32.lib", - ] + # TOOD(GYP) + #'msvs_settings': { + # 'VCManifestTool': { + # 'AdditionalManifestFiles': [ + # '$(ProjectDir)\\test\\views_unittest.manifest', + # ], + # }, + #}, + } - # TOOD(GYP) - #'msvs_settings': { - # 'VCManifestTool': { - # 'AdditionalManifestFiles': [ - # '$(ProjectDir)\\test\\views_unittest.manifest', - # ], - # }, - #}, - } + if (use_x11) { + configs += [ + "//build/config/linux:x11", + "//build/config/linux:xext", + ] + deps += [ + "//ui/events/devices", + "//ui/events/platform/x11", + "//ui/gfx/x", + ] + } - if (use_x11) { - configs += [ - "//build/config/linux:x11", - "//build/config/linux:xext", - ] - deps += [ - "//ui/events/devices", - "//ui/events/platform/x11", - "//ui/gfx/x", - ] - } - - if (use_aura) { - sources += gypi_values.views_unittests_aura_sources - deps += [ "//ui/aura:test_support" ] - if (!is_chromeos) { - sources += gypi_values.views_unittests_desktop_aura_sources - if (use_x11) { - sources += gypi_values.views_unittests_desktop_aurax11_sources - } + if (use_aura) { + sources += gypi_values.views_unittests_aura_sources + deps += [ "//ui/aura:test_support" ] + if (!is_chromeos) { + sources += gypi_values.views_unittests_desktop_aura_sources + if (use_x11) { + sources += gypi_values.views_unittests_desktop_aurax11_sources } } - if (!is_chromeos) { - sources += gypi_values.views_unittests_desktop_sources - } - if (use_x11) { - deps += [ - "//ui/events/platform/x11", - "//ui/gfx/x", - ] - } + } + if (!is_chromeos) { + sources += gypi_values.views_unittests_desktop_sources + } + if (use_x11) { + deps += [ + "//ui/events/platform/x11", + "//ui/gfx/x", + ] + } - if (is_mac) { - # views_unittests not yet compiling on Mac. http://crbug.com/378134 - sources -= [ - "bubble/bubble_window_targeter_unittest.cc", - "controls/button/custom_button_unittest.cc", - "controls/button/menu_button_unittest.cc", - "controls/menu/menu_controller_unittest.cc", - "controls/native/native_view_host_unittest.cc", - "focus/focus_manager_unittest.cc", - "ime/input_method_bridge_unittest.cc", - "widget/widget_unittest.cc", - "widget/window_reorderer_unittest.cc", - ] - } + if (is_mac) { + # views_unittests not yet compiling on Mac. http://crbug.com/378134 + sources -= [ + "bubble/bubble_window_targeter_unittest.cc", + "controls/button/custom_button_unittest.cc", + "controls/button/menu_button_unittest.cc", + "controls/menu/menu_controller_unittest.cc", + "controls/native/native_view_host_unittest.cc", + "focus/focus_manager_unittest.cc", + "ime/input_method_bridge_unittest.cc", + "widget/widget_unittest.cc", + "widget/window_reorderer_unittest.cc", + ] } }
diff --git a/ui/views/examples/BUILD.gn b/ui/views/examples/BUILD.gn index 455b06c..b908eb1 100644 --- a/ui/views/examples/BUILD.gn +++ b/ui/views/examples/BUILD.gn
@@ -88,35 +88,33 @@ } } -if (!is_win || link_chrome_on_windows) { - executable("views_examples_exe") { - testonly = true +executable("views_examples_exe") { + testonly = true - sources = [ - "examples_main.cc", - ] + sources = [ + "examples_main.cc", + ] - deps = [ - ":views_examples_lib", - "//base", - "//base:i18n", - "//ui/base", - "//ui/compositor", - "//ui/compositor:test_support", - "//ui/gfx", - "//ui/gl", - "//ui/resources:ui_test_pak", - "//ui/views", - "//ui/views:test_support", - "//ui/wm", - ] + deps = [ + ":views_examples_lib", + "//base", + "//base:i18n", + "//ui/base", + "//ui/compositor", + "//ui/compositor:test_support", + "//ui/gfx", + "//ui/gl", + "//ui/resources:ui_test_pak", + "//ui/views", + "//ui/views:test_support", + "//ui/wm", + ] - if (use_aura) { - deps += [ "//ui/aura" ] - } - if (use_x11) { - deps += [ "//ui/gfx/x" ] - } + if (use_aura) { + deps += [ "//ui/aura" ] + } + if (use_x11) { + deps += [ "//ui/gfx/x" ] } }
diff --git a/ui/webui/resources/cr_elements/cr_input/cr_input.css b/ui/webui/resources/cr_elements/cr_input/cr_input.css new file mode 100644 index 0000000..204e397 --- /dev/null +++ b/ui/webui/resources/cr_elements/cr_input/cr_input.css
@@ -0,0 +1,7 @@ +/* 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. */ + +:host { + display: inline-block; +}
diff --git a/ui/webui/resources/cr_elements/cr_input/cr_input.html b/ui/webui/resources/cr_elements/cr_input/cr_input.html new file mode 100644 index 0000000..e0eddc3d --- /dev/null +++ b/ui/webui/resources/cr_elements/cr_input/cr_input.html
@@ -0,0 +1,23 @@ +<link rel="import" href="chrome://resources/polymer/polymer/polymer.html"> +<link rel="import" href="chrome://resources/polymer/paper-input/paper-input-decorator.html"> +<link rel="import" href="chrome://resources/polymer/core-input/core-input.html"> +<link rel="import" href="chrome://resources/cr_elements/cr_events/cr_events.html"> + +<polymer-element name="cr-input"> + <template> + <link rel="stylesheet" href="cr_input.css"> + <cr-events id="events"></cr-events> + + <!-- TODO(jlklein): Use 'autoValidate' instead of isInvalid binding when + updated to 0.5.4. --> + <paper-input-decorator id="decorator" label="{{label}}" + floatingLabel="{{floatingLabel}}" value="{{value}}" + disabled?="{{disabled}}" error="{{error}}" + isInvalid="{{!$.input.validity.valid}}"> + <input is="core-input" id="input" value="{{value}}" + committedValue="{{committedValue}}" disabled?="{{disabled}}" + required?="{{required}}" type="{{type}}"> + </paper-input-decorator> + </template> + <script src="cr_input.js"></script> +</polymer-element>
diff --git a/ui/webui/resources/cr_elements/cr_input/cr_input.js b/ui/webui/resources/cr_elements/cr_input/cr_input.js new file mode 100644 index 0000000..3f8f253 --- /dev/null +++ b/ui/webui/resources/cr_elements/cr_input/cr_input.js
@@ -0,0 +1,128 @@ +/* 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 + * 'cr-input' is a single-line text field for user input. It is a convenience + * element composed of a 'paper-input-decorator' and a 'input is="core-input"'. + * + * Example: + * + * <cr-input></cr-input> + * + * @group Chrome Elements + * @element cr-input + */ +Polymer('cr-input', { + publish: { + /** + * The label for this input. It normally appears as grey text inside + * the text input and disappears once the user enters text. + * + * @attribute label + * @type string + * @default '' + */ + label: '', + + /** + * If true, the label will "float" above the text input once the + * user enters text instead of disappearing. + * + * @attribute floatingLabel + * @type boolean + * @default true + */ + floatingLabel: true, + + /** + * Set to true to style the element as disabled. + * + * @attribute disabled + * @type boolean + * @default false + */ + disabled: {value: false, reflect: true}, + + /** + * Set to true to mark the input as required. + * + * @attribute required + * @type boolean + * @default false + */ + required: {value: false, reflect: true}, + + /** + * The current value of the input. + * + * @attribute value + * @type string + * @default '' + */ + value: '', + + /** + * The validation pattern for the input. + * + * @attribute pattern + * @type string + * @default '' + */ + pattern: '', + + /** + * The type of the input (password, date, etc.). + * + * @attribute type + * @type string + * @default 'text' + */ + type: 'text', + + /** + * The message to display if the input value fails validation. If this + * is unset or the empty string, a default message is displayed depending + * on the type of validation error. + * + * @attribute error + * @type string + * @default '' + */ + error: '', + + /** + * The most recently committed value of the input. + * + * @attribute committedValue + * @type string + * @default '' + */ + committedValue: '' + }, + + /** + * Focuses the 'input' element. + */ + focus: function() { + this.$.input.focus(); + }, + + valueChanged: function() { + this.$.decorator.updateLabelVisibility(this.value); + }, + + patternChanged: function() { + if (this.pattern) + this.$.input.pattern = this.pattern; + else + this.$.input.removeAttribute('pattern'); + }, + + /** @override */ + ready: function() { + this.$.events.forward(this.$.input, ['change']); + this.patternChanged(); + }, +});
diff --git a/ui/webui/resources/cr_elements/cr_input/demo.html b/ui/webui/resources/cr_elements/cr_input/demo.html new file mode 100644 index 0000000..0934e48 --- /dev/null +++ b/ui/webui/resources/cr_elements/cr_input/demo.html
@@ -0,0 +1,14 @@ +<!doctype html> +<html> +<head> + <link href="cr_input.html" rel="import"> +</head> +<body unresolved> + <cr-input label="Blah"></cr-input> + <cr-input label="This is required" required error="Put something here!"> + </cr-input> + <cr-input label="Only numbers" pattern="^[0-9]*$" + error="Only numbers allowed!"></cr-input> + <cr-input label="Password" type="password"></cr-input> +</body> +</html>
diff --git a/ui/webui/resources/cr_elements/cr_network_icon/badge_3g.png b/ui/webui/resources/cr_elements/cr_network_icon/badge_3g.png new file mode 100644 index 0000000..cfe578b --- /dev/null +++ b/ui/webui/resources/cr_elements/cr_network_icon/badge_3g.png Binary files differ
diff --git a/ui/webui/resources/cr_elements/cr_network_icon/badge_4g.png b/ui/webui/resources/cr_elements/cr_network_icon/badge_4g.png new file mode 100644 index 0000000..0729051 --- /dev/null +++ b/ui/webui/resources/cr_elements/cr_network_icon/badge_4g.png Binary files differ
diff --git a/ui/webui/resources/cr_elements/cr_network_icon/badge_edge.png b/ui/webui/resources/cr_elements/cr_network_icon/badge_edge.png new file mode 100644 index 0000000..1620182 --- /dev/null +++ b/ui/webui/resources/cr_elements/cr_network_icon/badge_edge.png Binary files differ
diff --git a/ui/webui/resources/cr_elements/cr_network_icon/badge_evdo.png b/ui/webui/resources/cr_elements/cr_network_icon/badge_evdo.png new file mode 100644 index 0000000..7742ace --- /dev/null +++ b/ui/webui/resources/cr_elements/cr_network_icon/badge_evdo.png Binary files differ
diff --git a/ui/webui/resources/cr_elements/cr_network_icon/badge_gsm.png b/ui/webui/resources/cr_elements/cr_network_icon/badge_gsm.png new file mode 100644 index 0000000..b6690aa --- /dev/null +++ b/ui/webui/resources/cr_elements/cr_network_icon/badge_gsm.png Binary files differ
diff --git a/ui/webui/resources/cr_elements/cr_network_icon/badge_hspa.png b/ui/webui/resources/cr_elements/cr_network_icon/badge_hspa.png new file mode 100644 index 0000000..c1760fe --- /dev/null +++ b/ui/webui/resources/cr_elements/cr_network_icon/badge_hspa.png Binary files differ
diff --git a/ui/webui/resources/cr_elements/cr_network_icon/badge_hspa_plus.png b/ui/webui/resources/cr_elements/cr_network_icon/badge_hspa_plus.png new file mode 100644 index 0000000..ff2ac509 --- /dev/null +++ b/ui/webui/resources/cr_elements/cr_network_icon/badge_hspa_plus.png Binary files differ
diff --git a/ui/webui/resources/cr_elements/cr_network_icon/badge_lte.png b/ui/webui/resources/cr_elements/cr_network_icon/badge_lte.png new file mode 100644 index 0000000..16d3157 --- /dev/null +++ b/ui/webui/resources/cr_elements/cr_network_icon/badge_lte.png Binary files differ
diff --git a/ui/webui/resources/cr_elements/cr_network_icon/badge_lte_advanced.png b/ui/webui/resources/cr_elements/cr_network_icon/badge_lte_advanced.png new file mode 100644 index 0000000..d97c035d --- /dev/null +++ b/ui/webui/resources/cr_elements/cr_network_icon/badge_lte_advanced.png Binary files differ
diff --git a/ui/webui/resources/cr_elements/cr_network_icon/badge_roaming.png b/ui/webui/resources/cr_elements/cr_network_icon/badge_roaming.png new file mode 100644 index 0000000..7036c55 --- /dev/null +++ b/ui/webui/resources/cr_elements/cr_network_icon/badge_roaming.png Binary files differ
diff --git a/ui/webui/resources/cr_elements/cr_network_icon/secure.png b/ui/webui/resources/cr_elements/cr_network_icon/badge_secure.png similarity index 100% rename from ui/webui/resources/cr_elements/cr_network_icon/secure.png rename to ui/webui/resources/cr_elements/cr_network_icon/badge_secure.png Binary files differ
diff --git a/ui/webui/resources/cr_elements/cr_network_icon/cr_network_icon.css b/ui/webui/resources/cr_elements/cr_network_icon/cr_network_icon.css index 3406bcc..1ba4729 100644 --- a/ui/webui/resources/cr_elements/cr_network_icon/cr_network_icon.css +++ b/ui/webui/resources/cr_elements/cr_network_icon/cr_network_icon.css
@@ -4,8 +4,10 @@ :host { display: inline-block; + height: 50px; overflow: hidden; position: relative; + width: 50px; } #icon { @@ -38,10 +40,39 @@ top: -400%; } +/* Connecting animation */ + +#icon.connecting { + -webkit-animation: levels 1s infinite; + -webkit-animation-timing-function: steps(4, start); +} + +@-webkit-keyframes levels { + from { + top: 0%; + } + to { + top: -400%; + } +} + +/* Badges. */ +/* Note: These use left/right because we do not reverse the badges for RTL. */ + +/* Upper-left corner */ +#technology { + height: 40%; + left: 0px; + position: absolute; + top: 0px; +} + +/* Lower-right corner */ +#roaming, #secure { height: 40%; - margin-left: 60%; - margin-top: 60%; + left: 60%; position: absolute; + top: 60%; width: 40%; }
diff --git a/ui/webui/resources/cr_elements/cr_network_icon/cr_network_icon.html b/ui/webui/resources/cr_elements/cr_network_icon/cr_network_icon.html index a8a53fb2..4762f6c 100644 --- a/ui/webui/resources/cr_elements/cr_network_icon/cr_network_icon.html +++ b/ui/webui/resources/cr_elements/cr_network_icon/cr_network_icon.html
@@ -3,9 +3,15 @@ <polymer-element name="cr-network-icon"> <template> <link rel="stylesheet" href="cr_network_icon.css"> - <img id="icon"> + <img id="icon" src="{{iconType | toImageSrc}}"> + <img id="technology" src="{{technology | toBadgeImageSrc}}" + hidden?="{{!technology}}"> + <img id="roaming" + src="chrome://resources/cr_elements/cr_network_icon/badge_roaming.png" + hidden?="{{!roaming}}"> <img id="secure" - src="chrome://resources/cr_elements/cr_network_icon/secure.png"> + src="chrome://resources/cr_elements/cr_network_icon/badge_secure.png" + hidden?="{{!secure}}"> </template> <script src="cr_network_icon.js"></script> </polymer-element>
diff --git a/ui/webui/resources/cr_elements/cr_network_icon/cr_network_icon.js b/ui/webui/resources/cr_elements/cr_network_icon/cr_network_icon.js index 4f6c4d5f..c70079e 100644 --- a/ui/webui/resources/cr_elements/cr_network_icon/cr_network_icon.js +++ b/ui/webui/resources/cr_elements/cr_network_icon/cr_network_icon.js
@@ -10,10 +10,8 @@ (function() { /** * @typedef {{ + * showBadges: boolean, * showDisconnected: boolean, - * iconType: string, - * connected: boolean, - * secure: boolean, * strength: number * }} */ @@ -51,6 +49,30 @@ * @element cr-network-icon */ Polymer('cr-network-icon', { + /** + * The icon type to use for the base image of the icon. + * @type string + */ + iconType: 'ethernet', + + /** + * Set to true to show a badge for roaming networks. + * @type boolean + */ + roaming: false, + + /** + * Set to true to show a badge for secure networks. + * @type boolean + */ + secure: false, + + /** + * Set to the name of a technology to show show a badge. + * @type string + */ + technology: '', + publish: { /** * If set, the ONC data properties will be used to display the icon. @@ -85,9 +107,7 @@ /** @override */ attached: function() { var params = /** @type {IconParams} */ { - connected: false, - iconType: 'ethernet', - secure: false, + showBadges: false, showDisconnected: true, strength: 0, }; @@ -99,12 +119,9 @@ * network state. */ networkStateChanged: function() { - var iconType = getIconTypeFromNetworkType(this.networkState.data.Type); + this.iconType = getIconTypeFromNetworkType(this.networkState.data.Type); var params = /** @type {IconParams} */ { - connected: this.networkState.data.ConnectionState == 'Connected', - iconType: iconType, - secure: iconType == 'wifi' && - this.networkState.getWiFiSecurity() != 'None', + showBadges: true, showDisconnected: !this.isListItem, strength: this.networkState.getStrength(), }; @@ -116,10 +133,9 @@ * of network, showing a disconnected icon where appropriate and no badges. */ networkTypeChanged: function() { + this.iconType = getIconTypeFromNetworkType(this.networkType); var params = /** @type {IconParams} */ { - connected: false, - iconType: getIconTypeFromNetworkType(this.networkType), - secure: false, + showBadges: false, showDisconnected: true, strength: 0, }; @@ -127,32 +143,126 @@ }, /** + * Returns the url for an image based on identifier |id|. + * @param {string} src The identifier describing the image. + * @return {string} The url to use for the image 'src' property. + */ + toImageSrc: function(id) { + return id ? RESOURCE_IMAGE_BASE + id + RESOURCE_IMAGE_EXT : ''; + }, + + /** + * Returns the url for a badge image based on identifier |id|. + * @param {string} id The identifier describing the badge. + * @return {string} The url to use for the badge image 'src' property. + */ + toBadgeImageSrc: function(id) { + return id ? this.toImageSrc('badge_' + id) : ''; + }, + + /** * Sets the icon and badge based on the current state and |strength|. * @param {!IconParams} params The set of params describing the icon. * @private */ setIcon_: function(params) { var icon = this.$.icon; - if (params.iconType) - icon.src = RESOURCE_IMAGE_BASE + params.iconType + RESOURCE_IMAGE_EXT; - var multiLevel, strength; - if (params.iconType == 'wifi' || params.iconType == 'mobile') { - multiLevel = true; - strength = (params.showDisconnected && !params.connected) ? - -1 : params.strength; + var multiLevel = (this.iconType == 'wifi' || this.iconType == 'mobile'); + + if (this.networkState && multiLevel) { + this.setMultiLevelIcon_(params); } else { - multiLevel = false; - strength = -1; + icon.className = multiLevel ? 'multi-level level0' : ''; } - icon.classList.toggle('multi-level', multiLevel); + + this.setIconBadges_(params); + }, + + /** + * Toggles icon classes based on strength and connecting properties. + * |this.networkState| is expected to be specified. + * @param {!IconParams} params The set of params describing the icon. + * @private + */ + setMultiLevelIcon_: function(params) { + // Set the strength or connecting properties. + var networkState = this.networkState; + + var connecting = false; + var strength = -1; + if (networkState.connecting()) { + strength = 0; + connecting = true; + } else if (networkState.connected() || !params.showDisconnected) { + strength = params.strength || 0; + } + + var icon = this.$.icon; + icon.classList.toggle('multi-level', true); + icon.classList.toggle('connecting', connecting); icon.classList.toggle('level0', strength < 0); icon.classList.toggle('level1', strength >= 0 && strength <= 25); icon.classList.toggle('level2', strength > 25 && strength <= 50); icon.classList.toggle('level3', strength > 50 && strength <= 75); icon.classList.toggle('level4', strength > 75); + }, - this.$.secure.hidden = !params.secure; + /** + * Sets the icon badge visibility properties: roaming, secure, technology. + * @param {!IconParams} params The set of params describing the icon. + * @private + */ + setIconBadges_: function(params) { + var networkState = this.networkState; + + var type = + (params.showBadges && networkState) ? networkState.data.Type : ''; + if (type == CrOnc.Type.WIFI) { + this.roaming = false; + this.secure = networkState.getWiFiSecurity() != 'None'; + this.technology = ''; + } else if (type == CrOnc.Type.WIMAX) { + this.roaming = false; + this.secure = false; + this.technology = '4g'; + } else if (type == CrOnc.Type.CELLULAR) { + this.roaming = + networkState.getCellularRoamingState() == CrOnc.RoamingState.ROAMING; + this.secure = false; + var oncTechnology = networkState.getCellularTechnology(); + switch (oncTechnology) { + case CrOnc.NetworkTechnology.EDGE: + this.technology = 'edge'; + break; + case CrOnc.NetworkTechnology.EVDO: + this.technology = 'evdo'; + break; + case CrOnc.NetworkTechnology.GPRS: + case CrOnc.NetworkTechnology.GSM: + this.technology = 'gsm'; + break; + case CrOnc.NetworkTechnology.HSPA: + this.technology = 'hspa'; + break; + case CrOnc.NetworkTechnology.HSPA_PLUS: + this.technology = 'hspa_plus'; + break; + case CrOnc.NetworkTechnology.LTE: + this.technology = 'lte'; + break; + case CrOnc.NetworkTechnology.LTE_ADVANCED: + this.technology = 'lte_advanced'; + break; + case CrOnc.NetworkTechnology.UMTS: + this.technology = '3g'; + break; + } + } else { + this.roaming = false; + this.secure = false; + this.technology = ''; + } }, }); })();
diff --git a/ui/webui/resources/cr_elements/cr_network_icon/mobile.png b/ui/webui/resources/cr_elements/cr_network_icon/mobile.png index 548ef5f..9c2d026 100644 --- a/ui/webui/resources/cr_elements/cr_network_icon/mobile.png +++ b/ui/webui/resources/cr_elements/cr_network_icon/mobile.png Binary files differ
diff --git a/ui/webui/resources/cr_elements/cr_onc/cr_onc_data.js b/ui/webui/resources/cr_elements/cr_onc/cr_onc_data.js index 4bca1d2..01b0f55 100644 --- a/ui/webui/resources/cr_elements/cr_onc/cr_onc_data.js +++ b/ui/webui/resources/cr_elements/cr_onc/cr_onc_data.js
@@ -22,13 +22,22 @@ data: null, }, + /** @override */ created: function() { this.data = /** @type {CrOnc.NetworkConfigType} */({}); }, - /** - * @return {number} The signal strength of the network. - */ + /** @return {boolean} True if the network is connected. */ + connected: function() { + return this.data.ConnectionState == CrOnc.ConnectionState.CONNECTED; + }, + + /** @return {boolean} True if the network is connecting. */ + connecting: function() { + return this.data.ConnectionState == CrOnc.ConnectionState.CONNECTING; + }, + + /** @return {number} The signal strength of the network. */ getStrength: function() { var type = this.data.Type; var strength = 0; @@ -41,12 +50,21 @@ return strength; }, - /** - * Returns the WiFi security type. Undefined or empty defaults to 'None'. - * @return {string} The WiFi security type. - */ + /** @return {CrOnc.Security} The ONC security type. */ getWiFiSecurity: function() { return (this.data.WiFi && this.data.WiFi.Security) ? - this.data.WiFi.Security : 'None'; + this.data.WiFi.Security : CrOnc.Security.NONE; + }, + + /** @return {CrOnc.RoamingState} The ONC roaming state. */ + getCellularRoamingState: function() { + return (this.data.Cellular && this.data.Cellular.RoamingState) ? + this.data.Cellular.RoamingState : CrOnc.RoamingState.UNKNOWN; + }, + + /** @return {CrOnc.NetworkTechnology} The ONC network technology. */ + getCellularTechnology: function() { + return (this.data.Cellular && this.data.Cellular.NetworkTechnology) ? + this.data.Cellular.NetworkTechnology : CrOnc.NetworkTechnology.UNKNOWN; } });
diff --git a/ui/webui/resources/cr_elements/cr_onc/cr_onc_types.js b/ui/webui/resources/cr_elements/cr_onc/cr_onc_types.js index 8c010ac..714d4593 100644 --- a/ui/webui/resources/cr_elements/cr_onc/cr_onc_types.js +++ b/ui/webui/resources/cr_elements/cr_onc/cr_onc_types.js
@@ -12,16 +12,67 @@ var CrOnc = {}; +/** @enum {string} */ +CrOnc.Type = { + CELLULAR: 'Cellular', + ETHERNET: 'Ethernet', + VPN: 'VPN', + WIFI: 'WiFi', + WIMAX: 'WiMAX', +}; + +/** @enum {string} */ +CrOnc.ConnectionState = { + CONNECTED: 'Connected', + CONNECTING: 'Connecting', + NOT_CONNECTED: 'NotConnected', +}; + +/** @enum {string} */ +CrOnc.NetworkTechnology = { + EDGE: 'EDGE', + EVDO: 'EVDO', + GPRS: 'GPRS', + GSM: 'GSM', + HSPA: 'HSPA', + HSPA_PLUS: 'HSPA+', + LTE: 'LTE', + LTE_ADVANCED: 'LTE Advanced', + UMTS: 'UMTS', + UNKNOWN: 'Unknown', +}; + +/** @enum {string} */ +CrOnc.RoamingState = { + HOME: 'Home', + REQUIRED: 'Required', + ROAMING: 'Roaming', + UNKNOWN: 'Unknown', +}; + +/** @enum {string} */ +CrOnc.Security = { + NONE: 'None', + WEP_8021X: 'WEP-8021X', + WEP_PSK: 'WEP-PSK', + WPA_EAP: 'WPA-EAP', + WPA_PSK: 'WPA-PSK', +}; + /** @typedef {string|!Object} */ CrOnc.ManagedStringType; /** - * @typedef {{NetworkTechnology: string, Strength: number}} + * @typedef {{ + * NetworkTechnology: CrOnc.NetworkTechnology, + * RoamingState: CrOnc.RoamingState, + * Strength: number + * }} */ CrOnc.CellularType; /** - * @typedef {{Security: string, Strength: number}} + * @typedef {{Security: CrOnc.Security, Strength: number}} */ CrOnc.WiFiType; @@ -30,22 +81,13 @@ */ CrOnc.WiMAXType; -/** @enum {string} */ -CrOnc.Type = { - CELLULAR: "Cellular", - ETHERNET: "Ethernet", - VPN: "VPN", - WIFI: "WiFi", - WIMAX: "WiMAX", -}; - /** * @typedef {{ * Cellular: CrOnc.CellularType, - * ConnectionState: string, + * ConnectionState: CrOnc.ConnectionState, * GUID: string, * Name: CrOnc.ManagedStringType, - * Type: string, + * Type: CrOnc.Type, * WiFi: CrOnc.WiFiType, * WiMAX: CrOnc.WiMAXType * }}
diff --git a/ui/webui/resources/cr_elements_images.grdp b/ui/webui/resources/cr_elements_images.grdp index de2116d..46a3689 100644 --- a/ui/webui/resources/cr_elements_images.grdp +++ b/ui/webui/resources/cr_elements_images.grdp
@@ -1,18 +1,48 @@ <?xml version="1.0" encoding="utf-8"?> <grit-part> + <include name="IDR_WEBUI_CR_ELEMENTS_NETWORK_BADGE_3G" + file="cr_elements/cr_network_icon/badge_3g.png" + type="BINDATA" /> + <include name="IDR_WEBUI_CR_ELEMENTS_NETWORK_BADGE_4G" + file="cr_elements/cr_network_icon/badge_4g.png" + type="BINDATA" /> + <include name="IDR_WEBUI_CR_ELEMENTS_NETWORK_BADGE_EDGE" + file="cr_elements/cr_network_icon/badge_edge.png" + type="BINDATA" /> + <include name="IDR_WEBUI_CR_ELEMENTS_NETWORK_BADGE_EVDO" + file="cr_elements/cr_network_icon/badge_evdo.png" + type="BINDATA" /> + <include name="IDR_WEBUI_CR_ELEMENTS_NETWORK_BADGE_GPRS" + file="cr_elements/cr_network_icon/badge_gsm.png" + type="BINDATA" /> + <include name="IDR_WEBUI_CR_ELEMENTS_NETWORK_BADGE_HSPA" + file="cr_elements/cr_network_icon/badge_hspa.png" + type="BINDATA" /> + <include name="IDR_WEBUI_CR_ELEMENTS_NETWORK_BADGE_HSPA_PLUS" + file="cr_elements/cr_network_icon/badge_hspa_plus.png" + type="BINDATA" /> + <include name="IDR_WEBUI_CR_ELEMENTS_NETWORK_BADGE_LTE" + file="cr_elements/cr_network_icon/badge_lte.png" + type="BINDATA" /> + <include name="IDR_WEBUI_CR_ELEMENTS_NETWORK_BADGE_LTE_ADVANCED" + file="cr_elements/cr_network_icon/badge_lte_advanced.png" + type="BINDATA" /> + <include name="IDR_WEBUI_CR_ELEMENTS_NETWORK_BADGE_ROAMING" + file="cr_elements/cr_network_icon/badge_roaming.png" + type="BINDATA" /> + <include name="IDR_WEBUI_CR_ELEMENTS_NETWORK_BADGE_SECURE" + file="cr_elements/cr_network_icon/badge_secure.png" + type="BINDATA" /> <include name="IDR_WEBUI_CR_ELEMENTS_NETWORK_ICON_ETHERNET" file="cr_elements/cr_network_icon/ethernet.png" type="BINDATA" /> - <include name="IDR_WEBUI_CR_ELEMENTS_NETWORK_ICON_WIFI" - file="cr_elements/cr_network_icon/wifi.png" - type="BINDATA" /> <include name="IDR_WEBUI_CR_ELEMENTS_NETWORK_ICON_MOBILE" file="cr_elements/cr_network_icon/mobile.png" type="BINDATA" /> <include name="IDR_WEBUI_CR_ELEMENTS_NETWORK_ICON_VPN" file="cr_elements/cr_network_icon/vpn.png" type="BINDATA" /> - <include name="IDR_WEBUI_CR_ELEMENTS_NETWORK_ICON_SECURE" - file="cr_elements/cr_network_icon/secure.png" + <include name="IDR_WEBUI_CR_ELEMENTS_NETWORK_ICON_WIFI" + file="cr_elements/cr_network_icon/wifi.png" type="BINDATA" /> </grit-part>
diff --git a/ui/webui/resources/cr_elements_resources.grdp b/ui/webui/resources/cr_elements_resources.grdp index 8eb2787a..f1b89bf 100644 --- a/ui/webui/resources/cr_elements_resources.grdp +++ b/ui/webui/resources/cr_elements_resources.grdp
@@ -37,29 +37,38 @@ file="../../webui/resources/cr_elements/cr_dropdown_menu/cr_dropdown_menu.js" type="chrome_html" /> <structure name="IDR_CR_ELEMENTS_CR_NETWORK_ICON_CSS" - file="../../webui/resources/cr_elements/cr_network_icon/cr_network_icon.css" - type="chrome_html" /> + file="../../webui/resources/cr_elements/cr_network_icon/cr_network_icon.css" + type="chrome_html" /> <structure name="IDR_CR_ELEMENTS_CR_NETWORK_ICON_HTML" - file="../../webui/resources/cr_elements/cr_network_icon/cr_network_icon.html" - type="chrome_html" /> + file="../../webui/resources/cr_elements/cr_network_icon/cr_network_icon.html" + type="chrome_html" /> <structure name="IDR_CR_ELEMENTS_CR_NETWORK_ICON_JS" - file="../../webui/resources/cr_elements/cr_network_icon/cr_network_icon.js" - type="chrome_html" /> + file="../../webui/resources/cr_elements/cr_network_icon/cr_network_icon.js" + type="chrome_html" /> <structure name="IDR_CR_ELEMENTS_CR_ONC_TYPES_JS" - file="../../webui/resources/cr_elements/cr_onc/cr_onc_types.js" - type="chrome_html" /> + file="../../webui/resources/cr_elements/cr_onc/cr_onc_types.js" + type="chrome_html" /> <structure name="IDR_CR_ELEMENTS_CR_ONC_DATA_HTML" - file="../../webui/resources/cr_elements/cr_onc/cr_onc_data.html" - type="chrome_html" /> + file="../../webui/resources/cr_elements/cr_onc/cr_onc_data.html" + type="chrome_html" /> <structure name="IDR_CR_ELEMENTS_CR_ONC_DATA_JS" - file="../../webui/resources/cr_elements/cr_onc/cr_onc_data.js" - type="chrome_html" /> + file="../../webui/resources/cr_elements/cr_onc/cr_onc_data.js" + type="chrome_html" /> <structure name="IDR_CR_ELEMENTS_CR_EVENTS_HTML" file="../../webui/resources/cr_elements/cr_events/cr_events.html" type="chrome_html" /> <structure name="IDR_CR_ELEMENTS_CR_EVENTS_JS" file="../../webui/resources/cr_elements/cr_events/cr_events.js" type="chrome_html" /> + <structure name="IDR_CR_ELEMENTS_CR_INPUT_CSS" + file="../../webui/resources/cr_elements/cr_input/cr_input.css" + type="chrome_html" /> + <structure name="IDR_CR_ELEMENTS_CR_INPUT_HTML" + file="../../webui/resources/cr_elements/cr_input/cr_input.html" + type="chrome_html" /> + <structure name="IDR_CR_ELEMENTS_CR_INPUT_JS" + file="../../webui/resources/cr_elements/cr_input/cr_input.js" + type="chrome_html" /> <structure name="IDR_CR_ELEMENTS_CR_TOGGLE_BUTTON_CSS" file="../../webui/resources/cr_elements/cr_toggle_button/cr_toggle_button.css" type="chrome_html" />
diff --git a/ui/wm/BUILD.gn b/ui/wm/BUILD.gn index 290a90f9..74fea7c1 100644 --- a/ui/wm/BUILD.gn +++ b/ui/wm/BUILD.gn
@@ -115,39 +115,37 @@ ] } -if (!is_win || link_chrome_on_windows) { - test("wm_unittests") { - sources = [ - "core/capture_controller_unittest.cc", - "core/compound_event_filter_unittest.cc", - "core/cursor_manager_unittest.cc", - "core/focus_controller_unittest.cc", - "core/image_grid_unittest.cc", - "core/input_method_event_filter_unittest.cc", - "core/nested_accelerator_controller_unittest.cc", - "core/shadow_controller_unittest.cc", - "core/transient_window_manager_unittest.cc", - "core/transient_window_stacking_client_unittest.cc", - "core/visibility_controller_unittest.cc", - "core/window_animations_unittest.cc", - "test/run_all_unittests.cc", - ] +test("wm_unittests") { + sources = [ + "core/capture_controller_unittest.cc", + "core/compound_event_filter_unittest.cc", + "core/cursor_manager_unittest.cc", + "core/focus_controller_unittest.cc", + "core/image_grid_unittest.cc", + "core/input_method_event_filter_unittest.cc", + "core/nested_accelerator_controller_unittest.cc", + "core/shadow_controller_unittest.cc", + "core/transient_window_manager_unittest.cc", + "core/transient_window_stacking_client_unittest.cc", + "core/visibility_controller_unittest.cc", + "core/window_animations_unittest.cc", + "test/run_all_unittests.cc", + ] - deps = [ - ":test_support", - ":wm", - "//base", - "//base/test:test_support", - "//skia", - "//testing/gtest", - "//ui/aura:test_support", - "//ui/base:test_support", - "//ui/compositor:test_support", - "//ui/events:test_support", - "//ui/events/platform", - "//ui/gfx", - "//ui/gfx/geometry", - "//ui/gl", - ] - } + deps = [ + ":test_support", + ":wm", + "//base", + "//base/test:test_support", + "//skia", + "//testing/gtest", + "//ui/aura:test_support", + "//ui/base:test_support", + "//ui/compositor:test_support", + "//ui/events:test_support", + "//ui/events/platform", + "//ui/gfx", + "//ui/gfx/geometry", + "//ui/gl", + ] }